Разместите нашу кнопку!

Новые статьи:

Programming articles

Создание сайтов на шаблонах

Множество вариантов работы с графикой на канве

Шифруем файл с помощью другого файла

Перехват API функций - Основы

Как сделать действительно хороший сайт

Создание почтового клиента в Delphi 7

Применение паскаля для решения геометрических задач

Управление windows с помощью Delphi

Создание wap сайта

Операционная система unix, термины и понятия

SQL враг или друг

Возникновение и первая редакция ОС UNIX

Оптимизация проекта в Delphi

Ресурсы, зачем нужны ресурсы

Термины программистов 20 века

Советы по созданию собственного сайта с нуля

Шифруем файл с помощью пароля

Фракталы - геометрия природы

Crypt - Delphi программа для шифрования

Рассылка, зачем она нужна и как ее организовать?

Учебник по C++ для начинающих программистов

Уроки для изучения ассемблера

Загадочный тип PCHAR

Средства по созданию сайтов

Операторы преобразования классов is и as

Borland Developer studio 2006. Всё в одном

Создание базы данных в Delphi, без сторонних БД


Software engineering articles



Assembler&Win32. Курс молодого бойца. Урок 10.

Упрощаем программирование

     Альтернативы секции .const
     Главной альтернативой секции .const является простое объявление символьной константы. Всё гениальное просто (слишком сильно сказано):

     CONST_VALUE = 678h
     .data
     Dd CONST_VALUE
     .code
…..more code…
     Mov edi, CONST_VALUE
     Xor eax, CONST_VALUE

     Вторая не менее важная альтернатива это определение "макросимвола" (я это сам придумал, а по научному абсолютный символ или "прозвище"). Он задаётся через директиву equ.

     примеры

      CONST1 equ 0123h
     CONST2 equ 14d*15h
     CONST3 equ "slovo"
     CONST4 equ 56-45
     CONST5 equ (offset metka1)
     CONST6 equ (offset metka2+offset metka3)
     CONST7 equ (CONST2+10b)
     CONST8 equ CONST7/2
     CONST9 equ (offset metka1-offse metka5)
     CONST10 equ (offset metka4+CONST4)
     CONST11 equ add edx,edi
…. и так далее до посинения ……. :

    Директива equ используется в там же, где определяются символьные константы. Это ещё не все возможности этой директивы. О ней можно говорить очень много. Я вам объяснил, как надо объявлять численные константы, но также можно дать прозвище некоторой команде, например:

     Command1 equ mov eax, esi.

    После этого при каждом упоминании command1 будет подразумеваться команда move eax, esi.

     Пример
     Mov eax, CONST1
     Add edi, CONST2
     Xor ebp, CONST7
     CONST11
     Sub edx, CONST8

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

     Макросы.
     Макрос - это набор команд. С помощью equ мы могли создавать "прозвище" только для одной команды, а с помощью макросов можно создавать "прозвище" для нескольких команд. Для создания макроса надо использовать директивы macro и соответственно endm.

     Firstmacro macro
         Sub ebp, esp
         Mov eax, ebp
         Endm

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

     Secondmacro macro param1, param2
           Add edi, param1
           Sub esi, param2
         endm
     .code ; использование
     ………………………
     Secondmacro 55h,edx

     У макросов очень много возможностей. Я объяснил самые важные из них, а на объяснение всех возможностей этого урока не хватит. Макросы очень часто используются в MASM.

     Включаемые файлы.
     Иногда надоедает (особенно при создании оконных приложений) объявлять в каждой программе одни и те же структуры и константы. Хотелось бы один раз их задать, а потом их использовать в каждой своей программе как в Си или Паскале. Для этого предназначены включаемые файлы *.inc. В них можно задать структуры, константы, макросы. Для включения такого файла надо использовать директиву include. После этой директивы надо указать путь к включаемому файлу абсолютный или относительный. При написании такого файла просто думайте, что вы находитесь после директивы .model и до .data.

     Пример:

Файл sample.asm
;=======[CUT HERE]========
.386
.model flat, stdcall

include sample.inc

extrn MessageBoxA:PROC

.data

Msg db "First ASSEMBLER program",0h
Ttl db 'Hello, World!!!!',0h
RCTNGL RECT ?
.code

start:
     call MessageBoxA,0,offset Msg,offset Ttl,MB_OKCANCEL
     call ExitProcess, 0
end start
;=====[CUT HERE]==========
     Файл sample.inc
;=======[CUT HERE]========
extrn ExitProcess:PROC

UINT EQU
<DD>; 32 bits for WIN32

RECT struc
     rcLeft          UINT ?
     rcTop          UINT ?
     rcRight         UINT ?
     rcBottom     UINT ?
RECT ends

MB_OK = 0000H
MB_OKCANCEL = 0001H
MB_ABORTRETRYIGNORE = 0002H
MB_YESNOCANCEL = 0003H
MB_YESNO = 0004H
MB_RETRYCANCEL = 0005H
;=====[CUT HERE]===========

    Думаю что с включаемыми файлами всё понятно. Директива include заменяется на всё содержимое включаемого файла.

     Упрощённый вызов API функций в TASM.
     Если мы укажем в директиве .model укажем модель вызова функций. То вызывать API будет намного проще

Call <функция>, <параметр1>,<параметр2>,<параметр3>

    Теперь наша первая программа будет иметь такой вид:
     .386
.model flat, stdcall

extrn MessageBoxA:PROC
extrn ExitProcess:PROC
.data

Msg db "First ASSEMBLER program",0h
Ttl db 'Hello, World!!!!',0h


.code

start:
     call MessageBoxA,0,offset Msg,offset Ttl,0
     call ExitProcess, 0
end      start


Команда

call func, param1,pram2, paramn

при компиляции автоматически преобразуется в

     Push paramn
     Push param2
     Push param1
     Call func

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

     Реализация конструкции if.
     Если у вас есть опыт в языках программирования, возможно, вы видели что-то вроде if/else конструкций:

.IF eax==1
;eax равен 1
.ELSEIF eax=3
; eax равен 3
.ELSE
; eax не равен 1 и 3
.ENDIF

    Эта конструкция очень полезна. Вам не нужно вставлять сравнения и переходы, а только вставте директиву .IF (не забудьте точку перед .IF и .ELSE и т.д.). Директива .endif нужна для определения ещё одного сравнения, если предыдущие сравнения были ложгыми. Инструкции после директивы .else выполняются только в том случае, если все сравнения были ложными. Вложенности if позволяются:

.IF eax==1
.IF ecx!=2
; eax= 1 и ecx не равно 2
.ENDIF
.ENDIF

Это может быть сделано проще:

.IF (eax==1 && ecx!=2)
; eax = 1 и ecx не равно 2
.ENDIF


    А вот и операторы, которые вы можете использовать:
== равно
!= не равно
> больше
< меньше
>= больше или равно
<= меньше или равно
& проверка бита
! инверсия ( NOT )
&& логическое 'И' ( AND )
|| логическое 'ИЛИ' ( OR )
CARRY? флаг переноса (cf) установле
OVERFLOW? флаг переполнения (of) установлен
PARITY флаг паритета (pf) установлен
SIGN? флаг знака (sf) установлен
ZERO? флаг нуля (zf) установлен

     Такая конструкция есть и в TASM и в MASM.

     Вот и кончился очередной урок. На следующем уроке я объясню ещё несколько команд ассемблера.