|
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
下面是一段用c语言实现字符串的插入的程序,目的是在字符串s中的位置pos上插入字符c
- #include <stdio.h>
- #include <string.h>
- void my_strinsert(char* s, char c, unsigned int pos)
- {
- int i = 0;
- if (pos >= 0 && pos <= strlen(s))
- {
- for (i = strlen(s); i >= pos; i--)
- {
- *(s + i + 1) = *(s + i);
- }
- *(s + pos) = c;
- }
- }
- int main(void)
- {
- char s1[20] = "Hello World!";
- char s2[20] = "Hello BUPT";
- my_strinsert(s1, 'X', 4); // s becomes "HellXo World!"
- my_strinsert(s2, 'F', 6);
- //printf("%s", s1);
- //printf("%s", s2);
- return 0;
- }
复制代码
现在想要把它的函数void my_strinsert(char* s, char c, unsigned int pos)转换为ARM汇编语言的形式,如下:
- #include <stdint.h>
- __asm void my_strinsert(char *s, char c, unsigned int pos)
- {
- push {r4, lr} //保存寄存器
- mov r4, r0 //将指针 s 存储到寄存器 r4 中
- ldrb r2, [r1] //读取字符 c 到寄存器 r2
- //mov r2, r1
- mov r3, #0 //将寄存器 r3 初始化为 0
- loop
- ldrb r0, [r4, r3] //从位置 r3 读取字符到寄存器 r0
- cmp r3, r2 //比较当前位置 r3 和插入位置 r2 的大小
- bge insert //如果当前位置 r3 大于等于插入位置 r2,则跳转到插入字符的代码
- add r3, r3, #1 //如果当前位置 r3 小于插入位置 r2,则将 r3 加 1
- b loop //跳转到循环开始位置
- insert
- strb r2, [r4, r3] //将字符 c 存储到位置 r3
- add r3, r3, #1 //将 r3 加 1
- ldrb r0, [r4, r3] //从位置 r3 读取字符到寄存器 r0
- strb r0, [r4, r3] //将字符存储到位置 r3+1
- b end //跳转到结束位置
- end
- pop {r4, pc} //恢复寄存器并跳回
- }
- int main(void)
- {
- char s[20] = "Hello World!";
- my_strinsert(s, 'X', 4); // s becomes "HellXo World!"
-
- while (1);
- }
复制代码
但是为什么最后的结果输出还是"Hello World!",并没有实现将字符'X'插入,这是那个步骤出了问题呢?
在将原始字符串向后移动时,我没有正确地从字符串末尾开始。
以下是修改后的ARM汇编代码:
- #include <stdint.h>
- __asm void my_strinsert(char *s, char c, unsigned int pos)
- {
- push {r4, r5, lr} //保存寄存器
- mov r4, r0 //将指针 s 存储到寄存器 r4 中
- mov r2, r1 //将字符 c 存储到寄存器 r2
- mov r1, r3 //将插入位置 pos 存储到寄存器 r1
- mov r3, #0 //将寄存器 r3 初始化为 0
- find_end
- ldrb r0, [r4, r3] //从位置 r3 读取字符到寄存器 r0
- cmp r0, #0 //比较寄存器 r0 中的字符是否为 '\0'(字符串终结符)
- addne r3, r3, #1 //如果不是,则将 r3 加 1
- bne find_end //跳转到循环开始位置
- move_back
- cmp r3, r1 //比较当前位置 r3 和插入位置 r1 的大小
- blt insert //如果当前位置 r3 小于插入位置 r1,则跳转到插入字符的代码
- ldrb r0, [r4, r3] //从位置 r3 读取字符到寄存器 r0
- add r5, r3, #1 //计算目标位置:r5 = r3 + 1
- strb r0, [r4, r5] //将字符存储到目标位置
- sub r3, r3, #1 //将 r3 减 1
- b move_back //跳转到循环开始位置
- insert
- strb r2, [r4, r1] //将字符 c 存储到位置 r1
- b end //跳转到结束位置
- end
- pop {r4, r5, pc} //恢复寄存器并跳回
- }
- int main(void)
- {
- char s[20] = "Hello World!";
- my_strinsert(s, 'X', 4); // s becomes "HellXo World!"
- while (1);
- }
复制代码
这次,我将 find_end 循环中的 addne 指令更改为 addne r3, r3, #1,以便在字符串末尾之后(包括空字符)停止循环。
这将确保我们从字符串末尾(包括空字符)开始,将每个字符向后移动一位,直到达到插入位置。
现在,这个代码应该能够正确地将字符 'X' 插入到字符串 "Hello World!" 的第 4 个位置,并输出 "HellXo World!"。
|
|