3

我有以下程序,它获取 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,但是你可以看到它没有发生..

4

1 回答 1

2

您将 2^31 符号扩展为 64 位,这意味着它变为 0xffffffff80000000,当除以 2(使用无符号算术)时会导致溢出。显然您的输入是无符号的,因此您应该使用零扩展名(即 clear edx)。这样它就会产生预期的输出:

$ ./a.out
Divide : 2147483648 / 2 = 1073741824.00
于 2012-12-02T23:31:01.040 回答