Using masm I have the following code which works:
This compiles fine and works as excepted. Now I do the same thing just with sub instruction instead:
This gives the error: A2101: cannot add two relocatable labels.
Then I try also with xor:
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
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
try using offset label
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
xor dword ptr , label1 XOR label2
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
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
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
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.
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.
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
Maybe not perfect but it works:
sub dword ptr , 0 - (label1 - label2)
This gives the correct values and works as expected.
// CyberHeg
0 - (label1 - label2) = (label2 - label1) :)
ups yeah :stupid:
/me goes tell himself not to code when brain is inactive
// CyberHeg
/me goes tell himself not to code when brain is inactive
// CyberHeg