Wiem, że w architekturach, które osobiście znam (x86, 6502 itd.), Stos zwykle rośnie w dół (tj. Każdy element umieszczany na stosie skutkuje zmniejszeniem SP, a nie zwiększeniem).
Zastanawiam się, jakie jest historyczne uzasadnienie tego. Wiem, że w ujednoliconej przestrzeni adresowej wygodnie jest rozpocząć stos na przeciwległym końcu segmentu danych (powiedzmy), więc problem występuje tylko wtedy, gdy dwie strony zderzają się w środku. Ale dlaczego stos tradycyjnie otrzymuje górną część? Zwłaszcza biorąc pod uwagę, że jest to przeciwieństwo modelu „koncepcyjnego”?
(Zauważ, że w architekturze 6502 stos rośnie również w dół, mimo że jest ograniczony do pojedynczej strony 256-bajtowej, a ten wybór kierunku wydaje się arbitralny).
źródło
Jednym z dobrych wyjaśnień, które słyszałem, było to, że niektóre maszyny w przeszłości mogły mieć tylko nieoznaczone przesunięcia, więc chciałbyś, aby stos rósł w dół, abyś mógł uderzać w lokalnych graczy bez utraty dodatkowych instrukcji, aby sfałszować ujemne przesunięcie.
źródło
Stanley Mazor (architekt z 4004 i 8080) wyjaśnia, w jaki sposób wybrano kierunek wzrostu stosu dla 8080 (i ostatecznie dla 8086) w „Mikroprocesorach Intel: 8008 do 8086” :
źródło
Jednym z możliwych powodów może być to, że upraszcza wyrównanie. Jeśli umieścisz lokalną zmienną na stosie, która musi być umieszczona na 4-bajtowej granicy, możesz po prostu odjąć rozmiar obiektu od wskaźnika stosu, a następnie wyzerować dwa dolne bity, aby uzyskać odpowiednio wyrównany adres. Jeśli stos rośnie w górę, zapewnienie wyrównania staje się nieco trudniejsze.
źródło
A - B
koncepcyjnie można by to zaimplementować jakoA + (-B)
(tj. Oddzielny krok negacji dlaB
), nie jest to w praktyce.IIRC stos rośnie w dół, ponieważ sterta rośnie w górę. Mogło być na odwrót.
źródło
realloc(3)
potrzebuje więcej miejsca po obiekcie, aby po prostu rozszerzyć mapowanie bez kopiowania. Wielokrotne ponowne przydzielanie tego samego obiektu jest możliwe, jeśli następuje po nim dowolna ilość niewykorzystanego miejsca.Uważam, że to wyłącznie decyzja projektowa. Nie wszystkie z nich rosną w dół - zobacz ten wątek SO, aby uzyskać dobrą dyskusję na temat kierunku wzrostu stosu na różnych architekturach.
źródło
Myślę, że konwencja rozpoczęła się od IBM 704 i jego niesławnego „rejestru dekrementów”. Współczesna mowa nazwałaby to przesunięciem pola instrukcji, ale chodzi o to, że spadły one w dół , a nie w górę .
źródło
Jeszcze tylko 2 centy:
Poza wszystkimi wspomnianymi historycznymi przesłankami jestem całkiem pewien, że nie ma powodu, który byłby ważny w przypadku nowoczesnych procesorów. Wszystkie procesory mogą przyjmować podpisane przesunięcia, a maksymalizacja odległości stosu / stosu jest raczej dyskusyjna, odkąd zaczęliśmy zajmować się wieloma wątkami.
Osobiście uważam to za wadę projektu zabezpieczeń. Jeśli, powiedzmy, projektanci architektury x64 odwróciliby kierunek wzrostu stosu, większość przepełnień bufora stosu zostałaby wyeliminowana - co jest dość dużym problemem. (ponieważ struny rosną w górę).
źródło
Nie jestem pewien, ale kiedyś programowałem dla VAX / VMS. Wydaje mi się, że jedna część pamięci (sterta?) Rosła, a stos spadał. Kiedy się spotkali, zabrakło ci pamięci.
źródło
Jedną z zalet rosnącego stosu rosnącego w minimalnym systemie wbudowanym jest to, że pojedynczy fragment pamięci RAM może być redundantnie mapowany zarówno na stronę O, jak i stronę 1, umożliwiając przypisanie zerowych zmiennych stron począwszy od 0x000, a stos rośnie w dół od 0x1FF, maksymalizując ilość, którą musiałby wzrosnąć przed nadpisaniem zmiennych.
Jednym z pierwotnych założeń projektowych 6502 było to, że można go było połączyć, na przykład, z 6530, w wyniku czego powstał dwuczipowy system mikrokontrolera z 1 KB pamięci ROM programu, timerem, we / wy i 64 bajtami współdzielonej pamięci RAM między zmiennymi stosu i zerowej strony. Dla porównania, minimalny system wbudowany w tamtych czasach oparty na 8080 lub 6800 składał się z czterech lub pięciu chipów.
źródło