如何在地址计算中使用标签

时间:2016-03-30 14:18:57

标签: delphi assembly x86-64

我有以下内联汇编片段:

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;

编译器不接受这种语法:

  

E2105内联汇编语法错误

使用offsetptr@@无效。

我需要使用什么语法来进行编译?

2 个答案:

答案 0 :(得分:3)

标签地址是可重定位的operations on them are restricted to addition and subtraction of constants

  

可重定位表达式表示需要在链接时重定位的值,而绝对表达式表示不需要此类重定位的值。通常,引用标签,变量,过程或函数的表达式是可重定位的,,因为这些符号的最终地址在编译时是未知的

进一步:

  

内置汇编程序允许您对绝对值执行任何操作,但它将可重定位值的操作限制为常量的加法和减法。

您可以将标签地址(可重定位值)添加到常量,但不能从 <常数>减去可重定位值。您也无法将两个可重定位的值一起添加。

简而言之,它无法完成。

答案 1 :(得分:2)

它不起作用,因为不需要这种结构 编译器不允许这些结构来防止代码中的逻辑错误。

以下代码段实际上是正确的:

@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;

表达式:[rip + @partial + (4*7)]的计算结果如下:

  • rip(此指令后的IP)。
  • @partial rip与该标签之间的距离。
  • (7 * 4)除了其他所有内容之外的附加偏移

在计算中使用@label始终会产生偏移,而不是绝对值。 jmp @label始终转换为相对跳跃,绝不是绝对的jmp。

原始陈述(如果编译器允许)当然也是正确的:

lea r11,[rip + (7*4)+(@partial-@offset)]
r11 = rip($6B74FB) + 28 + @partial($0C) - @offset(0)  

但是因为RIP已经等于@offset的绝对地址,所以不需要包含它两次。