Этот код немного сбивает с толку, потому что один показывает вызов, а другой - функцию.И для простоты они оба должны показать оба.Существует два этапа модификации стека с целью вызова соглашений:
- При подготовке к вызову, когда аргументы и помещаются в стек.
- В вызываемой функциигде локальные ресурсы расположены в стеке.
Разница между этими двумя соглашениями не "одна инструкция" и не имеет ничего общего с RET
, скажем,, но где происходит уборка.Аргументы помещаются в стек до вызова, поэтому они
- должны быть очищены, когда функция очищает себя (локальные).
- Должны быть очищены, когда послефункция возвращает.
Как примечание к импорту, у первого варианта есть свои преимущества, а именно то, что вы объявляете функцию с переменным количеством аргументов.
Весь фрагмент RET
кажетсяотвлекать внимание, поскольку в соглашении о вызовах нет ничего конкретного для x86.Фактически, Windows 10 работает на ARM, который даже не поддерживает RET
Более того, в первом примере с cdecl
компилятор мог написать:
ret 8
Вместо
add esp,8
ret
И это имело бы тот же эффект.Фактически, это спасло бы инструкцию