16 位/32 位 x86

tem*_*ame 1 x86 assembly

学习指南问题:不过,我不知道用 16 位和 32 位编写它有什么区别。有人可以澄清这如何改变事情吗?

编写一个 80x86 汇编程序,该程序将在内存中添加字大小的有符号整数,并在看到零时停止。总和将始终大于 -32768 且小于 32767。总和应写入内存。如果整数串中只有一个零,则总共放置一个 0。使用 JNZ 命令。(如果最后一个操作导致一个标签的零跳转。)

16 位整数 DW 2,-300, 54, 30, 8,,-240, 0 总 DW ?

32 位整数 WORD 2,-300, 54, 30, 8,,-240, 0 共 WORD ?

cHa*_*Hao 5

32 位代码与 16 位代码有几个区别:

  • 首先,当然,您的寄存器和索引以及数据读取通常是 32 位宽。(您可以使用地址大小和操作数大小前缀来更改它。通常您不会使用地址大小前缀,但对于读取 16 位字的 32 位代码,我可以看到操作数大小前缀使用得很好广泛。一些组装者会为你处理。)

  • 32 位寄存器的名称以E,开头,基本上是 16 位寄存器的扩展。(例如,AX是 的低位字EAX。不幸的是,没有访问高位字的内置方法。您必须旋转或移位寄存器才能到达高 16 位。)

  • 索引也不同。16 位代码在如何组合寄存器方面受到更多限制。你会看到很多[BX+SI],但 IIRC[AX+BX]甚至不合法。它是 32 位代码。另外,32 位代码可以缩放第一项(乘以 1、2、4……我忘记是否允许 8)。例如,[EBX*4+ECX]

  • 在 16 位代码中,寄存器有相当严格的用途;例如,CX 是一个计数器,BX 基本上是一个基指针,SI 和 DI 是索引——因此它们的名字。反对这一点往往意味着跳过箍。在 32 位代码中,这明显放松了;虽然寄存器仍然主要保留其特殊用途,但更灵活的索引可以让几乎任何空闲寄存器用作索引。

  • 保护模式几乎始终开启。(有一些特殊情况,但它们不再常见了。你必须编写一个 DOS 游戏或其他东西才能看到它;每个像样的操作系统都会尽快进入保护模式。)有很多限制等等那就随它去吧。但是,除非您尝试执行内核级别的操作,否则大多数对您来说都是不可见的。大多数 16 位代码旨在以“实模式”或“虚拟 8086”模式运行,在这种模式下,CPU 基本上就像一个非常快的 8086,时髦的寻址等等。

  • 哦,是的,寻址。16 位代码使用“段”,其中段寄存器(CSDS等)简单地左移 4 位并添加到“偏移量”中,为您提供 20 位值(最大:1MB)。32 位代码远不及常规,但也远不及有限;它将段寄存器重新用作“选择器”,它可以指向 CPU 地址空间中的任何位置,但必须在描述符表(GDT 或 LDT)中进行设置。实际上,32 位代码几乎总是将所有段设置为指向同一内存区域。这就是所谓的“平面模型”,是迄今为止最常见的设置。16 位代码有六种不同的内存模型,这取决于代码和数据需要有多大。

原始数据的指令/指令通常相同;DW仍然通常表示“这是一个词”,DD表示“这是一个双字”等。

顺便说一句,“x86”和“80x86”通常意味着“32位”——主要是因为这个术语在32位CPU出现之前并不常见。