乙個函式呼叫包括將資料(包括引數和返回值)和控制從**一部分傳到另一部分。還包括對函式內區域性變數分配空間,並在退出時釋放空間。 其中,轉移控制到過程 和 從過程轉移出控制——使用指令;區域性變數的分配和釋放通過 程式棧 來實現。
棧由高位址向低位址方向增長。對單個過程分配的棧稱為 棧幀。以兩個指標來界定:幀指標%ebp和棧指標%esp.棧指標是不斷變化的,所以大多數資訊基於幀指標%ebp.(注意在我的電腦上,幀指標是%esp,所以在彙編時總是由 movl 8(%esp) %eax來得到引數)。
從上圖的棧幀結構中看到,假設p呼叫q。
乙個簡單的sum呼叫函式:
int accum = 0;該函式使用gcc –o sum sum.c –o1得到可執行檔案sum。對該可執行檔案使用objdump –d sum 得到反彙編**如下:int sum(int x, int y)
int main()
080483b4 :【彙編的乙個習慣技巧】80483b4: 8b 44 24 08 mov 0x8(%esp),%eax
80483b8: 03 44 24 04 add 0x4(%esp),%eax
80483bc: 01 05 18 a0 04 08 add %eax,0x804a018
80483c2: c3 ret
080483c3 :
80483c3: 83 ec 08 sub $0x8,%esp
80483c6: c7 44 24 04 03 00 00 movl $0x3,0x4(%esp)
80483cd: 00
80483ce: c7 04 24 01 00 00 00 movl $0x1,(%esp)
80483d5: e8 da ff ff ff call 80483b4 80483da: 83 c4 08 add $0x8,%esp
80483dd: c3 ret
對下面的乙個**片段:
call next這是乙個彙編**的習慣用法,結果是把popl指令位址放入%eax中——將程式計數器值放入整數暫存器的唯一方法。next:
popl %eax
這不是乙個過程呼叫,因為跳轉的結果與指令順序相同:
執行call next前,pc設為popl指令的位址(pc始終設定為下條指令位址);
執行call next後,%esp被設定為popl指令位址(因為它是呼叫者的返回位址);程式同時也跳轉到了popl指令,(此時幀指標和棧指標是重合的,棧指標%esp只有在宣告新區域性變數時會增大,所以%esp還儲存的是popl的位址),根據: %eax = m[r[%esp]],所以popl指令位址放入了%eax中
暫存器組是被所有過程共享的資源,但同一時刻只有乙個過程啟用,所以需要保證被呼叫者不會影響呼叫者在暫存器中的值。
將%eax, %edx, %ecx作為呼叫者儲存暫存器,被呼叫者可以覆蓋這些暫存器;
將%ebx, %ebi, %edi作為被呼叫者儲存暫存器,需要在過程開始前pushl,在過程結束後popl到暫存器。
int swap_add(int *xp, int *yp)彙編**為:int caller()
swap_add:對caller棧幀,分配如下:.lfb0:
.cfi_startproc
pushl %ebx
.cfi_def_cfa_offset 8
.cfi_offset 3, -8
movl 8(%esp), %ebx
movl 12(%esp), %ecx
movl (%ebx), %edx
movl (%ecx), %eax
movl %eax, (%ebx)
movl %edx, (%ecx)
addl %edx, %eax
popl %ebx
.cfi_def_cfa_offset 4
.cfi_restore 3
ret.cfi_endproc
caller:
.lfb1:
.cfi_startproc
subl $24, %esp
.cfi_def_cfa_offset 28
movl $534, 16(%esp)
movl $1057, 20(%esp)
leal 20(%esp), %eax
movl %eax, 4(%esp)
leal 16(%esp), %eax
movl %eax, (%esp)
call swap_add
addl $24, %esp
.cfi_def_cfa_offset 4
ret.cfi_endproc
共32個位元組:
+24 (乙個空閒位,在書上該位用來存放了「儲存的%ebp")
+20 arg2
+16 arg1
+8+4 &arg2
&arg1(%esp儲存該位址)
返回位址(from ret)
&arg1
返回位址(call呼叫會儲存該位址)
initial %ebx(%esp儲存該位址,由於沒有」儲存的%ebp「,所以該位置就類似於書上的%ebp位置。)
pushl %ebp
movl %esp %ebp (這一步結束,就將%ebp指向了」儲存的%ebp「的位址。)
在結束部分,要恢復%ebp的值:
popl %ebp
ret棧規則的關鍵是:每次函式呼叫它都會儲存自己的私有資訊(包括返回位址、棧指標%ebp、被呼叫者儲存暫存器值%ebp等,如果需要還有其他區域性變數)。
資料的機器級表示與處理 C語言的運算
高階語言程式中涉及的運算 以c語言為例 整數算術運算 浮點數算術運算 按位 邏輯 移位 位擴充套件和位截斷 指令集中涉及到的運算 涉及到的定點數運算 算術運算 帶符號整數運算 取負 符號擴充套件 加 減 乘 除 算術移位 無符號整數運算 0擴充套件 加 減 乘 除 邏輯運算 邏輯操作 與 或 非 移...
程式的機器級表示
三種 立即數 常數值,在att格式的彙編 中,書寫格式是 整數,如 123 0x12 暫存器 如 32位的 eax 16位的 ax 8位的 al 儲存器引用 mov 同等傳送,即倆者的大小一致 如 movb byte,movew word,movel longword dw movs movz 不同...
程式的機器級表示
32位和64位 instruction system architecture 程式計數器pc eip 整數暫存器 8個每個32位 有的用來記錄狀態,有的用來儲存臨時資料,區域性變數,返回值 3.條件碼暫存器 指標都是雙字 char short long 其他4位元組 movb movw movl ...