gpt4 book ai didi

assembly - 如何在 MASM 中编写远绝对 JMP/CALL 指令?

转载 作者:行者123 更新时间:2023-12-03 22:22:23 25 4
gpt4 key购买 nike

如何使用 MASM 编写远绝对 JMP 或 CALL 指令?具体来说,我如何让它使用 EA 和 CA 操作码发出这些指令,而不是使用 DB 或其他数据指令手动发出它们?

例如,考虑跳转到引导扇区中 FFFF:0000 处的 BIOS 重置入口点的情况。如果我使用 NASM,我可以以一种显而易见的方式在一条指令中对此进行编码:

jmp 0xffff:0

使用 GNU 汇编器,语法不太明显,但以下内容可以完成这项工作:
jmp 0xffff, 0

但是,当我尝试使用 MASM 的明显解决方案时:
jmp 0ffffh:0

我收到以下错误:
t206b.asm(3) : error A2096:segment, group, or segment register expected

我试图避免的解决方法

我可以在 MASM 中使用许多可能的解决方法,例如以下任何一种:

手动组装指令,手动发出机器代码:

    DB 0EAh, 0, 0, 0FFh, 0FFh

使用远间接跳转:

bios_reset DD 0ffff0000h
...
jmp bios_reset ; FF 2E opcode: indirect far jump

或者将地址压入堆栈并使用远 RET 指令“返回”它:

    push 0ffffh
push 0
retf

但是无论如何我可以使用实际的 JMP 指令并让 MASM 生成正确的操作码 (EA)?

最佳答案

有一种方法可以做到,但您需要使用 MASM 的 /omf switch 以便它生成 OMF 格式的目标文件。这意味着目标文件需要与 OMF 兼容的链接器链接,例如 Microsoft 的旧分段链接器(而不是他们当前的 32 位链接器)。

为此,您需要使用 MASM 的一个很少使用且不太了解的功能,SEGMENT指令的 AT address属性。 AT属性告诉链接器该段位于内存中的固定段落地址,如 address 所示。 .它还告诉链接器丢弃该段,这意味着不使用该段的内容,只使用它的标签。这也是为什么/omf必须使用开关。 MASM 的默认目标文件格式 PECOFF 不支持此功能。
AT属性为您提供了我们要跳转到的地址的段部分。要获得偏移部分,您需要做的就是在段内使用 LABEL 指令。结合 ORG 指令,您可以在特定段中的特定偏移量处创建标签。然后您需要做的就是在 JMP 或 CALL 指令中使用这个标签。

例如,如果您想跳转到 BIOS 重置例程,您可以执行以下操作:

bios_reset_seg SEGMENT USE16 AT 0ffffh
bios_reset LABEL FAR
bios_reset_seg ENDS

_TEXT SEGMENT USE16 'CODE'
jmp bios_reset
_TEXT ENDS

或者,如果您想调用入口点位于 0000:7E00 的引导加载程序的第二阶段部分:
zero_seg SEGMENT USE16 AT 0
ORG 7e00h
second_stage LABEL FAR
zero_seg ENDS

_TEXT SEGMENT USE16 'CODE'
call second_stage
_TEXT ENDS

关于assembly - 如何在 MASM 中编写远绝对 JMP/CALL 指令?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32706833/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com