2014-09-30 3 views
-1

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

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

+4

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

+0

Любой ответ, который будет вам полезен, будет зависеть от ABI, на который вы нацеливаетесь. С какой машиной/средой/инструментальной цепью вы работаете? –

+0

Вы ищете понимание некоторых конвенций? – Jack

ответ

1

В x86 для этого есть инструкции, которые называются call и ret. call сохранить текущий адрес в стеке и jmp на метку, переданную как аргумент. И инструкция, называемая ret, поп этот адрес и прыжок к ней после добавления одного байта на этот адрес. Пример

Код:

C

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 

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

0

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

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

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

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