10.6K subscribers
333 photos
19 videos
15 files
709 links
Архитектура | Программирование | Профессиональное развитие

Соер.Клуб - https://xn--r1a.website/soer_live

По всем вопросам писать на @soerdev
Download Telegram
Низкий уровень: как выглядят функции на ASM

Процессор умеет выполнять лишь простые машинные команды, как же тогда работают функции и классы языков высокого уровня?

Чтобы разобраться будем использовать Compiler Explorer который позволяет преобразовать конструкции высокого уровня в их представление на низком уровне (Assembler).

Начать предлагаю с того, что посмотреть какой код будет сгенерирован компилятором для следующего листинга:


int callme() {
return 1;
}

void main() {
callme();
}


в командной строке это можно сделать с помощью команды

gcc -g -o output.s -masm=intel -fno-verbose-asm -S -fdiagnostics-color=always example.c


но Compiler Expolrer делает это за нас, в результате получен следующий код:

callme:
push rbp
mov rbp, rsp
mov eax, 1
pop rbp
ret
main:
push rbp
mov rbp, rsp
mov eax, 0
call callme
nop
pop rbp
ret

Мы видим, что:

имена функций превратились в имена меток, на самом деле это реальные адреса по которым будут делаться переходы, представленные в виде меток.

для вызова функции используется специальная инструкция call

для возврата из функции используется специальная инструкция ret

чтобы вернуть значение из функции используется регистр eax - mov eax,1
в функции есть специальные части "пролог" и "эпилог"

Что такое "Пролог"

Это часть функции которая сохраняет текущие значения регистров, чтобы восстановить их при возврате из функции.


push rbp; инструкция push сохраняет в стеке значение rbp

mov rbp, rsp; копирует значение регистра указателя вершины стека (открытие кадра стека)

sub rsp, xx; выделяем память под локальные переменные

1. rbp используется для адресации локальных переменных, должен быть сохранен в стеке;
2. rsp используется для указания на вершину стека

Что такое "эпилог"

Этр код, который закрывает кадр стека и восстанавливаем значние rpb
mov rsp, rbp
pop rbp
ret


Red zone

Вероятно вы заметили, что у нас в прологе нет инструкции sub rsp, xx, все дело в том, что у процессоров есть оптимизация, которая называется red zone, в данном случае - область размером 128 байт которая находится за пределами RSP и не должна изменяться обработчиками сигналов и прерываний.

В качестве индивидуального задания можете попробовать добавить char a[128]; в код функции callme и посмотреть что будет.


Вывод:
Сегодня мы узнали, что функции высокого уровня на уровне ассемблера размещаются в теле программы и доступ к ним осуществляется путем перехода по адресу, где находится соответствующая функция.

Часто узнать функции в коде на ассемблере можно по следующим признакам:

для вызова функций используются инструкции call, ret

без оптимизаций компилятор добавит специальные куски кода "пролог" и "эпилог"

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

#asm #знания

SOER | PRO | Boosty
👍107864🤯3🤓22🔥1