单词大小和它的指示

时间:2013-12-11 15:24:40

标签: assembly x86 word computer-architecture ia-32

请参阅下面有关各种指令集架构中字长的问题,以及它与汇编语言的关系。感谢您的帮助。

首先是一些事实(如果其中任何一个错误,请纠正我)。处理器架构的字大小表示(编辑:其中一些是错误的,请参阅下面的Seva帖子)

  1. 每个寄存器的最大尺寸
  2. 每个内存地址的最大大小(可以寻址的内存量)
  3. CPU可以在单个指令中处理的最大整数
  4. 可以在单个操作中传输到工作存储器和从工作存储器传输的最大数据
  5. 现在出现了一个非常奇怪的事情:在IA-32的汇编语言中,字被指定为16位长。 IA-32指的是支持32位计算的所有x86版本(即字应该是32位长)。

    这使我对单词及其表示的内容(上面的列表)完全理解。

    感谢您帮助我深究这一点,

    马格努斯

    编辑2:请参阅以下x86架构上的两个有用链接。

    1. 由altie发布:http://en.wikibooks.org/wiki/X86_Assembly/X86_Architecture
    2. 一个简单的x86指南我偶然发现:http://www.swansontec.com/sintel.html

2 个答案:

答案 0 :(得分:7)

所有这些假设都有反例。

  

每条指令的大小

Intel x86从一开始就有可变长度指令。在Thumb-2模式下,ARM也是如此。

  

每个寄存器的最大尺寸

你的意思是 - 整数寄存器,对吗?例如,Intel上的浮点寄存器长度为10个字节。这是最接近的。但英特尔x86是一个值得注意的例外 - 它的定义“字”在16位CPU时被修复;随着ISA的推移,定义停滞不前。

类似地,在ARM的AArch64指令集的上下文中,“字”表示“32位”,而通用寄存器是64位。 “字”的定义在ARM的32位鼎盛时期得到了修复,并一直保持不变。

  

每个内存地址的最大大小

显然是错的。 16位Intel 286具有24位地址空间。这是通过存储器管理单元(MMU)执行的 - 寄存器中的用户级地址与进入存储器子系统的物理地址不同。与最近的Intel CPU上的PAE相同。在过去,Intel x86的线性20位地址由16位段和偏移量组成。

  

CPU可以在单个指令中处理的最大整数

这个很接近 - 但是有例外。这里和那里有两个寄存器命令。 MIPS有hi:lo - 一对专用的32位寄存器,可以作为单个64位寄存器。英特尔拥有可在xDX:xAX对上运行的命令。并且不要让我开始使用SIMD。

  

可以在单个操作中传输到工作存储器和从工作存储器传输的最大数据

ARM具有“加载多个”和“存储多个”命令,可以一次存储多达16个寄存器。英特尔拥有PUSHA / POPA。在物理层面上,内存总线也各不相同。

肮脏的小事实是,在出现的书的上下文和使用它的汇编程序之外,没有单一的真正定义。在英特尔,“字”用于表示远古时代的16位块;当CPU变为32位和64位时,他们保留了定义,现在我们讨论的是DWORD和QWORDS。现代64位Intel CPU上的寄存器是QWORD大小的。 Windows API不再是严格的英特尔,它诞生于16位英特尔,仍然保留了数据类型。 WORD在windows.h中被定义为无符号短(2个字节),并且它们不能永远改变它 - 它会破坏结构布局,因此对于每个人来说都是二进制格式。

另一方面,在ARM上,“字”表示32位,即使在AArch64指令集的上下文中也是如此。因此,有一些汇编命令,如“加载半字”,可以使用16位操作数。因此,当在ARM上的C for Windows(即Windows Phone,Windows RT,Windows CE / Mobile)中进行编码时,以及在相同的程序集中进行编码时,您必须记住两个不同的定义。幸运的是,鉴于模棱两可,没有人会用语言来思考 - 至少在没有将真实大小保持在一个人心中的情况下。此外,ARM的汇编语言强烈鼓励尽可能多地使用32位值,并在必要时提升16位变量。因此,即使函数的16位参数也会在内部作为32位寄存器传递。

答案 1 :(得分:1)

详细说明Seva的声明“甚至不让我开始使用SIMD”,许多x86指令支持许多操作数类型。请参阅此处进行讨论:http://en.wikibooks.org/wiki/X86_Assembly/X86_Architecture

CPUID指令输出中的各个字段将告诉您支持哪些模式。例如,SSE标志将告诉您XMM寄存器是否可用,AVX标志将告诉您是否有YMM寄存器可用。