【发布时间】:2014-11-27 09:11:36
【问题描述】:
我是汇编语言编程 (x86) 的初学者。
下面的说法对吗?
在像 BYTE、WORD、DWORD 这样的汇编数据类型中,分别表示 8 位、16 位和 32 位模式,而不仅仅是整数。它们本身没有意义,它们只是位模式。使用它们的说明赋予它们意义。
【问题讨论】:
我是汇编语言编程 (x86) 的初学者。
下面的说法对吗?
在像 BYTE、WORD、DWORD 这样的汇编数据类型中,分别表示 8 位、16 位和 32 位模式,而不仅仅是整数。它们本身没有意义,它们只是位模式。使用它们的说明赋予它们意义。
【问题讨论】:
“汇编”代码是关于许多特殊指令,它们对各种大小的操作数(对于 x86,1 个或更多字节)进行操作,这些操作数包含各个指令 假定 属于 特定 输入。
大多数基本指令集(例如 ADD、CMP、XOR)假定/处理其操作数,就好像它们是 N 字节 2 的补码整数一样。 BYTE、DWORD 等是表示“N”是什么的提示。
注意:大多数现代计算机都使用 2 的补码,因为 ADD、SUBTRACT 和 CMP(因为它本质上是减法)无论您将操作数解释为有符号结果还是无符号结果都会产生正确的答案,所以您只需要一条 ADD 和一条 SUB 指令,而不是每种类型的一条。 [在 CMP 之后,您确实需要知道操作数是有符号还是无符号。大多数现代 CPU 仅从 CMP 指令生成 unsigned-cmp 和 signed-cmp 结果,因此您只需要一条 CMP 指令。比较状态通常存储在具有无符号和有符号比较结果位的 CC 中。您确实需要 JMP SIGNED LESS 和 JUMP UNSIGNED LESS 指令]。
所谓的“浮点”指令通常将其操作数视为 32 位或 64 位 IEEE 浮点数。有一些“交叉”指令将一个操作数视为 2 的补码整数;这允许程序在这些表示之间进行转换。
所谓的字符串指令把操作数看成一个寄存器ECX长字符串,1、2、4或8个字节的值。
各种向量指令将其操作数视为 2 的补码整数的短向量或浮点数。
所以,是的,每个单独的机器指令假定其操作数的特定数据类型。
x86 汇编源代码在这一点上经常使人们感到困惑,因为看起来汇编语言程序员正在指定一个显式类型,例如DWORD 或 QWORD PTR。真正发生的事情是编码器正在编写一个广泛的指令类的名称(例如,MOV),并提供足够的提示,以便汇编器可以选择假定的特定二进制机器指令显式编码的数据类型。
【讨论】:
ja / jb) 或签名标志 (jg / jl) 取决于您的程序应如何解释数据。 This guide 适用于进位与溢出/无符号与有符号标志。
imul 的低半部分对于有符号/无符号也是一样的(因此缺少 2 或 3 个操作数或 mul,只是 imul r32,r32),当然按位的东西并不关心位的含义。