Browse Source

Init commit with the code

tags/v1.0
commit
5c5770bf6f
2 changed files with 109 additions and 0 deletions
  1. +1
    -0
      .gitignore
  2. +108
    -0
      main.c

+ 1
- 0
.gitignore View File

@@ -0,0 +1 @@
Keil/

+ 108
- 0
main.c View File

@@ -0,0 +1,108 @@
/*!
* @file
* main.c
* @brief
* A palindrome implementation and testing application
* for A.U.TH. Microprocessors and peripherals Lab.
*
* Created on: May 1, 2020
* Author: Christos Choutouridis AEM: 8997
* email : <cchoutou@ece.auth.gr>
*/
#include <stdint.h>

/*!
* The RAM address to use for palindrome result.
* @note:
* Select a RAM location above `__initial_sp`. See your startup_xx.s for details.
* Keil's RAM layout is:
*
* RAM: |<-Heap_Size-><-Stack_Size->|<- WASTED RAM SPACE ->|
* ^ ^ ^
* | | |
* Start:0x20000000 __initial_sp End of RAM
*
*/
#define RESULT 0x20001000

/*!
* String length calculation.
* @arg R0: Pointer to string
* @return R0: String length (unsigned)
*/
__asm uint32_t strLength (const char* src) {
// R0: length, return value
// R1: src
// R2: v = *src
MOV R1, R0 // Get variable
MOV R0, #0 // length{R0} =0;
len_loop // do {
LDRB R2, [R1], #1 // v{R2} = *src++;
CMP R2, #0 // if(v)
ADDNE R0, R0, #1 // ++length{R0};
BNE len_loop // } while (v);
BX LR // return length;
}

/*!
* A string palindrome predicate.
* @note
* We use a simple O(n), no stack algorithm.
* @note
* This function also writes to RAM address @ref RESULT the return value (which is nasty).
* @arg R0: Pointer to string
* @return R0: True if predicate
* False if not
*/
__asm uint32_t isPalindrome (const char* src) {
// R0: src[]
// R1: i
// R2: j
// R3: v1 = src[i]
// R4: v2 = src[j]
PUSH {R4, LR}
MOV R4, R0 // save R0
BL strLength // j{R2} = strLength(src) - 1
SUB R2, R0, #1
MOV R0, R4 // src{R0}
MOV R1, #0 // i{R1} =0;

pal_loop
CMP R1, R2 // while (i<j) {
BGE pal_true
LDRB R3, [R0, R1] // v1 = *src[i];
LDRB R4, [R0, R2] // v2 = *src[j];
CMP R3, R4 // if (v1 == v2) {
ADDEQ R1, R1, #1 // ++i;
SUBEQ R2, R2, #1 // --j;
BEQ pal_loop // // goto loop;
// } else
MOV R0, #0 // return *RESULT = 0;
LDR R1, =RESULT
STRB R0, [R1]
POP {R4, PC}
// }
pal_true
MOV R0, #1 // return *RESULT = 1;
LDR R1, =RESULT
STRB R0, [R1]
POP {R4, PC}
}

/*!
* Main routine
*/
int main(void) {
const char *s1 = "hello world!"; // Not a palindrome
const char *s2 = "aibohphobia"; // Aibophobia def= "Fear of palindromes", palindrome.

uint32_t res1 = isPalindrome (s1); // Test case 1
uint32_t res2 = isPalindrome (s2); // Test case 2
while (1); // Trap forever
//return 0; //!< comment out return, to suppress "statement is unreachable" warning.
//!^ @note:
//! **Weird** Keil's way for "statement is unreachable", suppresion.

}

Loading…
Cancel
Save