1>在linux下如果可執行檔依賴於其他共用庫,那麼系統就會從0x40000000開始分配到相應的空間,並將共用庫裝入到相應的空間
2>在i386中esp始終指向棧頂,而ebp固定指向函式活動記錄的一個固定位置,Ebp所指向的資料是調用該函數前ebp中的值,這樣可以保證安全返回。Ebp又叫幀指標
3>在i386中函數的調用方式:把所有或者一部分要傳遞的參數壓入棧中,也可以直接使用寄存器,然後將當前指令的下一條指令壓入棧中,跳到函數體執行。
4>i386函數函數體標準開頭:
Push ebp :(壓入old ebp)
Move ebp,esp :ebp=esp
Sub exp,xxx: 在棧上分配xxx位元組臨時空間
Push xxx :儲存xxx寄存器現場;
標準結尾:
Pop xxx :恢複xxx寄存器現場;
Mov esp,ebp esp=ebp; 恢複esp 同時回收局部變數空間,注意這是通過幀指標得到的棧幀
Pop ebp : 恢複儲存的ebp的值
Ret : 從棧中取得返回地址,並且跳轉到該位置;
5>gcc有個-fomit-frame-pointer可以取消幀指標,也就是ebp的運算,而是通過esp直接計算幀上變數的位置
無幀指標被調函數代碼
08048354 <a>:
8048354: 83 ec 10 sub $0x10,%esp
8048357: c7 44 24 08 01 00 00 movl $0x1,0x8(%esp)
804835e: 00
804835f: 8b 44 24 08 mov 0x8(%esp),%eax
8048363: 89 44 24 0c mov %eax,0xc(%esp)
8048367: 83 c4 10 add $0x10,%esp
804836a: c3 ret
有幀指標
08048354 <a>:
8048354: 55 push %ebp
8048355: 89 e5 mov %esp,%ebp
8048357: 83 ec 10 sub $0x10,%esp
804835a: c7 45 f8 01 00 00 00 movl $0x1,0xfffffff8(%ebp)
8048361: 8b 45 f8 mov 0xfffffff8(%ebp),%eax
8048364: 89 45 fc mov %eax,0xfffffffc(%ebp)
8048367: c9 leave
8048368: c3 ret
6>調用慣例(Calling Convention):函數參數的行程順序和方式:棧有從左至右,有從右至左,有的支援寄存器傳遞參數。
7>當函數返回後,esp指向指向參數下放,由調用方調整esp指標。這些都由編譯器的調用慣例決定。
8>lea eax,[eax+0x30] : eax=eax+0x30
9>關於堆的理解:程式像作業系統申請一塊適當大小的堆空間,然後程式自己管理這塊空間,而具體來講,管理著堆空間分配往往是程式的運行庫,運行庫相當於是作業系統“批發”了一塊較大的堆空間,然後給程式“零售”用, 當售完後或程式有大量記憶體需求時,再根據實際需求向作業系統“進貨”。運行空利用堆的分配演算法來處理。在Linux中一般"批發"用系統調用brk();
10>linux2.6裡面共用庫的裝載位於0xbfxxxxxx
11>大結構函數返回