-
Notifications
You must be signed in to change notification settings - Fork 2
Лекция 2
Inspirate789 edited this page May 15, 2022
·
16 revisions
| Номер параграфа начала сегмента |
19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
| Смещение |
[SEG]:[OFFSET]
=> физический адрес:
- SEG необходимо побитово сдвинуть на 4 разряда влево (или умножить на 16, что тождественно)
- К результату прибавить OFFSET
5678h:1234h =>
56780
+ 1234
= 579B4
Вычисление физического адреса выполняется процессором аппаратно, без участия программиста.
- Сегмент кода (регистр
CS
) - Сегменты данных (основной регистр -
DS
, для дополнительных сегментов -ES
,FS
,GS
) - Сегмент стека (регистр
SS
)
- Уменьшает регистр
CX
на 1 и выполняет переход на метку, еслиCX
не равен нулю. - Метка не может быть дальше -128..127 байт от команды.
- Модули (файлы исходного кода)
- Сегменты (описание блоков памяти)
- команды процессора;
- инструкции описания структур данных, выделения памяти для переменных и констант;
- макроопределения.
- Сегменты (описание блоков памяти)
метка команда/директива операнды ; комментарий
- В коде:
(5 раз прибавляем bx к ax)
mov cx, 5 label1: add ax, bx loop label1
- В данных:
Метка в описании данных является ссылкой на переменную, расположенную после неё. Метка не является директивой выделения памяти.
-
label
метка label тип
- Возможные типы:
- BYTE (1 байт)
- WORD (2 байта)
- DWORD (4 байта)
- FWORD (6 байт)
- QWORD (8 байт)
- TBYTE (10 байт)
- NEAR - тип для хранения меток в коде или адресов команд для меток ближнего перехода
- FAR - тип для хранения меток в коде или адресов команд для меток дальнего перехода
-
EQU, =
-
label EQU выражение
(Пример выражения: 5 + 2, вычисляется на этапе компиляции) - Макрос
- Вычисляет выражение в правой части и приравнивает его метке
-
-
Директива - инструкция ассемблеру, влияющая на процесс компиляции и не являющаяся командой процессора. Обычно не оставляет следов в формируемом машинном коде.
Псевдокоманда - директива ассемблера, которая приводит к включению данных или кода в программу, но не соответствующая никакой команде процессора.
Псевдокоманды определения данных указывают, что в соответствующем месте располагается переменная, резервируют под неё место заданного типа, заполняют значением и ставят в соответствие метку.
-
DB
(1 байт) -
DW
(2 байта) -
DD
(4 байта) -
DF
(6 байт) -
DQ
(8 байт) -
DT
(10 байт)
a DB 1
float_number DD 3.5e7
text_string DB ‘Hello, world!’
- ? - неинициализированное значение
- Пример:
uninitialized DW 512 DUP(?)
- сегмент кода (CS)
- сегмент данных (DS и дополнительные ES, FS, GS)
- сегмент стека (SS)
имя SEGMENT [READONLY] [выравнивание] [тип] [разрядность] [‘класс’]
...
имя ENDS
-
BYTE
(сегмент может начинаться с произвольного адреса) -
WORD
(Адрес начала сегмента кратен 2 байтам) -
DWORD
(Адрес начала сегмента кратен 4 байтам) -
PARA
(сегмент располагается в начале параграфа, т.е. адрес начала сегмента кратен 16 байтам) - по умолчанию -
PAGE
(сегмент располагается в начале страницы, т.е. адрес начала сегмента кратен 256 байтам)
-
PUBLIC
(сегменты с одним именем будут располагаться в памяти друг за другом независимо от порядка объявления) -
STACK
(сегмент будет использоваться под стек (сегмент стека), все такие сегменты будут объединяться в один, увеличивая общий стек) -
COMMON
(сегменты будут накладываться, т.е. начинаться с одного и того же адреса; память выделится по размеру наибольшего из сегментов; метки, на которые ссылаются сегменты, будут указывать на одни и те же ячейки памяти) -
AT
(нужен аргумент - номер параграфа начала сегмента; сегмент будет загружаться в память по некоторому фиксированному постоянному адресу, независимо от расположения остальных сегментов) -
PRIVATE
(сегмент не объединяется с другими) - по умолчанию
Класс - любая метка, взятая в одинарные кавычки. Сегменты одного класса будут расположены в памяти друг за другом.
.model модель, язык, модификатор
Служит для определения модели памяти программы. Позволяет сократить запись программ определённых типов.
-
TINY
- один сегмент на всё (как в случае COM-программы) -
SMALL
- код в одном сегменте, данные и стек - в другом -
COMPACT
- допустимо несколько сегментов данных -
MEDIUM
- код в нескольких сегментах, данные - в одном -
LARGE
,HUGE
- много сегментов кода и данных
C
PASCAL
BASIC
-
SYSCALL
,STDCALL
NEARSTACK
(по умолчанию) или FARSTACK
(ближний или дальний).
END [точка_входа]
- Точка входа - имя метки, объявленной в сегменте кода и указывающее на команду, с которой начнётся исполнение программы.
- Если в программе несколько модулей, только один может содержать точку входа.
Для обращения к переменной процессору необходимо знать обе составляющие адреса: и сегментную, и смещение.
Data1 SEGMENT WORD 'DATA'
Var1 DW 0
Data1 ENDS
Data2 SEGMENT WORD 'DATA'
Var2 DW 0
Data2 ENDS
Code SEGMENT WORD 'CODE'
ASSUME CS:Code
ProgramStart:
mov ax,Data1
mov ds,ax
ASSUME DS:Data1
mov ax,Data2
mov es,ax
ASSUME ES:Data2
mov ax,[Var2]
.
.
.
Code ENDS
END ProgramStart
- Задание набора допустимых команд: .8086, .186, .286, …, .586, .686, ...
- Управление программным счётчиком:
-
ORG значение
- начиная с этой директивы в сегменте отступ будет идти со значением параметра директивы (пример:ORG 100h
- пропускает первые 256 байт)
На практике директива
ORG
задаёт отступ относительно начала сегмента, по которому будет располагаться следующая за этой директивой переменная.; пример из 4 лабораторной работы (2 пример): SD1 SEGMENT para common 'DATA' C1 LABEL byte ORG 1h C2 LABEL byte SD1 ENDS ; C1 и C2 будут располагаться вплотную друг за другом (а если бы мы написали ORG 0h, то C1 и C2 наложились бы)
-
EVEN
- автоматически выравнивает всё, что идёт после неё, по чётным адресам -
ALIGN значение
- явно задаёт кратность выравнивания (выравнивание будет кратно параметру директивы); нужен для ускорения работы программы (можно поставить выравнивание по размеру машинного слова)
-
- Глобальные объявления:
-
public
- позволяет объявить метку доступной из других программ comm
-
extrn
- подключает метку из другого файла и делает её видимой в текущем файле (используется в связке сpublic
) global
-
- Условное ассемблирование:
IF выражение
...
ELSE
...
ENDIF
-
short
(короткий): -128 .. +127 байт (аналогично командеloop
) -
near
(ближний): в том же сегменте (без изменения регистраCS
, меняется толькоIP
) -
far
(дальний): в другой сегмент (с изменением значения в регистреCS
)
Для короткого и ближнего переходов непосредственный операнд (константа в коде) прибавляется к IP, а не заменяет его.
- Регистры общего назначения (РОН):
-
AX
(AH
,AL
) -
BX
(BH
,BL
) -
CX
(CH
,CL
) -
DX
(DH
,DL
)
-
- Индексные регистры:
SI
DI
- Сегментные регистры:
CS
DS
ES
FS
GS
SS
- Указательные регистры:
SP
BP
FLAGS
IP
- Могут использоваться в большинстве команд, как регистры общего назначения.
- Применяются в специфических командах поточной обработки данных (должно быть в 3 лекции).
- Регистровая адресация (
mov ax, bx
) - самый простой способ - Непосредственная адресация (
mov ax, 2
) - Прямая адресация (
mov ax, ds:0032
) - Косвенная адресация (
mov ax, [bx]
-bx
взят в [], чтобы взять из него смещение). В 8086 допустимыBX
,BP
,SI
,DI
. - Адресация по базе со сдвигом (
mov ax, [bx]+2; <==> mov ax, 2[bx]
). Удобно использовать для движения по массивам, задавая в bx номер элемента в массиве. - Адресация по базе с индексированием (допустимы
BX
+SI
,BX
+DI
,BP
+SI
,BP
+DI
). Используется для движения по матрице. Равноценные варианты записи:mov ax, [bx+si+2]
mov ax, [bx+2][si]
mov ax, 2[bx][si]
mov ax, [bx][si]+2
mov ax, [bx][si+2]
16 битов - отдельные флажки.
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
CF - PF - AF - ZF SF TF IF DF OF IOPL NT -
-
CF
(carry flag) - флаг переноса (при выходе за рязрядную сетку) -
PF
(parity flag) - флаг чётности -
AF
(auxiliary carry flag) - вспомогательный флаг переноса -
ZF
(zero flag) - флаг нуля -
SF
(sign flag) - флаг знака -
TF
(trap flag) - флаг трассировки -
IF
(interrupt enable flag) - флаг разрешения прерываний -
DF
(direction flag) - флаг направления -
OF
(overflow flag) - флаг переполнения (изменение знакового разряда) -
IOPL
(I/O privilege flag) (появился в 286 процессоре) - уровень приоритета ввода-вывода -
NT
(nested task) (появился в 286 процессоре) - флаг вложенности задач
- Источник - число, регистр или переменная
- Приёмник - регистр или переменная; не может быть переменной одновременно с источником
- Вычитает источник из приёмника, результат никуда не сохраняется (в отличие от команды
SUB
), а выставляются флагиCF
,PF
,AF
,ZF
,SF
,OF
- Переход типа
short
илиnear
- Обычно используются в паре с
CMP
- Термины “выше” и “ниже” - при сравнении беззнаковых чисел
- Термины “больше” и “меньше” - при сравнении чисел со знаком
Команда | Описание | Состояние флагов для выполнения перехода |
---|---|---|
JO | Есть переполнение | OF = 1 |
JNO | Нет переполнения | OF = 0 |
JS | Есть знак | SF = 1 |
JNS | Нет знака | SF = 0 |
JE, JZ | Если равно/если ноль | ZF = 1 |
JNE, JNZ | Не равно/не ноль | ZF = 0 |
JP/JPE | Есть чётность / чётное | PF = 1 |
JNP/JPO | Нет чётности / нечётное | PF = 0 |
JCXZ | CX = 0 | - |
Команда | Описание | Состояние флагов для выполнения перехода | Знаковый |
---|---|---|---|
JB JNAE JC |
Если ниже Если не выше и не равно Если перенос |
CF = 1 | Нет |
JNB JAE JNC |
Если не ниже Если выше или равно Если нет переноса |
CF = 0 | Нет |
JBE JNA |
Если ниже или равно Если не выше |
CF = 1 или ZF = 1 | Нет |
JA JNBE |
Если выше Если не ниже и не равно |
CF = 0 и ZF = 0 | Нет |
Команда | Описание | Состояние флагов для выполнения перехода | Знаковый |
---|---|---|---|
JL JNGE |
Если меньше Если не больше и не равно |
SF <> OF | Да |
JGE JNL |
Если больше или равно Если не меньше |
SF = OF | Да |
JLE JNG |
Если меньше или равно Если не больше |
ZF = 1 или SF <> OF | Да |
JG JNLE |
Если больше Если не меньше и не равно |
ZF = 0 и SF = OF | Да |
- Логическое умножение
- Аналог
AND
, но результат не сохраняется. - Выставляются флаги
SF
,ZF
,PF
.
Прерывание - особая ситуация, когда выполнение текущей программы приостанавливается и управление передаётся программе-обработчику возникшего прерывания.
- аппаратные (асинхронные) - события от внешних устройств;
- внутренние (синхронные) - события в самом процессоре, например, деление на ноль;
- программные - вызванные командой
INT
;
- Аналог системного вызова в современных ОС.
- Используется наподобие вызова подпрограммы.
- Номер функции передаётся через
AH
.
Функция | Назначение | Вход | Выход |
---|---|---|---|
02 | Вывод символа в stdout | DL = ASCII-код символа | - |
09 | Вывод строки в stdout | DS:DX - адрес строки, заканчивающейся символом $ | - |
Функция | Назначение | Вход | Выход |
---|---|---|---|
01 | Считать символ из stdin с эхом | - | AL - ASCII-код символа |
06 | Считать символ без эха, без ожидания, без проверки на Ctrl+Break | DL = FF | - |
07 | Считать символ без эха, с ожиданием и без проверки на Ctrl+Break | - | AL - ASCII-код символа |
08 | Считать символ без эха | - | AL - ASCII-код символа |
10 (0Ah) | Считать строку с stdin в буфер | DS:DX - адрес буфера | Введённая строка помещается в буфер |
0Bh | Проверка состояния клавиатуры | - | AL=0, если клавиша не была нажата, и FF, если была |
0Ch | Очистить буфер и считать символ | AL=01, 06, 07, 08, 0Ah | - |