Сегментация памяти, директивы ассемблера

Любые ассемблерные программы содержат, по крайней мере, один сегмент-сегмент кода. В некоторых программах используется сегмент для стековой памяти и сегмент данных для определения данных. Ассемблерная директива для описания сегмента 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