Can anyone explain this directly compiled x86 JMP opcode?

At school, we used bootstrap to run stand-alone programs without an operating system. I studied this program, and when protected mode is enabled, there is a down-jump performed by directly compiling the operation code and operands as data in the program. This was for the GNU assembler:

/* 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 */ 

code>

First of all, why do this (instead of the mnemonics command)?

I looked at Intel manuals, but I'm still a bit confused by the code. In particular, in Volume 2A, p. 3-549, there is a table of operation codes. Corresponding entry:

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

The actual operation code is obvious, but the first byte, 0x66, confuses me. Referring to the table in the Intel manual, cp obviously means that a 6-byte operand will follow. And, obviously, 6 bytes follow in the next two lines. 0x66 encodes the "operand override prefix". What does this have to do with cp in the table? I expected cp to have some kind of hex value, but there is an override prefix instead. Can someone clarify this for me?

Here is a dump from od:

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

TARGET_ADDRESS has been defined as 0x00010000.

I am also a little confused by the value of the last two bytes. However, this seems to be another question. This happens quite late, and I have been looking at Intel code and manuals for several hours, so hopefully I have a point.

Thanks for watching!

+7
assembly x86 gnu protected-mode opcode
source share
3 answers

0x66 indicates that JMP (0xEA) refers to six bytes. The default is 64K (16 bit) in real mode or 32 bit in protected mode (if I remember well). Increasing it, it also includes a segment descriptor, a segment index in either GDT or LDT, which means that this code does what is traditionally called a "long jump": a jump crossing segments in x86. The segment in this case indicates the second entry in the GDT. If you look in this program, you will most likely see how the GDT is defined in terms of the starting address and segment length (see Intel's Guide to Examining the GDT and LDT Tables, 32-bit entry describing each segment).

+12
source share

I came across this a bit. Some assemblers will only go to the LABEL. In this case, the person wants to make an absolute transition to a certain hard-coded offset. jmp TARGET_ADDRESS is not working, I guess, so they just put it as bytes to get around this problem.

+2
source share

0x66 defines the redefinition of the operand size of the current code segment size. Assuming the current code size is 16 bits, the new instruction pointer will be 32-bit, not 16-bit. If the current code segment size is 32-bit, then 0x66 will display the target command pointer as 16-bit. The current code size attribute depends on the CS selector used and its attributes loaded from the GDT / LDT table. In real mode, the code segment size is usually 16 bits, except in special cases of "unreal" mode.

0
source share

All Articles