литература / Пухальский Проектирование микропроцессорных систем 2001
.pdf420 |
Глава 4. Микропроцессоры 8086/8088 и сопроцессор 8087 |
В примере 4 приведен текст исходного модуля сот-программы, выполняющей ту же самую задачу, что и рассмотренная в начале этого параграфа ехе-программа.
Пример 4:
c_seg |
segment |
|
; Начало исходного модуля и сегмента кода |
|
|
assume |
CS: c_seg, DS: c_seg, SS: c_seg, ES: c_seg |
||
begin: |
org |
100/г |
; |
(сегментные регистры CS = DS = SS = ES) |
JMP |
main |
; Точка входа в программу по директиве end begin |
||
ascii 1 |
db |
8 dup (?) |
; Начало данных |
|
sign |
db |
(?) |
; |
(определения данных такие же, что и в ехе-программе) |
Messl |
|
|
; <— Остальные данные такие же, что и в ехе-программе |
|
db |
10, ‘ Выполнить новое вычисление? (Y)’, 13, 10, 10, “$’ ; Конец данных |
|||
main |
proc |
near |
; Начало процедуры main |
|
|
LEA |
DX, Mess |
; <г- Остальная часть сегмента кода такая же, |
|
|
JMP |
L8 |
||
|
; |
что и в ехе-программе |
||
L2: |
RET |
|
|
|
main |
endp |
|
; Конец процедуры main |
|
c_seg |
ends |
ь |
; Конец сегмента кода |
|
|
end |
begin |
; Конец программы (begin указывает точку входа программы) |
Команда JMP main использована для обхода данных, размещенных в начале сегмента ко да. Размер этих ехе- и сот-файлов составляет 1042 байт (ехе-файл) и 449 байт (com-файл).
2. Директивы определения данных
Директивы определения данных DB (байта), DW (слова), DD (двойного слова), DQ (квад рослова) и DT (10 байт) служат для задания размеров, содержимого и местоположения полей данных в памяти, используемых в программе. В отличие от других директив эти директивы генерируют объектный код (данные копируются в объектный файл). Эти директивы имеют формат:
[name] DL value_Q [, value_l] ... [, value_k],
где name — имя переменной, L = В, W, D, Q или Т, value_m (т = 0, 1, к) — данные, а квад ратные скобки означают необязательные параметры. Если параметр пате имеется, то трансля тор генерирует переменную пате, имеющую тип BYTE, WORD, DWORD, QWORD или TBYTE для директив DB, DW, DD, DQ и DT соответственно.
С переменной name ассемблер связывает смещение (относительный адрес) первого байта данных value_0 относительно начала сегмента данных. Смещение же любого операнда value_т будет определяться величиной value_m + т (знак + — оператор арифметического сложения). Выражение value_ni + m можно использовать в инструкциях (командах) МП для прямой адре сации любого из операндов, заданных директивами определения данных. При ассемблировании производится строгий контроль типов операндов и при несоответствии их в двухоперандных командах транслятор выдает сообщение: Operand types do not match (несоответствие типов опе рандов).
Директива DB используется напрямую только для МП 8086, директивы DW и DD — как для МП 8086 (CPU), так и для арифметического сопроцессора 8087 (NDCP — Numeric Data Coprocessor), а директивы DQ и DT — только для NDCP 8087. С помощью директивы переоп ределения типа данных LABEL все эти директивы можно использовать и для МП 8086.
424 |
Глава 4. Микропроцессоры 8086/8088 и сопроцессор 8087 |
Независимо от исходного формата при загрузке числа из памяти в регистр сопроцессора оно автоматически преобразуется во временный вещественный формат, а при записи в память осуществляется обратное преобразование в формат получателя — любой из остальных шести форматов. Поэтому элементарные и быстрые для МП 8086 команды загрузки и запоминания двоичных и десятичных целых чисел выполняются'сопроцессором достаточно долго. Благодаря аппаратному преобразованию всех форматов данных во временный вещественный формат про граммист может не заботиться об их преобразованиях. Конечно, при возвращении результата в память программист должен выбрать формат получателя, необходимый для восприятия резуль тата с требуемой точностью. Выполнение вычислений с большей точностью (64-разрядная ман тисса), чем точность форматов получателя (максимум 53-разрядная мантисса), обеспечивает для большинства достаточно сложных задач исключение накапливаемых ошибок округления промежуточных результатов.
Директива DB. Эта директива размещает и инициализирует один или более байтов дан ных в памяти. Директива DB (Define Byte — определение байта) имеет формат:
[name] DB value_0 [, value ]...[, value_k],
где name — необязательное имя переменной типа BYTE, с которым ассемблер связывает сме щение (относительный адрес) байта данного valuejd в сегменте данных. С этого адреса в сег менте данных последовательно будут располагаться все заданные байты value_m (т = 0 ...к). Аргументы value_m могут быть заданы одним из следующих способов:
целое число (например, 0Е7/г); константное выражение (например, 4*18, где * — оператор умножения); строковая константа (например, ‘Pentium’);
оператор DUP (например, 10 DUP (?) — резервирование 10 байт в памяти);
знак вопроса ? (указание ассемблеру оставить начальное значение неопределенным).
Символы строковой константы, заключенные в апострофы, транслируются в A SC II-коды в соответствии с табл. 1.9. Если в строковую константу входит апостроф, то его необходимо повторить два раза, например, ‘Об” ект’, что соответствует слову Об’ект. Строковая константа может быть любой длины, при условии, что она умещается вместе с директивой на одной стро ке текста программы (всего 128 символов). Символы строки входят в сегмент данных в порядке их следования, т. е. первый символ имеет меньший адрес, последний — больший.
Пример 6 (считаем, что данные расположены с начала сегмента данных, т. е. смещение переменной alpha равно 0000h — для уменьшения текста программы директивы определения сегментов опущены):
alpha db |
95h, 93h, ‘IBM PC’, ?, 10110b, ?, 36 ; 95 93 49 42 |
4D 20 50 43 00 16 00 24h (12 байт) |
||
db |
4 * 18, 5 dup (?), 2 dup (55, OAA/i) ; 48 00 00 00 |
00 00 37 АЛ 37 AA (10 байт) |
||
|
|
; |
(4x18 = 72^=48/!) |
|
MOV DL, alpha + 4 |
; DL <—M(alpha + 4) = M(0004) = 4Dh — A SC II-код символа M |
|||
; Здесь операнд alpha + 4 является адресом и используется реж им прямой адресации |
||||
MOV BX, offset alpha + 4 ; BX <—0004h — смещение (относительный адрес) символа М |
||||
LEA |
SI, alpha + 4 |
; SI 0004h — смещение (относительный адрес) символа М |
||
MOV АН, alpha +12 |
; АН 4- M(alpha + 12) = М(000С) = 48h |
|||
MOV BX, alpha + 4 |
; Ошибка: переменная M(alpha+4) типа BYTE, а не типа WORD |
Транслятор знак “?” заменяет значением 00h и команду LEA командой MOV. Оператор OFFSET вычисляет смещение (относительный адрес) переменной alpha+4 относительно начала
4.4. Директивы ассемблера |
425 |
сегмента данных, т. е. операнд offset alpha+4 является непосредственным операндом. На этом основании транслятор и заменяет команду LEA на команду MOV. В первых четырех командах вторые операнды можно заключать в квадратные скобки. Сказанное справедливо и для осталь ных директив определения данных за исключением допустимой длины строковой константы.
Оператор DUP. Этот оператор используется вместе с директивами DB, DW, DD, DQ и DT для задания нескольких одинаковых начальных значений. Оператор DUP (Duplicate — дубли ровать) имеет формат
count DUP (value_\ [, value_2] ... [, value_k}),
где count — аргумент (целое положительное число), задающий число раз, которое нужно про дублировать начальные значения, перечисленные в круглых скобках. Каждая величина value_m может быть любым выражением, имеющим значением целое число, символьную константу, знак вопроса ? или другой оператор DUP (допускается до 17 уровней вложенности операторов DUP). При трансляции знак вопроса ? заменяется значением 00h.
Пример 7:
data! db 4 dup (‘varl’) ; 76 61 72 31 76 61 72 31 76 61 72 31 76 61 72 31 — данные после
;трансляции (76ft 61ft 72ft 31ft — ASCII-коцы букв слова varl)
|
db |
8 dup (?) |
; 8 неинициализированных (неопределенных) байтов |
data2 |
db |
8 dup (ЗОЙ, 31ft) |
; 16 байтов, инициализированных значениями 30/г 31/г |
data3 |
db |
2 dup (4 dup (41ft, 42ft)) |
; 16 байтов, инициализированных значениями 41ft 42ft |
|
db 3 dup (37*10/3) |
; 3 байта, инициализированных значением 7В/г = 123 |
Оператор OFFSET. Этот оператор (Offset — смещение) имеет формат
OFFSET expression
и вычисляет смещение выражения expression относительно начала сегмента (вычисляет относи тельный адрес). Выражение expression может быть переменной или меткой. Команда LEA вы полняет аналогичные действия, но без использования оператора OFFSET.
Конструкцию offset expression можно использовать в инструкциях (командах) МП в каче стве непосредственного операнда.
Директива DW. Эта директива размещает и инициализирует одно или более слов данных в памяти. Директива DW (Define Word — определение слова, или двух байт) имеет формат:
[name] DW value_0[, value_ \] ...[, value_к]<
где пате — необязательное имя переменной типа WORD, с которым ассемблер связывает смещение (относительный адрес) младшего байта данного value_0 в сегменте данных. С этого адреса в смежных ячейках памяти последовательно будут располагаться все заданные слова value_m (т = 0, 1, ..., к): в первую ячейку памяти помещается младший байт слова, а в следую щую (с большим адресом) — старший байт слова. Аргументы value_m могут быть заданы од ним из следующих способов:
целое число — Word Integer (например, 0F0E7ft);
константное выражение — Word Integer (например, 318 / 65, где / — оператор деления); адресное выражение (например, пеаг_аггау)\
строковая константа — только один или два символа (например, ‘D’ или ‘PC’); оператор DUP (например, 7 DUP (?) — резервирование 7 x 2 = 1 4 байт в памяти);
знак вопроса ? (указание ассемблеру оставить начальное значение слова неопределенным).
4.4. Директивы ассемблера |
429 |
те, дает число 38.737094879150390625 с точными значениями только шести разрядов после точки. Более точное значение
л/l 500.5625 = 38,7370946251780736204989494586506.
Директ ива D Q . Эта директива размещает и инициализирует одно или более счетверенных слов (квадрослов) данных в памяти. Директива D Q (Define Q uad W ord— определение четырех
слов, или восьми байт) имеет формат:
[name] DQ valueJ ) [, value_ \ ] ... [, value_k],
где name — необязательное имя переменной типа QWORD, с которым ассемблер связывает смещение (относительный адрес) младшего байта данного value_0 в сегменте данных. Аргу менты value_m могут быть заданы одним из следующих способов (т = О... к):
целое число — Long Integer (например, 0ABCD193639431938/г);
константное выражение — Long Integer (например, 465 * 23 - 377 / 3);
вещественное число — Long Real (например, -1500.5625 или -15.005625е+2, где е - +2 — порядок числа; для положительных чисел и порядков знак “+” можно опускать);
кодированное вещественное число — Long Real (например, 80F0 000000000000/-, где г — указатель числа в формате NDCP)\
строковая константа — только один или два символа (например, ‘D’ или ‘PC’); оператор DUP (например, 10h DUP (?) — резервирование 1 6 x 8 = 128 байт в памяти); знак вопроса ? (указание ассемблеру оставить начальное значение неопределенным).
Вещественные числа типа ххх.ххх транслятор преобразует в формат Long Real. Кодиро ванные вещественные числа типа хххг транслятор проверяет на допустимые значения кодов.
Строковая константа типа QWORD должна содержать не более двух символов. Последний (или единственный) символ строки сохраняется в младшем байте младшего слова, а старший байт младшего слова содержит первый символ или 0, если строковая константа односимволь ная. Остальные байты заполняются нулями.
Пример 10 |
(считаем, что данные расположены с начала сегмента данных, т. е. смещение |
||||
переменной alp h a равно 0000/г): |
|
||||
alpha |
dq |
‘D’, ‘PC’ |
|
; 44 00 00 00 00 00 00 00 ♦ 43 50 00 00 00 00 00 00 |
|
|
dq |
+1500.5625, -3827.653 |
; 00 00 00 00 40 72 97 40 ♦ 93 18 04 56 4E E7 AD CO |
||
|
dq , 80100000 00000000r |
; 00 00 00 00 00 00 10 80 <- Long Real T |
|||
|
dq |
10000000000000A7г |
; A7 00 00 00 00 00 00 10 <- Long Real |
||
beta_w |
label |
word |
; Смещение переменной beta_w типа word равно 0030h |
||
beta_d |
label |
dword |
; Смещение переменной beta_d типа dword равно 0030h |
||
; Смещение переменных beta_w и beta_d типов WORD и DWORD равно смещению beta_q |
|||||
beta_q |
dq |
2ClE61F74D33BB03/z |
; 03 BB 33 4D F7 61 IE 2C — Long Integer |
||
buff |
dq |
? |
; Резервирование 8 байт памяти |
||
gamma |
dq |
98465 *523 -377/3 |
; 6EC8110300000000 — Long Integer |
||
|
MOV |
DX, beta_w + 3 ; DX |
M (beta_w + 3) = ЩЮЗЗ) = F74D/? |
||
|
; Здесь операнд beta_w является адресом и используется реж им прямой адресации |
||||
|
MOV |
BX, offset beta_w + 2 ; BX <—0032h — смещение операнда 4D33A |
|||
|
LES |
BP, beta_d + 1 |
; BP <—M(0031) = ЗЗВВ/г, ES <- M(0033) = F74Dh |
||
|
|
^Вычисление квадратного корня из числа 1500.5625 |