Jak procesor może nie obsługiwać stosu? Czy żadna architektura wykorzystująca podprogramy (jestem prawie pewien, że to wszystkie architektury) nie musi wypychać adresu zwrotnego na stos, aby mogła wrócić do miejsca, z którego wywołała podprogram? Stos oznacza po prostu sekcję pamięci ze wskaźnikiem, który rośnie w określonym kierunku i działa jak struktura danych stosu nie? Po prostu nie rozumiem, w jaki sposób architektura nie może obsługiwać stosu.
W jakim stopniu automatyczne zapisywanie w pamięci (zmienne automatyczne vs. zmienne statyczne) jest określane przez kompilator względem architektury sprzętowej?
Istnieje wiele mikrokontrolerów niskiego poziomu, które mają stosy sprzętowe do obsługi wywołań / zwrotów i przerwań podprogramów, ale utrudniają, jeśli nie niemożliwe, przechowywanie tam danych (zmiennych), a wdrożenie stosu danych czysto programowych byłoby strasznie nieefektywne. 8051 jest jednym klasycznym przykładem, a niskiej klasy PIC (PIC12 / PIC16) są kolejnym. Na tych komputerach stos danych jest emulowany przez przypisanie statycznych lokalizacji przechowywania dla zmiennych automatycznych, przy czym ilość ponownego użycia tych lokalizacji zależy od zaawansowania kompilatora.
Zauważ, że jeśli emulacja stosu jest wykonywana w ten sposób, oznacza to, że rekurencja - funkcja, która wywołuje siebie bezpośrednio lub pośrednio - nie działa, ponieważ każde wystąpienie funkcji wykorzystuje te same lokalizacje statyczne dla swoich rzekomo „prywatnych” zmiennych. Niektóre kompilatory pozwalają na ograniczone użycie rekurencji (zwykle realizowane za pomocą #pragmapewnego rodzaju), co spowoduje, że utworzy prawdziwy stos danych, bez względu na to, jak bardzo to spowalnia.
Nawiasem mówiąc, istnieją architektury procesorów, które w ogóle nie miały stosu sprzętu, nawet do obsługi podprogramów / przerwań, w tym DEC PDP-8 i IBM System / 360. Na tych komputerach PC (adres zwrotny) i rejestr statusu (dla przerwań) były zapisywane w rejestrach lub lokalizacjach pamięci, ale w każdym przypadku, o którym myślę, maszyna miała również wystarczająco elastyczne tryby adresu, które ułatwiły utworzenie stosu z oprogramowaniem.
Niektóre wcześniejsze komputery zapisywałyby w kodzie instrukcję skoku, aby spowodować powrót - bez pośrednich przeskoków - co uniemożliwiałoby ponowne wprowadzanie funkcji (teoretycznie można rozgałęzić się po skoku, ale to zwiększa złożoność, w niektórych przypadkach, zwłaszcza gdy adresy danych są całkowicie zakodowane w instrukcjach).
Paul A. Clayton
4
„wspieranie stosu” oznacza
posiadający jawny rejestr wskaźnika stosu, oraz
posiadanie prymitywnych instrukcji kodu maszynowego do manipulowania / używania rejestru wskaźnika stosu (takiego jak reti, który zmienia licznik programu na podstawie wskaźnika stosu w celu powrotu z wywołania funkcji).
Możesz to emulować bez wsparcia sprzętowego poprzez emulację, która jest kodem generowanym przez kompilator, który zawiera te same rzeczy w pamięci RAM za pomocą zmiennych. Rzadko / rzadko zdarza się, że nie ma bezpośredniego wsparcia dla stosu w żadnej nowoczesnej architekturze komputerowej.
Semantyka zmiennych w językach programowania prawie nie ma nic wspólnego z docelową architekturą sprzętową, dla jakiegokolwiek języka wyższego niż prosty montaż. Zadaniem kompilatorów jest generowanie kodu maszynowego zgodnego z kontraktem semantycznym języka programowania.
Większość ISA RISC (np. MIPS [z wyłączeniem MIPS16 i microMIPS], Alpha, SPARC, PA-RISC, Power, SuperH) nie ma wyraźnego rejestru wskaźnika stosu, który definiuje go w ABI. ARM jest wyjątkiem (częściowo dlatego, że cienia SP dla kilku trybów pracy), podobnie jak MIP16 i microMIPS (dla gęstości kodu).
Paul A. Clayton
2
Niektóre architektury (np. PIC) mają stos sprzętu, który ma ograniczone możliwości (można go używać tylko do adresów zwrotnych, a nie zmiennych). Niektóre bardzo małe architektury nie mają instrukcji przechowywania i przyrostu ani instrukcji PUSH, więc bardziej skomplikowane jest robienie stosów.
zmienne „auto” w C powinny zawsze być kompilowane do czegoś o zachowaniu inicjującym „auto” i „statyczne” z zachowaniem statycznym; na niektórych architekturach nie możesz wykonywać rekurencji, w takim przypadku kompilator może statycznie przydzielić wszystkie zmienne.
„wspieranie stosu” oznacza
Możesz to emulować bez wsparcia sprzętowego poprzez emulację, która jest kodem generowanym przez kompilator, który zawiera te same rzeczy w pamięci RAM za pomocą zmiennych. Rzadko / rzadko zdarza się, że nie ma bezpośredniego wsparcia dla stosu w żadnej nowoczesnej architekturze komputerowej.
Semantyka zmiennych w językach programowania prawie nie ma nic wspólnego z docelową architekturą sprzętową, dla jakiegokolwiek języka wyższego niż prosty montaż. Zadaniem kompilatorów jest generowanie kodu maszynowego zgodnego z kontraktem semantycznym języka programowania.
źródło
Niektóre architektury (np. PIC) mają stos sprzętu, który ma ograniczone możliwości (można go używać tylko do adresów zwrotnych, a nie zmiennych). Niektóre bardzo małe architektury nie mają instrukcji przechowywania i przyrostu ani instrukcji PUSH, więc bardziej skomplikowane jest robienie stosów.
zmienne „auto” w C powinny zawsze być kompilowane do czegoś o zachowaniu inicjującym „auto” i „statyczne” z zachowaniem statycznym; na niektórych architekturach nie możesz wykonywać rekurencji, w takim przypadku kompilator może statycznie przydzielić wszystkie zmienne.
źródło