C 组装模
我已经试了3个多小时来找出下一个程序的问题。 我要做的就是把x除以y,然后打印除法的结果和模。 此外,模的printf(内部为%)会把一切搞砸。有人知道如何解决这个问题吗? 我在做IA32的装配。假设我已经从用户那里得到了x和yC 组装模,c,assembly,modulo,C,Assembly,Modulo,我已经试了3个多小时来找出下一个程序的问题。 我要做的就是把x除以y,然后打印除法的结果和模。 此外,模的printf(内部为%)会把一切搞砸。有人知道如何解决这个问题吗? 我在做IA32的装配。假设我已经从用户那里得到了x和y .section .rodata format1: .string "Div : %d / %d = %d\n" format2: .string "Mod : %d % %d = %d\n" .text .globl main
.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
EAX、ECX和EDX是调用方保存的寄存器,这意味着在调用
printf
之前,您必须保存它们,而printf可以在不恢复它们的情况下随意更改任何这些寄存器
另一方面,EBX、ESI和EDI是被调用方保存的,这意味着每个函数都需要在调用之前将它们恢复到原始内容。根据,函数可以使用%ecx
和%edx
作为暂存寄存器,被调用方不必为调用方保留其值。这意味着,printf
可以覆盖%edx
的值,从而破坏reminer的值。您可以通过将%edx
的值传输到%esi
或%edi
来保存它,根据规范,它们的值必须由被调用方保留(它们“属于”调用方)
也就是说,您在格式2中有一个错误。您应该将其更改为:
format2: .string "Mod : %d %% %d = %d\n"
文字%%
必须以格式字符串的形式写入%%
,否则它将被printf
解释为格式说明符,可能printf正在更改寄存器的内容。我不这么认为,我尝试了其他操作数,如乘法,效果很好。输入是什么,当前输出是什么,预期的输出是什么?在调用printf之前,您没有清除堆栈,也没有保存寄存器。