/*! * @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 : */ #include /*! * 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 src{R0} Pointer to string * @return {R0} String length, -1 if src is NULL */ __asm uint32_t strLength (const char* src) { // R0: length, return value // R1: src // R2: v = *src MOV R1, R0 // Get variable CMP R1, #0 // if (src{R1} == NULL) MOVEQ R0, #-1 // return -1; BXEQ LR 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} CMP R0, #0 // if (src{R0} == NULL) BEQ pal_false // return false; 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