【发布时间】:2018-10-01 03:26:45
【问题描述】:
我正在尝试将以下程序转换为 x86 程序集 (AT&T)。
#include <stdio.h>
int main()
{
int n = 123;
int reverse = 0;
while (n != 0)
{
reverse = reverse * 10;
reverse = reverse + n%10;
n = n/10;
}
printf("%d\n", reverse);
return 0;
}
应该打印321。
但是,使用下面的代码,我得到的是 0。 任何人都可以告诉我我在这里做错了什么吗? (我只粘贴了下面的相关部分。我确定初始化和打印工作正常。你可以看到the whole thing here)
movl $123, %esi # int n
movl $0, %edi # int reverse
movl $10, %ebx # divisor
L1: # while n != 0
cmpl $0, %esi
je L2
# reverse = reverse * 10
imul $10, %edi
# reverse = reverse + n % 10
movl $0, %edx
movl %edi, %eax
idivl %ebx
addl %edx, %edi
# n = n / 10
movl %esi, %eax
movl $0, %edx
idivl %ebx
movl %eax, %esi
jmp L1
L2: # end while
movl %edi, %eax
也许我还没有完全理解 idivl 命令应该做什么。我知道它将 %edx:%eax 除以 %ebx 并将商存储在 %eax 中,余数存储在 %edx 中。
【问题讨论】:
-
是的,
idivl就是这样工作的。使用调试器单步执行代码,看看哪里出错了。 -
一个令人耳目一新的好问题。
-
一个
idiv给你商和余数;您无需使用相同的输入运行两次。 (哦,我认为这实际上是你的错误;即使你想要n/10和n%10,不使用相同的输入。) -
注意可以使用
xor %reg, %reg设置寄存器为0,这样会比movl $0, %reg快