Вызовы функций и сборка

Я пытаюсь понять, как программа выполняет вызов функции (используя семантику C) с кодом сборки x86. Любая помощь будет принята с благодарностью.

Я не смог найти никаких источников, чтобы конкретно ответить на этот вопрос.


person Nancy Raon    schedule 30.09.2014    source источник
comment
Безусловно, самый простой способ понять это — написать программу на языке C и скомпилировать ее с помощью вашего любимого компилятора с возможностью генерирования выходного листинга или — в противном случае — запустить приложение под отладчиком.   -  person 500 - Internal Server Error    schedule 30.09.2014
comment
Любой ответ, который будет вам полезен, будет зависеть от ABI, на который вы ориентируетесь. С какой машиной/средой/тулчейном вы работаете?   -  person Carl Norum    schedule 01.10.2014
comment
Вы ищете понять некоторые соглашения о вызовах?   -  person Jack    schedule 01.10.2014
comment
Тысячи просмотров с помощью Google вызова функции кода x86 на ассемблере - первый довольно приятный.   -  person TimSPQR    schedule 01.10.2014


Ответы (2)


В 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

Я надеюсь, что это помогает

person Jack    schedule 30.09.2014

Мне повезло со следующими ресурсами в прошлом.

Если вы ищете, как вызовы функций транслируются в ассемблер, поищите соглашение о вызовах __cdecl по приведенным выше ссылкам. По сути, разные соглашения о вызовах определяют разные (и не всегда стандартизированные) способы передачи параметров путем манипулирования стеком, и __cdecl — это лишь один из способов — соглашение о вызовах «C».

Если вам интересно, как вызвать функцию C из ассемблерного кода, последние две ссылки очень хороши.

Еще один совет, который я могу дать: если у вас есть ассемблерная функция, которую вы хотите вызвать из C, укажите соглашение о вызовах в объявлении функции на C. Например, однажды я написал ассемблерный код, следуя соглашению о вызовах __stdcall вместо __cdecl, поэтому в сигнатуре функции я явно указал соглашение __stdcall.

person Community    schedule 30.09.2014