Entonces sé cuáles se supone que son los siguientes registros y sus usos:
CS = Segmento de código (utilizado para IP)
DS = segmento de datos (utilizado para MOV)
ES = Segmento de destino (utilizado para MOVS, etc.)
SS = Segmento de pila (usado para SP)
Pero, ¿para qué están destinados los siguientes registros?
FS = "Segmento de archivo"?
GS = ???
Nota: Estoy no preguntar sobre cualquier sistema operativo en particular - Me estoy preguntando por lo que estaban destinados a ser utilizados por la CPU, en todo caso.
assembly
x86
cpu-architecture
cpu-registers
memory-segmentation
usuario541686
fuente
fuente
Respuestas:
Hay para qué fueron diseñados, y para qué los utilizan Windows y Linux.
La intención original detrás de los registros de segmento era permitir que un programa acceda a muchos segmentos diferentes (grandes) de memoria que estaban destinados a ser independientes y formar parte de una tienda virtual persistente. La idea se tomó del sistema operativo Multics de 1966 , que trataba los archivos como simples segmentos de memoria direccionables. No BS "Abrir archivo, escribir registro, cerrar archivo", simplemente "Almacenar este valor en ese segmento de datos virtuales" con eliminación de páginas sucias.
Nuestros sistemas operativos actuales de 2010 son un paso gigantesco hacia atrás, por eso se les llama "Eunucos". Solo puede abordar el segmento único de su espacio de proceso, lo que proporciona un "espacio de direcciones plano (en mi humilde opinión)". Los registros de segmento en la máquina x86-32 aún se pueden usar para registros de segmento reales, pero nadie se ha molestado (Andy Grove, ex presidente de Intel, tuvo un ataque público bastante famoso el siglo pasado cuando se dio cuenta después de que todos esos ingenieros de Intel gastaron energía y su dinero para implementar esta función, que nadie iba a usarla. ¡Ve, Andy!)
AMD, al pasar a 64 bits, decidió que no les importaba si eliminaban Multics como opción (esa es la interpretación caritativa; la poco caritativa es que no tenían ni idea de Multics) y, por lo tanto, deshabilitó la capacidad general de los registros de segmento en el modo de 64 bits. Todavía existía la necesidad de que los subprocesos accedan a la tienda local de subprocesos, y cada subproceso necesitaba un puntero ... en algún lugar del estado de subproceso inmediatamente accesible (por ejemplo, en los registros) ... para el almacén local de subprocesos. Dado que Windows y Linux usaron FS y GS (gracias Nick por la aclaración) para este propósito en la versión de 32 bits, AMD decidió permitir que los registros de segmento de 64 bits (GS y FS) se usaran esencialmente solo para este propósito (creo que puede hágalos apuntar a cualquier lugar de su espacio de proceso; no sé si el código de la aplicación puede cargarlos o no).
Hubiera sido arquitectónicamente más bonito en mi humilde opinión hacer que el mapa de memoria de cada hilo tuviera una dirección virtual absoluta (por ejemplo, 0-FFF digamos) que era su almacenamiento local del hilo (¡no se necesita un puntero de registro [segmento]!); Hice esto en un sistema operativo de 8 bits en la década de 1970 y fue extremadamente útil, como tener otra gran pila de registros para trabajar.
Entonces, los registros de segmento ahora son como su apéndice. Tienen un propósito vestigial. Para nuestra pérdida colectiva.
Los que no conocen la historia no están condenados a repetirla; están condenados a hacer algo más tonto.
fuente
Los registros
FS
yGS
son registros de segmento. No tienen un propósito definido por el procesador, sino que el sistema operativo que los ejecuta les da un propósito. En Windows de 64 bits, elGS
registro se utiliza para señalar las estructuras definidas por el sistema operativo.FS
yGS
son comúnmente utilizados por los núcleos del sistema operativo para acceder a la memoria específica de subprocesos. En Windows, elGS
registro se usa para administrar la memoria específica de subprocesos. El kernel de Linux utilizaGS
para acceder a la memoria específica de la CPU.fuente
*dest++ = lookup[*src++];
lo que de otra manera sería bastante incómodo si dest, lookup y src estuvieran en tres ubicaciones no relacionadas?FS se utiliza para señalar el bloque de información de subprocesos (TIB) en los procesos de Windows.
un ejemplo típico es ( SEH ) que almacena un puntero a una función de devolución de llamada en
FS:[0x00]
.GS se usa comúnmente como un puntero a un almacenamiento local de subprocesos (TLS). y un ejemplo que puede haber visto antes es la protección canary de pila (stackguard), en gcc puede ver algo como esto:
fuente
Según el Manual de Intel, en el modo de 64 bits, estos registros están pensados para usarse como registros base adicionales en algunos cálculos de direcciones lineales. Saqué esto de la sección 3.7.4.1 (p. 86 en el conjunto de 4 volúmenes). Por lo general, cuando la CPU está en este modo, la dirección lineal es la misma que la dirección efectiva, porque la segmentación a menudo no se usa en este modo.
Entonces, en este espacio de direcciones plano, FS y GS juegan un papel en el direccionamiento no solo de datos locales, sino de ciertas estructuras de datos del sistema operativo (pg 2793, sección 3.2.4), por lo que estos registros estaban destinados a ser utilizados por el sistema operativo, sin embargo, esos diseñadores particulares determinar.
Hay algunos trucos interesantes al usar anulaciones en los modos de 32 y 64 bits, pero esto implica software privilegiado.
Desde la perspectiva de las "intenciones originales", es difícil decir que son solo registros adicionales. Cuando la CPU está en modo de dirección real , es como si el procesador se estuviera ejecutando como un 8086 de alta velocidad y estos registros deben ser accedidos explícitamente por un programa. Por el bien de la verdadera emulación 8086, ejecutaría la CPU en modo virtual-8086 y estos registros no se utilizarían.
fuente
TL; DR;
Simplemente para acceder a datos más allá del segmento de datos predeterminado (DS). Exactamente como ES.
La lectura larga:
Bueno, casi, pero DS no es "algún" segmento de datos, sino el predeterminado. Todas las operaciones se realizaron de forma predeterminada (* 1). Aquí es donde se encuentran todas las variables predeterminadas, esencialmente
data
ybss
. De alguna manera, es parte de la razón por la que el código x86 es bastante compacto. Todos los datos esenciales, que es lo que se accede con mayor frecuencia (más el código y la pila) se encuentran a una distancia abreviada de 16 bits.ES se usa para acceder a todo lo demás (* 2), todo más allá de los 64 KiB de DS. Como el texto de un procesador de texto, las celdas de una hoja de cálculo o los datos de imagen de un programa de gráficos, etc. A diferencia de lo que se supone a menudo, no se accede tanto a estos datos, por lo que necesitar un prefijo duele menos que usar campos de dirección más largos.
Similar, es solo una molestia menor que DS y ES puedan tener que cargarse (y recargarse) al realizar operaciones de cadena; esto al menos se compensa con uno de los mejores conjuntos de instrucciones de manejo de caracteres de su tiempo.
Lo que realmente duele es cuando los datos del usuario superan los 64 KiB y las operaciones deben comenzar. Si bien algunas operaciones se realizan simplemente en un solo elemento de datos a la vez (piense
A=A*2
), la mayoría requiere dos (A=A*B
) o tres elementos de datos (A=B*C
). Si estos elementos residen en diferentes segmentos, ES se recargará varias veces por operación, agregando bastante sobrecarga.Al principio, con programas pequeños del mundo de 8 bits (* 3) y conjuntos de datos igualmente pequeños, no fue un gran problema, pero pronto se convirtió en un cuello de botella de rendimiento importante, y más aún en un verdadero dolor de cabeza para programadores (y compiladores). Con el 386 Intel finalmente entregó alivio al agregar dos segmentos más, por lo que cualquier operación unaria , binaria o ternaria en serie, con elementos esparcidos en la memoria, podría tener lugar sin tener que recargar ES todo el tiempo.
Para la programación (al menos en ensamblador) y el diseño del compilador, esto fue una gran ganancia. Por supuesto, podría haber habido aún más, pero con tres el cuello de la botella básicamente se había ido, así que no hay necesidad de exagerar.
Al nombrar las letras F / G son simplemente continuaciones alfabéticas después de E. Al menos desde el punto de vista del diseño de la CPU, no hay nada asociado.
* 1 - El uso de ES para el destino de cadenas es una excepción, ya que simplemente se necesitan dos registros de segmento. Sin ellos, no serían muy útiles, o necesitarían siempre un prefijo de segmento. Lo que podría matar una de las características sorprendentes, el uso de instrucciones de cadena (no repetitivas) que resultan en un rendimiento extremo debido a su codificación de un solo byte.
* 2 - Entonces, en retrospectiva, 'Segmento de todo lo demás' habría sido un nombre mucho mejor que 'Segmento adicional'.
* 3 - Siempre es importante tener en cuenta que el 8086 solo se pensó como una medida provisional hasta que el 8800 se terminó y estaba destinado principalmente al mundo integrado para mantener a los clientes del 8080/85 a bordo.
fuente