Как пользоваться masm32
Перейти к содержимому

Как пользоваться masm32

Компилятор MASM

На всех предыдущих уроках я рассказывал о компиляторе TASM, потому что он стандартный и ненавороченный. Но более популярный компилятор это MASM, он создан специально для написания программ на ассемблере для Win32. В нём есть макросы и специальные директивы для упрощения программирования.

Функции.

Основное преимущество MASM это макрос invoke, он позволяет вызывать API функции по-обычному с проверкой количества и типа параметров. Это почти тот же call, как в TASM, но этот макрос проверяет количество параметров и их типы. Вот так вызывается функция:

Чтобы использовать invoke для вызова процедуры, вы должны определить ее прототип:

Эта директива объявляет процедуру, названную testproc, которая берет 3 параметра размером DWORD.

Теперь, если вы сделаете это.

masm выдаст вам ошибку потому, что процедура testproc берет 3 параметра, а не 4. Masm также имеет контроль соответствия типов, т.е. проверяет, имеют ли параметры правильный тип (размер).

В invoke вы можете использовать ADDR вместо OFFSET. Это сделает адрес в правильной форме, когда код будет собран.

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

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

Конструкции сравнения и повтора.

If — Об этой конструкции я рассказывал на 10 уроке. Она имеет тот же самый синтаксис, что и в TASM.

Repeat — Эта конструкция выполняет блок, пока условие не истинно:

Эта конструкция повторяет код между repeat и until, пока eax не станет равным 1.

While — Конструкция while это инверсия конструкции repeat. Она выполняет блок, пока условие истинно:

Вы можете использовать директиву .BREAK, чтобы прервать цикл и выйти.

Если eax=7, цикл while будет прерван.

Директива continue осуществляет переход на код проверяющий условие цикла в конструкциях repeat и while.

Теперь наша первая программа видоизменяется следующим образом:

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

Прототипы каждой из библиотек есть в одноимённых включаемых файлах в папке include. Теперь не надо писать прототипы функций самому, они уже есть:

В этих включаемых файлах определены функции без букв A или W в конце. Теперь не надо указывать эти буквы в конце.

Директива option нужна для задания некоторых настроек компиляции. Опция casemap задаёт чувствительность к регистру символов. Мы указали none, тем самым установили чувствительность к регистру символов. Это надо, для того чтобы избежать конфликтов включаемых файлов от разных авторов.

Компиляция.

В основном вы будете использовать эту опцию, так как вы будете использовать внешний линкер (например link.exe), для компоновки ваших файлов.

Это генерирует формат файла для компоновщика microsoft.

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

выберите тип вызовов для ваших процедур.

Установите эту опцию, если хотите использовать отладчик.

Определяет ваш include путь

Линковка:

Это создаст информацию для отладки. Используйте эту опцию, когда вы хотите использовать отладчик.

Выбирает выходной формат отладочной информации. Это зависит от вашего отладчика. Softice и visual c++ отладчики оба могут обрабатывать CV (codeview)

Указывает файл определения (.def). Используется с dll, для экспортируемых функций.

Выходной файл DLL, а не EXE.

Указывает путь к файлам библиотек (*.lib).

Указывает путь для inc-файлов, по умолчанию.

Может изменить имя выходного файла.

Выбирает ОС на которой должна выполнятся программа: NATIVE|WINDOWS|CONSOLE|WINDOWSCE|POSIX

Я установил masm в папку d:\masm\masm32, в папке d:\masm находятся все тексты наших программ *.asm. А для компиляции я создал bat файл, который компилирует файл current.asm:

В результате после запуска это файл у нас в папке d:\masm готовая скомпилированная программа current.exe.

Вот и конец этого урока. В этом уроке я рассказал про макрософтский компилятор MASM. На следующем уроке мы напишем первое оконное приложение на ассемблере.

Клуб программистов

На всех предыдущих уроках я рассказывал о компиляторе TASM, потому что он стандартный и ненавороченный. Но более популярный компилятор это MASM, он создан специально для написания программ на ассемблере для Win32. В нём есть макросы и специальные директивы для упрощения программирования.

Функции.
Основное преимущество MASM это макрос invoke, он позволяет вызывать API функции по-обычному с проверкой количества и типа параметров. Это почти тот же call, как в TASM, но этот макрос проверяет количество параметров и их типы. Вот так вызывается функция:
Invoke <функция>, <параметр1>, <параметр2>, <параметр3>

Чтобы использовать invoke для вызова процедуры, вы должны определить ее прототип:

PROTO STDCALL testproc:DWORD, :DWORD, :DWORD

Эта директива объявляет процедуру, названную testproc, которая берет 3 параметра размером DWORD.
Теперь, если вы сделаете это.

invoke testproc, 1, 2, 3, 4

. masm выдаст вам ошибку потому, что процедура testproc берет 3 параметра, а не 4. Masm также имеет контроль соответствия типов, т.е. проверяет, имеют ли параметры правильный тип (размер).

В invoke вы можете использовать ADDR вместо OFFSET. Это сделает адрес в правильной форме, когда код будет собран.

testproc PROTO STDCALL :DWORD, :DWORD, :DWORD
.code
testproc proc param1:DWORD, param2:DWORD, param3:DWORD
……….
ret
testproc endp

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

testproc proc param1:DWORD, param2:DWORD, param3:DWORD
LOCAL var1:DWORD
LOCAL var2:BYTE
mov ecx, param1
mov var2, cl
mov edx, param2
mov eax, param3
mov var1, eax
add edx, eax
mul eax, ecx
mov ebx, var1
.IF bl==var2
xor eax, eax
.ENDIF
ret
testproc endp

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

Конструкции сравнения и повтора.

If
Об этой конструкции я рассказывал на 10 уроке. Она имеет тот же самый синтаксис, что и в TASM.

Repeat
Эта конструкция выполняет блок, пока условие не истинно:

.REPEAT
; код здесь
.UNTIL eax==1

Эта конструкция повторяет код между repeat и until, пока eax не станет равным 1.

While
Конструкция while это инверсия конструкции repeat. Она выполняет блок, пока условие истинно:

.WHILE eax==1
; код здесь
.ENDW

Вы можете использовать директиву .BREAK, чтобы прервать цикл и выйти.

.WHILE edx==1
inc eax
.IF eax==7
.BREAK
.ENDIF
.ENDW
Если eax=7, цикл while будет прерван.
Директива continue осуществляет переход на код проверяющий условие цикла в конструкциях repeat и while.Теперь наша первая программа видоизменяется следующим образом:

.486
.model flat, stdcall
option casemap :none

includelib .\masm32\lib\kernel32.lib
includelib .\masm32\lib\user32.lib
MessageBoxA PROTO STDCALL :DWORD, :DWORD, :DWORD, :DWORD
ExitProcess PROTO STDCALL :DWORD

.data
ttl db ‘11111’,0
.code
start:
invoke MessageBoxA,0,offset ttl,offset ttl,0
invoke ExitProcess,0
end start

При компиляции в TASM пути к статическим библиотекам мы указывали при компиляции, в MASM пути к статическим библиотекам мы указываем в тексте программы точно так же как и пути к включаемым файлам с помощью директивы includelib.
Прототипы каждой из библиотек есть в одноимённых включаемых файлах в папке include. Теперь не надо писать прототипы функций самому, они уже есть:
includelib .\masm32\lib\kernel32.lib
includelib .\masm32\lib\user32.lib
include .\masm32\include\kernel32.inc
include .\masm32\include\user32.inc
В этих включаемых файлах определены функции без букв A или W в конце. Теперь не надо указывать эти буквы в конце.
Директива option нужна для задания некоторых настроек компиляции. Опция casemap задаёт чувствительность к регистру символов. Мы указали none, тем самым установили чувствительность к регистру символов. Это надо, для того чтобы избежать конфликтов включаемых файлов от разных авторов.

ML [ /опции ] filelist [ /link linkoptions ]

/c ассемблирование без линковки
В основном вы будете использовать эту опцию, так как вы будете использовать внешний линкер (например link.exe), для компоновки ваших файлов.
/coff генерировать объектный файл в COFF формате
Это генерирует формат файла для компоновщика microsoft.
/Fo<file> имя объектного файла
может использоваться, если вы хотите, чтобы выходной файл был с другим именем, не таким как исходный файл.
/G<c|d|z> Использует вызовы Pascal, C, или Stdcall
выберите тип вызовов для ваших процедур.
/Zi Добавить символьную отладочную информацию
Установите эту опцию, если хотите использовать отладчик.
/I<name> Установить include путь
Определяет ваш include путь

LINK [опции] [файлы] [@commandfile]

/DEBUG Отладка
Это создаст информацию для отладки. Используйте эту опцию, когда вы хотите использовать отладчик.
DEBUGTYPE:CV|COFF Тип отладки: codeview / coff
Выбирает выходной формат отладочной информации. Это зависит от вашего отладчика. Softice и visual c++ отладчики оба могут обрабатывать CV (codeview)
/DEF:имя_файла DEF файл
Указывает файл определения (.def). Используется с dll, для экспортируемых функций.
/DLL DLL
Выходной файл DLL, а не EXE.
/LIBPATH:path Путь к библиотекам
Указывает путь к файлам библиотек (*.lib).
/I<имя> Устанавливает путь для inc-файлов
Указывает путь для inc-файлов, по умолчанию.
/OUT:имя_файла Out:имя_файла
Может изменить имя выходного файла.
/SUBSYSTEM: Подсистема
Выбирает ОС на которой должна выполнятся программа: NATIVE|WINDOWS|CONSOLE|WINDOWSCE|POSIX

Я установил masm в папку d:\masm\masm32, в папке d:\masm находятся все тексты наших программ *.asm. А для компиляции я создал bat файл, который компилирует файл current.asm:
;======[CUT HERE]=====
d:\masm\masm32\bin\ml.exe /c /coff current.asm
d:\masm\masm32\bin\link.exe /subsystem:windows current.obj
pause
;=======[CUT HERE]========
В результате после запуска это файл у нас в папке d:\masm готовая скомпилированная программа current.exe.

Вот и конец этого урока. В этом уроке я рассказал про макрософтский компилятор MASM. На следующем уроке мы напишем первое оконное приложение на ассемблере.

Разминка. Первая программа

Есть вопросы - пишите.

Итак, приступим. Нам понадобится сам MASM32, который легко найти в Интернете. Для своих проектов создадим папку, но, желательно не внутри MASM32. Назовем ее, но так, чтобы в названии были только английские буквы — компилятор, гад, по-русски не понимает и при компилляции будут трудности. Если имя не придумывается, то назовем просто ASM. Получилось? Тогда начнем. Немножко теории. В ассемблере любая программа содержит сегмент данных — он отмечается символом .data, сегмент констант — .const и сегмент кода — .code. В сегмент данных заносятся переменные, которые будут доступны из любой точки программы (глобальные переменные). То же самое относится и к сегменту констант. Тогда в общем виде структура программы имеет вид:

.data — глобальные переменные
.const — константы (по ходу дела не меняются)
.code — исполняемый код прогаммы
start: — его начало и наконец,
end start — его окончание.

MASM32 использует плоскую модель памяти — никаких сегментов памяти нет, она, в принципе, доступна вся. Об этом — в самом начале программы мы должны сообщить компиллятору (который сделает их нашего текста исполняемый .ехе файл):

.386 ; процессор
.model flat, stdcall ; 32 разрядная модель памяти
option casemap :none ; различает строчные и заглавные буквы

Накопленный человечеством опыт собран в библиотеках. Опыт программистов также собран в библиотеках — динамических и статических. Нам не нужно изобретать велосипед заново — воспользуемся тем, что уже есть (по крайней мере, на первых порах). Windows содержит огромное количество функций в библиотеках динамической компоновки (DLL — dynamic link library), эти функции часто называют API(Application Programming Interface). Подключим к нашему проекту библиотеки. Это делается помощью include и includelib так:

include \masm32\include\user32.inc
includelib \masm32\lib\user32.lib

Если мы впишем в текст программы эти строки, то к нашему проекту будет подключена библиотека user32. Одной библиотекой, как правило, не обойтись, чаще всего стандартный набор выглядит так:

include \masm32\include\windows.inc
include \masm32\include\masm32.inc
include \masm32\include\gdi32.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
include \masm32\include\Comctl32.inc
include \masm32\include\comdlg32.inc
include \masm32\include\shell32.inc
include \MASM32\include\oleaut32.inc

includelib \masm32\lib\masm32.lib
includelib \masm32\lib\gdi32.lib
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\Comctl32.lib
includelib \masm32\lib\comdlg32.lib
includelib \masm32\lib\shell32.lib
includelib \masm32\lib\oleaut32.lib

Все понятно? Если не все (или все не) — ничего страшного, потом разберемся. Едем дальше. Наша первая программа:

.386
.model flat, stdcall
option casemap :none
include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib

.data
TitleMsg db «Первая программа»,0
TextMsg db «Пишем здесь чаво-нибудь, типа — это я сам сделал(а)!» ,0

.code
start:
invoke MessageBox, NULL,ADDR TextMsg,ADDR TitleMsg, MB_OK
invoke ExitProcess, NULL
end start uild

Аккуратно копируем то, что между линиями отреза (они не должны попасть в копируемую область!), откравыем MASM32 editor, в меню File выбираем пункт New и вставляем туда скопированное. Теперь сохраним созданный файл в нашей папке под каким-нибудь название, и, что очень важно, с расширением .asm, ну, например, first.asm. Получилось? Если нет — то повторим все еще раз (или не раз, пока не получится). Теперь — компиляция, т.е. создание .ехе-файла. В меню редактора выбираем пункт Project и в нем — пункт Build All. Выдохнули и нажали. Если все сделано правильно, через какое-то время на экране появится что-то вроде:

Если картинка похожа, то .ехе-файл создан. Открываем нашу папку и находим его. Если папка была сначала пустой, то после компиляции там три файла — один first.asm — это наш исходник, другой, похожий на использованную туалетную бумагу — first.obj, и наконец, наш файл first.exe. Щелкаем по нему мышкой. Работает? Если не работает — ищем, что сделано неправильно, а если работает — то еще похожий пример:

.386
.model flat, stdcall
option casemap :none

include \masm32\include\windows.inc
include \masm32\include\masm32.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
includelib \masm32\lib\masm32.lib
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib

TextMsg1 db «Здесь — текст, типа — это я сам сделал(а)!» ,0
TextMsg2 db» (чтобы показывать друзьям и знакомым )»,0
TextMsg3 db «Copyright © А здесь — свою ФИО., «,13,10,»(полностью, чтобы они поверили)»,13,10,»ну и, конечно, -All Right Reserved»,0

.code
start:
invoke AboutBox,NULL,NULL,NULL,ADDR TextMsg1,ADDR TextMsg2,ADDR TextMsg3
invoke ExitProcess, NULL
end start

Повторим все то, что мы сделали раньше. Запускается? Для тех, у кого рука дрожит и текст не копируется, исходники — пример 1 и пример 2

Ну вот, разминка закончена. Тот, кто понял, что MASM32 он уже полностью освоил, может расслабиться, а для остальных — продолжение на следующей странице.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *