3 回答
qq_笑_17
TA贡献1818条经验 获得超7个赞
不,EIP / IP无法直接访问,但在位置相关的代码中,它是一个链接时间常量,因此您可以使用附近(或远程)符号作为立即数。
mov eax, nearby_label ; in position-dependent codenearby_label:
要使位置无关的32位代码获得EIP或IP:
call _here_here: pop eax; eax now holds the PC.
在比Pentium Pro(或可能是PIII)更新的CPU上,call rel32
rel32 = 0是特殊的,不会影响返回地址预测器堆栈。因此,这在现代x86上既高效又紧凑,是clang用于32位位置无关代码的。
在旧的32位Pentium Pro CPU上,这会使调用/返回预测器堆栈失去平衡,因此更喜欢调用实际返回的函数,以避免ret
在父函数中最多15个左右的指令错误预测。(除非你不会返回,或者很少这样做无关紧要。)但是,返回地址预测器堆栈将会恢复。
get_retaddr_ppro: mov eax, [esp] ret ; keeps the return-address predictor stack balanced ; even on CPUs where call +0 isn't a no-op.
在x86-64模式下,可以使用RIP相关直接读取RIPlea
。
default rel ; NASM directive: use RIP-relative by defaultlea rax, [_here] ; RIP + 0_here:
MASM或GNU .intel_syntax
:lea rax, [rip]
AT&T语法: lea 0(%rip), %rax
翻翻过去那场雪
TA贡献2065条经验 获得超13个赞
如果您需要特定指令的地址,通常这样的方法就可以了:
thisone: mov (e)ax,thisone
(注意:在某些汇编程序中,这可能是错误的并从[thisone]中读取一个单词,但通常会有一些语法让汇编程序做正确的事情。)
如果您的代码静态加载到特定地址,汇编程序已经知道(如果您告诉它正确的起始地址)所有指令的绝对地址。动态加载的代码,例如作为任何现代操作系统上的应用程序的一部分,将通过动态链接器完成的地址重定位获得正确的地址(假设汇编器足够智能以生成重定位表,它们通常是这样)。
添加回答
举报
0/150
提交
取消