标题实际上是我的第二个问题。 当我学习CSAPP第2版第3章时,出现了两个问题。有两个相对简单的文件。这里的第一个:为什么%esp被更改为imexpliccitly?
// code.c
int accum = 0;
int sum(int x, int y)
{
int t = x + y;
accum += t;
return t;
}
第二个:
// main.c
int main() {
return sum(1, 3);
}
我用gcc编译它们,这本书以下。为了得到一个32位程序,我添加了一个选项-m32(我的是64位的Ubuntu):
$ gcc -m32 -O1 -O prog code.c main.c
事情是好的可达这么远。但是当我使用GDB反汇编时,它真的让我困惑。我得到了以下结果相冲突以什么书说:
(gdb) disas sum
Dump of assembler code for function sum:
0x080483ed <+0>: mov 0x8(%esp),%eax
0x080483f1 <+4>: add 0x4(%esp),%eax
0x080483f5 <+8>: add %eax,0x804a020
0x080483fb <+14>: ret
End of assembler dump.
(gdb) disas main
Dump of assembler code for function main:
0x080483fc <+0>: push %ebp
0x080483fd <+1>: mov %esp,%ebp
0x080483ff <+3>: and $0xfffffff0,%esp
0x08048402 <+6>: sub $0x10,%esp
0x08048405 <+9>: movl $0x3,0x4(%esp)
0x0804840d <+17>: movl $0x1,(%esp)
0x08048414 <+24>: call 0x80483ed <sum>
0x08048419 <+29>: leave
0x0804841a <+30>: ret
End of assembler dump.
现在,这里是我的问题:
- 为什么没有任何保存的%ebp或调用函数时ESP动态%按照书中介绍的总和?或者是总和由编译器内联?
值3 & 1已经分别存储在M [%esp + 4] & M [%esp]中。在调用之和之后,没有指令改变存储在%esp中的值。但在总和中,第一条指令检索M [%esp + 8],实际上是3(我使用GDB &检查了该值来设置断点),而M [%esp + 4]存储值1。怎么来的?后来我设置断点2:
(gdb) break *0x08048414 (gdb) break sum
随后发现存储在%ESP值在这两个断点是不同的我:
Breakpoint 6, 0x08048414 in main()
(gdb) print $esp
$8 = (void *) 0xffffd020
(gdb) continue
Continuing.
Breakpoint 5, 0x080483ed in sum()
(gdb) print $esp
$9 = (void *) 0xffffd01c
为什么会出现这种情况?
'push','pop','call','ret'怎么样? – tkausl
这个代码编译成功很奇怪,因为'sum()'没有在'main.c'中定义。这是你编译的实际代码吗? –
@LiranFunaro我认为与C和坏的编译器设置它只会警告“未定义,我会假设它返回int,实际上需要这些参数” –