程序集max int divide

时间:2012-12-02 22:28:13

标签: c++ c assembly x86

我有以下程序,它获得2个无符号长数(%u),x和y, 然后将x除以y并以此格式打印结果:仅限X.YZ。

它适用于所有常规输入,例如:3/4 = 0.75,10 / 5 = 2.00,19 / 1000 = 0.01,依此类推。 但是当我尝试2 ^ 31/2时,我得到一个“核心转储”错误。 (2 ^ 31 = 2147483648)。

任何想法为什么?我猜我在某个地方得到了垃圾值,但无法弄清楚在哪里和为什么。

format: .string "Divide : %u / %u = %u.%.2d\n"

# operation divide
movl    %ebx,   %eax    #%eax=x
cltd    #sign extend eax to edx
divl    %esi    #x=x/y
pushl   %eax    #save %eax on stack
movl    %edx,   %eax    #%eax=xmody
cltd    #sign extend eax to edx
movl    $100,   %ecx    #%ecx=100
mull    %ecx    #multiply xmody by 100
divl    %esi    #divide by y
movl    %eax,   %edx
popl    %eax

pushl   %edx
pushl   %eax    #push x/y
pushl   %esi    #push y
pushl   %ebx    #push x
pushl   $format
call    printf

非常感谢! :d

编辑: 为了澄清,我希望1073741824(这是除法的结果)在%eax上,并且由于2147483648除以2,模数应为0。

所以在结果中我应该得到:1073741824.00,但你可以看到它没有发生..

1 个答案:

答案 0 :(得分:2)

你签名扩展2 ^ 31到64位,这意味着它变成0xffffffff80000000,当除以2(使用无符号算术)时会导致溢出。显然你的输入是无符号的,所以你应该使用零扩展(即只清除edx)。由此产生预期的输出:

$ ./a.out
Divide : 2147483648 / 2 = 1073741824.00