1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290
| @ assembly_functions.s .section .text
@ 基本数学运算 .global asm_add .global asm_multiply .global asm_divide
asm_add: @ int asm_add(int a, int b) @ 参数:r0 = a, r1 = b @ 返回:r0 = a + b add r0, r0, r1 bx lr
asm_multiply: @ int asm_multiply(int a, int b) @ 参数:r0 = a, r1 = b @ 返回:r0 = a * b mul r0, r0, r1 bx lr
asm_divide: @ int asm_divide(int dividend, int divisor) @ 参数:r0 = dividend, r1 = divisor @ 返回:r0 = dividend / divisor @ 检查除零 cmp r1, #0 moveq r0, #0 bxeq lr @ 使用硬件除法(如果支持) sdiv r0, r0, r1 bx lr
@ 字符串操作 .global asm_strlen .global asm_strcpy .global asm_strcmp
asm_strlen: @ int asm_strlen(const char *str) @ 参数:r0 = str @ 返回:r0 = 字符串长度 mov r1, r0 @ 保存原始指针 strlen_loop: ldrb r2, [r0], #1 @ 加载字符并递增指针 cmp r2, #0 @ 检查是否为空字符 bne strlen_loop sub r0, r0, r1 @ 计算长度 sub r0, r0, #1 @ 减去最后的递增 bx lr
asm_strcpy: @ char* asm_strcpy(char *dest, const char *src) @ 参数:r0 = dest, r1 = src @ 返回:r0 = dest mov r2, r0 @ 保存dest指针 strcpy_loop: ldrb r3, [r1], #1 @ 从src加载字符 strb r3, [r0], #1 @ 存储到dest cmp r3, #0 @ 检查是否为空字符 bne strcpy_loop mov r0, r2 @ 返回dest bx lr
asm_strcmp: @ int asm_strcmp(const char *str1, const char *str2) @ 参数:r0 = str1, r1 = str2 @ 返回:r0 = 比较结果 strcmp_loop: ldrb r2, [r0], #1 @ 从str1加载字符 ldrb r3, [r1], #1 @ 从str2加载字符 cmp r2, r3 @ 比较字符 bne strcmp_diff @ 不相等则跳转 cmp r2, #0 @ 检查是否到达字符串末尾 bne strcmp_loop mov r0, #0 @ 字符串相等 bx lr strcmp_diff: sub r0, r2, r3 @ 返回差值 bx lr
@ 内存操作 .global asm_memcpy .global asm_memset .global asm_memcmp
asm_memcpy: @ void* asm_memcpy(void *dest, const void *src, size_t n) @ 参数:r0 = dest, r1 = src, r2 = n @ 返回:r0 = dest push {r4, lr} mov r3, r0 @ 保存dest指针 @ 优化:按字复制(如果对齐) orr r4, r0, r1 tst r4, #3 @ 检查4字节对齐 bne memcpy_byte @ 不对齐则按字节复制 @ 按字复制 cmp r2, #4 blt memcpy_byte memcpy_word_loop: ldr r4, [r1], #4 str r4, [r0], #4 sub r2, r2, #4 cmp r2, #4 bge memcpy_word_loop @ 复制剩余字节 memcpy_byte: cmp r2, #0 ble memcpy_done memcpy_byte_loop: ldrb r4, [r1], #1 strb r4, [r0], #1 subs r2, r2, #1 bne memcpy_byte_loop memcpy_done: mov r0, r3 @ 返回dest pop {r4, lr} bx lr
asm_memset: @ void* asm_memset(void *s, int c, size_t n) @ 参数:r0 = s, r1 = c, r2 = n @ 返回:r0 = s push {r4, lr} mov r3, r0 @ 保存s指针 @ 扩展字节到字 and r1, r1, #0xFF @ 确保c是字节值 orr r1, r1, r1, lsl #8 orr r1, r1, r1, lsl #16 @ 按字设置(如果对齐) tst r0, #3 bne memset_byte cmp r2, #4 blt memset_byte memset_word_loop: str r1, [r0], #4 sub r2, r2, #4 cmp r2, #4 bge memset_word_loop @ 设置剩余字节 memset_byte: cmp r2, #0 ble memset_done memset_byte_loop: strb r1, [r0], #1 subs r2, r2, #1 bne memset_byte_loop memset_done: mov r0, r3 pop {r4, lr} bx lr
asm_memcmp: @ int asm_memcmp(const void *s1, const void *s2, size_t n) @ 参数:r0 = s1, r1 = s2, r2 = n @ 返回:r0 = 比较结果 cmp r2, #0 moveq r0, #0 bxeq lr memcmp_loop: ldrb r3, [r0], #1 ldrb r12, [r1], #1 cmp r3, r12 bne memcmp_diff subs r2, r2, #1 bne memcmp_loop mov r0, #0 @ 内存块相等 bx lr memcmp_diff: sub r0, r3, r12 @ 返回差值 bx lr
@ 位操作 .global asm_popcount .global asm_ffs .global asm_reverse_bits
asm_popcount: @ int asm_popcount(uint32_t value) @ 计算value中1的个数 @ 参数:r0 = value @ 返回:r0 = 1的个数 mov r1, #0 @ 计数器 popcount_loop: cmp r0, #0 beq popcount_done @ 清除最低位的1 sub r2, r0, #1 and r0, r0, r2 add r1, r1, #1 b popcount_loop popcount_done: mov r0, r1 bx lr
asm_ffs: @ int asm_ffs(uint32_t value) @ 找到第一个设置的位(从1开始计数) @ 参数:r0 = value @ 返回:r0 = 位位置(0表示没有设置的位) cmp r0, #0 moveq r0, #0 bxeq lr @ 使用CLZ指令优化 rsb r1, r0, #0 @ -value and r0, r0, r1 @ value & (-value) clz r0, r0 @ 计算前导零 rsb r0, r0, #32 @ 32 - clz bx lr
asm_reverse_bits: @ uint32_t asm_reverse_bits(uint32_t value) @ 反转32位中的位顺序 @ 参数:r0 = value @ 返回:r0 = 反转后的值 @ 使用RBIT指令(如果支持) rbit r0, r0 bx lr
@ 系统级操作 .global asm_enable_interrupts .global asm_disable_interrupts .global asm_get_cpsr .global asm_set_cpsr
asm_enable_interrupts: @ void asm_enable_interrupts(void) mrs r0, cpsr bic r0, r0, #0x80 @ 清除I位 msr cpsr_c, r0 bx lr
asm_disable_interrupts: @ void asm_disable_interrupts(void) mrs r0, cpsr orr r0, r0, #0x80 @ 设置I位 msr cpsr_c, r0 bx lr
asm_get_cpsr: @ uint32_t asm_get_cpsr(void) mrs r0, cpsr bx lr
asm_set_cpsr: @ void asm_set_cpsr(uint32_t cpsr) msr cpsr, r0 bx lr
|