I finally found the answer to little
conundrum. But first, a bit of a recap—the code for
__getpid (the function that acually does the system call) that
0804e380 <__getpid>: 804e380: b8 14 00 00 00 mov $0x14,%eax 804e385: cd 80 int $0x80 804e387: c3 ret
That was generated from the output from
objdump, and in
order to get that, I had to compile the program using
gcc -g -static
-o t1 t1.o t1a.o, but note the
-static bit there.
Normally, such routines are part of a shared library that aren't included in
the final executable, but by adding
-static when compiling, the
routines in the standard libraries are included in the final result. And had
I run the statically compiled version, I would have seen that the code that
calls the system supplied
__getpid() would have taken 11
minutes to run.
What bit of code was I actually testing?
(gdb) disassemble __getpid Dump of assembler code for function getpid: 0x00820730 <getpid+0>: mov %gs:0x4c,%edx 0x00820737 <getpid+7>: test %edx,%edx 0x00820739 <getpid+9>: mov %edx,%eax 0x0082073b <getpid+11>: jle 0x82073e <getpid+14> 0x0082073d <getpid+13>: ret 0x0082073e <getpid+14>: jne 0x820752 <getpid+34> 0x00820740 <getpid+16>: mov %gs:0x48,%eax 0x00820746 <getpid+22>: test %eax,%eax 0x00820748 <getpid+24>: nop 0x00820749 <getpid+25>: lea 0x0(%esi),%esi 0x00820750 <getpid+32>: jne 0x82073d <getpid+13> 0x00820752 <getpid+34>: mov $0x14,%eax 0x00820757 <getpid+39>: call *%gs:0x10 0x0082075e <getpid+46>: test %edx,%edx 0x00820760 <getpid+48>: jne 0x82073d <getpid+13> 0x00820762 <getpid+50>: mov %eax,%gs:0x48 0x00820768 <getpid+56>: ret 0x00820769 <getpid+57>: nop 0x0082076a <getpid+58>: nop 0x0082076b <getpid+59>: nop 0x0082076c <getpid+60>: nop 0x0082076d <getpid+61>: nop 0x0082076e <getpid+62>: nop 0x0082076f <getpid+63>: nop End of assembler dump.
Ah! That makes more sense then!
It's basically checking to see if the
getpid() system call
has been made, and if not, call it once, then cache the value for later
calls to this routine. You also won't notice an
int $80 here,
but that's because the shared library version of
uses a different
method of making a system call than the traditional
$80, although the older method is still supported, which is why I
suspect the static version of the system libraries use
to make system calls—to support older systems that might not support the
newer system call mechanism.