一、問候語
二、C語言程式碼分析
這段C語言程式碼共有3個函式組成。set_array函式傳入1個int型別的變數num,並建立了1個int型別臨時變數i和1個臨時int型別陣列array,裡面含有10個單位,此函式主要目的是呼叫compare函式,並將num和i傳入該函式中,得到其函式返回值並將該值賦值給array[i],共迴圈10次,由於set_array函式是void型別,故無需返回值;compare函式傳入2個int型別的變數a和b,無臨時變數建立,呼叫sub函式,並將a和b傳入該函式中,得到其函式返回值判斷是否大於等於0,如果該值大於等於0,則compare函式返回1,否則返回0;sub函式傳入2個int型別的變數a和b,無臨時變數建立,無函式呼叫,sub函式返回a-b。綜上我們可以看出這3個函式實現了為陣列array初始化的功能,i賦值從0到9,迴圈判斷num的值是否大於等於i,如果大於等於則array[i]=1,否則array[i]=0。
我們可以看出set_array函式有1個變數傳入,有臨時變數建立,有函式呼叫,無返回值;compare函式有2個變數傳入,無臨時變數建立,有函式呼叫,有返回值;sub函式有2個變數傳入,無臨時變數建立,無函式呼叫,有返回值;
三、MIPS指令集彙編知識點
1、葉子函式和非葉子函式
在一個函式中如果這個函式里面有呼叫其他的函式,則我們稱這個函式為非葉子函式,需要分配空間;在一個函式中如果這個函式里面沒有呼叫其他的函式,則我們稱這個函式為葉子函式,無需分配空間。故set_array函式和compare函式是非葉子函式,sub函式是葉子函式
2、大端模式和小端模式
小端模式下高位元組存放高地址,低位元組存放低地址;大端模式下低位元組存放高地址,高位元組存放低地址,上圖就是不同模式下存放12345678這個資料的空間不同之處,其中1234為高位元組,5678為低位元組。在MIPS指令集彙編中是採用大端模式,而在X86指令集彙編中則是採用小端模式
3、函式傳入的值在MIPS中的表示
我們用$a0到$a3來傳遞函式傳入前4個非浮點引數,從左到右,超過4個引數使用任務棧傳遞,此時從右往左依次壓棧。例如在sub函式中傳入a和b,則在MIPS彙編中$a0就是a,$a1就是b。我們在某個函式中呼叫其他函式時,需要傳參,此時也是用的$a0到$a3
4、函式返回的值在MIPS中的表示
如果是在一個函式中呼叫其他函式的返回值,則我們用$v0到$v1來表示,例如在compare函式中呼叫sub函式返回值,則這個函式返回值就是$v0。如果我們要將這個函式最終的返回值呼叫給其他函式,我們需要用$v0來儲存。無論是葉子函式還是非葉子函式結束時都需要jr $ra表示函式結束
5、函式中臨時變數和永久變數在MIPS中的表示
我們一般用$t0到t9來存放臨時變數,當呼叫子函式時,這些暫存器中的值可以被隨意更改,無需儲存。例如set_array函式中的臨時變數i就用t0來表示。我們一般用$s0到$s7存放永久變數,所謂的永久變數可以理解為全域性變數,或者函式呼叫結束後依然存在的變數
6、MIPS中開闢空間
MIPS中一個棧幀空間為32位,也就是4個位元組。棧幀中除了保留所用的儲存暫存器外,還必須保留返回地址$ra,是否儲存$fp要看具體情況。如果確保後面都用不到$fp,則可以不儲存,但為了保證$fp的值不被後面的過程覆蓋,通常應該儲存$fp的值,初始化$fp時,$fp總是指向當前棧幀前一個字或者當前棧幀第一個字的起始位置,一般是sw $ra, ?($sp)和addi $fp, $sp,?連用,其中?表示某個數值。除了陣列以外的臨時變數不用開闢空間,全域性變數需要開闢空間。葉子函式不用開闢返回地址$ra空間和幀指標$fp空間,而非葉子函式需要兩個都開闢
四、將C語言程式碼轉換成MIPS指令集彙編程式碼