fpu ia-32,浮点异常

时间:2014-11-13 13:39:20

标签: assembly gdb ia-32 sigfpe

我正在学习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

1 个答案:

答案 0 :(得分:3)

+1用于搜索SO并使用调试器,-1用于不读取指令集参考;)

您使用的div r/m32变体除以edx(前32位)和eax(低32位)形成的64位数量。此外,如果结果超出范围,您也会收到此异常。问题是你没有归零edx因此它有一些随机值导致整个分区溢出。您需要在无符号除法之前清除edx(零扩展eax),并在签名除法之前将eax符号扩展为edx

PS:我希望你没有真正使用div除以2。要划分或乘以2的幂,您应该使用班次。