Por que a pilha cresce para baixo?

31

Estou assumindo que há um histórico, mas por que a pilha cresce para baixo?

Parece-me que estouros de buffer seriam muito mais difíceis de explorar se a pilha crescesse para cima ...

Mehrdad
fonte
3
stackoverflow.com/questions/1677415/… observa que a pilha pode crescer de alguma maneira em algum grau.
JB rei
6
Há uma pergunta como esta: stackoverflow.com/questions/2035568/… . Questão de naturalidade há uma muito melhor pergunta e resposta sobre isso aqui: stackoverflow.com/questions/664744/...
Karlson
A questão vinculada não cobre completamente o problema de estouro de buffer.
Deadalnix
1
porque a pilha cresce para cima.
21412 Tylerl
2
O local da memória 0 está na parte superior ou inferior?

Respostas:

21

Eu acredito que se trata desde os primórdios da computação, quando a memória era muito limitado, e não era sábio para pré-alocar um grande pedaço de memória para uso exclusivo pela pilha. Portanto, alocando a memória heap do endereço zero para cima e empilhe a memória do final da memória para baixo, é possível que o heap e a pilha compartilhem a mesma área de memória.

Se você precisasse de um pouco mais de pilha, poderia tomar cuidado com o uso da pilha; se você precisar de mais pilha, tente liberar um pouco de memória heap. O resultado foi, é claro, principalmente, falhas espetaculares, pois a pilha substituía ocasionalmente a pilha e vice-versa.

Naqueles dias, não havia interwebz, portanto não havia problema de exploração de saturação de buffer. (Ou pelo menos na medida em que existia a interwebz, era tudo dentro das instalações de alta segurança do departamento de defesa dos estados unidos, de modo que a possibilidade de dados mal-intencionados não precisou de muita atenção.)

Depois disso, na maioria das arquiteturas, era tudo uma questão de manter a compatibilidade com versões anteriores da mesma arquitetura. É por isso que as pilhas invertidas ainda estão conosco hoje.

Mike Nakis
fonte
8
Volte mais longe na história e não havia heap, ainda hoje muitos micro controladores de 8 e 16 bits não têm heap. A pilha caiu para que o programa pudesse ser instalado em um endereço com pouca memória e a pilha era a memória restante. A inicialização da pilha pode ser realizada antes do carregamento do programa, simplificando os programas.
mattnz
1
A maioria dos microcontroladores pequenos tem um monte, mas não um monte que cresce. É difícil justificar o uso da alocação dinâmica de memória no heap quando você possui uma pequena quantidade de RAM (<1Kbytes) para trabalhar. Normalmente, o único tamanho da seção de memória que muda é a pilha.
Tehnyit 01/03
7

a memória do programa é tradicionalmente configurada como

code
constants
heap (growing up)
...
stack (growing down)

pilha e pilha podem ser trocadas

mas os estouros de buffer ainda poderão ser explorados se a pilha for para o outro lado

tomando o clássico strcpycomo exemplo

foo(char* in){
char[100] buff;
strcpy(buff,in);
}

com pilha de memória como

ret foo
arg in
buff array
ret strcpy
buf pointer
in

isso significa que, quando a cópia é concluída, o endereço de retorno strcpyé após o buffer (em vez do fooendereço de retorno) e pode ser substituído pelo que estiverin

catraca arrepiante
fonte
4

Alguns hardwares têm o heap começando na memória alta, diminuindo, enquanto a pilha começa na memória baixa crescendo.

O hardware PA-RISC da HP, entre outros, faz isso: http://www.embeddedrelated.com/usenet/embedded/show/68749-1.php

O venerável Sistema Operacional Multics rodava em hardware que tinha (possivelmente um de muitos) pilhas crescendo: veja http://www.acsac.org/2002/papers/classic-multics.pdf , final da seção 2.3.2:

Terceiro, as pilhas nos processadores Multics cresceram na direção positiva, e não na direção negativa. Isso significava que, se você realmente realizasse um estouro de buffer, substituiria quadros de pilha não utilizados, em vez de seu próprio ponteiro de retorno, tornando a exploração muito mais difícil.

Essa é uma afirmação bastante interessante. Os estouros de buffer se tornaram um problema tão grande apenas devido ao arranjo "habitual" de procedimento-chamada-pilha-quadro? Além disso, quanto da reputação de Multics como Totalmente Invulnerável era apenas um acaso de design de hardware?

Bruce Ediger
fonte
Bem, não ter pilha (s) executável (s) provavelmente ajudou o Multics tanto quanto a direção da pilha inteligente e, é claro, com muitos programas escritos em PL / 1, estouros de string também não eram realmente um problema.
Greg A. Woods,