Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Dos7book

.pdf
Скачиваний:
76
Добавлен:
09.02.2015
Размер:
5.1 Mб
Скачать

Глава 7: Ассемблерные команды отладчика Debug.exe

сложения неупакованных десятичных цифр, после чего полученная двоичная сумма должна быть преобразована в неупакованное десятичное слово командой AAA (7.03-01). Если первый операнд находится в регистре AL, то команда ADC может быть применена для сложения упакованных десятичных байтов; затем получаемую

двоичную сумму упакованных десятичных байтов надлежит преобразовать в правильный упакованный десятичный байт командой DAA (7.03-18).

 

1-й байт

 

2-й байт

Байты

Примеры

 

 

 

данных

 

 

 

 

 

 

 

 

10

 

(0-B)(0-F)

0-2

ADC [bp+si+ffff],bl

 

 

10

 

(C-F)(0-F)

 

ADC bl,bl

 

 

11

 

(0-B)(0-F)

0-2

ADC [bp+si+ffff],bx

 

 

11

 

(C-F)(0-F)

 

ADC bx,bx

 

 

12

 

(0-B)(0-F)

0-2

ADC bl,[bp+si+ffff]

 

 

13

 

(0-B)(0-F)

0-2

ADC bx,[bp+si+ffff]

 

 

14

 

 

1

ADC AL,ff

 

 

15

 

 

2

ADC AX,ffff

 

 

80

 

(1,5,9)(0-7)

1-3

ADC byte ptr [bp+si+ffff],ff

 

 

80

 

D(1-7)

1

ADC bl,ff

 

 

81

 

(1,5,9)(0-7)

2-4

ADC word ptr [bp+si+ffff],ffff

 

 

81

 

D(1-7)

2

ADC bx,ffff

 

 

83

 

(1,5,9)(0-7)

1-3

ADC word ptr [bp+si+ffff],±7f

 

 

83

 

D(1-7)

1

ADC bx,±7f

 

Примечание 1: отладчик DEBUG.EXE дизассемблирует как команду ADC коды

 

 

 

"1(2,3) (C-F)(0-F)" и "82 (1,5,9,D)(0-7)".

7.03-06

ADD – суммирование

 

 

Команда ADD выполняет суммирование операндов, игнорируя перенос в младшем разряде. Исходное состояние флага CF не принимается во внимание. Состояния флагов OF, SF, ZF, AF, PF и CF приводятся в соответствие с получаемой суммой, которая замещает собою первый операнд.

Команда ADD – двоичная операция, но имеются два исключения. Если первый операнд находится в регистре AX, то команда ADD может быть использована для сложения неупакованных десятичных цифр, после чего полученная двоичная сумма должна быть преобразована в неупакованное десятичное слово командой AAA (7.03-01). Если первый операнд находится в регистре AL, то команда ADD может быть применена для сложения упакованных десятичных байтов; затем получаемую

двоичную сумму упакованных десятичных байтов надлежит преобразовать в правильный упакованный десятичный байт командой DAA (7.03-18).

– 259 –

Глава 7: Ассемблерные команды отладчика Debug.exe

 

1-й байт

 

2-й байт

Байты

Примеры

 

 

 

данных

 

 

 

 

 

 

 

 

00

 

(0-B)(0-F)

0-2

ADD [bp+si+ffff],bl

 

 

00

 

(C-F)(0-F)

 

ADD bl,bl

 

 

01

 

(0-B)(0-F)

0-2

ADD [bp+si+ffff],bx

 

 

01

 

(C-F)(0-F)

 

ADD bx,bx

 

 

02

 

(0-B)(0-F)

0-2

ADD bl,[bp+si+ffff]

 

 

03

 

(0-B)(0-F)

0-2

ADD bx,[bp+si+ffff]

 

 

04

 

 

1

ADD AL,ff

 

 

05

 

 

2

ADD AX,ffff

 

 

80

 

(0,4,8)(0-7)

1-3

ADD byte ptr [bp+si+ffff],ff

 

 

80

 

C(1-7)

1

ADD bl,ff

 

 

81

 

(0,4,8)(0-7)

2-4

ADD word ptr [bp+si+ffff],ffff

 

 

81

 

C(1-7)

2

ADD bx,ffff

 

 

83

 

(0,4,8)(0-7)

1-3

ADD word ptr [bp+si+ffff],±7f

 

 

83

 

C(1-7)

1

ADD bx,±7f

 

Примечание 1: отладчик DEBUG.EXE дизассемблирует как команду ADD коды

 

 

 

"0(2,3) (C-F)(0-F)" и "82 (0,4,8,C)(0-7)".

7.03-07

AND – логическая операция "И"

Команда AND поразрядно сопоставляет биты операндов и сбрасывает в нуль бит результата, если в соответствующем разряде хотя бы у одного из операндов бит сброшен в нуль. Результат замещает собою первый операнд. Состояния флагов SF, ZF, PF приводятся в соответствие с полученным результатом. Флаги CF и OF сбрасываются в состояния NC (No Carry) и NV (No oVerflow) соответственно.

1-й байт

2-й байт

Байты

Примеры

данных

 

 

 

20

(0-B)(0-F)

0-2

AND [bp+si+ffff],bl

20

(C-F)(0-F)

 

AND bl,bl

21

(0-B)(0-F)

0-2

AND [bp+si+ffff],bx

21

(C-F)(0-F)

 

AND bx,bx

22

(0-B)(0-F)

0-2

AND bl,[bp+si+ffff]

23

(0-B)(0-F)

0-2

AND bx,[bp+si+ffff]

24

 

1

AND AL,ff

25

 

2

AND AX,ffff

80

(2,6,A)(0-7)

1-3

AND byte ptr [bp+si+ffff],ff

80

E(1-7)

1

AND bl,ff

81

(2,6,A)(0-7)

2-4

AND word ptr [bp+si+ffff],ffff

81

E(1-7)

2

AND bx,ffff

 

 

– 260 –

 

 

 

Глава 7:

Ассемблерные команды отладчика Debug.exe

Продолжение таблицы 7.03-07

 

 

 

 

 

 

 

83

 

 

(2,6,A)(0-7)

 

1-3

 

AND word ptr [bp+si+ffff],±7f

 

 

 

 

 

 

 

 

83

 

 

E(1-7)

 

 

1

 

AND bx,±7f

 

Примечание 1: отладчик

DEBUG.EXE дизассемблирует как команду AND коды

 

 

 

 

 

"2(2-3) (C-F)(0-F)" и "82 (2,6,A,E)(0-7)".

7.03-08

CALL – вызов процедуры

 

 

 

Команда CALL записывает в стек адрес возврата, и затем выполняет переход к подпрограмме по указанному адресу. Состояния флагов при этом не изменяются.

Различают несколько форм команды CALL. Вызов подпрограммы, находящейся вне сегмента кода вызывающей программы, выполняется командой CALL FAR с четырехбайтовым адресом перехода (сегмент : смещение). Вызов подпрограммы, находящейся внутри сегмента кода вызывающей программы, выполняется командой ближнего вызова ("near" CALL), которая не изменяет сегментный адрес и оперирует только с двухбайтовым смещением. Существуют две разные формы команды ближнего вызова с машинными кодами операций FFh и E8h.

Команда CALL ближнего вызова с кодом FFh записывает в стек 2 байта, выражающие состояние регистра IP, и затем замещает прежнее состояние IP величиной смещения, взятого либо из указанных ячеек памяти, либо из указанного регистра общего назначения.

Команда CALL ближнего вызова с кодом E8h, за которым следует слово (2 байта) данных, действует иначе: после сохранения прежнего состояния регистра IP в стеке она суммирует свое слово данных с имеющимся смещением в регистре IP. Когда при ассемблировании отладчик DEBUG.EXE встречает двухбайтовый адрес перехода в ассемблерной команде, он автоматически вычисляет разность между заданным адресом и смещением для следующей команды. Получаемая разность представляет как раз то слово данных, которое записывается после байта E8h в ассемблируемый машинный код.

Поскольку обе формы команды CALL ближнего вызова осуществляют переходы только в пределах текущего сегмента, постольку возврат обратно к вызывающей программе из подпрограмм, вызванных командой CALL ближнего вызова, должен выполняться командой RET (7.03-73), которая восстанавливает из стека только содержимое регистра IP.

Команда дальнего вызова CALL FAR записывает в стек 2 слова (4 байта) из регистров CS:IP, а затем сегмент и смещение из адреса назначения замещают прежние значения и в регистре CS, и в регистре IP. Потому происходит переход в другой сегмент. По той же причине возврат обратно к продолжению вызывающей программы из подпрограмм, вызванных командой CALL FAR, следует выполнять

– 261 –

Глава 7: Ассемблерные команды отладчика Debug.exe

посредством команды RETF (7.03-74), которая восстанавливает из стека содержимое сразу двух регистров – CS: и IP.

1-й байт

2-й байт

Байты

Примеры

Примечания

данных

 

 

 

 

9A

 

4

CALL FAR ffff:ffff

*1

E8

 

2

CALL ffff

 

FF

(1,5,9)(0-7)

0-2

CALL [bp+si+ffff]

*2

FF

(1,5,9)(8-F)

0-2

CALL FAR [bp+si+ffff]

*2

FF

D(0-7)

 

CALL bx

*3

Примечание 1: в приведенном примере первое число это сегментный адрес перехода, второе число смещение. Указывать маркер "FAR" в такой строке вызова не обязательно: в любом случае будет выполнен дальний переход.

Примечание 2: когда команда CALL получает адрес перехода по ссылке, характер операции зависит от наличия в строке вызова маркера "FAR": при его наличии из памяти считываются 4 байта данных, и выполняется дальний переход, а при отсутствии маркера "FAR" из памяти считывается только смещение (два байта данных), и тогда выполняется ближний переход.

Примечание 3: если команда CALL получает адрес перехода из регистра, то в этот регистр заранее должно быть записано смещение. Обращение CALL к 16-битовому регистру всегда вызывает ближний переход.

Примечание 4: отладчик DEBUG.EXE дизассемблирует код "FF D(8-F)" как команду "CALL FAR bx".

Примечание 5: перед командой CALL нельзя ставить префиксы повторения F2h и F3h (7.02-03, 7.02-04).

7.03-09 CBW – преобразование байта в слово

Команда CBW (Convert Byte into Word) выполняет преобразование байтового числа со знаком в однобайтовом регистре AL в двухбайтовое число со знаком (слово) в регистре AX путем заполнения старшего однобайтового регистра AH

состоянием знакового бита исходного числа из младшего однобайтового регистра AL. Состояния флагов команда CBW не изменяет.

Код

Пример

98

CBW

– 262 –

Глава 7: Ассемблерные команды отладчика Debug.exe

7.03-10 CLC – сброс флага переноса

Команда CLC (CLear Carry) сбрасывает флаг переноса CF в состояние NC.

Код

Пример

F8

CLC

7.03-11 CLD – сброс флага направления

Команда CLD (CLear Direction flag) сбрасывает флаг направления DF в состояние UP, при котором смещения в индексных регистрах DI и/или SI в ходе исполнения строковых операций (CMPSB, LODSB, MOVSB, SCASB, STOSB, и

т.д.) будут изменяться в сторону увеличения.

Код

Пример

FC

CLD

7.03-12 CLI – сброс флага прерывания

Команда CLI (CLear Interrupt flag) сбрасывает флаг прерывания IF в состояние DI (Disable Interrupts = запретить прерывания). При этом процессор игнорирует все внешние прерывания, кроме немаскируемого прерывания INT 02 (8.01-03).

Код

Пример

FA

CLI

Примечание 1: программные прерывания исполняются командой INT (7.03-28) всегда, безотносительно к состоянию флага IF.

Примечание 2: команда CLI не выполняется из программ, уровень привилегий которых ниже уровня, установленного для операций ввода-вывода в битах 0Ch и 0Dh регистра флагов (A.11-4).

7.03-13 CMC – реверсирование флага переноса

Команда CMC (Complementary Carry) изменяет любое текущее состояние флага переноса CF на противоположное: NC (No Carry) на CY (CarrY) или наоборот.

Код

Пример

F5

CMC

– 263 –

Глава 7: Ассемблерные команды отладчика Debug.exe

7.03-14 CMP – сравнение операндов

Команда CMP (CoMPare) приводит флаги OF, SF, ZF, AF, PF и CF в

соответствие с разностью между первым операндом (уменьшаемым) и вторым операндом (вычитаемым). При этом сама разность не никуда не записывается, оба операнда сохраняют свои значения.

Интерпретация состояний флагов, оставляемых командой CMP, зависит от того, были ли операнды числами со знаком или без знака. После сопоставления чисел без знака следует пользоваться командами условных переходов JA, JB, JBE, JNB, а после сопоставления чисел со знаком командами JG, JGE, JL, JLE. Полные имена всех команд условного перехода отражают статус первого (левого) операнда по отношению ко второму (правому) операнду, например, JA (Jump if Above = перейти, если выше) означает, что для исполнения перехода левый операнд команды CMP должен быть больше, чем ее правый операнд.

 

1-й байт

 

2-й байт

Байты

Примеры

 

 

 

данных

 

 

 

 

 

 

 

 

38

 

(0-B)(0-F)

0-2

CMP [bp+si+ffff],bl

 

 

38

 

(C-F)(0-F)

 

CMP bl,bl

 

 

39

 

(0-B)(0-F)

0-2

CMP [bp+si+ffff],bx

 

 

39

 

(C-F)(0-F)

 

CMP bx,bx

 

 

3A

 

(0-B)(0-F)

0-2

CMP bl,[bp+si+ffff]

 

 

3B

 

(0-B)(0-F)

0-2

CMP bx,[bp+si+ffff]

 

 

3C

 

 

1

CMP AL,ff

 

 

3D

 

 

2

CMP AX,ffff

 

 

80

 

(3,7,B)(8-F)

1-3

CMP byte ptr [bp+si+ffff],ff

 

 

80

 

F(9-F)

1

CMP bl,ff

 

 

81

 

(3,7,B)(8-F)

2-4

CMP word ptr [bp+si+ffff],ffff

 

 

81

 

F(9-F)

2

CMP bx,ffff

 

 

83

 

(3,7,B)(8-F)

1-3

CMP word ptr [bp+si+ffff],±7f

 

 

83

 

F(9-F)

1

CMP bx,±7f

 

Примечание 1: отладчик DEBUG.EXE дизассемблирует как команду CMP коды

 

 

 

"3(A,B) (C-F)(0-F)" и "82 (3,7,B,F)(8-F)".

7.03-15

CMPSB – сопоставление байтов

Команда CMPSB (CoMPare Strings of Bytes) выполняет сравнение пары байтов.

Адреса сопоставляемых байтов должны быть заранее загружены в пары регистров DS:SI и ES:DI. Если сравниваемые байты равны, флаг переноса CF сбрасывается в состояние NC (No Carry), а флаг нуля ZF устанавливается в состояние ZR (ZeRo). Если сравниваемые байты неодинаковы, то флаг нуля ZF сбрасывается в состояние

– 264 –

Глава 7: Ассемблерные команды отладчика Debug.exe

NZ (No Zero), а флаг переноса CF устанавливается в состояние CY (CarrY). Устанавливаемые состояния флагов OF, SF, AF, PF соответствуют результату вычитания сопоставляемых байтов, хотя сам этот результат нигде не сохраняется и не отображается.

После сравнения пары байтов оба смещения в регистре SI и в регистре DI – увеличиваются на единицу или уменьшаются на единицу: это зависит от состояния флага направления DF, которое следует заранее задать командой CLD (счет вверх, 7.03-11) или командой STD (счет вниз, 7.03-85). Так или иначе, после завершения сравнения одной пары байтов командой CMPSB все значения смещений в регистрах оказываются подготовленными к сравнению следующей пары байтов.

Команде CMPSB часто предшествуют префиксы повторения F2h (REPNZ, 7.02-03) или F3h (REPZ, 7.02-04), которые позволяют исполнять команду CMPSB несколько раз подряд и тем самым сопоставлять группы байтов. Перед командой CMPSB также можно использовать один из префиксов смены сегмента (2Eh, 26h или 36h, 7.02-01); он позволит осуществить адресацию относительно другого сегментного регистра (CS:, ES: или SS:) вместо принимаемого по умолчанию сегментного регистра DS. Сегментный адрес ES другого сравниваемого байта посредством префикса смены сегмента изменить нельзя.

Код

Пример

A6

CMPSB

Примечание 1: при наличии перед командой CMPSB префикса повторения F2h или F3h порядок циклического исполнения операций включает сначала установление флагов по результату сравнения байтов, затем изменение смещений в индексных регистрах DI и SI, и только потом проверку условия выхода из цикла по состоянию флагов. Поэтому смещения в индексных регистрах DI и SI в момент выхода из цикла указывают не на ту пару байтов, которая удовлетворила условию выхода, а на следующую за ней пару байтов.

7.03-16 CMPSW – сопоставление слов

Команда CMPSW (CoMPare Strings of Words) сравнивает два двухбайтовых слова и затем изменяет смещения в индексных регистрах DI и SI на 2, подготавливая тем самым адреса к сравнению следующей пары слов. Под действием префикса 66h смены разрядности операнда (7.02-06) команда CMPSW сравнивает пары четырехбайтовых слов (типа Dword) и изменяет смещения в индексных регистрах на 4. Все остальные особенности команды CMPSW такие же,

как у команды CMPSB (7.03-15).

– 265 –

Глава 7: Ассемблерные команды отладчика Debug.exe

Код

Пример

A7

CMPSW

7.03-17 CWD – формирование четырехбайтового числа.

Команда CWD (Convert Word into Double word) преобразует двухбайтовое число со знаком в регистре AX в четырехбайтовое число со знаком. Для размещения старших разрядов этого числа выделяется регистр DX, причем собственно преобразование выполняется посредством заполнения регистра DX знаковым разрядом из регистра AX. Состояния флагов команда CWD не изменяет.

Код

Пример

99

CWD

7.03-18 DAA – коррекция после сложения

Команда DAA (Decimal Adjustment after Addition) преобразует в однобайтовом регистре AL двоичный результат сложения двух упакованных десятичных байтов в правильное упакованное десятичное число, содержащее две десятичные цифры на байт (о сложении неупакованных десятичных чисел - в разделе 7.03-01).

Двоичная сумма упакованных десятичных байтов может вызывать десятичное переполнение отдельно как в четырех младших, так и в четырех старших битах однобайтового регистра AL. Сначала проверяются младшие 4 бита: если число в них превышает 9 или если флаг AF установлен в состояние AC, то команда DAA выполняет сложение AL=(AL+6). Затем аналогичная проверка выполняется для старших четырех бит однобайтового регистра AL: если число в AL превышает 9Fh или если флаг CF установлен в состояние CY, то команда DAA выполняет сложение AL =(AL+60h). Флаги AF, CF, SF, ZF и PF приводятся в соответствие с получаемым результатом. Состояние флага OF не сохраняется.

 

 

Код

Пример

 

 

27

DAA

7.03-19

DAS – коррекция после вычитания

Команда DAS (Decimal Adjustment after Subtraction) преобразует в однобайтовом регистре AL двоичный результат вычитания двух упакованных однобайтовых операндов в правильное упакованное десятичное число, содержащее две

– 266 –

Глава 7: Ассемблерные команды отладчика Debug.exe

десятичные цифры на байт (о вычитании неупакованных десятичных чисел - в

разделе 7.03-04).

Двоичная разность упакованных десятичных байтов может вызывать десятичное переполнение отдельно как в четырех младших, так и в четырех старших битах однобайтового регистра AL. Сначала проверяются младшие 4 бита: если число в них превышает 9 или если флаг AF установлен в состояние AC, то команда DAS выполняет вычитание AL=(AL–6). Затем аналогичная проверка выполняется для старших четырех бит однобайтового регистра AL: если число в AL превышает 9Fh или если флаг CF установлен в состояние CY, то команда DAS выполняет вычитание AL=(AL–60h). Флаги AF, CF, SF, ZF и PF приводятся в соответствие полученному результату. Состояние флага OF не сохраняется.

Код

Пример

2F

DAS

7.03-20 DEC – уменьшение на единицу

Команда DEC (DECrement) уменьшает указанный операнд на единицу и приводит флаги OF, SF, ZF, AF и PF в соответствие с полученным результатом. Флаг CF при исполнении команды DEC сохраняет свое прежнее состояние.

1-й байт

2-й байт

Байты

Примеры

данных

 

 

 

4(8-F)

 

 

DEC bx

FE

(0,4,8)(8-E)

0-2

DEC byte ptr [bp+si+ffff]

FE

C(8-F)

 

DEC bl

FF

(0,4,8)(8-E)

0-2

DEC word ptr [bp+si+ffff]

Примечание 1: байты 4(0-F) могут быть интерпретированы 64-разрядными процессорами как префиксы (7.02-08). Поэтому вместо однобайтового кода 4(8-F) команды "DEC bx" предпочтительно применять двухбайтовый код "FF C(8-F)". Он воспринимается как команда "DEC bx" всеми процессорами платформы x86 и правильно дизассемблируется отладчиком DEBUG.EXE, но при

ассемблировании его приходится вводить как данные инструкцией

DB (7.01-01).

7.03-21 DIV – деление чисел

Команда DIV (DIVide) выполняет деление чисел без знака (для чисел со знаком надо использовать команду IDIV, 7.03-24). Задаваемый в команде DIV операнд

– 267 –

Глава 7: Ассемблерные команды отладчика Debug.exe

это делитель. Если делитель представляет собой байт, то заранее предполагается наличие делимого в регистре AX; после деления частное помещается в AL, а остаток в AH. Если делитель представляет собой двухбайтовое слово, то заранее предполагается наличие старших разрядов делимого в регистре DX, младших разрядов делимого в регистре AX; после деления частное помещается в регистр AX, а остаток в регистр DX. Состояния флагов OF, SF, ZF, AF, PF, CF не сохраняются, после деления они остаются в неопределенном состоянии.

Хотя команда DIV является двоичной операцией, тем не менее неупакованные

десятичные двухбайтовые слова могут быть подвергнуты операции двоичного деления, если они заранее преобразованы в приемлемую квази-двоичную форму командой AAD (7.03-02).

1-й байт

2-й байт

Байты

Примеры

данных

 

 

 

F6

(3,7,B)(0-7)

0-2

DIV byte ptr [bp+si+ffff]

F6

F(0-7)

 

DIV bl

F7

(3,7,B)(0-7)

0-2

DIV word ptr [bp+si+ffff]

F7

F(0-7)

 

DIV bx

Примечание 1: если операция деления вызывает переполнение в том регистре, куда должно быть помещено частное, то процессор автоматически вызывает обработчика прерывания INT 00 (8.01-01). Дальнейший ход событий зависит от этого обработчика.

7.03-22 ESC – передача кодов асинхронному сопроцессору.

Команда ESC (= ESCape) использовалась для передачи данных и команд от центрального процессора к асинхронно работающему внешнему сопроцессору, подключенному к системной шине. Каждой команде ESC должен был предшествовать префикс ожидания WAIT (7.02-05), заставляющий центральный

процессор ожидать поступления сигнала готовности от адресуемого устройства по шине BUSY. Позднее командам арифметических сопроцессоров были присвоены отдельные наименования (7.04), но оставшиеся машинные коды, начинающиеся с байтов D9h - DFh, отладчик DEBUG.EXE по-прежнему дизассемблирует как команду ESC:

D9 (0,4,8)(8-F), D9 D(1-7), DA (C-F)(0-F), DB (0,4,8,C,D,F)(8-F), DB (2,3,6,7,A-D,F)(0-7), DB E(4 – F), DD (0,2,6)(8-F),

DD (E,F)(0-F), DE D(8,A-F), DF (0,4,8)(8-F), DF (E,F)(0-F).

Многие из перечисленных кодов уже задействованы в расширенном наборе команд современных арифметических сопроцессоров. Команда ESC, как и все другие сопроцессорные команды (7.04), начинающиеся с байтов D8h - DFh,

– 268 –

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]