Saltar a contenido

Práctica 1.1.1: Relación software-hardware y comparativa C vs ensamblador

1.1.1. Relación software-hardware y comparativa C vs ensamblador

En esta práctica observarás dos niveles distintos de interacción entre un programa y el hardware. En la parte A simularás un circuito con Arduino para relacionar el código con una entrada (el botón) y una salida (el LED). En la parte B ejecutarás una suma en el simulador LC-3 y la compararás con el código C equivalente. No se trata de ejecutar C dentro del simulador LC-3: son entornos y arquitecturas distintos.

1. Objetivos

  • Explicar cómo colaboran el programa, el procesador, la memoria y los periféricos durante una ejecución.
  • Observar una entrada y una salida en una simulación de microcontrolador.
  • Seguir instrucciones y datos de un programa LC-3, distinguiendo ensamblador, registros y memoria.
  • Comparar el nivel de abstracción y el detalle visible en C y en ensamblador, sin confundir sus herramientas de ejecución.

2. Relación con RA y criterios de evaluación

Código Descripción
RA 1 Reconoce los elementos y herramientas que intervienen en el desarrollo de un programa informático, analizando sus características y las fases en las que actúan hasta llegar a su puesta en funcionamiento.
CE 1.a Se ha reconocido la relación de los programas con los componentes del sistema informático: memoria, procesador, periféricos, entre otros.
CE 1.e Se han clasificado los lenguajes de programación, identificando sus características.

El criterio principal es CE 1.a. Se trabaja CE 1.e al comparar un lenguaje de alto nivel (C) con ensamblador, de menor nivel y ligado a una arquitectura.

3. Requisitos y recursos

  • Un navegador actualizado y conexión a Internet.
  • Para la parte A, acceso al editor de circuitos de Tinkercad. La disponibilidad de la simulación compartida puede depender de la cuenta y de los permisos del recurso; si pide iniciar sesión o no permite editar, abre un circuito nuevo y replica el montaje. No compartas datos personales ni publiques el proyecto sin autorización.
  • Para la parte B, uno de los simuladores LC-3 indicados abajo. El código se escribe y se ensambla en el simulador; no necesitas instalar un compilador de C.
  • Para la ampliación sobre CPU, el simulador LMC de Peter Higginson.
  • Conceptos previos: diferencia básica entre entrada y salida, y entre código fuente y ejecución. Consulta 1.1 Relación entre software y hardware y 1.5 Lenguajes de programación si necesitas repasarlos.

Recursos en línea

4. Pasos a seguir

4.1. Parte A: observar software y hardware con Tinkercad

  1. Abre el recurso compartido de Tinkercad. Si puedes acceder al circuito, identifica la placa Arduino, el botón, el LED y las conexiones. Si no puedes editarlo o el recurso no está disponible, crea un circuito nuevo y añade esos componentes siguiendo el vídeo. Reproduce el montaje y el código tal como se presentan en el recurso; no cambies pines al azar.

  2. Antes de ejecutar, localiza qué señal actúa como entrada del programa y qué componente produce la salida. Anota los nombres de los pines que aparecen en el montaje y cómo están conectados. Si el montaje incluye una resistencia, indica su función de limitación de corriente; no conectes el LED directamente a una salida sin respetar el circuito del recurso.

  3. Pulsa Iniciar simulación (o la opción equivalente) y acciona el botón. Observa cuándo cambia el estado del LED. Si no cambia, detén la simulación y revisa las conexiones y el código frente al recurso antes de volver a probar.

  4. Explica el recorrido de la información en esta simulación: el botón proporciona una señal de entrada, el microcontrolador ejecuta el programa y este modifica una salida conectada al LED. Distingue lo que muestra la simulación de lo que sería una medición eléctrica real. Comenta también qué hace el procesador con las instrucciones, qué estado o datos puede mantener temporalmente la memoria y cómo se relacionan los periféricos de entrada y salida con el programa; no supongas que todos los simuladores exponen internamente esos detalles.

  5. Como pequeña modificación, revisa el programa para localizar cómo detecta la pulsación y decide el estado del LED. Si la actividad de clase permite editarlo, cambia el comportamiento para que el LED alterne entre encendido y apagado con cada pulsación; prueba varias pulsaciones y registra el resultado. El planteamiento original también propone explorar una regla que encienda el LED tras dos pulsaciones y lo apague con una; antes de implementarla, define claramente el estado inicial y cómo contarás las pulsaciones. Si no tienes permiso para modificar el proyecto compartido, describe el cambio que harías en el código y úsalo como propuesta, sin afirmar que lo has probado.

4.2. Parte B: suma de 5 + 3 en LC-3 y comparación con C

  1. Abre uno de los simuladores LC-3. Localiza la zona para escribir o pegar código fuente y los controles Compile/Assemble, Step (paso a paso), Run y Reset. En la interfaz de SpaceTech puedes usar Compile y Step; en LC3web, abre el ensamblador para pegar el código, ensámblalo y carga el resultado en el simulador. Los nombres pueden variar ligeramente según el simulador.

  2. Pega este programa LC-3. Ensámblalo y carga el programa. Si aparece un error, comprueba que las etiquetas estén escritas igual en sus referencias y en sus definiciones.

    .ORIG x3000
    
    LD R0, NUM1          ; Cargar el valor de NUM1 en R0
    LD R1, NUM2          ; Cargar el valor de NUM2 en R1
    ADD R2, R0, R1       ; Sumar R0 y R1, guardar el resultado en R2
    
    ; Convertir el resultado a ASCII
    LD R3, ASCII_ZERO    ; Cargar el valor ASCII de '0' en R3 (48)
    ADD R0, R2, R3       ; Sumar R2 (resultado 8) con 48 para convertirlo
                          ; en el carácter ASCII correspondiente (x0038)
    
    ; Mostrar el resultado
    TRAP x21             ; Mostrar el carácter ASCII en pantalla
    HALT                 ; Finalizar el programa
    
    NUM1       .FILL x0005 ; Primer número (5)
    NUM2       .FILL x0003 ; Segundo número (3)
    ASCII_ZERO .FILL x0030 ; Código ASCII de '0' (48 en decimal)
    
    .END                   ; Fin del programa
    

    El ensamblador sitúa el inicio del programa en x3000. LD carga en un registro el contenido de una posición identificada por etiqueta; ADD suma registros y deja el resultado en el registro de destino. El programa carga 5 y 3 en R0 y R1, calcula 8 en R2, y suma x0030 (48 decimal, código ASCII del carácter 0) para obtener x0038, el código ASCII de 8, en R0. TRAP x21 (servicio OUT) escribe el carácter correspondiente al byte bajo de R0 en la consola; HALT detiene la ejecución. Los .FILL son datos en memoria, no instrucciones ejecutadas como operaciones de suma.

    Fíjate especialmente en estas tres instrucciones del ejemplo original:

    • LD R3, ASCII_ZERO carga en R3 el valor x0030, equivalente a 48 y al carácter ASCII 0.
    • ADD R0, R2, R3 suma ese valor al resultado numérico 8 para obtener x0038, el código ASCII del carácter 8.
    • TRAP x21 muestra ese carácter en la consola; por eso la salida visible es 8, no el texto x0038.
  3. Ejecuta el programa paso a paso. Tras cada instrucción, registra en una tabla la instrucción, el registro relevante y el valor esperado. Si el simulador usa hexadecimal, anota también su equivalente decimal cuando sea útil. Continúa hasta que el programa se detenga y consulta la consola.

  4. Comprueba que el resultado visible es el carácter 8. No confundas el número decimal 8 con el valor x0038: este último es su código ASCII. El 8 se muestra como un carácter porque el programa convierte el resultado antes de llamar a OUT.

  5. Compara con este programa equivalente en C. Léelo como código fuente y determina qué expresa; no lo pegues en el simulador LC-3, que acepta código de la arquitectura LC-3 y no compila C.

    #include <stdio.h>
    
    int main(void) {
        int num1 = 5;
        int num2 = 3;
        int resultado = num1 + num2;
        printf("%d\n", resultado);
        return 0;
    }
    

    En C se expresa la suma mediante variables, el operador + y una llamada a printf; un compilador de C traduciría este fuente para una plataforma de destino. En LC-3 se ven de forma explícita registros, cargas desde memoria, suma, conversión a ASCII y una llamada al servicio de salida. No deduzcas que cada línea de C equivale a una única instrucción de máquina: el compilador puede generar varias instrucciones y optimizarlas.

4.3. Ampliación: seguir la CPU con LMC

Esta parte recupera la actividad de Little Man Computer (LMC) de la propuesta anterior. El LMC es una metáfora didáctica de una CPU con memoria de números, entrada y salida; no representa por completo un ordenador actual.

  1. Abre el simulador LMC enlazado en los recursos. Localiza el área de programa, memoria, controles de ejecución y zonas de entrada y salida.

  2. Escribe el programa. DAT declara un dato en memoria, no una operación ejecutable.

    INP           ; Entrada del primer número
    STA NUM1      ; Guardar el número en la memoria
    INP           ; Entrada del segundo número
    ADD NUM1      ; Sumar NUM1 al acumulador
    OUT           ; Mostrar el resultado
    HLT           ; Terminar el programa
    NUM1 DAT 0    ; Variable para almacenar el primer número
    
  3. Comprueba la etiqueta NUM1 y ejecuta paso a paso. Introduce 5 en la primera petición y 3 en la segunda. Registra cómo cambian PC y ACC y consulta NUM1 si la interfaz lo muestra.

  4. Continúa hasta el final y verifica que la salida es 8. Si el simulador no muestra un registro o dato, anótalo como «no visible» y explica qué debería contener.

  5. Interpreta el recorrido: STA NUM1 guarda el primer dato; ADD NUM1 lo suma al valor del acumulador. Relaciona INP y OUT con operaciones de entrada y salida, teniendo presente que el modelo abstrae los periféricos reales.

Como ampliación opcional, PCjs permite explorar la simulación de ordenadores históricos completos. En algunas máquinas se puede cargar un sistema antiguo, como MS-DOS, y observar cómo el software y el sistema operativo interactúan con el hardware simulado. Las opciones dependen de la máquina seleccionada; no es necesario para completar la práctica.

5. Comprobaciones de finalización

  • En la parte A has identificado el botón como entrada y el LED como salida, y puedes describir cómo el programa relaciona ambos.
  • En la parte B el programa se ensambla, R2 contiene x0008 después de la suma y la consola muestra el carácter 8.
  • Puedes explicar por qué x0030 + x0008 = x0038 y por qué TRAP x21 muestra 8.
  • Tu comparación distingue claramente código C de instrucciones ensamblador LC-3 y no afirma que C se ejecute en el simulador LC-3.
  • En LMC, la ejecución con entradas 5 y 3 termina mostrando 8; explicas el papel de NUM1, ACC y PC o indicas qué dato no expone la interfaz.
  • Has separado datos en memoria, registros e instrucciones, y has relacionado el procesador con entrada/salida sin afirmar que la simulación equivale por completo a un ordenador real.

6. Ejercicios y entregables

  1. Responde con tus palabras:
    • En Tinkercad, ¿qué componente proporciona la entrada y cuál representa la salida? ¿Qué papel tiene el microcontrolador?
    • ¿Cómo interpreta la CPU las instrucciones del programa y qué papel tiene la memoria durante la ejecución? Distingue lo que puedes observar de lo que solo puedes inferir en cada simulador.
    • ¿Cómo actúan los periféricos de entrada y salida y cuál es el recorrido de los datos entre el programa, el procesador, la memoria y esos periféricos?
    • En LC-3, ¿qué contienen NUM1, NUM2 y ASCII_ZERO? ¿En qué se diferencian de R0, R1, R2 y R3?
    • ¿Por qué se suma x0030? ¿Qué cambiaría si la suma produjera un resultado de dos cifras?
    • ¿Qué información muestra la ejecución paso a paso de LC-3 que queda oculta al leer el programa C? ¿Qué tareas prácticas facilita la abstracción de C?
    • ¿Qué aspectos de este modelo simplificado no representan todos los detalles de un ordenador real (sistema operativo, RAM, controladores o electrónica de los periféricos)?
  2. Completa una tabla comparativa con, al menos, estos aspectos: nivel de abstracción, forma de expresar la suma, acceso visible a registros y memoria, mecanismo de salida, herramienta necesaria para ejecutar y plataforma/arquitectura a la que está ligado el código.
  3. En LMC, repite la ejecución con entradas 2 y 6; predice el resultado antes de ejecutar y registra los cambios de ACC y NUM1.
  4. Entrega un documento identificado con tu nombre, módulo, unidad y práctica que incluya:
    • las respuestas a las preguntas y la tabla comparativa;
    • una captura de la simulación Tinkercad en funcionamiento o, si no fue posible acceder, una explicación del montaje y la incidencia de acceso;
    • una captura de la consola LC-3 con el carácter 8 y una tabla breve del seguimiento de registros;
    • el código LC-3 empleado y el código C equivalente;
    • una reflexión final sobre procesador, memoria, periféricos, instrucciones y datos, incluyendo una diferencia entre la simulación y un ordenador real.
    • la tabla de seguimiento LMC, el caso de ampliación y una captura de la salida o una nota sobre los datos que la herramienta no muestra.

7. Solución orientativa

  • Parte A: el botón es un dispositivo de entrada; el LED es una salida. El microcontrolador ejecuta el programa y lee el estado de una entrada digital para decidir qué señal aplicar a la salida conectada al LED. El circuito y el código deben concordar en los pines. La simulación representa el comportamiento lógico y eléctrico del montaje con un modelo, no todas las características de una placa física.
  • Parte B: al ejecutar LD R0, NUM1 y LD R1, NUM2, los registros reciben x0005 y x0003. ADD R2, R0, R1 deja x0008 en R2. LD R3, ASCII_ZERO carga x0030; ADD R0, R2, R3 deja x0038 en R0. TRAP x21 envía el carácter ASCII asociado al byte bajo de R0 a la salida de consola. HALT finaliza el programa. Los .FILL reservan/inicializan palabras de memoria para los datos.
  • Comparación: C expresa la intención con abstracciones y una función de biblioteca de entrada/salida. LC-3 expone una secuencia concreta para esa ISA: cargas, operaciones sobre registros y trampa del sistema. C no es ejecutable en LC-3; para ejecutarlo se requiere un compilador y un entorno compatibles con la plataforma objetivo. Ensamblador también requiere un ensamblador para la ISA correspondiente.
  • Reflexión: LC-3 permite inspeccionar un modelo didáctico de CPU, registros, memoria e instrucciones. Un ordenador real incorpora muchos niveles adicionales; la RAM es memoria principal de trabajo y no es lo mismo que los registros, y los periféricos suelen comunicarse mediante controladores e interfaces gestionados por software de sistema.
  • LMC: con las entradas 5 y 3, INP coloca el primer valor en ACC; STA NUM1 lo conserva en memoria; el segundo INP carga 3 en ACC y ADD NUM1 deja 8. OUT muestra ese resultado y HLT termina. Para 2 y 6, NUM1 contiene 2 y ACC acaba en 8. El PC avanza por las instrucciones; el modo de visualizar los registros depende del simulador.

Fuentes y referencias