16bit / 32bit x86

时间:2012-03-23 13:19:19

标签: assembly x86

学习指南问题:我不知道在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 总的话?

2 个答案:

答案 0 :(得分:4)

32位代码与16位代码存在一些差异:

  • 首先,当然,您的寄存器,索引和数据读取通常为32位宽。 (您可以使用地址大小和操作数大小前缀来更改它。通常您不会使用地址大小前缀,但对于读取16位字的32位代码,我可以看到使用的操作数大小前缀相当漂亮一些装配工将为你处理这件事。)

  • 32位寄存器的名称以E开头,基本上是16位寄存器的扩展。 (例如,AXEAX的低位词。不幸的是,没有内置的方法可以访问高位词。你必须旋转或移动寄存器才能进入高位词。位。)

  • 索引也不同。 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出现。

答案 1 :(得分:-2)

汇编程序代码不同,生成的目标代码也不同。你的学习指南是史前的,忘了16位,并用32位(或64!)写。当你的教授/导师说总和上的限制强烈暗示正在请求16位代码时,说"只有恐龙才能记住16位代码",(你可能想要考虑备份课程:)

我似乎误解了你的问题?如果您没有选择学习指南,那么是的,您会遇到16位指令和旧的16位寄存器 - AX,BX,CX,DX,PC,SP,SI,DI以及可能的段寄存器同样。

我现在不知道如何实际生成16位代码,尤其是在运行16位代码时出现问题的64位盒子上。在32位的盒子上,或者像DosBox这样的实用程序,你可以运行旧的MASM汇编器,然后运行可执行文件。