MIPS彙編語言——3.C語言轉化

MIPS彙編語言——3.C語言轉化

C語言的賦值語句編譯成MIPS

f=(g+h)-(i+j)

add t0,g,hadd t1,i,jsub f,t0,t1


用存數、取數指令進行編譯

A[12]=h+A[8]

lw $t0,32($s3) #$t0=A[8]add $to,$to,$s2 #$t0=h+A[8]sw $to,48($s3)


將if-then-else編譯成條件分支指令

if(i==j) f=g+h;else f=g-h;

Tips:對於if-then-else,採用bne ...,...,else更方便

bne i,j,elseadd f,g,hj exit#很重要!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!else: sub,f,g,hexit: ...


while循環

while(save[i]==k) i+=1;

loop: sll $t1,i,2 #$t1=i*4 add $t1,$t1,$s6 #$s6是基地址 lw $t0,0($t1) #$to=save[i] bne $t0,k,Exit #若save[i]!=k則退出循環 addi i,i,1 #若save[i]==k則執行i+=1 j loop #在循環的末尾,程序跳到循環的開始,並增加exit標籤Exit:

不調用其他過程的子程序

int leaf_example(int g,int h,int i,int j{ int f; f=(g+h)-(i+j); return f;}

假設j,h,i,j對應$a0,$a1,$a2,$a3,f對應$s0

leaf example: addi $sp,$sp,-12 sw $t1,8($sp) sw $t0,4($sp) sw $s0,0($sp) add $t0,$a0,$a1 add $t1,$a2,$a3 sub $s0,$t0$t1 add $v0,$s0,$zero lw $s0,0($sp) lw $t0,4($sp) lw $t1,8($sp) addi %sp,$sp,12 jr $ra


編譯一個遞歸過程

int fact(int n){ if(n<1) return 1; else return n*fact(n-1)

參數n對應寄存器$a0,棧中保存兩個寄存器,一個是返回地址,另一個是$a0(N)

fact: addi $sp,$sp,-8 sw $ra,4($sp) sw $a0,0($sp) slti $t0,$a0,1 #i<1? beq $t0,$zero,L1 #if i>=1,goto L1 #if i<1 addi $v0,$zero,1 addi $sp,$sp,8 jr,$ra #有關jr $ra:子程序中的return之後需要jr $ra(本應lw $a0,$ra後再退出,但是這裡$a0,$ra沒有變化,因此跳過了) #if i>=1L1:addi $a0,$a0,-1 jal fact #call fact(n-1) lw $a0,0($sp) lw $ra,4($sp) addi $sp,$sp,8 #值得注意的是,return n*fact(n-1)過程裡面的fact(n-1)的值是退棧完成之後再以v0為代表而計算的 mul $v0,$v0,$a0 jr $ra #return to caller。 #子程序的return結束後要jr $ra,返回主程序

C語言,字元串複製

void strcpy(char x[],char y[]){ int i; i=0; while((x[i]=y[i])!=)//copy/test byte i+=1;}

假定數組x,y的基地址在$a0,$a1,i在$s0中

$s0要保存在棧中

當編譯器遇到一個葉過程時,它會在用完所有臨時寄存器之後,才使用那些必須保存的寄存器。

strcpy: addi $sp,$sp,-4 sw $s0,0($sp)#上面壓棧只壓入了$s0,但是程序中其實還用到了$t0,$t1等。保險起見可以把$t0,$t1都壓棧。不壓也可以。#將i初始化為0 add $s0,$zero,$zero#循環開始L1: add $t1,$a1,$s0 #把y[i]放在$t1中。 #注意,不用i*4,因為y是位元組(byte)的數組而非字(word)的數組 #為什麼y是位元組(byte)的數組? #因為y[i]是字元串,比如cal中的c、a、l分別佔4byte lbu $t2,0($t1) #$t2=y[i] #c語言幾乎都用位元組來表示字元,幾乎所有位元組的載入都用lbu #load unsigned byte,只載入了一個Byte$t3 #ASCII碼中,每個字元由7~8位二進位數字表示,因此一個字元佔1Byte add $t3,$s0,$a0 #$t3=x[i] sb $t2,$t3 #$t2=$t3,x[i]=y[i]#若字元是0(『)則退出循環 beq $t2,$zero,L2#若不是0則I++繼續循環 addi $s0,$s0,1 j L1#到了最後一個字元,退出循環。需要換原$s0和棧指針 L2: lw $s0,0($sp) addi $sp,$sp,4 jr $ra #子程序調用return結束後記得jr $ra,回到主程序

推薦閱讀:

TAG:彙編語言 | MIPS | 計算機語言 |