¿Te resulta más fácil leer con fondo crema, un tono de color, más contraste o un texto más grande? Elige tus colores y tu texto una sola vez, para todas las páginas.

Lección gratuita

Cómo ejecuta el procesador cada instrucción

Después de esta lección: Puedo seguir la búsqueda, la decodificación y la ejecución de una instrucción.

Lección de 50 min11 comandosLaboratorio de compiladores y arquitectura: gcc, flex, bison y RISC-V en una VM

La misma rutina, miles de millones de veces

El servidor de una tienda en línea atiende pedidos todo el día. Su procesador da unos tres mil millones de pasos por segundo, y todos siguen la misma rutina corta.

Lee la instrucción siguiente, averigua qué pide, hazla y pasa a la otra. Si sabes seguir esa rutina con una instrucción, puedes seguirla con cualquier programa.

Al final de esta lección

Nota

Puedo seguir la búsqueda, la decodificación y la ejecución de una instrucción.

Palabras clave

PalabraQué significaEjemplo
Contador de programael registro con la dirección de la siguiente instrucciónpc
Registro de instruccióndonde se guarda la instrucción recién leída
Búsquedaleer de la memoria la siguiente instrucción
Decodificaciónpartir la instrucción en sus campos
Ejecuciónhacer el trabajo que pide la instrucción
Código de operaciónel campo que dice qué tipo de instrucción esopcode

Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.

Una rutina que se repite sin parar

El contador de programa, pc, guarda la dirección de la siguiente instrucción. En la búsqueda, el procesador lee la palabra de esa dirección, la deja en el registro de instrucción y suma 4 a pc.

En la decodificación parte la palabra en campos: qué tipo de instrucción es y qué registros usa. En la ejecución hace el trabajo y escribe el resultado. Después vuelve a buscar.

Entra en la carpeta de arquitectura

Comando
cd ~/arch

Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.

Ensambla el add.s del laboratorio

Comando
riscv64-linux-gnu-as add.s -o add.o

Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.

Enlázalo

Comando
riscv64-linux-gnu-ld add.o -o add

Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.

Mira cómo el emulador busca y decodifica

Comando
qemu-riscv64 -d in_asm ./add

Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.

Lo que buscó el emulador

qemu buscó cinco palabras en la memoria y decodificó cada una. Cada línea enseña la dirección, la palabra en hexadecimal y la instrucción que salió al decodificarla.

Las direcciones suben de 4 en 4, de 0x000100b0 a 0x000100c0, porque aquí cada instrucción ocupa 4 bytes. Fíjate en que li ha desaparecido: el procesador solo ve addi a0,zero,2.

Decodificar es partir la palabra en campos

Un add son 32 bits cortados en seis campos. Los siete bits de abajo son el código de operación: 51, que significa cálculo con dos registros.

Después vienen cinco bits para rd, el registro de destino, tres bits de detalle y cinco bits para cada entrada, rs1 y rs2. El registro a0 es x10 y a1 es x11. Así que 00b50533 dice: x10 = x10 + x11.

Ejemplo resuelto: los campos de 00b50533

BitsCampoValorSignificado
31 a 25funct70000000Suma normal, no resta
24 a 20rs201011 (11)Segunda entrada: x11, a1
19 a 15rs101010 (10)Primera entrada: x10, a0
14 a 12funct3000Suma o resta
11 a 7rd01010 (10)El resultado va a x10, a0
6 a 0opcode0110011 (51)Cálculo con dos registros

Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.

La instrucción como 32 bits

Comando
python3 -c "print(format(0x00b50533, '032b'))"

Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.

Saca opcode, rd, rs1 y rs2

Comando
python3 -c "print(0x00b50533 & 127, (0x00b50533 >> 7) & 31, (0x00b50533 >> 15) & 31, (0x00b50533 >> 20) & 31)"

Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.

Se ejecuta y pc avanza

La ejecución hace el trabajo: una suma, una carga, una comparación. Casi todas las instrucciones dejan pc donde lo puso la búsqueda, 4 bytes más allá. Un salto que se toma escribe otra dirección en pc, y eso es todo lo que es un salto.

Con -d exec, qemu escribe una línea por cada instrucción que ejecuta. El segundo número entre corchetes es el pc de RISC-V.

Una línea por instrucción ejecutada

Comando
qemu-riscv64 -one-insn-per-tb -d exec,nochain ./add

Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.

Guarda la traza en un archivo

Comando
qemu-riscv64 -one-insn-per-tb -d exec,nochain -D traza.txt ./add

Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.

Cuenta las instrucciones ejecutadas

Comando
wc -l traza.txt

Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.

Un error frecuente

Advertencia

Mucha gente cree que el contador de programa cuenta cuántas instrucciones se han ejecutado. No cuenta nada. Guarda una dirección: dónde está la siguiente instrucción. En un bucle vuelve una y otra vez a las mismas direcciones.

Avanzar en el procesador de esta máquina

gdb puede parar un programa nativo y ejecutarlo de instrucción en instrucción. Si lo usas a mano, espera tus órdenes. Con -batch y una lista de órdenes, las ejecuta y termina, así que un Run puede usarlo.

El Run de abajo para en main, muestra pc, ejecuta una instrucción con stepi y vuelve a mostrar pc. En un procesador Arm la dirección avanza 4. En uno x86 las instrucciones miden de 1 a 15 bytes, así que el paso varía.

Compila el programa loop del laboratorio

Comando
gcc -O2 -o loop loop.c

Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.

Para en main y avanza una vez

Comando
gdb -batch -iex 'set debuginfod enabled off' -ex 'break main' -ex run -ex 'info registers pc' -ex stepi -ex 'info registers pc' ./loop

Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.

Para ir más lejos: contar un bucle

Escribe y construye pares.s de la lección de instrucciones, o pide la línea de printf a alguien de tu grupo. Antes de ejecutar nada, calcula cuántas instrucciones ejecuta: tres antes del bucle, tres en cada vuelta, seis vueltas y dos al final.

Después guarda su traza con -D pares.txt, cuéntala con wc -l y compara. ¿Qué direcciones salen seis veces?

Sobre este laboratorio y su código: Laboratorio de compiladores y arquitectura: gcc, flex, bison y RISC-V en una VM

¿Enseñas a una clase? Asigna este módulo a tus alumnos con guía del profesor, tareas con corrección automática y un laboratorio para cada alumno.