Layout of a process in memory
Higher addresses |
... |
Argument vector and environment vector |
grows downward towards the heap local variables allocated here
...
HEAP grows upwards towards the stack malloc allocates space here
|
BSS uninitialized global variables
|
DATA initialized global variables
|
STRINGS e.g. for char * name = “Bob”, the “Bob” is stored here. Probably read only
|
CODE the machine language instructions of the executable Probably read only
|
... |
Lower addresses
|
Say we have the following declarations in main():
int n1 = 0xb76f81c4;
char buf[9];
int n2 = 0x81ef3ba2;
and then we read in the next full line into the buffer called buf using gets().
Space for the variables is allocated on the stack, in the order given. The stack grows downward, but the variables extend upward from their base addresses. In addition, ints are stored in LSB (little endian) fashion, i.e. least significant byte first.
Before line read in using gets()
Buffer for line is allocated 9 bytes
with char buf[9];
|
|
... higher address ... |
|
|
|
Stack grows downward so n1 allocated first, then buf,
|
|
|
|
||
|
|
||
|
|
||
|
|
||
|
b |
7 |
Most significant byte |
|
6 |
f |
... show each byte as 2 hex digits |
|
8 |
1 |
|
&n1 ---> |
c |
4 |
Least significant byte |
|
|
......
... stack grows downward ...
9 bytes allocated for buf
....... |
|
|
|
||
|
|
||
8 |
|
||
7 |
|
||
6 |
|
||
5 |
|
||
4 |
|
||
3 |
|
||
2 |
|
||
1 |
|
||
buf ---> 0 |
|
||
|
8 |
1 |
Most significant byte |
|
e |
f |
... show each byte as 2 hex digits |
|
3 |
b |
|
&n2 ---> |
a |
2 |
Least significant byte |
|
|
|
|
|
|
... lower address ... |
Line input is:
123456\n
Note: these are ascii characters '1' '2' etc.
gets() appends a null character '\0'
|
|
... higher address ... |
|
|
|
Stack grows downward
|
|
|
|
||
|
|
||
|
|
||
|
|
||
|
b |
7 |
Most significant byte |
|
6 |
f |
... show each byte as 2 hex digits |
|
8 |
1 |
|
&n1 ---> |
c |
4 |
Least significant byte |
|
|
......
... stack grows downward ...
9 bytes allocated for buf
....... |
|
|
|
||
|
|
||
8 |
|
||
7 |
|
||
6 |
'\0' |
||
5 |
'6' |
||
4 |
'5' |
||
3 |
'4' |
||
2 |
'3' |
||
1 |
'2' |
||
buf ---> 0 |
'1' |
||
|
8 |
1 |
Most significant byte |
|
e |
f |
... show each byte as 2 hex digits |
|
3 |
b |
|
&n2 ---> |
a |
2 |
Least significant byte |
|
|
|
|
|
|
... lower address ... |
Line input is:
12345678\n
Note: these are ascii characters '1' '2' etc.
gets() appends a null character '\0'
Allocated space for line is full.
|
|
... higher address ... |
|
|
|
Stack grows downward
|
|
|
|
||
|
|
||
|
|
||
|
|
||
|
b |
7 |
Most significant byte |
|
6 |
f |
... show each byte as 2 hex digits |
|
8 |
1 |
|
&n1 ---> |
c |
4 |
Least significant byte |
|
|
......
... stack grows downward ...
9 bytes allocated for buf
....... |
|
|
|
||
|
|
||
8 |
'\0' |
||
7 |
'8' |
||
6 |
'7' |
||
5 |
'6' |
||
4 |
'5' |
||
3 |
'4' |
||
2 |
'3' |
||
1 |
'2' |
||
buf ---> 0 |
'1' |
||
|
8 |
1 |
Most significant byte |
|
e |
f |
... show each byte as 2 hex digits |
|
3 |
b |
|
&n2 ---> |
a |
2 |
Least significant byte |
|
|
|
|
|
|
... lower address ... |
Line input is:
1234567890\n
Note: these are ascii characters '1' '2' etc.
gets() appends a null character '\0'
buffer overflows.
|
|
... higher address ... |
|
|
|
Stack grows downward
|
|
|
|
||
|
|
||
|
|
||
|
|
||
|
b |
7 |
Most significant byte |
|
6 |
f |
... show each byte as 2 hex digits |
|
8 |
1 |
|
&n1 ---> |
c |
4 |
Least significant byte |
|
|
......
... stack grows downward ...
9 bytes allocated for buf
....... |
|
|
'\0' |
||
|
'0' |
||
8 |
'9' |
||
7 |
'8' |
||
6 |
'7' |
||
5 |
'6' |
||
4 |
'5' |
||
3 |
'4' |
||
2 |
'3' |
||
1 |
'2' |
||
buf ---> 0 |
'1' |
||
|
8 |
1 |
Most significant byte |
|
e |
f |
... show each byte as 2 hex digits |
|
3 |
b |
|
&n2 ---> |
a |
2 |
Least significant byte |
|
|
|
|
|
|
... lower address ... |
Finally, line input is:
1234567890129\n
Note: these are ascii characters '1' '2' etc.
gets() appends a null character '\0'
buffer overflows and first 2 bytes of n1 are overwritten.
Since '\0' byte is really 0, and '9' is 57 or
39 in hex, n1 in hex becomes 0xb76f0039
|
|
... higher address ... |
|
|
|
Stack grows downward
|
|
|
|
||
|
|
||
|
|
||
|
|
||
|
b |
7 |
Most significant byte |
|
6 |
f |
... show each byte as 2 hex digits |
|
'\0' |
|
|
&n1 ---> |
'9' |
Least significant byte |
|
|
'2' |
......
... stack grows downward ...
9 bytes allocated for buf
....... |
|
|
'1' |
||
|
'0' |
||
8 |
'9' |
||
7 |
'8' |
||
6 |
'7' |
||
5 |
'6' |
||
4 |
'5' |
||
3 |
'4' |
||
2 |
'3' |
||
1 |
'2' |
||
buf ---> 0 |
'1' |
||
|
8 |
1 |
Most significant byte |
|
e |
f |
... show each byte as 2 hex digits |
|
3 |
b |
|
&n2 ---> |
a |
2 |
Least significant byte |
|
|
|
|
|
|
... lower address ... |