【问题标题】:Mixing 32 bit and 16 bit code with nasm使用 nasm 混合 32 位和 16 位代码
【发布时间】:2010-09-06 07:24:20
【问题描述】:

这是一个低级系统问题。

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

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

那么,当我在同一个文件中混合 32 位和 16 位代码时,如何让 nasm 成功组装代码?有什么技巧吗?

【问题讨论】:

    标签: operating-system nasm osdev assembly


    【解决方案1】:

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

    感谢您的建议!

    特里

    【讨论】:

      【解决方案2】:

      0x66 和 0x67 是操作码,用于指示以下操作码应被解释为非默认位数。更具体地说,(根据this link),

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

      这表明它是错误的。

      【讨论】:

        【解决方案3】:

        这不是在开玩笑!

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

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

        【讨论】:

          【解决方案4】:

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

          查看英特尔 IA-32 软件开发人员指南,第 3 卷,第 16 章(混合 16 位和 32 位代码;章节编号可能会根据本书的版本而变化):

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

          只有在保护模式或长模式之外使用 BITS 32 指令才会混淆汇编器。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2012-10-10
            • 2011-05-22
            • 2012-02-10
            • 2014-12-17
            • 2013-02-07
            • 2013-01-11
            相关资源
            最近更新 更多