Я изучаю ia-32, и все было хорошо на 32-битном Ubuntu, но я переключился на 64-битный и начал использовать флаг -m32, и теперь я не могу использовать DIV где угодно, нет это вопрос содержания регистров, он всегда дает исключение с плавающей запятой ... И я уверен, что я не делю на ноль. Я использую gcc и gdb.fpu ia-32, исключение с плавающей запятой
Это самый близкий вопрос к моей проблеме: 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
Да! Он работал путем обнуления edx. И да, сначала я использовал смены, но тогда мне понадобилась остальная часть деления, чтобы преобразовать int в двоичный файл, так что мне нужно% ах. Я слишком мало читаю из набора команд T.T, это правда. Мне стыдно. – Vcoder
'SHR' возвращает сдвинутый бит в флагом переноса (' CF'). Также вы можете получить LSB перед сменой маскировки. Для двоичного преобразования вы можете просто использовать shift left, чтобы получить бит в правильном порядке без какой-либо рекурсии и т. Д. – Jester