Добавил:
kostikboritski@gmail.com Выполнение курсовых, РГР технических предметов Механического факультета. Так же чертежи по инженерной графике для МФ, УПП. Писать на почту. Дипломы по кафедре Вагоны Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

литература / Пухальский Проектирование микропроцессорных систем 2001

.pdf
Скачиваний:
333
Добавлен:
12.11.2017
Размер:
21.12 Mб
Скачать

360

Глава 4. Микропроцессоры 8086/8088 и сопроцессор 8087

 

 

шепшческие команды

7

 

Байт 1

 

0

7

Байт 2

0 7

Байт 3 0

ADD — сложить (add)

 

 

O O O O O O r f w mod

 

 

j

 

 

 

Регистр/память с регистром

 

 

reg

r/m

 

 

Непосредственный операнд с регистром/памятью

l O O O O O s w mod 0

0

Oi

r/m

data

8/16

Непосредственный операнд с аккумулятором

0 0 0

0 0

1

0 w

data

8/16

 

 

ADC — сложить с переносом (add with carry)

0 0 0 1 0 0

 

 

 

 

 

i

 

 

 

Регистр/память с регистром

 

d w mod)

 

reg

r/m

 

 

Непосредственный операнд с регистром/памятью

1 0 0 0 0 0

s w mod',0 1 Oi

r/m

data

8/16

Непосредственный операнд с аккумулятором

0 0 0

1 0

1 0 w

data

8/16

 

 

INC — инкремент (increment);

dst <— dst + 1

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Регистра/памяти

 

*

1

1

1

1

1

1

1

w modi 0

0

0:

r/m

 

 

Регистра

 

*

0 1 0 0 01 reg

 

 

 

 

 

 

 

AAA — Л5 С//-коррекция для сложения (ASCII adjustfor add)

 

 

 

 

 

 

 

 

 

 

 

 

 

 

0 0

1 1 0

1 1 1

 

 

 

 

 

 

 

DAA — десятичная коррекция для сложения (decimal adjust for add)

 

 

 

 

 

 

 

 

 

 

 

|0

0

1

0

0

1

1

1

 

 

 

 

 

 

 

SUB — вычесть (subtract)

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Регистр/память из регистра

 

0 0

1 0

1 0

d w mod1,

 

reg

 

r/m

 

 

Непосредственный операнд из регистра/памяти

l O O O O O s w

mod\ 1 0

1

r/m

data

8/16

Непосредственный операнд из аккумулятора

0

0

1 0

1

1

0 w

data

8/16

 

 

SBB — вычесть с заемом (subtract with borrow)

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Регистр/память из регистра

 

0

0

0

1

1

0

d w mod\

 

reg

 

r/m

 

 

Непосредствен, операнд из регистра/памяти

l O O O O O s w

mod, 0

1

1

r/m

data

8/16

Непосредственный операнд из аккумулятора

0

0

0

1

1

1

0 w

data

8/16

 

 

DEC — декремент (decrement);

dst <— dst - 1

 

 

 

 

 

 

1 w mod\0

 

 

 

 

 

Регистра/памяти

 

*

1

1

1

1

1

1

0

1

r/m

 

 

Регистра

 

*

0

1

0 0

11

 

reg

 

 

 

 

 

 

 

NEG — изменить знак числа (change sign)

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

1

1

1

1

0

1

I

wmodiO

1

1

r/m

 

 

CMP — сравнить (compare)

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Регистр/память и регистр

 

0

0

1

1

1

0

d

W m o d

 

r e g

 

r /m

 

 

Непосредственный операнд и регистр/память

l O O O O O s w m o d \

1

1

1

r /m

d a ta

8/16

Непосредственный операнд и аккумулятор

0 0 1 1 1 1

0

w

d a t a

8/16

 

 

AAS — ASC/1-коррскиия для вычитания (ASCII adjustfor subtract)

 

 

 

 

 

 

 

 

 

 

 

 

|0

0

1

1

1

1

1

1

 

 

 

 

 

 

 

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

0 0

1 0

1 1 1 1

 

 

 

 

 

 

 

 

(decimal adjustfo r subtract)

 

 

 

 

 

 

 

MUL — умножить целые числа без знака (multiply unsigned)

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

1

1

1

1

0

1

1 w modi 1 0 0

r/m

 

 

IMUL — умножить целые числа со знаком (integer multiply signed)

l l l l O l l w modi 1 0 1 1 r/m

AAM — А5 С//-коррекция для умножения (ASCII adjust for multiply)

1 1 0 1 0 1 0 0 0 0 0 0 1 0 1 0

4.3. Система команд МП 8086/8088

DIV — разделить целые числа без знака (divide unsigned)

l l l l O l l w mod 111 0 i r/m

IDIV — разделить целые числа со знаком (integer divide signed)

l l l l O l l w modi 1 1 1 : r/m

AAD — /1Л’С//-коррекция для деления (ASCII adjustfo r divide)

 

 

1 1 0 1 0 1 0 1 0 0 0 0

10

 

CBW — преобразовать байт в слово (convert byte to word)

 

 

 

 

 

 

 

 

 

 

 

1 0

0

1

1 0

0

0

 

 

 

 

CWD — преобразовать слово в двойное слово (convert word to double word)

 

 

 

 

 

1 0

0

1

1 0

0

1

 

 

 

 

Логические команды

 

7

 

Байт 1

 

0

7 Байт 2 0 7

NOT — инвертировать (invert)

 

1

1 1 1 0 1

1 w mod] 0 1

0i

 

dst <— dst

 

r/m

SHL/SAL — сдвинуть логически/арифметически влево (shift logical!arithmetic left)

 

 

 

11

1

0 1

0

0

v w modi 1 0

0!

r/m

SHR — сдвинуть логически вправо (shift logical right)_____________

 

 

 

 

 

 

 

1

1 0 1 0 0

v w modi 1

0

1 i

r/m

SAR— сдвинуть арифметически вправо (shift arithmetic right)

 

 

 

 

 

 

 

 

 

 

1

1

0

1

0

0

v w mod 1 1 1 !

r/m

ROL — сдвинуть циклически влево (rotate left)

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

1

l O l O O v w modi 0

0

0

r/m

ROR — сдвинуть циклически вправо (rotate right)

 

 

 

 

 

 

 

 

 

 

 

 

 

 

1

l O l O O v w

modi 0 0

1!

r/m

RCL — сдвинуть циклически влево через перенос

 

l O l O O v w modi 0

 

 

 

(rotate through C F left)

1

1 0

r/m

RCR — сдвинуть циклически вправо через перенос

1

1 0 1 0 0

v w modi0

1

1 i

 

(rotate through C F right)

r/m

AND — поразрядная конъюнкция операндов;

dst <— dst & src

 

 

 

 

 

 

 

Регистр/память с регистром

 

0

0

1

0

0

0 d w mod

reg

 

r/m

Непосредственный операнд с регистром/памятью

1

0 0 0 0 0

0 w mod, 1

0

0

r/m

Непосредственный операнд с аккумулятором

 

0

0 1 0 0 1

0 w

data

8/16

TEST — поразрядное И операндов без их изменения

 

SrC] & src2

 

 

 

 

 

 

Регистр/память и регистр

 

1

0

0

0

0

1

0

w mod

reg

 

r/m

Непосредственный операнд и регистр/память

 

1

1

1

1

0

1

1

w mod\ 0

0

0

r/m

Непосредственный операнд и аккумулятор

]_j ”

1

0

1

0

1

0

0 w

data

8/16

OR — поразрядное ИЛИ операндов; dst <—dst v src

 

 

 

 

 

 

 

 

 

 

 

Регистр/память с регистром

 

0

0 0 0 1 0

d w mod

reg

 

r/m

Непосредственный операнд с регистром/памятью

1

0 0 0 0 0

0 w modO 0

1

r/m

Непосредственный операнд с аккумулятором

 

0 0 0 0

1

1

0 w

data

8/16

XOR — поразрядное исключающее ИЛИ (exclusive OR);

dst <—dst © src

 

 

 

Регистр/память с регистром

 

0

0

1

1 0

0 d w mod

reg

 

r/m

Непосредственный операнд с регистром/памятью

1

0

0

0

0

0

0 w mod 1

1

0

r/m

Непосредственный операнд с аккумулятором

 

0

0

1

1

0

1

0 w

data

8/16

361

Байт 3 0

data 8/16

data 8/16

data 8/16

data 8/16

362

Глава 4. Микропроцессоры 8086/8088 и сопроцессор 8087

 

Команды манипуляции цепочками

 

 

Байт 1

 

О

 

 

 

REP — повторять операцию до СХ = 0 (repeat)

 

 

 

 

 

 

 

z

 

 

 

REP/REPZ/REPE = 1), REPNZ/REPNE = 0)

1

1

1

1

0 0

1

 

 

 

MOVS — переслать байт/слово (move byte/word)

1 0 1 0 0 1

0 w

 

 

 

MOVS/MOVSB/MOVSW

 

 

 

CMPS — сравнить байт/слово (compare byte/word)

1 0

1 0

0 1

1 w

 

 

 

CMPS/CMPSB/CMPSW

 

 

 

SCAS — сканировать байт/слово (scan byte/word)

1 0 1 0 1

1

l w

 

 

 

SCAS/SCASB/SCASW

 

 

 

LODS — загрузить байт/слово в AL/AX (load byte/word to AL/AX)

0 w

 

 

 

LODS/LODSB/LODSW

1

0 1

0 1

1

 

 

 

STOS — запомнить байт/слово из AL/AX (store byte/word from AL/AX)

 

 

 

STOS/STOSB/STOSW

11

0

1

0

1

0

1 w

 

 

 

Команды передачи управления

 

 

Байт 1

 

0 7 Байт 2

0 7

Байт 3 0

CALL — вызов процедуры (подпрограммы)

 

 

 

 

 

 

 

 

disp low

disp high

Прямой внутрисегментный [near)

1 1 1 0

1 0

0 0

Косвенный внутрисегментный (near)

1 1 1 1 1 1 1 1

mod\0 1 0!

r/m

 

Прямой межсегментный (far)

1 0

0

1

1 0

10

offset low

offset high

 

 

 

 

 

 

 

 

 

 

seg low

 

seg high

Косвенный межсегментный (far)

1 1 1 1 1 1 1 1

mod, 0 1 1 j

r/m

 

JMP — безусловный переход (unconditionaljump)

 

 

 

 

 

 

 

 

 

 

 

Прямой внутрисегментный (near)

1 1 1 0

1 0

0

1

disp low

disp high

Прямой внутрисегментный короткий (short)

1 1 1 0

1 0

11

disp#

 

 

Косвенный внутрисегментный (near)

1 1 1 1 1 1 1 1

mod\ 1 0 0 j

r/m

 

Прямой межсегментный (far)

1 1 1 0

1 0

1 0

offset low

offset high

 

 

 

 

 

 

 

 

 

 

seg low

 

seg high

Косвенный межсегментный (far)

1 1 1 1 1 1 1 1

mod\ 1 0 1'

r/m

 

Внутрисегментный (near)

1

1

0 0

0 0

1

1

 

 

 

Внутрисегментный и SP + /ml6 (near)

1

1 0 0 0 0

1

0

data low

data high

Межсегментный (far)

 

1 1 0

0

1 0

11

 

 

 

Межсегментный и SP + im\6 (far)

1 1 0

0 1 0

10

data low

data high

JE/JZ — перейти, если нуль/если равно (jump on zero/on equal)

 

 

 

 

 

 

Флаг ZF = 1

 

0

1 1 1 0

1 0

0

dispS

 

•кропэП

JNE/JNZ — перейти, если не нуль/если не равно (jump on not zero/oti not equal)

 

 

Флаг ZF = 0

 

0 1 1 1 0

10

1

disp&

 

 

JS — перейти, если знак установлен (jump on sign)

 

 

 

 

 

 

 

 

dispf.

 

 

Флаг SF = 1

 

0

1 1 1 1 0

0 0

 

 

JNS — перейти, если знак сброшен (jump on not sign)

 

 

 

 

 

 

 

 

 

 

Флаг SF =0

 

0

1 1 1 1 0

0

1

dispS,

 

 

1 1 1 0 0 0 0 0

 

4.3. Система команд МП 8086/8088

363

JO — перейти, если есть переполнение (jump on overflow)

 

 

disp8

Флаг OF = 1

0 1 1 1 0

0 0 0

JNO — перейти, если нет переполнения (jump on not overflow)

 

 

dispS

Флаг OF = 0

0 1 1 1 0

0 0 1

JP/JPE — перейти, если есть паритет/если четный паритет (jump on parity/parity even)

Флаг PF = 1

0 1 1 1 1 0

10

disp8

JNP/JPO — перейти, если нет паритета/если нечетный паритет (jump on not parity/parity odd)

Флаг PF = 0

0 1 1 1 1 0

1 1

disp8

JB/JNAE/JC — перейти, если ниже/если не выше и не равно (без знака) (jump on below/not above or equal)

Флаг CF = 1 0 1 1 1 0 0 1 0 dispS

JNB/JAE/JNC — перейти, если не ниже/если выше или равно (без знака) (jump on not below/above or equal)

Флаг CF = 0 0 1 1 1 0 0 1 1 dispS

JBE/JNA — перейти, если ниже или равно/если не выше (без знака) (jump on below or equal/not above)

Флаг CF v ZF = 1 0 1 1 1 0 1 1 0 dispS

JNBE/JA — перейти, если не ниже и не равно/если выше (без знака) (jump on not below or equal/above)

Флаги CF v ZF = 0 0 1 1 1 0 1 1 1 dispS

JL/JNGE — перейти, если меньше/если не больше и не равно (со знаком) (jump on less/not greater or equal)

Флаг SF ® OF = 1 0 1 1 1 1 1 0 0 disp8

JNL/JGE — перейти, если не меньше/если больше или равно (со знаком) (jump on not less/greateror equal)

Флаги SF © OF =0 (SF = OF) 0 1 1 1 1 1 0 1 disp8

JLE/JNG — перейти, если меньше или равно/если не больше (со знаком) (jump on less or equal/not greater)

Флаги SF © OF v ZF = 1 0 1 1 1 1 1 1 0 disp8

JNLE/JG — перейти, если не меньше и не равно/если больше (со знаком) (jump on not less or equal/greater)

Флаги SF © OF v ZF = 0

0 1 1 1 1 1 1 1

dispS

LOOP — зациклить CX раз (loop CX times)

1 1 1 0

0 0 10

disp8

 

LOOPZ/LOOPE — зациклить, пока нуль/равно (loop while zero/equal)

disp8

 

1 1 1 0

0 0 0 1

LOOPNZ/LOOPNE — зациклить, пока не нуль/не равно (loop while not zero/not equal) disp8

JCXZ — перейти, если CX = 0 (jump on CX zero)

 

1 1 1 0

0 0 11

disp8

INT — прервать (interrupt — прерывание)

 

 

 

 

type

Определенного типа (type * 03h)

1 1 0

0

1 1 0

1

Типа 3 (type =03/i)

1 1 0

0

1 1 0

0

 

INTO — прервать, если есть переполнение (interrupt on overflow)

 

 

Выполняется только при OF = 1

1 1 0

0

1 1 1 0

 

IRET — возвратиться из прерывания (interrupt return)________________

110 0 1111

364

Глава 4. Микропроцессоры 8086/8088 и сопроцессор 8087

Команды управления процессором

 

7

 

Байт 1

0 7 Байт 2 0

CLC — сбросить флаг переноса (clear carry)

 

1

1

1 1 1 0 0 0

CF<r- 0

 

*

CMC — инвертировать флаг переноса (complement carry)

 

 

 

C F «—CF

t. .....

*

1

1

1 1 0

1 0

1

STC — установить флаг переноса (set carry)

 

1

1

1 1 1 0 0

1

CF <—1

 

*

CLD — сбросить флаг направления (clear direction)

 

 

 

 

 

D F < - 0

 

* 1 1 1 1 1 1 0 0

STD — установить флаг направления (set direction)

* 1 1 1 1 1 1 0 1

DF <— 1

 

CLI — сбросить флаг прерывания (clear interrupt)

* 1 1 1 1 1 0 10

IF <r- 0

 

STI — установить флаг прерывания (set interrupt)

* 1 1 1 1 1 0 11

IF <—1

 

HLT — остановить (halt)

 

1

1

1 1 0

1 0

0

 

 

 

WAIT — ожидать активного значения сигнала TEST (wait)

1 0 0 1 1 0 11

ESC — переключиться на сопроцессор (escape to external device)

1 1 0 1 1 X X X modix x x! r/m

LOCK — префикс блокировки шины (bus lock prefix)

1 1 1 1 0 0 0 1

П р и м е ч а н и е : символом

отмечены команды, не требующие дополнительного пояснения.

Описание команд. Многие команды МП 8086/8088 выполняют те же операции, что и ко­ манды МП 8080/8085 (например, команды MOV, AND, OR и др.). Различия таких команд за­ ключаются лишь в методах адресации операндов, размерах операндов (байт/слово) и способах записи некоторых однотипных для МП 8086/8088 и 8080/8085 команд на языке ассемблера. Так, если регистр содержит адрес операнда, находящегося в памяти, то он заключается в пря­ мые скобки (на языке ассемблера для МП 8086/8088). Ниже приведено детальное описание всех команд, не отмеченных символом “*”, в последовательности, соответствующей последователь­ ности вышеприведенного описания их форматов, за исключением случаев, противоречащих логике изложения материала. Так, команды передачи данных PUSH, POP, PUSHF и POPF будут описаны в группе команд передачи управления (описание всех команд, использующих стек, сосредоточено в одном месте).

1. Команды передачи данных

Команды M OV dst, src. Эти команды выполняют операции передачи данных:

dst <— src.

Можно использовать как непосредственные операнды imm, так и операнды, находящиеся в аккумуляторе (А), регистрах (reg), сегментных регистрах (seg) и в памяти (М).

reg) и 11 + еа тактов

4.3. Система команд МП 8086/8088

365

Выполняются команды MOV за 10 тактов (А —» М; М —» А), 2 такта (reg —■>reg; reg —» seg SS, DS, ES; reg —> reg), 8 + еа тактов (M —> reg; M —» seg SS, DS, ES), 9 + еа тактов (reg —» M; seg —> M), 4 такта (imm —> reg) и 10 + еа тактов (imm —> M). Операндом-получателем не может быть сегментный регистр кода CS.

Пример 4:

MOV CL, 240

MOV ВХ, 38h

MOV CH, BL

MOV DI, BX

MOV [DI+10A], 5A3DA MOV AX, CS

MOV DX, ES:[BX] segES MOV DX, [BX]

CL <r- 240d = F0h — непосредственный операнд BX <— 003 8h — непосредственный операнд

CH <— BL = 38h DI <—BX = 0038Л

M(Dl+\0h) 5A3DA — слово (ЕЛ = DI + 10A = 0048A) AX <r- CS — сегментный регистр кода

DX M(BX), ES: — префикс замены сегмента DS на ES

Эквивалентная форма предыдущей команды

Квадратные скобки используются для указания адреса памяти ([ ] — оператор индексиро­ вания). В поле комментария для памяти М всегда будет указываться лишь эффективный адрес ЕА, так как сегментный регистр, используемый по умолчанию для вычисления физического адреса, определяется табл. 4.9. В последних двух командах был использован префикс замены сегмента, поэтому М(ВХ) означает M(16-ES+BX), где ВХ = ЕА. Далее в примерах программ, поясняющих назначение команд, будут использоваться, как правило, только регистровые и не­ посредственные операнды, так как операции, выполняемые командами, не зависят от режима адресации. Это позволяет использовать в программах конкретные числовые примеры, не ус­ ложняя их директивами ассемблера, определяющими имена данных в памяти.

Команды XCHG dst, src и NOP. Команда XCHG выполняет операцию обмена операндов:

dst <н> src.

Если в операции участвует операнд, находящийся в памяти, то на время обмена устанав­ ливается значение сигнала LOCK = 0, независимо от наличия префикса LOCK (шина блокиру­ ется до конца выполнения команды). Команда XCHG АХ, АХ используется как команда NOP (пустая операция) — машинный код равен 90h (см. табл. 4.11).

Выполняется команда XCHG за 3 такта (reg А), 4 такта (reg (reg <--> М). Команда NOP выполняется за 3 такта.

Пример^-. XCHG ВХ, SI; ВХ

SI.

Команды IN AL/AX, port и IN

AL/AX, DX. Эти команды осуществляют ввод данных из

внешних устройств (I/O):

 

AL <— I/0(port), АХ

l/0(port), AL <— //O(DX), АХ <— //O(DX).

Команды имеют два формата: длинный и короткий (двухбайтная и однобайтная команды). Ввод данных производится только в регистры AL (ввод байта) или АХ (ввод слова).

Выполняются команды за 10 тактов (длинный формат) и 8 тактов (короткий формат).

Пример 6:

IN

AL, port

; длинный формат, AL

I/0(port), где port = 00 -*■FF/г

IN

AX, port

; длинный формат (фиксированный порт), АХ 4—I/0(port)

IN

AL, DX

; короткий формат, AL

//O(DX), где DX — адрес I/O

IN

AX, DX

; короткий формат (переменный порт), АХ I/0(DX)

366

Глава 4. Микропроцессоры 8086/8088 и сопроцессор 8087

Команда IN port аналогична одноименной команде МП 8080/8085 — адресуется 28 = 256 устройств ввода. В однобайтных командах адрес порта находится в 16-разрядном регистре DX, поэтому адресуется 216 = 65536 устройств ввода.

Команда OUT port, AL/AX и OUT DX, AL/AX. Эти команды осуществляют вывод дан­ ных в внешние устройства (I/O):

I/0(pori) <- AL, I/0(port) <- АХ, 1Ю(DX) <- AL, //O(DX) <- AX.

Команды имеют два формата: длинный и короткий (двухбайтная и однобайтная команды) Вывод данных производится только из регистров AL (вывод байта) или АХ (вывод слова).

Выполняются команды за 10 тактов (длинный формат) и 8 тактов (короткий формат).

Пример 7:

OUT

port, AL

; длинный формат, I/0(port) <— AL (port = 00 FF/г)

OUT

port, AX

; длинный формат (фиксированный порт), UO(port) <— АХ

OUT

DX, AL

; короткий формат, //O(DX) <— AL (DX — адрес I/O)

OUT

DX, AX

; короткий формат (переменный порт), //O(DX) <— АХ

Команда OUT port аналогична одноименной команде МП 8080/8085

— адресуется

28 = 256 устройств вывода. В однобайтных командах адрес порта находится в

16-разрядном

регистре DX, поэтому адресуется 216 = 65536 устройств вывода.

 

Команда XLAT/XLATB пате. Эта команда (XLAT и XLATB — синонимы) заменяет содержимое регистра AL байтом из таблицы перекодировки (максимальная длина таблицы рав­ на 256 байт):

AL ^— M(BX+AL),

'■'i- ii~ •*

-*-f'

где M Memory (память), BX — начальный адрес таблицы, исходное значение AL = 00 + FF/г (содержимое AL используется как индекс таблицы, адресуемой регистром ВХ). Команда XLAT очень удобна для выборки данных из 256-байтной таблицы. Например, если в таблицу записать коды ASCII, то команду XLAT можно использовать для преобразования двоичных чисел из ре­ гистра AL в коды ASCII.

Выполняется команда XLAT за 11 тактов.

Пример 8:

LEA ВХ, tabl

MOV AL, 12

XLAT tabl

MOV BX, offset tabl

MOV AL, 12

XLAT ES\tabl

BX <— адрес начала таблицы tabl (tabl — символическое имя операнда) AL <— QCh (директивы и операторы языка ассемблера см. в § 4.4)

AL <г- М(ВХ + tabl), команду XLAT здесь можно использовать без операнда tabl

ВХ <—адрес начала таблицы tabl (то же самое, что и LEA ВХ, tabl)

AL <— OCh

AL <— M(BX + tabl), ES:tabl — замена сегментного регистра DS на ES.

Операнд name является необязательным (фиктивным) — не транслируется ассемблером в машинный код, т. е. этот операнд играет роль краткого комментария, используемого для удобства чтения программы, написанной на языке ассемблера, в которой используется не­ сколько таблиц преобразований (обычно пате — имя таблицы).

Выражение ES :пате в языке ассемблера употребляется для переопределения сегментного регистра, используемого по умолчанию, на ES. Фиктивный операнд пате в команде XLAT также пригоден для этого. Переопределение сегментного регистра можно выполнить с помо­

4.3. Система команд МП 8086/8088

367

щью префикса замены сегмента и в не стандартной форме: segES XLAT. Пример использова­ ния команды XLAT имеется в задаче 10.

Команда LEA г 16, addr. Эта команда вычисляет эффективный адрес ЕА операнда, нахо­ дящегося в памяти, в соответствии с заданным режимом адресации и помещает его значение в указанный регистр:

rl 6 <— addr.

В символике команды использовано специальное обозначение addr = src для конкретиза­ ции операнда-источника (он может находиться только в памяти).

Выполняется команда за 2 + еа тактов.

Пример 9: LEA BP, [BXJ[SIj; BP ВХ + SI = ЕД.

Команды LDS г 16, тет и LES г16, тет. Эти команды загружают полный указатель из памяти и записывают его в пару регистров DS: г!6 или ES: г16 соответственно:

rl 6 <— M(addr), DS <— M(addr + 2) и /16 ^— M(addr), ES <—M(addr + 2).

В символике команды использовано специальное обозначение тет = src для конкретиза­ ции операнда-источника (он может находиться только в памяти М).

Выполняются команды за 16 + еа тактов.

Пример 10:

LDS

SI, [BXJ

; SI

Л*(ВХ), DS <- Л4(ВХ + 2)

LES

DI, [BP]

; DI

Л/(ВР), ES <- М(ВР + 2)

2.Арифметические команды

ВМП 8086/8088 можно использовать пять типов представления исходных чисел, над ко­ торыми производятся арифметические операции:

целые числа без знака — все разряды байта и слова определяют величину числа; целые числа со такам — числа представлены в дополнительном коде (старшие разряды

байта и слова задают знак числа);

упакованные BCD-числа (Binary Coded Decimal - код 8 -4 -2 -1) — в одном байте содер­ жится двухразрядное десятичное число от 00 до 99d (для каждой десятичной цифры использу­ ется одна тетрада);

неупакованные BCD-числа — в одном байте содержится одноразрядное десятичное число

от 00 до 09d (старшая тетрада содержит код 0000/;);

десятичные ASCII-числа (ASCII American Standard Code for Information Interchange

американский стандартный код для информационного обмена) — в одном байте содержится одноразрядное десятичное число, представленное его ASCII-кодом от 30h до 39h для цифр от О до 9 (старшая тетрада содержит код 00U );

Независимо от формата представления чисел ALU при выполнении команд сложения, вы­ читания, умножения и деления производит над ними операции как над двоичными кодами. По­ этому для получения правильного результата при использовании трех последних типов чисел нужно выполнять специальные команды коррекции.

Команда NEG dst. Эта команда используется для изменения знака числа, представленного в дополнительном коде. Команда выполняет операцию:

dst <г- 0 - dst

368 Глава 4. Микропроцессоры 8086/8088 и сопроцессор 8087

(вычисление двоичного дополнения Two’s Complement), т. е. модуль dst отрицательного чис­ ла преобразуется в дополнительный код. Эта операция эквивалентна операции поразрядного инвертирования числа и сложения с 1: dst <— dst + 1. Флаг переноса CF устанавливается в 1, если операнд не равен 0. Очевидно, что повторное выполнение команды NEG дает исходный операнд, т. е. команду NEG можно использовать для получения модуля числа по его дополни­ тельному коду. Флаг переполнения OF устанавливается в 1, если dst = -128 (байт) и -32768 (слово).

Выполняется команда за 3 такта (reg) и 16 + еа тактов (М).

Пример И : NEG ВХ; NEG СН; NEG [BP + SI],

Задача 1. Найти дополнительный код десятичного числа X = -825d. Результат поместить в регистр СХ. Ответ для проверки: | X | = 339/г, [-825^]д = 0 - 339/г = FCC7/i. Решение-.

MOV CX, 825d NEG CX

MOV CL, 80h NEG CL

СХ 825d = 0339h — модуль числа X

СХ <— VC.C.1h — дополнительный код числа X

Проверка особых случаев

СХ 80h — дополнительный код числа -128 = -2 7

СХ = 80h — число не изменяется, OF <—1 — переполнение

MOV NEG

<> и

оо

О 00

с х

; СХ <— 8000/г — дополнительный код числа -32768 - ~215 ; СХ = 8000/г, OF <—1 — переполнение

Команды ADD dst, src, ADC dst, src, DAA и AAA. Команды ADD и ADC выполняют операции сложения двоичных чисел:

dst <— dst + src и dst <— dst + src + CF,

где CF — значение флага переноса CF (ADD — сложение без переноса, ADC — сложение с переносом). Операнды могут иметь различную разрядность:

dst& <г- dst% + src%, dst\6 <r-dst16 + src\6, dst\6 <— dstl6 + im\6, dst\6 <— dst\6 + imS,

где г'ш8 — непосредственный операнд с расширением знака для сложения чисел, представлен­ ных в дополнительном коде (например, команда ADD ВХ, OFFCl/г транслируется в машинный код 83C3C1 — старший байт FF операнда г'т8 игнорируется). Числа могут быть без знака и со знаком. Если при сложении возникает перенос из старшего разряда байта (слова), то он фикси­ руется во флаге CF, т. е. флаг CF является расширителем разрядности чисел. Это позволяет вычислять сумму двух чисел, представленных т байтами (словами): сложение младшйх байт (слов) выполняется командой ADD, а последовательное сложение остальных байт (слов) — командой ADC, или только командой ADC, если предварительно сбросить флаг переноса CF в 0 командой CLC.

Команда DAA используется для десятичной коррекции содержимого регистра AL после сложения упакованных BCD-чисел с помощью команды ADD AL, src8. После коррекции в ре­ гистре AL получается сумма в упакованном BCD-формате. Если сумма превышает число 99d, то флаг переноса CF устанавливается в 1 (вес 100d).

Команда ААА используется для коррекции содержимого регистра AL после сложения не­ упакованных BCD-чисел и десятичных ASCII-чисел с помощью команды ADD AL, srcS. Коман­

да ААА выполняет операции:

 

 

AL 0#,

где # — десятичная сумма (# = 0. . . 9);

АН <г—АН +1, C

F 1 и AF 1, если сумма больше 9;

АН <— АН,

CF ь О

и AF «—0, если сумма меньше 10.

4.3. Система команд МП 8086/8088

369

Выполняются команды ADD и ADC за 3 такта (reg —* reg), 9 + еа тактов —> reg), 16 + еа тактов (reg —> М), 4 такта (imm —>reg; imm —» А) и 17 + еа тактов (/ww —> М). Команды

DAA и ААА выполняются за 4 такта. Стрелка

указывает операнд-получатель результата

операции.

 

Задача 2. Найти суммы десятичных чисел без знака 126с? + 2 lld и 42483d + 27787с?. От­ вет для проверки: 126й? + 2 \ld = 343с/ = 157/г и 42483с/ + 21181d = 70270с/ = 1 127ЕА. Решение'.

MOV

DL, 126с/

; DL <- 126d = lEh, 217с/ = D9h

ADD

DL, 217с/

; DL <— DL + D9A = 51h = 87c/, CF = 1 — вес 28 = 256c/ (256 + 87 = 343c/)

 

 

; В следующем фрагменте CF = 1 — вес 216 => 65536d + 4734с/ = 70270с/

MOV SI, 42483с/

; SI <- 42483d = A5F3h, 27787d = 6C8Bh

ADD

SI, 27787c/

; SI <— SI + 6C8BA = 127ЕЙ = 4734c/, CF = 1

Задача 3. Вычислить сумму 64-разрядных двоичных чисел без знака

X = ВЕ58 1D32 FA77 C90Dh и У= 7С4А 1938 AD36 3943h

(числа представлены четырьмя словами). Начальные адреса чисел (младших слов) равны addr1 и addrl. Сумму поместить на место второго слагаемого. Ответ для проверки: сумма равна 1 ЗАА2 366В А7АЕ 0250h (четыре слова и один байт для переноса). Решение:

LEA

BX, addr1

LEA

SI, addr2

MOV

CX, 4

CLC

 

MOV

AX, [BX]

ADC

[SI], AX

INC

BX

INC

BX

INC

SI

INC

SI

LOOP

LI

LAHF

 

AND

AH, 1

MOV

[SI], AH

BX <r- начальный адрес первого слагаемого SI <— начальный адрес второго слагаемого СХ <— 0004/г — число слов слагаемых

CF 0 — сброс флага переноса

АХ <- М(ВХ) = C90D/?, FA77A, 1D32h, ВЕ58h

M(SI) <- М(SI) + АХ + CF = 0250h, А7АЕЙ, 366ВЙ, 3AA2h BX BX + 1

B X ^ B X + 1 SI <—SI + I SI <- SI + 1

CX <— CX - 1 и переход, пока CX не равно 0

АН low byte PSW = SF ZF 0 AF 0 PF 1 CF

AH <— 0000 OOOx, где x — флаг переноса CF = 0 или 1 A/(SI) = M(addr2 + 8) <— CF

Задача 4. Найти суммы в дополнительном коде чисел

Х + У = -39с/+ 126с/и Х + У= -1999с/+ 1936с/.

Ответ для проверки: [-39с/ + 126с/]д = [8 7 % = 57/г и [-1999с/ + 1936с/]д = [-63с/]д = FFC1A.

Решение:

MOV

DL, 39d

DL 4- 39d = 21h — модуль числа X, 126d = lEh

 

NEC

DL

DL <—D9h — дополнительный код числа X

 

ADD

DL, 126d

DL

DL + 7Е/г = 51h = 87с/

 

MOV

SI, 1999d

SI

1999d = ICFh — модуль числа X

 

NEG

SI

SI <— F831/i — дополнительный код числа X

 

ADD

SI, 1936d

SI

SI + 790/г = FFC1 h — дополнительный код суммы (отрицательное

NEG

SI

SI

003Fh = 63d — модуль суммы

число)

24 Г. И. Пухальский