Perché la pila cresce verso il basso?


31

Suppongo che ci sia una storia, ma perché lo stack cresce verso il basso?

Mi sembra che gli overflow del buffer sarebbero molto più difficili da sfruttare se lo stack aumentasse ...


3
stackoverflow.com/questions/1677415/… osserva che lo stack può crescere in qualche modo in entrambi i modi.
JB King,

6
C'è una domanda come questa: stackoverflow.com/questions/2035568/… . In realtà c'è una domanda e una risposta molto migliori su questo qui: stackoverflow.com/questions/664744/…
Karlson,

La domanda collegata non copre del tutto il problema dell'overflow del buffer.
deadalnix,

1
perché il mucchio cresce verso l'alto.
tylerl,

2
La posizione di memoria 0 è in alto o in basso?

Risposte:


21

Io credo che proviene dai primissimi giorni di calcolo, quando la memoria era molto limitata, e non è stato saggio pre-allocare un grande pezzo di memoria per l'uso esclusivo dallo stack. Quindi, allocando la memoria heap dall'indirizzo zero verso l'alto e impilando la memoria dalla fine della memoria verso il basso, è possibile che sia l'heap sia lo stack condividano la stessa area di memoria.

Se avessi bisogno di un po 'più di heap, potresti stare attento all'utilizzo dello stack; se hai bisogno di più stack, puoi provare a liberare un po 'di memoria heap. Il risultato fu, ovviamente, soprattutto crash spettacolari, dato che lo stack occasionalmente sovrascriveva il mucchio e viceversa.

A quei tempi non c'erano interwebz, quindi non c'erano problemi di sfruttamento del buffer sovraccarico. (O almeno nella misura in cui esistesse l'interwebz, era tutto all'interno di strutture ad alta sicurezza del dipartimento della difesa degli Stati Uniti, quindi non è stato necessario riflettere molto sulla possibilità di dati dannosi.)

Dopodiché, con la maggior parte delle architetture si trattava solo di mantenere la compatibilità con le versioni precedenti della stessa architettura. Ecco perché le pile rovesciate sono ancora con noi oggi.


8
Torna indietro nella storia e non c'era nessun heap, anche oggi, molti micro controller a 8 e 16 bit non hanno un heap. Lo stack è cresciuto in modo che il programma potesse essere installato in un indirizzo di memoria insufficiente e lo stack era la memoria rimanente. L'inizializzazione dello stack potrebbe essere eseguita prima del caricamento del programma, semplificando i programmi.
Mattnz,

1
La maggior parte dei microcontrollori piccoli ha un mucchio, ma non un mucchio che cresce. È difficile giustificare l'uso dell'allocazione dinamica della memoria sull'heap quando si ha una piccola quantità di RAM (<1 KB) con cui lavorare. Di solito l'unica dimensione della sezione di memoria che cambia è lo stack.
tehnyit

7

la memoria del programma è tradizionalmente impostata come

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

heap e stack possono essere scambiati

ma gli overflow del buffer possono ancora essere sfruttati se lo stack è andato dall'altra parte

prendendo il classico strcpycome esempio

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

con memoria stack come

ret foo
arg in
buff array
ret strcpy
buf pointer
in

ciò significherebbe che al termine della copia l'indirizzo di ritorno strcpyè dopo il buffer (anziché l' fooindirizzo di ritorno) e può essere sovrascritto da qualsiasi cosa si trovi inin


4

Alcuni hardware hanno l'heap che inizia a memoria alta, che cresce, mentre lo stack inizia a memoria bassa che cresce.

L'hardware HP PA-RISC, tra gli altri, lo fa: http://www.embeddedrelated.com/usenet/embedded/show/68749-1.php

Il venerabile sistema operativo Multics funzionava su hardware che aveva (uno dei forse molti) stack in crescita: vedi http://www.acsac.org/2002/papers/classic-multics.pdf , fine della sezione 2.3.2:

In terzo luogo, le pile sui processori Multics sono cresciute nella direzione positiva, piuttosto che in quella negativa. Ciò significa che se si realizzasse effettivamente un overflow del buffer, si sovrascriverebbero i frame stack non utilizzati, anziché il proprio puntatore di ritorno, rendendo lo sfruttamento molto più difficile.

È un'affermazione piuttosto interessante. Gli overflow del buffer sono diventati un problema così grande solo a causa della disposizione "consueta" di procedure-call-stack-frame? Inoltre, quanta parte della reputazione di Multics come Totally Invulnerable era solo un colpo di fortuna nella progettazione hardware?


Bene, non avere stack eseguibili probabilmente ha aiutato Multics tanto quanto la direzione dello stack intelligente, e ovviamente con molti programmi scritti in PL / 1, anche gli overflow delle stringhe non erano davvero un problema.
Greg A. Woods,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.