“ imul”的操作数大小不匹配

时间:2019-09-21 13:56:47

标签: assembly x86 att

尽管我只使用long进行乘法运算,但不知道为什么operand size is wrong

.type _square, @function
_square:
pushl %ebp
movl %esp, %ebp
subl $4, %esp #room for the local variable

movl 8(%ebp), %ecx #the first and only argument
movl $1, %eax

_finding_loop:
incl %eax
movl %eax, %ebx
imull %ebx, -4(%ebp) #storing the result in local var
cmpl -4(%ebp), %ecx #compare with the argument
je _found #epilogue and returning
jmp _finding_loop

1 个答案:

答案 0 :(得分:2)

这是一个伪造的错误消息。问题不是操作数 size ,而是imul的目的地必须是寄存器。 https://www.felixcloutier.com/x86/imul。只有 source 可以选择是内存。

(AT&T语法为op src, dst,与使用英特尔语法的英特尔手册相反。)

当您发现没有道理的错误时,应查阅ISA参考并确保所需的指令实际上是可编码的:汇编程序会打印一条错误消息,提示未正确解释原因,这并非闻所未闻。指令无法汇编。但是通常它要么是一个模糊的操作数大小,要么是您想要的编码不存在。

也许GAS内部人员将内存目标视为未知大小或随机大小,而没有任何迹象表明该操作数的大小与add %reg, (mem)相同。也许是因为 imul没有存储目标形式。


像普通人一样将局部变量保存在寄存器中。当寄存器用完时,只需要将变量溢出到堆栈上的插槽中即可。

EAX,ECX和EDX在常规呼叫约定中被称为呼叫拥挤者,因此您可以在不保存/恢复的情况下使用它们。 (EBX是调用保留的,因此您的函数已经破坏了调用者的EBX值,从而违反了调用约定。)


cmpl -4(%ebp), %ecx #compare with the argument
je _found #epilogue and returning
jmp _finding_loop

切勿在{{1​​}}上的上写一个条件分支。而是jmp保持循环或掉线。


IDK您的循环应该做什么。您没有初始化存储目标。您是否认为它将jne top_of_loop的结果存储到内存中?如果是这样,为什么要先将EAX复制到EBX?

看起来您正在搜索一个数字的sqrt,而不仅是平方一个数字,因此函数名称很奇怪。如果是这样,您可能希望将ebx*ebx作为循环条件,以在jb时保持循环,并在循环后对上述变量进行比较。 (如果用不是理想正方形的arg调用该函数,则为该参数。)

x*x < target