ejemplos modo protegido.pdf


Vista previa del archivo PDF ejemplos-modo-protegido.pdf


Página 1...71 72 73747591

Vista previa de texto


;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
:
;
;
;
;
;

ej07.asm - modo protegido 32 bits y pila expand down
Protected Mode by Examples – 1era Edición - Octubre 2004
Autor:
Mariano Cerdeiro
<m.cerdeiro@soix.com.ar>
http://www.soix.com.ar/links/mpbyexamples.html
compilar: nasm ej07.asm -o ej07.com
Los microprocesadores de Intel IA-32 están optimizados para correr
código de 32 bits. Hasta este ejemplo se utilizó siempre código de 16
bits, el único que se puede correr en modo real. En modo protegido, y
mediante el seteo del bit D del descriptor de segmento de código, se
puede setear si el segmento es de 16 bits o de 32. Además de indicarlo
en el descriptor de código, es necesario indicar cuándo compilar con
código de 32 bits al compilador. La diferencia entre código de 16 y 32
reside en qué tamaño de registros y en qué tipo de direccionamiento
son utilizados de forma predeterminada. En modo de 16 bits se pueden
usar registros de 32 y direccionamiento de 32, así como en un segmento
de 32 se pueden usar direccionamiento de 16 y registros de 16. Sin
embargo, en los segmentos de 16 bits las instrucciones de 16 bits son
más cortas y se ejecutan más rápido; lo contrario sucede entonces en
un segmento de 32 bits. Las instrucciones más cortas son las de 32
bits y por eso son más rápidas. También se obtienen otras ventajas,
como que los segmentos de códigos pueden tener un largo mayor a 64 Kb.
Además del segmento de código de 32 bits, en este ejemplo se utiliza
un segmento de pila de 32 bits expand down, lo que implica que SIEMPRE
se pushean o popean valores de 32 bits para mantener alineada la pila,
por lo que un push ax decrementará esp en 4, copiará ax y dejará dos
bytes en 0, o en lo que estaban según el modelo del procesador. Este
manejo de la pila es transparente para el programador, cuando hace pop
ax, recibirá dos bytes de ax, y los otros dos serán desechados, de
modo que se asegura tener la pila siempre alineada a 4 bytes, lo cual
mejora la performance. El segmento de pila es además expand down, lo
que implica que los offset válidos van desde el límite a 0FFFFFFFFh,
con lo que se optimiza el uso de la pila en caso de necesitar
ampliarla. Un ejemplo:
Si se tiene una pila en un segmento de datos normal con límite 4
Kbytes, se la inicializará con esp apuntando a 4 Kbytes. Si ésta se
llena, esp apuntará a 0. En caso de que se la desee ampliar, no
bastará con cambiar el límite, ya que esp seguirá siendo 0. Es por eso
que se debe cambiar el límite, por ejemplo por 8 Kbytes, copiar los 4
Kbytes de datos de la pila que se encontraban en los offset 0 a 4 Kb a
los offsets 4 Kb a 8 Kb y apuntar el esp a 4 Kb. Todo esto es para
modificar el tamaño de la pila en caso de que se trate de un segmento
normal. En cambio, en un segmento expand down, se coloca inicialmente
el segmento en expand down con límite en 0FFFFF000h y el esp apuntando
en 0FFFFFFFCh, por lo que lo que se tienen 4 Kb de espacio en pila.
Cuando se va llenado la pila, esp se decrementa hasta llegar a
0FFFFF000h, momento en que se deberá ampliar la pila. Sin embargo, en
este caso bastará con cambiar el límite que anteriormente estaba en
0FFFFF000h por 0FFFFE000h, con lo que el esp seguirá apuntando a
0FFFFF000h y no habrá que mover los datos de lugar. De esta forma,
ampliar la pila requiere únicamente modificar su límite. Es por eso
que se recomienda utilizar los segmentos expand down para los
segmentos de pila, como se hace en este ejemplo.