Asignar o ajustar direcciones en tiempo de ejecución
La reubicación es el proceso de asignar direcciones de carga para código y datos dependientes de la posición de un programa y ajustar el código y los datos para reflejar las direcciones asignadas. [1] [2] Antes de la llegada de los sistemas multiproceso, y todavía en muchos sistemas integrados, las direcciones de los objetos son absolutas comenzando en una ubicación conocida, a menudo cero. Dado que los sistemas multiprocesamiento se vinculan y cambian dinámicamente entre programas, se hizo necesario poder reubicar objetos utilizando código independiente de la posición . Un enlazador generalmente realiza la reubicación junto con la resolución de símbolos , el proceso de búsqueda de archivos y bibliotecas para reemplazar referencias simbólicas o nombres de bibliotecas con direcciones utilizables reales en la memoria antes de ejecutar un programa.
La reubicación normalmente la realiza el enlazador en el momento del enlace , pero también puede realizarse en el momento de la carga mediante un cargador que la reubica , o en el momento de la ejecución mediante el propio programa que se está ejecutando . Algunas arquitecturas evitan la reubicación por completo al posponer la asignación de direcciones al momento de la ejecución; como, por ejemplo, en máquinas de pila con aritmética de direcciones cero o en algunas arquitecturas segmentadas donde cada unidad de compilación se carga en un segmento separado.
La tabla de reubicación es una lista de punteros creada por el traductor (un compilador o ensamblador ) y almacenada en el objeto o archivo ejecutable. Cada entrada en la tabla, o "corrección", es un puntero a una dirección absoluta en el código objeto que debe cambiarse cuando el cargador reubica el programa para que haga referencia a la ubicación correcta. Las correcciones están diseñadas para admitir la reubicación del programa como una unidad completa. En algunos casos, cada corrección en la tabla es en sí misma relativa a una dirección base de cero, por lo que las correcciones en sí mismas deben cambiarse a medida que el cargador se mueve a través de la tabla. [2]
En algunas arquitecturas, una corrección que cruza ciertos límites (como un límite de segmento) o que no está alineada con un límite de palabra es ilegal y el enlazador la marca como un error. [3]
En cambio, los segmentos son valores relativos en el archivo EXE de DOS. Estos segmentos deben corregirse cuando el ejecutable se ha cargado en la memoria. El cargador de EXE utiliza una tabla de reubicación para encontrar los segmentos que deben ajustarse.
Windows de 32 bits
Con sistemas operativos Windows de 32 bits, no es obligatorio proporcionar tablas de reubicación para archivos EXE, ya que son la primera imagen cargada en el espacio de direcciones virtuales y, por lo tanto, se cargarán en su dirección base preferida.
Al ejecutar binarios nativos de 64 bits en Windows Vista y superiores, ASLR es obligatorio [ cita requerida ] y, por lo tanto, el compilador no puede omitir las secciones de reubicación.
Sistemas tipo Unix
El formato ejecutable y enlazable (ELF) y el formato de biblioteca compartida utilizados por la mayoría de los sistemas tipo Unix permiten definir varios tipos de reubicación. [4]
Procedimiento de reubicación
El enlazador lee la información del segmento y las tablas de reubicación en los archivos de objeto y realiza la reubicación mediante:
fusionar todos los segmentos de tipo común en un solo segmento de ese tipo
asignar direcciones de tiempo de ejecución únicas a cada sección y a cada símbolo, dando a todos los códigos (funciones) y datos (variables globales) direcciones de tiempo de ejecución únicas [ aclaración necesaria ]
haciendo referencia a la tabla de reubicación para modificar [ ¿por qué? ] las referencias de símbolos para que apunten a las [ aclaración necesaria ] direcciones de tiempo de ejecución correctas.
Ejemplo
El siguiente ejemplo utiliza la arquitectura MIX de Donald Knuth y el lenguaje ensamblador MIXAL. Los principios son los mismos para cualquier arquitectura, aunque los detalles pueden cambiar.
(A) El programa SUBR se compila para producir el archivo de objeto (B), que se muestra como código de máquina y ensamblador. El compilador puede iniciar el código compilado en una ubicación arbitraria, a menudo la ubicación 1, como se muestra. La ubicación 13 contiene el código de máquina para la instrucción de salto a la instrucción ST en la ubicación 5.
(C) Si SUBR se vincula posteriormente con otro código, se puede almacenar en una ubicación distinta de 1. En este ejemplo, el enlazador lo coloca en la ubicación 120. La dirección en la instrucción de salto, que ahora está en la ubicación 133, se debe reubicar para apuntar a la nueva ubicación del código para la instrucción ST , ahora 125. [1 61 que se muestra en la instrucción es la representación del código de máquina MIX de 125].
(D) Cuando el programa se carga en la memoria para ejecutarse, puede cargarse en una ubicación distinta a la asignada por el enlazador. Este ejemplo muestra que SUBR ahora está en la ubicación 300. La dirección en la instrucción de salto, ahora en 313, necesita reubicarse nuevamente para que apunte a la ubicación actualizada de ST , 305. [4 49 es la representación de la máquina MIX de 305].
^ "Tipos de código de objeto". Manual de referencia del cargador de aplicaciones iRMX 86 (PDF) . Intel . págs. 1-2–1-3. Archivado (PDF) del original el 2020-01-11 . Consultado el 2020-01-11 . […] El código absoluto y un módulo de objeto absoluto son códigos que han sido procesados por LOC86 para ejecutarse solo en una ubicación específica de la memoria. El cargador carga un módulo de objeto absoluto solo en la ubicación específica que debe ocupar el módulo. El código independiente de la posición (comúnmente conocido como PIC) se diferencia del código absoluto en que el PIC se puede cargar en cualquier ubicación de memoria. La ventaja del PIC sobre el código absoluto es que el PIC no requiere que reserve un bloque específico de memoria. Cuando el cargador carga el PIC, obtiene segmentos de memoria iRMX 86 del grupo del trabajo de la tarea que realiza la llamada y carga el PIC en los segmentos. Una restricción que afecta a PIC es que, como en el modelo de segmentación PL/M-86 COMPACT […], puede tener solo un segmento de código y un segmento de datos, en lugar de dejar que las direcciones base de estos segmentos, y por lo tanto los segmentos mismos, varíen dinámicamente. Esto significa que los programas PIC tienen necesariamente menos de 64K bytes de longitud. El código PIC se puede producir por medio del control BIND de LINK86. El código localizable en tiempo de carga (comúnmente conocido como código LTL) es la tercera forma de código objeto. El código LTL es similar a PIC en que el código LTL se puede cargar en cualquier lugar de la memoria. Sin embargo, al cargar código LTL, el cargador cambia la parte base de los punteros para que los punteros sean independientes del contenido inicial de los registros en el microprocesador. Debido a esta corrección (ajuste de las direcciones base), el código LTL se puede utilizar en tareas que tienen más de un segmento de código o más de un segmento de datos. Esto significa que los programas LTL pueden tener más de 64K bytes de longitud. FORTRAN 86 y Pascal 86 generan automáticamente código LTL, incluso para programas cortos. El código LTL se puede generar mediante el control BIND de LINK86. […]
^ ab Levine, John R. (2000) [octubre de 1999]. "Capítulo 1: Enlaces y cargas y Capítulo 3: Archivos de objetos". Enlaces y cargadores. La serie Morgan Kaufmann sobre ingeniería de software y programación (1.ª ed.). San Francisco, California, EE. UU.: Morgan Kaufmann . p. 5. ISBN1-55860-496-0. OCLC 42413382. Archivado desde el original el 5 de diciembre de 2012. Consultado el 12 de enero de 2020 .Código: [1][2] Erratas: [3]
^ Borland (1999-09-01) [1998-07-02]. "Artículo de Borland n.º 15961: Cómo lidiar con los mensajes de 'Desbordamiento de reparación'". community.borland.com . Base de datos de información técnica - Producto: Borland C++ 3.1. TI961C.txt n.º 15961. Archivado desde el original el 7 de julio de 2008 . Consultado el 15 de enero de 2007 .
^ "Formato ejecutable y enlazable (ELF)" (PDF) . skyfree.org . Especificación de formatos portátiles de Tool Interface Standards (TIS), versión 1.1. Archivado (PDF) desde el original el 24 de diciembre de 2019 . Consultado el 1 de octubre de 2018 .
Lectura adicional
Johnson, Glenn (1975-12-21) [1975-11-13]. 11/34 Prueba de lógica básica de gestión de memoria. Digital Equipment Corporation (DEC). MAINDEC-11-DFKTA-AD . Consultado el 19 de agosto de 2017 .
Formaniak, Peter G.; Leitch, David (julio de 1977). "A Proposed Microprocessor Software Standard" (Un estándar de software para microprocesadores propuesto). BYTE - la revista de sistemas pequeños . Technical Forum. Vol. 2, no. 7. Peterborough, New Hampshire, EE. UU.: Byte Publications, Inc. pp. 34, 62–63. ark:/13960/t32245485 . Consultado el 6 de diciembre de 2021 .(3 páginas) (NB. Describe un formato hexadecimal reubicable de Mostek ).
Ogdin, Carol Anne; Colvin, Neil; Pittman, Tom; Tubb, Philip (noviembre de 1977). "Formatos de código de objeto reubicables". BYTE - la revista de sistemas pequeños . Foro técnico. Vol. 2, núm. 11. Peterborough, New Hampshire, EE. UU.: Byte Publications, Inc. págs. 198–205. ark:/13960/t59c88b4h, ark:/13960/t3kw76j24 . Consultado el 6 de diciembre de 2021 .(8 páginas) (NB. Describe un formato hexadecimal reubicable por TDL ).
Kildall, Gary Arlen (febrero de 1978) [1976]. "Una técnica sencilla para la reubicación estática de código de máquina absoluto". Revista de calistenia y ortodoncia informática del Dr. Dobb . 3 (2). People's Computer Company : 10-13 (66-69). ISBN 0-8104-5490-4. #22 ark:/13960/t8hf1g21p . Consultado el 19 de agosto de 2017 .[4][5][6]. Presentado originalmente en: Kildall, Gary Arlen (1977) [22–24 de noviembre de 1976]. "Una técnica simple para la reubicación estática del código de máquina absoluto". Escrito en Naval Postgraduate School , Monterey, California, EE. UU. En Titus, Harold A. (ed.). Registro de la conferencia: Décima conferencia anual de Asilomar sobre circuitos, sistemas y computadoras: artículos presentados del 22 al 24 de noviembre de 1976. Conferencia de Asilomar sobre señales, sistemas y computadoras . Asilomar Hotel and Conference Grounds, Pacific Grove, California, EE. UU.: Western Periodicals Company. págs. 420–424. ISSN 1058-6393 . Consultado el 6 de diciembre de 2021 .(609 páginas). (Este método de "redimensionamiento", llamado reubicación de límites de página , podría aplicarse estáticamente a una imagen de disco CP/M-80 usando MOVCPM [pl] para maximizar el TPA para que se ejecuten los programas. También fue utilizado dinámicamente por el depurador CP/M Dynamic Debugging Tool (DDT) para reubicarse a sí mismo en una memoria superior. El mismo enfoque fue desarrollado independientemente por Bruce H. Van Natta de IMS Associates para producir código PL/M reubicable . Como reubicación de límites de párrafo , otra variante de este método fue utilizada más tarde por los TSR auto-reubicantes HMA dinámicos como KEYB , SHARE y NLSFUNC bajo DR DOS 6.0 y superiores. Un método mucho más sofisticado y granular a nivel de bytes basado en un enfoque algo similar fue concebido e implementado independientemente por Matthias R. Paul y Axel C. Frinke para su eliminación dinámica de código muerto para minimizar dinámicamente la huella de tiempo de ejecución de los controladores residentes y los TSR (como FreeKEYB).)
Mossip, Richard H. (septiembre-octubre de 1980). Escrito en Bloomingdale, Nueva Jersey, EE. UU. "Relocatable Code" (PDF) . S-100 Microsystems . Vol. 1, no. 5. Mountainside & Springfield, Nueva Jersey, EE. UU.: Libes, Inc. págs. 54-55. ISSN 0199-7955. ark:/13960/s2cfgkmxcwg. ark:/13960/s2qdm1t01nr. Archivado (PDF) desde el original el 27 de noviembre de 2023 . Consultado el 27 de noviembre de 2023 .[7][8] (2 páginas) (NB. Describe la reubicación de los límites de página y la reubicación de ensambladores).
Huitt, Robert; Eubanks, Gordon ; Rolander, Thomas "Tom" Alan ; Laws, David; Michel, Howard E.; Halla, Brian; Wharton, John Harrison ; Berg, Brian; Su, Weilian; Kildall, Scott ; Kampe, Bill (2014-04-25). Laws, David (ed.). "Legacy of Gary Kildall: The CP/M IEEE Milestone Dedication" (PDF) (transcripción del vídeo). Pacific Grove, California, EE. UU.: Computer History Museum . Número de referencia del CHM: X7170.2014. Archivado (PDF) desde el original el 2014-12-27 . Consultado el 2020-01-19 . […] Laws: […] "reubicación dinámica" del SO. ¿Puede decirnos qué es eso y por qué era importante? […] Eubanks : […] lo que hizo Gary […] fue […] alucinante. […] Recuerdo el día en la escuela que entró de golpe al laboratorio y dijo: “He descubierto cómo reubicar”. Aprovechó el hecho de que el único byte siempre iba a ser el byte de orden superior . Y así creó un mapa de bits . […] No importaba cuánta memoria tuviera la computadora, el sistema operativo siempre podía ser movido a la memoria superior. Por lo tanto, se podía comercializar esto […] en máquinas con diferentes cantidades de memoria. […] No se podía vender un CP/M de 64K y un CP/M de 47K. Sería ridículo tener una compilación difícil en las direcciones. Así que Gary se dio cuenta de esto una noche, probablemente en medio de la noche pensando en algo de codificación, y esto realmente hizo que CP/M fuera posible comercializar. Realmente creo que sin esa reubicación habría sido un problema muy difícil. Hacer que la gente lo compre les parecería complicado, y si añadías más memoria tendrías que conseguir un sistema operativo diferente. […] Intel […] tenía los bytes invertidos , ¿no?, para las direcciones de memoria. Pero siempre estaban en el mismo lugar, por lo que se podían reubicar en un límite de 256 bytes , para ser precisos. Por lo tanto, siempre se podía reubicar con solo un mapa de bits de dónde estaban esos […] Leyes: Sin duda, la explicación más elocuente que he tenido sobre la reubicación dinámica […][9][10] (33 páginas)
Liberer, Eckhard; Von Massenbach, Thomas (1987). "CP/M 2 lernt dazu. Modulare Systemerweiterungen auch für das 'alte' CP/M". c't - magazin für computertechnik (parte 1) (en alemán). 1987 (1). Heise Verlag : 124-135; Liber, Eckhard; Von Massenbach, Thomas (1987). "CP/M 2 lernt dazu. Modulare Systemerweiterungen auch für das 'alte' CP/M". c't - magazin für computertechnik (parte 2) (en alemán). 1987 (2). Heise Verlag : 78–85; Huck, Alex (9 de octubre de 2016). «RSM für CP/M 2.2». Homecomputer DDR (en alemán). Archivado desde el original el 25 de noviembre de 2016. Consultado el 25 de noviembre de 2016 .
Guzis, Charles "Chuck" P. (16 de marzo de 2015). "Re: Programación en lenguaje ensamblador CP/M". Vintage Computer Forum . Género: CP/M y MP/M. Archivado desde el original el 1 de febrero de 2020 . Consultado el 1 de febrero de 2020 . […] ¿Alguna vez se preguntó cómo funciona MOVCPM [pl] ? Dado que BDOS y CCP están en la memoria alta, por encima de la aplicación del usuario, las direcciones deben cambiarse cada vez que se cambia el tamaño de la memoria del sistema. Ahora bien, eso requiere reubicar direcciones en el código 8080 , ya que el direccionamiento relativo no es parte del hardware. Sin implementar un ensamblador y un cargador reubicables completos, ¿cómo se hace esto? En realidad, es bastante inteligente y MP/M incluso usa este esquema para construir sus archivos reubicables en páginas. Simplemente ensambla el programa fuente dos veces con el segundo origen de ensamblaje 100H (256 bytes) más alto que el primero. Luego se comparan las dos imágenes binarias, byte por byte, y se construye un mapa de los pares de bytes que difieren en valor exactamente en 100H. El resultado es una lista de ubicaciones donde se debe ajustar el valor de reubicación si se debe mover la ubicación de un programa en la memoria. MP/M llama a este tipo de archivo PRL (página reubicable), pero no sé si CP/M 2.2 acuñó alguna vez un nombre para ello. […]
Guzis, Charles "Chuck" P. (2015-07-29). "Re: ¿Cómo funciona MOVCPM.COM?". Vintage Computer Forum . Género: CP/M y MP/M. Archivado desde el original el 2020-02-01 . Consultado el 2020-02-01 . […] MOVCPM [pl] utiliza un tipo temprano de formato PRL. Básicamente, CP/M se ensambla dos veces; la segunda vez tiene un desplazamiento de 100H bytes. Se comparan los dos binarios y se construye un mapa de bits . Un bit establecido implica que se debe ajustar el byte de orden superior de una dirección. Los bytes de dirección de orden inferior no se ven afectados; por lo tanto, "archivo reubicable de página". Cada byte en el mapa de bits corresponde a 8 bytes en los datos binarios. […] Por lo tanto, todo lo que se va a mover en MOVCPM es parte de la imagen y su mapa de bits de reubicación. […]
Guzis, Charles "Chuck" P. (8 de noviembre de 2016). "Re: ¿Es seguro usar RST 28h en programas ensambladores CP/M?". Vintage Computer Forum . Género: CP/M y MP/M. Archivado desde el original el 1 de febrero de 2020 . Consultado el 1 de febrero de 2020 . […] He hecho referencia a los archivos PRL y cómo comenzaron originalmente con MOVCPM [pl] , pero se convirtieron en una parte integral de MP/M y CP/M 3.0 . Pero los archivos PRL usan un mapa de bits en el que cada bit corresponde a una ubicación de memoria; un bit indica que se debe agregar un desplazamiento de reubicación de página a la ubicación de memoria correspondiente. Si tiene muy pocas referencias de memoria absolutas (a diferencia de las relativas), es posible que desee emplear una lista de punteros (2 bytes por referencia) en lugar de un mapa de bits. Es poco probable que esto ocurra en el código 8080 , que no tiene saltos relativos, pero puede ser un factor a tener en cuenta en el código Z80 . El truco para averiguarlo rápidamente es ensamblar el programa dos veces; la segunda vez con un desfase de 100H, y luego comparar los dos binarios. La ventaja de la reubicación en tiempo de ejecución es que no hay que incurrir en penalizaciones por el código que intenta evitar el problema de la reubicación: no hay "trucos"; simplemente se escribe código directo. […]
Calingaert, Peter (1979) [1978-11-05]. "8.2.2 Reubicación del cargador". Escrito en la Universidad de Carolina del Norte en Chapel Hill . En Horowitz, Ellis (ed.). Ensambladores, compiladores y traducción de programas . Serie de ingeniería de software informático (1.ª impresión, 1.ª ed.). Potomac, Maryland, EE. UU.: Computer Science Press, Inc., págs. 237–241. ISBN 0-914894-23-4. ISSN 0888-2088. LCCN 78-21905 . Consultado el 20 de marzo de 2020 .(2+xiv+270+6 páginas)
Formato de archivo OBJ de Microsoft. Microsoft , Servicios de soporte técnico de productos. Nota de aplicación SS0288. Archivado desde el original el 9 de septiembre de 2017. Consultado el 21 de agosto de 2017 .
Elliott, John C. (5 de junio de 2012) [2 de enero de 2000]. «Formato de archivo PRL». seasip.info . Archivado desde el original el 26 de enero de 2020 . Consultado el 26 de enero de 2020 . […] Un archivo PRL es un archivo binario reubicable, utilizado por MP/M y CP/M Plus para varios módulos distintos de los archivos .COM . El formato de archivo también se utiliza para archivos FID en Amstrad PCW . Hay varios formatos de archivo que utilizan versiones de PRL: SPR (System PRL), RSP (Resident System Process). LINK-80 también puede producir archivos OVL ( overlay ), que tienen un encabezado PRL pero no son reubicables. Los controladores GSX están en formato PRL; también lo son las extensiones de sistema residentes (.RSX). […][11]
Elliott, John C. (5 de junio de 2012) [2 de enero de 2000]. «Formato REL de Microsoft». seasip.info . Archivado desde el original el 26 de enero de 2020 . Consultado el 26 de enero de 2020 . […] El formato REL lo generan M80 de Microsoft y RMAC de Digital Research . […]
feilipu (2018-09-05) [2018-09-02]. "Compatibilidad con PRL, ejecutable reubicable en página para MP/M". z88dk . Archivado desde el original el 2020-02-01 . Consultado el 2020-01-26 . […] A partir de los archivos .REL de Microsoft ensamblados , el enlazador tiene que generar un ejecutable en formato .PRL para MP/M . El formato .PRL es esencialmente un archivo .COM con información adicional para permitir que el programa y sus datos se reubiquen en cualquier página. ¿Cómo se ve un archivo .PRL? Los primeros bytes son el tamaño del programa, seguido del origen del programa en 0x0100. Después del programa, hay una máscara bit por byte adjunta para permitir que el sistema MP/M sepa qué bytes del programa deben cambiarse cuando se reubica el programa. ¿Cómo hace el enlazador eso sin desarmar toda la aplicación? De antemano, el programa está vinculado a dos orígenes diferentes, 0x0100 y 0x0200, desde los objetos .REL. El truco del vinculador consiste simplemente en reconocer qué bytes difieren en las dos versiones del ejecutable. Estos bytes se registran en la máscara de bits almacenada después del ejecutable, y el programa .PRL final está diseñado para ejecutarse desde 0x0100 más su desplazamiento de página. El mismo truco se realiza para los archivos ejecutables .RSP y .SPR, excepto que ambos formatos renuncian al desplazamiento y se ejecutan desde 0x0000 más su desplazamiento de página. […]
Brothers, Hardin (abril de 1983). "Entender el código reubicable". 80 Micro . El siguiente paso (39). 1001001, Inc .: 38, 40, 42, 45. ISSN 0744-7868 . Consultado el 6 de febrero de 2020 .[12][13]
Brothers, Hardin (abril de 1985). "Programas reubicables: los vagabundos de la microinformática". 80 Micro . El siguiente paso (63). CW Communications/Peterborough, Inc. : 98, 100, 102–103. ISSN 0744-7868 . Consultado el 6 de febrero de 2020 .[14][15]
Sage, Jay (mayo-junio de 1988). Carlson, Art (ed.). "ZCPR 3.4 - Programas de tipo 4". The Computer Journal (TCJ) - Programación, soporte al usuario, aplicaciones . ZCPR3 Corner (32). Columbia Falls, Montana, EE. UU.: 10-17 [15-16]. ISSN 0748-9331. ark:/13960/t1wd4v943 . Consultado el 29 de noviembre de 2021 .[16][17]
Mitchell, Bridger (julio-agosto de 1988). Carlson, Art (ed.). "Z3PLUS y reubicación: información sobre ZCPR3PLUS y cómo escribir código Z80 autoreubicable". The Computer Journal (TCJ): programación, asistencia al usuario, aplicaciones . Advanced CP/M (33). Columbia Falls, Montana, EE. UU.: 9-15. ISSN 0748-9331. ark:/13960/t36121780 . Consultado el 9 de febrero de 2020 .[18][19]
Sage, Jay (septiembre-octubre de 1988). Carlson, Art (ed.). "Más sobre código reubicable, archivos PRL, ZCPR34 y programas de tipo 4". The Computer Journal (TCJ) - Programación, soporte al usuario, aplicaciones . ZCPR3 Corner (34). Columbia Falls, Montana, EE. UU.: 20-25. ISSN 0748-9331. ark:/13960/t0ks7pc39 . Consultado el 9 de febrero de 2020 .[20][21][22]
Sage, Jay (enero-febrero de 1992). Carlson, Art; McEwen, Chris (eds.). "Diez años de ZCPR". The Computer Journal (TCJ) - Programación, soporte al usuario, aplicaciones . Z-System Corner (54). S. Plainfield, Nueva Jersey, EE. UU.: Socrates Press: 3–7. ISSN 0748-9331. ark:/13960/t89g6n689 . Consultado el 29 de noviembre de 2021 .[23][24][25]
Sage, Jay (mayo-junio de 1992) [marzo-junio de 1992]. Carlson, Art; McEwen, Chris (eds.). "Programas de tipo 3 y tipo 4". The Computer Journal (TCJ) - Programación, soporte al usuario, aplicaciones . Z-System Corner - Algunas nuevas aplicaciones de programas de tipo 4 (55). S. Plainfield, Nueva Jersey, EE. UU.: Socrates Press: 13-19. ISSN 0748-9331. ark:/13960/t4dn54d22 . Consultado el 29 de noviembre de 2021 .[26][27]
Ganssle, Jack (febrero de 1992). "Writing Relocatable Code - Some built-in code must run at more than one address" (Escritura de código reubicable: algunos códigos integrados deben ejecutarse en más de una dirección). Embedded Systems Programming (Programación de sistemas integrados). The Ganssle Group - Perfecting the Art of Building Embedded Systems (El grupo Ganssle: perfeccionando el arte de construir sistemas integrados) / TGG. Archivado desde el original el 18 de julio de 2019. Consultado el 20 de febrero de 2020 .