2017-05-24 72 views
1

標題實際上是我的第二個問題。 當我學習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. 

現在,這裏是我的問題:

  1. 爲什麼沒有任何保存的%ebp或調用函數時ESP動態%按照書中介紹的總和?或者是總和由編譯器內聯?
  2. 值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 

爲什麼會出現這種情況?

+1

'push','pop','call','ret'怎麼樣? – tkausl

+0

這個代碼編譯成功很奇怪,因爲'sum()'沒有在'main.c'中定義。這是你編譯的實際代碼嗎? –

+0

@LiranFunaro我認爲與C和壞的編譯器設置它只會警告「未定義,我會假設它返回int,實際上需要這些參數」 –

回答

1

爲什麼在本書描述中調用函數sum時沒有任何保存%ebp或移動%esp?

您可能已經啓用了省略幀指針的選項,最有可能使用-Ox編譯器選項。可以強制GCC仍保持其與-fno-省略幀指針GCC命令行參數:

https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html#index-O

但總和的內部,所述第一指令檢索M [%ESP + 8],實際上是3,而M [%esp + 4]存儲值1.怎麼回事?

調用指令將eip寄存器推入堆棧並移動esp。你用32位模式編譯它,所以偏移量是4個字節。

相關問題