我正在学习ia-32并且在32位Ubuntu上一切正常,但我切换到64位并开始使用标志-m32,现在我无法在任何地方使用DIV,无论内容如何寄存器,它给我总是浮点异常...而且我确定我没有除以零。我正在使用gcc和gdb。
这是我最接近问题的问题:FPU IA-32 SIGFPE, Arithmetic exception
我试图将指令fldcw与0x220放在一起,但没有区别。
我的源代码:
.section .text
Division:
.int 0x220
str:
.asciz "%d"
.global binario # void binario(int)
binario:
pushl %ebp # prologo
movl %esp,%ebp #
finit
fldcw Division
pushl %ebx
pushl %ecx
pushl %edx
movl 8(%ebp),%eax # param x to eax
cmpl $0,%eax # compare x with 0
je fim # return recursive call
movl $2,%ecx # prepare division
divl %ecx # divide eax with 2
movl $0,%ecx # clean ecx
movb %al,%cl # put division result on cl
pushl %ecx # push x/2
call binario # recursive call
add $8,%esp # clean esp
movl $0,%ecx # clean ecx
movb %ah,%cl # put division rest on cl
pushl %ecx # push division rest
pushl $str # push string
call printf # call printf function
addl $8,%esp # clean esp
fim:
pushl %edx
pushl %ecx
pushl %ebx
movl %ebp,%esp # epilogo
popl %ebp #
ret
GDB日志:
28 divl %ecx # divide eax with 2
2: $ecx = 2
1: $eax = 33
(gdb)
Program received signal SIGFPE, Arithmetic exception.
binario () at ex08.s:28
28 divl %ecx # divide eax with 2
2: $ecx = 2
1: $eax = 33
答案 0 :(得分:3)
+1用于搜索SO并使用调试器,-1用于不读取指令集参考;)
您使用的div r/m32
变体除以edx
(前32位)和eax
(低32位)形成的64位数量。此外,如果结果超出范围,您也会收到此异常。问题是你没有归零edx
因此它有一些随机值导致整个分区溢出。您需要在无符号除法之前清除edx
(零扩展eax
),并在签名除法之前将eax
符号扩展为edx
。
PS:我希望你没有真正使用div
除以2
。要划分或乘以2
的幂,您应该使用班次。