[英]operand size mismatch for `imul '
虽然我只使用 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
这是一个虚假的错误信息。 问题不是操作数大小,而是imul
的目标必须是寄存器。 https://www.felixcloutier.com/x86/imul 。 只有源可以选择为 memory。
(AT&T 语法是op src, dst
,与使用 Intel 语法的 Intel 手册相反。)
当你得到一个没有意义的错误时,你应该查阅 ISA 参考并确保你想要的指令实际上是可编码的:汇编程序打印一个不能正确解释为什么指令可以的错误消息并不是闻所未闻的。不被组装。 但通常它要么是不明确的操作数大小,要么是您想要的编码不存在。
也许 GAS 内部将 memory 目标视为具有未知或一些随机大小,并且没有任何东西像add %reg, (mem)
那样暗示该操作数的大小。 也许是因为imul
没有记忆目的地形式。
像普通人一样将局部变量保存在寄存器中。 当您用完寄存器时,您只需要将变量溢出到堆栈上的插槽。
EAX、ECX 和 EDX 在正常调用约定中被调用破坏,因此您可以在不保存/恢复的情况下使用它们。 (EBX 是保留调用的,因此您的 function 已经破坏了调用者的 EBX 值,从而违反了调用约定。)
cmpl -4(%ebp), %ecx #compare with the argument
je _found #epilogue and returning
jmp _finding_loop
永远不要在jmp
上写条件分支。 而是执行jne top_of_loop
以保持循环或失败。
IDK 你的循环应该做什么。 您没有初始化 memory 目标。 您是否认为它将ebx*ebx
的结果存储到 memory 中? 如果是这样,为什么首先将 EAX 复制到 EBX?
看起来您正在搜索一个数字的 sqrt,而不仅仅是一个数字的平方,所以 function 的名称很奇怪。 如果是这样,您可能希望jb
作为您的循环条件,以在x*x < target
时继续循环,并在循环后排序 equal vs. above。 (如果 function 被调用的 arg 不是一个完美的正方形。)
.globl find_exact_sqrt
find_exact_sqrt:
mov 4(%esp), %ecx # target number
mov $1, %eax # start searching from 2*2=4
.Lloop: # file-local label, not exported in the symbol table
# do {
inc %eax
mov %eax, %edx
imul %edx, %edx # eax squared
cmp %ecx, %edx
jb .Lloop # }while(i*i < target); // unsigned
ret
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.