第三章 程式的轉換

2021-10-19 06:29:28 字數 3810 閱讀 1184

計算機硬體只能識別和理解機器語言程式,用各種組合語言或高階語言編寫的源程式都要翻譯(彙編,解釋或編譯)成以機器指令形式表示的機器語言才能在計算機中執行。

計算機的指令有微指令,機器指令和偽(巨集)指令之分。微指令是微程式級命令,屬於硬體範疇;偽指令是由若干機器指令組成的指令序列,屬於軟體範疇;機器指令介於二者之間,處於硬體和軟體的交介面。

在計算機系統的抽象層中,最重要的抽象層就是指令集體系結構(isa),他作為計算機硬體之上的抽象層,對使用硬體的軟體遮蔽了底層硬體的實現細節,將物理上的計算機硬體抽象成乙個邏輯上的虛擬計算機,稱為機器語言級虛擬機器。

isa 定義了機器語言級虛擬機器的屬性和功能特性,主要包括以下資訊:

通常,將乙個 c 語言程式轉換為可執行目標**的過程分為 4 個步驟:

預處理:在預處理截斷對帶有#開頭的語句進行處理,在源程式中插入所有用#include命令指定的檔案和用#define宣告指定的巨集。

編譯:將預處理後的源程式編譯生成相應的組合語言程式。

彙編:由匯程式設計序將組合語言轉換為可重定向的機器語言目標**檔案。

源程式檔案字尾名為.c,所包含的標頭檔案字尾名為.h;預處理過的原始檔字尾名為.i;組合語言源程式字尾名為.s;編譯後的可重定向檔案字尾名為.o,最終生成的可執行**檔案沒有字尾。

ia-32 中的定點暫存器中共有 8 個通用暫存器,2 個專用暫存器和 6 個段暫存器。

根據指令給定的資訊得到運算元或運算元位址的方式稱為定址方式。

立即定址是指指令中直接給出運算元;暫存器定址指指令中給出運算元所存放的暫存器的編號。除了立即定址和暫存器定址外,其他定址方式下的運算元都在儲存單元中,也稱為儲存器操作胡。

c 語言基本資料型別和 ia-32 運算元型別的對應關係:

c 語言宣告

intel 運算元型別

彙編指令長度字尾

儲存長度(位元組)

(unsigned) char

整數/位元組b1b

(unsigned) short

整數/字w2b

(unsigned) int

整數/雙字l4b

(unsigned) long int

整數/雙字l4b

(unsigned) long long int--

8bchar *

整數/雙字l4b

float

單精度浮點數s4b

double

雙精度浮點數l8b

long double

擴充套件精度浮點數

t10b~12b

在表中,可以看出雙字整數和雙精度浮點數的長度字尾都一樣,因為已經通過指令操作碼區分了是浮點數還是整數,所以長度字尾相同不會產生歧義。

c 語言程式的基本資料型別主要由以下幾類:

序數,位串:用來表示序號,元素個數,元素總長度,位串等的無符號數。

帶符號整數:是 c 語言應用最廣泛的基本資料型別,可宣告位 char,short,int,long 等。

浮點數:用來表示實數,可宣告為 float,double 和 long double 等。

1. 傳送指令

傳送指令用於暫存器,儲存單元或 i/o 埠之間傳送資訊。

通用資料傳送指令:

輸入輸出指令:專門用於累加器和 i/o 埠之間進行資料傳送。例如:in 指令用於將 i/o 埠內容送至累加器,out 指令將累加器內容送至 i/o 埠。

標誌傳送指令:標誌傳送指令專門用於對標誌暫存器進行操作。如 pushf 指令用於將標誌暫存器的內容壓棧,popf 指令將棧頂內容送至標誌暫存器。

2. 定點算術運算指令

加/減運算指令:add/sub。用於對給定長度的兩個位串進行相加或相減,兩個運算元中最多只有乙個是儲存器運算元,不區分是無符號數還是帶符號整數,產生的和/差送到目的位址,生成的標誌資訊送到標誌暫存器 eflags。

增/減運算指令:inc/edc。對給定長度的乙個位串加一或減一,給定的運算元既是源運算元,也是目的運算元。

取負指令:neg。用於求運算元的負數。

比較指令:cmp。用於兩個暫存器運算元的比較,用目的運算元減去源運算元,結果不送回目的運算元,即兩個運算元保持不變,只是標誌位作相應改變,因而類似於 sub 指令。

乘法指令:

若指令只給出乙個運算元,則另乙個源運算元隱含再累加器 eax 中。對於 mul 指令,若乘積高 n 位為全 0,則標誌 of 和 cf 皆為 0,否則皆為 1。對於 imul 指令,若乘積的高 n 位為全 0 或全 1,並且等於低 n 位中的最高位,則 of 和 cf 皆為 0,否則皆為 1。

除法指令:

指令中只能明顯指出除數,用累加器 eax,edx 存放被除數。若源運算元(除數)是 32 位,則 64 位被除數隱含在 edx-eax 暫存器中,計算後的商在 eax,餘數在 edx。

3. 按位運算指令

邏輯運算指令:

not:單運算元取反指令,將運算元每一位取反,然後把結果送回對應位。

and:對雙運算元進行按位邏輯「與」,主要用來實現「掩碼」操作。

or:對雙運算元進行按位邏輯「或」,常用於使目的操作時的特定位置為 1.

xor:對雙運算元進行按位邏輯「異或」,常用於判斷兩個運算元中哪些位不同或用於改變指定位的值。

test:根據兩個運算元相「與」的結果來設定標誌位,常用於檢測某種條件但不能改變源運算元的場合。

移位指令:

shl:邏輯左移,每左移一次,最高位送入 cf,並在低位補 0。

shr:邏輯右移,每右移一次,最低位送入 cf,並在低位補 0。

sal:算術左移,操作與 shl 類似,每次移位,最高位送入 cf,並在低位補 0.執行 sal 指令使,如果移位前後符號位發生變化,則 of=1,表示左移後結果溢位。這是 sal 與 shl 的不同之處。

sar:算術右移,每右移一次,運算元的最低位送入 cf,並在高位補符號位。

rol:迴圈左移,每左移一次,最高位移到最低位,並送入 cf。

ror:迴圈右移,每右移一次,最低位移到最高位,並送入 cf。

rcl:帶迴圈左移,將 cf 作為運算元的一部分迴圈左移。

rcr:帶迴圈右移,將 cf 作為運算元的一部分迴圈右移。

4. 控制轉移指令

條件轉移指令:以條件標誌或者條件標誌位的邏輯運算結果作為轉移依據。

條件設定指令:set。用來將條件標誌組合得到的條件值設定到乙個 8 位通用暫存器中。

條件傳送指令:cmov。如果符合條件就進行傳送操作,佛則什麼都不做。

呼叫指令:call。是一種無條件轉移指令,跳轉方式與 jmp 指令類似,它具有兩個功能:

將返回位址入棧(相當於 push 操作)

跳轉到指定位址處執行。

返回指令:ret。是一種無條件轉移指令,是子程式執行後返回主程式繼續執行。

5. 浮點處理指令

浮點裝入指令 fld 用來將儲存單元中的浮點數轉入到浮點暫存器棧的棧頂。

浮點儲存指令 fst 和 fstp 用來將浮點暫存器棧頂中的元素儲存到儲存單元中。

第三章 程式的控制結構 1049 晶晶赴約會

1049 晶晶赴約會 時間限制 1000 ms 記憶體限制 65536 kb 提交數 39179 通過數 25650 題目描述 晶晶的朋友貝貝約晶晶下週一起去看展覽,但晶晶每週的1 3 5有課必須上課,請幫晶晶判斷她能否接受貝貝的邀請,如果能輸出yes 如果不能則輸出no。注意yes和no都是大寫字...

讀書筆記 《csapp》第三章 程式的機器級表示

因為考研,真的無法深入做題。而且考研都快涼了啊。真是個大菜雞啊。將源 轉換為可以執行 的過程linux gcc og o p p1.c p2.c c語言擴充套件器擴充套件源 插入所有用 include命令制定的檔案,並擴充套件所有用 define宣告制定的巨集 編譯器產生兩個原始檔的彙編 分別為p1...

第三章 堆疊

1.基礎知識 堆疊可以實現很多的應用,遞迴的問題轉化成非遞迴形式,在本質上也是堆疊的問題.它是一種 filo 操作的資料結構,一般也有兩種儲存方式 陣列跟鍊錶實現形式,這裡我給出了鍊錶形式的堆疊模板,裡面包括了基本的堆疊所有的操作,還有兩個比較著名的應用例子,時間倉促,精力比較有限,關於迷宮老鼠還沒...