Init commit with the code
This commit is contained in:
commit
5c5770bf6f
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
Keil/
|
108
main.c
Normal file
108
main.c
Normal 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…
x
Reference in New Issue
Block a user