Структура ассемблерных программ

Автор работы: Пользователь скрыл имя, 05 Мая 2012 в 06:11, реферат

Описание работы

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

Файлы: 1 файл

Структура ассемблерных программ.doc

— 92.00 Кб (Скачать файл)

Структура ассемблерных программ

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

Инструкция процессора на языке ассемблера состоит не более чем из четырех поле и имеет следующий формат:

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

Единственное обязательное поле – поле кода операции (мнемоника), определяющее инструкцию, которую должен выполнить микропроцессор. Поле операндов определяется кодом операции и содержит дополнительную информацию о команде. Каждому коду операции соответствует определенное число операндов. Метка служит для обозначения какого-то определенного места в памяти, т. е. содержит в символическом виде адрес, по которому храниться инструкция. Преобразование символических имен в действительные адреса осуществляется программой ассемблера. Часть строки исходного текста после символа «;» (если он не является элементом знаковой константы или строки знаков) считается комментарием и ассемблером игнорируется. Комментарии вносятся в программу как поясняющий текст и могут содержать любые знаки до ближайшего символа конца строки. Для создания комментариев, занимающих несколько строк, может быть использована директива COMMENT. Пример:

Метка

Код операции

Операнды

;Комментарий

MET:

MOVE

AX, BX

;Пересылка


 

Предложения

Как было указано выше, исходный программный модуль – это последовательность предложений, каждое из которых записывается в отдельной строке:

<Предложение>

<Предложение>

...

<Предложение>

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

        пробел обязателен между рядом стоящими идентификаторами и/или числами (чтобы отделить их друг от друга);

        внутри идентификаторов и чисел пробелы недопустимы;

        в остальных местах пробелы можно ставить или не ставить;

        там, где допустим один пробел, можно ставить любое число пробелов.

Все предложения языка ассемблера делятся на директивы ассемблера и инструкции (команды) процессора.

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

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

1.       инструкции пересылки данных;

2.       арифметические, логические и операции сдвига;

3.       операции со строками;

4.       инструкции передачи управления;

5.       инструкции управления процессором.

 

Выражения

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

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

Операторы выполняют арифметические, логические, побитовые и другие операции над операндами выражений.

Ниже даны описания наиболее часто используемых в выражениях операторов.

Арифметические операторы.

выражение_1

*

выражение_2

выражение_1

/

выражение_2

выражение_1

MOD

выражение_2

выражение_1

+

выражение_2

выражение_1

-

выражение_2

 

+

выражение

 

-

выражение

Эти операторы обеспечивают выполнение основных арифметических действий (здесь MOD - остаток от деления выражения_1 на выражение_2, а знаком / обозначается деление нацело). Результатом арифметического оператора является абсолютное значение.

Операторы сдвига.

выражение

SHR

счетчик

выражение

SHL

счетчик

Операторы SHR и SHL сдвигают значение выражения соответственно вправо и влево на число разрядов, определяемое счетчиком. Биты, выдвигаемые за пределы выражения, теряются. Замечание: не следует путать операторы SHR и SHL с одноименными инструкциями процессора.

 Операторы отношений.

выражение_1

EQ

выражение_2

выражение_1

NE

выражение_2

выражение_1

LT

выражение_2

выражение_1

LE

выражение_2

выражение_1

GT

выражение_2

выражение_1

GE

выражение_2


 

Мнемонические коды отношений расшифровываются следующим образом:

EQ – равно;

NE – не равно;

LT – меньше;

LE – меньше или равно;

GT – больше;

GE – больше или равно.

Операторы отношений формируют значение 0FFFFh при выполнении условия и 0000h в противном случае. Выражения должны иметь абсолютные значения. Операторы отношений обычно используются в директивах условного ассемблирования и инструкциях условного перехода.

Операции с битами.

 

NOT

выражение

выражение_1

AND

выражение_2

выражение_1

OR

выражение_2

выражение_1

XOR

выражение_2

 

Мнемоники операций расшифровываются следующим образом:

NOT – инверсия;

AND – логическое И;

OR – логическое ИЛИ;

XOR – исключающее логическое ИЛИ.

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

Оператор индекса.

[[выражение_1]] [выражение_2]

Оператор индекса [] складывает указанные выражения подобно тому, как это делает оператор +, с той разницей, что первое выражение необязательно, при его отсутствии предполагается 0 (двойные квадратные скобки указывают на то, что операнд не обязателен).

Оператор PTR

тип  PTR  выражение

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

 

Имя типа

Значение

BYTE

1

WORD

2

DWORD

4

QWORD

8

TBYTE

10

NEAR

0FFFFh

FAR

0FFFEh

 

Оператор PTR обычно используется для точного определения размера, или расстояния, ссылки. Если PTR не используется, ассемблер подразумевает умалчиваемый тип ссылки. Кроме того, оператор PTR используется для организации доступа к объекту, который при другом способе вызвал бы генерацию сообщения об ошибке (например, для доступа к старшему байту переменной размера WORD).

Операторы HIGH и LOW

HIGH

выражение

LOW

выражение


Операторы HIGH и LOW вычисляют соответственно старшие и младшие 8 битов значения выражения. Выражение может иметь любое значение.

Оператор SEG

SEG  выражение

Этот оператор вычисляет значение атрибута СЕГМЕНТ выражения. Выражение может быть меткой, переменной, именем сегмента, именем группы или другим символом.

Оператор OFFSET

OFFSET  выражение

Этот оператор вычисляет значение атрибута СМЕЩЕНИЕ выражения. Выражение может быть меткой, переменной, именем сегмента или другим символом. Для имени сегмента вычисляется смещение от начала этого сегмента до последнего сгенерированного в этом сегменте байта.

Оператор SIZE

SIZE  переменная

Оператор SIZE определяет число байтов памяти, выделенных переменной.

 

Приоритеты операций

 При вычислении значения выражения операции выполняются в соответствии со следующим списком приоритетов (в порядке убывания):

1.       LENGTH, SIZE, WIDTH, MASK, (), [], <>.

2.       Оператор имени поля структуры (.).

3.       Оператор переключения сегмента (:).

4.       PTR, OFFSET, SEG, TYPE, THIS.

5.       HIGH, LOW.

6.       Унарные + и -.

7.       *, /, MOD, SHR, SHL.

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

9.       EQ, NE, LT, LE, GT, GE.

10.    NOT.

11.    AND.

12.    OR, XOR.

13.    SHORT, .TYPE.

Ссылки вперед

 Хотя ассемблер и допускает ссылки вперед (т.е. к еще необъявленным объектам программы), такие ссылки могут при неправильном использовании приводить к ошибкам. Пример ссылки вперед:

JMP  MET

 ...

MET: ...

  Всякий раз, когда ассемблер обнаруживает неопределенное имя на 1-м проходе, он предполагает, что это ссылка вперед. Если указано только имя, ассемблер делает предположения о его типе и используемом регистре сегмента, в соответствии с которыми и генерируется код. В приведенном выше примере предполагается, что MET – метка типа NEAR и для ее адресации используется регистр CS, в результате чего генерируется инструкция JMP, занимающая 3 байта. Если бы, скажем, в действительности тип ссылки оказался FAR, ассемблеру нужно было бы генерировать 5-байтовую инструкцию, что уже невозможно, и формировалось бы сообщение об ошибке. Во избежание подобных ситуаций рекомендуется придерживаться следующих правил:

1.       Если ссылка вперед является переменной, вычисляемой относительно регистров ES, SS или CS, следует использовать оператор переключения сегмента. Если он не использован, делается попытка вычисления адреса относительно регистра DS.

2.       Если ссылка вперед является меткой инструкции в команде JMP и отстоит не далее, чем на 128 байтов, можно использовать оператор SHORT. Если этого не делать, метке будет присвоен тип FAR, что не вызовет ошибки, но на 2-м проходе ассемблер для сокращения размера содержащей ссылку инструкции вынужден будет вставить дополнительную и ненужную инструкцию NOP.

3.       Если ссылка вперед является меткой инструкции в командах CALL или JMP, следует использовать оператор PTR для определения типа метки. Иначе ассемблер устанавливает тип NEAR, и, если в действительности тип метки окажется FAR, будет выдано сообщение об ошибке.


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

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

Директивы определения данных могут задавать:

        скалярные данные, представляющие собой единичное значение  или набор единичных значений;

        записи, позволяющие манипулировать с данными на уровне бит;

        структуры, отражающие некоторую логическую структуру данных.


Скалярные данные

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

Формат

Функция

[[имя]] DB значение,...

определение байтов

[[имя]] DW значение,...

определение слов

[[имя]] DD значение,...

определение двойных слов

[[имя]] DQ значение,...

определение квадрослов

[[имя]] DT значение,...

определение 10 байтов


Директива DB обеспечивает распределение и  инициализацию 1 байта памяти для каждого из указанных  значений. В качестве значения может кодироваться целое  число, строковая константа, оператор DUP (см. ниже), абсолютное выражение или знак «?». Знак «?» обозначает  неопределенное значение. Значения, если их несколько, должны  разделяться запятыми.  Если директива имеет имя, создается переменная типа  BYTE с соответствующим данному значению указателя позиции  смещением.

Если в одной директиве определения памяти заданы  несколько значений, им распределяются последовательные байты памяти. В этом случае, имя, указанное в начале директивы, именует только первый из этих байтов, остальные остаются безымянными. Для ссылок на них используется выражение вида имя+k, где k – целое число.

Строковая константа может содержать столько символов, сколько помещается на одной строке. Символы строки хранятся в памяти в порядке их следования, т.е. 1-й символ имеет  самый младший адрес, последний - самый старший.

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

счетчик DUP (значение,...)

Указанный в скобках список значений повторяется  многократно в соответствии со значением счетчика. Каждое  значение в скобках может быть любым выражением, имеющим  значением целое число, символьную константу или другой  оператор DUP (допускается до 17 уровней вложенности операторов DUP). Значения, если их несколько, должны  разделяться запятыми.

Оператор DUP может использоваться не только при определении памяти, но и в других директивах.

Синтаксис директив DW, DD, DQ и DT идентичен синтаксису директивы DB.

Примеры директив определения скалярных данных:

integer1

DB

16

string1

DB

'abCDf'

empty1

DB

?

contan2

DW

4*3

string3

DD

'ab'

high4

DQ

18446744073709551615

high5

DT

1208925819614629174706175d

db6

DB

5 DUP(5 DUP(5 DUP(10)))

dw6

DW

DUP(1,2,3,4,5)


Записи

Запись представляет собой набор полей бит,  объединенных одним именем. Каждое поле записи имеет собственную длину, исчисляемую в битах, и не обязано  занимает целое число байтов.  Объявление записи в программе на языке ассемблера  включает в себя 2 действия:

        объявление шаблона или типа записи директивой  RECORD;

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


Формат директивы RECORD:

имя_записи  RECORD  имя_поля:длина[[=выражение]],...

Директива RECORD определяет вид 8- или 16-битовой  записи, содержащей одно или несколько полей. Имя_записи  представляет собой имя типа записи, которое будет  использоваться при объявлении записи. Имя_поля и длина (в битах) описывает конкретное поле записи. Выражение, если оно  указано задает начальное (умалчиваемое) значение поля. Описания полей записи в директиве RECORD, если их  несколько, должны разделяться запятыми. Для одной записи  может быть задано любое число полей, но их суммарная длина не должна превышать 16 бит.

Длина каждого поля задается константой в пределах от 1  до 16. Если общая длина полей превышает 8 бит, ассемблер  выделяет под запись 2 байта, в противном случае – 1 байт.  Если задано выражение, оно определяет начальное значение поля. Если длина поля не меньше 7 бит, в качестве  выражения может быть использован символ в коде ASCII.  Выражение не должно содержать ссылок вперед. Пример:

item  RECORD   char:7='Q',weight:4=2

Запись item будет иметь следующий вид:

 

char

weight

0000

1010001

0010

 

При обработке директивы RECORD формируется шаблон  записи, а сами данные создаются при объявлении записи,  которое имеет следующий вид:

[[имя]]  имя_записи  <[[значение,...]]>

По такому объявлению создается переменная типа записи  с 8- или 16-битовым значением и структурой полей,  соответствующей шаблону, заданному директивой RECORD с именем имя_записи.  Имя задает имя переменной типа записи. Если имя  опущено, ассемблер распределяет память, но не создает переменную, которую можно было бы использовать для доступа к записи.

В скобках <> указывается список значений полей записи.  Значения в списке, если их несколько, должны разделяться  запятыми. Каждое значение может быть целым числом, строковой  константой или выражением и должно соответствовать длине  данного поля. Для каждого поля может быть задано одно  значение.  Скобки <> обязательны, даже если начальные значения не  заданы. Пример:

table  item 10  DUP(<'A',2>)

Если для описания шаблона записи использовалась  директива RECORD из предыдущего примера, то по этому объявлению  создается 10 записей, объединенных именем table.

 

Структуры

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

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

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

Формат объявления типа структуры:

имя STRUC

    описания_полей

имя ENDS

Директивы STRUC и ENDS обозначают соответственно  начало и конец описания шаблона (типа) структуры. Описание  типа структуры задает имя типа структуры и число, типы и  начальные значения полей структуры. Описания_полей определяют поля структуры и могут быть заданы  аналогично описанию скалярных типов. Пример:

table  STRUC

    count  DB  10

    value  DW  10 DUP(?)

    tname  DB  'font'

table   ENDS

При обработке директив STRUC и ENDS формируется шаблон  структуры, а сами данные создаются при объявлении структуры,  которое имеет следующий вид:

[[имя]]   имя_структуры <[[значение,...]]>

Значения полей в объявлении  структуры аналогично значению полей при объявлении записи.

 

Информация о работе Структура ассемблерных программ