use*_*277 6 x86 assembly types
x86 CPU有一些处理整数和浮点数的指令.
例如:INC指令递增一个整数(可以存储在存储器或寄存器中)1,因此INC指令"知道"它应该将它正在操作的位解释为整数.那么我们可以说x86 CPU有数据类型(我们可以说C++有数据类型)吗?或者为了让我们能够说出来,x86 CPU应该提供类型安全等其他功能(它没有提供)?
Pet*_*des 10
是的,asm的操作可以处理不同格式的数据,您可以调用这些类型.但是类型安全性为零.这是表达它的好方法.
因此INC指令"知道"它应该将它正在操作的位解释为整数.
但这是表达这一点的笨拙方式. INC不"知道"任何东西 ; 它只是将操作数提供给ALU中的二进制加法器. 完全由程序员(或编译器)在正确的字节上以正确的顺序使用正确的指令来获得所需的结果. 例如,用类型实现高级变量.
每个asm指令都会在锡上执行它所说的,不多也不少.指令集参考手册条目中的"操作"部分记录了它对机器的体系结构状态的全部影响,包括FLAGS和可能的异常.例如inc.或者是一个更复杂的指令,带有更有趣的伪代码,显示每个位的存放位置,BMI2pdep r32a, r32b, r/m32(和图表).这些都摘自英特尔的PDF有一个前奏部分,介绍像任何标记CF ? Bit(BitBase, BitOffset);为bts(位检查并设置)
一切都只是字节(包括指针,浮点数,整数,字符串,甚至是像x86这样的冯·诺伊曼体系结构中的代码).(或者在某些东西不是1字节的倍数的机器上,一切都只是位.)
什么都不会为你的类型宽度神奇地缩放索引.(虽然AVX512确实disp8在寻址模式中使用缩放,但是8位位移可以编码最多为矢量宽度的-128 .. + 127倍,而不是只有那么多字节.在源级汇编中,你仍然可以写入字节偏移,并且在可能的情况下由汇编程序使用更紧凑的机器代码编码.)
如果你想inc al在指针的低字节上使用循环(对齐)数组的前256个字节,那就完全没问题了.(并且在P6系列以外的CPU上有效,在读取完整寄存器时会出现部分寄存器停顿.)
在某种程度上,x86对许多类型都有本机支持.大多数整数指令有字节,字,双字和qword 操作数大小.当然还有FP指令(float/ double/ long double),甚至是大多数过时的BCD内容.
如果您关心有符号溢出和无符号溢出,请分别查看OF或CF. (所以有符号与无符号整数的关系是你在大多数指令之后看到的标志,因为add/sub对于无符号和2的补码是相同的二进制运算).
但扩大的倍数和除法确实来自有符号和无符号版本.单操作数imul与mul(和BMI2 mulx)进行有符号或无符号N x N => 2N位乘法.(但通常你不需要高半结果,并且可以简单地使用更高效的imul r32, r/m32(或其他操作数大小).乘法的低半部分是输入的有符号或无符号解释的相同二进制操作数;只有高半部分取决于输入的MSB是否具有正或负的位置值.)
使用与您正在实现的C++数据类型相同的操作数大小并不总是一个好主意.例如,通常可以使用32位操作数大小计算8位和16位,从而避免任何部分寄存器问题.对于add/sub,进位仅从LSB传播到MSB,因此您可以执行32位操作并仅使用结果的低8位.(除非您需要右移或其他东西.)当然,8位操作数大小cmp可以很方便,但这不会写任何8位寄存器.
x86数据类型/格式不仅包括整数
float和doubleSSE和SSE2以及x87内存操作数.vcvtph2ps反向):仅加载/存储.一些Intel CPU在GPU中具有半精度mul/add支持,但x86 IA内核只能转换为节省内存带宽并至少float用于向量FP数学指令.fbstpbt/ bts/ etc的位图:bts [rdi], eax可以在dword 之外选择一个位rdi.与寄存器目标不同,位索引不会被&0x1f(https://www.felixcloutier.com/x86/bt)屏蔽.(这就是为什么bt/bts/etc mem,reg这么多uops,而reg,reg和mem,立即也不错).另请参阅如何阅读英特尔操作码表示法,以获取英特尔指令集参考手册中使用的所有表示法列表.例如,r/m8是8位整数寄存器或存储器位置. imm8是一个8位立即数.(如果大于8,通常将符号扩展为操作数大小.)
本手册使用m32fp表示x87 FP内存操作数,m32int表示x87 fild/ fistp(整数加载/存储),以及其他整数源x87指令fiadd.
还有像m16:64这样的东西,内存中的远指针(段:偏移量),例如作为间接远jmp或远的操作数call.  计算远端指针和x86支持的"类型"肯定是合理的.  有些指令从指向的2 + 8字节操作数lgs rdi, [rsi]加载.(当然,更常用于16位代码.)gs:rdirsi
m128/xmm可能不是你真正称之为"数据类型"的东西; 没有SIMD指令实际上将操作数视为128位或512位整数.除了shuffle之外,64位元素是最大的.(或纯粹的按位运算,但这实际上是并行的128个独立的AND运算,根本没有相邻位之间的交互.)