code16,code32什么区别啊,谢谢
我本来以为在code16开头的代码段中,不能出现eax等这种32位的寄存器,但后来发现不是这个样子?
请达人解释一下
谢谢
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
我本来以为在code16开头的代码段中,不能出现eax等这种32位的寄存器,但后来发现不是这个样子?
请达人解释一下
谢谢
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
接受
或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
发布评论
评论(9)
lz说的是NASM吧?又是《自己动手写操作系统》?x86确可以在16位代码中使用32位寄存器啊。
ARM里面的Thumb好像是操作32位寄存器的。
我看得是setup.s,linux启动文件
如果想您所说得那样,code16和code32到底什么区别啊?
过去8位CPU有Intel的8080。后来Zilog公司搞出了向下兼容于8080的Z80,它增加了3个16位寄存器,尽管它仍然是8位CPU。
这个问题在我的置顶贴 《x64指令系统》之指令编码内幕 以及 《x86 & x64 沉思录》里都可以找到根本的答案。
两个概念:
1、default operand size: 缺省的操作数大小
2、effective operand size:有效的操作数大小
以及
1、default address size:缺省的地址大小
2、effective address size:有效的地址大小
-------------------------------------------------------------------
在 16 位实模式代码里,使用 32 位的寄存器是很正确、正常的行为。
在实模式里:
1、default operand size 是 16 位
2、effective operand size 是 16 和 32 位。
也就是说:缺省的操作数是 16 位的,但是 16 位和 32 位的操作数都是有效的。
所以,如果在 16 位代码里使用 32 位寄存器,则必须使用 prefix --- operand size override prefix: 66h
更往深一点:
其实,实模式里的 default operand size 是 16,是由 CS.D = 0 来决定的,这个 CS.D = 0 是 CPU 复位时的初始状态。
这个 CPU 的初始状态是可以通过编程改变的。也就是说:实模式下,缺省的操作数大小可以改为 32 位的。
code16 与 code32 的区别是对于编译器来说的。
1、使用了 code16 是告诉编译器:下面的代码要编译成 16 位代码。
更易于理解地说:是告诉编译器,下面的代码要运行在 16 位模式(实模式)下,你要帮我编译成实模式的代码。
在这种情况下,要注意的是:16 位代码的寻址模式比 32 位代码的寻址少很多。
2、使用了 code32 是告诉编译器,下面的代码要编译成 32 位代码。
更易于理解地说:是告诉编译器,下面的代码要运行在 32 保护模式下,因此,你要帮我编译成 32 位的代码。
-------------------------------------------------------------------------------------------------
16 位代码与 32 位代码,除了使用的数据宽度区别外,另一个重要的区别就是:寻址模式。
16 位下:
只支持 [si]、[di]、[bp]、[bx] 这些基址寄存器与变址寄存器的间接寻址
以及:[bx+si]、[bx+di]、[bp+si]、[bp+di] 基址+变址的间接寻址
32 位下:
寻址模式就丰富得多了,并不局限于由 基址与变址 组合成的寻址。扩大到所有的 GPRs 寄存器。
cocd 16 与 code 32 同时出现在一个汇编语言文件里,主要是 OS 的实始化引导之类的程序。
用来从实模式切换到保护模式时使用。绝大多数的汇编源文件,不大可能同时出现这两个指示命令字
谢谢mik,还有proil,beep
在某种长度指令里,能不能表示某种寄存器,并不取决于该类寄存器的数据长度,而是看能不能容纳寄存器编码。也就是说,取决于寄存器的总数。比方说,某CPU里共有65537个寄存器,那code16肯定不能访问所有这些寄存器的。因为要对这65537个寄存器编码,至少17位,code16指令里连个寄存器编码都放不下,还有操作码,放哪儿?即使这65537个寄存器都是8位的,也不行。反过来,如果只有很少几个64位的、128位的寄存器,反而可以。譬如,有2个1024位寄存器,也只需要安排1位就可以了。
指令前缀可以指出指令时32位的还是16位的.
通常指令前缀编译器会自动加的
控制指令编码和访问寄存器是两码事。。。