Isso significa que o ponteiro base ou o ponteiro da pilha estão realmente movendo os endereços de memória em vez de subir? Por que é que?
Sim, as push
instruções diminuem o ponteiro da pilha e gravam na pilha, enquanto pop
fazem o inverso, leem da pilha e aumentam o ponteiro da pilha.
Isso é um pouco histórico, pois para máquinas com memória limitada, a pilha foi colocada alta e cresceu para baixo, enquanto a pilha foi colocada baixa e cresceu para cima. Há apenas uma lacuna de "memória livre" - entre a pilha e a pilha, e essa lacuna é compartilhada; qualquer um pode crescer na lacuna conforme necessário individualmente. Portanto, o programa fica sem memória quando a pilha e o heap colidem, deixando sem memória livre.
Se a pilha e a pilha crescem na mesma direção, há duas lacunas, e a pilha não pode realmente crescer na lacuna da pilha (o vice-versa também é problemático).
Originalmente, os processadores não tinham instruções de manipulação de pilha dedicadas. No entanto, como o suporte à pilha foi adicionado ao hardware, ele assumiu esse padrão de crescimento descendente e os processadores ainda seguem esse padrão hoje.
Alguém poderia argumentar que em uma máquina de 64 bits há espaço de endereço suficiente para permitir várias lacunas - e, como evidência, várias lacunas são necessariamente o caso quando um processo possui vários encadeamentos. Embora isso não seja motivação suficiente para mudar tudo, uma vez que, com sistemas com múltiplos hiatos, a direção do crescimento é indiscutivelmente arbitrária, então a tradição / compatibilidade diminui a escala.
Você teria que mudar as instruções de manuseamento da pilha CPU, a fim de mudar a direção da pilha, ou então desistir de uso das empurrando & popping instruções (por exemplo, dedicados push
, pop
, call
, ret
, outros).
Observe que a arquitetura do conjunto de instruções MIPS não possui push
& dedicado pop
; portanto, é prático aumentar a pilha em qualquer direção - você ainda pode querer um layout de memória de uma lacuna para um processo de encadeamento único, mas pode aumentar a pilha para cima e para a pilha. para baixo. Se você fez isso, no entanto, algum código C varargs pode exigir ajuste na origem ou na passagem de parâmetro oculto.
(De fato, como não há manipulação de pilha dedicada no MIPS, poderíamos usar pré ou pós incremento ou pré ou pós decremento para empurrar a pilha, desde que usássemos o reverso exato para saltar da pilha e também assumindo que o O sistema operacional respeita o modelo de uso de pilha escolhido. De fato, em alguns sistemas embarcados e em alguns sistemas educacionais, a pilha MIPS é aumentada.)
-4(%rbp)
não move o ponteiro da base e+4(%rbp)
não poderia ter funcionado.