|
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
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!"。
|
|