指令:计算机的语言(二)
设计原则3:优秀的设计需要适当的折中
上面的格式称为R型,用于寄存器。
另一种是I型,用于带一个常数的算术指令以及加载指令。
I型字段如下:
immediate | rs1 | funct3 | rd | opcode |
12位 | 5位 | 3位 | 5位 | 7位 |
12位immediate字段为补码值,可以从-2^11到2^11-1之间的整数。当I型格式用于加载指令时,immediate字段表示一个字节偏移量,所以加载字指令可以取相对于基地址偏移量+-2048字节的任何字。
加载寄存器指令:ld x9, 32(x22),这里x22放在immediate字段中,x9放在rd字段中,还需要存储字sw的指令格式,需要两个源寄存器(用于基址和存储数据)和一个用于地址偏移量的immediate字段,S型字段如下所示:
immediate[11:5] | rs2 | rs1 | funct3 | immediate[4:0] | opcode |
7位 | 5位 | 5位 | 3位 | 5位 | 7位 |
S型格式的12位immediate字段分成了两个字段:低5位和高7位。这样设计为了rs1和rs2字段在相同位置。
指令格式通过操作码字段中的值来区分:每个格式在第一个字段opcode中被分配了一组不同的操作码值,以便硬件知道如何处理指令的其余部分。
当前涉及到的指令的值:register(寄存器)
例题:将RISC-V汇编语言翻译为机器语言reg表示0~31之间的寄存器编号,address表示12地址或常量,funct3和funct7附加的操作码字段。
假设数组A的基址存放于x10,h存放于x21,则赋值语句:
A[30] = h + A[30] + 1;
被编译成:
lw x9, 120(x10) //临时寄存器x9获取A[30]的值 add x9, x21, x9;//x9=h+A[30] addi x9, x9, 1 sw x9, 120(x10) //将结果写入A[30]
答案:为了方便起见,首先使用十进制来表示机器语言指令。
详细阐述
addi没有对应的subi指令,可以用二进制补码整数表示负数,所以addi可以用来做常数减法。
硬件/软件接口
大多数指令系统结构都是设置16或32个通用寄存器。
重点
当前的计算机构建基于两个关键原则:
1.指令由数字形式表示。
2.程序和数据一样保存在存储器中来进行读写。
存储程序,可以存储一个编辑器程序的源代码、相应的编译后的机器代码、编译程序正在使用的文本,甚至是生成机器代码的编译器。
将指令作为数据的一个结果就是程序经常以二进制数据文件的形式来发布。