Pregunta

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 pregunto si es posible hacer algo como

mov eax, flags

o algo así

Además, para escribir, ¿es posible configurarlos a mano?

¿Fue útil?

Solución

Algunas banderas se pueden establecer o borrar directamente con instrucciones específicas:

  • CLC , STC , y CMC : borre, establezca y complemente la bandera de transporte
  • CLI y STI : borre y establezca el indicador de interrupción (que debe hacerse atómicamente)
  • CLD y STD : borre y establezca 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 inferiores (esos 5 indicadores más 3 bits indeterminados) en el registro AH, y puede usar SAHF para almacenar esos valores de AH nuevamente en el registro de banderas.

También puede utilizar la instrucción PUSHF para colocar las banderas en la pila, léalas y modifíquelas en la pila, y luego use el POPF 1 instrucción para almacenarlos nuevamente en el registro de banderas.

Tenga en cuenta que no puede configurar los indicadores de VM y RF con POPF: conservan sus valores anteriores. Del mismo modo, 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.


Nota al pie 1:

Tenga en cuenta que popf es bastante lento en las CPU modernas; consulte la guía de optimización y las tablas de instrucciones de Agner Fog . Está microcodificado porque en modo kernel puede cambiar IF y AC, y el nivel de privilegio IO. Sufrimos la penalización independientemente del modo en las CPU actuales porque los decodificadores no son sensibles al modo.

Si es posible, use lahf / sahf en lugar de pushf / popf para el rendimiento, o guarde una sola bandera que le interese como setc al y luego add al, 255 para establezca CF = (AL! = 0) . O setnc al / sub al, 1 o lo que sea. Las secuencias para establecer o borrar SF u OF en función de un registro 0 o 1 también son sencillas, con / sin invertir el indicador.

Otros consejos

Puede usar las instrucciones pushf y popf que empujarán las banderas a la pila, puede modificarlas y luego volver a activarlas.

Si solo necesita el byte inferior del registro de banderas (que contiene SF, ZF, AF, PF, CF), existe la extraña pero conveniente instrucción LAHF (ja, ja), que carga los 8 bits inferiores las banderas se registran en AH, y su contraparte SAHF para almacenar AH en banderas.

Para la bandera de transporte específicamente, x86 ofrece CLC, STC y CMC, para borrar, establecer y complementar la bandera de transporte, respectivamente.

La manera más simple 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

SETcc

Esta familia de instrucciones es otra forma de observar algunas banderas / combinación de banderas.

Establece el valor de un byte en función de las BANDERAS individuales.

Por ejemplo, para CF :

stc
setc al
; al == 1

clc
setc al
; al == 0

Runnububble upUp GH con aserciones .

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:

Runnububble upUp GH con aserciones .

  • LAHF: carga indicadores de estado en AH
  • Copia el byte bajo del registro EFLAGS, incluidas las banderas Sign, Zero y Carry.
  • 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 indicadores de estado

  • Copia AH en el byte bajo del registro EFLAGS
  • Recuperar el valor de las banderas almacenadas anteriormente

    .code
     mov ah, saveflags ; load save flags into AH 
     sahf ; copy into flags register 
    
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top