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