Синтаксис макроассемблера masm32



Мы поможем в написании ваших работ!


Мы поможем в написании ваших работ!



Мы поможем в написании ваших работ!


ЗНАЕТЕ ЛИ ВЫ?

Синтаксис макроассемблера masm32



Соглашения по именованию

Имена переменных, констант и меток должны удовлетворять следующим условиям.

1. Длина идентификатора не должна превышать 247 символов.

2. Регистр букв идентификаторов не учитывается, если только нет опции option casemap: none

3. Первым символом идентификатора должна быть одна из букв латинского алфавита (A…Z или a…z) либо символы подчёркивания (_) либо знака доллара ($). Последующие символы могут быть также цифрами.

4. Идентификатор не должен совпадать с любым из зарезервированных слов макроассемблера: директивы, команды ассемблера, типы данных, встроенные идентификаторы ассемблера, которые начинаются со знака коммерческого “эт” (@).

Директивы

Директива – команда макроассемблера, которая выполняется во время трансляции исходного кода программы. Директивы используются для определения логических сегментов, выбора модели памяти, определения переменных, создания процедур и т.п. Директивы независимы от регистра символов, поэтому записи .data, .DATA или .Data совершенно одинаковы.

Директива .data определяет сегмент программы, в котором располагаются значения переменных, хранимых в exe-файле.

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

Директива .code определяет сегмент в программе, в котором располагаются машинные команды.

В masm32 предусмотрено большое количество разных директив. Полный список директив и операторов можно просмотреть в справке masm32 ® Help ® Masm32 Help ® Full Listing.

Формат записи команды ассемблера имеет четыре поля:

Метка: Мнемоника Операнд(ы) ; Комментарии

Однострочные комментарии начинаются с символа точки с запятой (;) и располагаются до конца текущей строки.

Блочные комментарии начинаются с директивы COMMENT, за которой следует маркер начала и конца блока, определяемы программистом. Текст комментария располагается между маркерами, например:

COMMENT !

Текст комментария

Текст комментария

!

Здесь роль маркера играет восклицательный знак.

Определение типов данных

Пример 1.1.4. Разработаем программу сложения трёх беззнаковых четырёхбайтовых чисел, хранящихся в исполнимом файле, и размещения суммы в ячейках неинициализированной памяти. Пусть значения трёх слагаемых: 11111111h, 0AAAAAAAAh и 44444444h. Имена переменных, в которых будут храниться эти слагаемые соответственно пусть будут X, Y и Z. В качестве имени переменной, в которую будет записана сумма, выберем SUM. Заметим, что размер каждого слагаемого 4 байта.

В таблице 1.1.1 представлены целочисленные типы данных, используемые в masm32.

Таблица 1.1.1. Целочисленные типы данных

Тип (Type) Размер (Size) Описание (Description)
BYTE 1 byte 8-разрядное беззнаковое целое (0…255)
SBYTE 1 byte 8-разрядное знаковое целое (-128…+127)
WORD 2 bytes 16-разрядное беззнаковое целое (0…65’535)
SWORD 2 bytes 16-разрядное знаковое целое (-32’768…+32’767)
DWORD 4 bytes 32-разрядное беззнаковое целое (0…4’294’967’295)
SDWORD 4 bytes 32-разрядное знаковое целое (-2’147’483’648…+2’147’483’647)
FWORD 6 bytes 48-разрядное беззнаковое целое
QWORD 8 bytes 64-разрядное беззнаковое целое
TBYTE 10 bytes 80-разрядное беззнаковое целое

Как видно из таблицы беззнаковое четырёхбайтовое число имеет тип DWORD. Следовательно, в программе необходимо объявить переменные X, Y, Z и SUM типа DWORD. Теперь можно записать исходный текст программы.

.386

.model flat, stdcall

option casemap: none

include \masm32\include\windows.inc

include \masm32\include\kernel32.inc

include \masm32\include\masm32.inc

include \masm32\include\debug.inc

includelib \masm32\lib\kernel32.lib

includelib \masm32\lib\masm32.lib

includelib \masm32\lib\debug.lib

.data

X dword 11111111h ; Инициализация переменной X

Y dword 0AAAAAAAAh ; Инициализация переменной Y

Z dword 44444444h ; Инициализация переменной Z

.data?

SUM dword ? ; Выделение памяти под переменную SUM

.code

start:

mov eax, X

PrintHex eax, "- Инициализация eax"

add eax, Y

PrintHex eax, "- Первое сложение"

add eax, Z

PrintHex eax, "- Второе сложение"

mov SUM, eax

PrintHex SUM, "- Запись результата в SUM"

ret

end start

Запустите программу и проверьте правильность полученного результата на калькуляторе MS Windows.

Основные логические команды ассемблера

Потренируемся писать программы, используя простейшие логические команды. Описание логических команд приведено в приложении Б, а также в справке masm32 ® Help ® Opcodes Help. К основным логическим командам можно отнести:

1. or operand1, operand2 – команда поразрядного логического сложения (ИЛИ). В математических выражениях обозначается символом Ú. Результат помещается в operand1.

2. and operand1, operand2 – команда поразрядного логического умножения (И). В математических выражениях обозначается символом Ù. Результат помещается в operand1.

3. xor operand1, operand2 – команда поразрядного логического сложения по модулю 2 (исключающее ИЛИ). В математических выражениях обозначается символом Å. Результат помещается в operand1.

4. not operand1 – команда поразрядного логического отрицания (НЕ). В математических выражениях обозначается символом Ø. Результат помещается в operand1.

Заметим, что размер операндов в двухоперандных командах должен быть одинаков.

Упражнение 1.1.3. Разработайте программу для вычисления выражения R = (XÚY) + (XÙZ). Исходные данные хранить в переменных:

X = 11111111h

Y = 0EEEEEEEEh

Z = 1h

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

Упражнение 1.1.4. Разработайте программу для вычисления выражения R = Ø(XÙY) Å (XÙZ). Исходные данные хранить в переменных:

X = 11111111h

Y = 33333333h

Z = 99999999h

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

Упражнение 1.1.5. Разработайте программу для вычисления выражения R = 1 Å 2 Å 3 Å 4 Å 5, используя для этого регистры наименьшего размера. Результат вывести в шестнадцатеричном представлении.

Упражнение 1.1.6. Разработайте программу для вычисления выражения R = X‑Y+Z. Исходные данные хранить в переменных со знаковым типом данных:

X = 1234567d

Y = 2345678d

Z = -1000000d

Оператор повторения DUP

Для создания переменных, содержащих повторяющиеся значения элементов, используется оператор DUP. Например, оператор:

X byte 8 DUP(41h)

инициализирует переменную X байтом 41h, повторенным 8 раз, т.е. числом 4141414141414141h.

В макроассемблере смысл понятия “переменная” отличается от этого понятия, используемого в языках высокого уровня. На самом деле переменная X есть не что иное, как адрес, по которому располагается первый байт из последовательности повторяющихся байтов. Второй байт будет располагаться по адресу X+1, третий байт по адресу X+2 и т.д.

Поэтому команда ассемблера mov al, X означает пересылку в регистр al первого байта, расположенного в памяти по адресу X. Для пересылки второго байта надо воспользоваться командой mov al, X+1, третьего байта mov al, X+2, четвёртого байта mov al, X+3 и т.д.

Для загрузки в регистр общего назначения собственно адреса X, а не данных, хранящихся по этому адресу, существует специальная команда загрузки расширенного адреса lea ebx, X. Загрузку адреса можно осуществить также и командой пересылки mov eax, offset X. Здесь ключевую роль играет директива offset. Встречая эту директиву, masm32 ещё на этапе компиляции определяет конкретный адрес X и подставляет его непосредственно в код команды. В отличие от offset команда lea вычисляет адрес X в ходе выполнения программы. Однако результаты при этом получаются одинаковые.

Пример 1.1.5. Найдём адреса ячеек памяти, по которому masm32 разместит байты переменной X, объявленной выше, и увеличим самый первый байт переменной X на единицу, а второй байт уменьшим на единицу. Для вывода дампа памяти воспользуемся командой отладчика DbgDump. Обратите внимание на символьное представление данных в дампе памяти. Байт 42h – код большой латинской буквы B.

.386

.model flat, stdcall

option casemap: none

include \masm32\include\windows.inc

include \masm32\include\kernel32.inc

include \masm32\include\masm32.inc

include \masm32\include\debug.inc

includelib \masm32\lib\kernel32.lib

includelib \masm32\lib\masm32.lib

includelib \masm32\lib\debug.lib

.data

X byte 8 DUP(42h) ; объявление и инициализация переменной X

.code

start:

mov eax, offset X ; загрузка в eax адреса переменной X (1 способ)

PrintHex eax, "-адрес, полученный ком-й mov eax, offset X"

lea ebx, X ; загрузка в ebx адреса переменной X (2 способ)

PrintHex ebx, "- адрес, полученный командой lea ebx, X"

DbgDump offset X, 8 ; печать дампа памяти

inc X ; инкремент первого байта переменной X

DbgDump offset X, 8 ; печать дампа памяти

dec X+1 ; декремент второго байта переменной X

DbgDump offset X, 8 ; печать дампа памяти

ret

end start

Команда inc X осуществляет увеличение на единицу байта, хранящегося по адресу X. Команда dec X+1 уменьшает на единицу содержимое байта, хранящегося по адресу X+1.

В этом примере показано два равноправных способа получения адреса, по которому хранится переменная. Первый способ mov eax, offset X выполняется за 4 такта на i80386, а второй способ lea ebx, X за два такта. На процессорах i80486 и более поздних обе команды выполняются за один такт (см. справку masm32 ® Help ® Opcodes Help ® mov и lea).

Упражнение 1.1.7. Используя определение данных из примера 1.1.5, разработайте программу определения суммы всех восьми байтов. Заметьте, что размер суммы восьми байтов 42h больше одного байта. Поэтому сумму необходимо аккумулировать в двухбайтовом или четырёхбайтовом регистре. Перед сложением аккумулятора al с очередным байтом из памяти необходимо предварительно занести этот байт в другой регистр, например в bl:

mov eax,0 ; обнуление регистра eax

mov ebx,0 ; обнуление регистра ebx

mov al,X ; размещение первого байта в регистре al

mov bl,X+1 ; размещение второго байта в регистре bl

add eax,ebx ; сложение первого и второго байта,

; результат – в eax

Множественная инициализация

Множественная инициализация используется для определения массивов данных. Например, оператор:

X word 2222h, 3333h, 8888d, 9090d

инициализирует переменную X словом 2222h или, что то же самое, записывает в адрес X слово 2222h. Слово 3333h располагается в памяти по адресу X+2, так как размер первого слова два байта. Слово 8888d располагается в памяти по адресу X+4, а слово 9090d – по адресу X+6. Обратите внимание, что множественная инициализация допускает смешение типов данных.

Упражнение 1.1.8. Инициировать в памяти ASCII-коды первых восьми прописных букв латинского алфавита и вывести их дамп памяти. Подсказка: ASCII–код прописной латинской буквы “A” равен 41h.



Последнее изменение этой страницы: 2016-06-29; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 3.236.232.99 (0.01 с.)