несоответствие размера операнда для imul - PullRequest
0 голосов
/ 21 сентября 2019

хотя я использую только длинные для умножения, понятия не имею, почему 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 Ответ

2 голосов
/ 21 сентября 2019

Это ложное сообщение об ошибке.Проблема не в операнде size , а в том, что адресат imul должен быть регистром. https://www.felixcloutier.com/x86/imul. Опционально памятью может быть только source .

(Синтаксис AT & T равен op src, dst, в отличие от руководств Intel, в которых используется синтаксис Intel.)

Если вы получаете ошибку, которая не имеет смысла, вам следует обратиться к справочнику 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

Никогда не записывайте условную ветвь более a jmp.Вместо этого выполните jne top_of_loop, чтобы продолжить цикл или провалиться.


IDK, что должен делать ваш цикл.Вы не инициализировали адрес своей памяти.Вы думали, что он собирается сохранить результат ebx*ebx в памяти?Если это так, то зачем сначала копировать EAX в EBX?

Похоже, вы ищете квадрат числа, а не просто возводите квадрат в квадрат, поэтому имя функции странное.Если это так, вы, вероятно, хотите, чтобы jb в качестве условия цикла продолжало цикл, пока x*x < target, и сортировало равное или выше после цикла.(Если функция вызывается с аргументом, который не является идеальным квадратом.)

.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
...