Un programa para un procesador que no tienes
Los móviles, los portátiles y los servidores usan procesadores distintos, y cada uno solo entiende sus propias instrucciones. RISC-V es un diseño abierto que cualquiera puede fabricar. Esta máquina no es RISC-V, pero un emulador le permite ejecutar un programa RISC-V igualmente.
Al terminar esta lección
Nota
Puedo seguir un programa RISC-V corto, desde su ensamblador hasta su código de salida.
Palabras clave
- Procesador: la parte del ordenador que ejecuta instrucciones.
- Instrucción: un paso pequeño que el procesador sabe dar, como sumar.
- Registro: un almacén diminuto y rápido dentro del procesador.
- Emulador: un programa que se comporta como otro procesador.
- Código de salida: el número que un programa devuelve al terminar.
- Caché: una memoria pequeña y rápida que guarda lo usado hace poco.
Para empezar: lo que ya sabes
Nota
Responde mentalmente. 1. ¿En qué convierte un compilador el código fuente? 2. ¿Qué paso une el código máquina en un solo programa? 3. ¿Qué es el ensamblador? Hoy lees ensamblador escrito por una persona.
Antes de empezar
Nota
Pulsa Iniciar el laboratorio en la barra superior de esta lección. Este laboratorio es una máquina Ubuntu entera para ti, así que tarda un poco más en arrancar que un contenedor. Cada botón Ejecutar escribe su comando en el terminal de la máquina, uno detrás de otro, en la misma sesión. Si alguno dice que la máquina aún está arrancando, espera unos segundos y púlsalo otra vez. Donde la lección dice Escribe esto, el programa espera a que le escribas: pulsa Abrir el terminal en la barra y escríbelo tú.
Un programa RISC-V, línea a línea
add.s tiene cinco instrucciones. li pone un número en un registro: 2 en a0 y 3 en a1. add los suma y guarda el resultado en a0. li a7, 93 elige la llamada al sistema de Linux que termina un programa, y ecall la hace. Linux toma el número de a0 como código de salida.
cd ~/archSe muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
cat add.sSe muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Comprueba
Consejo
Después de add a0, a0, a1, ¿qué hay en a0? Respuesta: 5, la suma de 2 y 3.
Constrúyelo y ejecútalo en un emulador
El ensamblador convierte las palabras en código máquina y el enlazador hace un programa. file dice que es para RISC-V. Este procesador no puede ejecutarlo, así que lo ejecuta qemu-riscv64, una instrucción RISC-V tras otra. No muestra nada. echo $? muestra el código de salida que dejó el programa: 5.
riscv64-linux-gnu-as add.s -o add.oSe muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
riscv64-linux-gnu-ld add.o -o addSe muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
file addSe muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
qemu-riscv64 ./addSe muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
echo $?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 echo $? muestra lo último que escribió un programa. Muestra el código de salida, un número de 0 a 255 que el programa devuelve al terminar. Cambia 2 y 3 por 200 y 100, vuelve a construirlo y la respuesta es 44: 300 no cabe, así que la cuenta vuelve a empezar.
Las instrucciones son números
objdump -d enseña el programa tal como lo ve el procesador. Cada línea da una dirección, la instrucción como número en hexadecimal y después la instrucción en palabras. Todos los números tienen ocho cifras hexadecimales, porque cada una de estas instrucciones ocupa 32 bits. ecall es 00000073.
riscv64-linux-gnu-objdump -d addSe muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Una caché hace que la memoria parezca rápida
loop.c suma dos veces una tabla de 16 millones de números. Fila a fila, el número siguiente está junto al anterior en memoria y la caché ya lo ha traído. Columna a columna, cada número está 16 KB más allá, así que el procesador espera a la memoria casi cada vez. La suma es la misma, 16777216; el tiempo no: columna a columna tarda varias veces más.
gcc -O2 -o loop loop.cSe muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
./loopSe muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Escribe esto: mira cómo avanza el procesador
En el terminal, escribe gdb ./loop. Escribe break main y después run: el programa se detiene al principio de main. Escribe info registers pc para ver el contador de programa (pc), la dirección de la siguiente instrucción. Escribe stepi para ejecutar una sola instrucción y vuelve a mirar pc: ha avanzado. Escribe quit y después y.
Comprobación final
Consejo
Responde sin mirar atrás. 1. ¿Qué es un registro? 2. ¿Qué comando ejecuta un programa RISC-V en esta máquina? 3. ¿Qué muestra echo $?? 4. ¿Por qué es más rápido fila a fila? Respuestas: un almacén diminuto y rápido dentro del procesador; qemu-riscv64; el código de salida del último comando; el número siguiente ya está en la caché.
Para el profesorado
Consejo
Esta lección se trabaja en un laboratorio de máquina virtual: cada estudiante tiene su propia máquina Ubuntu, y un botón Ejecutar escribe en su terminal y muestra lo que salió. Ideas clave: 1. Un procesador ejecuta instrucciones que trabajan con registros. 2. Un ensamblador y un enlazador convierten el ensamblador en un programa, y un emulador lo ejecuta para otro procesador. 3. La memoria cercana a la última lectura es rápida gracias a la caché. Error frecuente: tomar el código de salida por lo que el programa muestra. Material: el laboratorio y un navegador. Consejo: antes de ./loop, pide a la clase que adivine qué forma es más rápida y por cuánto. El laboratorio no tiene comprobación y no califica nada; pide una entrega propia si quieres una nota.