Layout of a process in memory

Higher addresses

...

Argument vector and environment vector


STACK

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,

then n2










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 ...