作業系統之組合語言 2

2021-07-30 05:18:16 字數 2008 閱讀 6636

現在,讓我們看看程式呼叫過程中彙編操作,乙個過程呼叫包括將資料(以過程引數和返回值的形式), 和控制從**的一部分傳遞到令一部分。另外,它還必須在進入是為過程的區域性變數分配空間,並在退出時釋放這些空間。

棧幀結構

ia32程式用程式棧來支援過程呼叫。機器用棧來傳遞過程引數,儲存返回資訊,儲存暫存器用於以後恢復,以及本地儲存,為整個過程分配的那部分棧稱為棧幀(stack frame)。最頂端的棧幀以兩個指標界定,暫存器%ebp為幀指標,而暫存器%esp為棧指標。當程式執行時,棧指標是可以移動的,因此絕大多數資訊的訪問都是相對於幀指標的。

轉移控制

call指令:其效果是將返回值位址入棧,並跳轉到被呼叫過程的起始處。返回位址是在程式中緊跟在call後面的那條指令的位址。這樣當被呼叫函式返回時,執行會從此處繼續。ret指令從棧中彈出位址,並跳轉到這個位置。例如下面**:

int accum = 0;  

intsum(int x,int y);

int main()

intsum(int x,int y)

經過反彙編後,節選處call部分的**如下圖所示:

在main函式中我們可以看到,在main函式中,位址為0x080483dc的call指令呼叫函式sum,指明了棧指標%esp和程式計數器%eip的值。我們可以看到在main函式中,位址0x080483dc的下乙個執行位址是是0x080483e1,這一點很重要。call指令的效果是將返回位址0x080483e1壓入棧中,並跳到函式sum的第一條指令,位址為0x8048394。函式sum繼續執行,直到遇到位址為0x080483a4的ret指令。這條指令從棧中彈出值0x080483e1,然後跳轉到這個位址,就在呼叫sum的call函式之後,繼續main函式的執行。

暫存器使用示例

int swap_add(int* xp,int* yp);  

intcaller()

int swap_add(int* xp,int* yp)

我們先來看看caller函式呼叫swap_add正在執行時的棧幀結構。有些指令訪問的棧位置是相對於棧指標%esp的,而另一些的訪問的棧位置是相對於基位址指標%ebp的。

我們可以看到,在呼叫swap_add之前,我們用push1指令把%ebp的資料壓入棧,然後為這個棧分配24位元組。caller的幀棧包括區域性變數arg1和arg2的儲存,其位置相對於幀指標是-4和-8。這些變數必須存在棧中,因為我們必須為他們生成位址。

在這裡我們可以看到分配給棧幀的24個位元組中,8個用於區域性變數,8個用於向swap_add傳遞引數,還有8個未使用。因為gcc堅持乙個x86程式設計指導方針,也就是乙個函式使用的所有棧空間必須是16位元組的整數倍,包括儲存%ebp值的4個位元組和返回值的4個位元組,caller一共使用了32個位元組,採用這個規則是為了保證訪問資料的嚴格對齊。

作業系統組合語言之AT T指令

計算機系統結構cpu內部 1.pc program counter 指令指標暫存器 指向下一條指令的位址 eip x86 32 或者 rip x86 64 2.暫存器與暫存器堆 registers 在處理器cpu內部以名字來訪問的快速儲存單元 3.條件狀態碼 condition codes 用於儲存...

作業系統組合語言之AT T指令

計算機系統結構cpu內部 1.pc program counter 指令指標暫存器 指向下一條指令的位址 eip x86 32 或者 rip x86 64 2.暫存器與暫存器堆 registers 在處理器cpu內部以名字來訪問的快速儲存單元 3.條件狀態碼 condition codes 用於儲存...

自製作業系統2 組合語言學習與Makefile入門

2020.10.15 第二天的任務也比較輕鬆,主要是學習組合語言知識,和學會使用makefile批處理檔案。notepad 文件 helloos3 hello os tab 4 org 0x7c00 指明程式的裝載位址 以下的記述用於標準fat12格式的軟盤 jmp entry db 0x90 中略...