Eu sei que nas arquiteturas com as quais estou pessoalmente familiarizado (x86, 6502, etc), a pilha normalmente cresce para baixo (ou seja, cada item colocado na pilha resulta em um SP diminuído, não um incrementado).
Estou me perguntando sobre o fundamento histórico para isso. Eu sei que em um espaço de endereço unificado, é conveniente iniciar a pilha na extremidade oposta do segmento de dados (digamos), então só haverá um problema se os dois lados colidirem no meio. Mas por que a pilha tradicionalmente fica com a parte superior? Especialmente considerando como isso é o oposto do modelo "conceitual"?
(E observe que na arquitetura 6502, a pilha também cresce para baixo, embora seja limitada a uma única página de 256 bytes, e essa escolha de direção parece arbitrária.)
fonte
Uma boa explicação que ouvi foi que algumas máquinas no passado só podiam ter offsets não assinados, então você gostaria que a pilha diminuísse para que pudesse atingir seus locais sem ter que perder a instrução extra para falsificar um offset negativo.
fonte
Stanley Mazor (arquiteto 4004 e 8080) explica como a direção do crescimento da pilha foi escolhida para 8080 (e eventualmente para 8086) em "Microprocessadores Intel: 8008 a 8086" :
fonte
Uma possível razão pode ser que simplifica o alinhamento. Se você colocar uma variável local na pilha que deve ser colocada em um limite de 4 bytes, você pode simplesmente subtrair o tamanho do objeto do ponteiro da pilha e zerar os dois bits inferiores para obter um endereço alinhado corretamente. Se a pilha crescer para cima, garantir o alinhamento se torna um pouco mais complicado.
fonte
A - B
possa ser conceitualmente implementado comoA + (-B)
(ou seja, uma etapa de negação separada paraB
), não é na prática.IIRC a pilha cresce para baixo porque a pilha cresce para cima. Poderia ter sido o contrário.
fonte
realloc(3)
precisa de mais espaço após um objeto apenas para estender o mapeamento sem copiar. A realocação repetida do mesmo objeto é possível quando é seguido por uma quantidade arbitrária de espaço não utilizado.Acredito que seja puramente uma decisão de design. Nem todos eles crescem para baixo - consulte este tópico do SO para uma boa discussão sobre a direção do crescimento da pilha em diferentes arquiteturas.
fonte
Acredito que a convenção começou com o IBM 704 e seu infame "registro de decremento". A fala moderna o chamaria de campo de deslocamento da instrução, mas o fato é que eles diminuíram , não aumentaram .
fonte
Apenas 2c mais:
Além de todo o raciocínio histórico mencionado, tenho certeza de que não há razão válida para os processadores modernos. Todos os processadores podem ter deslocamentos assinados, e maximizar a distância heap / pilha é bastante discutível desde que começamos a lidar com vários threads.
Pessoalmente, considero isso uma falha de design de segurança. Se, digamos, os designers da arquitetura x64 tivessem invertido a direção do crescimento da pilha, a maioria dos estouros de buffer da pilha teria sido eliminada - o que é um grande negócio. (já que as cordas crescem para cima).
fonte
Não tenho certeza, mas fiz alguma programação para o VAX / VMS naquela época. Parece que me lembro de uma parte da memória (a pilha ??) aumentando e a pilha diminuindo. Quando os dois se conheceram, você estava sem memória.
fonte
Uma vantagem do crescimento descendente da pilha em um sistema embarcado mínimo é que um único pedaço de RAM pode ser mapeado redundantemente na página O e na página 1, permitindo que variáveis de página zero sejam atribuídas começando em 0x000 e a pilha crescendo para baixo de 0x1FF, maximizando o quantidade que teria que aumentar antes de substituir as variáveis.
Um dos objetivos do projeto original do 6502 era que ele pudesse ser combinado com, por exemplo, um 6530, resultando em um sistema de microcontrolador de dois chips com 1 KB de ROM de programa, temporizador, E / S e 64 bytes de RAM compartilhados entre as variáveis da pilha e da página zero. Em comparação, o sistema embarcado mínimo da época baseado em 8080 ou 6800 seria de quatro ou cinco chips.
fonte