Meu código x86 pré-compilado pode estar sendo executado em 16 bits (modo real ou modo protegido de 16 bits) ou 32 bits (modo protegido i386). Como posso detectá-lo a partir do código em tempo de execução?
Consegui chegar a esta fonte NASM:
bits 16
cpu 386
pushf
test ax, strict word 0 ; In 32-bit mode this is `test eax, ...', +2 bytes.
jmp short found_16
; Fall through to found_32.
found_32:
bits 32
popf
int 32 ; Or whatever code.
found_16:
bits 16
popf
int 16 ; Or whatever code.
No entanto, não gosto, porque ele usa a pilha. Existe uma solução que não modifique nenhum registrador de uso geral, registrador de segmento ou flags, não use a pilha e funcione em um 8086 (somente modo de 16 bits) e em um 386 (ambos os modos)?
Tentei lea esi, [dword esi+0]
no modo de 32 bits, mas isso não é possível no modo de 16 bits.
Observe que estou ciente de que para a maioria dos programas o modo é decidido em tempo de compilação (como parte da arquitetura e plataforma), e eles não precisam ser capazes de detectar o modo em tempo de execução. Também para programas iniciados normalmente, o sistema operacional escolherá o modo correto com base no cabeçalho do arquivo, portanto, quase não há perigo de executar acidentalmente um arquivo de programa completo no modo errado. No entanto, alguns trechos de programa, como o shellcode de exploração, podem se beneficiar da detecção em tempo de execução de todos os tipos (incluindo a arquitetura e o sistema operacional). Também tenho alguns outros casos de uso obscuros em mente.