Почему процедура вызывает исключение в операции с плавающей точкой?
Пытаюсь получить из unix-времени отдельно секунды, минуты, часы, день, месяц и год, но моя процедура вызывает исключение в операции с плавающей точкой. Помогите исправить. Вот код процедуры
section .seconds_to_date
seconds_to_date:
push eax
push ebx
push ecx
push edx
mov ebx, 60
div ebx ; eax - minutes
mov [seconds], edx ; seconds
div ebx ; hours
mov [minutes], edx ; minutes
mov ebx, 24
div ebx ; eax - days (целое по идее)
mov ebx, 30
div ebx ; eax - month
mov [day], edx
mov ebx, 12
div ebx ; eax number of years
mov [month], edx
mov ebx, 1970
add eax, ebx ; year
mov [year], eax
pop edx
pop ecx
pop ebx
pop eax
ret
Ответы (1 шт):
SIGFPE, вопреки названию, обычно посылается не из-за операции с плавающей точкой, а из-за деления на ноль/переполнения при целочисленном делении. В данном случае здесь второе. И большинство оболочек при этом выводят сильно путающее сообщение «Исключение в операции с плавающей точкой». Это старый известный квирк сложившийся по мутным историческим причинам.
С точки зрения x86 инструкция div делит 64-битное число в регистрах edx:eax, а 32-х битное частное помещается в eax, а остаток в ebx. Если частное не влезает в 32-х битный регистр, то кидается исключение #DE (INT 0, Divide Error, Ошибка Деления), собственно оно же кидается и при делении на ноль.
По коду, собственно скорей всего перед вызовом функции ты не инициализируешь edx и явно не обнуляешь его при повторном делении. Ну и в довершении ко всему при вычислении дней/месяцев ты какую-то откровенную ерунду творишь.