Я пытаюсь понять, как программа выполняет вызов функции (используя семантику C) с кодом сборки x86. Любая помощь будет принята с благодарностью.
Я не смог найти никаких источников, чтобы конкретно ответить на этот вопрос.
Я пытаюсь понять, как программа выполняет вызов функции (используя семантику C) с кодом сборки x86. Любая помощь будет принята с благодарностью.
Я не смог найти никаких источников, чтобы конкретно ответить на этот вопрос.
В x86 для этого есть инструкции call
и ret
. call
сохранить текущий адрес в стеке и перейти к метке, переданной в качестве аргумента. И инструкция под названием ret
извлекает этот адрес и переходит к нему после добавления к этому адресу одного байта.
Пример кода:
С
int sum(int a, int b)
{
return a + b;
}
void f(void)
{
sum(2, 2);
g();
}
Компилятор может сгенерировать (пример, похожий на сборку x86):
f:
push 2
push 2
call sum
call g
ret
sum:
pop eax
pop ebx
add eax, ebx
ret
Я надеюсь, что это помогает
Мне повезло со следующими ресурсами в прошлом.
Если вы ищете, как вызовы функций транслируются в ассемблер, поищите соглашение о вызовах __cdecl
по приведенным выше ссылкам. По сути, разные соглашения о вызовах определяют разные (и не всегда стандартизированные) способы передачи параметров путем манипулирования стеком, и __cdecl
— это лишь один из способов — соглашение о вызовах «C».
Если вам интересно, как вызвать функцию C из ассемблерного кода, последние две ссылки очень хороши.
Еще один совет, который я могу дать: если у вас есть ассемблерная функция, которую вы хотите вызвать из C, укажите соглашение о вызовах в объявлении функции на C. Например, однажды я написал ассемблерный код, следуя соглашению о вызовах __stdcall
вместо __cdecl
, поэтому в сигнатуре функции я явно указал соглашение __stdcall
.