Pergunta

Pelo que tenho lido, parece que há 9 bandeiras diferentes. É possível ler / alterá-los diretamente? Eu sei que eu posso saber, por exemplo, se a flag zero é definido depois de fazer uma instrução CMP / JMP, mas eu estou perguntando se é possível fazer algo parecido

mov eax, flags

ou algo assim.

Além disso, para a escrita, é possível configurá-los à mão?

Foi útil?

Solução

Algumas bandeiras pode ser definido ou limpo diretamente com instruções específicas:

  • CLC , STC , e CMC : clara, definida, e complementar a bandeira carry
  • CLI e STI : clara e definir o sinalizador de interrupção (que deve ser feito atomicamente)
  • CLD e STD : clara e definir o sinalizador de direção

Para ler e escrever o sinal, zero, carry auxiliar, paridade e bandeiras de transporte, você pode usar LAHF para carregar os 8 bits inferiores (aqueles 5 bandeiras mais 3 bits indeterminados) no registo AH, e você pode usar SAHF para armazenar esses valores de AH de volta para as bandeiras registo.

Você também pode usar o PUSHF instrução para empurrar as bandeiras para a pilha, leia e modificá-los na pilha, e depois usar o POPF 1 instrução para armazená-los de volta para as bandeiras registo.

Note que você não pode definir os sinalizadores VM e RF com POPF - eles mantêm seus valores anteriores. Da mesma forma, você só pode alterar o nível de privilégio de E / S durante a execução no nível de privilégio 0, ea bandeira interrupção só pode ser alterado durante a execução em um nível de privilégio, pelo menos, por mais privilegiado que o nível I / O privilégio.


Nota 1:

Note que popf é bastante lento em CPUs modernas; Consulte o Guia de otimização e de instrução mesas Agner de nevoeiro. É microcodificadas porque no modo kernel que é capaz de mudar IF e AC, e nível de privilégio IO. Nós sofrer a penalidade independentemente do modo em CPUs atuais, porque os descodificadores não são sensíveis-mode.

Se possível, use LAHF / SAHF vez de pushf / popf para o desempenho, ou salvar uma única bandeira que você se preocupa com como setc al então add al, 255 mais tarde para set CF = (AL!=0). Ou setnc al / sub al, 1 ou qualquer outra coisa. Sequências para configurar ou clara SF ou com base em um registro 0 ou 1 também são simples, com / sem inverter a bandeira.

Outras dicas

Você pode usar o pushf e instruções POPF que vai empurrar as bandeiras na pilha, você pode modificá-los, e, em seguida, pop-los recuar.

Se você precisa apenas o byte inferior do registrador de flags (que contém SF, ZF, AF, PF, CF), então não é o LAHF instrução estranho, mas conveniente (ha ha), que carrega o fundo 8 bits do bandeiras registar em AH, e sua contraparte SAHF para armazenar AH em bandeiras.
Para o flag carry especificamente, x86 ofertas CLC, STC e CMC, para limpar, set, e complementar a bandeira de transporte, respectivamente.

Maneira mais simples é usar pushf / popf .

Se você deseja mover eflags em eax, use o código abaixo.

pushf                  # push eflags into stack
pop %eax               # pop it into %eax
  • LAHF: sinalizadores de status carrega na AH
  • Copia o byte baixo dos EFLAGS registar incluindo Sinal, Zero, e bandeiras transportar.
  • Salvar uma cópia das bandeiras em uma variável para a guarda

    .data
     saveflags BYTE ? 
    .code 
     lahf ; load flags into AH 
     mov saveflags,ah ; save them into a variable 
    
  • SAHF: lojas AH em sinalizadores de status

  • Cópias AH para o byte baixo dos EFLAGS registar
  • Recuperar o valor de bandeiras armazenadas anteriormente

    .code
     mov ah, saveflags ; load save flags into AH 
     sahf ; copy into flags register 
    
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top