尝试在 at&t 程序集中编写 strcpy,没有输出
Trying to write strcpy in assembly at&t, no output
我正在尝试用汇编、at&t 语法编写 char *my_strcpy(char *dest, const char *source);
,它应该与 C 中的 strcpy 完全一样。我的 c 文件如下所示:
.globl my_strcpy
my_strcpy:
push %rbp
mov %rsp, %rbp
mov %rdi, %rax
jmp copy_loop
跳转毫无意义
copy_loop:
cmp [=11=], (%rsi)
您没有指定这应该是 8、16、32 还是 64 位比较。当我 assemble 它时,我得到一个 32 位比较;例如它查看地址 %rsi
处的 32 位字是否为零。您需要将其更改为 cmpb [=17=], (%rsi)
.
je end
mov %rsi, %rdi
正如用户 500 所指出的,这会将 %rsi
寄存器中的地址复制到 %rdi
寄存器中,并覆盖它。这不是你想要的。你可能想要像 movb (%rsi), (%rdi)
这样的指令,但实际上不存在这样的指令:x86 没有这样一条指令来将内存移动到内存(特殊例外:参见 movsb
指令)。因此,您需要先将地址 %rsi
处的字节复制到寄存器中,然后使用另一条指令将其向前复制,例如mov (%rsi), %cl ; mov %cl, (%rdi)
。请注意,使用 8 位 %cl
寄存器可以清楚地表明这些应该是一个字节的移动。
movzbl (%rsi), %ecx
是在现代 x86 上加载字节的更有效方式。您仍然通过使用 mov %cl, (%rdi)
读取 CL 来存储它,但是覆盖整个 RCX 而不是合并到 RCX 中更好。
addq , %rsi
addq , %rdi
您可能想了解 inc
指令,但 add
没问题。
je copy_loop
我想你的意思是jmp copy_loop
,因为这里的跳转应该是无条件发生的。 (或者你应该重新安排你的循环,这样条件分支就可以在底部。因为你想复制终止 0
字节,你可以只复制然后 然后 检查 0 , 比如 do{}while(c != 0)
)
end:
leave
ret
我正在尝试用汇编、at&t 语法编写 char *my_strcpy(char *dest, const char *source);
,它应该与 C 中的 strcpy 完全一样。我的 c 文件如下所示:
.globl my_strcpy
my_strcpy:
push %rbp
mov %rsp, %rbp
mov %rdi, %rax
jmp copy_loop
跳转毫无意义
copy_loop:
cmp [=11=], (%rsi)
您没有指定这应该是 8、16、32 还是 64 位比较。当我 assemble 它时,我得到一个 32 位比较;例如它查看地址 %rsi
处的 32 位字是否为零。您需要将其更改为 cmpb [=17=], (%rsi)
.
je end
mov %rsi, %rdi
正如用户 500 所指出的,这会将 %rsi
寄存器中的地址复制到 %rdi
寄存器中,并覆盖它。这不是你想要的。你可能想要像 movb (%rsi), (%rdi)
这样的指令,但实际上不存在这样的指令:x86 没有这样一条指令来将内存移动到内存(特殊例外:参见 movsb
指令)。因此,您需要先将地址 %rsi
处的字节复制到寄存器中,然后使用另一条指令将其向前复制,例如mov (%rsi), %cl ; mov %cl, (%rdi)
。请注意,使用 8 位 %cl
寄存器可以清楚地表明这些应该是一个字节的移动。
movzbl (%rsi), %ecx
是在现代 x86 上加载字节的更有效方式。您仍然通过使用 mov %cl, (%rdi)
读取 CL 来存储它,但是覆盖整个 RCX 而不是合并到 RCX 中更好。
addq , %rsi
addq , %rdi
您可能想了解 inc
指令,但 add
没问题。
je copy_loop
我想你的意思是jmp copy_loop
,因为这里的跳转应该是无条件发生的。 (或者你应该重新安排你的循环,这样条件分支就可以在底部。因为你想复制终止 0
字节,你可以只复制然后 然后 检查 0 , 比如 do{}while(c != 0)
)
end:
leave
ret