直接读程序计数器
19052 观看
6回复
回应 (6)
34像
不,EIP / IP无法直接访问,但在位置相关的代码中,它是一个链接时间常量,因此您可以使用附近(或远程)符号作为立即数。
mov eax, nearby_label ; in position-dependent code
nearby_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 default
lea rax, [_here] ; RIP + 0
_here:
MASM或GNU .intel_syntax
:lea rax, [rip]
AT&T语法: lea 0(%rip), %rax
27像
如果您需要特定指令的地址,通常这样的方法就可以了:
thisone:
mov (e)ax,thisone
(注意:在某些汇编程序中,这可能是错误的并从[thisone]中读取一个单词,但通常会有一些语法让汇编程序做正确的事情。)
如果您的代码静态加载到特定地址,汇编程序已经知道(如果您告诉它正确的起始地址)所有指令的绝对地址。动态加载的代码,例如作为任何现代操作系统上的应用程序的一部分,将通过动态链接器完成的地址重定位获得正确的地址(假设汇编器足够智能以生成重定位表,它们通常是这样)。
作者: TrayMan 发布者: 01.03.2009 04:1815像
8像
没有指令直接读取x86上的指令指针(EIP)。您可以使用一个内联汇编来获取当前指令的地址:
// GCC inline assembler; for MSVC, syntax is different
uint32_t eip;
__asm__ __volatile__("movl $., %0", : "=r"(eip));
该.
汇编指令获取与由汇编当前指令的地址取代。请注意,如果您在函数调用中包装上面的代码段,则每次都会获得相同的地址(在该函数内)。如果你想要一个更实用的C函数,你可以使用一些非内联汇编:
// In a C header file:
uint32_t get_eip(void);
// In a separate assembly (.S) file:
.globl _get_eip
_get_eip:
mov 0(%esp), %eax
ret
这意味着每次要获取指令指针时,由于需要额外的函数调用,效率会稍微降低。请注意,这样做不会破坏返回地址堆栈(RAS)。返回地址堆栈是处理器内部使用的单独的返回地址堆栈,以便于RET指令的分支目标预测。
每次有CALL指令时,当前EIP都会被推送到RAS,每次有RET指令时,都会弹出RAS,并将top值用作该指令的分支目标预测。如果你弄乱了RAS(比如没有将每个CALL与RET匹配,就像在Cody的解决方案中那样),你将会得到一大堆不必要的分支误预测,从而减慢你的程序速度。这种方法不会破坏RAS,因为它有一对匹配的CALL和RET指令。
作者: Adam Rosenfield 发布者: 01.03.2009 05:043像
有一种独立于架构(但依赖于gcc)的方式来访问正在使用标签作为值执行的地址:
http://gcc.gnu.org/onlinedocs/gcc/Labels-as-Values.html
void foo()
{
void *current_address = $$current_address_label;
current_address_label:
....
}
作者: Fons
发布者: 13.06.2012 11:35
0像
来自类别的问题 :
- assembly x86中“非暂时”内存访问的含义是什么?
- assembly 你如何在gcc中从C / C ++源获得汇编程序输出?
- assembly 什么是好的C反编译器?
- assembly 在主要C / C ++编译器生成的代码中注册分配规则
- assembly 解释汇编代码
- assembly 编写固件:汇编还是高级?
- x86 将3D数学转换为SSE或其他SIMD需要多少加速?
- x86 System.BadImageFormatException:无法加载文件或程序集(来自installutil.exe)
- x86 EBP帧指针寄存器的用途是什么?
- x86 直接读程序计数器
- x86 有什么好的x86汇编语言资源?
- program-counter 在C中更改程序计数器
- program-counter 从汇编代码转换为机器代码(Y86)时如何确定程序计数器?
- program-counter 有没有办法在Chrome调试器中移动程序计数器?
- program-counter 带分支的Verilog程序计数器
- program-counter mips是否具有32位地址和32位指令?