Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
СПО_Лекции_2011_01.docx
Скачиваний:
7
Добавлен:
31.07.2019
Размер:
521.09 Кб
Скачать

Упрощённый вызов 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 )

II

логическое 'ИЛИ' ( OR )

CARRY?

флаг переноса (cf) установле

OVERFLOW?

флаг переполнения (of) установлен

PARITY

флаг паритета (pf) установлен

SIGN?

флаг знака (sf) установлен

ZERO?

флаг нуля (zf) установлен

Такая конструкция есть и в TASM и в MASM. Биты, сдвиг логический, арифметический и циклический.

Обратите внимание: Большинство примеров ниже использует 8 битные числа, это сделано для того, чтобы вам было легче понять, как это работает.

Функции сдвига (сдвиг логический операнда влево/вправо)

SHL операнд, количество_сдвигов SHR операнд, количество_сдвигов

SHL и SHR сдвигают биты операнда (регистр/память) влево или вправо соответственно на один разряд.

Указанное выше действие повторяется количество раз, равное значению второго операнда.

Пример:

; al = 01011011 (двоичное) shr al, 3

Это означает: сдвиг всех битов регистра al на 3 разряда вправо. Так что al станет 00001011. Биты слева заполняются нулями, а биты справа выдвигаются. Последний выдвинутый бит, становится значением флага переноса cf.

Бит переноса это бит флагового регистра процессора. Этот регистр не такой как eax или ecx, к которому вы можете непосредственно обращаться (хотя есть опкоды, которые это делают), его содержание, зависит от результатов многих команд. Об этом я вам расскажу позже, единственное, что вы должны сейчас запомнить, это то, что флаг переноса это бит во флаговом регистре и что он может быть установлен (т.е. равен 1) или сброшен (равен 0). Команда shl такая же, как и shr, но сдвигает влево.

; bl = 11100101 (двоичное) shl bl, 2

После выполнения команды регистр bl будет равен 10010100 (двоичное). Два последних бита заполнились нулями, флаг переноса установлен, потому, что последний выдвинутый слева бит был равен 1

Здесь есть еще два других опкода: (сдвиг арифметический операнда влево/вправо)

SAL операнд, количество_сдвигов SAR операнд, количество_сдвигов

Команда SAL такая же, как SHL, а вот SAR не совсем такая, как SHR. Команда SAR также, как и SHR сдвигает все биты операнда вправо на один разряд, при этом выдвигаемый справа бит становится значением флага переноса cf. Обратите внимание: одновременно слева в операнд вдвигается не нулевой бит, как в SHR, а значение старшего бита операнда. Пример:

al = 10100110

sar al, 3 al = 11110100 sar al, 2 al = 11111101

bl = 00100110 sar bl, 3 bl = 00000010

Циклический сдвиг

rol операнд, количество_сдвигов ; циклический сдвиг операнда влево

ror операнд, количество_сдвигов ; циклический сдвиг операнда вправо

rcl операнд, количество_сдвигов ; циклический сдвиг операнда влево через флаг переноса

rcr операнд, количество_сдвигов ; циклический сдвиг операнда вправо через флаг переноса

Циклический сдвиг напоминает смещение, выдвигаемые биты, снова вдвигаются с другой стороны: