Некоторые x86-64 принципы стека:
Стек должен быть выровнен 16 байт перед вызовом функции, в соответствии с обоими основными соглашениями о вызовах, включая системный ABI x86-64, используемый в MacOS. Если это не так, вы рискуете ошибкой сегментации при вызове внешних функций. (Поскольку им разрешено принимать выравнивание и использовать movaps
для 16-байтовых копий в / из стековой памяти, например.)
Интересный факт - на MacOS системные вызовы работают правильно, когда стек не выровнен на 16 байтов.
Для push rax
значение rax помещается поверх стека.
Для sub rsp,8
вершина стека остается неизменной (поэтому все, что там находилось в памяти, останется там).
Изменение значения rsp равно точно так же для обеих инструкций.
Так, например, вы можете сделать либо:
sub rsp,16
или
push rax
push rax
И указатель стека rsp
будет указывать точно на то же место.
Для перемещения указателя стека только на 8, фиктивный push или pop может быть столь же эффективным или более эффективным, чем add/sub
. Кроме того, обычно нет.