- Откуда берется
edi
?
... Из вышеприведенного, очевидно, edi содержит аргумент.
Этосоглашение о вызовах (для Linux и многих других ОС):
Все языки программирования для этих ОС передают первый параметр в rdi
.Результат (возвращаемое значение) передается в rax
.
И поскольку ваш компилятор C интерпретирует int
как 32 бита, используются только младшие 32 бита rdi
и rax
, чтоedi
и eax
.
Языки программирования для Windows передают первый параметр в rcx
...
Но тогда какую роль играет [rbp-0x4]
?
Использование rbp
имеет в основном исторические причины.В 16-битном коде (как он использовался в ПК 1980-х и 1990-х годов) было невозможно адресовать данные в стеке с помощью регистра sp
(что соответствует rsp
).Единственный регистр, который позволял легко адресовать значения в стеке, был регистр bp
(соответствующий rbp
).
И даже в 32- или 64-битном коде сложнее написать компилятор, которыйобращается к локальным переменным (в стеке), используя rsp
, а не rbp
.
Компилятор генерирует первые 3 инструкции кода ассемблера, прежде чем он узнает, что делается в функции C.Компилятор помещает значение в стек, потому что вы можете сделать что-то вроде address = &num
в коде.Это, однако, невозможно, когда num
находится в регистре, но только когда num
находится в памяти.
Почему бы не просто mov eax, edi
?
Если вы скажете компилятору оптимизировать код, он сначала проверит содержимое функции C перед генерацией первой инструкции на ассемблере.Он обнаружит, что не нужно помещать значение в память.
В этом случае код действительно будет выглядеть так:
mov eax, edi
ret