C 组装模

C 组装模,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

我已经试了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    
    .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之前,您没有清除堆栈,也没有保存寄存器。