Я знаю, что '@ 4' - это размер стека, но зачем он нужен?
Чтобы позволить компоновщику сообщать о фатальной ошибке, если ваш компилятор ошибсяСоглашение о вызовах для функции (это может произойти, если вы забудете включить заголовочные файлы в C и проигнорируете все предупреждения компилятора или если объявление точно не соответствует функции в разделяемой библиотеке).
Почему функциям C не требуются декорации?
Функции, использующие соглашение о вызовах cdecl
, обозначаются одним начальным символом (так что на самом деле это будет _printf
).
Причина, по которой в оформленное имя не закодирован размер параметра, заключается в том, что вызывающая сторона отвечает как за установку, так и за удаление стека, поэтому несоответствие количества аргументов не будет фатальным для настройки стека (хотявызывающая функция может по-прежнему аварийно завершать работу, если ей, конечно, не даны правильные аргументы).Возможно даже, что количество аргументов является переменным, как в случае printf
.
Когда я смотрел в kernel32.dll с помощью шестнадцатеричного редактора, я видел только ExitProcess
not _ExitProcess@4
.
Искаженные имена обычно сопоставляются с фактическими экспортированными именами DLL с использованием файлов определений (*.def
), которые затем компилируются в *.lib
файлы библиотеки импорта, которые можно использоватьв вашем вызове компоновщика.Примером такого файла определения для kernel32.dll
является this .Следующая строка определяет отображение для ExitProcess
:
_ExitProcess@4 = ExitProcess
Это то, как я должен использовать эти функции?
Я не знаю NASM оченьхорошо, но код, который я видел до сих пор, обычно определяет оформленное имя, как в вашем примере.
Вы можете найти больше информации на этой превосходной странице о соглашениях о вызовах Win32 .