Fork me on GitHub

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中查询帮助文档解决。

posted @ 2022-04-18 13:41  郭幸坤  阅读(329)  评论(0编辑  收藏  举报
1