Articulo de referencia

Hackear una computadora

La computadora Hack es un diseño teórico de computadora creado por Noam Nisan y Shimon Schocken y descrito en su libro, Los elementos de los sistemas informáticos: Construyendo ...

La computadora Hack es un diseño teórico de computadora creado por Noam Nisan y Shimon Schocken y descrito en su libro, Los elementos de los sistemas informáticos: Construyendo una computadora moderna desde los primeros principios. [ 1 ] Al usar el término “moderna”, los autores se refieren a una máquina digital binaria que está diseñada según el modelo de arquitectura de von Neumann .

El ordenador Hack está diseñado para la construcción virtual práctica en una aplicación de simulador de hardware como parte de un curso básico, pero completo, de organización y arquitectura de ordenadores . [ 2 ] Uno de estos cursos, creado por los autores y presentado en dos partes, está disponible gratuitamente como un curso online masivo y abierto (MOOC) llamado «Construye un ordenador moderno desde los primeros principios: De Nand a Tetris» . [ 3 ] En los doce proyectos incluidos en el curso, los alumnos comienzan con una puerta NAND de dos entradas y terminan con un ordenador virtual completamente operativo, que incluye tanto hardware (memoria y CPU) como software (ensamblador, máquina virtual, lenguaje de programación similar a Java y sistema operativo). Además del simulador de hardware utilizado para la implementación inicial del hardware del ordenador, también está disponible en el sitio web del autor un programa emulador completo del ordenador Hack y un ensamblador que admite los proyectos descritos en el libro y el curso online. [ 4 ]

Arquitectura de hardware

Diagrama de bloques de computadora de hackeo

El hardware del ordenador Hack consta de tres elementos básicos, como se muestra en el diagrama de bloques . Hay dos unidades de memoria de 16 bits independientes y una unidad central de procesamiento (CPU). Dado que el ordenador transfiere y procesa datos en palabras de 16 bits, el ordenador Hack se clasifica como una arquitectura de 16 bits .

La memoria de instrucciones, implementada como memoria de solo lectura desde el punto de vista del ordenador y denominada ROM, almacena el código binario del programa para su ejecución. La memoria de acceso aleatorio (RAM) proporciona almacenamiento para los datos de un programa en ejecución y ofrece servicios y áreas de almacenamiento para el mecanismo de entrada/salida (E/S) mapeado en memoria del ordenador . El procesamiento de datos y la gestión del control del programa son responsabilidad de la CPU.

Las tres unidades están conectadas mediante buses paralelos. Los buses de direcciones (15 bits), así como los buses de datos e instrucciones (16 bits) para las unidades ROM y RAM, son completamente independientes. Por lo tanto, el diseño Hack sigue el modelo de arquitectura Harvard en lo que respecta a la comunicación por bus entre las unidades de memoria y la CPU. Toda la memoria es direccionable únicamente por palabra.

Memoria de solo lectura (ROM)

El módulo ROM del ordenador Hack se presenta como una matriz lineal de registros de memoria secuenciales de 16 bits, direccionables individualmente. Las direcciones comienzan en 0 ( 0x0000 ). Dado que los elementos de memoria son dispositivos secuenciales, la aplicación de simulación y la aplicación del emulador del ordenador suministran una señal de reloj del sistema . El bus de direcciones ROM tiene un ancho de 15 bits, por lo que hay un total de 32 768 palabras individuales disponibles para las instrucciones del programa. La dirección de la palabra activa la proporciona un registro de contador de programa dentro de la CPU (véase más abajo). El valor en el registro de memoria ROM identificado por la dirección colocada en el bus de direcciones de instrucciones en un ciclo de reloj determinado está disponible como la instrucción "actual" al comienzo del siguiente ciclo. No hay registro de instrucciones ; las instrucciones se decodifican en cada ciclo a partir del registro ROM activo.

Memoria de acceso aleatorio (RAM)

Aunque el módulo RAM también se considera una matriz lineal continua de registros de memoria secuenciales de lectura y escritura de 16 bits, direccionables individualmente, su organización funcional se divide en tres segmentos según su rango de direcciones. Las direcciones 0 ( 0x000 ) a 16383 ( 0x3FFF ) contienen registros convencionales de lectura y escritura de 16 bits y están destinadas al almacenamiento de datos de programas de propósito general.

Los registros en las direcciones 16384 ( 0x4000 ) a 24575 ( 0x5FFF ) funcionan esencialmente como memoria RAM de datos, pero también están designados para su uso por un subsistema de E/S de pantalla integrado. Los datos escritos en las direcciones de este rango generan una salida en la pantalla virtual de 256 x 512 del ordenador (véase E/S). Si un programa no requiere salida de pantalla, los registros de este rango pueden utilizarse para datos generales del programa.

La última dirección en el espacio de direcciones de la RAM, en 24576 ( 0x6000 ), contiene un único registro de una palabra cuyo valor actual está controlado por la salida de un teclado conectado al ordenador que aloja el programa emulador Hack. Este registro de mapa de memoria del teclado es de solo lectura (véase E/S).

Las direcciones de memoria de datos comprendidas entre 24577 ( 0x6001 ) y 32767 ( 0x7FFF ) no son válidas. Las transiciones de estado del registro de memoria RAM seleccionado también están coordinadas por la señal del reloj del sistema.

unidad central de procesamiento (CPU)

Diagrama de bloques de la CPU de la computadora Hack
Diagrama de bloques de la CPU de la computadora Hack

Como se ilustra en el diagrama adjunto, la unidad central de procesamiento (CPU) de la computadora Hack es una unidad lógica integrada con una estructura interna. Proporciona muchas de las funciones presentes en las CPU comerciales convencionales. El elemento más complejo de la CPU es la unidad aritmético-lógica (ALU), que proporciona la funcionalidad computacional de la computadora. La ALU es un dispositivo lógico combinacional con dos operandos de entrada de 16 bits y una única salida de 16 bits. El cálculo producido como salida de los operandos se especifica mediante un conjunto de seis entradas ordenadas de un bit a la ALU. La ALU también emite dos indicadores de estado de un bit que señalan si el resultado del cálculo es cero (indicador zr) o negativo (indicador ng).

La CPU también contiene dos registros de 16 bits , denominados D y A. El registro D (Datos) es un registro de propósito general cuyo valor actual siempre proporciona el operando x a la ALU, aunque para algunas instrucciones su valor se ignora. Si bien el registro A (Dirección) también puede proporcionar su valor actual como el operando y a la ALU cuando así lo indica una instrucción, su valor también puede usarse para el direccionamiento de la memoria de datos y como dirección de destino en la memoria de instrucciones para las instrucciones de bifurcación. Para facilitar esta función, el registro A está directamente asociado con un "pseudoregistro" denominado M, que no está implementado explícitamente en el hardware. Por lo tanto, este registro M representa el valor contenido en la RAM que tiene la dirección del valor actual contenido en el registro A.

El último elemento importante de la CPU es el registro del contador de programa (PC). El PC es un contador binario de 16 bits cuyos 15 bits menos significativos especifican la dirección en la memoria de instrucciones de la siguiente instrucción a ejecutar. A menos que una instrucción de bifurcación indique lo contrario, el PC incrementa su valor al final de cada ciclo de reloj. La CPU también incluye lógica para cambiar, bajo control de programa, el orden de ejecución de las instrucciones, estableciendo el PC a un valor no secuencial. El PC también implementa una entrada de reinicio de un bit que inicializa su valor a 0 (0x0000) cuando cambia de estado lógico 0 a 1 y viceversa. A diferencia de muchos diseños de CPU reales, no se proporciona ningún mecanismo de hardware accesible mediante programa para implementar interrupciones externas o internas de la CPU ni para admitir llamadas a funciones.

Entrada y salida (E/S) externas

El ordenador Hack emplea un enfoque de E/S basado en mapeo de memoria. La salida en blanco y negro, en formato de mapa de bits, a una pantalla virtual de 256 x 512 píxeles se consigue escribiendo un mapa de bits de la salida deseada en las direcciones de memoria de datos 16384 ( 0x4000 ) a 24575 ( 0x5FFF ). Las palabras de datos en este rango de direcciones se consideran una matriz lineal de bits, donde cada valor representa el estado blanco/negro de un píxel en la pantalla virtual del emulador. El bit menos significativo de la palabra en la primera dirección de memoria del segmento de RAM de pantalla establece el píxel de la esquina superior izquierda en blanco si es 0 y en negro si es 1. El siguiente bit más significativo de la primera palabra controla el siguiente píxel a la derecha, y así sucesivamente. Una vez descrita la primera fila de 512 píxeles por las primeras 32 palabras de la memoria de pantalla, el mapeo continúa de la misma manera para la segunda fila con las siguientes 32 palabras. La lógica externa al ordenador lee el segmento del mapa de memoria RAM de la pantalla y actualiza la pantalla virtual.

Si se conecta un teclado al ordenador que aloja el programa emulador de CPU, este coloca un código de escaneo de 16 bits, correspondiente a la tecla pulsada durante la ejecución del programa, en el registro del teclado en la dirección RAM 24576 (0x6000). Si no se pulsa ninguna tecla, este registro contiene el valor 0. El emulador proporciona un botón para activar/desactivar el teclado. El esquema de codificación sigue de cerca la codificación ASCII para caracteres imprimibles. Generalmente, se respeta el efecto de la tecla Mayús . También se proporcionan códigos para otras teclas que suelen estar presentes en un teclado de PC estándar; por ejemplo, las teclas de control de dirección (←, ↑, ↓, →) y las teclas Fn.

Ciclo operativo

El funcionamiento paso a paso de la CPU y las unidades de memoria se controla mediante un reloj integrado tanto en el simulador de hardware como en el emulador. Al inicio de un ciclo de reloj, se decodifica la instrucción en la dirección ROM emitida por el valor actual del contador de programa. Los operandos de la ALU especificados en la instrucción se almacenan donde sea necesario. La ALU realiza el cálculo especificado y se activan los indicadores de estado correspondientes. El resultado del cálculo se guarda según lo especificado en la instrucción. Finalmente, el contador de programa se actualiza con el valor de la siguiente instrucción requerida. Si la instrucción actual no especifica un salto, el valor del PC simplemente se incrementa. Si se especifica un salto, el PC se carga (desde el registro A) con la dirección de la siguiente instrucción a ejecutar. El ciclo se repite entonces utilizando el valor actual del PC.

Gracias a su arquitectura de memoria Harvard, el ordenador Hack está diseñado para ejecutar la instrucción actual y obtener la siguiente en un único ciclo de reloj de dos partes. La velocidad del reloj puede variarse mediante un elemento de control tanto en el simulador de hardware como en el emulador de CPU. Sin embargo, independientemente de la velocidad seleccionada, cada instrucción se ejecuta completamente en un ciclo. El usuario también puede ejecutar un programa paso a paso.

La ejecución de un programa cargado en la ROM está controlada por el bit de reinicio de la CPU. Si el valor del bit de reinicio es 0, la ejecución procede según el ciclo operativo descrito anteriormente. Al establecer el bit de reinicio en 1, el contador de programa (PC) se establece en 0. Al restablecer el bit de reinicio a cero, se inicia la ejecución del programa actual en la primera instrucción; sin embargo, la RAM conserva los valores de cualquier actividad previa al reiniciarse.

No existe soporte de hardware ni de lenguaje máquina para interrupciones de ningún tipo.

Tipos de datos

Los valores almacenados en la memoria ROM deben representar instrucciones válidas del lenguaje máquina Hack, tal como se describe en la sección Arquitectura del conjunto de instrucciones.

Cualquier valor de 16 bits puede almacenarse en la RAM. El tipo de dato del valor almacenado en la RAM se deduce de su ubicación y/o su uso dentro de un programa. El tipo de dato principal compatible con el hardware es el entero con signo de 16 bits, que se representa en formato de complemento a dos. Por lo tanto, los enteros con signo tienen un rango de -32768 a 32767. Los 15 bits inferiores de un valor en la RAM también pueden representar una dirección en la ROM o la RAM en el sentido de un puntero .

Para los valores en los registros de memoria RAM asignados para E/S de pantalla, el valor será interpretado como un mapa de 16 píxeles de la pantalla virtual de 256 filas x 512 columnas por el subsistema de E/S independiente de la computadora si la pantalla está "encendida".

El valor del código almacenado en la memoria del teclado puede leerse mediante programación e interpretarse para su uso por un programa.

No existe soporte de hardware para tipos de coma flotante .

Arquitectura del conjunto de instrucciones (ISA) y lenguaje de máquina

La arquitectura del conjunto de instrucciones (ISA) y el lenguaje máquina derivado del ordenador Hack son escasos en comparación con muchas otras arquitecturas. Aunque los 6 bits utilizados para especificar un cálculo por la ALU podrían permitir 64 instrucciones distintas, solo 18 están implementadas oficialmente en la ISA del ordenador Hack. Dado que el hardware del ordenador Hack no admite directamente la multiplicación (ni la división) de enteros ni las llamadas a funciones, no existen instrucciones en lenguaje máquina correspondientes en la ISA para estas operaciones.

El lenguaje de máquina Hack solo tiene dos tipos de instrucciones, cada una codificada en 16 dígitos binarios.

Instrucciones A

Las instrucciones cuyo bit más significativo es "0" se denominan instrucciones A o instrucciones de dirección. La instrucción A se codifica en campos de bits de la siguiente manera:

0 b 14 b 13 b 12 b 11 b 10 b 9 b 8 b 7 b 6 b 5 b 4 b 3 b 2 b 1 b 0

0 – la parte más significativa de una instrucción A es "0"

b 14 - b 0 - estos bits proporcionan la representación binaria de un entero no negativo en el rango decimal de 0 a 32767.

Cuando se ejecuta esta instrucción, los 15 bits restantes se extienden a cero por la izquierda y se cargan en el registro A de la CPU. Como efecto secundario, el registro de RAM con la dirección representada por ese valor se habilita para operaciones de lectura/escritura posteriores en el siguiente ciclo de reloj.

Instrucciones C

El otro tipo de instrucción, conocida como instrucción C (instrucciones de cálculo), es la herramienta básica de programación. Tiene el bit más significativo "1". Los 15 bits restantes se codifican en campos de bits para definir los operandos, el cálculo realizado y la ubicación de almacenamiento para el resultado del cálculo especificado. Esta instrucción también puede especificar una bifurcación del programa basada en el resultado del cálculo más reciente. El formato es

Instrucción C: dest = comp ; salto , tanto dest como salto pueden estar vacíos, lo que da dos opciones: dest = comp o comp ; salto

La instrucción C se codifica en campos de bits de la siguiente manera:

111 a c 1 c 2 c 3 c 4 c 5 c 6 d 1 d 2 d 3 j 1 j 2 j 3

1 – la parte más significativa de una instrucción C es "1"

11 – estos dos últimos bits son ignorados por la CPU y, por convención, siempre se establecen en "1" cada uno.

a – este bit especifica la fuente del operando "y" de la ALU cuando se utiliza en un cálculo.

c 1 -c 6 : estos seis bits de control especifican los operandos y el cálculo que realizará la ALU.

d 1 -d 3 : estos tres bits especifican el/los destino(s) para almacenar la salida actual de la ALU.

j 1 -j 3 : estos tres bits especifican una condición de bifurcación aritmética, una bifurcación incondicional (salto) o ninguna bifurcación.

El esquema de codificación informática Hack de la instrucción C se muestra en las siguientes tablas.

En estas tablas,

  • A representa el valor que se encuentra actualmente en el registro A.
  • D representa el valor que se encuentra actualmente en el registro D.
  • M representa el valor actualmente contenido en el registro de memoria de datos cuya dirección está contenida en el registro A; es decir, M == RAM[A]

lenguaje ensamblador

El ordenador Hack dispone de un lenguaje ensamblador basado en texto para crear programas para la plataforma de hardware que implementa la arquitectura de conjunto de instrucciones (ISA) del ordenador Hack. Los programas en lenguaje ensamblador Hack pueden almacenarse en archivos de texto con la extensión “.asm”. Los archivos fuente en lenguaje ensamblador Hack distinguen entre mayúsculas y minúsculas. Cada línea de texto contiene uno de los siguientes elementos:

  • Línea en blanco
  • Comentario
  • Declaración de etiqueta (con comentario opcional al final de la línea)
  • Instrucción A (con comentario opcional al final de la línea)
  • Instrucción en C (con comentario opcional al final de la línea)

Cada uno de estos tipos de línea tiene una sintaxis específica y puede contener símbolos predefinidos o definidos por el usuario, o constantes numéricas. El ensamblador ignora las líneas en blanco y los comentarios. Las declaraciones de etiquetas, las instrucciones A y las instrucciones C, tal como se definen a continuación, no pueden incluir caracteres de espacio en blanco internos, aunque se permiten (y se ignoran) los espacios en blanco iniciales o finales.

Comentarios

Cualquier texto que comience con la secuencia de dos caracteres "//" es un comentario. Los comentarios pueden aparecer solos en una línea del código fuente o al final de cualquier otra línea del código fuente del programa. El ensamblador ignora por completo todo el texto que sigue a la secuencia de caracteres que identifica el comentario hasta el final de la línea; por lo tanto, no genera código máquina.

Símbolos y constantes numéricas

El lenguaje ensamblador Hack permite el uso de símbolos alfanuméricos para diversos fines específicos. Un símbolo puede ser cualquier secuencia de dígitos alfabéticos (mayúsculas y minúsculas) o numéricos. Los símbolos también pueden contener cualquiera de los siguientes caracteres: guion bajo ("_"), punto (""), signo de dólar ("$") y dos puntos (":"). Los símbolos no pueden comenzar con un dígito. Los símbolos distinguen entre mayúsculas y minúsculas. Los símbolos definidos por el usuario se utilizan para crear nombres y etiquetas de variables (véase más abajo).

El ensamblador de Hack reconoce algunos símbolos predefinidos para su uso en programas de lenguaje ensamblador. Los símbolos R0, R1, …, R15 están vinculados respectivamente a los enteros del 0 al 15. Estos símbolos representan registros de propósito general y, por lo tanto, sus valores representan direcciones de memoria de datos del 0 al 15. Los símbolos predefinidos SCREEN y KBD también se especifican para representar la dirección de memoria de datos del inicio de la salida de pantalla virtual mapeada en memoria (16384) y la entrada de teclado (24756). Existen otros símbolos (SP, LCL, ARG, THIS y THAT) que se utilizan para construir la pila de software del sistema operativo .

Se puede utilizar una cadena de dígitos decimales (0–9) para representar una constante decimal no negativa en el rango de 0 a 32 767. No se permite el uso del signo menos para indicar un número negativo. No se admiten representaciones binarias ni octales.

Variables

En un programa en lenguaje ensamblador, se pueden crear símbolos definidos por el usuario para representar variables; es decir, un registro de RAM con nombre. El símbolo se vincula durante el proceso de ensamblaje a una dirección de RAM elegida por el ensamblador. Por lo tanto, las variables deben tratarse como direcciones cuando aparecen en el código fuente en lenguaje ensamblador.

Las variables se definen implícitamente en el código fuente del lenguaje ensamblador cuando se referencian por primera vez en una instrucción A. Cuando el ensamblador procesa el código fuente, el símbolo de la variable se vincula a un valor entero positivo único a partir de la dirección 16. Las direcciones se vinculan secuencialmente a los símbolos de las variables en el orden en que aparecen por primera vez en el código fuente. Por convención, los símbolos definidos por el usuario que identifican las variables del programa se escriben en minúsculas.

Etiquetas

Las etiquetas son símbolos delimitados por paréntesis izquierdo (") y derecho ")". Se definen en una línea de código fuente independiente y el ensamblador las vincula a la dirección de memoria de la siguiente instrucción. Las etiquetas se definen solo una vez, pero pueden usarse varias veces en cualquier parte del programa, incluso antes de la línea donde se definen. Por convención, las etiquetas se escriben en mayúsculas. Se utilizan para identificar la dirección de destino de las instrucciones de salto en C.

Instrucciones A

La instrucción A tiene la sintaxis "@ xxxx ", donde xxxx puede ser una constante decimal numérica entre 0 y 32767, una etiqueta o una variable (predefinida o definida por el usuario). Al ejecutarse, esta instrucción establece el valor del registro A y del pseudoregistro M a un valor binario de 15 bits representado por " xxxx ". Este valor de 15 bits se extiende a 16 bits en el registro A, dejando ceros a la izquierda.

La instrucción A puede utilizarse para tres propósitos. Es el único medio para introducir un valor numérico (no negativo) en el ordenador bajo control programático; es decir, puede utilizarse para crear constantes de programa. En segundo lugar, se utiliza para especificar una ubicación de memoria RAM mediante el mecanismo de pseudoregistro M para su posterior referencia por una instrucción C. Finalmente, una instrucción C que especifica un salto utiliza el valor actual del registro A como dirección de destino del salto. La instrucción A se utiliza para establecer dicha dirección de destino antes de la instrucción de salto, normalmente mediante una etiqueta.

Instrucciones C

Las instrucciones C dirigen el motor de cálculo de la ALU y las capacidades de control de flujo del programa de la computadora Hack. La sintaxis de la instrucción se define mediante tres campos: "comp", "dest" y "jump". El campo "comp" es obligatorio en cada instrucción C. La sintaxis de la instrucción C es "dest = comp ; jump". Los caracteres "=" y ";" se utilizan para delimitar los campos de la instrucción. Si no se utiliza el campo "dest", se omite el carácter "=". Si no se utiliza el campo "jump", se omite el carácter ";". La instrucción C no permite espacios internos.

El campo `comp` debe ser uno de los 28 códigos mnemotécnicos documentados que se definen en la tabla anterior. Estos códigos se consideran unidades independientes y deben escribirse en mayúsculas, sin espacios internos. Cabe destacar que los 6 bits de control de la ALU podrían especificar hasta 64 funciones computacionales; sin embargo, solo las 18 presentadas en la tabla están oficialmente documentadas para su reconocimiento por el ensamblador.

El campo `dest` se puede usar para especificar una o más ubicaciones donde almacenar el resultado del cálculo. Si se omite este campo, junto con el delimitador `="`, el valor calculado no se almacena. Las combinaciones de ubicaciones de almacenamiento permitidas se especifican mediante los códigos mnemotécnicos definidos en la tabla anterior.

El campo de salto se puede usar para especificar la dirección en la ROM de la siguiente instrucción a ejecutar. Si se omite este campo, junto con el delimitador ";", la ejecución continúa con la instrucción inmediatamente posterior a la actual. La dirección de destino del salto, en la ROM, viene dada por el valor actual del registro A si se cumple la condición de salto especificada. Si la condición de salto falla, la ejecución continúa con la siguiente instrucción en la ROM. Se proporcionan códigos mnemotécnicos para seis comparaciones diferentes según el valor del cálculo actual. Además, se proporciona un salto incondicional como séptima opción. Dado que el campo comp siempre debe proporcionarse, aunque el valor no sea necesario para el salto incondicional, la sintaxis de esta instrucción es "0;JMP". Las condiciones de salto admitidas se especifican en la tabla anterior.

Ensamblador

El software gratuito compatible con el ordenador Hack incluye una aplicación de ensamblador de línea de comandos. El ensamblador lee los bloques de código fuente en lenguaje ensamblador de Hack (*.asm) y genera archivos de salida en lenguaje máquina de Hack (*.hack). El archivo de lenguaje máquina también es un archivo de texto. Cada línea de este archivo es una cadena de 16 caracteres binarios que representa la codificación de cada línea ejecutable correspondiente del archivo de texto fuente, según la especificación descrita en la sección "Arquitectura del conjunto de instrucciones (ISA) y lenguaje máquina". El archivo creado puede cargarse en el emulador del ordenador Hack mediante una función proporcionada por la interfaz de usuario del emulador.

Ejemplo de programa en lenguaje ensamblador

A continuación se muestra un programa de ejemplo comentado escrito en lenguaje ensamblador Hack. Este programa suma los primeros 100 enteros consecutivos y coloca el resultado del cálculo en una variable definida por el usuario llamada " sum ". Implementa un bucle while para iterar a través de los valores enteros del 1 al 100 y suma cada entero a la variable "sum". La variable definida por el usuario " cnt " mantiene el valor entero actual durante el bucle. Este programa ilustra todas las características de las capacidades del lenguaje ensamblador "documentadas" de la computadora Hack, excepto la E/S mapeada en memoria. Es la traducción al ensamblador Hack del fragmento C:

// Suma 1+...+100 int cnt = 1 ; int sum = 0 ; while ( cnt <= 100 ) { sum += cnt ; cnt ++ ; }

El contenido del archivo fuente en lenguaje ensamblador de Hack se muestra en la segunda columna en negrita. Los números de línea se proporcionan como referencia en la siguiente explicación, pero no aparecen en el código fuente. El código máquina de Hack generado por el ensamblador se muestra en la última columna, con la dirección de ROM asignada en la columna anterior. Cabe destacar que los comentarios de línea completa, las líneas en blanco y las definiciones de etiquetas no generan código máquina. Asimismo, el ensamblador ignora los comentarios que aparecen al final de cada línea que contiene una instrucción en lenguaje ensamblador.

La salida del ensamblador, que se muestra en la última columna, es una cadena de texto de 16 caracteres binarios, no una representación de un entero binario de 16 bits.

Nótese que la secuencia de instrucciones sigue el patrón de instrucción A, instrucción C, instrucción A, instrucción C, ... . Esto es típico de los programas en lenguaje ensamblador Hack. La instrucción A especifica una constante o dirección de memoria que se utiliza en la instrucción C subsiguiente.

Se ilustran las tres variantes de la instrucción A. En la línea 11 (@100), el valor constante 100 se carga en el registro A. Este valor se utiliza en la línea 12 (D=DA) para calcular el valor que se usa para comprobar la condición de bifurcación del bucle.

Dado que la línea 4 (@cnt) contiene la primera aparición de la variable definida por el usuario "cnt", esta instrucción vincula el símbolo a la siguiente dirección de RAM no utilizada. En este caso, la dirección es 16, y ese valor se carga en el registro A. Además, el pseudoregistro M también hace referencia a esta dirección, y RAM[16] se convierte en la ubicación de memoria RAM activa.

El tercer uso de la instrucción A se observa en la línea 21 (@LOOP). En esta instrucción, se carga el valor de la etiqueta vinculada, que representa una dirección en la memoria ROM, en el registro A y el pseudoregistro M. La instrucción de salto incondicional subsiguiente en la línea 22 (0;JMP) carga el valor del registro M en el registro del contador de programa de la CPU para transferir el control al inicio del bucle.

El ordenador Hack no proporciona ninguna instrucción en lenguaje máquina para detener la ejecución del programa. Las dos últimas líneas del programa (@END y 0;JMP) crean una condición de bucle infinito que los programas en lenguaje ensamblador Hack utilizan habitualmente para finalizar programas diseñados para ejecutarse en el emulador de CPU.

Véase también

  • Hennessy, John L., y Patterson, David A. (2019). Arquitectura de computadoras: un enfoque cuantitativo, 6.ª edición . Cambridge, Massachusetts: Morgan Kaufmann Publishers
  • Justice, Matthew. (2021). Cómo funcionan realmente las computadoras. San Francisco, California: No Starch Press.
  • Malvino, Albert P., y Brown, Jerald A. (1993). Electrónica digital de computadoras, 3.ª edición . Nueva York, Nueva York: Glencoe McGraw-Hill
  • Null, Linda y Lobur, Julia. (2019). Fundamentos de organización y arquitectura de computadoras. 5.ª edición . Burlington, Massachusetts: Jones and Bartlett Learning.
  • Patt, Yale N., y Patel, Sanjay J. (2020). Introducción a los sistemas informáticos: de bits y compuertas a C y más allá, 3.ª edición. Nueva York, Nueva York: McGraw Hill Education.
  • Petzold, Charles. (2009). Código: El lenguaje oculto del hardware y el software informático. Redmond, Washington: Microsoft Press.
  • Scott, John Clark. (2009). ¿Pero cómo lo sabe? Los principios básicos de las computadoras para todos. Oldsmar, Florida: John C. Scott.
  • Whipple, Richard. (2019). Construye tu propia computadora desde cero. Seattle, Washington: Amazon Kindle.

Referencias

  1. Nisan, Noam; Schocken, Shimon (2021). Los elementos de los sistemas informáticos: Construyendo una computadora moderna desde los primeros principios, 2.ª edición . Cambridge, Massachusetts: The MIT Press.
  2. Schocken, Shimon (2021), Programa de estudios de Nand to Tetris .
  3. "Construye una computadora moderna desde los principios básicos: De Nand a Tetris" . Consultado el 21 de agosto de 2021 .
  4. "De Nand a Tetris" . Consultado el 23 de agosto de 2021 .