我已经尝试了3个多小时来弄清楚下一个程序出了什么问题。 我所要做的就是将y除以y,然后打印除法的结果和模数。 此外,模数的printf,内部%,混乱。有谁知道如何解决这个问题? 我正在组装IA32。假设我已经从用户那里得到了x和y。
.section .rodata
format1: .string "Div : %d / %d = %d\n"
format2: .string "Mod : %d % %d = %d\n"
.text
.globl main
.type main, @function
# operation divide
movl x, %eax
cltd
idivl y
pushl %eax
pushl y
pushl x
pushl $format1
call printf
# operation modulo
pushl %edx
pushl y
pushl x
pushl $format2
call printf
我知道模数应该保存在%edx寄存器中,为什么它不起作用? 非常感谢! d:
编辑: 好的,所以我在%ebx中保存了%edx,现在模数工作正常。 (如果我打印%edx中的内容,它会给出正确的模数) 但是屏幕上的打印仍然不是我想要的。这是x = 2,y = 4的输出:
Divide : 2 / 4 = 0
Modulo : 2 %d = 4
我希望它看起来像这样:
Divide : 2 / 4 = 0.50
Modulo : 2 % 4 = 2
答案 0 :(得分:2)
EAX,ECX和EDX是调用者保存的寄存器,这意味着你必须在调用printf
之前保存它们,{{1}}可以自由更改任何这些寄存器而无需恢复它们。
答案 1 :(得分:2)
根据System V ABI for Intel386,允许函数使用%ecx
和%edx
作为临时寄存器,并且被调用者不必为调用者保留其值。这意味着,允许printf
覆盖%edx
的值,从而破坏提升者的值。您可以通过将%edx
的值转移到%esi
或%edi
来保存它,根据规范,它们的值必须由被调用者保存(它们“属于”调用者)。
这就是说,format2
中有错误。你应该把它改成:
format2: .string "Mod : %d %% %d = %d\n"
文字%
必须在格式字符串中写为%%
,否则它将被printf
描述为格式说明符。