使用nasm混合32位和16位代码


5

这是一个低级系统问题。

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

无论如何,我用我的程序集[BITS 32]和[BITS 16]来告诉nasm应该使用哪些类型的操作,但是当我测试我的代码时使用bochs,它看起来像某些操作bochs不是执行我写的代码。它看起来像汇编程序是附加额外和0x67的困惑bochs。

那么,如何让nasm成功汇编代码,在同一个文件中混合使用32位和16位代码?有什么窍门吗?

0

你不是在开玩笑这是低级的!

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

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


3

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

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

这表明它是错误的bochs。


0

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

看看英特尔IA-32软件开发人员指南,第3卷,第16章(混音16位和32位代码;章节数可能根据这本书的编辑更改):

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

如果您在保护模式或长时间模式之外使用它,BITS 32指令只会混淆汇编器。


6

问题原来是因为我没有正确设置我的描述符表。我有一点翻错了,所以而不是去16位模式,我正在进入32位模式(段发生有一兆的限制)。

感谢您的建议!

特里

+1

提示:接受你自己的答案,当发生这种情况。 17 3月. 102010-03-17 21:13:07