The conditional assembly

Sometimes we may want a macro instruction or a code fragment to be assembled differently depending on certain conditions. Both MASM and GAS provide this functionality too, but let's get back to FASM (as the most convenient one) and consider the following macro instruction:

macro exordd p1, p2
{
if ~p1 in <eax, ebx, ecx, edx, esi, edi, ebp, esp> &
~p2 in <eax, ebx, ecx, edx, esi, edi, ebp, esp>
push eax
mov eax, [p2]
xor [p1], eax
pop eax
else
if ~p1 in <eax, ebx, ecx, edx, esi, edi, ebp, esp>
xor [p1], p2
else if ~p2 in <eax, ebx, ecx, edx, esi, edi, ebp, esp>
xor p1, [p2]
else
xor p1, p2
end if
end if
}

It may appear a bit complicated at first, but the purpose of the macro is rather simple. We extend an XOR instruction so that we may specify two memory locations as operands, which cannot be done with the original instruction. For simplicity, we only operate on double word values.

In the beginning, we check whether both parameters are labels of memory locations and if they are, we load the value from one of them to a register and perform a XOR operation, as we would when the first operand is a memory location and the second operand is a register.

If this condition is not true, we move to the second part of the macro instruction, where we perform a XOR operation appropriately depending on whether the first operand is a memory location or the second one, or whether they are both general purpose registers.

As an example, let's take two variables named my_var1 and my_var2 containing values 0xCAFECAFE and 0x02010201, respectively, and swap them with XOR:

exordd my_var1, my_var2   ; a = a xor b
mov ebx, [my_var2]
exordd ebx, my_var1 ; b = b xor a
mov [my_var2], ebx
exordd my_var1, ebx ; a = a xor b
exordd ebx, ebx ; Reset EBX register for extra fun

Once processed, the preceding code would expand to this:

push eax                 ; exordd my_var1, my_var2
mov eax, [my_var2]
xor [my_var1], eax
pop eax
mov ebx, [my_var2]
xor ebx, [my_var1] ; exordd ebx, my_var1
mov [my_var2], ebx
xor [my_var1], ebx ; exordd [my_var1], ebx
xor ebx, ebx ; exordd ebx, ebx

As we see, the exordd macro instruction is expanded differently depending on its parameters.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset