Pergunta

Na escola temos vindo a utilizar um programa de inicialização para executar programas stand-alone sem um sistema operacional. Eu tenho estudado este programa e quando o modo protegido está habilitado há um salto muito executado por montar diretamente o opcode e operandos como dados dentro do programa. Este foi para a montador GNU:


         /* this code immediately follows the setting of the PE flag in CR0 */

.byte   0x66, 0xEA
.long   TARGET_ADDRESS
.word   0x0010          /* descriptor #2, GDT, RPL=0 */

Em primeiro lugar, porque é que um quer fazer isso (em vez do mnemônico de instrução)?

Eu tenho estado a olhar para os manuais Intel, mas ainda estou um pouco confuso com o código. Especificamente em 2A Volume, página 3-549, há uma mesa de opcodes. A entrada relevante:

EA *cp* JMP ptr16:32  Inv.  Valid  Jump far, absolute, address given in
operand

O código de operação real é óbvio, mas o primeiro byte, 0x66, tem me confundiu. Referindo-se à tabela no manual da Intel, o CP, aparentemente, significa que um byte 6 operando seguirá. E, obviamente, 6 bytes seguir nas próximas duas linhas. 0x66 codifica um 'Operando de tamanho substituição prefixo'. O que isso tem a ver com a cp na tabela? Eu estava esperando que haja algum valor hexadecimal para o cp, mas em vez disso, há esse prefixo override. Alguém por favor pode esclarecer isso para mim?

Aqui é um lixo a partir od:

c022    **ea66    0000    0001    0010**    ba52    03f2    c030

TARGET_ADDRESS foi definida como 0x00010000.

Eu também estou confuso um pouco pelo significado dos dois últimos bytes. No entanto, isso parece ser uma outra questão completamente. Está ficando muito tarde, e eu tenho estado a olhar para o código e os manuais Intel para horas, então eu espero que eu tenho o meu ponto de vista.

Agradecimentos para olhar!

Foi útil?

Solução

O 0x66 indica que o JMP (0xEA) refere-se a seis bytes. O padrão é referindo-se a 64K (16 bits) em modo real ou a 32 bits em modo protegido (se me lembro bem). Tê-lo aumentado, também inclui o descritor de segmento, o índice do segmento tanto no GDT ou o LDT, o que significa que este código está fazendo o que é tradicionalmente chamado de "salto em distância": um salto que os segmentos além cruzadas no arquitetura x86. O segmento, neste caso, aponta para a segunda entrada na GDT. Se você olhar antes nesse programa, é provável que você ver como o GDT é definido em termos do segmento de endereço inicial e comprimento (olhar no manual Intel para estudar as tabelas GDT e LDT, 32 entrada bit descrevendo cada segmento).

Outras dicas

eu me deparo com isso um pouco. Algumas montadoras só vai saltar para um rótulo. Neste caso, a pessoa quer fazer um salto absoluto para um específico codificado offset. jmp TARGET_ADDRESS não vai funcionar Eu estou supondo, então eles simplesmente colocá-lo como bytes de contornar este problema.

0x66 especifica operando override tamanho do tamanho atual segmento de código. Assumindo que o tamanho do código atual é de 16 bits, o novo ponteiro de instrução será de 32 bits, não de 16 bits. Se o tamanho actual segmento de código é de 32 bits, a 0x66 irá processar ponteiro instrução de destino como de 16 bits. A corrente de atributo de tamanho de código depende selector de CS no uso e os seus atributos carregado a partir GDT mesa / LDT. Em modo real o tamanho do segmento de código é geralmente de 16 bits, exceto casos especiais de modo "irreal".

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top