assembly - 从寄存器中减去变量?错误 A2022 : instruction operands must be the same size

标签 assembly x86 masm

.data
    num1    word   0FEEDh

.code
main PROC
    mov     ecx, 0E4C7FFFDh   ;ecx = 0E4C7FFFD hex
    sub     ecx, num1         ;;;;; error on this line

我希望能够从寄存器 ecx 中减去变量 num1,但该尝试给出:

error A2022: instruction operands must be the same size

我对 Assembly 很陌生,正在尝试了解基础知识。我怎样才能做到这一点?

最佳答案

ecx是一个32位寄存器,一个dword(双字);在x86术语中,一个WORD是2个字节。
当您尝试时:

sub     ecx, num1         ;ecx = ecx - num1

汇编器检查了标签num1,发现它的类型为word,因此尝试生成

sub     ecx, word ptr [num1]    ;ecx = ecx - num1

但是该操作码不存在。

subsub r32, r/m32 形式确实存在,但从 2 字节变量加载 4 字节会在高半部分引入 2 字节垃圾。

sub     ecx, dword ptr [num1]   ; don't *just* change to this

这可以汇编,但您需要将 num1 更改为双字才能使其正确。 (除非您还想将 num1 之后组装的任何 2 个字节读取到 .data 部分中)。如果您使用 num1 dword 0FEEDh,MASM sub ecx, num1 将起作用,因为它将推断内存操作数的正确大小。如果您想让 MASM 根据您使用变量的方式检查变量大小,请忽略操作数大小覆盖,除非您需要它们(例如,从字符串中一次复制 4 个字节。)


汇编器建议通过将 num1 设为双字变量或将 ecx 更改为 cx 来解决该问题。这没有错(cx 无法存储你的常量,但 masm 不知道);然而还有另一种可能性。您可以零扩展到暂存寄存器并减去它:

movzx   edx, num1    ; zero-extending load from a byte or word var
sub     ecx, edx

或者如果 num1 已签名(masm 有一个 SWORD 但我通常看到 WORD 用于两个签名且未签名):

movsx   edx, num1    ; sign-extending load
sub     ecx, edx

关于assembly - 从寄存器中减去变量?错误 A2022 : instruction operands must be the same size,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70911147/

相关文章:

linux - 有没有人在 Linux 的 Wine 中使用 MASM 汇编语言?

c - 在 C 中模拟 thiscall 以实现无需自引用的结构函数

assembly - 堆栈和寄存器在汇编器中如何工作?

c - C程序的调试(Redis服务器)

exception - 这个汇编代码如何设置 SEH?

汇编编程 - WinAsm 与 Visual Studio 2017

assembly - x86 程序集中是否有任何暂停/ sleep 或事件

函数返回结构的调用约定

assembly - 编译器可以优化汇编中的函数前导码吗?

linux汇编反转一个字符串