Незнакомый синтаксис для инструкции "imul" в сборке x86


Я написал очень простую C-функцию под названием "multby22", которая делает именно то, что подразумевает ее название: она занимает много времени и возвращает это время, умноженное на 22. (Я знаю, что это бессмысленная функция,но я написал ее, чтобы попытаться помочь мне с сборкой x86.) Итак:

long multby22(long x) {
    return 22 * x;
}

Когда я выполнил программу и запустил "objdump" на исполняемом файле, я нашел дизассемблированный код для "multby22" следующим образом:

080483ff <multby22>:
   80483ff:       55                    push   %ebp              
   8048400:       89 e5                 mov    %esp,%ebp         // Create the stack frame.
   8048402:       8b 45 08              mov    0x8(%ebp),%eax    // Grab the argument and put it into the %eax register.
   8048405:       6b c0 16              imul   $0x16,%eax,%eax   // ???
   8048408:       5d                    pop    %ebp              // Pop the buffer pointer and return.
   8048409:       c3                    ret   

Я понимаю, что "imul" - это для умножения целых чисел, но я был не могу найти ничего, что помогло бы мне с этим синтаксисом! Самое близкое, что я нашел, это:

imul [reg] [reg] [const]

...где 2-й и 3-й аргументы умножаются вместе и затем помещаются в 1-й аргумент, который должен быть регистром. В сборке, которую я сгенерировал, 1-й аргумент является константой!

2 4

2 ответа:

Вы нашли правильную инструкцию. Синтаксис сборки AT&T просто оказывается "обратным" по сравнению с тем, как это делают все остальные. Регистр назначения находится справа.

Ваш код умножает EAX на 22 (0x16) и помещает результат в EAX.

Если вы пытаетесь сравнить инструкции с документацией, вам, вероятно, следует обратиться к дизассемблеру, который может выводить синтаксическую разборку Intel.

0x16 = 22 в десятичной системе счисления. Компилятор записывает его в шестнадцатеричной системе счисления. Таким образом, первое будет умножено на второе и сохранено в третьем.