Сегментация памяти, директивы ассемблера
Любые ассемблерные программы содержат, по крайней мере, один сегмент-сегмент кода. В некоторых программах используется сегмент для стековой памяти и сегмент данных для определения данных. Ассемблерная директива для описания сегмента SEGMENT имеет следующий формат:
< имя > SEGMENT
:
.
< имя > ENDS
Имя сегмента обязательно, оно должно быть уникальным. Директива ENDS означает конец сегмента.
Пример оформления сегмента данных с именем “data”:
data SEGMENT
A dB 35h, 44, 0FAh
AB dW 3145h, 4456h, 1F4Ah
A3 dB "Абрикосовое дерево"
data ENDS
Сегмент данных предназначен для определения констант, рабочих полей и областей для ввода-вывода. В соответствии с имеющимися директивами в ассемблере разрешено определение данных различной длины: например, директива DB определяет байт, а директива DW определяет слово.
Формат директивы определения данных:
[имя] DN <выражение>
Имя элемента данных не обязательно, но если в программе есть ссылка на некоторый элемент данных, то это делается посредством имени. Например:
MOV AX, AB ;содержимое слова по адресу АВ (см. пример выше) пересылается в регистр АХ.
После выполнения этого оператора в АХ будет записано число 3145h. Символическое имя АВ является адресом определенной ячейки памяти. В нашем случае этот адрес равен 3, т.к. адресация в сегменте относительна к началу сегмента. Символическое имя А транслируется системой ассемблирования в значение равное 0. Это адрес первого байта в сегменте (содержимое его равно 35h). Далее определены еще два байта со значениями 44 и 0FAh, следовательно, адрес АВ вычисляется как 0+3 байта =3.
Команда MOV AL, A+2 загружает в регистр АL значение FA, команда MOV AX, AB+2 загружает регистр АХ значение 4456h.
DN в выражении (1) может иметь следующие мнемоники:
DB (байт), DW (слово), DD (двойное слово), DQ (учетверенное слово), DT (10 байт).
Выражение может содержать константу, например:
FL DB 25; несколько констант: FL1 DB 11,12,25,84,91,... , разделённых запятыми и ограниченных длиной строки.
Ассемблер определяет эти константы в виде последовательности смежных байтов. Ссылка по имени FL1 указывает на первую константу - 11, по FL1+1, - на вторую, равную 12.
Выражение может содержать знак вопроса для неопределенного значения:
FL2 DW ?
Здесь резервируется два байта. Выражение допускает так же повторение константы в следующем формате:
[имя] Dn <число повторений> DUP(<выражение>)
Например:
DW 10 DUP(?) ;десять неопределенных слов
DB 5 DUP(14) ;пять байт содержащих 0Eh
DB 3 DUP(4 DUP(8)) ;двенадцать восьмерок.
Выражение может содержать символьную строку. Символьная строка используется для описания данных, таких, как, например, имена людей или заголовки страниц. Содержимое строки отмечается одиночными кавычками. Ассемблер переводит символьные строки в объективный код в обычном формате ASCII. Символьная строка определяется только директивой DB:
KSP DB 'ТРАВОСТОЙ'
Если в программе необходимо изменить последнюю букву в слове ТРАВОСТОЙ на "П", запишем оператор:
mov KSP+8, 'П'
Прямая адресация
Наиболее естественный способ адресации данных - это прямая адресация, когда адрес нужной ячейки памяти является частью команды, например:
mov AL, A ;содержимое ячейки с адресом А помещается в регистр AL.
Аналогичным способом можно произвести и обратное действие:
mov A, AL ;содержимое регистра AL пересылается в ячейку памяти, адрес которой определяется в результате трансляции ассемблером символического имени А.
Косвенная адресация
Существует способ адресации памяти, при котором исполнительный адрес выбирается из некоторого регистра, а не из самой команды. Например, в команде
mov AL, [DI]
исполнительный адрес содержится в регистре DI; квадратные скобки указывают на то, что содержимое регистра DI является адресом некоторой ячейки памяти. Описанным способом можно использовать любой из четырех регистров SI, DI, BX, BP.
Чтобы занести адрес в один из указанных регистров можно использовать конструкцию offset:
mov BX, offset AB
Благодаря присутствию здесь оператора offset в регистр BX загрузится адрес области памяти с именем AB.
Команда
mov AX, [BX]
занесет в регистр AX (аккумулятор) значение 3145h. Если дважды инкрементировать (т.е. увеличить на единицу) содержимое регистра ВХ и снова выполнить эту же команду в регистре АХ окажется значение 4456h:
INC BX
INC BX
MOV AX, [BX] ;в регистре АХ значения 4456h.
Напишем простую программу, выполнение которой будем наблюдать в отладчике. Пусть в сегменте данных резервируется два слова. Запишем в первое слово значение 27FC, во второе - 573А.
dat SEGMENT; начало сегмента данных
A dW 2 dup (?)
dat ENDS ;конец сегмента данных
ASSUME CS: cod, ds: dat
cod SEGMENT; начало кодового сегмента
START: mov AX, dat ;инициализация
mov DS, AX ; сегментного регистра
mov A, 27FCh ;запись числа в первое зарезервированное слово
mov A+2, 573Ah ; запись числа во второе зарезервированное слово
RET
cod ENDS ; конец кодового сегмента
END START
Директива ASSUME
Директива ASSUME сообщает Ассемблеру назначение каждого сегмента. Так. в директиве ASSUME приведенной программы, показывается, что сегмент с именем cod является кодовым сегментом (в нем содержится программа), а сегмент с именем dat является сегментом данных и он соотносится с регистром DS.
Индивидуальные задания
Написать программу, в которой в сегменте данных резервируется память под следующие данные:
![]() | вариант 1 | вариант 2 | вариант 3 | вариант 4 | вариант 5 |
Т1 | 5 слов без инициализации (исп. DUP) | строка символов "веселый день" | 1 двойное слово без инициализации | 1 байт без инициализации | 2 слова без инициализации (исп.DUP) |
T2 | строка символов "кислые щи" | 6 слов без инициализации (исп.DUP) | послед. 4 байт: 82h,137,А5h, 1100111B | 4 слова со значением E48Ah (исп.DUP) | последовательность 4 слов: A83h, F47h, 892, 101110111B |
T3 | 3 слова со значением. A584h (исп.DUP) | Последовательность . 6 байт 89h, 10010010B, 254, AAh, -112, 7Fh | 5 слов со значением EF3Ah (исп.DUP) | строка символов "промозглая сырость" | строка символов "острова в океане" |
Т4 | Последовательность 4 байт 4Ah, F7h, -54, 111101B | последовательность. 2 слов: 7777h, 8888h | строка символов "кошкин дом" | последов. 3 байт: 84h, -111, CEh | 5 байт со знач. 55h (исп.DUP) |
Имя | вариант 6 | вариант 7 | вариант 8 | вариант 9 | вариант 10 |
T5 | 6 слов без инициализации (исп.DUP) | строка символов "бедная овечка" | 1 двойное слово без инициализации | 1 байт без инициализации | 2 слова без Инициализации (исп.DUP) |
T6 | строка символов “литературный вечер" | 3 слова без инициализации (исп.DUP) | Последовательность 4 байт: 82h,137,А5h, 1100111B | 4 слова со значением E48Ah (исп.DUP) | последовательность 4 слов: A83h, F47h,892, 101110111B |
T7 | 2 слова со значением F4E8h (исп.DUP) | последовательность 5 байт AEh,1011011B, 135, F4h, -96 | 4 слова со значение E73Ah (исп.DUP) | строка символов "паук каракурт" | строка символов "муха цокотуха" |
T8 | последовательность 6 байт 7Eh, B5h, -103, 1110100B, 250 | последовательность 3 слов: EEF7h, 12A8h, CA34h | строка символов "ночь в опере" | последовательность 3 байт -35h, -107, FAh | 6 байт со значением F4h (исп.DUP) |
При выполнении последующих пунктов задания использовать оператор MOV.
1. Инициализировать сегментные регистры DS, ES
2. Записать по адресу
вариант 1 | вариант 2 | вариант 3 | вариант 4 | вариант 5 |
Т3+2 слово 3333h | Т2+2 слово 4444h | Т3+4 слово 7777h | T1 байт FAh | T4+1 байт FAh |
вариант 6 | вариант 7 | вариант 8 | вариант 9 | вариант 10 |
Т5+4 слово BCCBh | Т6+4 слово FAFAh | Т7+6 слово AA56h | T5 байт 7Ah | T8+3 байт FAh |
3. Занести в указанный регистр адрес ячейки, используя синтаксическую конструкцию с "OFFSET":
вариант 1 | вариант 2 | вариант 3 | вариант 4 | вариант 5 |
BX, T1+4 | SI, T2 | DI, T1+2 | BX, T2+6 | SI, T3+1 |
вариант 6 | вариант 7 | вариант 8 | вариант 9 | вариант 10 |
BX, T7+2 | SI, T6 | DI, T7+4 | BX, T8+2 | SI, T5+3 |
4. Занести в регистр AX содержимое указанного сегментного регистра
вариант 1 | вариант 2 | вариант 3 | вариант 4 | вариант 5 |
DS | SS | ES | CS | DS |
вариант 6 | вариант 7 | вариант 8 | вариант 9 | вариант 10 |
ES | CS | DS | SS | ES |
5. Записать в память значение аккумулятора (слово), адресуемое указанным регистром
вариант 1 | вариант 2 | вариант 3 | вариант 4 | вариант 5 |
BX | SI | DI | BX | SI |
вариант 6 | вариант 7 | вариант 8 | вариант 9 | вариант 10 |
BX | SI | DI | BX | SI |
6. Инкрементировать дважды значение адреса в регистре, указанном в предыдущем пункте. Инкрементировать значение аккумулятора. Использовать оператор INC reg.
7. Повторить пункт 5.
8. Используя оператор MOV изменить шестую букву в строке символов на букву "W".
Пример оформления программы приведен ниже.
assume cs:code, ds:dat | ||
dat segment | ||
t1 db 'тучи над городом' | ||
t2 dw 7 dup(?) | ||
t3 dw 1f47h,1222h,10011011b,1345h,6789 | ||
t4 dw ? | ||
t5 dw 0a45h | ||
dat ends | ||
code segment | ||
start: | ||
mov ax, dat | ||
mov ds, ax | ||
mov t4, 2222h | ||
mov ax, ds | ||
mov cx, offset t3 | ||
mov bx, cx | ||
mov dx, [bx] | ||
mov t3+6, 1111 | ; в память по адресу Т3+6 (т.е.30) ; заносит ся значение 1111 | |
mov si, offset t2 | ; в регистр заносится адрес Т2, ; который равен 16 | |
mov ax, 1112h | ||
mov [si], ax | ; в память по адресу, хранящемуся в SI, заносится значение аккумулятора | |
inc si | ;инкрементирование содержимого ;регистра SI (содержимое SI увеличить на 1) | |
inc si | ||
inc ax | ||
mov ax, cs | ||
mov [si], ax | ||
ret | ||
code ends | ||
end start |
Лабораторная работа №.3