将 32 位和 16 位代码与 nasm 混合

发布于 2024-07-04 08:43:45 字数 379 浏览 4 评论 0原文

这是一个低级系统问题。

我需要混合 32 位和 16 位代码,因为我试图从保护模式返回到实模式。 作为一些背景信息,我的代码是在 GRUB 启动后执行此操作,因此我没有任何讨厌的操作系统来告诉我可以做什么和不能做什么。

无论如何,我在程序集中使用 [BITS 32] 和 [BITS 16] 来告诉 nasm 它应该使用哪种类型的操作,但是当我使用 bochs 测试我的代码时,对于某些操作,bochs 似乎没有执行以下代码我写。 看起来汇编器粘在了额外的 0x660x67 中,这让 bochs 感到困惑。

那么,如何让 nasm 成功地汇编在同一文件中混合 32 位和 16 位代码的代码? 有什么技巧吗?

This is a low-level systems question.

I need to mix 32 bit and 16 bit code because I'm trying to return to real-mode from protected mode. As a bit of background information, my code is doing this just after GRUB boots so I don't have any pesky operating system to tell me what I can and can't do.

Anyway, I use [BITS 32] and [BITS 16] with my assembly to tell nasm which types of operations it should use, but when I test my code use bochs it looks like the for some operations bochs isn't executing the code that I wrote. It looks like the assembler is sticking in extras 0x66 and 0x67's which confuses bochs.

So, how do I get nasm to successfully assemble code where I mix 32 bit and 16 bit code in the same file? Is there some kind of trick?
­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­

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

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

发布评论

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

评论(4

夜空下最亮的亮点 2024-07-11 08:43:45

0x66 和 0x67 是用于指示后续操作码应解释为非默认位数的操作码。 更具体地说,(根据此链接),

“当 NASM 处于 BITS 16 模式时,使用 32 位数据的指令以 0x66 字节为前缀,而引用 32 位地址的指令则以 0x67 前缀。在 BITS 32 模式下,情况相反:32 位指令不需要前缀,而使用 16 字节的指令。位数据需要 0x66,而处理 16 位地址的数据则需要 0x67。”

这表明这是博赫斯的错。

The 0x66 and 0x67 are opcodes that are used to indicate that the following opcode should be interpreted as a non-default bitness. More specifically, (and according to this link),

"When NASM is in BITS 16 mode, instructions which use 32-bit data are prefixed with an 0x66 byte, and those referring to 32-bit addresses have an 0x67 prefix. In BITS 32 mode, the reverse is true: 32-bit instructions require no prefixes, whereas instructions using 16-bit data need an 0x66 and those working on 16-bit addresses need an 0x67."

This suggests that it's bochs that at fault.

酒解孤独 2024-07-11 08:43:45

如果您处于实模式,则默认大小隐式为 16 位,因此您应该使用 BITS 16 模式。 这样,如果您需要 32 位操作数大小,则添加 0x66 前缀,而对于 32 位地址大小,则添加 0x67 前缀。

请参阅《Intel IA-32 软件开发人员指南》第 3 卷第 16 章(混合 16 位和 32 位代码;章节编号可能会根据本书的版本而变化):

实地址模式、虚拟8086模式和SMM是本机16位模式。

如果您在保护模式或长模式之外使用 BITS 32 指令,它只会使汇编程序感到困惑。

If you're in real mode your default size is implicitly 16 bits, so you should use BITS 16 mode. This way if you need a 32-bit operand size you add the 0x66 prefix, and for a 32-bit address size you add the 0x67 prefix.

Look at the Intel IA-32 Software Developer's Guide, Volume 3, Chapter 16 (MIXING 16-BIT AND 32-BIT CODE; the chapter number might change according to the edition of the book):

Real-address mode, virtual-8086 mode, and SMM are native 16-bit modes.

The BITS 32 directive will only confuse the assembler if you use it outside of Protected Mode or Long Mode.

原谅我要高飞 2024-07-11 08:43:45

问题原来是我没有正确设置描述符表。 我有一个位翻转错误,所以我没有进入 16 位模式,而是进入 32 位模式(段的限制恰好为 1 兆)。

感谢您的建议!

特里

The problem turned out to be that I wasn't setting up my descriptor tables correctly. I had one bit flipped wrong so instead of going to 16-bit mode I was going to 32-bit mode (with segments that happened to have a limit of one meg).

Thanks for the suggestions!

Terry

抠脚大汉 2024-07-11 08:43:45

你不是开玩笑说这是低水平的!

您是否检查了生成的操作码/操作数以确保 nasm 正确遵循您的 BITS 指令? 还要检查以确保跳转目标正确 - 也许 nasm 使用了错误的偏移量。

如果这不是 nasm 中的错误,那么可能是 bochs 中存在错误。 我无法想象人们会经常从 32 位模式切换回 16 位模式。

You weren't kidding about this being low-level!

Have you checked the generated opcodes / operands to make sure that nasm is honoring your BITS directives correctly? Also check to make sure the jump targets are correct - maybe nasm is using the wrong offsets.

If it's not a bug in nasm, maybe there is a bug in bochs. I can't imagine that people switch back to 16-bit mode from 32-bit mode very often anymore.

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