Что происходит в ассемблере, когда Вы называете метод/функцию?

Инструментарий Разработчика Facebook раньше был довольно плох. Теперь версия 2.0 отсутствует и выглядит большой. Вот рецензия.

, Как Использовать Инструментарий Разработчика Facebook 2.0 - Devtacular

19
задан Gordon Gustafson 12 February 2010 в 22:21
поделиться

11 ответов

Обычно происходит следующее:

  1. Аргументы функции хранятся в стеке. В порядке, зависящем от платформы.
  2. Местоположение для возвращаемого значения «выделяется» в стеке
  3. Адрес возврата для функции также сохраняется в стеке или в специальном регистре ЦП.
  4. Функция (или фактически , адрес функции) вызывается, либо через специфичную для ЦП команду вызова , либо через обычную инструкцию jmp или br (переход / переход)
  5. Функция читает аргументы (если есть) из стека и запускает код функции
  6. Возвращаемое значение из функции сохраняется в указанном месте (стек или регистр ЦП специального назначения)
  7. Выполнение переходит обратно к вызывающей стороне, и стек очищается (путем восстановления указателя стека в исходное значение).

Подробности вышеизложенного варьируются от платформы к платформе и даже от компилятора к компилятору (см., например, соглашения о вызовах STDCALL и CDECL). Например, в некоторых случаях регистры ЦП используются вместо хранения данных в стеке. Однако общая идея та же

Подробности вышеизложенного варьируются от платформы к платформе и даже от компилятора к компилятору (см., Например, соглашения о вызовах STDCALL и CDECL). Например, в некоторых случаях регистры ЦП используются вместо хранения данных в стеке. Однако общая идея та же

Подробности вышеизложенного варьируются от платформы к платформе и даже от компилятора к компилятору (см., Например, соглашения о вызовах STDCALL и CDECL). Например, в некоторых случаях регистры ЦП используются вместо хранения данных в стеке. Однако общая идея та же

44
ответ дан 30 November 2019 в 02:07
поделиться

Вы можете убедиться в этом сами:

Под Linux «скомпилируйте» свою программу с помощью:

gcc -S myprogram.c

И вы получите листинг программы на ассемблере (myprogram.s).

Конечно, вы должны немного знать об ассемблере, чтобы понять его (но его стоит изучить, потому что он помогает понять, как работает ваш компьютер). Вызов функции (на архитектуре x86) в основном:

  • помещает переменную a в стек
  • помещает переменную b в стек
  • помещает переменную n в стек
  • переход к адресу функции
  • загружает переменные из stack
  • делать что-то в функции
  • чистый стек
  • вернуться к основному
13
ответ дан 30 November 2019 в 02:07
поделиться

Что происходит при сборке?

Краткое объяснение: текущее состояние стека сохраняется, создается новый стек, загружается и запускается код функции, которая должна быть выполнена. Это включает неудобства для нескольких регистров вашего микропроцессора, некоторые безумные чтения / записи в память, и после этого состояние стека вызывающей функции восстанавливается.

3
ответ дан 30 November 2019 в 02:07
поделиться

Аргументы помещаются в стек и выполняется инструкция "call"

Вызов представляет собой простой "jmp" с помещением адреса инструкции в стек ("ret" в конце метода хлопая и прыгая на нем)

1
ответ дан 30 November 2019 в 02:07
поделиться

Думаю, вы хотите взглянуть на стек вызовов, чтобы лучше понять, что происходит во время вызова функции: http://en.wikipedia.org/wiki/Call_stack

1
ответ дан 30 November 2019 в 02:07
поделиться

Очень хорошая иллюстрация: http://www.cs.uleth.ca/~holzmann/C/system/memorylayout.pdf

1
ответ дан 30 November 2019 в 02:07
поделиться

1- контекст вызова устанавливается в стеке

2- параметры помещаются в стек

3- выполняется «вызов» метода

0
ответ дан 30 November 2019 в 02:07
поделиться

Общая идея заключается в том, что вам необходимо

  1. сохранить текущее локальное состояние
  2. передать аргументы функции
  3. вызвать фактическую функцию. Это включает в себя размещение адреса возврата где-нибудь, чтобы инструкция RET знала, где продолжить.

Особенности варьируются от архитектуры к архитектуре. И даже более конкретная специфика может варьироваться в зависимости от языка. Хотя обычно есть способы контролировать это до некоторой степени, чтобы обеспечить взаимодействие между разными языками.

Довольно полезной отправной точкой является статья Википедии о соглашениях о вызовах . Например, на x86 стек почти всегда используется для передачи аргументов функциям. Однако на многих архитектурах RISC

0
ответ дан 30 November 2019 в 02:07
поделиться

Что происходит? В x86, первая строка вашей основной функции может выглядеть примерно так:

call foo

Инструкция call помещает адрес возврата в стек, а затем jmp в местоположение фу.

1
ответ дан 30 November 2019 в 02:07
поделиться

Общая идея состоит в том, что регистры, которые используются в вызывающем методе, помещаются в стек (указатель стека находится в регистре ESP ), этот процесс вызывается "толкать регистры". Иногда их тоже обнуляют, но это зависит от обстоятельств. Программисты на ассемблере обычно освобождают больше регистров, чем обычные 4 ( EAX , EBX , ECX и EDX на x86), чтобы иметь больше возможностей. внутри функции.

Когда функция завершается, то же самое происходит в обратном порядке: стек восстанавливается до состояния до вызова. Это называется «извлечение регистров».

Обновление: этот процесс не обязательно должен происходить. Компиляторы могут оптимизировать его и встраивать ваши функции.

Обновление: обычно параметры функции помещаются в стек в обратном порядке, когда они извлекаются из стека, они отображаются как в обычном порядке. Этот порядок не гарантируется C. (ref: Inner Loops Рик Бут)

0
ответ дан 30 November 2019 в 02:07
поделиться

What happens?

C mimics what will occur in assembly...

It is so close to machine that you can realize what will occur

void foo() {
    printf("in foo");

/*

db mystring 'in foo'
mov eax, dword ptr mystring
mov edx , dword ptr _printf
push eax
call edx
add esp, 8
ret
//thats it
*/

}

int main() {
    foo();
    return 0;
}
1
ответ дан 30 November 2019 в 02:07
поделиться