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

Исследование процессов вводавывода информации и системы арифметических команд x86 микропроцессоров семейства Intel. Учебное пособие

.pdf
Скачиваний:
0
Добавлен:
12.08.2026
Размер:
949 Кб
Скачать

Фрагмент программы, реализующий данную операцию:

.

.

.

mov ax,x1; сложить младшие слова из x1 и y1 add ax,y1; и поместить сумму в sum

mov sum,ax

mov ax,x1+2; сложить старшие слова из x1 и y1 adc ax,y1+2; и поместить сумму в sum+2

mov sum+2,ax

.

.

.

В нём предполагается, что младшие слова операндов и суммы находятся соответственно в x1, y1 и sum, а старшие слова в x1, y1 и sum+2. Младшие слова складываются командой add (поскольку нет необходимости учитывать значение флага CF от предыдущей операции), а старшие слова – adc. Аналогичным образом при операции с большей точностью операнды следует хранить в последовательно расположенных ячейках памяти, причём младшее слово имеет наименьший адрес, следующее слово – адрес больший на 2 и т.д.

Рассмотрим вычитание с двойной точностью.

Заём

1

0006

A92F

 

0004

В837

0001

F0F8

31

По-прежнему правильные результаты получаются при обработке операндов по 16 бит. Приведем пример программы, вычисляющей выражение U=X+Y+24–Z с двойной точностью:

.

.

.

mov ax,x ; сложить числа с двойной mov dx,x+2 ; точностью x,x+2 и y,y+2

add ax,y

adc dx,y+2

add ax,24

; прибавить к результату число 24

adc dx,0

; с двойной точностью

sub ax,z

; вычесть из суммы число z,z+2

sbb dx,z+2 ; с двойной точностью

mov w,ax

; запомнить весь результат w,w+2

mov w+2,dx

.

.

Отметим, что программы на языке ассемблер можно писать как большими, так и маленькими буквами.

Команды расширения знака. Команда cbw расширяет знак байта из регистра al, образуя в регистре ax эквивалентное слово в дополнительном коде. Если например, (al) = 11001000, то после выполнения команды cbw в регистре ax получится код 1111111111001000. Аналогично, команда cwd расширяет знак слова из ax в регистр dx, формируя двойное слово в регистрах dx:ax . В обеих командах операнд неявно указывается кодом операции и

32

должен находиться в al или ax. Флажки не модифицируются. Рассмотренные команды используются для выравнивания длины операндов участвующих в операциях сложения и вычитания.

Команды INC, DEC, NEG, CMP. Специальные арифметические команды микропроцессора Intel 80×86 приведены в табл. 4.

 

 

Таблица 4

Специальные арифметические команды

 

 

 

Название

Мнемоника и формат

Описание

 

 

 

Инкремент

inc opr

(opr)←(opr) + 1

Декремент

dec opr

(opr)←(opr) – 1

Изменение знака

neg opr

(opr)← – (opr)

Сравнение

cmp opr1,opr2

(opr1) – (opr2)

 

 

 

Эти команды воздействуют на все арифметические флажки, но команды inc и dec не воздействуют на флаг CF. Команды inc, dec и neg имеют один операнд. Команда inc производит инкремент операнда на 1, а команда dec – декремент операнда на 1. Команда neg изменяет знак операнда. В них допускается любой режим адресации, кроме непосредственного. Команды inc и dec предназначены главным образом для счёта и индексирования и широко используются для организации программных циклов. Команда сравнения cmp идентична команде sub, но результат вычитания нигде не запоминается. Один из операндов в команде cmp должен быть регистром (за исключением непосредственного операнда opr2); другой операнд может иметь любой режим адресации, но opr1 не может быть непосредственным значением. Она используется только для установки флажков на основе соотношения между операндами и обычно применяется перед командами условного перехода. Выполнение перехода зависит от состояния флажков, т.е. от значений сравниваемых операндов. В табл. 5 приведены результаты выполнения команды cmp.

33

 

 

 

 

 

Таблица 5

Результаты выполнения команды cmp

 

 

 

 

 

 

 

Условие

 

 

Флаг

 

 

 

 

 

 

 

 

OF

SF

 

ZF

CF

 

 

 

 

 

 

Беззнаковые операнды

 

 

 

 

 

(opr1) < (opr2)

 

0

1

(opr1) = (opr2)

 

1

0

(opr1) > (opr2)

 

 

 

Знаковые операнды

 

 

 

 

 

(opr1) < (opr2)

0/1

1

 

0

(opr1) = (opr2)

0

0

 

1

0

(opr1) > (opr2)

0/1

 

0

 

 

 

 

 

 

Команды двоичного умножения и деления. Команды,

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

Таблица 6

Команды умножения и деления

Название

Мнемоника

 

Описание

 

и формат

 

 

 

 

 

 

Умножение

imul src

 

Операнды – байты

со знаком

 

 

(ax)← (al)×(src)

 

 

 

Операнды – слова

 

 

 

(dx:ax)← (ax)×(src)

 

 

 

произведение со знаком

Умножение

mul src

 

аналогично команде imul, но операнды

без знака

 

 

и произведение без знака

 

 

 

 

Разделить

idiv src

 

Делитель – байт

со знаком

 

 

(al)← частное (ax)/(src)

 

 

 

(ah))← остаток (ax)/(src)

 

 

 

Делитель – слово

 

 

 

(ax)← частное (dx:ax)/(src)

 

 

 

(dx)← остаток (dx:ax)/(src)

 

 

 

Частное и остаток имеют знаки.

 

 

 

Знак остатка равен знаку делимого.

Разделить

div src

 

Аналогично команде idiv, но операнды,

без знака

 

 

частное и остаток без знака

 

 

 

 

 

34

 

1292 10
1710

Команды умножения осуществляют умножение байт с получением результата-слова и умножения слов, давая в результате двойное слово. При этом, умножая байты, необходимо использовать указатель типа byte ptr после команды mul (imul), а при умножении слов – word ptr. Команды imul и mul устанавливают флаги OF и CF в состояние ”1”, если для результата требуется два байта или два слова одновременно. Проверяя состояние этих флажков, можно определить, размещается произведение в одном байте или слове. Остальные флажки могут модифицироваться, но их состояния не определены, т.е. не предсказуемы. В качестве src может быть общий регистр или ячейка памяти с любым режимом адресации, но не может быть непосредственный операнд. Отметим, что в обеих командах imul и mul переполнение невозможно, так как для произведения отводится достаточное место. Например: пусть в al находится чело 0В4h, которое можно интерпретировать как знаковое -7610 или беззнаковое 18010 . В регистре BL поместим число 11h, которое соответствует

Тогда, применив команду imul bl, получим (ax)=0FAF4h= – и (CF)=(OF)=1, так как результат велик для 8 бит. Если применить команду mul bl, то получим (ax)=0BF4h =306010 и

(CF)=(OF)=1.

Команды деления idiv и div дают неопределенное состояние флагов и, как команды умножения, не допускают непосредственных операндов, т.е. делитель должен находиться в одном из РОН или ячейки памяти. В команде idiv знакового деления знак частного, определяется по алгебраическому правилу, а остатку присваивается знак делимого. Отметим, что для получения правильного результата операция деления накладывает определенные ограничения на размерность делимого и делителя, а именно: если делитель – слово, то делимое должно иметь формат двойного слова; если делитель – байт, то делимое – слово. В некоторых случаях длина частного может превысить длину аккумулятора (ax или al). В этом случае МП генерирует внутреннее прерывание типа 0 и переходит к соответствующей процедуре обработки этого прерывания. Аналогичная ситуация возникает если делитель равен нулю.

35

Логические операции. В ассемблере для микропроцессора Intel 8086 имеются четыре основные логические операции: И (AND), ИЛИ (OR), «исключающее ИЛИ» (XOR), и отрицание (NOT)

Команды, выполняющие логические операции над операндами для рассматриваемого микропроцессора, приведены в табл. 7.

 

Таблица 7

Команды логических операций

 

 

Команда

Назначение

 

 

AND dst,src

Логическое И

OR dst,src

Логическое ИЛИ

XOR dst,src

Логическое исключающее ИЛИ

NOT dst

Инверсия

 

 

Команда AND dst,src выполняет побитовое «Логическое И» над приёмником (регистр или переменная) и источником (число, регистр или переменная; источник и приёмник не могут быть переменными одновременно) и помещает результат в приёмник. Любой бит результата равен 1, только если соответствующие биты обоих операндов были равны 1, и равен 0 в остальных случаях. Наиболее часто AND применяют для выборочного обнуления отдельных битов.

Например, команда

and al,00001111b

обнулит старшие четыре бита регистра AL, сохранив неизменными четыре младших.

Флаги OF и CF обнуляются, SF, ZF и PF устанавливаются в соответствии с результатом, AF не определён.

Команда OR dst,src выполняет побитовое «Логическое ИЛИ» над приёмником (регистр или переменная) и источником (число, регистр или переменная; источник и приёмник не могут быть переменными одновременно) и помещает результат в приёмник. Любой бит результата равен 0, только если соответствующие биты обоих операндов были равны 0, и равен 1 в остальных случаях.

36

Наиболее часто команду OR применяют для выборочной установки отдельных битов.

Например, команда

or al,00001111b

приведёт к тому, что младшие четыре бита в регистре AL будут установлены в 1.

При выполнении команды флаги OF и CF обнуляются, SF, ZF и PF устанавливаются в соответствии с результатом, AF не определён.

Команда XOR dst,src выполняет побитовое «Логическое исключающее ИЛИ» над приёмником (регистр или переменная) и источником (число, регистр или переменная; источник и приёмник не могут быть переменными одновременно) и помещает результат в приёмник. Любой бит результата равен 1, если соответствующие биты обоих операндов различны, и равны 0, в остальных случаях. Команду XOR применяют для самых различных случаев. Например, команда

xor ax,ax

обнуляет регистр AX, а команды

xor ax,bx xor bx,ax

меняют местами содержимое регистров AX и BX.

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

mov ax,0

xchg ax,bx

Командой NOT dst «Инверсия» каждый бит приёмника (регистр или переменная) устанавливается в 1, если он был равен 0, и сбрасывается в 0, если он был равен 1. При этом флаги не затрагиваются. Например, команды

mov al,00111100b

not al

изменят содержимое АL на значение 11000011 b.

37

Дополнительные сведения. Необходимо отметить, что в группу арифметических команд входит ещё шесть команд корректировки результатов вычислений, которые приведены в табл. 8.

 

 

Таблица 8

Команды корректировки результатов вычислений

 

 

 

Название корректировки

Мнемоника

Описание

 

и формат

 

 

 

 

сложение

aad

(al) ← (al)

вычитание

aas

(al) ← (al)

умножение

aam

(ah:al) ← ( ah:al)

деление

aad

(ah:al) ← (ah:al)

сложение

daa

(al) ← (al)

вычитание

das

(al) ← (al)

 

 

 

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

+47

26

6D

Поскольку в двоично-десятичных числах не используются значения А, В, С, D, E, F, полученный результат не является корректным. Для ликвидации неопределенности необходимо воспользоваться соответствующей командой корректировки результата. Так, для чисел, записанных в упакованном виде, используются команды daa и das, исправляющие результат вычислений после операций сложения и вычитания. Для чисел, представленных в неупакованном виде, применяются четыре

38

команды aaa, aas, aam и aad – корректировка сложения, вычитания, умножения и деления соответственно. Все эти команды однобайтовые. Корректируемый операнд всегда должен находиться в аккумуляторе (al или al:ah). Все команды исправления результата вычислений, кроме aad, применяются после соответствующих операций над двоично-десятичными числами. Команду корректировки деления aad необходимо применять перед операцией деления над числами.

Вернемся к приведенному примеру. После получения промежуточного результата необходимо воспользоваться командой dda, вследствие чего в аккумуляторе сформируется правильный результат, равный 73. Если же промежуточный результат был уже корректным, то никаких действий данная команда производить не будет. Отметим, что если было произведено исправление результата вычислений, то могут измениться значения флагов AF, CF, ZF, OF, PF, SF.

Основные правила при разработке программ на языке

ASSEMBLER

Для разработки ассемблерных программ в операционной системе DOS необходимо на диске компьютера D выбрать папку SHELLS, а в ней программу под названием VC.COM. После этого на экране монитора откроется окно синего цвета под названием D\SHELLS\VC.COM. В этом окне Вы увидите две одинаковые DOSовские панели под названием D\SHELLS. В них будут представлены некоторые файлы с расширениями: .exe, .map, .hlp и др. Для создания своего файла с программой необходимо на клавиатуре нажать клавиши Sift–F4. После этого откроется окно под названием Edit. В этом окне необходимо набрать имя создаваемого Вами файла с обязательным расширением .asm. Само имя файла может начинаться как с латинской буквы, так и с цифры и состоять не более чем из восьми символов, например, lab_1.asm. После этого нажимается клавиша Enter и на экране монитора появляется чистое

39

окно, в котором и набирается текст программы пользователя с использованием допустимых символов языка ASSEMBLER. Набор текста программы желательно начинать, отступив от левого края несколько позиций, т.е. создать слева от основного текста программы свободное поле нажатием клавиши Tab. В этом поле обычно размещаются метки, на которые происходит передача управления в некоторых командах программы. При написании программ на языке ASSEMBLER для указанных выше ЭВМ используются три модели памяти: tiny, small и flat. Мы в дальнейшем будем использовать модель small, а сама программа в первых наших работах всегда будет начинаться стандартными инструкциями:

.model small

.stack 100h

.data

Эти инструкции означают, что выбирается малая модель памяти, объёмом 64 Кбайта, и под стек отводится 256 байт. После идентификатора .data с новой строки описывается структура памяти, которая будет использоваться программой для хранения данных. Эта область памяти и называется сегментом данных. Её объём всегда должен быть меньше 64 Кбайт, так как в любой модели памяти ПЭВМ должны ещё обязательно располагаться сегмент кода и сегмент стека. Например, если нам необходимо выделить три области памяти в сегменте данных, объёмом 150 байт, 300 слов и 200 двойных слов, то в программе после указанного идентификатора .data необходимо написать следующие инструкции:

buffer_1 db 150

buffer_2 dw 300

buffer_3 dd 200

Вместо идентификаторов buffer можно использовать любые другие, начинающиеся с буквы. В область памяти buffer_1 ,например,

40

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