Да, если вы хотите использовать колл-стэк в качестве структуры данных стека, выполнение операции возврата до тех пор, пока указатель стека не вернется в начальную точку, является нормальным. Обращайтесь с адресами как без знака: если вы хотите проверить, находится ли RSP ниже RBP, используйте cmp
/ jb
. Или просто cmp/jne
, если вы уверены, что RSP не смог получить выше RBP.
Если вам нужно какое-либо пространство стека для локальных переменных, отличное от структуры данных, вам потребуетсяопорная точка, отличная от rbp
, или просто используйте rbp
в качестве не совсем традиционного указателя кадра. Например, переместите RSP, чтобы освободить место для местных жителей , прежде чем скопировать его в RBP. Наличие указателя кадра вообще необязательно.
Наличие некоторого пространства над RBP, которое по-прежнему является частью вашей структуры стековых данных, может также упростить обработку в угловом случае без риска наступления на сохраненное значение RBP или адрес возврата. Вы можете просто позволить ему подняться на одну высоту по любой причине.
например,
func:
push %rbp
sub $32, %rsp
mov %rsp, %rbp
# Space from 0(%rbp) to 31(%rbp) can be used for locals separate from your stack data structure
...
lea 32(%rbp), %rsp # point RSP at the saved RBP value
pop %rbp
ret
Обратите внимание, что для режима адресации 0(%rbp)
по-прежнему требуется disp8
, в отличие от 0(%rbx)
, который можетпросто не используйте смещение как (%rbx)
. Поэтому вы можете использовать другой регистр, например, RBX, в качестве привязки. Или даже регистр с замкнутым вызовом, если это конечная функция, например, RDX или R8. (Если вы не собираетесь использовать его в каких-либо режимах адресации, не имеет значения, если вы выберете тот, который требует префикса REX; вы все равно будете использовать его с 64-битным размером операнда при сравнении с RSP. Вы хотите оптимизировать, предполагая, что ваш стек не пересекает границу 4 ГБ и используя cmp %ecx, %esp
, чтобы сохранить 1 байт размера кода.)
func:
lea -8(%rsp), %rsi # or just mov, depending what you want.
...
# once RSP is pointing back where it started
ret