Assembly 奇怪的数据大小?

Assembly 奇怪的数据大小?,assembly,x86,gdb,word,att,Assembly,X86,Gdb,Word,Att,但在x86汇编AT&T语法中,我使用movw move word将半字移动到16位寄存器,使用movl move long将字移动到32位寄存器。我在一个运行32位操作系统的64位操作系统上使用虚拟机 我做错了什么 这是否意味着在我的虚拟机中运行的操作系统的大小是: 1 Byte = 8bits 1 Halfword = 16bits = 2 Bytes 1 Word = 32 bits = 4 Bytes 1 Long = 64 bits = 8 Bytes 我查看了GDB的尺寸,我认为它们

但在x86汇编AT&T语法中,我使用movw move word将半字移动到16位寄存器,使用movl move long将字移动到32位寄存器。我在一个运行32位操作系统的64位操作系统上使用虚拟机

我做错了什么

这是否意味着在我的虚拟机中运行的操作系统的大小是:

1 Byte = 8bits
1 Halfword = 16bits = 2 Bytes
1 Word = 32 bits = 4 Bytes
1 Long = 64 bits = 8 Bytes
我查看了GDB的尺寸,我认为它们是:

1 Byte = 4bits
1 Halfword = 8bits = 2 Bytes
1 Word = 16 bits = 4 Bytes
1 Long = 32 bits = 8 Bytes

在x86中,一个字始终为16位:

1 Byte = 8bits
1 Halfword = 16bits = 2 Bytes
1 Word = 32 bits = 4 Bytes
1 Long = 64 bits = 8 Bytes 
32位计算机上的GDB/实际大小:

1 Byte = 8 bits
1 Word = 16 bits = 2 Bytes
1 Dword (long) = 32 bits = 8 Bytes
1 Qword = 64 bits = 16 Bytes
由于16位处理器的原因,英特尔在字大小上搞砸了。

术语字大小,或,通常指寄存器的大小和本机加载/存储的大小。维基百科的文章提到了我在这个答案中写的一些相同的东西

对于64位系统,一个字可能意味着8个字节,但64位RISC机器通常使用字=32位。它们中的大多数都是从32位RISC ISA演变而来的,因此保留相同的术语并将64位称为双字是很自然的

注意,GDB使用自己的单词概念,与ISA分开

但是x86是从16位8086演变而来的,其中word=16位。当x86扩展为32位模式i386时,对每个人来说最简单的选择就是保持所有东西的名称相同。x86双字仍然是32位,x86字仍然是16位。即使是原始的8086+8087也可以加载和存储dword和qword整数、浮点数和双精度数,并且在8086中存在cwd sign extend word to dword等指令,用于设置idiv,因此在386将寄存器宽度扩展到dword之前,这些术语已经被充分使用

还要注意的是,重命名所有内容会让人非常困惑,因为当386是新的时,它们中的大多数仍然在16位模式下运行DOS程序。即使是现代的x86-64 CPU也完全支持在16位实模式下运行,因此,在英特尔手册的不同部分中,让word有不同的含义是非常令人困惑的

字节始终是8位的八位字节,但在某些历史计算机体系结构中除外。有一些是9位字节的。C标准仍然不需要CHAR_BIT=8,因此要编写完全可移植的代码,不能假设或2的补码是有符号整数

因此,在x86文档和asm助记符/语法中:

B=Byte=8位PADDB在向量中添加压缩的8位整数 W=word=16位PADDW在向量中添加压缩的16位整数 D=长或dword双字=32位填充D在向量中添加压缩的32位整数 Q=quad word=64位PADDQ在向量中添加压缩的64位整数 DQ=双四元组有时oct word=128b movdqa拷贝对齐128b。PUNPCKLQDQ:将128b src和dest的两个64位低位Q字交织到DQ dest中。 AVX movdqa ymm0,[rdi]是32B负载,尽管它仍然使用相同的助记符。AVX更像是多个128b通道,而不是真正的本机256b向量,因此这种方法是合理的

在NASM语法中,像mov ax这样的语法有时需要单词ptr[rdi]来指定操作数大小,而不是从dest寄存器推断操作数大小。AT&T语法使用助记符上的后缀来指定操作数大小,如果您不想让它保持隐式并从寄存器选择中推断:movw%rdi,%ax

助记符中的B/W/D事物早于向量扩展,例如字符串移动指令中的B/W/D事物。STOS没有*rdi+=size=al/ax/eax/rax。它可以用操作数写入,如 STOS字节指针[RDI]告诉汇编程序要编码的操作数大小版本。但是,即使使用Intel/MASM/NASM语法,也可以编写STOSB/STOSW/STOSD/STOSQ

x86并不是一个面向单词的体系结构。 机器字的整个概念并不适合x86。仅32位的P5奔腾CPU保证了最多64位的原子加载/存储。e、 g.使用x87或MMX,即使整数寄存器宽度仅为32位。64位CAS需要在32位模式下锁定cmpxchg8b

对于x86-64,可以保证对SSE2的支持,因此我们有16字节向量寄存器,并且基本上可以有效地支持每个操作数大小为8、16、32或64位的整数指令。由于32位操作数大小是x86-64机器代码中的默认值,因此不需要额外的前缀,因此对于代码大小以及除此之外的其他性能(例如,对于某些CPU上的div或imul),它是最有效的

此外,未对齐的加载和存储是完全有效的,甚至不需要额外的缓存RMW周期来将未对齐或字节存储提交到L1d缓存,只要它们不跨越缓存线边界。指令格式是字节流,而不是对齐的字


因此,说现代x86-64有任何特定的字长并不是很有意义。这个概念不适合x86-64作为ISA,当然也不适合具有高效未对齐加载/存储的实际现代微体系结构。

请参见Peter Cordes的答案。带半字的GDB列表对于Intel和compatibles没有任何意义。对于这一点,无论您使用的是16位、32位还是64位处理器。英特尔没有搞砸。我猜
你在想机器词。这些在这里不起作用。字节、单词等有固定的含义和大小。是的,你是对的,我以为一台32位的电脑应该有一个32位的单词来表示所有内容,请阅读下面的引号。我所说的英特尔混乱的意思是,他们选择了16位,这样它就可以与一些旧处理器兼容,但我想我错了。非常感谢。处理器中的大多数寄存器通常是字大小的,在许多并非所有的体系结构中,在一次操作中可以向工作存储器传输或从工作存储器传输的最大数据段是一个字。-在Wikipedia about wordsISTM上,您将机器词与单词类型混淆。另一个重复:和相关:
1 Byte = 8bits
1 Halfword = 16bits = 2 Bytes
1 Word = 32 bits = 4 Bytes
1 Giant (long) = 64 bits = 8 Bytes