Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Ассемблер.docx
Скачиваний:
0
Добавлен:
01.04.2025
Размер:
47.44 Кб
Скачать

Ассемблер

Структура и образ памяти программы типа .EXE

ES DS PSP 256 байт

СS Сегмент IP команд

Сегмент данных

SS Сегмент SP

стека

PSP – префикс программного сегмента

  1. title from lightbulb

  2. text segment ‘code’

  3. assume CS: text, DS:data

  4. myproc proc

  5. mov AX, data

  6. mov DS, AX

  7. -----------------

  8. myproc endp

  9. text ends

  10. ----------------

  11. data segment

  12. ----------------

  13. data ends

  14. ----------------

  15. stack segment stack ‘stack’

  16. dw 128 dup (0)

  17. stack ends

  18. end myproc

2. Идентификатор программного сегмента: слово в апострофах указывает класс «программный». Класс анализируется компоновщиком для компоновки загрузочного модуля, при этом сегменты, принадлежащие одному классу, загружаются в память друг за другом

3. Сопоставляет сегментные регистры и адресуемые ими сегменты

4. Имя процедуры

5. Инициализирует сегмент данных (настраиваем регистр данных на начало сегмента данных)

а) пересылает адрес в аккумулятор

б) из аккумулятора в сегмент данных

8. Конец процедуры

9. Конец сегмента

15. Описываем сегмент стека

Структура и образ памяти программы типа .COM

CS DS ES SS PSP

256 байт

IP = 100h Сегмент

команд и данных

SP = FFFEh


title from lightbulb

text segment ‘code’

assume CS:text, DS:text

org 100h ; резервирует 256 байт PSP

myproc proc

------------------------

myproc endp

--------определения данных----------------------

text ends

end myproc

Пример

TITLE COM-PROG

CODESG SEGMENT PARA ‘CODE’

ASSUME CS:CODESG, DS:CODESG, SS:CODESG, ES:CODESG

ORG 100h

BEGIN: JMP MAIN

;---------

FLDA DW 250

FLDB DW 125

FLDC DW ?

;---------

MAIN PROC NEAR

MOV AX, FLDA ;переслать 0250 в AX

ADD AX, FLDB ; прибавить 0125 в AX

MOV FLDC, AX ; записать сумму в FLDC

RET ; вернуться в DOS

MAIN ENDP

CODESG ENDS

END BEGIN

Устройство Управления декодирует байты программы и управляет работой операционного устройства и шинного интерфейса.

Связь с внешними устройствами осуществляется через специальные тристабильные схемы, называемые буферами.

Регистр флагов

По результатам операций АЛУ аппаратно устанавливает либо сбрасывает отдельные биты в регистре флагов. Слово состояния процессора (PSW) приведено на рисунке

15 0

OF

DF

IF

TF

SF

ZF

x

AF

x

PF

x

CF

x означает, что содержимое бита не имеет значения

CF – флаг переноса (carry) устанавливается, если в результате выполнения операции из старшего бита переносится или занимается единица при сложении или вычитании, иначе CF = 0. На CF влияют также команды сдвига и умножения

PF – флаг четности (parity) равен 1, если результат операции содержит четное число двоичных единиц

AF – флаг дополнительного переноса (auxiliary) устанавливается, если есть перенос из старшего бита младшей тетрады (бит D3) в младший бит старшей тетрады (бит D4). Используется в операциях над упакованными BCD

ZF – флаг\признак нулевого результата, устанавливается в единицу, если получен нулевой результат, иначе ZF = 0

SF – флаг знака результата (sign) равен единице, если результат отрицательный, т.е. он дублирует старший знаковый бит результата

TF – флаг трассировки (отладки). Если этот флаг установлен в единичное состояние , то процессор переходит в режим пошагового выполнения команд, т.е. после выполнения каждой команды генерируется внутреннее прерывание (тип 1) через вектор, расположенный по адресу 04

IF – флаг разрешения прерывания – если флаг установили в единицу, то прерывания микропроцессора от внешних устройств разрешены (микропроцессор распознает маскируемые прерывания)

DF – флаг направления

OF – флаг переполнения установки

CF, DF, IF можно изменять программно

команды STC, STD, STI устанавливают соответствующие флаги в 1

команды CLC, CLD, CLI устанавливают соответствующие флаги в 0

Пример: сложение однобайтовых чисел

125+4=129 – выходит за пределы чисел со знаком (-128 - +127), но для беззнаковых чисел результат корректный

Перенос в бит D7 равен 1. Флаги: OF = 1, CF = 0, ZF = 0, SF = 1, AF = 1

Резервирование памяти.

count dw 1000 // помещает значение 1000 по адресу count

coef dw 5, 10, 68 //указанными числами заполняются слова

mask db 0FFh // в байт с именем mask записывается FF

mes db ‘-смещение’

// байтовая строка с текстом «смещение» начиная с адреса mes

adr dw mes

// в слове adr смещение строки первого байта строки mes

addr dd myproc

//в двойном слове помещается двухместный адрес процедуры

В первом слове – относительный адрес

Во втором -сегментный

area dw 128 dup (?) // резервируем 128 слотов память

text db 100 dup (‘#’)

//100 байт массива заполняется кодом решетки

array dw 1024 dup (256)

//массив из 1024 слов, в каждом слове 256

константы

kilo equ 1024

//kilo – константа, которой присваивается значение 1024 навсегда

offs = 80-2*12+40*2

//начальное значение offs = ... Но в тексте программы можно менять

leng = FFFh

//leng – название числа FFFF

mes db ‘ждите’

meslen = $ - mes

Использование байта в словных операциях (оператор PTR)

Bits dw F4E9h

mov ax, bits //помещает в аккумулятор F5E9

mov bh, byte ptr bits

//пересылает в старший байт регистра младший байт (E9) переменной

mov clm byte ptr bits + 1

//пересылка старшего байта (F5) в cl

addr dd myproc

// в двойное слово помещается двухсловный адрес процедуры

mov bx, word ptr addr //относительный адрес myproc

move es, word ptr addr + 2 //сегментный адрес

Все переменные адресуются младшим байтам

Система команд

Семь групп режимов адресации:

  1. Регистровая адресация

  2. Непосредственная адресация

  3. Прямая адресация

  4. Косвенная регистровая адресация

  5. Адресация по базе

  6. Прямая адресация с индексированием

  7. Адресация по базе с индексированием

Самые быстрые – регистровая и непосредственная, т.к. в этом случае операционный блок МП извлекает их либо из регистров, либо из конвейера команд

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

Регистровая адресация

Операнд извлекается из регистра

MOV AX, CX

INC CX

XCHG BX, BP

Непосредственная адресация

Константа является операндом-источником и содержится в команде

MOV CX, 500

MOV CL, -30

K EQU 1024

MOV CX, K

Прямая адресация

Исполнительный адрес является составной частью команды

MOV AX, TABLE

mem dw 0

……………….

inc mem

строгая запись

inc ds:mem

По умолчанию все смещения вычисляются относительно ds, поэтому его можно не указывать.

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

- для сегментных регистров ES, CS, SS

inc es:mem

- при обращении к памяти по известному АБСОЛЮТНОМУ адресу

mov al, ds:17h

mov bx, es:2ch

Косвенная регистровая адресация

Исполнительный адрес операнда содержится в базовом регистре BX, регистре указателя базы BP или в индексном регистре (SI или DI)

Операнды заключаются в квадратные скобки

При использовании BX, SI или DI подразумевается регистр DS

При использовании BP подразумевается регистр SS

MOV BX, OFFSET TABLE

MOV AX, [BX]

эти две команды выполняют те же действия, что и команда

MOV AX, TABLE

Адресация по базе

Исполнительный адрес вычисляется с помощью сложения значения сдвига с содержимым регистров BX или BP

MOV AX, [BX]+4 // если начальный адрес записи в BX, то в AX загрузится 5 и 6 байты от начала записи.

эта команда эквивалентна

MOV AX, 4[BX]

MOV AX, [BX+4]

Прямая адресация с индексированием

Исполнительный адрес вычисляется как сумма значений сдвига и индексного регистра (DI или SI). Тип адресации удобен при работе с таблицами, когда сдвиг указывает на начало таблицы, а индексный регистр – на её элемент

Например если TABLE – таблица байт, то последовательность команд

MOV DI, 2

MOV AL, TABLE [DI]

загрузит третий элемент таблицы TABLE в регистр AL

Адресация по базе с индексированием

Исполнительный адрес вычисляется как сумма значений базового регистра, индексного регистра и возможно сдвига. Удобен при адресации двумерных массивов

MOV AX, TABLE [BX][DX]

возможна также следующая запись

MOV AX, TABLE[BX+2][DX]

MOV AX, TABLE [BX][DX+2]

Пример 1:

MOV CX, L ;инициализация счетчика

MOV SI, -1 ; инициализация индекса

MOV AL, 20h ; код пробела

NEX: INC SI ; увеличение индекса

CMP AL, STR [SI] ; сравнение с пробелом

LOOPNE NEX ; цикл пока CX не 0 и не пробел

JNZ ST ; если CX = 0, но не пробел

Пример 2:

array db 0, 10, 20, 30, 40, 50, 60, 70, 80, 90

mov bx, 5

mov al, array[bx]

или

mov bx, offset array

mov al, 5[bx]

Пример 3:

syms db ‘ЙЦУКЕНГШЩЗХЪ’

‘QWERTYUIOP[]’

…………………………

mov bx, 12

mov si, 6

mov dl, syms[bx][si]

Циклы

Команда LOOP служит для выполнения конечного числа циклов, использует начальное значение в регистре CX. В каждом цикле команда LOOP автоматически уменьшает содержимое СХ на 1. Пока значение СХ не будет равно 0, управление передается по адресу, указанному в операнде; если в СХ будет 0, управление переходит на следующую после LOOP команду

Разновидности:

1. LOOPE (LOOPZ) – передает управление, если СХ имеет ненулевое значение и флаг нуля установлен

2. LOOPNE (LOOPZE) – передает управление, если СХ имеет ненулевое значение и флаг нуля сброшен

Пример 1:

array dw 1024 dup (?)

mov cx, 1024

lea bx, array

mov si, 0

адрес массива помещен в ВХ

null: mov [bx][si], 0 //очищаем содержимое

inc si

inc si

loop null

loop уменьшает значение СХ на 1, если в СХ не 0, то переходит на метку

Пример 2: //фрагмент программы задержки выполнения

mov cx, 10

outer: push cx // сохраняем СХ в стеке

mov cx, 0 // пересылаем в СХ 0

tun: loop tun //цикл, вычитает 1, если не 0, то на метку

pop cx //восстанавливает значение из стека СХ

loop outer