Codigo cosido

El código enhebrado es una de las formas de implementar una máquina virtual  intermedia al interpretar lenguajes de programación (junto con bytecode ). Ocasionalmente, el término código reticulado también se encuentra en la literatura .

La representación principal del programa cuando se usa código enhebrado es una matriz de llamadas a subrutinas . La implementación del código enhebrado, la forma en que se almacenan estas llamadas puede ser diferente. Este código puede ser procesado por un intérprete (que se conoce como intérprete de direcciones ), o puede ser una simple secuencia de instrucciones de máquina que llama a una subrutina. Algún conjunto de subrutinas básicas de una máquina virtual que utiliza código de subprocesos se implementa como subrutinas escritas en código de máquina ordinario .

El código enhebrado se conoce más comúnmente como una técnica utilizada en la implementación de Forth . Sin embargo, también se usó en la implementación del lenguaje de programación B (precursor de C ). A veces también se usa en la implementación de BASIC , COBOL y otros lenguajes de programación.

Funciones de código enhebrado

El código cosido es relativamente compacto en comparación con el código máquina. Esta ventaja viene a costa de cierta desaceleración. Sin embargo, aquí entra en juego un efecto sinérgico  : a veces, un código compacto es más pequeño y notablemente más rápido que un código normal sin subprocesos [1] . Un programa lo suficientemente pequeño como para caber completamente en la RAM se ejecutará más rápido que un programa que usa memoria virtual, lo que implica la paginación desde el disco duro. De manera similar, un programa que cabe completamente en la memoria caché del procesador se ejecutará más rápido .

Tipos de código cosido

Código de subrutina

Este tipo de código enhebrado no es esencialmente diferente del código de máquina . Esta es una secuencia de llamadas a subrutinas ya compiladas.

El programa se ve así:

llamadaSub1; llamadaSub2; llamarSub3;


Código cosido directo

Este código se obtiene de la subrutina si se eliminan las llamadas a llamada del código. Solo las direcciones de las subrutinas permanecen en el cuerpo del código. La llamada a las subrutinas se lleva a cabo utilizando el intérprete de direcciones más simple, que ocupa varias instrucciones de máquina (en algunas arquitecturas de procesador, una).

intérprete de llamadas; Subdirección1; Subdirección2; ... direcciónSALIR; ... ... Intérprete: código máquina, SIGUIENTE ... Sub...: código máquina, SIGUIENTE ... SALIR: código máquina, SIGUIENTE

En el código de subprocesos directos, cualquier definición (por ejemplo, Sub) comienza con el código de máquina. El intérprete debe almacenar en la pila de retorno el valor pasado del contador de instrucciones (esto no es PC, ni IP, sino otro que se mueve a través del código Forth) y hacer que su dirección de retorno sea actual. Ahora se convertirá en el nuevo puntero al código Forth. Algunas versiones de Intel x86 utilizan el registro SI. Al leer datos en una dirección indirecta en este registro, su valor cambia automáticamente.

NEXT es la secuencia utilizada en lugar de return. Si completamos Sub1, entonces NEXT accede al contador de instrucciones Forth, lo cambia al tamaño del código y, en el siguiente paso, ya se ejecuta la primera instrucción de máquina de Sub2. La velocidad de transición no es peor que la de un par de comandos de devolución de llamada. Pero la transición NEXT en un procesador especializado se puede ejecutar como una sola instrucción.

SALIR - restaura el valor anterior del contador del programa y salta a la dirección correspondiente.

Código subproceso indirecto

Se diferencia del código subproceso directo en que el cuerpo del código no comienza con una llamada al intérprete, sino con la dirección donde se encuentra el intérprete.

Interpretador de direcciones; Subdirección1; Subdirección2; ... direcciónSALIR; ... ... Intérprete: dirección de código de máquina, código de máquina, NEXT ... Sub...: dirección de código de máquina, código de máquina, SIGUIENTE ... SALIR: dirección de código de máquina, código de máquina, SIGUIENTE

Código cosido enrollado

Puede, por ejemplo, usarse para reducir el tamaño del código cuando es de importancia crítica. Puede ser tanto directo como indirecto. En lugar de direcciones directas de subrutinas y códigos, utiliza sus pliegues que, por lo general, son más cortos que estas direcciones. Usando códigos de 2 bytes, puede usar un espacio de direcciones de más de 64 kilobytes.

Entonces, si sabemos que el código y los datos están alineados en relación con el tamaño de algún segmento (por ejemplo, 16 bytes), podemos usar la dirección física dividida por 16 como la dirección doblada.

En algunos casos, se puede usar una tabla de direcciones para doblar. El código cosido es la posición de la dirección en la tabla. El intérprete lee este código de la tabla y salta a la dirección adecuada.

El código de bytes se puede considerar como un caso especial de código plegado con una tabla de direcciones.

Notas

  1. Velocidad de varias técnicas de envío de intérpretes V2

Literatura y referencias