fpu ia-32, исключение с плавающей точкой
Я изучаю ia-32, и на 32-битной Ubuntu все шло нормально, но я перешел на 64-битную и начал использовать флаг -m32, и теперь я не могу использовать DIV где угодно, независимо от содержимого регистров, это дает мне всегда Исключение с плавающей точкой... И я уверен, что я не делю на ноль. Я использую GCC и GDB.
Это самый близкий вопрос к моей проблеме: FPU IA-32 SIGFPE, Арифметическое исключение
Я пытался поставить инструкцию 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 ответ
+1 для поиска SO и использования отладчика, -1 для не чтения ссылки на набор команд;)
div r/m32
Используемый вариант делит 64-битное количество, образованное из edx
(верхние 32 бита) и eax
(младшие 32 бита). Кроме того, вы также получите это исключение, если ваш результат выходит за пределы допустимого диапазона. Проблема в том, что вы не обнуляете edx
таким образом, он имеет случайное значение, которое вызывает переполнение всего деления. Вам нужно очистить edx
(Нуль-расширение eax
) перед беззнаковым делением и подписать-продлить eax
в edx
перед подписанным делением.
PS: я надеюсь, что вы на самом деле не используете div
делить на 2
, Делить или умножать на степени 2
Вы должны использовать смены.