RISC-V · Codificación

Decodificar una instrucción RV32I

Una instrucción RISC-V es una palabra de 32 bits. Codificarla es repartir su información (qué operación, qué registros, qué constante) en campos de posición fija; decodificarla es el proceso inverso. Aquí lo haces primero a mano con un ejemplo y después con la herramienta.

Qué significa codificar una instrucción

El texto addi a0, zero, 5 es para personas. El procesador solo ve bits, así que la ISA define una plantilla: los 7 bits bajos (opcode) indican el grupo y, con él, el formato; el resto de campos dicen qué registros intervienen y qué constante (inmediato) usar. RV32I tiene seis formatos (R, I, S, B, U y J) y todos mantienen rs1, rs2 y rd en las mismas posiciones.

Ejemplo resuelto: 0x00500513

  1. Hexadecimal → binario. Cada dígito hex son 4 bits: 0x00500513 = 0000 0000 0101 0000 0000 0101 0001 0011.
  2. opcode = bits 6–0. 0010011: el grupo OP-IMM (operación con inmediato). Esto fija el formato: I.
  3. rd = bits 11–7. 01010 = 10 → x10, que en la ABI se llama a0. Es el registro destino.
  4. funct3 = bits 14–12. 000: dentro de OP-IMM, 000 es addi.
  5. rs1 = bits 19–15. 00000 = x0 (zero), el registro que siempre vale 0.
  6. imm = bits 31–20. 000000000101 = 5. El bit 31 es 0, así que el valor es positivo.
  7. Instrucción. addi a0, zero, 5: a0 = 0 + 5. Es la codificación de la pseudoinstrucción li a0, 5.

La misma descomposición, calculada por el decodificador del sitio:

0x00500513 · I-Type
CampoBitsBinarioSignificado
imm[11:0][31:20]000000000101trozo del inmediato
rs1[19:15]00000registro x0 (zero)
funct3[14:12]000selecciona la operación dentro del grupo
rd[11:7]01010registro x10 (a0)
opcode[6:0]0010011grupo OP-IMM
imm5 (0x5)inmediato reconstruido (con signo)
Instrucciónaddi a0, zero, 5

Fíjate en el orden de trabajo: primero el opcode, porque hasta saber el formato no sabes cómo leer los bits 31–7. En formato I esos bits son un inmediato de 12 bits; en formato R serían funct7 y rs2.

Decodificador

Escribe una palabra de 8 dígitos hexadecimales (con o sin 0x) o una instrucción en ensamblador de una línea. Los colores de la rejilla de bits corresponden a los campos del formato detectado.

Ejercicio guiado

Ahora una instrucción de formato R. Sigue el mismo orden: opcode, después el resto de campos. Cuando compruebes la respuesta verás la descomposición completa.

Decodifica una instrucción tipo R

Identifica los campos de 0x40B50533. Presta atención a funct7: es lo que distingue add de sub.

0x40B50533

Abrir en la herramienta

Decodifica una instrucción con inmediato negativo

Pasa 0xFFF28293 a binario y separa sus campos. Indica el formato, el opcode, los registros, funct3 y el valor decimal del inmediato.

0xFFF28293

Abrir en la herramienta

Qué hace exactamente el algoritmo

  1. Convierte los 8 dígitos hexadecimales en un entero de 32 bits.
  2. Extrae los campos con desplazamientos y máscaras: opcode = w & 0x7F, rd = (w >> 7) & 0x1F, funct3 = (w >> 12) & 0x7, rs1 = (w >> 15) & 0x1F, rs2 = (w >> 20) & 0x1F, funct7 = w >>> 25.
  3. Elige el formato según el opcode y recompone el inmediato con sus trozos. El desplazamiento aritmético a la derecha copia el bit 31, que es la extensión de signo.
  4. Comprueba funct3 y funct7. Si la combinación no corresponde a una instrucción RV32I (por ejemplo funct7 = 0000001, que usa la extensión M para mul), la palabra se marca como no reconocida en lugar de mostrar una instrucción equivocada.
  5. En modo ensamblador hace el camino inverso (campos → palabra) y después decodifica la palabra obtenida, de modo que siempre ves las dos representaciones.

Alcance y limitaciones

  • Reconoce 37 de las 40 instrucciones de RV32I: add, sub, sll, slt, sltu, xor, srl, sra, or, and; addi, slti, sltiu, xori, ori, andi, slli, srli, srai; lb, lh, lw, lbu, lhu; sb, sh, sw; beq, bne, blt, bge, bltu, bgeu; jal, jalr, lui y auipc.
  • No reconoce FENCE, ECALL ni EBREAK, ni instrucciones de extensiones (M, A, F, D, C) o de RV64.
  • El ensamblador trabaja con una sola línea y no acepta etiquetas ni pseudoinstrucciones (li, mv, j…): los saltos se escriben con el desplazamiento en bytes, por ejemplo beq t0, t1, -8.
  • En lui y auipc el inmediato se escribe y se muestra como el valor de 20 bits (lui t0, 0x12345), no desplazado 12 posiciones.
  • Los desplazamientos de saltos se muestran como números relativos al PC, no como etiquetas.

Para seguir

Referencias