Using masm I have the following code which works:

add dword ptr [esp], label1 - label2

This compiles fine and works as excepted. Now I do the same thing just with sub instruction instead:

sub dword ptr [esp], label1 + label2

This gives the error: A2101: cannot add two relocatable labels.

Then I try also with xor:

xor dword ptr [esp], label1 XOR label2

which gives the error: A2026: constant expected.

Is there a way to fix it or won't it be possible to get working? I find it strange that subtracting of labels seems to work while adding doesn't.

// CyberHeg
Posted on 2002-09-27 11:55:02 by CyberHeg
try using offset label
Posted on 2002-09-27 13:40:13 by Qages
Since the offset of your labels are not known at assembletime and can change at runtime (due to relocations) the values of label1 and label2 are not constant so only their relative difference can be calculated (with the subtract)

The only way to do this easily will be to resolve the offsets at runtime:
sub dword ptr , label1 + label2

lea eax,[label1]
lea eax,[label1 + eax]
sub dword ptr [esp],eax

xor dword ptr , label1 XOR label2

lea eax,[label1]
lea ecx,[label2]
xor eax,ecx
xor dword ptr [esp],eax
Posted on 2002-09-27 16:23:44 by huh
Thanks for the explanation.

The offset directive didn't help either but thats understandable now.

I wonder if there is a document explaining those pre-processor directives like +, -, XOR and whatever else exists which is processed at compile time and not runtime.

// CyberHeg
Posted on 2002-09-28 02:42:01 by CyberHeg
It's important to know what instructions are possible, then you know that all those calculations must take place at assemble-time because the instruction generated by the assembler is: sub , {constant}. And then the loader can relocate the constant - add the start memory address.

So, a relocatable address can be looked at as: {constant} +
is the same for the whole PE file.

Therefore, add dword ptr , label1 - label2

becomes: add dword ptr , {constant1} + - ( {constant2} + )

reduces to: add dword ptr , {constant1} - {constant2}

but: sub dword ptr , label1 + label2

becomes: sub dword ptr , {constant1} + + {constant2} +

reducing to: sub dword ptr , {constant1} + {constant2} + 2*( )

You can see now there is no way to calculate 2*( ) until run-time -- unless you assume your program is going to load at 400000h, but the assembler has no way to know this.
Posted on 2002-09-28 11:01:46 by bitRAKE
With sub instruction I solved it now.

Maybe not perfect but it works:

sub dword ptr , 0 - (label1 - label2)

This gives the correct values and works as expected.

// CyberHeg
Posted on 2002-09-28 13:43:38 by CyberHeg
0 - (label1 - label2) = (label2 - label1) :)
Posted on 2002-09-28 16:41:59 by bitRAKE
ups yeah :stupid:

/me goes tell himself not to code when brain is inactive

// CyberHeg
Posted on 2002-09-29 01:52:25 by CyberHeg