我有以下程序,它获得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,但你可以看到它没有发生..
答案 0 :(得分:2)
你签名扩展2 ^ 31到64位,这意味着它变成0xffffffff80000000,当除以2(使用无符号算术)时会导致溢出。显然你的输入是无符号的,所以你应该使用零扩展(即只清除edx
)。由此产生预期的输出:
$ ./a.out
Divide : 2147483648 / 2 = 1073741824.00