C語言過程(函式)的機器級表示

2022-07-30 07:57:17 字數 3053 閱讀 3453

乙個函式呼叫包括將資料(包括引數和返回值)和控制從**一部分傳到另一部分。還包括對函式內區域性變數分配空間,並在退出時釋放空間。  其中,轉移控制到過程 和 從過程轉移出控制——使用指令;區域性變數的分配和釋放通過 程式棧 來實現。

棧由高位址向低位址方向增長。對單個過程分配的棧稱為 棧幀。以兩個指標來界定:幀指標%ebp和棧指標%esp.棧指標是不斷變化的,所以大多數資訊基於幀指標%ebp.(注意在我的電腦上,幀指標是%esp,所以在彙編時總是由 movl 8(%esp) %eax來得到引數)。

從上圖的棧幀結構中看到,假設p呼叫q。

乙個簡單的sum呼叫函式:

int accum = 0;

int sum(int x, int y)

int main()

該函式使用gcc –o sum sum.c –o1得到可執行檔案sum。對該可執行檔案使用objdump –d sum 得到反彙編**如下:

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

next:

popl %eax

這是乙個彙編**的習慣用法,結果是把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:

.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

對caller棧幀,分配如下:

共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 ...