How do I use labels in address calculations

你离开我真会死。 提交于 2021-01-29 02:05:37

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!