Logo GenDocs.ru

Поиск по сайту:  

Загрузка...

Шпаргалка по языку Ассемблер - файл 1.docx


Шпаргалка по языку Ассемблер
скачать (68.6 kb.)

Доступные файлы (1):

1.docx69kb.15.11.2011 22:04скачать

содержание
Загрузка...

1.docx

Реклама MarketGid:
Загрузка...
РЕГИСТРЫ

Регистры общего назначения

· AX ¾ accumulator: *, /, I/O, AH ¾ прерывания и *, / ; AL ¾ BCD

· BX ¾ base: адресация при обращении к памяти

· CX ¾ counter: счётчик; CL ¾ счётчик при сдвиге

· DX ¾ data: *, / ; I/O с портами

· BP ¾ base: работа со стеком

· SP ¾ stack: указатель на вершину стека

· SI ¾ source: адрес строки-источника

· DI ¾ destination: адрес строки-приёмника

ESI/EDI используются при работе со строками и цепочными командами

· CS ¾ code: сегмент кода

· DS ¾ data: сегмент данных

· SS ¾ stack: сегмент стека

SS:SP и SS:BP ¾ обращение к стеку, BP в “передаче параметров ч/з стек”

· EIP ¾ instruction: адрес выполняемой команды

· EFLAGS ¾ flags: регистр флагов

Þ 0 ¾ carry flag: =1, если был перенос при сложении или заём при вычитании, также служит индикатором умножения; признак беззнакового переполнения

Þ 2 ¾ parity flag: = 1, если в результате чётное число единичных битов

Þ 4 ¾ af: =1, если был перенос или заём из 3-го бита в 4-й (исп-ся в BCD)

Þ 6 ¾ zero flag: =1, если операция имеет нулевой результат

Þ 7 ¾ sign flag: = старшему биту результата

Þ 8 ¾ trace flag: если ==1, то после каждой команды проц генерирует прерыв.

Þ 9 ¾ interrupt flag: если ==1, то разрешена реакция на внешние прерывания

Þ 10 ¾ direction flag: если ==1, то автодекремент адресов при строчных опер

Þ 11 ¾ overflow flag: =1, если произошло переполнение разрядной сетки при сложении чисел с одинаковыми знаками или вычитании чисел с разными знаками; =1, если изменился знаковый бит операнда при сдвиге

Þ 12-13 ¾ input/output privilege level: уровень привилегий доступа к I/O к-дам

Þ 14 ¾ nested task: флаг вложенности задач (protected mode)


^ ОРГАНИЗАЦИЯ ПАМЯТИ

Прога может состоять из одного и более сегментов, адреса начала которых хранятся в соответствующих регистрах. МП в реальном режиме формирует 4-хкомпонентную схему адресации, при которой 20-разрядные физические адреса образуются из 4-х источников:

1. Регистры BX или BP

2. Индексные регистры: SI/DI

3. Смещение

4. CS, DS, etc...

20-разрядный физический адрес формируется путём сложения содержимого одного из сегментных регистров (сдвинутого влево на 4) и эффективного адреса.


^ ПРОГА НА ASM

Прога на ASM ¾ последовательность операторов:

1. команд (инструкций)

2. директив (псевдооператоров)

3. макрокоманд

4. комментариев

Формат директивы: [идентификатор] директива [операнд][;комментарий]

myvar db 5, 255, -1 ; переменная

Есть такие директивы:

db (1), dw (2), dd (4), dq (8), df (6) far word, dp (6) pointer, dt (10) ten byte

pole dw 1, 15h, 15, -2 ; старшие биты ¾ по СТАРШИМ адресам!

01 00

15 00

0F 00

FE FF


МАССИВЫ

выражение dup (операнд-1, ... , операнд-N)

pole dw 100 dup (1,2, dup(0))

^ ОПРЕДЕЛЕНИЕ BCD-ЧИСЕЛ

1. Упакованные: 54 = | 0101 ‘ 0100 | (младшая цифра ¾ справа)

pole db 56h, 34h, 12h = 123456

2. Неупакованные: в байте одна цифра: pole db 6,5,4,3,2,1 = 123456

pole db 36h, 35h, 34h, 33h, 32h, 31h

^ ОПРЕДЕЛЕНИЕ СТРОК СИМВОЛОВ

ar db ‘Minsk’,’$’

ОПРЕДЕЛЕНИЕ АДРЕСОВ ЯЧЕЕК ПАМЯТИ

ar1 dw 10 ; в ar1 число 10

ar2 dw ar1 ; в ar2 смещение ar1

mov AX, offset ar1

lea AX, ar1

mov AX, ar2

= одно и то же

ar1 dw 100 dup(?)

ar2 dw ?

ar3 dw ar2-ar1 ; ar3 = 200 (длина ar1)

^ ДИРЕКТИВЫ ОПРЕДЕЛЕНИЯ СИМВОЛИЧЕСКИХ ИМЁН

имя выражение equ выражение

имя выражение = выражение

a equ 500

n=1

n=n+1

Различия: equ можно использовать с числами и текстом, = ¾ только с числами ; equ нельзя переопределять, а = ¾ можно.


^ ДИРЕКТИВЫ ОПРЕДЕЛЕНИЯ СЕГМЕНТА (MASM)

имя_сегмента segment директивы

d1 segment

........

d1 ends

c1 segment

........

c1 ends

end ; метка конца проги из 2+ сегментов

В проге д/б: assume ds:d1, cs:c1 или assume ds:c1, cs:c1



см “формат директивы сегментации”


^ ФОРМАТ ДИРЕКТИВЫ СЕГМЕНТАЦИИ

имя segment [выравнивание] [комбинация] [‘класс’] [размер_сегмента]

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

· Выравнивание определяет границу адреса, начиная с которой сегмент будет загружен в память: byte (2), word (4), para (16) (= by default), page (256)

· Комбинация определяет возможность и способы объединения сегментов с одним именем. С различными именами НЕ объединяются.

private ¾ не объединяются (= by default)

public ¾ все сегменты с одним именем объединяются в один непрерывный сегмент, адресация в котором ведётся от начала первого объединённого сегментика.

stack ¾ все сегменты с одним именем объединяются в один непрерывный сегмент; отличие от public: адресация ведётся относительно SS, а SP устанавливается:

мл

ss:sp

ss:sp

вершина

начало

ст

SS:0FFFFh ¾ максимальное смещение

common ¾ все одноимённые сегменты этого типа будут загружаться в память, начиная с одного адреса, т.о. можно формировать оверлейные проги. Длина области загрузки = длине самого длинного сегмента. Все адреса накладываемых сегментов отсчитываются от одного начального адреса.

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

Достоинство public: при объединении нескольких одноимённых сегментов кода в один сегмент отсутствует необходимость изменения CS при передаче управления в сегменте кода, т.е. межсегментные переходы заменяются внутрисегментными.

Исходник-1:

d1 segment common

............

d1 ends

c1 segment public

............

c1 ends

Исходник-2:

d2 segment common

............

d2 ends

c1 segment public

............

c1 ends

Загрузочный модуль имеет следующий вид:

d1 d2

c1

c2


^ КЛАСС СЕГМЕНТА

Определяет порядок следования сегментов. Сегменты одного класса загружаются в память один за другим до момента, пока не начнётся сегменты другого класса. В качестве сегмента может быть использован любой идентификатор, взятый в кавычки. Если класс не указан, то линкер копирует в EXE сегменты в той последовательности, в какой они расположены в объектном файле.

^ АТРИБУТ РАЗМЕРА СЕГМЕНТА

use16 (default) ¾ 16-разрядная адресация, размер сегмента £ 64 Kb

use32 ¾ 32-разрядная адресация, размер сегмента £ 4 Gb

ДИРЕКТИВЫ СЕГМЕНТАЦИИ TASM

TASM может использовать MASM-директивы, которые сложны, но дают полный контроль.

Однако есть и упрощённые директивы:

· .model модель_памяти [ ] ; .model small

· .code [имя] ¾ начало/продолжение сегмента кода, по дефолту назначается CS, что является аналогом assume cs:@code ; к-во .code ¾ не ограничено

· .data ¾ начало/продолжение сегмента данных; к-во .data ¾ не ограничено

· .stack [размер] ¾ число байт, резервируемых под стек

· .fardata [имя] ¾ начало/продолжение сегмента данных типа far

Директива .model создаёт следующие идентификаторы: @code, @data, @fardata

^ МОДЕЛИ ПАМЯТИ

модель

тип кода

тип данных

tiny

near

near

small

near

near

medium

far

near

compact

near

far

large

far

far


^ ФОРМАТ МАШИННОЙ КОМАНДЫ

1b-вый префикс

КОП

байт спос. адресации

байт SIB

смещение

операнд


Однобайтовые префиксы:



· Префикс замены сегмента: отменяет неявное назначение сегментного регистра.

· Префикс разрядности адреса: уточняет разрядность адреса операнда команды (16 = default).

· Префикс разрядности операнда: указывает на разрядность операнда.

· Префикс повторения: используется командами обработки строк.

КОП (1 или 2 байта): это обязательное поле, содержит код операции.

Способ адресации:

mode

register / КОП

register / memory

7 6

5 4 3

2 1 0


Возможные значения mode:

Þ 00 ¾ EA = базовый_адрес + индексный_адрес

Þ 01 ¾ EA = 1-байтное смещение + база + индекс

Þ 10 ¾ EA = 2/4-байтное смещение + база + индекс

Þ 11 ¾ операндами являются регистры

Þ ПАМЯТЬ-ПАМЯТЬ ¾ НЕВОЗМОЖНО кроме цепочечных команд и команд одного истока.

Байт SIB: Scale Base Index ¾ масштаб индекса базы: используется для расширения возможностей адресации операндов: в защищённом режиме для определения местоположения операнда в памяти.

SS

index

base

7 6

5 4 3

2 1 0


ss ¾ поле масштаба: масштабный множитель для индексных компонент

index ¾ используется для хранения номера индексного регистра

base ¾ используется для хранения адреса базового регистра (почти любой РОН)

^ ОСОБЕННОСТИ ИСПОЛЬЗОВАНИЯ РЕГИСТРОВ И СМЕЩЕНИЙ ПРИ ВЫЧИСЛЕНИИ ЭФФЕКТИВНОГО АДРЕСА

Pentium может выполнять команды в реальном и защищённом режиме

real = 16 bit (default)

В защищённом режиме МП определяет размер выполняемой команды, анализируя бит D в дескрипторе сегмента. D=0 => 16, D=1 (default) => 32

Однако МП может выполнять команды любого режима, анализируя специальный префикс размера адреса и операнда. Данные префиксы отменяют значение бита D на основе заданных в самой команде значений. TASM автоматически добавляет эти префиксы в OBJ-код.

16 разрядов

32 разряда

Базовые регистры

BX, BP

Любой РОН кроме ESP

Индексные регистры

SI, DI

Любой РОН кроме ESP

Масштаб

НЕТ

1, 2, 4, 8

Смещение

0, 8, 16 бит

0, 8, 32 бит

EA = база+(индекс*масштаб)+смещение

^ РЕЖИМЫ АДРЕСАЦИИ

Способ определения операнда ¾ режим адресации.

1. Регистровая адресация: МП извлекает/загружает операнд из/в регистр.

mov AX, BX ; Указатель на регистры находится в самой команде

2. Непосредственная адресация: операнд задаётся в самой команде

mov CX, 100 ; Непосредственный операнд м/б только источником

При пересылке ASM дублирует старший значащий бит операнда-источника до заполнения приёмника.

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

3. Прямая адресация: используется в том случае, когда операндом служит имя переменной:

ar dw ?

mov AX, ar

Тут для вычисления EA используется только смещение, находящееся непосредственно в команде. Прямая адресация бывает двух видов:

а) Относительная: обычно используется в командах условного перехода. В поле смещения команды находится 8, 16, 32-бита. Адрес перехода формируется так: к содержимому EIP/IP прибавляется смещение: jg метка

б) Абсолютная: в самой машинной команде находится адрес: mov AX, pole

Остальные виды адресации являются косвенными, т.е. в самой команде может храниться лишь часть EA, а остальные составляющие находятся в одном из базовых или сегментных регистров (или одновременно в обоих).

4. Косвенная базовая адресация: EA может находиться в любом РОНе, кроме регистров работы со стеком: mov AX, [BX] ; В AX загружается ячейка памяти размером два байта по адресу EA=BX

5. Косвенная базовая адресация со смещением: EA = сумме значений смещения и базового адреса: EA = (BX) + 4h ........

mov AX, ar1[BX] => EA = (BX) + ar1

6. Косвенная индексная адресация со смещением: EA = сумме значений смещения и РОНа. Это позволяет масштабировать содержимое индексного регистра: mov AX, ar[SI*4] ; EA = AR + SI*4

7. Косвенная базовая индексная адресация: EA = сумме двух РОНов

mov AX, [BX][DI] ; EA = (BX)+(DI)

8. Косвенная базовая индексная адресация со смещением:

mas dw 1000 dup(?)

mov AX, mas[BX][DI] ; EA = (BX)+(DI)+mas



Самый быстрый способ адресации ¾ регистровый. Самый медленный ¾ № 8.

^ АРИФМЕТИЧЕСКИЕ КОМАНДЫ

Арифметические операции могут выполняться над операндами следующих типов:

· двоичные числа без знака

· двоичные числа со знаком

· упакованные 10-тичные числа без знака

· неупакованные 10-тичные числа без знака

Логические схемы АЛУ выполняют операцию сложения, считая, что оба операнда ¾ беззнаковые.

^ ПЕРЕПОЛНЕНИЕ ПРИ СЛОЖЕНИИ (БЕЗЗНАКОВОМ)

CF ¾ признак переноса при сложении или заёма при вычитании, т.е. переполнения

OF ¾ признак знакового переполнения

В операциях “+” и “-” (знаковых) OF показывает, находится ли результат внутри диапазона представимых чисел: 225+1=0, CF=1, OF=0;

Т.о. при сложении может быть знаковое переполнение, если знаки операндов одинаковы и само переполнение заключается в том, что при сложении положительных чисел получается отрицательная сумма, т.е. есть перенос в старший бит, но нет переноса из старшего бита (>127)

При сложении отрицательных чисел получается положительный результат, т.е. есть перенос из старшего бита, но нет переноса в старший бит (<-128)

СЛОЖЕНИЕ

· add ПРИЁМНИК, ИСТОЧНИК ; модифицируются AF, CF, OF, SF, ZF, DF

· adc ПРИЁМНИК, ИСТОЧНИК ; модифицируются AF, CF, OF, SF, ZF, DF, к арифметической сумме операндов добавляется 1, если к началу операции сложения CF=1 ; Т.к. данная команда использует перенос от предыдущего операнда, то она может использоваться для сложения операндов > 64 бита.

Пример сложения с adc:

ar1 dd ?

ar2 dd ?

sum dd ?

mov EAX, ar1

add EAX, ar2

mov sum, EAX

mov EAX, ar1+4

adc EAX, ar2+4

mov sum+4, EAX

· inc ПРИЁМНИК ; увеличение значения на 1

ВЫЧИТАНИЕ

· sub ПРИЁМНИК, ИСТОЧНИК

· sbb ПРИЁМНИК, ИСТОЧНИК ; вычитание с заёмом: содержимое источника вычитается из содержимого приёмника и из результата вычитается 1, если CF=1 до начала операции

· dec ПРИЁМНИК ; уменьшение значения на 1

· neg ПРИЁМНИК ; отрицание приёмника: изменяет знак операнда, т.е. операнд вычитается из нуля. Если операнд =0, то знак не меняется.

-(-128) => переполнение, OF=1

· cmp ПРИЁМНИК, ИСТОЧНИК ; Из содержимого приёмника вычитается содержимое источника и результат никуда не помещается

УМНОЖЕНИЕ

· mul ИСТОЧНИК ; (ИСТОЧНИК=регистр или ячейка памяти)

Выполняет беззнаковое умножение источника (b, w, dw) и аккумулятора.

Если ИСТОЧНИК ¾ байт, то в качестве аккумулятора берётся AL, а результат двойной длины помещается в AH, AL и т.д.

ИСТОЧНИК

АККУМУЛЯТОР

результат

Байт

AL

AH AL

Слово

AX

DX AX

Двойное слово

EAX

EDX EAX

Операнды рассматриваются как двоичные беззнаковые числа. Результат ВСЕГДА положительный. Если старшая половина результата AH, DX, EDX содержит информацию, отличную от нуля, то CF=1 и OF=1, иначе CF=OF=0, т.е. когда CF=OF=1, то AH, DX, EDX содержат значимые числа результата; состояние остальных флагов не определено.

· imul ¾ умножение со знаком: аналогично mul, но операнды знаковые. Если старшая половина результата (AH, DX, EDX) не является расширением младшей, то CF=OF=1, иначе CF=OF=0, т.е. CF=OF=1 если в старшей части есть значимые цифры:

mov BL, 3 | mov AL, 161 | mul BL ; Теперь в AH=01, в AL=E3 ; CF=1, OF=1

mov BL, 3 | mov AL, 161 | imul BL ; Теперь AH=FE, AL=E3, OF=1, CF=1

Т.о. если множимое и множитель совпадают по знаку, то mul и imul дают одинаковый результат. Если знаки разные, то mul даёт “+”, а imul “-” результат.

ДЕЛЕНИЕ

· div ИСТОЧНИК (делитель) ; Делит b, w, dw без знака

АККУМУЛЯТОР

(делимое)

делитель

ЧАСТНОЕ

ОСТАТОК

AX

Байт

AL

AH

DX AX

Слово

AX

DX

EDX EAX

Двойное слово

EAX

EDX

Если значение частного превосходит вместимость регистра, в который помещается частное, то возникает ситуация деления на 

ноль и генерируется Interrupt0. Частное и остаток в данном случае не определены. После div все флаги не определены.

· idiv ИСТОЧНИК ; Делит b, w, dw со знаком ; Здесь возможно переполнение.

Знак частного определяется по алгебраическому правилу. Остатку присваивается знак делимого. Все флаги не определены.

Переполнение возникает в следующих ситуациях:

1. Делитель = 0

2. При делении байтов без знака делимое по меньшей мере в 256 раз превышает делитель (для байта).

3. При делении байтов со знаком частное вне [-128, 127] и т.д.

Пример:

mov AX, 512 ; AX = 0200

mov BL, 160 ; BL = A0

div BL ; AX = 2003 ; 32 (остаток) и 3 (ответ)

Пример:

mov AX, 512 ; AX = 0200

mov BL, 160 ; BL = A0

idiv BL ; AX = 20FB ; 32 и -5

^ КОМАНДЫ ПРЕОБРАЗОВАНИЯ ТИПОВ

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

· cbw ¾ convert byte to word ; заполняет AH битами = знаку AL

· cwd ¾ convert word to double word ; заполняет DX битами = знаку AX

· cwde ¾ convert word to double word ; заполн. старшую часть EAX знаком AX

· cdq ¾ convert double to quarter ; заполняет EDX знаком EAX

^ ЛОГИЧЕСКИЕ КОМАНДЫ

Эффективное преобразование отдельных битов:

· or, and, xor ПРИЁМНИК ИСТОЧНИК ;

· test ПРИЁМНИК ИСТОЧНИК ; приёмник AND источник à никуда

· nop ; инвертирует все биты

SF, ZF, CF устанавливаются по обычным правилам, остальные ¾ сбрасываются.

Чаще всего логические команды используются для селективной установки битов, инвертирования, сброса и проверки битов в приёмнике в соответствии с двоичным набором источника. МАСКА ¾ источник с битами J

· or ¾ селективная установка ; or AL, 101b (биты 0 и 2 стали =1)

· xor ¾ селективное инвертирование (биты маски, соответствующие инвертируемым должны быть =1); xor AX, AX = обнуление.

· and ¾ селективный сброс бит (биты маски, соответствующие инвертируемым должны быть =0)

· test ¾ используется в селективной проверке бит. Он формирует ZF=0, если любой единичный бит маски соответствует единичному биту переменной, иначе ZF=1 (т.е. выполняется побитовое логическое and (см. Зубков))

^ КОМАНДЫ СДВИГА

· sal ПРИЁМНИК, СЧЁТЧИК_СДВИГА ¾ shift arithmetic left ; старшие биты теряются, но последний сохраняется в CF, а справа операнд дополняется нулями; СЧЁТЧИКОМ_СДВИГА может быть CL или непосредственный операнд. OF=1, если знаковый бит меняет значение. OF имеет смысл только в случае сдвига на один бит.

· shl ¾ shift logical left ; алгоритм аналогичен sal

· sar ¾ shift arithmetic right ; младшие биты теряются, но последний сохраняется в CF, а слева происходит дублирование знака операнда.

· shr ¾ shift logical right ; слева операнд дополняется НУЛЯМИ, а знаковый бит НЕ дублируется.

Сдвиг влево на L разрядов эквивалентен умножению на 2L, а сдвиг вправо эквивалентен делению на 2L ;

Логический сдвиг вправо (shr) соответствует div, а арифметический (sar) соответствует idiv, но есть отличия в выполнении sar и idiv.

Например: деление -5 на 2 с помощью idiv даст -2, а sar даст 3:

5: 0000’0101 ; -5: 1111’1011

-3: 1111’1101 ; 3: 0000’0011

Различие в том, что idiv округляет все числе по направлению к нулю, а sar округляет все “+” числа к нулю, а “-” числа ¾ от нуля.

^ КОМАНДЫ ЦИКЛИЧЕСКОГО СДВИГА

В отличие от команд сдвига тут выдвигаемые биты добавляются с другой стороны операнда. Последний выдвигаемый бит сохраняется в CF.

· rol ¾ rotate left: CL=4, F123 à 123F, CF=1

· ror ¾ rotate right

· rcl ¾ rotate through carry left: сдвиг циклический влево через перенос

· rcr ¾ rotate through carry right: сдвиг циклический вправо через перенос

^ КОМАНДЫ ПЕРЕХОДОВ

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

Смещение находится в команде перехода.

В общем случае переходы бывают:

1. short ¾ [-128, 127] от следующей за командой перехода командой

EA = IP + смещение_метки

2. near ¾ в любую точку текущего сегмента

3. far ¾ межсегментный переход: смещение=новое_значение_CS+само_смещ.

^ БЕЗУСЛОВНЫЙ ПЕРЕХОД

jmp АДРЕС ; Есть 5 форматов команды безусловного перехода ; неявно ¾ near

1. jmp short МЕТКА ¾ внутрисегментный прямой короткий переход, смещение в самой команде. МЕТКА указывает на первый байт новой команды. IP=EA=(IP)+8битное_смещение ; (IP) указывает на следующую за jmp команду.

2. jmp near ptr МЕТКА ¾ внутрисегментный прямой близкий переход

EA=(IP)+16битное_смещение

3. jmp МЕТКА ¾ внутрисегментный косвенный переход: МЕТКА указывает на ячейку памяти, содержащую эффективный адрес (EA) перехода

4. jmp far ptr МЕТКА ¾ межсегментный прямой далёкий переход. Новое CS и IP находится в самой команде. МЕТКА указывает на команду, на которую осуществляется переход. Переход осуществляется двумя регистрами: CS и IP.



5. jmp МЕТКА ¾ межсегментный косвенный переход: МЕТКА указывает на ячейку памяти, состоящую из двух слов. Первое слово загружается в IP, а второе в CS

В случаях 3 и 5 тип перехода определяется типом операнда.

^ КОМАНДЫ УСЛОВНОГО ПЕРЕХОДА

Команды условного перехода могут осуществлять переход в пределах текущего кодового сегмента, т.е. прямой near переход.

b = below = ниже

a = above = выше (знаковые числа)

l = less = меньше

g = greater = больше

1. je/jz МЕТКА ¾ перейти по равенству или по ZF=1

2. jne/jnz МЕТКА ¾ перейти если не равно или если не нуль.

3. js МЕТКА ¾ SF=1 (отрицательное число) => переход

4. jns МЕТКА ¾ SF=0 => переход

5. jo МЕТКА ¾ OF=1 => переход

6. jno МЕТКА ¾ OF=0 => переход

7. jb/jna/jc ¾ перейти если ниже, менее или равно, CF=1

8. jnb/jae/jnc ¾ перейти если не ниже, выше или равно, CF=0

9. jbe/jna ¾ перейти если ниже или рано, не выше, т.е. (CF or ZF)=1

10. jl/jng ¾ перейти если меньше, не больше

11. jg/jle ¾ перейти если больше, не меньше


^ КОМАНДЫ ЦИКЛОВ

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

1. loop ОПЕРАНД ; Алгоритм: уменьшается значение ECX/CX на 1 и передаётся управление на метку-операнд. Переход осуществляется на [-128, 127] байт от следующей за loop команды. Выход ¾ если ECX/CX = 0

mov CX, 100 ; выполнить цикл 100 раз

ECX/CX выполняет роль счётчика. Если случайно CX=0, то цикл выполниться 65536 раз. МП, выполняя loop, уменьшит CX от 0 до FFFFh и, т.к. CX¹0, начнётся повторение цикла. Для исключения таких ситуаций используются две команды услов. перехода: jcxz МЕТКА и jecxz МЕТКА; Они осуществляют переход, если содержимое CX = 0, т.е. проверяется содержимое CX, а не флаги.

2. loopz / loope МЕТКА ¾ выполнять цикл пока CX¹0 / флаг ZF=0;

3. loopnz / loopne МЕТКА ¾ выполнять цикл пока CX¹0 / флаг ZF=1;

^ ОРГАНИЗАЦИЯ ВЛОЖЕННЫХ ЦИКЛОВ

Написать прогу, определяющую количество цифр в массиве ASCII-текста:

ar1 db 1000 dup (?)

xor AX, AX

mov CX, 1000

pov1:

mov BX, CX

dec CX

cmp ar1[BX],’0’

jl pov2

cmp ar1[BX],’9’

jg pov2

inc AX

pov2:

loop pov1;

Двумерный случай: подсчитать суммы элементов строк массива (5 строк, 4 столбца):

arr dw 20 dup(?)

sums dw 5 dup(0)

mov SI, 0

mov CX, 5

mov BX,0

again1:

push CX

mov CX, 4

xor DI, DI

xor AX, AX

again2:

add ax, word ptr arr[BX][DI]

add DI,2

loop again2

mov word ptr summs [SI], AX

add BX, DI

pop CX

add SI, 2

loop again1

^ КОМАНДЫ ОБМЕНА ДАННЫМИ

КОМАНДЫ ПЕРЕСЫЛКИ ДАННЫХ

1. mov ПРИЁМНИК, ИСТОЧНИК

В данной команде запрещены следующие сочетания операндов:

· ЯЧЕЙКА_ПАМЯТИ, ЯЧЕЙКА_ПАМЯТИ ¾ такое допустимо лишь в цепочных командах

· нельзя загружать непосредственно адресуемый операнд в регистр сегмента: такое НЕЛЬЗЯ:

d1 segment

mov DS, d1

d1 ends

· нельзя пересылать содержимое одного сегментного регистра в другой

· нельзя использовать CS в качестве приёмника

2. xchg ОПЕРАНД_1, ОПЕРАНД_2 ¾ меняет местами операнды

^ ОПРЕДЕЛЕНИЕ РАЗМЕРА ДАННЫХ

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

1. Если один операнд ¾ регистр, то размер = размеру регистра: mov AL, 5

2. Если в качестве операндов mov используются именованные ячейки памяти:

ar1 db ?

ar2 dw ?

mov ar1, 5 ; 1 байт

mov ar2, 2 ; 2 байта

Но бывают случаи, когда размер используемых данных не определён.

mov [BX], 5 ; неизвестно, сколько байт пересылается

В ASMе есть средства для явного указания количества байт, участвующих в операции. Для этого используется директива ptr:

Синтаксис: ИМЯ_ТИПА ptr ВЫРАЖЕНИЕ ; mov word ptr [BX], 5



ИМЯ_ТИПА: byte, word, dword, ... , near, far ;

ВЫРАЖЕНИЕ: переменные элементы, имеющие тип ИМЯ_ТИПА

^ КОМАНДЫ ЗАГРУЗКИ АДРЕСОВ И УКАЗАТЕЛЕЙ

Данные команды работают с адресами.

1. lea РЕГИСТР, ПАМЯТЬ ¾ load effective address: возвращает в РЕГИСТР смещение ПАМЯТИ относительно начала сегмента

lea AX, ar1

lea AX, ar1[DI] ; В AX (смещение ar1 + DI)

^ КОМАНДЫ ЗАГРУЗКИ УКАЗАТЕЛЯ И СЕГМЕНТНЫХ РЕГИСТРОВ

1. lds РЕГИСТР, ПАМЯТЬ ; Считывает из памяти dword и загружает первые 16 бит в указанный РЕГИСТР, а следующие 16 бит ¾ в DS

2. lgs РЕГИСТР, ПАМЯТЬ ; ---“--- , а следующие 16 бит ¾ в GS

3. lfs РЕГИСТР, ПАМЯТЬ ; ---“--- , а следующие 16 бит ¾ в FS

4. lss РЕГИСТР, ПАМЯТЬ ; ---“--- , а следующие 16 бит ¾ в SS

^ ТАБЛИЧНЫЕ ПРЕОБРАЗОВАНИЯ ДАННЫХ

Для организации перекодирования из одного кода в другой используется:

xlat ИМЯ_ТАБЛИЦЫ_ИСТОЧНИКА ; xlat выбирает байт из таблицы источника и загружает его в AL. Перед выполнением xlat начальный адрес должен быть в BX, а номер извлекаемого байта в AL, т.е. в AL перед выполнением xlat находится смещение извлекаемого из таблицы байта.

Написать прогу перекодировки из ASCII в EBCDIC:

TABL db 48h dup(?)

db 0F0h

db 0F1h

db 0F2h

.............

ar1 db 1000 dup(?)

ar2 db 1000 dup(?)

lea BX, TABL

mov CX, 1000

mov SI, 0

pov:

mov AL, ar1[SI]

xlat TABL

mov ar2[SI], AL

inc SI

loop pov

^ ДИРЕКТИВЫ ПЕРЕКЛЮЧЕНИЯ ТИПА МИКРОПРОЦЕССОРА

По умолчанию TASM поддерживает только команды 8086.Каждый последующий “старший” МП поддерживает все команды “младших”, а также расширяет возможности старых команд. В целом, код для “младших” моделей компактнее и производительнее. Для поддержки системы команд, отличной от 8086, или команд сопроцессора используются директивы:

.286, .386, .486, .586p, .387 (7=сопроцессор) и т.д.

Данные директивы м/б вставлены в любом месте исходного текста и начинают действовать с той точки, где они вставлены в исходник. В исходнике м/б указано несколько директив типа МП:

mov AX, ar1 ; 8086

.386

mov EAX, ar2 ; 80386

.8086

^ КОМАНДЫ РАБОТЫ СО СТЕКОМ

Стек ¾ область оперативной памяти, предназначенная для временного хранения данных. Для работы со стеком используются регистры: SS, SP/ESP, BP/EBP

Размер стека £ 64Kb в реальном режиме, и £ 4Gb в защищённом.

В каждый момент времени доступен только один стек, адрес которого ¾ в SS.

Структура стека имеет вид:

младшие адреса

КОД

ДАННЫЕ

SS:0000

SS:SP --------------------à

SS:0FFFFh

вершина стека

дно стека

СТЕК

старшие адреса

SP растёт в сторону 0000, т.е. ; Регистры ESP/SP указывают на вершину стека, т.е. содержат смещение, по которому в стек был занесён последний элемент данных. Для адресации используется SP или ESP в зависимости от use16 / use32. BP/EBP используется в случае произвольного доступа к элементам стека и предназначен для передачи параметров подпрограммам через стек.

^ КОМАНДЫ ЗАНЕСЕНИЯ ДАННЫХ В СТЕК

1. push ИСТОЧНИК ¾ помещает содержимое регистра (2/4 байта), ячейки памяти (2/4) или непосредственный операнд (2/4) на вершину стека. При этом перед занесением информации в стек значение SP/ESP уменьшается на 2/4 (в зависимости от use16 / use32).

2. pusha ¾ заносит в стек группу: AX, CX, DX, BX, SP, BP, SI, DI ; Значение SP до выполнения pusha

3. pushad ¾ заносит в стек EAX, ECX, EDX, EBX, ESP, EBP, ESI, EDI ; Это всё ¾ начиная с 386-го проца.

4. pushf ¾ помещает на вершину стека регистр флагов (2 байта)

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

5. pushfd ¾ сохраняет EFLAGS (4 байта).

^ КОМАНДЫ ИЗВЛЕЧЕНИЯ ДАННЫХ ИЗ СТЕКА

1. pop ПРИЁМНИК ; Содержимое вершины стека пересылается в опренд-приёмник, а затем значение SP/ESP увеличивается на 2/4

Обычно push и pop используются парами. При этом с помощью pop данные извлекаются в порядке, обратном их помещению push.

2. popa ¾ обратно pusha

3. popad

4. popf

5. popfd


^ КОМАНДЫ ВВОДА/ВЫВОДА ПРИ РАБОТЕ С ПОРТАМИ

Каждое устройство ввода/вывода в общем имеет один или несколько регистров, доступ к которым осуществляется через адресное пространство ввода/вывода ¾ 8, 16, 32-разрядные регистры. Под портом ввода/вывода понимается специальный аппаратный регистр, который используется для взаимодействия с внешним устройством. Адресное пространство ввода/вывода состоит из 216=56536 адресов.

1. in АККУМУЛЯТОР, ПОРТ ; Операндом может быть или непосредственный операнд 0-256 или DX. Использование DX 

позволяет задать любой порт. Байт, слово, д-слово передаётся из порта ввода/вывода в AL, AH, AX, EAX; Размер передаваемых данных определяется размером аккумулятора.

2. out ПОРТ, АККУМУЛЯТОР ; Передаёт байт, слово д-слово в порт из AL, AH, AX, EAX

^ КОМАНДЫ ОБРАБОТКИ СТРОК (ЦЕПОЧЕЧНЫЕ ПРИМИТИВЫ)

Позволяют работать со строками длиной до 64Kb за одно выполнение команды.

Эти команды называются примитивами, т.к. без префикса повторения rep они оперируют лишь одним b, w, dw; Использование префикса позволяет многократно выполнить команду обработки строк аппаратным способом и т.о. гарантируется более быстрое выполнение, чем в случае программного цикла. Независимо от формата примитива операнды определяются SI, DI, ES, DS;

МП аппаратно предполагает, что строка-источник размещается в сегменте данных, и для её адресации используется пара DS:SI, а строка-приёмник размещается в дополнительном регистре и адресуется ES:DI ;

Применение различных сегментных регистров для источника и приёмника позволяет размещать две цепочки в разных сегментах => max длина = 64 Kb

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

Строковые команды автоматически модифицируют содержимое SI/DI на 1/2/4 байта с целью доступа к следующему элементу строки. При этом DF определяет:

1. DF = 0 : содержимое SI/DI увеличивается на 1/2/4

2. DF = 1 : содержимое SI/DI уменьшается на 1/2/4

^ ПРЕФИКСЫ ПОВТОРЕНИЯ

Префикс повторения представляет собой не команду, а однобайтовый идентификатор, который заставляет МП выполнять аппаратное повторение обработки строки, что значительно сокращает время по сравнению с программно организованными циклами. При использовании префикса повторения содержимое CX уменьшается на 1 после каждого повторения команды обработки строк. В CX должно быть загружено требуемое число повторений до выполнения строковой команды. Если CX=0, то команда НЕ ВЫПОЛНИТСЯ, и управление передастся на следующую команду: ar1 в [ES:DI], ar2 в [DS:SI]

1. rep СТРОК_КОМНДА ¾ повт. команду, пока CX¹0: rep movs ar1,ar2 см.

2. repz / repe ¾ повторять команду, пока CX¹0 / ZF=1 : используется в сочетании с командами cmps (сравнение строк) и scas (сканирование).

mov CX, 100 | repe cmps ar2,ar1 ; Поэлементно сравнивается ar2 и ar1, пока не будет просмотрено 100 пар элементов или пока не встретятся несовпадающие элементы.

3. repne / repnz ¾ повторять, пока CX¹0 / ZF=0

4. cld ¾ clear direction flag : DF=0 (increment)

5. stp ¾ setup direction flag : DF=1 (decrement)

^ ПЕРЕСЫЛКА СТРОК

· movs ПРИЁМНИК (ES:DI), ИСТОЧНИК (DS:SI) : без rep команда может пересылать 1/2/4 байта

· movsb ¾ без операндов

· movsw ¾ без операндов

· movsd ¾ без операндов

Перед использованием rep надо сделать:

mov SI, offset ar1

mov DI, offset ar2

^ КОМАНДЫ ЗАГРУЗКИ СТРОК

1. lods ИСТОЧНИК ¾ загружает элемент строки источника (b, w, dw), адресуемый SI в AL, AX, EAX ; При этом SI указывает на следующий элемент строки

2. Имеются безоперандовые: lodsb, lodsw, lodsd

^ СОХРАНЕНИЕ СТРОК

1. stos ПРИЁМНИК ¾ содержимое регистра AL, AX, EAX (в зависимости от типа операнда) помещается в элемент строки, адресуемый DI, при этом DI после выполнения команды модифицируется.

2. Имеются безоперандовые: stosob, stosw, stosd

^ СРАВНЕНИЕ СТРОК

1. cmps ПРИЁМНИК (DI), ИСТОЧНИК (SI) ¾ вычитает b, w, dw приёмника из источника. Работает обратно cmp. Содержимое строк не меняется.

2. Имеются безоперандовые: smpsb, cmpsw, cmpsd

Модифицируются флаги: AF, OF, PF, SF, ZF

G ~ A ; L ~ B

^ ИСТОЧНИК ? ПРИЁМНИК

без знака

со знаком

>

ja

jg

³

jae

jge

<

jb

jl

£

jbe

jle

=

je


^ СКАНИРОВАНИЕ СТРОК

1. scas ПРИЁМНИК ¾ вычитает элемент строки приёмника (b, w, dw), адресуемый DI, из содержимого AL, AX, EAX ; При этом содержимое строки приёмника и регистра не меняется, модифицируются флаги: AF, OF, PF, SF, ZF ; Данные флаги отражают соотношение элемента строки и регистра. Это может быть использовано для поиска элемента строки.

2. Имеются безоперандовые: scasb, scasw, scasd

^ ВВОД ЭЛЕМЕНТА ЦЕПОЧКИ ИЗ ПОРТА

1. ins ПРИЁМНИК (DI), ПОРТ (DX) ¾ вводит элемент цепочки из порта, номер которого указан в DX. При этом после пересылки ins производит коррекцию DI на 1/2/4 байта.

2. Имеются безоперандовые: insb, insw, insd

^ ВЫВОД ЭЛЕМЕНТА ЦЕПОЧКИ В ПОРТ

1. outs ПОРТ (DX), ИСТОЧНИК (SI) ¾ выводит элемент цепочки в порт, номер которого указан в DX.

2. Имеются безоперандовые: outb, outw, outd

^ АРИФМЕТИКА В BCD-ЧИСЛАХ



BCD-числа ¾ вид представления информации, в основу которого положен принцип кодирования каждой 10-тичной цифры числа 2-ичной тетрадой. При этом каждый байт может содержать одну или две десятичные цифры => имеется два формата:

1. Упакованный: в байте две 10-тичные цифры: 25 = 0010’0101

2. Неупакованный: в байте одна 10-тичная цифра: 5 = 0000’0101

125: Неупакованный: pole db 5, 2, 1 ; мл 05|02|01 ст

1256 : Упакованный: pole db 56h, 12h ; 56|12

pole db 125 => 7|D

ar db 3 dup(?) ; введём 125 в ASCII : 35|32|31

^ АРИФМЕТИКА НЕУПАКОВАННОГО BCD

Специальных арифметических команд для работы с BCD нет => необходимо использовать обычные + - * / , но при этом, если мы работаем с BCD, необходимо делать коррекцию. ASCII à 2-ичное число à ASCII

^ КОМАНДЫ КОРРЕКЦИИ

1. aaa ¾ коррекция неупакованного BCD при сложении. Преобразует значение AL в корректное неупакованное 10-тичное число. При этом AH=0. Если результат >9, то CF=1. Модифицируются AF, CF.

2. aas ¾ коррекция неупакованного BCD при вычитании. Преобразует находящийся в AL результат операции вычитания двух неупакованных чисел в корректное неупакованное число в AL. Если результат >9, то CF=1. Модифицируются AF, CF.

^ ПРИМЕР СЛОЖЕНИЯ НЕУПАКОВАННЫХ BCD-ЧИСЕЛ

op1 db 5, 1 ; 15

op2 db 6, 2 ; 26

sum db 3 dup (0)

xor SI, SI

mov CX, 2

pov:

mov AL, op1[SI]

adc AL, op2[SI]

aaa

mov sum[SI], AL

inc SI

loop pov

adc sum[SI], 0

Если результат сложения двух неупакованных BCD чисел лежит в диапазоне [0;9], то он верен: 03+05=08, CF=0 ; Тогда коррекция не требуется. Но если результат превышает 9, то нужно использовать aaa-коррекцию (+6, если CF=1)

0011

+ 1001

= 1100 ; 12

+ 0110

=10010 ; Левая единичка учтётся при adc sum[SI],0

^ КОРРЕКЦИЯ НЕУПАКОВАННЫХ BCD-ЧИСЕЛ ПРИ УМНОЖЕНИИ

aam ¾ корректирует результат предшествующей операции умножения двух корректных 10-тичных неупакованных цифр. Для выполнения преобразования aam делит AL на 10 и запоминает частное в AH, а остаток в AL. Старшие полубайты перемножаемых цифр д/б предварительно обнулены.

Пример: умножение одноразрядных неупакованных чисел: 5*7 = 35 = 2316 ;

mov AL, 5 ; AH:AL = 00:05

mov BL, 7 ; BH:BL = 00:07

mul BL ; AX = 00|23

aam ; AX = 03|05 ¾ корректное число ; 2316/10 = 3 и остаток = 5

Так можно делать преобразование ASCII в BCD.

^ КОРРЕКЦИЯ НЕУПАКОВАННЫХ BCD-ЧИСЕЛ ПРИ ДЕЛЕНИИ

aad ¾ должна выполняться ПЕРЕД операцией деления. aad преобразует неупакованное делимое в двоичное значение и загружает его в AL. С этой целью старшая цифра делимого (находится в AH) умножается на 10 и полученный результат добавляется к младшей цифре (находится в AL), затем AH обнуляется.

3510 / 7 :

mov BL, 7 ; AX = 03|05

aad ; AX = 00|23

div BL ; AX = 00|05

^ ВИДЫ ПРЕДСТАВЛЕНИЙ ЧИСЕЛ И ПРЕОБРАЗОВАНИЙ

125 ; ASCII

31|32|35 ; ASCII

01|02|05 ; неупакованное BCD

ASCII à неупакованное BCD à 2-ичное à арифметика à 2-ичное à неупакованное BCD à ASCII

^ АРИФМЕТИКА УПАКОВАННЫХ BCD-ЧИСЕЛ

В одном байте ¾ две цифры.

1234

ar1 db 34h, 12h ¾ упакованное; 04h, 03h, 02h, 01h ¾ неупакованное

Специальных + - * / арифметических команд для упакованных BCD нет.

Существует две команды коррекции для сложения и вычитания. Для умножения и деления ¾ НЕТ!

1. daa ¾ коррекция при сложении: корректирует результат предшествовавшего сложения двух упакованных цифр, содержащихся в AL. Затем содержимое AL преобразуется в пару корректных 10-тичных цифр; daa анализирует AF, CF и тетрады на запрещённые комбинации и, если необходимо, прибавляет 6 для коррекции: может модифицировать любые флаги кроме OF.

op1 db 17h

op2 db 15h

17 ; 0001’0111

+ 15 ; 0001’0101

= ; 0010’1100 ; 2C ; C ¾ запрещённая комбинация

+ 6 ; 0000’0110

= 32 ; 0011’0010 ; 32 = OK

Или:

19 ; 0001’10001

+ 19 ; 0001’10001

= ; 0011’0010 ; 32 ; AF=1 (3à4)

+ 6 ; 0000’0110

= 38 ; 0011’1000 ; 38 = OK

2. das ¾ коррекция при вычитании: работает по аналогичному алгоритму.

СТРУКТУРЫ

Структура представляет собой набор полей байтов, определённый одним именем. Объявление состоит из двух этапов:

1. Объявление типа структуры или шаблона.

2. Объявление собственно структуры.

имя_типа_структуры sctruc

определение полей данных



имя_типа_структуры ends

Каждое поле внутри структуры может иметь или не иметь имя. Определённые поля могут быть проинициализированы.

d1 struc

a1 db ?

a2 dw 5

a3 db ‘Minsk’

d1 ends

Объявление шаблона НЕ резервирует память. Сама структура создаётся при объявлении структурной переменной:

имя_структ_переменной имя_структуры <[Значение-1], [Значение-2], ...>

С помощью данного объявления создаётся структурная переменная в соответствии с полями шаблона. Размер определяется как сумма длин полей. При этом имя структурной переменной указывает на младший байт структуры. В угловых скобках перечисляется список значений полей, разделённых запятыми. Скобки обязательны даже при отсутствии начальных значений.

var1 d1 <1, 3, > ; a1=1, a2=3 , a3 ¾ без изменений

В шаблоне задаётся неявная инициализация полей, а при определении структурных переменных могут быть заданы новые значения, подавляющие неявные. Можно задать массив структур: 100 dup (< >) ; Структурные переменные могут быть операндами выражений.

^ ОБРАЩЕНИЕ К ПОЛЯМ СТРУКТУРЫ

имя_структурной_переменной.имя_поля

mov AL, var1.a1

xor SI, SI

mov BX, offset var1

mov AL, [BX].a1[SI]

Пусть в d1 : a3 db 1000 dup(?), и надо в

10-е место a3 5-й структуры загнать $

Решение:

lea BX, var1+1003*4

mov AL, ‘$’

mov SI, 9

mov [BX].a3[SI], AL

ЗАПИСИ

Запись ¾ набор полей, объединённых одним именем.

Объявление: record

Объявление собственно записи:

имя_типа_записи record имя_поля:длина[=значение]

Описания полей отделяются запятыми.

drec record ст a1:3,a2:8=’a’,a3:1=1 мл ; Возможные длины записи: 8/16/32 бита

3 8 1

| a1 | a2 | a3

15 1

Собственно переменная создаётся так:

имя_записи тип_записи < >

var1 drec <7, ‘b’, 0> ; или в {таких скобках} и a3=0, т.е. нестрогий порядок

Использование dup позволяет создавать массивы записей:

var2 drec 100 dup (<>)

Обращаться напрямую (var2.a2) НЕЛЬЗЯ!

^ ПРИМЕР ИСПОЛЬЗОВАНИЯ ЗАПИСИ В КАЧЕСТВЕ ОПЕРАНДА

d1 record a1:3, a2:5, a3:7

var d1 <1,2,3>

1. Использование имени записи в качестве операнда:

mov AX, var

AX: 0|001|0001’0|0000011 ; 0:3bit:5bit:7bit

2. Использование имени поля записи:

mov AL, a1 ; 12

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

Имена записей и полей записей м/б использованы с атрибутными операторами width и mask;

· width: mov AL, width a1 ; AL=3

Вычисляет длину записи или поля записи в битах: mov AL, width d1 ; AL=12

· mask: формирует операнд-маску с единицами в битах указанного поля и нулями в остальных полях:

test AX, mask a1

jz pov ; Переход на pov, если ZF=1, т.е. если содержимое a1 ¾ нули.

ВЫРАЖЕНИЯ

Могут быть использованы в командах или директивах и состоять операторов и операндов. Операнды бывают таких типов:

1. Const ¾ число, строка, символ или символическая константа (pole equ 5)

2. Операнд прямой памяти: СЕГМЕНТ:СМЕЩЕНИЕ (ES:ar1)

3. Регистр

4. Указатель позиции ($)

5. Базированный операнд: смещение[BX] или смещение[BP]

6. Индексный операнд: смещение[SI]

7. Базо-индексный операнд: смещение[BX][SI]

8. Элемент структуры: var.a1

9. Запись

10. Поле записи

^ ОПЕРАЦИИ НАД ВЫРАЖЕНИЯМИ

1. Арифметические операции: выр_1 + - * / выр_2 ; + - бинарные и унарные

2. Операции сдвига: выр_1 shl/shr счётчик ; 5 shr 2

3. Операции отношения: выр_1 ? выр_2 : eq=, ne¹, lt<, le£, gt>, ge³

Сравниваются два числовых выражения и получается результат: 0=false, 0FFFFh=true;

mov AX, a gt b

4. Операции над битами: выр_1 ? выр_2 : not, and, or, xor

5. Операции присваивания атрибутов:

· тип ptr выражение ; Переменная/метка, задаваемая выражением интерпретируется как указанного типа: jmp far ptr метка

· high / low выражение : возвращает соответственно старший или младший байты выражения

ar1 equ 0F1F2h

mov AL, high a1 ; AL=F1

mov AL, low a1 ; AL=F2

· short метка : присваивает метке тип short

· this тип : создаёт адресный операнд с заданными атрибутами

a1 equ this byte ; word/etc...

a2 dw 100 dup(?)

· mov a2,0 ; 2 байта

· mov a1,0 ; 1 байт



Каждая переменная имеет три атрибута: сегмент, смещение, тип. Оператор this кроме типизирования переменной назначает ей также текущее смещение, которое должно быть у адреса следующей доступной ячейки памяти. В данном случае a1 и a2 имеют одинаково смещение.

· label ; Задаётся: переменная label тип ;

a1 label byte ; аналогично a1 equ this byte

Вызывает типизирование переменной и назначение текущего смещения. Т.о. использование label позволяет назначить одной и той же ячейке памяти разные переменные; label можно использовать для создания стека.

a2 dw 100 dup(?)

a1 label word ; смещение a1 указывает на первое свободное слово за a2

6. Операции, возвращающие значения:

· $ : возвращает текущее значение счётчика адреса, т.е. смещение адреса текущего оператора

a1 db ‘Minsk’

a2 equ $-a1 ; a2=5 ; Т.о. с помощью $ можно определить длину строки.

· seg выражение : возвращает значение атрибута “сегмент” выражения.

ar1 dw ?

mov AX, seg ar1 ; В AX адрес сегмента с ar1

· offset выражение : возвращает значение атриб. “смещение” выражения.

mov AX, offset ar1

· length переменная : возвращает число элементов типа b/w/dw

ar1 dw 50 dup(?)

mov CX, length ar1 ; CX=50

· type выражение : возвращает число, представляющее собой тип выражения. Если выражение является переменной, то вычисляется её размер в байтах; byte=1, word=2, dword=4, tbyte=10 ; Если const, то =0.

Если имя структуры ¾ число байт в шаблоне структуры.

var1.a1[SI]

[BX].a1[SI]

add BX, type d1 ; d1 ¾ тип шаблона

· size переменная : возвращает число байтов памяти, зарезервированное под переменную, т.е. возвращает length*type;

^ ПРИОРИТЕТ ОПЕРАЦИЙ

В порядке убывания приоритета.

1. length, size, width, mask, ( ), [ ], < >

2. .

3. :

4. ptr, offset, seg, type, this

5. high, low

6. + - унарные

7. * / shr, shl, mod

8. + - бинарные

9. Операции отношения: eq=, ne¹, lt<, le£, gt>, ge³

10. not

11. and

12. or, xor

13. short

Если приоритет на очевиден => скобки.

ПОДПРОГРАММЫ

Под ПП понимается совокупность команд, написанная один раз и используемая в разных местах программы. Передача управления процедуре ¾ вызов. После вызова выполняется процедура, а затем управление передаётся в основную программу к той точке, откуда был сделан вызов, т.е. к следующей за вызовом команде.

Формат:

имя_процедуры proc [расстояние] ; near/far ; near = default

команды

имя_процедуры endp

near-процедура м/б вызвана только из того сегмента, в котором она была определена, far-процедура м/б вызвана и из другого сегмента. Допускается вложенность процедур (вызов процедуры из процедуры).

При вызове процедуры надо:

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

2. Процедура должна запомнить адрес возврата и извлечь его перед выходом из стека с помощью команды ret ; ret может извлечь IP/EIP и CS для перехода внутри одного сегмента или любого сегмента соответственно.

^ ФОРМАТЫ КОМАНДЫ CALL

call имя_процедуры

Осуществляется безусловный переход на указанную процедуру с сохранением в стеке адреса следующей команды. Режимы адресации аналогичны jmp, но тут не short вызова. Вызов может быть:

1. Прямой: адрес перехода в самой call.

· Внутрисегментный (в команде только смещение)

· Межсегментный (CS и смещение)

call near ptr метка ¾ внутрисегментный прямой вызов

call far ptr метка ¾ межсегментный прямой вызов

В случае межсегментного прямого вызова (call far ptr procedure1) сначала в стек заносится CS, а затем IP.

2. Косвенный: адрес в регистре или ячейке памяти.

· call word ptr имя_переменной (имя ячейки памяти или регистр)

В стек помещается IP, а затем в IP из ячейки памяти загружается новое значение.

· call dword ptr имя_переменной ¾ межсегментный косвенный переход

В стек помещаются старые значения IP и CS, а новые загружаются из стека.

^ ФОРМАТ КОМАНДЫ CALL

ret [число] ; возврат из процедуры

ret передаёт управление на команду, следующую за вызвавшей процедуру call.

ASM генерирует внутрисегментный ret для near процедур и межсегментный ret для far. При этом внутрисегментный ret извлекает из стека только старый IP, а межсегментный ret ещё и CS.

Если в ret указано число, то оно добавляется к содержимому SP после извлечения адреса возврата. Это используется для удаления из стека параметров функции.

МАКРОСРЕДСТВА

Достоинства процедур:

1. Экономия памяти

2. Сокращение времени разработки программы и размера исходника



Недостаток: потери времени при передаче параметров и сохранении регистров в стеке.

В случае использования коротких фрагментов в разных местах программы используются макросредства (сокращается время выполнения, но увеличиваются потери памяти).

Макросредства позволяют формировать в программе макросы (блоки команд и директив с общим именем), а затем использовать это имя (макрокоманду) для представления всего блока. TASM замещает каждую макрокоманду на последовательность команд и директив в соответствии с макроопределениями => формируется макрорасширение. Замена макрокоманды на макроопределение осуществляется на этапе компиляции.

^ МАКРОДИРЕКТИВЫ, МАКРООПРЕДЕЛЕНИЯ (МАКРОСЫ)

Макрос ¾ блок команд и директив, начинающийся с macro и заканчивающийся с endm. Формат:

имя macro [форм_пар-1, форм_пар-2, ...]

endm

Имя потом используется для вызова макроопределения.

Формальные параметры представляют собой внутренние по отношению к данному макроопределению имена, которые используются для обозначения значений при вызове. В теле макроса м/б любые команды, директивы, макродирективы.

m1 macro op2

add AX, op2

endm

Теперь: m1 BX будет выглядеть как add AX, BX.

TASM ассемблирует предложения теля macro только при вызове макрокоманды и только в той точке, где вызов имел место, т.е. все адреса в ассемблируемом коде будут связаны с точкой вызова макрокоманды, а не с местом расположения макроопределения, которое само по себе не ассемблируется. TASM замещает все вхождения имени макроса его фактическим значением. Параметры замещаются в порядке следования. Если число фактических параметров меньше числа формальных, то формальные параметры, для которых нет фактических, замещаются пустыми строками.

Для правильной обработки тела макроса с метками используется директива local, позволяющая организовать задание метки в макросах.

local формальное_имя_1, ...

Формальное имя м/б использовано при каждом исполнении макрокоманды и ASM гарантирует его единственность: ??xxxx ; типа ??0000, ??0001

local используется только в макроопределении и идёт сразу за директивой macro.

pause macro Time

local L1

mov CX, Time

L1: loop L1

endm

Теперь:

pause 1000 à mov CX, 1000

??0000: loop ??0000

pause 10000 à mov CX, 10000

??0001: loop ??0001


^ ПЕРЕДАЧА ПАРАМЕТРОВ ЧЕРЕЗ СТЕК

Параметры помещаются в стек непосредственно перед вызовом процедуры. Для чтения используется не pop, в BP, в который сразу же после входа в процедуру помещают адрес вершины стека.

push param1

push param2

call procedure

add SP, 4

procedure proc near

push BP

mov BP, SP

mov AX, [BP+4] ; param2

mov BX, [BP+6] ; param1

pop BP

ret

procedure endp

^ УСЛОВНОЕ АССЕМБЛИРОВАНИЕ

if выражение1

...

elseif выражение2

...

elseif выражение3

...

else

...

endif

Компилируется тот участок, для которого выражение = TRUE. Если все они = FALSE, то компилируется else;

IF1/ELSEIF1 ¾ если ассемблер выполняет первый проход ассемблирования

IF2/ELSEIF2 ¾ если ассемблер выполняет второй проход ассемблирования

IFE выражение / ELSIFE выражение ¾ если выражение равно нулю

IFDEF метка / ELSEIFDEF метка ¾ если метка определена

IFNF метка / ELSEIFNDEF метка ¾ если метка не определена

..................

и т.д.

Есть директивы условной генерации ошибок:

.err

.err1 ¾ ошибка при первом проходе

.err2 ¾ ошибка при втором проходе

.erre выражение ¾ ошибка, если выражение равно нулю

.errdef метка ¾ ошибка, если метка определена


Скачать файл (68.6 kb.)

Поиск по сайту:  

© gendocs.ru
При копировании укажите ссылку.
обратиться к администрации