Pregunta

Decidí aprender yo mismo el lenguaje ensamblador.

Me di cuenta de que mi programa no se compilará si intento cambiar el valor de cualquier registro de segmento.

Todos los artículos que he encontrado dicen que puedo cambiar el valor de al menos 4 registros de segmento, entonces, ¿qué pasa?

Realmente solo estoy interesado en el por qué en este momento, no tengo ningún propósito real al cambiar estas direcciones.

¿Fue útil?

Solución

Dijiste que estabas interesado en saber por qué, entonces:

En modo real, un segmento es una "ventana" de 64K para la memoria física y estas ventanas están espaciadas por 16 bytes.En modo protegido, un segmento es una ventana a la memoria física o virtual, cuyo tamaño y ubicación están determinados por el sistema operativo, y tiene muchas otras propiedades, incluido el nivel de privilegio que debe tener un proceso para acceder a él.

De aquí en adelante todo lo que digo se refiere al modo protegido.

Hay una tabla en la memoria llamada tabla de descriptores globales (GDT), que es donde se guarda la información sobre estos tamaños y ubicaciones de ventanas y otras propiedades.También puede haber tablas de descriptores locales por proceso, y funcionan de manera similar, por lo que solo me centraré en la GDT.

El valor que se carga en un registro de segmento se conoce como selector de segmento.Es un índice de GDT o LDT, con un poco de información de seguridad adicional.Naturalmente, si un programa intenta cargar un descriptor que está fuera de los límites de GDT, se produce una excepción.Además, si el proceso no tiene suficientes privilegios para acceder al segmento, o si algo no es válido, se produce una excepción.

Cuando ocurre una excepción, el kernel la maneja.Este tipo de excepción probablemente se clasificaría como un error de segmentación.Entonces el sistema operativo mata tu programa.

Hay una última advertencia:en el conjunto de instrucciones x86, no puede cargar valores inmediatos en registros de segmento.Debe utilizar un registro intermedio o un operando de memoria o POP en el registro de segmento.

MOV DS, 160  ;INVALID - won't assemble

MOV AX, 160  ;VALID - assembles, but will probably result in an
MOV DS, AX   ;exception, and thus the death of your program

Creo que cabe señalar que la arquitectura permite muchos segmentos.Pero AFAIK, cuando se trata de los principales sistemas operativos x86, los registros de segmento solo sirven para algunos propósitos:

  • Mecanismos de seguridad, como evitar que los procesos del espacio del usuario se dañen entre sí o al sistema operativo.
  • Tratar con procesadores múltiples/multinúcleos
  • Almacenamiento local de subprocesos:Como optimización, algunos sistemas operativos (incluidos Linux y Windows) utilizan registros de segmento para el almacenamiento local de subprocesos (TLS).Dado que los subprocesos comparten el mismo espacio de direcciones, es difícil para un subproceso "saber" dónde está su región TLS sin utilizar una llamada al sistema o desperdiciar un registro...pero dado que los registros de segmento son prácticamente inútiles, no hay nada de malo en "desperdiciarlos" en aras de un TLS rápido.Tenga en cuenta que al configurar esto, un sistema operativo puede omitir los registros de segmento y escribir directamente en los registros de caché de descriptores, que son registros "ocultos" utilizados para almacenar en caché las búsquedas GDT/LDT activadas por referencias a los registros de segmento, en cuyo caso si intenta para leer desde los registros de segmento no lo verá.

Aparte de un segmento por subproceso para TLS, en realidad solo se utilizan unos pocos segmentos (multiplicados por el número de procesadores), y solo por el sistema operativo.Los programas de aplicación pueden completamente ignore los registros de segmento.

Esto se debe al diseño del sistema operativo, no a limitaciones técnicas.Puede haber sistemas operativos integrados que requieran programas de espacio de usuario para trabajar con los registros de segmento, aunque no conozco ninguno.

Otros consejos

¿Estás escribiendo ejecutables de Windows?

En modo protegido (Win32), los registros de segmento ya no se utilizan.

Referencia:

El modelo de memoria también es drásticamente diferente de los viejos tiempos del mundo de 16 bits.¡Bajo WIN32, ya no necesitamos preocuparnos por el modelo o segmento de memoria!Solo hay un modelo de memoria:Modelo de memoria plana.No hay más segmentos de 64K.La memoria es un gran espacio continuo de 4 GB.Eso también significa que no tienes que jugar con registros de segmentos.Puede usar cualquier registro de segmento para abordar cualquier punto en el espacio de memoria.Esa es una GRAN ayuda para los programadores.Esto es lo que hace que la programación de ensamblaje WIN32 sea tan fácil como C.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top