Низкоуровневое программирование для Дzenствующих

Вид материалаДокументы

Содержание


III.3. Обработка выражения в MASM
Program image
III.4. Целочисленные выражения MASM
MASM не различается знаковые и беззнаковые числа (подобно тому, как это делает x86
Подобный материал:
1   ...   34   35   36   37   38   39   40   41   42

III.3. Обработка выражения в MASM


MASM обрабатывает выражения в правой и левой части в зависимости от контекста. Там, где вам необходима предварительная обработка выражений, используется оператор «%». Он заставляет препроцессор ML сначала вычислить выражение после оператора % (то есть выражение в правой части относительно %), и только потом продолжить анализ всей строки. Например, если вы хотите, чтобы при вызове макро:

num TEXTEQU <123>
FunMacro num

макропараметр был бы равен не строке «num», а значению текстового макро num, вы должны поставить оператор % перед num. Например:

FunMacro %num
;;или
FunMacro %(1+2*num)

Но и с оператором % не всё гладко.
Оказывается препроцессор ML, различает два (фактически три) вида выражений, в которых используется оператор %. Первый вид выражений – Арифметические:

Все выражения, содержащие операторы +,-,*,\ а так же сдвиговые и битовые операции

Строковые выражения:

Все выражения результат вычисления которых – строка.

Примеры:

;Арифметические выражения
%(num shl 3)
%num = 2134 shl 3 + 2*6
;Всё равно арифметическое выражение
%(num shl 3 @CatStr(num))
;Строковое выражение
%(@CatStr(num shl 3))
;Строковое выражение
%PROGRAM IMAGE

Так вот что интересно.

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

То есть:

Левая часть = Правая часть
(Вызвать все макрофункции, и заменить все строковые макропеременные) = (Вызвать все макрофункции, и заменить все строковые и целочисленные макропеременные и константы)

В строковых выражениях происходит замена только строковых макропеременных (текстовых макро) (замете, что в ML нет строковых макроконстант). Это значит что в случае:

%echo PROGRAM_IMAGE_BASE

Появится: «PROGRAM_IMAGE_BASE», а не его числовое значение.

Однако есть и третий частный случай, когда оператор % относится только к одному литералу:

%literal

В этом случае происходит полный комплекс подстановок:
  1. Вызываются макрофункции.
  2. Заменяются все макропеременные или макроконстанты.

Например:

FunMacro %literal

Значение literal будет подставлено в вызов макро, в независимости от того, какой тип имеет literal.

-= Внимание =-

Выдержка их руководства MASM:
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
temp TEXTEQU %(SIZEOF array / LENGTHOF array)
% ECHO Bytes per element: temp

Note that you cannot get the same results simply by putting the % at the beginning of the first echo line, because % expands only text macros, not numeric equates or constant expressions.
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

Следует так же отметить, что в выражениях с exitm оператор % работает точно так же, как с выражениями в TEXTEQU.

 

III.4. Целочисленные выражения MASM


Целочисленные, побитовые операции так же необходимы разработчику макроопределений. Они дают возможность скрыть обработку битовых полей, или вычисление сложных выражений. Например, как это сделано в макрофункции $$$MAKELANGID.

$$$MAKELANGID macro p:REQ,s:REQ
m$__langid = (s SHL 10) or p
EXITM
endm

Вы всегда должны помнить, что препроцессор MASM не различается знаковые и беззнаковые числа (подобно тому, как это делает x86), и значение числа не может выходить за диапазон dword. Препроцессор MASM не выдаёт предупреждений при переполнении. Следующий пример демонстрирует такое поведение:

myint = 0ffffffffh

myint = myint + 1 ;; myint = 0

%echo @CatStr(%myint)


=================================


OUT:

0


;; Ещё один пример с умножением:


myint = 0ffffffffh

;;

;; 0ffffffffh * 2 = (dword)1FFFFFFFEh = 4294967294

myint = myint * 2

%echo @CatStr(%myint)

=================================

OUT:

4294967294

В следующей статье мы поговорим про то, как работать с 64-bits макропеременными, используя данный факт.

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

Оператор

Пример

Описание

AND

res = op1 AND op2

Операция логического «И» над каждым битом операндов op1 и op2.

OR

res = op1 OR op2

Операция логического «ИЛИ» над каждым битом операндов op1, op2

NOT

res = NOT op1

Операция логического «НЕ» над каждым битом операнда op1

XOR

res = op1 XOR op2

Операция XOR между операндами op1, op2

SHL

res  = op1 SHL count

Выполняет побитовый сдвиг влево (наподобие команды x86 shl) операнда op1, на количество бит, указанное в операнде count.

SHR

res  = op1 SHL count

Выполняет побитовый сдвиг вправо операнда op1, на число бит, указанное в операнде count.

+,-,*,/

 

Основные математические операции

MOD

res = op1 MOD op2

Возвращает остаток от деления операнда op1 на операнд op2

[]

res = op1[op2]

Операция: «Смещение». Выполняет сложение операндов op1 и op2