Conjunto de instrucciones para niños
Un conjunto de instrucciones es como el "idioma" que entiende el cerebro de una computadora, llamado CPU. Es una lista de todas las órdenes o comandos que la CPU puede ejecutar. Imagina que es un manual de instrucciones muy detallado para que la computadora sepa qué hacer.
Este "idioma" incluye cómo la computadora maneja diferentes tipos de información, qué operaciones puede realizar (como sumar o restar), cómo usa sus espacios de almacenamiento temporales (llamados registros) y cómo organiza su memoria.
Existen principalmente tres tipos de conjuntos de instrucciones:
- CISC (Complex Instruction Set Computer): Computadoras con un conjunto de instrucciones complejo.
- RISC (Reduced Instruction Set Computer): Computadoras con un conjunto de instrucciones reducido.
- SISC (Simple Instruction Set Computing): Computadoras con un conjunto de instrucciones simple.
A veces, se usa el término "arquitectura del conjunto de instrucciones" (ISA) para diferenciar estas órdenes de cómo se construyen físicamente las partes de la computadora (la microarquitectura). Por ejemplo, dos procesadores diferentes, como el Intel Pentium y el AMD Athlon, pueden entender casi el mismo conjunto de instrucciones (como el x86), aunque su diseño interno sea distinto.
Contenido
- ¿Cómo funciona el lenguaje máquina?
- ¿Cómo se implementa un conjunto de instrucciones?
- Diseño de un conjunto de instrucciones
- Tipos de instrucciones y ejemplos
- Véase también
¿Cómo funciona el lenguaje máquina?
El lenguaje máquina es el nivel más básico de comunicación con la computadora. Está formado por instrucciones muy específicas que le dicen a la CPU exactamente qué hacer. Cada instrucción puede indicar:
- Qué registros usar para cálculos o para controlar el flujo del programa.
- Qué lugares específicos de la memoria deben ser usados.
- Cómo interpretar los datos que se van a usar (llamados operandos).
Las tareas más complicadas que hace una computadora se construyen combinando muchas de estas instrucciones sencillas, que se ejecutan una tras otra.
Tipos de operaciones básicas
La mayoría de los conjuntos de instrucciones incluyen operaciones para:
- Mover datos:
- Poner un valor fijo en un registro.
- Mover información de la memoria a un registro y viceversa. Esto es clave para que la CPU pueda trabajar con los datos.
- Leer y escribir datos en dispositivos como el teclado o la pantalla.
- Hacer cálculos matemáticos:
- Sumar, restar, multiplicar o dividir valores en los registros y guardar el resultado.
- Realizar operaciones lógicas "bit a bit" (como AND, OR, NOT) con los datos.
- Comparar dos valores para saber si son iguales, si uno es mayor que otro, etc.
- Controlar el programa:
- Saltar a otra parte del programa para ejecutar instrucciones allí.
- Saltar a otra parte solo si se cumple una condición específica.
- Saltar a otra parte, pero guardando la posición actual para poder regresar después (como cuando un programa llama a una función).
Instrucciones complejas
Algunas computadoras tienen instrucciones "complejas" que pueden hacer varias cosas a la vez. Estas instrucciones son como atajos que combinan muchos pasos en uno solo. Por ejemplo:
- Guardar varios registros en un área especial de la memoria llamada pila.
- Mover grandes bloques de información de un lugar a otro en la memoria.
- Realizar cálculos matemáticos avanzados con números decimales (coma flotante), como el seno o la raíz cuadrada.
- Instrucciones que combinan operaciones matemáticas con acceso directo a la memoria.
Un tipo de instrucción compleja muy popular hoy en día es SIMD (Single Instruction, Multiple Data). Esta operación permite realizar el mismo cálculo en muchos datos al mismo tiempo. Las instrucciones SIMD son muy útiles para trabajar con imágenes, sonido y video, ya que pueden procesar grandes cantidades de información de forma paralela y rápida. Algunos ejemplos comerciales de SIMD son MMX, 3DNow! y AltiVec.
CISC vs. RISC
Diseñar un conjunto de instrucciones es complicado. Al principio, existían los sistemas CISC (Complex Instruction Set Computer), que tenían muchísimas instrucciones diferentes. Sin embargo, en los años 70, una investigación mostró que muchas de esas instrucciones podían eliminarse sin afectar el rendimiento.
Así nació el concepto RISC (Reduced Instruction Set Computer), una arquitectura que usa un conjunto de instrucciones más pequeño y simple. Un conjunto de instrucciones más sencillo puede permitir que el procesador funcione más rápido, sea más pequeño y consuma menos energía. Por otro lado, un conjunto más complejo puede optimizar operaciones comunes, usar mejor la memoria y hacer la programación más sencilla.
¿Cómo se implementa un conjunto de instrucciones?
Un conjunto de instrucciones se puede construir de varias maneras, pero todas deben lograr que la computadora funcione de la misma forma para el programador. Las diferentes formas de construirlo ofrecen ventajas y desventajas en cuanto a costo, rendimiento, consumo de energía y tamaño.
Los ingenieros usan bloques de circuitos electrónicos ya diseñados, como multiplexores (que eligen una señal de varias), contadores, registros y ALU (que hace cálculos). Con estos bloques, describen cómo se codifica y ejecuta cada instrucción.
También hay nuevas formas de implementar conjuntos de instrucciones, como compilarlos en una memoria especial dentro de la CPU o usar chips reconfigurables (FPGA).
Además, un conjunto de instrucciones puede ser "emulado" por un programa de computadora. Esto significa que un software imita el comportamiento de un hardware. Aunque es más lento, es útil para que los desarrolladores prueben sus programas antes de que el hardware real esté listo.
La forma en que se implementa un conjunto de instrucciones influye mucho en las instrucciones que se eligen. Por ejemplo, algunas formas de organizar las operaciones en la CPU (llamadas "pipeline") solo permiten cargar o guardar un dato en la memoria por instrucción, lo que lleva a arquitecturas como RISC.
Diseño de un conjunto de instrucciones
Densidad del código
En las computadoras antiguas, la memoria era muy cara. Por eso, era importante que los programas fueran lo más pequeños posible para que cupieran en la memoria limitada. La "densidad del código" se refiere a qué tan compacto es un programa. Las computadoras con alta densidad de código a menudo tenían instrucciones complejas que hacían muchas cosas a la vez.
Las arquitecturas RISC, que surgieron cuando la memoria se hizo más barata, buscan simplificar los circuitos para aumentar la velocidad. Las instrucciones RISC suelen hacer solo una operación a la vez (como sumar registros o cargar datos en un registro) y tienen un tamaño fijo. Esto las hace más fáciles de manejar y optimizar para la velocidad. Sin embargo, como necesitan más instrucciones para hacer una tarea, pueden usar más ancho de banda de memoria.
Las computadoras con un conjunto de instrucciones mínimo (MISC) tienen muy pocas instrucciones (entre 16 y 64), lo que permite que varias instrucciones quepan en una sola "palabra" de la máquina. Esto hace que sean fáciles de implementar en chips pequeños.
Número de operandos
Los conjuntos de instrucciones se pueden clasificar por cuántos datos (operandos) pueden manejar explícitamente en una sola instrucción. Aquí, 'a', 'b' y 'c' son lugares en la memoria, y 'reg1' se refiere a un registro:
- 0-operando (máquina de pila): Las operaciones se hacen en los datos que están en la parte superior de una "pila". Primero se ponen los datos en la pila, luego se hace la operación y el resultado se saca.
- Ejemplo: `push a`, `push b`, `add`, `pop c` (pone 'a', luego 'b', los suma, y guarda el resultado en 'c').
- 1-operando (máquinas de acumulador): La mayoría de las instrucciones usan un operando explícito y un "acumulador" (un registro especial) para el otro.
- Ejemplo: `load a`, `add b`, `store c` (carga 'a' en el acumulador, le suma 'b', y guarda el resultado en 'c').
- 2-operandos: La mayoría de las computadoras CISC y RISC usan esto.
- CISC: `load a, reg1`, `add reg1, b`, `store reg1, c` (carga 'a' en reg1, suma 'b' a reg1, guarda reg1 en 'c').
- RISC: `load a, reg1`, `load b, reg2`, `add reg1, reg2`, `store reg2, c` (carga 'a' en reg1, 'b' en reg2, suma reg1 y reg2, guarda reg2 en 'c').
- 3-operandos: Permite usar mejor los datos.
- CISC: `add a, b, c` (suma 'a' y 'b' y guarda en 'c').
- RISC: `load a, reg1`, `load b, reg2`, `add reg1, reg2, reg3`, `store reg3, c` (carga 'a' en reg1, 'b' en reg2, suma reg1 y reg2 y guarda en reg3, guarda reg3 en 'c').
Características importantes
Un buen conjunto de instrucciones debe tener cuatro características principales:
- Completo: Debe poder realizar cualquier tarea que una computadora pueda hacer en un tiempo razonable.
- Eficiente: Debe permitir cálculos rápidos sin necesitar un diseño muy complicado de la CPU y sin usar demasiados recursos (como memoria).
- Autocontenidas: Cada instrucción debe tener toda la información que necesita para ejecutarse por sí misma.
- Independientes: Las instrucciones no deben depender de que otra instrucción se haya ejecutado antes.
Para que un conjunto de instrucciones sea completo, solo se necesitan unas pocas instrucciones básicas (como escribir, mover y leer, y parar). Las arquitecturas RISC se basan en esta idea. Sin embargo, en la práctica, los conjuntos de instrucciones son más amplios para lograr un mejor rendimiento.
Tipos de instrucciones y ejemplos
Transferencia de datos
Estas instrucciones copian datos de un lugar a otro sin cambiarlos y sin afectar los "flags" (pequeños indicadores que muestran el resultado de una operación). Pueden mover palabras completas, partes de palabras (como bytes) o bloques grandes de datos.
Pueden ser:
- De registro a registro.
- De registro a memoria.
- De memoria a registro.
- De memoria a memoria.
Ejemplos:
- move: Copia el contenido de un registro (o memoria) a otro.
- store: Copia el contenido de un registro a la memoria.
- load: Copia el contenido de una posición de memoria a un registro.
- move block: Copia un bloque de datos de una parte de la memoria a otra.
- push: Introduce un dato en la "pila" (un área de memoria especial).
- pop: Saca un dato de la "pila".
Instrucciones aritméticas
Realizan operaciones matemáticas y suelen cambiar los "flags".
Ejemplos:
- add: Suma.
- subtract: Resta.
- increment: Aumenta un valor en 1.
- decrement: Disminuye un valor en 1.
- multiply: Multiplica.
- divide: Divide.
- negate: Cambia el signo de un número.
- absolute: Calcula el valor absoluto de un número.
Instrucciones de comparación
Comparan dos valores y modifican los "flags" para indicar el resultado (por ejemplo, si son iguales o si uno es mayor). Suelen usarse antes de una instrucción que decide si saltar o no a otra parte del programa.
Ejemplos:
- compare: Resta dos valores, pero solo modifica los "flags" sin guardar el resultado.
- test: Compara un valor con cero.
Instrucciones lógicas
Realizan operaciones lógicas "bit a bit" (como AND, OR, XOR, NOT) entre dos datos. También modifican los "flags".
Ejemplos:
- and: El "y" lógico.
- or: El "o inclusivo" lógico.
- xor: El "o exclusivo" lógico.
- not: La negación lógica (cambia 0 por 1 y 1 por 0).
Instrucciones de desplazamiento
Mueven los bits de un número hacia la izquierda o la derecha. Pueden ser aritméticas (manteniendo el signo) o lógicas (rellenando con ceros).
Ejemplos:
- shift: Desplazamiento aritmético o lógico.
- rotate: Rotación (los bits que salen por un lado entran por el otro).
Instrucciones de bits
Permiten revisar un bit específico de un dato, ponerlo a 0 o a 1, o cambiarlo.
Ejemplos:
- bit test: Comprueba el valor de un bit.
- bit clear: Comprueba un bit y lo pone a 0.
- bit set: Comprueba un bit y lo pone a 1.
Instrucciones de control
Cambian el orden normal en que se ejecutan las instrucciones de un programa.
Saltos
Pueden ser:
- Incondicionales: Siempre saltan a otra parte del programa.
- Ejemplos: jump o branch.
- Condicionales: Saltan solo si se cumple una condición.
- Ejemplos: jcond o bcond (donde "cond" indica la condición).
Llamadas a subrutinas
Permiten ejecutar bloques de código que se usan varias veces (funciones o subrutinas).
Ejemplos:
- call: Llama a una subrutina.
- ret: Regresa de una subrutina al punto donde fue llamada.
Gestión de interrupciones
Se usan para manejar eventos especiales (interrupciones) que pueden detener temporalmente el programa principal para atender algo urgente (como una tecla presionada).
Instrucciones de entrada y salida (E/S)
Estas instrucciones permiten a la CPU comunicarse con dispositivos externos, como el teclado, el ratón, la pantalla o una impresora.
Pueden ser:
- E/S "mapeada" en memoria: Los dispositivos se ven como si fueran parte de la memoria, y se usan las mismas instrucciones de movimiento de datos.
- E/S independiente: Se necesitan instrucciones especiales para indicar que se está hablando con un dispositivo de E/S.
Ejemplos:
- input o read: Lee información de un dispositivo y la lleva a la memoria.
- output o write: Envía información a un dispositivo.
Instrucciones de control y misceláneas
Otras instrucciones que controlan el funcionamiento general de la CPU.
Ejemplos:
- halt: Detiene la ejecución del programa hasta que un evento externo lo reinicia.
- wait: Detiene el programa hasta que ocurre un evento específico.
- nop: No hace nada. Se usa para rellenar espacios o para crear pequeñas pausas.
- enable: Activa las interrupciones.
- disable: Desactiva las interrupciones.
- test and set: Se usa para asegurar que solo un procesador a la vez pueda acceder a un recurso compartido, como una parte de la memoria.
Véase también
En inglés: Instruction set Facts for Kids