Lenguaje de máquina

El lenguaje de máquina o código de máquina , es una continuación de bits que es interpretada por el procesador de una computadora que ejecuta un programa de computadora . Es el idioma nativo de un procesador , es decir el único que puede procesar. Se compone de instrucciones codificadas en binario y datos a procesar .

Cada procesador tiene su propio lenguaje de máquina, incluido el código de máquina que solo se puede ejecutar en la máquina para la que ha sido preparado. Si un procesador A es capaz de ejecutar todas las instrucciones del procesador B , decimos que A es compatible con B . Lo contrario no es necesariamente cierto: A puede tener instrucciones adicionales que B no conoce.

El código de máquina ahora se genera automáticamente, generalmente por el compilador de un lenguaje de programación o mediante un código de bytes .

Instrucciones de idioma

Las "palabras" de un lenguaje de máquina se denominan instrucciones . Cada uno de ellos dispara un comando desde el procesador (por ejemplo: buscar un valor en la memoria para cargar un registro , agregar dos registros , etc.).

Un procesador con arquitectura RISC reconoce solo unas pocas instrucciones diferentes, mientras que un procesador con arquitectura CISC tiene una amplia gama. Sin embargo, algunos procesadores CISC recientes transforman internamente instrucciones complejas en una serie de instrucciones simples, que luego se ejecutan.

Un programa es solo una larga secuencia de instrucciones que ejecuta el procesador. Se ejecutan secuencialmente excepto cuando una instrucción de salto transfiere la ejecución a una instrucción diferente a la siguiente. También hay saltos condicionales que se ejecutan (la ejecución continúa en otra dirección) o se ignoran (la ejecución continúa en la siguiente instrucción) bajo ciertas condiciones.

Código de operación

Cada instrucción comienza con un número llamado código de operación (o código de operación ) que determina la naturaleza de la instrucción. Por ejemplo, para computadoras con arquitectura x86 , el código de operación 0x6A(en binario 01101010) corresponde a la instrucción push (agregue un valor en la parte superior de la pila ). Por lo tanto, la instrucción 0x6A 0x14( 01101010 00010100) coincide con push 0x14 (agregue el valor hexadecimal 0x14 , o el decimal 20, en la parte superior de la pila).

Longitud de las instrucciones

Algunos procesadores codifican todas sus instrucciones con el mismo número de bits (por ejemplo: ARM , MIPS , PowerPC ), mientras que para otros la longitud de la instrucción depende del código de operación (ejemplo: x86 ). La organización de las combinaciones de bits depende en gran medida del procesador. El más común es la división en campos . Uno o más campos especifican la operación exacta (por ejemplo, adición ). Los otros campos indican el tipo de operandos , su ubicación o un valor literal (los operandos contenidos en una instrucción se denominan inmediatos ).

Ventajas y desventajas

Cuando todas las instrucciones son del mismo tamaño, también se alinean en la memoria . Por ejemplo, si todas las instrucciones están alineadas en 32 bits (4 bytes), entonces los dos bits menos significativos de la dirección de memoria de cualquier instrucción están en cero. Esto permite, en particular, una implementación más fácil de la caché de predicciones de ramas bimodales .

Por otro lado, el código máquina ocupa menos espacio en memoria si no tiene un tamaño mínimo, ya que se eliminan los campos no utilizados.

Escribiendo el código

Si bien el lenguaje de máquina era el único disponible en los albores de las computadoras, hoy en día es muy largo y tedioso desarrollarlo en binario: hay que pasar por al menos un lenguaje intermedio.

Muchos lenguajes de programación se transforman en lenguaje de máquina durante la compilación . Todos los programas ejecutables contienen al menos una pequeña parte en lenguaje máquina.

El lenguaje más fácil de convertir a código de máquina es ensamblador porque tiene casi las mismas instrucciones. Ensamblador (o lenguaje ensamblador) difiere de una máquina a otra, aunque las instrucciones son, en última instancia, muy similares. Los idiomas de más alto nivel se traducen en ensamblador durante la compilación. Los idiomas que utilizan una máquina virtual pasan por un código de bytes que la máquina virtual convierte sobre la marcha.

Ejemplos de

Procesador MIPS

Como ejemplo específico, veamos la arquitectura MIPS . Sus instrucciones siempre tienen una longitud de 32 bits. El tipo general de instrucción viene dado por los 6 bits más significativos (en una representación de 32 bits, el 6 a la izquierda), que se denomina campo de operación .

Las instrucciones Tipo-J y Tipo-I están completamente especificadas por el campo de operación . Las instrucciones de tipo R tienen un campo adicional, funct , para determinar la naturaleza exacta de la operación. Los campos de estos 3 tipos de instrucciones son:

6 5 5 5 5 6 bits [ op | rs | rt | rd |shamt| fonct] type-R [ op | rs | rt | adresse/immédiat ] type-I [ op | adresse cible ] type-J

rs , rt y rd indican operandos de tipo de registro; shamt indica un cambio ( cantidad de cambio ); y la dirección o campo inmediato contiene un operando en forma de valor.

Por ejemplo, agregar los registros 1 y 2 y colocar el resultado en el registro 6 se codifica:

[ op | rs | rt | rd |shamt| fonct] 0 1 2 6 0 32 décimal 000000 00001 00010 00110 00000 100000 binaire

Cargue un valor de la celda de memoria 68 celdas después del que apunta el registro 3 en el registro 8:

[ op | rs | rt | adresse/immédiat ] 35 3 8 68 décimal 100011 00011 01000 0000000001000100 binaire

Saltar a la dirección 1025(la siguiente instrucción a ejecutar es en la dirección 1025):

[ op | adresse cible ] 2 1025 décimal 000010 00000000000000010000000001 binaire

Procesador ARM

Los procesadores de la arquitectura ARM son un caso especial en la medida en que todas las instrucciones son condicionales. Todos tienen 32 bits de longitud y sus primeros cuatro bits indican en qué condiciones se debe ejecutar la instrucción.

Ver también