Показать полную графическую версию : Деление
idiv bx => Error: Division by zero
(ax = 65535 [т.е. -1], bx = 1)
В чём проблема? Почему не получается разделить -1 на 1?
Команда idiv bx работает так:
ax = ax div bx
dx = ax mod bx
Получается, что не совсем так?
ManHack, а можно весь кусок кода?
Операция idiv документация Intel (http://www.intel.com/software/products/documentation/vlin/mergedprojects/analyzer_ec/mergedprojects/reference_olh/mergedProjects/instructions/instruct32_hh/vc135.htm)
Все, нашел ошибку!
При делении на BX(а BX - это слово) Операнд(т.е. делимое) должно быть двойным словом.
Т.е. находится в DX:AX
Тогда будет возможно деление в пределах -32,768 / +32,767
Что содержит DX до начала операции?
Кусок из Питера Абеля (http://www.lib.ru/CTOTOR/IBMPC/abel.txt)
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
Что за среда разработки? Фраза "деление на ноль" все же настораживает. Т.е. ИМХО сигнализируется неправильная ошибка.
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
У меня среда ругается, если я записываю больше одного слова.
Как объясняется этот феномен?
Среда разработки 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.
Моя программа призвана вычислять выражение (a - b*c)/(b - c), но достаточно разобраться как просто делить -1 на 1 (или что-то подобное), когда деление происходит пары чисел DX:AX?
И всё-таки, что насчёт конструкций вида " idiv eax, eax, ah "? Они вообще реальны? Как они работают и при каких условиях? Что-то толком про такой вариант использования idiv нигде не нашёл, ни у Юрова, ни у Абеля...
DillerInc
13-04-2010, 17:07
И всё-таки, что насчёт конструкций вида " 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
Необходимость исходит в виде требований свыше ничего кроме ax, bx, cx и dx не использовать ^^
Но за код спасибо. Теперь я знаю, что мне нужна команда cwd.
© OSzone.net 2001-2012
vBulletin v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.