Assm - Деление

Ответить
Аватара пользователя
ManHack

Assm - Деление

Сообщение ManHack »

idiv bx => Error: Division by zero

(ax = 65535 [т.е. -1], bx = 1)

В чём проблема? Почему не получается разделить -1 на 1?

Команда idiv bx работает так:

ax = ax div bx

dx = ax mod bx

Получается, что не совсем так?
Аватара пользователя
lxa85

Re: Assm - Деление

Сообщение lxa85 »

ManHack, а можно весь кусок кода?

Операция idiv документация Intel


Все, нашел ошибку!

При делении на BX(а BX - это слово) Операнд(т.е. делимое) должно быть двойным словом.

Т.е. находится в DX:AX

Тогда будет возможно деление в пределах -32,768 / +32,767

Что содержит DX до начала операции?



Кусок из
Питера Абеля



читать дальше »




BYTE1 DB 80H ;Data items

BYTE2 DB 16H

WORD1 DW 2000H

WORD2 DW 0010H

WORD3 DW 1000H

;--------------

E10IDIV PROC

MOV AX,WORD1 ;Слово / байт

IDIV BYTE1 ; остаток:частное в AH:AL

MOV AL,BYTE1 ;Байт / байт

CBW ; расширить делимое в AH

IDIV BYTE3 ; остаток:частное в AH:AL



MOV DX,WORD2 ;Двойное слово / слово

MOV AX,WORD3 ; делимое в DX:AX

IDIV WORD1 ; остаток:частное в DX:AX



MOV AX,WORD1 ;Слово / слово

CWD ; расширить делимое в DX

IDIV WORD3 ; остаток:частное в DX:AX

RET

E10DIV ENDP





Что за среда разработки? Фраза "деление на ноль" все же настораживает. Т.е. ИМХО сигнализируется неправильная ошибка.
Аватара пользователя
ManHack

Re: Assm - Деление

Сообщение ManHack »

Код:

Код: Выделить всё

var
   a, b, c, ans : integer;
begin
   readln(a, b, c);
   asm
      mov bx, b
      mov ax, c
      imul bx
      neg ax
      mov cx, a
      add ax, cx
      mov cx, c
      sub bx, cx
      idiv bx
      mov ans, ax
   end;
   writeln('Value = ', ans);
   readln;
end.

dx на момент выполнения команды idiv содержит ноль.



Среда Turbo Assembler (ассемблер для Intel-совместимых, втроенный в Turbo Pascal 7.0)



Т.е. всегда делится содержимое пары DX:AX на BX?

Или в каких-то случаях делится только содержимое AX на BX? (в каких?)

А каким образом вообще производится деление пары?

Допустим, в AX у меня записано 12, а в DX записано 7, что тогда будет в BX?

А что будет в BX, если в DX записано 65535, а в AX, допустим, 3?

Мне просто интересно как формируется одно число из этой пары DX:AX.



А ещё я видел, что некоторые пишут три регистра после idiv. Например, так:

idiv eax, eax, ah

У меня среда ругается, если я записываю больше одного слова.

Как объясняется этот феномен?
Аватара пользователя
lxa85

Re: Assm - Деление

Сообщение lxa85 »

Среда разработки Lazarus. Все выполнилось не чихнув.

Давай смотреть входные данные.

BTW, а проще конструкции задать нельзя? Больно много действий перед idiv, что усложняет подготовку тестов.



Код:

Код: Выделить всё

program Project1;
{$mode objfpc}{$H+}
uses
  Classes, SysUtils
  { you can add units after this };
var
   a, b, c, ans : integer;
{$IFDEF WINDOWS}{$R Project1.rc}{$ENDIF}
{$ASMMODE intel}
begin
//   readln(a, b, c);
a:=1;b:=2;c:=7;
   asm
      mov bx, b
      mov ax, c
      imul bx
      neg ax
      mov cx, a
      add ax, cx
      mov cx, c
      sub bx, cx
      idiv bx
      mov ans, ax
   end;
end.
Аватара пользователя
ManHack

Re: Assm - Деление

Сообщение ManHack »

Моя программа призвана вычислять выражение (a - b*c)/(b - c), но достаточно разобраться как просто делить -1 на 1 (или что-то подобное), когда деление происходит пары чисел DX:AX?

И всё-таки, что насчёт конструкций вида " idiv eax, eax, ah "? Они вообще реальны? Как они работают и при каких условиях? Что-то толком про такой вариант использования idiv нигде не нашёл, ни у Юрова, ни у Абеля...
Аватара пользователя
DillerInc

Re: Assm - Деление

Сообщение DillerInc »

Цитата ManHack:



И всё-таки, что насчёт конструкций вида " idiv eax, eax, ah "?
Assm - Деление




...такой конструкции нет.Подобная есть только для умножения.

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



Код:

Код: Выделить всё

asm
  mov     eax, -1 ; Загружаем в EAX делимое
  cdq                  ; Заполняем EDX знаковым битом регистра EAX
  mov     ecx, 01 ; Загружаем в ECX делитель
  idiv      ecx       ; Делим
end;
Результат:
EAX == -1
EDX == остаток от деления == 0
Аватара пользователя
ManHack

Re: Assm - Деление

Сообщение ManHack »

Необходимость исходит в виде требований свыше ничего кроме ax, bx, cx и dx не использовать ^^

Но за код спасибо. Теперь я знаю, что мне нужна команда cwd.
Ответить

Вернуться в «Программирование и базы данных»