有人可以解释这个直接组装的x86 JMP操作码吗? [英] Can someone explain this directly assembled x86 JMP opcode?

查看:192
本文介绍了有人可以解释这个直接组装的x86 JMP操作码吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在学校,我们一直在使用引导程序来运行没有操作系统的独立程序.我一直在研究此程序,并且在启用保护模式时,通过直接将操作码和操作数作为程序内的数据进行汇编,可以执行远距离跳转.这是供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 */

首先,为什么要这么做(而不是助记符指令)?

我一直在看Intel手册,但是对代码仍然有些困惑.特别是在第3-549页的第2A卷中,有一个操作码表.相关条目:

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

实际的操作码很明显,但是第一个字节0x66让我感到困惑.参考Intel手册中的表,cp显然意味着将跟随6字节的操作数.很显然,接下来的两行中有6个字节. 0x66编码操作数大小覆盖前缀".这与表中的cp有什么关系?我期望cp有一些十六进制值,但是有这个覆盖前缀.有人可以帮我清理一下吗?

这是来自od的转储:

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

TARGET_ADDRESS被定义为0x00010000.

最后两个字节的含义也让我有些困惑.但是,这似乎完全是另一个问题.已经很晚了,我已经盯着代码和英特尔手册几个小时了,所以我希望我能理解我的观点.

感谢您的光临!

解决方案

0x66表示JMP(0xEA)引用了六个字节.默认值是在实模式下引用64K(16位),在保护模式下引用32位(如果我记得很好的话).增加它之后,它还包括段描述符,段在GDT或LDT中的索引,这意味着该代码正在进行传统上称为长跳转"的操作:跨过段中的段的跳转x86体系结构.在这种情况下,该细分指向GDT上的第二个条目.如果您以前看过该程序,则可能会看到如何根据段的起始地址和长度来定义GDT(请参阅Intel手册以研究GDT和LDT表,其中32位条目描述了每个段)./p>

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!

解决方案

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).

这篇关于有人可以解释这个直接组装的x86 JMP操作码吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆