The explanation for the below question was perfect and told me precisely
what I was curious about. Thanks!!!
&> veej.
On Sun, 6 Feb 2005, Ian Lance Taylor wrote:
JANAPA REDDI VIJAY <Vijay.Janapareddi@xxxxxxxxxxxx> writes:
I realize that in the _fini function the call instruction is executed
to an instruction immediately following it and the value is
immediately poped into a register. I am guessing this is done to get
the instruction pointer since there is no direct way to get the ip on
x86?! I have seen this behavior even in libc.
I am unsure why this is needed to be done the way it is done? I am not
able to generalize how the call and pop combination is used by the
compiler.
Any comments on that are much appreciated. Thank you.
0x80489a0 <_fini>: push %ebp
0x80489a1 <_fini+1>: mov %esp,%ebp
0x80489a3 <_fini+3>: push %ebx
0x80489a4 <_fini+4>: push %edx
***> 0x80489a5 <_fini+5>: call 0x80489aa <_fini+10>
***> 0x80489aa <_fini+10>: pop %ebx
0x80489ab <_fini+11>: add $0x11ce,%ebx
You need to pay attention to the add, also. This sequence is used to
get the pointer to the global offset table in position independent
code. The use of the call/pop sequence gets the current PC. The
compiler, assembler and linker cooperate to ensure that the global
offset table is always at a fixed known offset from the text section.
Adding 0x11ce will turn out to be the correct offset from the pop
instruction to the global offset table. The global offset table, in
turn, is used to access all global variables and non-hidden functions.
This kind of code will appear in position independent code--that is,
code compiler with -fpic or -fPIC. It will not normally appear in
code compiled without -fpic or -fPIC. It is possible that the _fini
function is always compiled with -fPIC so that it will be suitable for
any executable or shared library.
Let us know if that does not answer your question.
Ian