我有以下内联汇编片段:
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内联汇编语法错误
使用offset
,ptr
或@@
无效。
我需要使用什么语法来进行编译?
答案 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)]
的计算结果如下:
在计算中使用@label
始终会产生偏移,而不是绝对值。 jmp @label
始终转换为相对跳跃,绝不是绝对的jmp。
原始陈述(如果编译器允许)当然也是正确的:
lea r11,[rip + (7*4)+(@partial-@offset)]
r11 = rip($6B74FB) + 28 + @partial($0C) - @offset(0)
但是因为RIP已经等于@offset的绝对地址,所以不需要包含它两次。