MIPS汇编指令翻译机器码

MIPS汇编指令翻译机器码

(好不容易想明白原理,浅浅做一个记录)初学者还请多多指教。

寄存器的编号及其地址

指令翻译为机器码,寄存器的编号十分重要,rs,rt,rd的序号都根据序号而定。

$zero寄存器,到$ra寄存器,它们的编号是0~31,机器码中相应位置的编号为5’b00000~5’b11111,从大到小的顺序,计算时依次相加即可。

名字 编号 机器码编号 名字 编号 机器码编号
$s0 0 00000 t 8   t8~ t8 t9 24~25 11000~11001
$at 1 00001 k 0   k0~ k0 k1 26~27 11010~11011
v 0   v0~ v0 v1 2~3 00010~00011 $gp 28 11100
a 0   a0~ a0 a3 4~7 00100~00111 $sp 29 11101
t 0   t0~ t0 t7 8~15 01000~01111 $fp 30 11110
s 0   s0~ s0 s7 16~23 10000~10111 $ra 31 11111

机器码的格式

以R型指令为例

add $s0,$s1,$s2

op rs rt rd shamt funct
000000 01011 01101 01000 00000 100010
6bit 5bit 5bit 5bit 5bit 6bit

对于add指令,op值为00000,进一步来说,所有的R型指令的op都为0,它的特殊功能都由funct来决定。

rs,rt,rd的值都是从上一部分的表格中的来的rs,rt,rd是通用寄存器的代称,值要根据具体使用的寄存器而定,shamt表示移位数

机器码的翻译

想把所有指令的要求都背下来有些不太现实,那么会使用指令集就是一种能力

求”bne $t0,t1,next“的机器码

以一个程序中的标签为例,讲解我们如何根据程序以及指令集确定程序中某些lable的地址

MIPS汇编指令翻译机器码_第1张图片

要想知道机器码,我们首先要对应指令中的寄存器的位置,即哪一个是rs,rt,rd。从指令集中即可查得。

MIPS汇编指令翻译机器码_第2张图片

对照可得,$t0是rs,$t1是rt,对应的机器码分别是01000和01001,bne的op是000101

但是要求得机器码,我们还要知道next的值

这里有一段伪代码

if(GPR[rs]!=GPR[rt])
	PC=PC+4+sign_entend(offset||0^2)
else
	PC=PC+4	

我们首先要知道,MIPS中的指令大小是一个字,即4个字节,并且所有指令都以此存放在程序的.text部分,地址一般从0x00003000开始,要移动到下一条指令,就需要将指针向后移动一个字,即四个字节,如果要移动多个指令,就要移动相应的字节。

知道了这个之后我们就能很好理解这条指令了,功能是如果rs和rt寄存器中的数据相同就执行下一条指令,我们需要做的就是寻址,next就起到这个作用。

bne是不等时跳转,如果相等那么就是指令向后移动一条,就是PC=PC+4。 但是这个程序中下一条指令到了next的位置,在这个程序中是相当于移动了两条,多移动了一条,因为程序中基础有一次向后移动(+4)。

PC=PC+4+sign_entend(offset||0^2)

对照指令表中的sign-extend(offset||0^2)就是给offset后面加上两个0,就是乘四,多移几位,就是多移几个字,就是移动4*n个字节。

所以这个程序中我们很好看出,next使得程序多移动了一条指令,所以next是1。

最终我们可以根据指令集写出这个指令的机器码

000101 01000 01001 0000000000000001
#每四位对齐
0001 0101 0000 1001 0000 0000 0000 0001

化为16进制便是

0x15090001

参考资料:《数字设计与计算机体系结构》

你可能感兴趣的:(开发语言)