從彙編角度理解C語言(一) 原

十一閒暇在學習Standford大學公開課《編程範示》的視頻以及相關一些講義,體會到世界一流大學課程的魅力。講師從編程語言入手,講到計算機體系結構、講到編譯原理、講到操作系統、講到函數式編程,在課堂上各種示例信手寫來、行雲流水,也讓聽者體會到入木三分、酣暢淋漓之感覺。

以下是我對有關體系統結構相關部分的學習筆記與總結,主要是講C語言如何翻譯成彙編(後面爲了表達方便,我以第一人稱描述) :

爲了更方便及清晰地介紹C語言翻譯成彙編代碼是什麼樣子,我們以精簡指令集(RISC)處理器爲參考,自行設計出一套虛構的處理器彙編代碼指令。

此處理器由32個寄存器,每個寄存器可存儲4個字節長度的字,即32位。我們將支持以下3種類型的指令:

“Load/Store”指令用於在寄存器和內存之間移動數據;
“ALU”指令用於對寄存器中數據的操作處理;
“Branch/Jump”用於改變下一指令執行的位置,即用於指令的跳轉。

下面一一介紹。

Load
此類型指令用於把數據裝載到寄存器中,源可以是常量,另外一個寄存器,或者是內存地址。內存地址表達方式爲Mem[address](address可以是一個常數,一個寄存器值或者寄存器加一個常數的偏移值)。
正常一般的情況下,一次存取1個字的數據(4個字節),但如果要存取的爲半字或一字節時可用表達爲"=.2"(1bytes),"=.1"(1byte)。

在下面舉例說明中爲了更精確的理解,指令上面保留了英文註釋,加精部分爲實際彙編指令。

舉例:
Load the constant 23 into register 4 
R4 = 23 
 
Copy the contents of register 2 into register 3 
R3 = R2 
 
Load char (one byte) starting at memory address 244 into register 6 
R6 =.1 Mem[244] 
 
Load R5 with the word whose memory address is in R1 
R5 = Mem[R1] 
 
Load the word that begins 8 bytes after the address in R1. 
This is known as "constant offset" mode and is about the fanciest 
addressing mode a RISC processor will support. 
R4 = Mem[R1+8] 


Store
指令與Load指令相反,用於把數據存儲到內存中去(在RISC體系結構中沒有直接把數據從內存中的一個地址轉移到另一個地址的方法,所以你只有先把數據裝載到寄存器中,然後再存儲到內存中)。

舉例:
Store the constant number 37 into the word beginning at 400 
Mem[400] = 37 
 
Store the value in R6 into the word whose address is in R1 
Mem[R1] = R6 
 
Store lower half-word from R2 into 2 bytes starting at address 1024 
Mem[1024] =.2 R2 
 
Store R7 into the word whose address is 12 more than the address in R1 
Mem[R1+12] = R7 

Store R7 into the word whose address is 12 more than the address in R1 
Mem[R1+12] = R7 

ALU
ALU(Arithmetic Logical Unit)算術邏輯運算單元,他的操作只能針對寄存器和常數(有的處理器只支持寄存器操作)。

舉例:
Add 6 to R3 and store the result in R1 
R1 = 6 + R3 
 
Subtract R3 from R2 and store the result in R1 
R1 = R2 - R3 

另外對於處理器來講,處理整數和處理浮點數是採用不同方式的,並且對於除法運算,一般都需要更多的指令週期完成。 

Branch
默認情況下,CPU會從內存的低地址至高地址依次獲取存並執行指令,而如果要想實現指令的跳轉,就要用到Branch指令了,它通過改變PC寄存器的值來改變指令下一跳的地址。

以下是跳轉指令的舉例:
Begin executing at address 344 if R1 equals 0 
BEQ R1, 0, 344  "branch if equal" 
 
Begin executing at addr 8 past current instruction if R2 less than R3 
BLT R2, R3, PC+8  "branch if less than" 

以下列舉出了所有跳轉指令:
BLT  < (第一個數小於第二個數時跳轉)
BLE  <=
BGT  >
BGE  >=  
BEQ  == 
BNE  !=

另外還有一個絕對跳轉指令Jmp,舉例說明如下:
Begin executing at address 2000 unconditionally- like a goto 
Jmp 2000 
 
Begin executing at address 12 before current instruction 
Jmp PC-12 

此外爲了我們更方便的目的,再補充兩條數據轉換指令(整型與浮點型之間的轉換),

Take bits in R3 that represent integer, convert to float, store in R2 
R2 = ItoF R3 
 
Take bits in R4, convert from float to int, and store back in same Note 
that converting in this direction loses information, the fractional 
component is truncated and lost 
R4 = FtoI R4 

至此,介紹過了所有要用到的彙編指令,下幾章就將逐步介紹各種C語句都會翻譯成怎樣的彙編代碼。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章