目录
指令集:一个给定的计算机体系结构所包含的指令集合。
常见的指令集有MIPS、Inter X86、ARMv7和ARMv8。本书选择MIPS指令集来介绍。
存储程序概念:多种类型的指令和数据均以数字的形式存储于存储器中的概念。
下面是MIPS汇编语言指令:
名字 | 示例 | 注释 |
32个寄存器 | $s0 - $s7,$t0 - $t9, $a0 - $a3,$v0,$v1, $gp,$fp,$sp, $ra,$at,$zero |
寄存器用于数据的快速存取。 在MIPS中,只能对放在寄存器中的数据执行算数操作。 寄存器$zero的值恒为0。 寄存器$at被汇编语器保留,用于处理大的常数。 |
Memory[0],Memory[4],... ,Memory[4294967292] | 存储器只能通过数据传输指令访问。 MIPS使用字节编址,所以连续的字地址相差4。 存储器用于保存数据结构、数组和溢出的寄存器。 |
*注:寄存器$s0,...,$s7常用来表示变量寄存器;寄存器$t0,...,$t9常用来表示临时寄存器。
类别 | 指令 | 示例 | 含义 | 注释 |
算术 | 加法 | 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[$2 + 20] | 内存-->寄存器(一个字) |
存字 | sw $s1, 20 ($s2) | Memory[$s2+20] = $1 | 寄存器-->内存(一个字) | |
取半字 | lh $s1, 20 ($s2) | $s1 = Memory[$2 + 20] | 内存-->寄存器(半字) | |
取无符号半字 | lhu $s1, 20 ($s2) | $s1 = Memory[$2 + 20] | 内存-->寄存器(半字) | |
存半字 | sh $s1, 20 ($s2) | Memory[$s2+20] = $1 | 寄存器-->内存(半字) | |
取字节 | lb $s1, 20 ($s2) | $s1 = Memory[$2 + 20] | 内存-->寄存器(一个字节) | |
取无符号字节 | lbu $s1, 20 ($s2) | $s1 = Memory[$2 + 20] | 内存-->寄存器(一个字节) | |
存字节 | sb $s1, 20 ($s2) | Memory[$s2+20] = $1 | 寄存器-->内存(一个字节) | |
取链接字 | ll $s1, 20 ($s2) | $s1 = Memory[$2 + 20] | 取字作为原子交换的前半部分 | |
存条件字 | sc $s1, 20 ($s2) | Memory[$s2+20] = $1; $s1 = 0 or 1 |
存字作为原子交换的后半部分 | |
取立即数的高位 | lui $s1, 20 | $s1 = 20* |
取立即数并放在高16位 | |
逻辑 | 与 | and $s1, $s2, $s3 | $s1 = $s2 & $s3 | 三个寄存器操作数 |
或 | or $s1, $s2, $s3 | $s1 = $s2 | $s3 | 三个寄存器操作数 | |
或非 | nor $s1, $s2, $s3 | $s1 = ~($s2 | $s3) | 三个寄存器操作数 | |
立即数与 | andi $s1, $s2, 20 | $s1 = $s2 & 20 | 和常数按位与 | |
立即数或 | ori $s1, $s2, 20 | $s1 = $s2 | 20 | 和常数按位或 | |
逻辑左移 | sll $s1, $s2, 10 | $s1 = $s2 << 10 | 常数左移相应位 | |
逻辑右移 | srl $s1, $s2, 10 | $s1 = $s2 >> 10 | 常数右移相应位 | |
条件分支 | 等于时跳转 | beq $s1, $s2, 25 | if( $s1 == $s2 ) go to PC + 4 +100 |
相等检测; 和PC相关的跳转 |
不等于时跳转 | bne $s1, $s2, 25 | if( $s1 != $s2 ) go to PC + 4 +100 |
不相等检测; 和PC相关的跳转 |
|
小于时置位 | slt $s1, $s2, $s3 | if( $s2 < $s3 ) $s1 = 1; else $s1 = 0 |
比较是否小于 |
|
无符号数比较 小于时置位 |
sltu $s1, $s2, $s3 | if( $s2 < $s3 ) $s1 = 1; else $s1 = 0 |
比较是否小于无符号数 | |
无符号数比较 小于立即数时置位 |
slti $s1, $s2, 20 | if( $s2 < 20 ) $s1 = 1; else $s1 = 0 |
比较是否小于常数 | |
无符号数比较 小于无符号立即数时置位 |
sltiu $s1, $s2, 20 | if( $s2 < 20 ) $s1 = 1; else $s1 = 0 |
比较是否小于无符号常数 | |
无条件跳转 | 跳转 | j 2500 | go to 10000 | 跳转至目标地址 |
跳转至寄存器所指位置 | jr $ra | go to $ra | 用于switch语句, 以及过程调用 |
|
跳转并链接 | jal 2500 | $ra = PC + 4; go to 10000 |
用于过程调用 |
*注意:三个寄存器操作数:有且只有3个操作数,且操作数只能从32个32bit寄存器中选取。
硬件设计三条基本原则:
1、简单源于规整(只有三个操作数)
2、越小越好(只有32个寄存器)
3、优秀的设计需要适宜的折中方案(R型-->I型,见2.3节)
2.1 计算机硬件的操作数
寄存器大小:MIPS体系结构中寄存器大小为32bit。
字:计算机中基本的访问单位,32bit。
MIPS体系中共有32个寄存器,是由于设计原则2:越小越好和受指令格式位数的限制。
*注意:MIPS也有64bit的版本MIPS-64,其具有32个64bit的寄存器。此处32bit指的是MIPS-32。
2.1.1 存储器操作数
地址:用于在存储器空间中指明某特定数据元素的位置的值。
数据传送指令:存储器和寄存器之间传送数据的指令。
数据传送指令又分为取数指令和存数指令。
取数(load)指令:存储器-->寄存器,
存数(store)指令:寄存器-->存储器,
按字节编址:存储器被划分成若干个单元,每个单元容量为1个字节(8bit),从0开始编号(地址)。MIPS是按字节编址的。