问题
I have the following snippet of inline assembly:
procedure Foo;
asm
//.....
@partialloop: shr rdx,1 //every instruction is 4 bytes
lea r11,[rip + (7*4)+(@partial-@offset)]
@offset: sub r11,rdx
xor r8,r8
jmp r11 //do a partial loop
@loop64: mov [rcx],rax
@partial: mov [rcx+08H],rax
//....
end;
The compiler does not accept this syntax:
E2105 Inline assembler syntax error
Create use of offset
, ptr
or @@
does not help.
What syntax do I need to use to make this compile?
回答1:
Label addresses are relocatable and operations on them are restricted to addition and subtraction of constants.
A relocatable expression denotes a value that requires relocation at link time, while an absolute expression denotes a value that requires no such relocation. Typically, expressions that refer to labels, variables, procedures, or functions are relocatable, since the final address of these symbols is unknown at compile time.
further:
The built-in assembler allows you to carry out any operation on an absolute value, but it restricts operations on relocatable values to addition and subtraction of constants.
You can add a label address (relocatable value) to a constant but you cannot subtract a relocatable value from a constant. You also cannot add two relocatable values together.
In brief, it just cannot be done.
回答2:
It does not work, because there is no need for this construct.
The compiler disallows these constructs to prevent logical errors in code.
The following snippet is actually correct:
@partialloop: shr rdx,1 //every instruction is 4 bytes
lea r11,[rip + @partial + (7*4)] //r11= end of the loop
@offset: sub r11,rdx //step back as needed
xor r8,r8 //only do a single iteration
jmp r11 //do a partial loop
@loop64: mov [rcx],rax
@partial: mov [rcx+08H],rax
//....
end;
The expression: [rip + @partial + (4*7)]
evaluates as follows:
- rip (the IP after this instruction).
- @partial the distance between rip and that label.
- (7*4) an addition offset on top of everything else
Using a @label
in calculations always yields an offset, not an absolute value. A jmp @label
always translates into a relative jump, never an absolute jmp.
The original statement (if allowed by the compiler) would of course also be correct:
lea r11,[rip + (7*4)+(@partial-@offset)]
r11 = rip($6B74FB) + 28 + @partial($0C) - @offset(0)
But because RIP is already equal to the absolute address of @offset there is no need to include it twice.
来源:https://stackoverflow.com/questions/36311628/how-do-i-use-labels-in-address-calculations