64-битное разделение носа Idiv - PullRequest
3 голосов
/ 14 января 2012
;print out division message
mov rcx, 0                       ;zero out register
mov rax, [input]
mov rcx, [input2]
idiv rcx                        ;divide rax by rcx
mov rdi, rax                    ;for printing purposes
call print_int

Я не могу понять, почему это не деление, я получаю сообщение об ошибке "Исключение с плавающей точкой" Я использую 64-битный компьютер, и значения являются целыми числами, а не с плавающей точкой ...Идеи?

Я знаю, что после деления частное должно быть в rax, а остальное должно быть в rdx, я верю, но на данный момент я просто пытаюсь получить в свои руки частное.

Ответы [ 2 ]

8 голосов
/ 14 января 2012

Ваша функция выглядит немного сложной для меня. idiv работает, как и ожидалось, с этой функцией:

_mydiv:
  xor  %rdx, %rdx ; clear high bits of dividend
  mov  %rdi, %rax ; copy dividend argument into rax
  idiv %rsi       ; divide by divisor argument
  ret             ; return (quotient is in rax)

В переводе на синтаксис NASM и на окна ABI, я думаю, это будет что-то вроде:

_mydiv:
  mov  r8, rdx    ; copy divisor argument to scratch register
  xor  rdx, rdx   ; clear high bits of dividend
  mov  rax, rcx   ; copy dividend argument into rax
  idiv r8         ; divide by divisor in scratch register
  ret             ; return (quotient is in rax)

Возможно, вы попираете свои параметры и что-то путаете?

Редактировать: глядя на ваш код, мне приходит в голову, что он может вообще не быть написан как правильная функция. Важные шаги:

  1. Поместите дивиденд в RDX: RAX - для вас это, вероятно, означает очистку RDX и помещение входного дивиденда в RAX.
  2. Поместите делитель в какой-то другой регистр - вы выбрали RCX, это должно быть хорошо.
  3. Разделить - idiv rcx.
  4. Результат будет в формате RAX.

Вы должны обратить особое внимание на шаг 1 - убедитесь, что RDX: RAX имеет нормальное содержимое! Почему вы получаете исключение с плавающей запятой, я не могу понять из кода, который вы показали.

1 голос
/ 14 января 2012

Вы на самом деле делите 128-битное число в RDX: RAX на RCX. Поэтому, если RDX не инициализирован, результат, вероятно, будет больше 64-битного, что приведет к исключению переполнения. Попробуйте добавить CQO перед разделением, чтобы подписать расширение RAX в RDX.

Я не могу объяснить бит с плавающей запятой, может быть, кто-то решил повторно использовать вектор прерывания для общих математических ошибок где-то внизу?

...