Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   Программирование и базы данных (http://forum.oszone.net/forumdisplay.php?f=21)
-   -   Деление (http://forum.oszone.net/showthread.php?t=172779)

ManHack 10-04-2010 21:58 1389683

Деление
 
idiv bx => Error: Division by zero
(ax = 65535 [т.е. -1], bx = 1)
В чём проблема? Почему не получается разделить -1 на 1?
Команда idiv bx работает так:
ax = ax div bx
dx = ax mod bx
Получается, что не совсем так?

lxa85 11-04-2010 06:36 1389854

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 11-04-2010 23:56 1390416

Код:

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 12-04-2010 00:55 1390457

Среда разработки 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 12-04-2010 22:53 1391142

Моя программа призвана вычислять выражение (a - b*c)/(b - c), но достаточно разобраться как просто делить -1 на 1 (или что-то подобное), когда деление происходит пары чисел DX:AX?
И всё-таки, что насчёт конструкций вида " idiv eax, eax, ah "? Они вообще реальны? Как они работают и при каких условиях? Что-то толком про такой вариант использования idiv нигде не нашёл, ни у Юрова, ни у Абеля...

DillerInc 13-04-2010 17:07 1391656

Цитата:

Цитата ManHack
И всё-таки, что насчёт конструкций вида " idiv eax, eax, ah "? »

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

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


ManHack 13-04-2010 23:21 1391928

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


Время: 17:25.

Время: 17:25.
© OSzone.net 2001-