简体   繁体   中英

operand size mismatch for `imul '

although I use only longs for multiplication, Have no idea, why the 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

That's a bogus error message. It's not operand size that's the problem, it's that imul 's destination has to be a register. https://www.felixcloutier.com/x86/imul . Only the source can optionally be memory.

(AT&T syntax is op src, dst , opposite of Intel's manuals which use Intel syntax.)

When you get an error that doesn't make sense, you should consult an ISA reference and make sure the instruction you want is actually encodeable: it's not unheard of for assemblers to print an error message that doesn't properly explain why an instruction can't be assembled. But usually it's either an ambiguous operand-size or that the encoding you want doesn't exist.

Perhaps GAS internals treat a memory destination as having unknown or some random size, and nothing kicks in to imply a size for that operand the way it would for add %reg, (mem) . Maybe because imul doesn't have a memory-destination form.


Keep your local variables in registers like a normal person. You only need to spill a variable to a slot on the stack when you run out of registers.

EAX, ECX, and EDX are call-clobbered in the normal calling conventions so you can use them without saving/restoring. (EBX is call-preserved so your function is already violating the calling convention by destroying its caller's EBX value.)


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

Never write a conditional branch over a jmp . Instead do jne top_of_loop to either keep looping or fall through.


IDK what your loop is supposed to do. You didn't initialize your memory destination. Did you think it was going to store the result of ebx*ebx into memory? If so, why copy EAX to EBX in the first place?

It looks like you're searching for the sqrt of a number, not just squaring a number, so the function name is weird. If so, you probably want jb as your loop condition to keep looping while x*x < target , and sort out equal vs. above after the loop. (In case the function is called with an arg that isn't a perfect square.)

.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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM