计算机架构总结笔记(3)

上一节大概介绍了MIPS32汇编语言的书写规则,这一节将继续深入,讲解机器码的书写规范

计算机架构总结笔记(3)_第1张图片

承接前文,汇编语言就是机器码的注记符,汇编语言的每一行代码都可以改写成一串数字的形式,这就是机器码。

机器码的分类----R,I,J型指令

在之前的内容中,可以将汇编指令简要分为三种:

1. 计算类指令,比如add,sub等

2. 存取类指令 比如sw lw等

3. 跳转类指令,比如beq bnq等

具体到机器码时,分类方式又有所不同。MIPS32的指令分类依靠的是指令的书写格式,由此分成了R,I,J型三种指令

I型指令

出现常数的指令,比如sw,lw,beq,bnq等,但是不包含移位指令(Shift)

J型指令

J,Jar等无条件指令,但不包含子程序调用指令(Jr)

R型指令

其余所有都为R型指令,R型指令的特点是所有操作单元都是寄存器,例如add sub等

R型指令的书写规范

R型指令的操作域如下

 为了简化操作每个空间都有独自命名,具体如下

每个空间都视为无符号整数,五位数可以表示0-31,六位数可以表示0-63

每个空间的解释:

 opcode:这里作为R型指令的识别码,计算机首先读入opcode确定指令为R型,之后再继续进行读入(注意计算机首先从高位读入)

funct:功能代码 这里写入具体的操作类型,辅助opcode进行识别

如前文所述,R型指令最多可以写64种

rs:register source 含有第一个信息源寄存器的代码

rt:register target 在R型指令中其实是第二个register source,含有第二个信息源寄存器的代码

rd:register destination 含有目的寄存器的代码

shamt:移位指示符,用来表示移位的位数。除了移位操作以外都置零

应用实例

用加法操作举例

add   $8,$9,$10

将其分解成机器码的规范格式(注意寄存器的对应)

add   R[rd] = R[rs] + R[rt]

查表可知add指令的机器码是32,所以完整机器码如下

计算机架构总结笔记(3)_第2张图片

 也可以写成16、十进制的形式

0x 012A 4020

19,546,144

特殊的R型指令--NOP指令

NOP指令的机器码为0x00000000

汇编语言表示为

sll $0,$0,0

不难看出NOP指令并没有进行有效操作,其目的是让机器暂缓执行指令,等待一个机器周期

I型指令的书写规范

由于I型指令需要用到常数,而且常数的位数一般较多。因此五位的寄存器码是不能满足常数的需求的。由此,对R型指令的规范进行了改变,以便适应I型指令

I型指令的机器码和操作域如下

 每个空间的解释:

 opcode:和R型不同,这里的opcode直接对应I型操作指令的机器码(类似R型funct的功能)

rs:与R型相同

rt:和R型操作的rd类似,存有目的地寄存器的机器码

应用实例

以常数加法操作为例

addi  $21,$22,-50

按照机器码的书写规范如下:(注意寄存器对应)

addi  R[rt] = R[rs] + SignExtImm

查表可知addi的机器码是8,因此书写如下:

计算机架构总结笔记(3)_第3张图片

 注意这里的-50是用补码形式书写

对于过大的常数

即使经过I型指令的调整,也可能会有超标的常数出现。对于高于16位的常数的情况,解决方法如下:

Lui指令

lui reg,imm

这条指令将一个多位数imm的高16位移入寄存器,同时将寄存器的低16位置零

因此,当我们面对较大常数时,比如下面的情况

addi $t0,$t0,0xABABCDCD

实际上计算机内部进行了如下指令

lui $at,0xABAB     # upper 16bit	
ori $at,$at,0xCDCD # lower 16bit
add $t0,$t0,$at    # move

这样就把32位数载入寄存器了

I型应用举例2 存取指令

对于存取指令,例如

sw $4, -64($6)

位于后面的寄存器永远为register source,前面的永远为目的寄存器

I型应用实例3 跳转指令

对于带条件的跳转指令,比如beq和bne指令也是I型指令。beq的操作码为4,bne的操作码为5.下面将详细介绍常数在跳转指令中的表现形式

由于跳转指令主要用于循环操作,因此指令需要地址空间较少。在MIPS32架构计算机和大部分现代计算机中,指令地址通常都存放在程序计数器(PC)中。跳转操作就是以PC的地址为基准实现相对跳转

首先给出beq操作的一个应用

	Loop:   beq   $9,$0,End      
            addu  $8,$8,$10      
            addiu $9,$9,-1     
            j     Loop
    End:

这样构成了一个简单的for循环操作,也可以知道beq操作一般写为

beq $a, $b, label

的形式,常数对应的助记符就是label的位置

如前文所述,PC应用的是计数器相对寻址,也就是说,如果条件成立,指令会跳转到PC+label代表的偏移量的位置。由于immediate一共有16位,所以可以表示的地址空间是64KB(\left (-2^{15} ,2^{15} \right ))

然而,由于MIPS架构是按字寻址,一条指令就要占据4个byte,64KB的寻址空间还是稍显渺小。因此,在使用中使用偏移量的地址指代偏移的字地址,这样就将寻址空间扩展为2^{18}

对于beq指令来说,如果不进行跳转,则PC=PC+4;如果跳转,则PC=PC+4+immediate*4

以上面的循环例子来说,因为要跳过三条指令,所以immediate=3,机器码为

计算机架构总结笔记(3)_第4张图片

再看下面这条指令

beq $5 , $5, -1

偏移量为-1*4 = -4, 刚好跳转到这条指令之前,构成死循环

如果目的地过大,则可以用far指代过远的地址,应用如下:

beq $s0,$0,far           bne $s0,$0,next
# next instr    -->      j   far                   
                         next: # next instr

J型指令的书写规范

应用J型指令,可以实现在整个内存空间全部范围的跳转

然而,J型指令的指令空间为32位,其中OPCODE和上面一样都需要占据6位空间。因此,为了在4GB大小的内存空间实现寻址,需要使用特定方法对指令空间实现拓展

指令空间如下所示:

计算机架构总结笔记(3)_第5张图片

首先,和beq指令一样,可以用字地址代指字节地址。因此,26位空间就被拓展到了28位空间。对于剩下的四位,取PC计数器的高四位合并,这样就合成了32位地址

这样,指令运行后新的PC地址为:–New PC = { (PC+4)[31..28], target address, 00 }

总结

三种类型的指令空间:

计算机架构总结笔记(3)_第6张图片

beq等指令使用PC相对寻址,j使用绝对寻址

你可能感兴趣的:(学习,架构,系统架构)