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

Operating system 使用nasm混合32位和16位代码,operating-system,nasm,osdev,assembly,Operating System,Nasm,Osdev,Assembly,这是一个低级的系统问题 我需要混合32位和16位代码,因为我正试图从保护模式返回到实模式。作为一点背景信息,我的代码是在GRUB启动后才这样做的,所以我没有任何讨厌的操作系统来告诉我我能做什么和不能做什么 无论如何,我在我的程序集中使用[BITS 32]和[BITS 16]来告诉nasm应该使用哪种类型的操作,但是当我测试我的代码使用bochs时,看起来有些操作的bochs没有执行我编写的代码。看起来汇编器正在插入额外的0x66和0x67,这让bochs感到困惑 那么,在同一个文件中混合使用32

这是一个低级的系统问题

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

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

那么,在同一个文件中混合使用32位和16位代码的情况下,如何让nasm成功地组装代码呢?有什么把戏吗?
你不是在开玩笑说这是低级的

您是否已检查生成的操作码/操作数,以确保nasm正确执行BITS指令?还要检查以确保跳跃目标正确-可能nasm使用了错误的偏移


如果它不是nasm中的一个bug,那么bochs中可能有一个bug。我无法想象人们会经常从32位模式切换回16位模式。

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

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


这表明这是bochs的错。

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

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

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


BITS 32指令只会在保护模式或长模式之外使用时混淆汇编程序。

问题是我没有正确设置描述符表。我有一个位翻转错误,所以我没有进入16位模式,而是进入了32位模式(碰巧有一个meg限制的段)

谢谢你的建议

特里