標題實際上是我的第二個問題。 當我學習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,實際上需要這些參數」 –