在保护模式下进行间接远跳转/调用

发布于 2024-10-14 11:51:57 字数 908 浏览 4 评论 0原文

如何在保护模式下执行间接远跳转/调用?首先,我认为这样做是允许的:(

jmp 0x10:eax;

不要担心段选择器..我的 GDT 的第二个条目是有效的代码段)

但是当 nasm 组装它时,这是一个语法错误。查看Intel(指令集参考)手册的Book 2a,只能使用jmp ptr16:32来完成,其中ptr16:32是一个立即数,或使用jmp m16:32,其中m16:32是包含48位跳转地址(16:32)的内存位置。

现在我尝试以这种方式对其进行编码:

mov dword[ds:jumpaddress_offset],eax
; or just dword[jumpaddress_offset],eax
mov word[ds:jumpaddress_sel],0x10;
; or just mov word[ds:jumpaddress_sel],0x10;
jmp dword far [dword ds:jumpaddress];
...
jumpaddress:
jumpaddress_sel dw 0
jumpaddress_offset dd 0

它组装成功,但是当我尝试运行它时,处理器出现一般保护故障并重新启动。我不知道发生了什么事。

我假设编码是这样的:(

例如我想使用间接跳转跳转到 0x10:0x8010)

dw 0x10
dd 0x8010

这可能有什么问题? 难道48位内存值应该以小端编码吗? 并且应该这样编码吗?

;0010 0000 8010
dd 0x10,0x80,0,0,0x10,0

我还没有尝试做最后一项。

How do I perform an indirect far jump/call in protected mode? First I was thinking that doing this is allowable:

jmp 0x10:eax;

(Don't worry about the segment selector..the 2nd entry of my GDT is a valid code segment)

But when nasm assembled it, it was a syntax error. Looking at the Book 2a of the Intel (instruction set reference) manual, it can only be done using jmp ptr16:32, where the ptr16:32 is an immediate value, or using jmp m16:32, where the m16:32 is a memory location containing the 48-bit jump address (the 16:32).

Now I tried to encode it this way:

mov dword[ds:jumpaddress_offset],eax
; or just dword[jumpaddress_offset],eax
mov word[ds:jumpaddress_sel],0x10;
; or just mov word[ds:jumpaddress_sel],0x10;
jmp dword far [dword ds:jumpaddress];
...
jumpaddress:
jumpaddress_sel dw 0
jumpaddress_offset dd 0

It assembled successfully, but when I tried to run it the processor gets a general protection fault and restarts. I don't know what happened.

I assumed the encoding is like this:

(for example I want to jump to 0x10:0x8010 using indirect jump)

dw 0x10
dd 0x8010

What could be the wrong with this?
Is it that the 48-bit memory value should be coded in little endian?
And should it be coded like this?

;0010 0000 8010
dd 0x10,0x80,0,0,0x10,0

I haven't tried doing the last one.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

满天都是小星星 2024-10-21 11:51:57

一个常用的技巧是使用 far ret 来模拟跳跃,例如:

push 0x10
push eax
retf

A frequently used trick is to emulate the jump using a far ret, such as:

push 0x10
push eax
retf
滴情不沾 2024-10-21 11:51:57

x86 处理器使用小端模式。与此一致,目标的偏移量位于内存中的段之前。对于您的示例,您应该使用:

dd 0x8010 ;远跳转的偏移量

dd 0x10 ;远跳转的段,出于对齐原因扩展为双字

;--------------------------------

db 0x10, 0x80, 0, 0, 0x10, 0, 0, 0 ;也可以。

您可能仍然会获得特权例外。为了使代码正常工作,目标代码段必须具有与源代码段相同的特权级别。

主要来源:Robert L. Hummel 的《处理器和协处理器》

The x86 processors use little-endian mode. In keeping with that, the offset of a target precedes the segment in memory. For your example you should use:

dd 0x8010 ;offset of far jump

dd 0x10 ;segment of far jump, expanded to double-word for alignment reasons

;------------------

db 0x10, 0x80, 0, 0, 0x10, 0, 0, 0 ;will also work.

You might still get a privilege exception. For the code to work the target code segment must have the same privilege level as the source segment.

Primary source: The Processor and Coprocessor by Robert L. Hummel

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文