assembly - register - ¿Cómo leer y escribir registros x86 directamente?
registers assembly x86 (6)
Algunas banderas se pueden establecer o borrar directamente con instrucciones específicas:
- CLC , STC y CMC : borre, configure y complemente la bandera de acarreo
- CLI y STI : borre y establezca la bandera de interrupción (que debe hacerse de forma atómica)
- CLD y STD : borra y establece la bandera de dirección
Para leer y escribir el signo, cero, transporte auxiliar, paridad y banderas de transporte, puede usar LAHF para cargar los 8 bits más bajos (esos 5 indicadores más 3 bits indeterminados) en el registro AH, y puede usar SAHF para almacenarlos. Los valores de AH vuelven al registro de banderas.
También puede usar la instrucción PUSHF para empujar las banderas en la pila, leerlas y modificarlas en la pila, y luego usar la instrucción POPF para almacenarlas nuevamente en el registro de banderas.
Tenga en cuenta que no puede configurar los indicadores de VM y RF con POPF, ya que conservan sus valores anteriores. De manera similar, solo puede cambiar el nivel de privilegio de E / S cuando se ejecuta en el nivel de privilegio 0, y el indicador de interrupción solo se puede cambiar cuando se ejecuta en un nivel de privilegio al menos tan privilegiado como el nivel de privilegio de E / S.
Por lo que he leído, parece que hay 9 banderas diferentes. ¿Es posible leerlos / cambiarlos directamente? Sé que puedo saber, por ejemplo, si el indicador de cero se establece después de hacer una instrucción cmp / jmp, pero estoy preguntando si es posible hacer algo como
mov eax, flags
o algo.
Además, para escribir, ¿es posible configurarlas a mano?
La forma más sencilla es usar pushf / popf .
Si desea mover eflags
a eax
, use el código a continuación.
pushf # push eflags into stack
pop %eax # pop it into %eax
Puedes usar las instrucciones pushf y popf que empujarán las banderas en la pila, puedes modificarlas y luego volver a sacarlas.
Si solo necesita el byte inferior del registro de banderas (que contiene SF, ZF, AF, PF, CF), existe la instrucción impar pero conveniente LAHF (ha ha), que carga los 8 bits más bajos de las banderas que se registran en AH, y su contraparte SAHF para almacenar AH en banderas.
Específicamente para la bandera de acarreo, x86 ofrece CLC, STC y CMC para borrar, configurar y complementar la bandera de acarreo, respectivamente.
SETcc
Esta familia de instrucciones es otra forma de observar algunas banderas / combinación de banderas. Por ejemplo, para CF
:
stc
setc al
; al == 1
clc
setc al
; al == 0
Jcc
Esta familia de instrucciones es, por supuesto, otra posibilidad para ciertos indicadores, y podría usarse para implementar SETcc
:
jc set
mov al, 0
jmp end
set:
mov al, 1
end:
- LAHF: carga banderas de estado en AH
- Copia el byte bajo del registro EFLAGS, incluidos los distintivos Firmar, Cero y Llevar.
Guardar una copia de las banderas en una variable para su custodia.
.data saveflags BYTE ? .code lahf ; load flags into AH mov saveflags,ah ; save them into a variable
SAHF: almacena AH en banderas de estado
- Copia AH en el byte bajo del registro EFLAGS
Recupera el valor de las banderas almacenadas anteriormente
.code mov ah, saveflags ; load save flags into AH sahf ; copy into flags register