2010-03-10 7 views
3

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

как бы переписать это на ассемблере? (Как бы компилятор для C переписать его?)

int function(int a, int &b, int *c){ 
return a*(b++)+(*c); 
} 

я знаю, что это пример своего рода сосет .. но этот путь я могу понять все возможности

ответ

5

Что вы ищете, это информация о calling conventions. Способ вызова и возврата функций зависит от многих факторов, включая архитектуру процессора, компилятор и операционную систему. Вызывающий и вызывающий должны согласовать соглашение, чтобы параметры и возвращаемое значение были правильно переданы.

+1

Вызовы вызова также известны как прикладной двоичный интерфейс (ABI) http://en.wikipedia.org/wiki/Application_binary_interface. –

+0

ммм, классно. thx – Pyjong

3

Что Аарон сказал о вызовах конвенций, это правильный ответ. Для моего личного изучения темы я нашел Smashing the Stack For Fun and Profit, чтобы стать отличным упражнением в роли фрейма стека, и что может произойти, когда оно станет поврежденным. Finlay Я рекомендую assembly primer for hackers, который охватывает важные концепции ассемблера, а также забавные вещи, которые вы можете делать с вашим отладчиком.

+0

maaan !!! это видео ... huaaaahh !! объяснил все, даже те разочаровывающие регистры сегментов теперь мне понятны! БОЛЬШОЕ СПАСИБО!!! – Pyjong

+0

Ха-ха, я рад помочь. – rook

5

Во-первых, ссылки (int&) находятся не в C, а только на C++.

Если вы хотите увидеть, что происходит под капотом с gcc, используйте флаг -S. Вам не нужно иметь настоящую программу.

g++ -S func.c 

создает файл func.s, который содержит (минус заголовки и такие, на коробке x86):

.text 
.globl __Z8functioniRiPi 
__Z8functioniRiPi: 
LFB2: 
    pushq %rbp 
LCFI0: 
    movq %rsp, %rbp 
LCFI1: 
    movl %edi, -4(%rbp) 
    movq %rsi, -16(%rbp) 
    movq %rdx, -24(%rbp) 
    movq -16(%rbp), %rax 
    movl (%rax), %edx 
    movl %edx, %ecx 
    imull -4(%rbp), %ecx 
    movq -24(%rbp), %rax 
    movl (%rax), %eax 
    addl %eax, %ecx 
    incl %edx 
    movq -16(%rbp), %rax 
    movl %edx, (%rax) 
    movl %ecx, %eax 
    leave 
    ret 

Обратите внимание на имя C++ коверкая (__Z8functioniRiPi). Теперь мы даем г ++ на -O2 флаг:

.text 
    .align 4,0x90 
.globl __Z8functioniRiPi 
__Z8functioniRiPi: 
LFB2: 
    pushq %rbp 
LCFI0: 
    movq %rsp, %rbp 
LCFI1: 
    movl (%rsi), %ecx 
    movl %ecx, %eax 
    imull %edi, %eax 
    addl (%rdx), %eax 
    incl %ecx 
    movl %ecx, (%rsi) 
    leave 
    ret 

-O3 дает один и тот же код; оптимизировать нечего.

Удачи, играя со сборкой.^_^