mips编程入门
mips编程入门
参考博客:【十分钟教会你汇编】MIPS编程入门(妈妈说标题要高大上,才会有人看>_<!)
程序举例一
.data
msg: .asciiz "Hello World"
.text
.globl main
main: li $v0, 4 # syscall 4 (print_str)
la $a0, msg # argument: string
syscall
在上述程序中
数据段以.data为开始标志
.asciiz是数据类型,"Hello World"是数据内容
代码段以.text为开始标志
.globl是一个指令,它告诉汇编器这个main符号可以从当前文件外部访问
程序入口为main:标志
syscall指令和前面的li、la指令是一套组合拳
当$v0中的数字为4,执行syscall时,会打印出$a0对应地址的字符串
可以理解为:因$v0中的数字为4,所以syscall此时使用了模式4,模式4的功能是打印字符串,字符串的首地址在$a0处。
syscall还有其他运行模式,如下表所示
Service | Code in $v0对应功能的调用码 | Arguments所需参数 | Results返回值 |
---|---|---|---|
print_int打印一个整型 | $v0 = 1 | $a0 = integer to be printed将要打印的整型赋值给 $a0 | ||
print_float打印一个浮点 | $v0 = 2 | $f12 = float to be printed将要打印的浮点赋值给 $f12 | ||
print_double打印双精度 | $v0 = 3 | $f12 = double to be printed将要打印的双精度赋值给 $f12 | ||
print_string | $v0 = 4 | $a0 = address of string in memory将要打印的字符串的地址赋值给 $a0 | ||
read_int | $v0 = 5 | | integer returned in $v0将读取的整型赋值给 $v0 | ||
read_float读取浮点 | $v0 = 6 | | float returned in $v0将读取的浮点赋值给 $v0 | ||
read_double读取双精度 | $v0 = 7 | | double returned in $v0将读取的双精度赋值给 $v0 | ||
read_string读取字符串 | $v0 = 8 | $a0 = memory address of string input buffer将读取的字符串地址赋值给 $a0 $a1 = length of string buffer (n)将读取的字符串长度赋值给 $a1 | ||
sbrk应该同C中的sbrk()函数动态分配内存 | $v0 = 9 | $a0 = amount需要分配的空间大小(单位目测是字节 bytes) | address in $v0将分配好的空间首地址给 $v0 | |
exit退出 | $v0 =10 |
程序举例二
本段代码实现的功能是建立一个数组,并利用嵌套的循环逐列存放1~256。
.data
data: .word 0 : 256 # 创建一个大小为256的数组data[256]
.text
li $t0, 16 # $t0 = number of rows
li $t1, 16 # $t1 = number of columns
move $s0, $zero # $s0 = row counter
move $s1, $zero # $s1 = column counter
move $t2, $zero # $t2 = the value to be stored
loop: mult $s0, $t1 # $s2 = row * #cols (two-instruction sequence)
mflo $s2 # move multiply result from lo register to $s2
add $s2, $s2, $s1 # $s2 += col counter
sll $s2, $s2, 2 # $s2 *= 4 (shift left 2 bits) for byte offset
#以上四行是算出数据应该存入的数组中的位置
sw $t2, data($s2) # 相当于data[s2]=t2
addi $t2, $t2, 1 # increment value to be stored
addi $s0, $s0, 1 # increment row counter
li $v0,1
la $a0,0($t2)
syscall
bne $s0, $t0, loop # not at bottom of column so loop back
move $s0, $zero # reset row counter
addi $s1, $s1, 1 # increment column counter
bne $s1, $t1, loop # loop back if not at end of matrix (past the last column)
# We're finished traversing the matrix.
li $v0, 10 # system service 10 is exit
syscall # we are outta here.
t2输出结果:
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
可以发现,t2输出结果是从1输出到256。转化为c语言代码:
#include<stdio.h>
int main()
{
int t0=16;//行数
int t1=16;//列数
int data[256];//大小为256的数组
int s0=0;//行计数器
int s1=0;//列计数器
int t2=0;//存储的数据
do{
do{
s2=t1*s0+s1;
data[s2]=t2;
printf("%d",t2);
t2++;
s0++;
}while(s0!=t0);
s0=0;
s1++;
}while(s1!=t1);
}
至此,MIPS的基本入门就结束了,其余碰到的没讲过的指令可在MARS中查询帮助文档解决。