|
据说若要深入学习MIPS开发的话,《MIPS处理器设计透视》这书是必不可少的。不过若只是学习MIPS汇编,这书可能就不大合适了。汇编语言还是隐藏了CPU的很多细节,而这本书里讲的貌似就是这部分,在对汇编有所了解之后再来阅读可能要更好。
学习函数式语言的时候总是满足于看书,理解下语法语义即可,真正写的代码则少的可怜,不过确实“改变了编程的看法”,目的也算达到了。汇编就不行了,看书不够,一定得动手。所以学MIPS需要一个模拟器。pcspim应该是比较标准的了,不过感觉Mars可能要更好用(准确地说,Mars非常非常好用)。
MIPS是以优雅著称,据说即使是其竞争对手也如此认为。RISC么,32个寄存器,指令长度都一样。其中的指令大约这么三种形式:
j 1000 li $1, 10 add $1, $2,$3
差异就是各个参数的长度不同。如add指令的三个参数都只有两个位宽(0~255),每个参数表示一个寄存器。如果把指令看作函数,那参数就可以看作是有类型的。而MIPS的汇编器是很强大的(听说可以进行窥孔优化),像add $t0, $0, 10这样的指令会被汇编器翻译成addi $t0,$0,10。汇编器处理前后指令的对比可以在Mars中显示出来。
记几个helloworld吧,
求3的阶乘:
li $t0, 0 li $t1, 1 if_1: add $t0, $t0, 1 mul $t1, $t1, $t0 bne $t0, 3, if_1
在Mars下可以看到寄存器的变化,最后$t1寄存器的值是6。
mips汇编的分支(branch)指令分b系(bne,beq,bgt等等)和j系(j, jr等),差别就是b系指令的跳转都是有条件的,而且地址在参数中指明,而j系的跳转都是无条件的。j系指令的地址长度更长,寻址范围要更大,所以远程跳转都是j。
输出Helloworld:
.text .globl main main: li $v0, 4 # just the print syscall in SPIM la $a0, str syscall .data str: .asciiz "hello world"
这应该算个比较完整的汇编程序了。程序的可执行代码都是在.text段,数据在.data段。.globl指明程序的入口地址,那个:str指代的就是这段字符串的地址。字符串么,就是数组。数组不就是指针么。
其中这个syscall会与操作系统的不同而有差异。系统调用的号码由$v0指明,参数在$a系的寄存器中传递,返回值放回到$v0。这里调用的是spim实现的4号系统调用,即print string。
定义一个函数f_add,它可以将两个数相加:
.text .globl main f_add: add $v0, $a0, $a1 jr $ra main: li $a0, 1 li $a1, 2 jal f_add add $t0, $v0, $0 li $v0, 1 add $a0, $0, $t0 syscall
在使用jal指令的时候,它会把发生跳转的地址记录在$ra寄存器中。这样函数在结尾的时候就可以用jr返回原先的位置了。
使用寄存器传递参数的好处貌似就是约定了函数的调用规范,兼容性要更好。例如x86下的BASIC和C在参数传递时压栈的顺序貌似就是相反的。
寄存器编号 | 助记符 | 用法 |
$0 | zero |
永远返回0,有点象NULL设备,往里写东西都给你丢了。看似浪费,其实有用的。等会学到汇编的时候再提,呵呵! |
$1 | at | (Assembly Temporary汇编缓存)保留给汇编使用 |
$2~$3 | v0,v1 | 子函数调用的返回结果。 就是return 返回的那些东西保存的地方,这个简单。 |
$4~$7 | a0,a3 | (Arguments)子函数调用的前几个参数,就像行参保存的东西。 |
$8~$15 | t0,t7 | 暂时变量,子函数使用时不需要保存与恢复,就像子函数中使用tmp这样的临时变量。 |
$16~$23 | s0,s7 | 子函数寄存器变量。子函数写入时必须保存其值并在返回前恢复原值,从而调用函数看到的这些寄存器的值没有变化。 |
$24~$25 | t8,t9 | 同t0 t7等 。 |
$26~$27 | k0,k1 | 异常使用的。保留给中断或自陷处理程序使用,其值可能在你眼皮底下改变。 |
$28 | gp | (Global Pointer)全局指针,这个比较有意思。一些运行系统维护这个指针以便于存取static和extern 变量。 |
$29 | sp | (Stack Pointer)栈指针 |
$30 | s8/fp |
第九个寄存器变量,相当于s8; 如果需要的话作为帧指针,否则作sacved register。 |
$31 | ra | 子程序的返回地址 |
|Archiver|手机版|小黑屋|软路由
( 渝ICP备15001194号-1|
渝公网安备 50011602500124号 )
GMT+8, 2025-7-6 13:59 , Processed in 0.138034 second(s), 15 queries , Gzip On, Redis On.
Powered by Discuz! X3.5 Licensed
© 2001-2025 Discuz! Team.