- •Тема 4 Программная модель микропроцессоров архитектуры ia-32
- •1. Особенности архитектуры ia-32
- •2. Структура микропроцессоров ia-32
- •3. Регистры
- •4. Формат команды микропроцессора ia-32
- •5. Типы данных
- •6. Пространство памяти
- •7. Режимы адресации
- •8. Система команд
- •8.1. Инструкции пересылки данных
- •8.2. Инструкции двоичной арифметики
- •8.3. Инструкции десятичной арифметики
- •8.4. Инструкции логических операций
- •8.5. Инструкции сдвигов
- •8.6. Инструкции обработки бит и байт
- •8.7. Инструкции передачи управления
- •8.8. Инструкции строковых операций
- •8.9. Инструкции работы с флагами
- •8.10. Инструкции загрузки указателей
- •8.11. Разные инструкции
8.1. Инструкции пересылки данных
Инструкции данного типа позволяют передавать константы или переменные между регистрами и памятью, а также портами ввода/вывода в различных комбинациях, но в памяти может находиться не более одного операнда. Основные инструкции пересылки данных перечислены в таблице 8.2. Для P6 добавлено значительное количество команд типа MOV (CMOVC, CMOVE, CMOVG и т.д.).
Таблица 8.2
Команда |
Описание |
BSWAP r32 |
Перестановка байт из порядка младший–старший (L–H) в порядок старший–младший (H–L) (486+) |
CBW/CWDE |
Преобразование байта AL в слово AX (расширение знака AL в AH: AH заполняется битом AL.7) или слова AX в двойное слово EAX |
CMOVA/CMOVNBE reg, reg/mem |
Пересылка, если выше ((CF или ZF) = 0) (P6+) |
CMPXCHG r/m, r |
Обмен по результату сравнения. Сравнение AL (AX, EAX) с r/m; если равно, то содержимое загружается в r/m и ZF=1. Иначе содержимое r/m загружается в AL (AX, EAX), ZF=0 (486+) |
IN AL/AX/EAX,DX/i8 |
Ввод из порта ввода/вывода с адресом, хранящимся в DX или i8 в AL, AX, или EAX |
MOV r/m,r ~r,r/m/i ~r,Sreg ~Sreg,r/m16 ~AL,moffs8 ~AX,moffs16 ~EAX,moffs32 ~moffs8,AL ~moffs16,AX ~moffs32,EAX |
Пересылка (копирование) данных из левого операнда команды в правый |
OUT DX/i8,AL/AX/EAX |
Вывод в порт ввода/вывода с адресом, хранящимся в DX/i8 из AL/AX/EAX |
POP r/m16 ~r/m32 ~Sreg |
Извлечение слова (двойного слова) данных из стека в регистр/память/сегментный (кроме CS) регистр с инкрементацией (E)SP |
POPA |
Извлечение данных из стека в регистры DI, SI, BP, BX, DX, CX, AX (286+) |
POPAD |
Извлечение данных из стека в регистры EDI, ESI, EBP, EBX, EDX, ECX, EAX (386+) |
PUSH r/m16 ~r/m32 ~i16 ~i32 |
Помещение слова (двойного слова) из регистра/памяти/константы в стек после декремента (E)SP (286+, 386+) |
PUSHA |
Помещение в стек регистров AX, CX, DX, BX, SP (исходное значение), BP, SI, DI (286+) |
PUSHAD |
Помещение в стек регистров EAX, ECX, EDX, EBX, ESP (исходное значение), EBP, ESI, EDI (386+) |
XCHG r/m,r |
Взаимный обмен данными между регистрами или регистром и памятью |
8.2. Инструкции двоичной арифметики
Инструкции выполняют все арифметические действия с байтами, словами и двойными словами, кодирующими знаковые или беззнаковые целые числа. Умножение и деление для 8086 возможны только с аккумулятором, результат для 16–битных операндов расширяется в DX. Все команды данной группы перечислены в табл.8.3.
Таблица 8.3
Команда |
Описание |
ADC r/m, r/m/i |
Сложение двух операндов с учетом переноса от предыдущей операции. Если слово складывается с i8, то последний операнд знаком расширяется до слова (r/m = r/m + r/m/i + CF) |
ADD r/m, r/m/i |
Сложение двух операндов. Если слово складывается с i8, то последний операнд знаком расширяется до слова (r/m = r/m + r/m/i) |
CMP r/m, r/m/i |
Сравнение (вычитание без сохранения результата, установка флагов) |
DEC r/m |
Декремент (вычитание 1, не действующее на флаг CF, r/m = r/m – 1) |
DIV r/m |
Деление беззнаковое: AX на r/m8, частное в AL, остаток в AH; DX:AX на r/m16, частное в AX, остаток в DX; EDX:EAX на r/m32, частное в EAX, остаток в EDX. Деление на ноль или переполнение (частное не помещается в регистр) вызывает прерывание #DE |
IDIV r/m |
Деление знаковое |
IMUL r/m
~r16, r/m16 ~r32, r/m32 ~r16, r/m16, i8 ~r32, r/m32, i8 ~r16, r/m16, i16 ~r32, r/m32, i32 ~r16, i8 ~r32, i8 ~r16, i16 ~r32, i32 |
Умножение знаковое: AX = AL * r/m8; DX:AX = AX * r/m16; EDX:EAX = EAX * r/m32 (386+) r16 = r16 * r/m16 (286+) r32 = r32 * r/m32 (386+) r16 = r/m16 * i8 (286+) r32 = r/m32 * i16 (386+) r16 = r/m16 * i16 (286+) r32 = r/m32 * i32 (386+) r16 = r16 * i8 (286+) r32 = r32 * i8 (386+) r16 = r16 * i16 (286+) r32 = r32 * i32 (386+) |
INC r/m |
Инкремент (сложение с 1, не действующее на флаг CF, r/m = r/m–1) |
MUL r/m |
Беззнаковое умножение: AX = AL * r/m8; DX:AX = AX * r/m16; EDX:EAX = EAX * r/m32 |
NEG r/m |
Изменение знака операнда |
SBB r/m, r/m/i |
Вычитание с заемом: r/m = r/m – r/m/i – CF |
SUB r/m, r/m/i |
Вычитание: r/m = r/m – r/m/i |
XADD r/m, r |
Обмен содержимым и сложение, сумма сохраняется в r/m (486+) |
Приведенный ниже пример демонстрирует работу описанных инструкций.
; Пример 03
; программа выводит на экран заданное число в установленной системе
; счисления после его преобразования в строку функцией Itoa
CSEG SEGMENT
ASSUME cs:CSEG, ds:CSEG, es:CSEG, ss:CSEG
ORG 100h
Start:
jmp Beg
String DB 10 DUP(20h)
DB '$'
Beg:
mov cx,10 ; число преобразуемых цифр
mov ax,7cfh ; преобразуемое число
lea bx,String+9 ; адрес конца строки
mov si,10 ; система счисления
call _Itoa ; вызов функции преобразования
lea dx,String
mov ah,9 ; вывод полученной строки
int 21h ; на экран
int 20h
; Подпрограмма преобразования числа в текстовую строку
; в заданной системе счисления
;
; Вход:
; AX = преобразуемое число
; DS:BX = указатель на конец строки, в которую помещается
; преобразуемое число
; CX = число преобразуемых знаков
; SI = система счисления
;
; Разрушаемые регистры: AX, BX, CX, DX
_Itoa PROC
Convert:
sub dx,dx ; преобразование AX в двойное слово в DX:AX
div si
add dl,'0' ; преобразование остатка в текстовый символ
mov [bx],dl ; помещение полученного символа в строку
cmp ax,0 ; если значащих разрядов нет
je AllCount ; закончить
dec bx ; указатель адреса следующей значащей цифры
loop Convert ; переход к следующей цифре
AllCount:
ret ; возврат
_Itoa ENDP
CSEG ENDS
end Start