A palindrome implementation and testing application for A.U.TH. Microprocessors and peripherals Lab.
Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.
 
 
 

109 linhas
3.2 KiB

  1. /*!
  2. * @file
  3. * main.c
  4. * @brief
  5. * A palindrome implementation and testing application
  6. * for A.U.TH. Microprocessors and peripherals Lab.
  7. *
  8. * Created on: May 1, 2020
  9. * Author: Christos Choutouridis AEM: 8997
  10. * email : <cchoutou@ece.auth.gr>
  11. */
  12. #include <stdint.h>
  13. /*!
  14. * The RAM address to use for palindrome result.
  15. * @note:
  16. * Select a RAM location above `__initial_sp`. See your startup_xx.s for details.
  17. * Keil's RAM layout is:
  18. *
  19. * RAM: |<-Heap_Size-><-Stack_Size->|<- WASTED RAM SPACE ->|
  20. * ^ ^ ^
  21. * | | |
  22. * Start:0x20000000 __initial_sp End of RAM
  23. *
  24. */
  25. #define RESULT 0x20001000
  26. /*!
  27. * String length calculation.
  28. * @arg R0: Pointer to string
  29. * @return R0: String length (unsigned)
  30. */
  31. __asm uint32_t strLength (const char* src) {
  32. // R0: length, return value
  33. // R1: src
  34. // R2: v = *src
  35. MOV R1, R0 // Get variable
  36. MOV R0, #0 // length{R0} =0;
  37. len_loop // do {
  38. LDRB R2, [R1], #1 // v{R2} = *src++;
  39. CMP R2, #0 // if(v)
  40. ADDNE R0, R0, #1 // ++length{R0};
  41. BNE len_loop // } while (v);
  42. BX LR // return length;
  43. }
  44. /*!
  45. * A string palindrome predicate.
  46. * @note
  47. * We use a simple O(n), no stack algorithm.
  48. * @note
  49. * This function also writes to RAM address @ref RESULT the return value (which is nasty).
  50. * @arg R0: Pointer to string
  51. * @return R0: True if predicate
  52. * False if not
  53. */
  54. __asm uint32_t isPalindrome (const char* src) {
  55. // R0: src[]
  56. // R1: i
  57. // R2: j
  58. // R3: v1 = src[i]
  59. // R4: v2 = src[j]
  60. PUSH {R4, LR}
  61. MOV R4, R0 // save R0
  62. BL strLength // j{R2} = strLength(src) - 1
  63. SUB R2, R0, #1
  64. MOV R0, R4 // src{R0}
  65. MOV R1, #0 // i{R1} =0;
  66. pal_loop
  67. CMP R1, R2 // while (i<j) {
  68. BGE pal_true
  69. LDRB R3, [R0, R1] // v1 = *src[i];
  70. LDRB R4, [R0, R2] // v2 = *src[j];
  71. CMP R3, R4 // if (v1 == v2) {
  72. ADDEQ R1, R1, #1 // ++i;
  73. SUBEQ R2, R2, #1 // --j;
  74. BEQ pal_loop // // goto loop;
  75. // } else
  76. MOV R0, #0 // return *RESULT = 0;
  77. LDR R1, =RESULT
  78. STRB R0, [R1]
  79. POP {R4, PC}
  80. // }
  81. pal_true
  82. MOV R0, #1 // return *RESULT = 1;
  83. LDR R1, =RESULT
  84. STRB R0, [R1]
  85. POP {R4, PC}
  86. }
  87. /*!
  88. * Main routine
  89. */
  90. int main(void) {
  91. const char *s1 = "hello world!"; // Not a palindrome
  92. const char *s2 = "aibohphobia"; // Aibophobia def= "Fear of palindromes", palindrome.
  93. uint32_t res1 = isPalindrome (s1); // Test case 1
  94. uint32_t res2 = isPalindrome (s2); // Test case 2
  95. while (1); // Trap forever
  96. //return 0; //!< comment out return, to suppress "statement is unreachable" warning.
  97. //!^ @note:
  98. //! **Weird** Keil's way for "statement is unreachable", suppresion.
  99. }