MIPS初见

最近的MIPS感觉都是照猫画虎,写一篇做个笔记没准还能想明白点新东西,不知道咋用一定要经常打开指令集,这里MIPS指令集

输入输出

重要的是这个syscall指令的用法,详见MIPS汇编语言syscall指令的用法

因此在输入输出相应的类型时,要发出对应的指令,将常用的输入输出写在这备忘:

字符串

输出

.data
str: .asciiz"Hello Wolrd"

.text
la $a0,str
li $v0,4
syscall

参照上面的样例,我们就大致清楚了怎么对字符串进行输出,首先在.data区内开辟一个空间,在.text里面先需要把相应地址传送给寄存器$a0,然后通过调用$v0 = 4的指令将其输出。syscall($v0 = 4)指令:以$a0寄存器所存地址为首地址输出,直到遇上'\0'停止。

输入

.data
str: .space 1024

.text
li $t0,1
li $v0,12
syscall
sb $v0,str($t0) #存入str[1]

输入字符使用$v0 = 12,读入字符串则使用$v0 = 8。

TIPS:

  1. .asciiz.在读入字符串时会在最后加上'\0',.ascii不会加'\0',两者都以字节为单位存储数据,data段进行变量声明是在内存中紧密有序存储的,所以.asciiz之后分配的空间首地址可能无法字对齐,因此定义.ascii.asciiz时尽量写在最后面。
  2. syscall($v0 = 8)指令代表:读入一个字符串,其中$a0表示读入的首地址,$a1表示读入的字符数n,与fget类似,会在读入的字符串最后加'\n',因此实际上最多读入n-1个字符。

整数

输入使用syscall($v0 = 5),将读入的整数存在$v0中。输出使用syscall($v0 = 1),将寄存器$a0中的整数输出。

.text
    li $v0,5
    syscall
    move $a0,$v0

    li $v0,1
    syscall

条件语句

单条件

if-else判断相等

if(i == j){
    then do A;
}
else{
    then do B;
}

MIPS使用beq实现

.text:
li $v0,5
syscall
move $t0,$v0

li $v0,5
syscall
move $t1,$v0

beq $t0,$t1,A
    do B
    j end

A:
    do A

end:
    li $v0,10
    syscall

使用bne实现:

.text:
li $v0,5
syscall
move $t0,$v0

li $v0,5
syscall
move $t1,$v0

bne $t0,$t1,else
    do A
    j end

else:
    do B

end:
    li $v0,10
    syscall

与0比较的if-else

if(a <= 0){
    then do A;
}
else{
    do B;
}

MIPS实现:

.text
li $v0,5
syscall
move $t0,$v0

bgtz $t0,else
    do A
    j end

else:
    do B

end:
    li $v0,10
    syscall

非0值比较if-else

使用slt使其转化为与0比较的if-else,若条件中含=则按条件取反。

初始条件slt$t2所代表含义beq/bne
i < jslt $t2,$t0,$t10:初始条件为假 1:初始条件为真beq $t2,$0,else
i > jslt $t2,$t1,$t00:初始条件为假 1:初始条件为真beq $t2,$0,else
i <= jslt $t2,$t1,$t00:初始条件为真 1:初始条件为假beq $t2,$0,else
i >= jslt $t2,$t0,$t10:初始条件为真 1:初始条件为假beq $t2,$0,else

.text
li $v0,5
syscall
move $t0,$v0

li $v0,5
syscall
move $t1,$v0

slt $t2,$t1,$t0
bne $t2,$0,else
    do A
    j end

else:
    do B

end:
    li $v0,10
    syscall

多条件

&&

可以先判断第一个条件,若不成立直接跳转else,否则判断第二个条件。

.text
li $v0,5
syscall
move $t0,$v0

li $v0,5
syscall
move $t1,$v0

li $v0,5
syscall
move $t2,$v0

li $v0,5
syscall
move $t3,$v0

slt $t4,$t0,$t1
beq $t4,$0,beq
slt $t4,$t2,$t3
beq $t4,$0,beq
    do A
    j end

else:
    do B

end:
    li $v0,10
    syscall

||

两个条件判断后进行一次或运算再判断是否跳转

.text
li $v0,5
syscall
move $t0,$v0

li $v0,5
syscall
move $t1,$v0

li $v0,5
syscall
move $t2,$v0

li $v0,5
syscall
move $t3,$v0

slt $t4,$t0,$t1
slt $t5,$t2,$t3
or $t4,$t4,$t5
beq $t4,$1,else
    do A
    j end

else:
    do B

end:
    li $v0,10
    syscall

循环语句

.text
li $v0,5
syscall
move $s0,$v0

li $v0,5
syscall
move $s1,$v0

li $t0,0
for_loopi:
beq $t0,$s0,end_loopi
    li $t1,0
    for_loopj:
    beq $t1,$s1,end_loopj
        do loop
    addi $t1,$t1,1
    j forloopj
    end_loopj:
addi $t0,$t0,1
j for_loopi

end_loopi:
    li $v0,10
    syscall

一维数组的使用

字符数组

.data
str: .space 1024
.text
#set
li $v0,12
syscall
sb $v0,str($t0)

#get
lb $t1,str($t0)

整型数组

.data
a: .space200 #a[50]

.text
#set
sll $t1,$t0,2
sw $v0,a($t1)

#get
sll $t1,$t0,2
lb $t2,a($t1)

二维数组的使用

#使用宏
.macro getindex(%ans,%i,%j)
    sll    %ans,%i,3
    add    %ans,%ans,%j
    sll    %ans,%ans,2
.end_macro

.data
a: .space 256 #int a[8][8]

.text
#save $t0 = i,$t1 = j
li $v0,5
syscall
getindex($t2,$t0,$t1)
sw $v0,a($t2)

#get
getindex($t2,$t0,$t1)
lw $s0,a($t2)

宏定义

.macro 函数名(参数)

.end_macro

#scanf函数示例
.macro scanf(%x)
    li $v0,5
    syscall
    move %x,$v0
.end_macro

递归函数

按C语言一步一步翻译,递归的时候注意要把$ra和函数的参数压栈,如func_name(n + 1)对应:

sw $ra,0($sp) #存$ra
subi $sp,$sp,4 
sw $t0,0($sp) #存参数
subi $sp,$sp,4
addi $t1,$t0,1 #将n + 1存入$t1
move $a0,$t1 #传值
jal factorial #下一层函数运行都return(jr $31)时将回到这一层
addi $sp,$sp,4
lw $t0,0($sp) #读回这一层的参数
addi $sp,$sp,4
lw $ra,0($sp) #读回这一层的$ra

今天就复习到这里,这就去看刘老师的ppt做作业

  • 1
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值