簡體   English   中英

'imul' 的操作數大小不匹配

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM