有短程序,代码如下:
/* init.c */
#include <syscall.h>
#include <stdio.h>
int main()
{
int pid, exitstatus;
char shell[] = "shell";
char * args[] = {shell, 0};
while(1) {
pid = fork();
if (!pid)
exec(shell, args);
while (pid != wait(&exitstatus));
printf("Shell exited with status %d; starting it back up...", exitstatus);
}
}
使用gcc编译:
gcc -nostdinc -fno-strict-aliasing -fno-builtin -Wall -gstabs -Werror -O0 -m32 -c -o init.o init.c
使用objdump检查变量pid的gstabs信息:
objdump -G init.o | grep pid
和objdump的输出:
37 LSYM 0 0 00000018 777 pid:(0,1)
当我尝试在gdb中打印pid的内存地址时:
print &pid
结果显示&amp; pid == $ ebp + 0x18,但汇编代码实际上在内存地址$ esp + 0x18处运行,汇编代码将在下面显示。
init.o的反汇编输出的一部分:
20 2c: c7 44 24 20 00 00 00 movl $0x0,0x20(%esp)
21 33: 00
22 34: e8 fc ff ff ff call 35 <main+0x35>
23 39: 89 44 24 18 mov %eax,0x18(%esp)
24 3d: 83 7c 24 18 00 cmpl $0x0,0x18(%esp)
25 42: 75 16 jne 5a <main+0x5a>
26 44: 8d 44 24 1c lea 0x1c(%esp),%eax
27 48: 89 44 24 04 mov %eax,0x4(%esp)
28 4c: 8d 44 24 26 lea 0x26(%esp),%eax
这里是第23行:
mov %eax,0x18(%esp)
我认为这个指令的作用是将fork()的结果存储到变量pid中,并且它使用地址$ esp + 0x18而不是$ ebp + 0x18,因为gdb显示,结果,我不能当我在gdb中执行print pid时(以及其他局部变量),获得所需的结果。那么,这怎么可能发生呢?