2012-01-13 4 views
3
;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 

Я не могу показаться, чтобы выяснить, почему это не деля, я получаю enrror «плавающей точкой Exception» Я использую 64-битную машину и значения являются целыми числами, не плавающие точка .... идеи?64bit NASM подразделение IDIV

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

+0

Возможный дубликат [nasm x86-64 bit division] (http://stackoverflow.com/questions/8845191/nasm-x86-64-bit-division) –

ответ

7

Ваша функция выглядит немного сложнее для меня. 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 имеет нормальное содержание! Почему вы получаете исключение с плавающей запятой, которое я не могу угадать из кода, который вы указали.

+0

, а именно, много, я не расчищал регистрацию rdx раньше, спасибо много !!! – user1050632

+0

Почему вы используете r8 в nasm? это необходимо? – Nande

+1

@Nande, а не для NASM, но чтобы быть правильным для окон abi, где rdx является регистром передачи параметров. –

1

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

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

+0

Для справок в будущем, где можно найти инструкции типа 'cqo '? В синтаксисе GAS это 'cqto', и не ясно, что он должен преобразовать в синтаксис MASM. – Vortico

+0

@ Vortico: [Руководство по архитектуре Intel] (http://www.intel.com/content/www/us/en/processors/architectures-software-developer-manuals.html) - всегда хорошее начало. Что касается CQO, то я признаюсь, что не знал подходящего суффикса для 128-битного слова, но мне пришлось искать CBW/CWD/CDQ, чтобы узнать, что такое 64-разрядный эквивалент можно назвать – doynax

Смежные вопросы