Значение регистра eax в ассемблерной программе

Я выполняю задание, связанное с программированием на языке C и ассемблере. Вот простая программа на языке C:

int multiply(int a, int b) {
    int k = 4; 
    int c,d, e;
    c = a*b ;
    d = a*b + k*c;
    return d;
}

И это оптимизированная сборка

_a$ = 8                                       ; size = 4
_b$ = 12                                                ; size = 4
_multiply PROC
        mov     eax, DWORD PTR _a$[esp-4]
        imul    eax, DWORD PTR _b$[esp-4]
        lea     eax, DWORD PTR [eax+eax*4]
        ret     0
_multiply ENDP

Я хочу знать значение регистра eax после этой строки кода в сборке

lea     eax, DWORD PTR [eax+eax*4]

Я знаю, что при добавлении целых чисел в сборку результат сохраняется в месте назначения. и когда мы умножаем, он сохраняется в eax. поэтому, если я вызову функцию умножения ( 3 , 8 ), значение регистра eax после этой строки должно быть 120. Я прав?


person narayanpatra    schedule 21.08.2019    source источник
comment
Один шаг через дизассемблирование с отладчиком и убедитесь сами?   -  person Lundin    schedule 21.08.2019
comment
Значение eax после выполнения этой инструкции должно равняться eax+eax*4   -  person ForceBru    schedule 21.08.2019
comment
Если вы подумаете об этом в обратном порядке, вы сможете сделать вывод... в предыдущей строке есть c в eax, то есть значение a*b. d = a*b + c*4 совпадает с d = c + c*4 (компилятор достаточно умен, чтобы понять это). lea eax, DWORD PTR [eax + eax*4] загружает eax со значением eax + eax*4, которое равно c + c*4, таким образом, желаемое возвращаемое значение функции. Тем не менее, я бы порекомендовал выполнить поиск в Интернете по x86 lea instruction, так как вы найдете много информации о том, что он делает и почему.   -  person lurker    schedule 21.08.2019
comment
Ваш вопрос, что делает инструкция lea? Если это так, обратитесь к Какова цель инструкции LEA?.   -  person Sander De Dycker    schedule 21.08.2019
comment
когда мы умножаем, он сохраняется в eax. Нет, это только если вы используете один операнд mul или imul и результат идет в EDX:EAX. Когда вы используете обычный 2-операнд imul, это точно так же, как add. Вы можете делать такие вещи, как imul esi, edi. (Это быстрее, потому что ему не нужно никуда записывать старшую половину, поэтому этот компилятор, похоже, MSVC, решил использовать imul eax, [esp-4 + _b$] вместо одного операнда imul dword ptr [esp-4 + _b$], хотя у него уже есть другой операнд в EAX и он было бы безопасно забить EDX)   -  person Peter Cordes    schedule 21.08.2019
comment
Что вы путаете? Почему ответ не будет точно таким, как вы ожидаете от источника C (godbolt. org/z/llPL8g показывает встроенную вызывающую программу) или из asm? Очевидно, что компилятор правильно реализует исходный код C, и эти входные данные не вызывают какого-либо неопределенного поведения C (например, переполнения со знаком), так в чем вопрос? Как видно из комментариев, людям приходится гадать, какой из них может быть полезен. Как это написано, одно слово «да» будет полным ответом на ваш вопрос. Обычно это признак того, что это не очень полезный или плохо сформулированный вопрос.   -  person Peter Cordes    schedule 21.08.2019
comment
@PeterCordes: надеюсь, ты никогда не окажешься на месте свидетеля :)   -  person mevets    schedule 21.08.2019
comment
@mevets: потому что адвокаты и судья будут жаловаться, если я попытаюсь прояснить вопрос? Должны ли мы просто предположить, что вопрос касается LEA, когда единственная ошибка в вопросе заключается в утверждении, что умножение всегда помещает результат в EAX? Для LEA существует несколько канонических дубликатов, поэтому этот вопрос имеет какую-либо причину для существования только в том случае, если он касается чего-то другого. Но что?   -  person Peter Cordes    schedule 21.08.2019
comment
@PeterCordes: да. Это была хорошая шутка, надеюсь, я вас не обидел.   -  person mevets    schedule 21.08.2019
comment
@mevets: да, я понял, что ты шутишь, я просто не был уверен, какая часть. Например, ответить на длинный, но, в конечном счете, вопрос «да» или «нет» просто «да»? Или просьба разъяснить? Я не обиделся, но я подумал, что вы могли использовать эту шутку, чтобы предположить, что некоторые из моих комментариев зашли слишком далеко или были слишком жесткими по этому вопросу. Если это была чисто шутка, то неважно :P   -  person Peter Cordes    schedule 21.08.2019


Ответы (1)


lea — это «загрузить эффективный адрес».

Наборы инструкций могут иметь довольно сложные режимы вычисления адреса с несколькими регистрами, которые обычно используются только для чтения и записи данных в память, но lea позволяет программисту получить адрес, к которому будет обращаться инструкция.

По сути, он выполняет вычисление внутри скобки, возвращает это значение - он не обращается к памяти (что обычно подразумевает скобка).

В данном случае она используется как быстрый способ умножить на 5, потому что остальная часть функции была оптимизирована!

person Gem Taylor    schedule 21.08.2019