|
@@ -28,14 +28,17 @@ |
|
|
|
|
|
|
|
|
/*! |
|
|
/*! |
|
|
* String length calculation. |
|
|
* String length calculation. |
|
|
* @arg R0: Pointer to string |
|
|
|
|
|
* @return R0: String length (unsigned) |
|
|
|
|
|
|
|
|
* @arg src{R0} Pointer to string |
|
|
|
|
|
* @return {R0} String length, -1 if src is NULL |
|
|
*/ |
|
|
*/ |
|
|
__asm uint32_t strLength (const char* src) { |
|
|
__asm uint32_t strLength (const char* src) { |
|
|
// R0: length, return value |
|
|
// R0: length, return value |
|
|
// R1: src |
|
|
// R1: src |
|
|
// R2: v = *src |
|
|
// R2: v = *src |
|
|
MOV R1, R0 // Get variable |
|
|
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; |
|
|
MOV R0, #0 // length{R0} =0; |
|
|
len_loop // do { |
|
|
len_loop // do { |
|
|
LDRB R2, [R1], #1 // v{R2} = *src++; |
|
|
LDRB R2, [R1], #1 // v{R2} = *src++; |
|
@@ -62,6 +65,8 @@ __asm uint32_t isPalindrome (const char* src) { |
|
|
// R3: v1 = src[i] |
|
|
// R3: v1 = src[i] |
|
|
// R4: v2 = src[j] |
|
|
// R4: v2 = src[j] |
|
|
PUSH {R4, LR} |
|
|
PUSH {R4, LR} |
|
|
|
|
|
CMP R0, #0 // if (src{R0} == NULL) |
|
|
|
|
|
BEQ pal_false // return false; |
|
|
MOV R4, R0 // save R0 |
|
|
MOV R4, R0 // save R0 |
|
|
BL strLength // j{R2} = strLength(src) - 1 |
|
|
BL strLength // j{R2} = strLength(src) - 1 |
|
|
SUB R2, R0, #1 |
|
|
SUB R2, R0, #1 |
|
@@ -77,7 +82,7 @@ pal_loop |
|
|
ADDEQ R1, R1, #1 // ++i; |
|
|
ADDEQ R1, R1, #1 // ++i; |
|
|
SUBEQ R2, R2, #1 // --j; |
|
|
SUBEQ R2, R2, #1 // --j; |
|
|
BEQ pal_loop // // goto loop; |
|
|
BEQ pal_loop // // goto loop; |
|
|
// } else |
|
|
|
|
|
|
|
|
pal_false // } else |
|
|
MOV R0, #0 // return *RESULT = 0; |
|
|
MOV R0, #0 // return *RESULT = 0; |
|
|
LDR R1, =RESULT |
|
|
LDR R1, =RESULT |
|
|
STRB R0, [R1] |
|
|
STRB R0, [R1] |
|
@@ -91,14 +96,20 @@ pal_true |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
/*! |
|
|
/*! |
|
|
* Main routine |
|
|
|
|
|
|
|
|
* Main routine. |
|
|
|
|
|
* @note |
|
|
|
|
|
* This routine plays the role of debuging-mode unit testing. |
|
|
*/ |
|
|
*/ |
|
|
int main(void) { |
|
|
int main(void) { |
|
|
const char *s1 = "hello world!"; // Not a palindrome |
|
|
const char *s1 = "hello world!"; // Not a palindrome |
|
|
const char *s2 = "aibohphobia"; // Aibophobia def= "Fear of palindromes", palindrome. |
|
|
|
|
|
|
|
|
const char *s2 = "aibohphobia"; // Aibophobia def= "Irational fear of palindromes", palindrome. |
|
|
|
|
|
const char *s3 = ""; // Empty string, palindrome. |
|
|
|
|
|
const char *s4 = 0; // NULL pointer. Out of scope, not palindrome |
|
|
|
|
|
|
|
|
uint32_t res1 = isPalindrome (s1); // Test case 1 |
|
|
uint32_t res1 = isPalindrome (s1); // Test case 1 |
|
|
uint32_t res2 = isPalindrome (s2); // Test case 2 |
|
|
uint32_t res2 = isPalindrome (s2); // Test case 2 |
|
|
|
|
|
uint32_t res3 = isPalindrome (s3); // Test case 3 |
|
|
|
|
|
uint32_t res4 = isPalindrome (s4); // Test case 4 |
|
|
|
|
|
|
|
|
while (1); // Trap forever |
|
|
while (1); // Trap forever |
|
|
//return 0; //!< comment out return, to suppress "statement is unreachable" warning. |
|
|
//return 0; //!< comment out return, to suppress "statement is unreachable" warning. |
|
|