github 上的 riscv 操作码与 risc-v 规范中的操作码不同
riscv-opcodes on github are different than opcodes from risc-v specs
我对 RISC-V 和汇编编码还是个新手。我想要命令的操作码/二进制值。但令我感到困惑的是,A. 不同的页面列出了不同的命令操作码,而 B.10 个命令具有相同的操作码。我怀疑对 B 的回答是不同的命令描述了相同的机制,但我仍然不确定哪些操作码是正确的。
来源:
https://github.com/riscv/riscv-opcodes/blob/20e4f0285c563e5a403bd6ba735beadbbd3c203e/opcodes
添加 rd rs1 rs2 16=0 15..10=0 9..7=0 6..2=0x0C 1..0=3
来源:
https://content.riscv.org/wp-content/uploads/2017/05/riscv-spec-v2.2.pdf
0110011 添加
那么为什么github页面说ADD的操作码是0C,十进制是12,而0110011是十进制的51?
你好。
前 7 位代表指令的操作码。 github 源代码和 pdf 都列出了相同的 ADD 操作码。 0x0C = 0000_1100 二进制。但是 github 来源说 5 位 (6..2),所以 0x0C = 01100 二进制。任何有效操作码的前 2 位始终为 11 二进制。将 01100 11 连接在一起,你会得到 0110011 二进制,51 十进制。
视觉上(按位左移然后或):
01100 11 -> ADD Opcode
----- --
0x0C 3 -> 0x0C << 2 | 3 -> 12*4 + 3 = 51
具有相同操作码的指令如 BEQ 和 BNE,均具有操作码 1100011=BRANCH,将有另一个字段进一步定义指令的功能。因此 BRANCH 操作码 1100011 将所有分支指令组合在一起。要区分 BEQ(分支相等)和 BNE(分支不相等),您必须查看 funct3 字段。 BEQ 的 funct3=000,BNE 的 funct3=001。 funct3 字段将唯一标识 BRANCH (1100011) 指令的功能:BEQ、BNE、BLT、BGE、BLTU、BGEU)。
LUI 等一些指令由操作码唯一标识,因此不需要 funct3 字段。其他指令,如带有 OP (0110011) 操作码的指令,需要一个 funct3 字段和一个 funct7 字段。注意 ADD 和 SUB 都具有相同的操作码 (OP = 0110011) 以及相同的 funct3 (000),因此 funct7 字段是微分器。 ADD 的 funct7 是 0000000 而 SUB 的 funct7 是 0100000.
RISC-V Spec 第 19 章的开头显示了一个 table,其中包含所有有效的 OPCODES 及其二进制值。记住每个 OPCODE 的前 2 位是 11,table 中省略了这一点。例如,查看 table 找到 STORE,如果我们想知道 STORE 的操作码,向左扫描到 inst[6:5] 列,你会找到 01。从 STORE 向上扫描到 inst[4:2] 行和你找到 000。由此我们可以构造存储操作码 01 000 11 -> 0100011。所有存储指令(SB、SH、SW)都将 0100011 作为其操作码。要弄清楚指令是 SB、SH 还是 SW,请查看 funct3 字段 000=SB, 001=SH, 010=SW.
我对 RISC-V 和汇编编码还是个新手。我想要命令的操作码/二进制值。但令我感到困惑的是,A. 不同的页面列出了不同的命令操作码,而 B.10 个命令具有相同的操作码。我怀疑对 B 的回答是不同的命令描述了相同的机制,但我仍然不确定哪些操作码是正确的。
来源: https://github.com/riscv/riscv-opcodes/blob/20e4f0285c563e5a403bd6ba735beadbbd3c203e/opcodes 添加 rd rs1 rs2 16=0 15..10=0 9..7=0 6..2=0x0C 1..0=3
来源: https://content.riscv.org/wp-content/uploads/2017/05/riscv-spec-v2.2.pdf 0110011 添加
那么为什么github页面说ADD的操作码是0C,十进制是12,而0110011是十进制的51?
你好。
前 7 位代表指令的操作码。 github 源代码和 pdf 都列出了相同的 ADD 操作码。 0x0C = 0000_1100 二进制。但是 github 来源说 5 位 (6..2),所以 0x0C = 01100 二进制。任何有效操作码的前 2 位始终为 11 二进制。将 01100 11 连接在一起,你会得到 0110011 二进制,51 十进制。
视觉上(按位左移然后或):
01100 11 -> ADD Opcode
----- --
0x0C 3 -> 0x0C << 2 | 3 -> 12*4 + 3 = 51
具有相同操作码的指令如 BEQ 和 BNE,均具有操作码 1100011=BRANCH,将有另一个字段进一步定义指令的功能。因此 BRANCH 操作码 1100011 将所有分支指令组合在一起。要区分 BEQ(分支相等)和 BNE(分支不相等),您必须查看 funct3 字段。 BEQ 的 funct3=000,BNE 的 funct3=001。 funct3 字段将唯一标识 BRANCH (1100011) 指令的功能:BEQ、BNE、BLT、BGE、BLTU、BGEU)。
LUI 等一些指令由操作码唯一标识,因此不需要 funct3 字段。其他指令,如带有 OP (0110011) 操作码的指令,需要一个 funct3 字段和一个 funct7 字段。注意 ADD 和 SUB 都具有相同的操作码 (OP = 0110011) 以及相同的 funct3 (000),因此 funct7 字段是微分器。 ADD 的 funct7 是 0000000 而 SUB 的 funct7 是 0100000.
RISC-V Spec 第 19 章的开头显示了一个 table,其中包含所有有效的 OPCODES 及其二进制值。记住每个 OPCODE 的前 2 位是 11,table 中省略了这一点。例如,查看 table 找到 STORE,如果我们想知道 STORE 的操作码,向左扫描到 inst[6:5] 列,你会找到 01。从 STORE 向上扫描到 inst[4:2] 行和你找到 000。由此我们可以构造存储操作码 01 000 11 -> 0100011。所有存储指令(SB、SH、SW)都将 0100011 作为其操作码。要弄清楚指令是 SB、SH 还是 SW,请查看 funct3 字段 000=SB, 001=SH, 010=SW.