C语言 __i686.get_pc_thunk.bx 是什么?为什么我们需要这个电话?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6679846/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What is __i686.get_pc_thunk.bx? Why do we need this call?
提问by Thangaraj
When I disassemble my small function, I happened to see this call
当我反汇编我的小函数时,我碰巧看到了这个调用
call 0xf60d2f47 <__i686.get_pc_thunk.bx>.
I have no clue why I need this call in my program. Any explanation would be helpful.
我不知道为什么我的程序中需要这个调用。任何解释都会有所帮助。
回答by caf
This call is used in position-independent code on x86. It loads the position of the code into the %ebxregister, which allows global objects (which have a fixed offset from the code) to be accessed as an offset from that register.
此调用用于 x86 上的位置无关代码。它将代码的位置加载到%ebx寄存器中,这允许全局对象(与代码具有固定偏移量)作为该寄存器的偏移量被访问。
Position-independent code is code that can be loaded and executed, unmodified, at different addresses. It is important for code that will be linked into shared libraries, because these can be mapped at a different address in different processes.
位置无关代码是可以在不同地址加载和执行的代码,无需修改。对于将链接到共享库的代码很重要,因为它们可以映射到不同进程中的不同地址。
Note that an equivalent call is notrequired on x86-64, because that architecture has IP-relative addressing modes (that is, it can directly address memory locations as an offset from the location of the current instruction).
需要注意的是等效的呼叫被不需要在x86-64的,因为这架构具有IP相关的寻址模式(即,它可以直接寻址的存储器位置作为从当前指令的位置偏移)。
回答by Ritesh
Adding more to the information by example:
通过示例添加更多信息:
Suppose after you do disass on gdb inside function startup, then you will find something like this:
假设你在函数启动里面对 gdb 做 disass 之后,你会发现这样的:
0x012c17a3 <startup+7>: call 0x12b2ce7 <__i686.get_pc_thunk.bx>
0x012c17a8 <startup+12>: add ##代码##x10d6518,%ebx
Then after you have called __i686.get_pc_thunk.bx, register ebx will be populated by value 0x012c17a8, which is the address of next instruction.
然后在调用 __i686.get_pc_thunk.bx 后,寄存器 ebx 将填充值0x012c17a8,这是下一条指令的地址。
You can read the function as get_pc(program counter).
您可以将该函数读作 get_pc(program counter)。
I found this article very nice for better understanding:
我发现这篇文章非常好,可以更好地理解:
https://www.technovelty.org/linux/plt-and-got-the-key-to-code-sharing-and-dynamic-libraries.html
https://www.technovelty.org/linux/plt-and-got-the-key-to-code-sharing-and-dynamic-libraries.html

