Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скляров И. Изучаем Assembler за 7 дней (2010).pdf
Скачиваний:
1531
Добавлен:
23.02.2015
Размер:
2.11 Mб
Скачать

http://www.sklyaroff.ru

34

2.4. Некоторые важные директивы ассемблера

Мы уже изучили одну директиву COMMENT, сейчас познакомимся еще с несколькими директивами, наиболее часто используемыми в программах на ассемблере. Остальные директивы (равно как и команды ассемблера) мы будем изучать по ходу чтения книги.

2.4.1. Директивы определения данных

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

имя_переменной d* значение

где d* — одна из нижеприведенных директив:

db— резервировать память для данных размером 1 байт;

dw — резервировать память для данных размером 2 байта (слово);

dd — резервировать память для данных размером 4 байта (двойное слово); df — резервировать память для данных размером 6 байт;

dp — резервировать память для данных размером 6 байт; dq — резервировать память для данных размером 8 байт; dt — резервировать память для данных размером 10 байт.

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

Примеры:

Name1 db 13 Name2 dw ?

Name3 db 1,2,3,4,5,6,7,8,9,0Ah,0Bh,0Ch,0Dh,0Eh,0Fh db ‘A’

db 10,20,30,40,50,60 float_name dd 2.7e5

Директива

str db ‘Hello, World!’

эквивалентна следующей директиве:

str db ‘H’,’e’,’l’,’l’,’o’,’ ‘,’W’,’o’,’r’,’l’,’d’,’!’

В директивах определения данных возможно применение конструкции повторения DUP. Конструкция DUP определяет количество повторений операнда. Например, следующее определение:

db 0,0,0,0,0,0,0,0

эквивалентно db 8dup(0)

Еще пример конструкции DUP:

dw 100 DUP(?)

; сто неопределенных слов

4 Переменной в программировании называют некоторое хранимое в памяти значение, которое может изменяться во время выполнения программы.

http://www.sklyaroff.ru

35

Более сложный пример:

name db 3 dup(‘abc’,?,6)

эквивалентно:

name db ‘abc’,?,6, ‘abc’,?,6,‘abc’,?,6

Возможны вложенные конструкции DUP, например: db 4 dup(3 dup(8)) ; двенадцать восьмерок

2.4.2. Директива эквивалентности

Директива эквивалентности присваивает имени значение операнда:

имя EQU операнд

В этой директиве обязательно должны присутствовать и имя и операнд, причем операнд только один. Директива EQU является аналогом команды #define препроцессора языка C. На этапе ассемблирования все имена, определенные с помощью EQU в программе будут заменены соответствующим операндом.

Примеры:

Namber EQU 3

Message EQU ‘Hello, World!$’ R EQU AX

Var EQU 4[si]

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

2.4.3. Директива присваивания

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

Примеры:

X=1

offset=X+10 ; offset = 11 X=0

2.4.4. Директивы задания набора допустимых команд

По умолчанию MASM использует набор команд процессора 8086 и выдает сообщение об ошибке, если используется команда в программе, которую этот устаревший процессор не поддерживает. Чтобы возможно было использовать команды, появившееся в более новых процессорах необходимо использовать следующие директивы:

.8086 — разрешены только команды 8086 (используется по умолчанию);

.186 — разрешены команды 80186;

.286 и .286c — разрешены непривилегированные команды 80286;

.286p — разрешены все команды 80286;

.386 и .386c — разрешены непривилегированные команды 80386;

.386p — разрешены все команды 80386;

.486 и .486c — разрешены непривилегированные команды 80486;

.486p — разрешены все команды 80486;

.586 и .586c — разрешены непривилегированные команды P5 (Pentium);

.586p — разрешены все команды P5 (Pentium);

http://www.sklyaroff.ru

36

.686 — разрешены непривилегированные команды P6 (Pentium Pro, Pentium II);

.686p — разрешены все команды P6 (Pentium Pro, Pentium II);

.8087 — разрешены команды NPX 8087;

.287 — разрешены команды NPX 80287;

.387 — разрешены команды NPX 80387;

.MMX — разрешены команды IA MM;

.K3D — разрешены команды AMD 3D.

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

2.4.5. Упрощенные директивы определения сегмента

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

.data или .DATA — определяет начало или продолжение сегмента инициализированных данных, т. е. данных, которые имеют начальное значение, например:

.data

var1 dw 13

str1 db "Text string"

.data? или .DATA? — определяет начало или продолжение сегмента данных, в котором располагаются неинициализированные данные. При рассмотрении директив определения данных мы говорили, что неинициализированные данные определяются при помощи оператора ?. Например:

.data?

var1 dw ? db 10 dup(?)

Однако ничто не мешает вам располагать неинициализированные данные вместе с инициализированными данными в сегменте данных, определяемом с помощью директивы .data. Преимущество директивы .data? перед .data в том, что при ее использовании уменьшается размер исполняемого файла, т. к. неинициализированные данные не занимают места. В случае .data неинициализированные данные заполняются случайными значениями, а потому файл увеличивается на соответствующий размер.

.const или .CONST? — определяет начало или продолжение сегмента данных, в котором определены константы, т. е. данные которые не изменяются в ходе работы программы. Разумеется, вам ничто не мешает определять константы в сегменте данных с помощью директивы .data, однако преимущество .const состоит в том, что такой сегмент получает атрибут "только для чтения" (read only) для лучшей защиты констант от модификации.

.stack [размер] или .STACK [размер] — определяет начало или продолжение сегмента стека. Необязательный параметр размер задает размер стека. Если размер не указан, размер стека предполагается равным 1 Кбайт.

.code [имя] или .CODE [имя] — определяет начало или продолжение сегмента кода. Если имя не указано, то по умолчанию используется имя _TEXT (для моделей памяти tiny, small, compact и flat) или имя_модуля_TEXT для моделей памяти medium, large и huge.

2.4.6. Директива указания модели памяти

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