NOTEBOOK

Classification of ISA

最近在看RISC-V v1手册的中文译版,在第一章里面讲到ISA可以分为模块化的和增量化的,还举了很生动的例子来比喻两者

后来读胡伟武老师的《计算机体系结构》,里面从指令对于数据的使用方法的角度对ISA进行了分类,感觉很有意思

0. 从指令对数据的使用方法看ISA

只看文字肯定不好理解,不如直接看一个指令例子

1. C = A + B

堆栈型 累加器型 寄存器-存储器型 寄存器-寄存器型
PUSH A
PUSH B
ADD
POP C
LOAD A
ADD B
STORE C
LOAD R1, A
ADD R1, B
STORE C, R1
LOAD R1, A
LOAD R2, B
ADD R3, R1, R2
STORE C, R3

1.0 堆栈型

PUSH和POP都是对堆栈的操作,本应不该有后面的参数;PUSH A指的是把A从内存中取出来,然后压入堆栈;如果没有后面的参数A,那么压谁呢?

解释:PUSH A把A从内存中取出来,压入堆栈;PUSH B把B从内存中取出来,压入堆栈;ADD把栈顶的两个数弹出,作为加法器的输入,并把输出压回栈;POP C把栈顶的数弹出,存入内存单元C中

1.1 累加器型

指令的隐含操作数是累加器

解释:LOAD A把内存单元A存入累加器;ADD B把累加器的值与内存单元B的值相加,并把结果写回累加器;STORE C把累加器的值存入内存单元C

1.2 寄存器-存储器型

一个操作数是寄存器,一个操作数是内存地址

解释:LOAD R1, A把内存单元A的值存入寄存器R1;ADD R1, B把内存单元B的值和寄存器R1的值相加,并把结果写回R1;STORE C, R1把寄存器R1的值存入内存单元C

1.3 寄存器-寄存器型

两个操作数都是寄存器

解释:LOAD R1, A把内存单元A的值存入寄存器R1;LOAD R2, B把内存单元B的值存入寄存器R2;ADD R3, R1, R2把寄存器R1和寄存器R2做加法,把结果写入寄存器R3;STORE C, R3把寄存器R3写到内存单元C

2. 哪种结构好?

可以从代码量与内存交换的数据量两个方面来看

// 代码片段
A = B - C
D = A - C
B = D + A

注:假设,操作码占用8位,内存地址和操作数都是16位,寄存器型ISA有16个通用寄存器

  堆栈型 累加器型 寄存器-存储器型 寄存器-寄存器型
汇编代码 PUSH B
PUSH C
SUB
POP A
PUSH A
PUSH C
SUB
POP D
PUSH D
PUSH A
ADD 
POP B
LOAD C
NEG
ADD B
STORE A
LOAD C
NEG
ADD A
STORE D
ADD A
STORE B
LOAD R1, B
SUB R1, C
STORE R1, A
SUB R1, C
STORE R1, D
ADD R1, A
STORE R1, B
LOAD R1, B
LOAD R2, C
SUB R3, R1, R2
STORE R3, A
SUB R4, R3, R2
STORE R4, D
ADD R5, R4, R3
STORE R5, B
代码量 12·1+9·2=30 10·1+8·2=26 7·1+7·2+7·1=28 8·1+5·2+5·1+3·2=29
与内存交换的数据量 30+9·2=48 26+8·2=42 28+7·2=42 29+5·2=39

结论:在代码量方面,累加器型ISA更优;在与内存交换的数据量方面,寄存器-寄存器型ISA更优

补充:因为指令必须是byte的整数倍。所以LOAD R1, B中的R1要占8bit;ADD R5, R4, R3中的R5和R4占8bit,R3占8bit