Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can someone explain this directly assembled x86 JMP opcode?

At school we have been using a bootstrap program to run stand-alone programs without an operating system. I have been studying this program and when protected mode is enabled there is a far jump executed by directly assembling the opcode and operands as data within 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 */

First of all, why would one want to do this (instead of the instruction mnemonic)?

I have been looking at the Intel manuals, but am still a little confused by the code. Specifically in Volume 2A, page 3-549, there is a table of opcodes. The relevant entry:

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

The actual opcode is obvious, but the the first byte, 0x66, has me confused. Referring to the table in the Intel manual, the cp apparently means that a 6 byte operand will follow. And obviously 6 bytes follow in the next two lines. 0x66 encodes an 'Operand-size override prefix'. What does this have to do with the cp in the table? I was expecting there to be some hex value for the cp, but instead there is this override prefix. Can someone please clear this up for me?

Here is a dump from od:

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

TARGET_ADDRESS was defined as 0x00010000.

I am also confused a bit by the significance of the last two bytes. However, that seems to be another question altogether. It is getting quite late, and I have been staring at code and the Intel manuals for hours, so I hope I got my point across.

Thanks for looking!

like image 745
Mr. Shickadance Avatar asked Feb 13 '09 07:02

Mr. Shickadance


People also ask

What is the purpose of the x86 assembly language jmp instruction?

In the x86 assembly language, the JMP instruction performs an unconditional jump. Such an instruction transfers the flow of execution by changing the program counter.

How does jmp work in assembly?

Description. The jmp instruction transfers execution control to a different point in the instruction stream; records no return information. Jumps with destinations of disp[8|16|32] or r/m[16|32] are near jumps and do not require changes to the segment register value.

What size in bytes are opcodes on an x86 processor?

x86 opcodes are 1 byte for most common instructions, especially instructions which have existed since 8086. Instructions added later (e.g. like bsf and movsx in 386) often use 2-byte opcodes with a 0f escape byte.

What is a far jump in assembly?

A FAR jump specifies both a segment and offset, which are both absolute in the sense that they specify the required code segment and instruction pointer, rather than an offset relative to the current code segment / instruction pointer.


1 Answers

The 0x66 indicates that the JMP (0xEA) refers to six bytes. The default is refering to 64K (16 bits) in real mode or to 32 bits in protected mode (if I recall well). Having it increased, it also includes the segment descriptor, the index of the segment either in the GDT or the LDT, which means, that this code is making what is traditionally called a "long jump": a jump that cross beyond segments in the x86 architecture. The segment, in this case, points to the second entry on the GDT. If you look before in that program, you'll likely see how the GDT is defined in terms of the segment starting address and length (look in the Intel manual to study the GDT and LDT tables, 32 bit entry describing each segment).

like image 72
Diego Sevilla Avatar answered Sep 22 '22 06:09

Diego Sevilla