计算机语言中的基本单词称为指令,一个给定计算机体系结构所包含的指令集合是指令集。
存储程序概念:多种类型的指令和数据均以数据的形式存储于存储器中的概念,存储程序型计算机即源于此。
名字 | 示例 | 注释 |
---|---|---|
32个寄存器 | $s0-$s7,$t0-$t9,$zero,$a0-$a3,$v0-$v1,$gp,$fp,$sp,$ra,$at | 寄存器用于数据的快速存取。在MIPS中,只能对存放在寄存器中的数据执行算术操作,寄存器$zero的值恒为零,寄存器$at被汇编器保留,用于处理大的常数。 |
2^30个存储字 | Memory[0]… | 存储器只能通过数据传输指令访问,MIPS使用字节编址,所以连续的字地址相差4.存储器用于保存数据结构、数组和溢出的寄存器。 |
MIPS汇编语言
类别 | 指令 | 示例 | 含义 | 注释 |
---|---|---|---|---|
算术 | 加法 | add $s1,$s2,$s3 | $s1=$s2+$s3 | 三个寄存器操作数 |
算术 | 减法 | sub $s1,$s2,$s3 | $s1=$s2-$s3 | 三个寄存器操作数 |
算术 | 立即数加法 | addi $s1,$s2,20 | $s1=$s2+20 | 用于常数数据 |
数据传输 | 取字 | lw $s1,20($s2) | $s1=Memory[$s2+20) | 将一个字从内存中取到寄存器中 |
数据传输 | 存字 | sw $s1,20($s2) | Memory[$s2+20]=$s1 | 将一个字从寄存器中取到内存中 |
计算机硬件的操作
MIPS汇编语言计述算术运算,每条MIPS算术指令只执行一个操作,并且有且仅有3个变量。两个进行运算的数和一个保存结果的数。
add a,b,c 表示将两个变量b和c相加,并将它们的和放在变量a中。
其他算术操作类似。
计算机硬件的操作数
MIPS指令的操作数必须来自寄存器,而寄存器由硬件直接构建且数量有限,是计算机硬件设计的基本元素。
字:计算机中的基本访问单位,通常是32位为一组,在MIPS体系结构中与寄存器大小相同,一个字是四个字节。
-
存储器操作数
寄存器的个数有限,但存储器可以存储数十亿个数据,因此访问大的数据结构时,数据结构存储在存储器中。MIPS指令必须包含在存储器和寄存器之间传送数据的指令。这些指令叫做数据传送指令。这就要求给出在存储器中的地址(用于在存储器空间中指明某特定数据元素位置的值)。
取数指令:将数据从存储器中复制到寄存器的数据传送。格式是在操作码后接着目标寄存器,再后面是用来访问存储器的常数和寄存器。常数和第二个寄存器中的值相加即得存储器地址。lw,如 lw $t0,8($s3). 8为偏移量,而$s3这类寄存器叫做基址寄存器。两种字节寻址:一种是使用最左边或“大端”字节的地址作为字地址,另一种是使用最右边或“小端”字节的地址作为字地址。MIPS采用大端编址。
与取数相对应的是存数指令:sw,操作码+待存储数据的寄存器+数据元素的偏移量+基址寄存器。如sw,$to,48($s3)
-
常数或立即数操作数
加立即数操作:addi 如:addi $s3,$s3,4
有符号数和无符号数
二进制位:也称二进制位,二进制状态之一,即0或1,是信息的基本组成单位。
最高有效位:在MIPS字中最左边的一位。
最低有效位:在MIPS中最右边的一位。
原码:最高位为符号为,0正1负
反码:除符号位外,取反
补码:负数初符号位外,各位取反再加1.
用补码表示的数:以32位为例
(x31×-2^31)+…+(x0× 2^0)
一个数和它按位取反的结果相加,和一定是-1.
符号扩展:将低位按原数填满,高位用符号为扩展。
二进制补码的得名规则:一个n位的数与它的相反数做无符号加法,结果是2n,因此,x的相反数-x的二进制补码表示是2n-x。
偏移表示法:最小的负数用
000...00
0
2
000...000_2
000...0002表示,最大的正数用
111..11
1
2
111..111_2
111..1112表示,0一般用
1000...0
0
2
1000...00_2
1000...002表示。即通过将数加一个偏移使其具有非负的表示形式。
计算机中指令的表示
指令在计算机中是以若干或高或低的点型号的序列表示的,并且形式上和数的表示相同。
由于指令需要用到寄存器,所以将寄存器的名字映射成数字。
在MIPS汇编语言中,$s0-$s7映射到寄存器16-23,寄存器$t0-$t7映射到寄存器8-15。
机器指令
机器指令分为若干字段,指令的布局形式叫作指令格式。所有MIPS指令都是32位长。
为了区分汇编语言,把指令的数字形式称为机器语言,这样的指令序列叫作机器码。
MIPS字段
op | rs | rt | rd | shamt | funct |
---|---|---|---|---|---|
6位 | 5位 | 5位 | 5位 | 5位 | 6位 |
各字段的含义:
op:指令的基本操作,通常称为操作码(指令中用来表示操作和格式的字段)。
rs:第一个源操作数寄存器
rt:第二个源操作数寄存器
rd:用于存放做结果的目的寄存器
shamt:位移量
funct:功能。一般称为功能码,用于指明op字段中操作的特定变式。
由于不同操作对寄存器的需求不同,因此MIPS采用了保持所有指令长度相同,但不同类型的指令采用不同的指令格式。上述指令格式为R型,而立即数和数据传送指令用的是I型。
op | rs | rt | constant or address |
---|---|---|---|
6位 | 5位 | 5位 | 16位 |
逻辑操作
逻辑操作 | MIPS指令 |
---|---|
左移 | sll |
右移 | srl |
按位与 | and,andi |
按位或 | or,ori |
按位取反 | nor |
异或 | xor |
决策指令
- beq register1, register2, L1 表示register1和register2中的数值相等,则转到标签为L1的语句执行。
- bne register1, register2 , L1 表示如果register1和register2中的数据不同,则转到标签为L1的语句执行。
这两条指令称为条件分支指令。 - MIPS指令中将无条件分支指令命名为jump,简写成j。
- 循环
借助Loop标签和j操作以及条件语句可以实现循环操作。
小于则置位:slt slt $t0, $s3, $s4 如果$s3<$s4则$t0=1,否则为0
立即数版的小于则置位:slti
sltu和sltiu用来处理无符号整数
有时为了实现switch和case语句,使用转移地址表达成目的,转移地址表是包含不同指令序列地址的表。
计算机硬件对过程的支持
过程:根据提供的参数执行一定任务的存储的子程序。
在MIPS中过程调用时寄存器的分配:
- $a0-$a3:用于传递参数的4个参数寄存器
- $v0-$v1:用于返回值的两个寄存器
- $ra:用于返回起始点的返回地址寄存器
除了分配寄存器,还有一条过程调用指令:跳转到某个地址的同时将下一条指令的地址保存在寄存器$ra中。格式为: j a l P r o c e d u r e A d d r e s s jal ProcedureAddress jalProcedureAddress
返回地址:指向调用点的连接,使过程可以返回到合适的地址,在MIPS中它存储在寄存器$ra中。jr $ra 表示无条件跳转到寄存器所指定的地址。
程序计数器:包含在程序中正被执行指令地址的寄存器。
更多寄存器
参数多于4个时,需要将寄存器换出,要用到栈这种数据结构。
而按照历史惯例,栈“增长”是按照地址从高到低的顺序进行的。这意味着将数据压栈时,栈指针值减小,出栈时,栈指针数值增。
在MIPS中,栈指针分配的寄存器是29号寄存器,$sp。
- $s0-$s7:8个保留寄存器,在过程调用中必须被保存(一但被调用,由被调用者保存和恢复)
- $t-=$t9:10个临时寄存器,在过程调用中不必被调用者保存。
嵌套过程
一个过程中有其他或自身过程的执行,需要将需要保留的寄存器存储到栈中,随着过程的返回,栈指针改变,一次取出占中的寄存器值。
-
全局指针:MIPS保留了一个寄存器$gp,指向静态数据区的保留寄存器。
-
在栈中为新数据分配空间
栈中需要存储过程的局部变量,这些变量不适用于寄存器。栈中包含过程所保存的寄存器和局部变量的片段称为过程帧或活动记录。 -
在堆中为新数据分配空间
除了动态变量是对过程局部有效,还需要在内存中为静态变量和动态数据结构提供空间。MIPS约定:栈由内存高端开始并向下增长,内存低端的第一部分是保留的,之后是MIPS机器码的第一部分,称为代码段,之上是静态数据段,静态数据之上是动态数据,类似链表这样的数据结构会在生命周期内增长或缩短,与其对应的段习惯上称为堆。
MIPS中的相关寄存器总结
名称 | 寄存器号 | 用途 | 调用时是否保存 |
---|---|---|---|
$zero | 0 | 常数0 | 不适用 |
$v0-$v1 | 2~3 | 计算结果和表达式求值 | 否 |
$a0-$a3 | 4~7 | 参数 | 否 |
$t0-$t7 | 8~15 | 临时变量 | 否 |
$s0~$s7 | 16~23 | 保存的寄存器 | 是 |
$t8-$t9 | 24~25 | 更多临时变量 | 否 |
$gp | 28 | 全局指针 | 是 |
$sp | 29 | 栈指针 | 是 |
$fp | 30 | 帧指针 | 是 |
$ra | 31 | 返回地址 | 是 |
另外,$at寄存器1被汇编器所保留。$k0~$k1寄存器26-27被操作系统所保留。
MIPS中32位立即数和寻址
32位立即数
MIPS指令集中的读取立即数高位指令lui 专门用于设置寄存器中常数的高16位,允许后续指令设置常数的低16位。lui 将立即数常量存放在寄存器的高16位。ori 立即数或,可以用来设置寄存器低位。
分支和跳转中的寻址
MIPS跳转指令采用J型指令格式,除了6位操作码外,其余都是地址字段。
2 | 100000 |
---|---|
6位 | 26位 |
条件分支指令规定了两个操作数,保留16位指定分支地址
5 | 16 | 17 | EXit |
---|---|---|---|
6位 | 5位 | 5位 | 16位 |
由于16位太小,可以在分支地址上加一个寄存器,则程序计数器=寄存器+分支地址
PC相对寻址:一种寻址方式,将PC和指令中的常数相加作为寻址结果。
MIPS寻址模式总结
- 寻址模式:根据对操作数和/或地址的使用不同加以区分的多种寻址方式中的一种
- 立即数寻址:操作数是位于指令自身中的常数。
- 寄存器寻址:操作数是寄存器。
- 基址寻址或偏移寻址:操作数在内存中,其地址是指令中基址寄存器和常数的和。
- PC相对寻址:地址是PC和指令中常数的和。
- 伪直接寻址:跳转地址由指令中26位字段和PC高位相连而成。
并行与指令:同步
数据竞争:假如来自不同线程的两个访存请求访问同一个地址,它们连续出现,并且至少其中一个是写操作,那么这两个存储访问形成数据竞争。
加锁和解锁:采用加锁可以创建一个仅允许单处理器操作的区域,叫做互区。
硬件原语:多处理器中实现同步需要一组硬件原语,提供对存储单元进行原子读和原子写的能力。
在交换原语的过程中,可以避免冲突的发生。
另外,两个同时到达的原语会进行排序,不会造成两个都成功的现象。
对于单个原子存储器操作,可以采用指令对,第二条指令返回一个表明这对指令是否原子执行的标志值。如果处理器的操作都是在这对指令之前或之后执行,这对指令就是原子的。
在MIPS中,指令对包括链接取数和条件存数。只有条件存数指令执行成功,链接取数才能返回1.