c语言变量存储区

高内存地址
--------------------------------------
堆栈段



BSS (uninitialized global variables, uninitialized local variables declared with the static keyword)

Data Segment (global variables and static variables that are initialized by the programmer.)

Text Segment

-------------------------------------

低内存地址

 

2. Notes on Assembly - Memory from a process' point of view

http://blog.ooz.ie/2008/09/0x03-notes-on-assembly-memory-from.html

 

In-depth memory layout is specific to both the CPU architecture and the OS itself. I'm going to describe how a process sees its own memory share during execution.

Memory Layout from a process perspective

When a program is executed it is read into memory* where it resides until termination. The code allocates a number of special purpose memory blocks for different data types. A very common scheme, but not the only one, is depicted in the following table.

*that's why a statement that the size of your binary does not influence the memory use is not true. Programs static code is read into the lower part of memory.



Stack

a very dynamic kind of memory located at it's top (high addresses) and growing downwards



Memory not allocated yet

Memory that will soon become allocated by the stack, that grows down. Stack will grow until it hits the administrative limit (predefined).

Administrative limit for the stack
Shared Libraries
Administrative limit for the heap

Memory not allocated yet

Memory that will soon become allocated by the heap growing up from underneath.


Heap

It is said that this is the most dynamic part of memory. It is dynamically allocated and freed in big chunks. The allocation process is rather complex (stub/buddy system) and is more time consuming than putting things on stack.


BSS

Memory containing global variables of known (predeclared) size.


Constant data

All constants used in a program.


Static program code

Reserved / other stuff


In order to prove that things work this way (on many systems anyway) I wrote a C program, mem_sequence.c , that allocates 5 types of data, finds their location the (virtual) memory address, sorts them in descending order and then displays presenting a similar output to the table above. mem_sequence.c is tested on Linux, FreeBSD, MacOS X, WinXP and DOS. All UNIX-like systems preserve a similar model with slight differences in address thresholds, the output from Microsoft systems is different and hence interesting.

This is how you use mem_sequence :
$ gcc mem_sequence.c -o mem_sequence
$ ./mem_sequence
1.(0xbf828124) stack
2.(0x0804a008) heap
3.(0x080497d4) bss
4.(0x08048688) const's
5.(0x08048557) code
^Z
[1]+ Stopped ./mem_sequence
$ cat /proc/`pidof mem_sequence`/maps
08048000-08049000 r-xp 00000000 fd:01 313781 mem_sequence
08049000-0804a000 rw-p 00000000 fd:01 313781 mem_sequence
0804a000-0806b000 rw-p 0804a000 00:00 0 [heap]
b7dda000-b7ddb000 rw-p b7dda000 00:00 0
b7ddb000-b7efe000 r-xp 00000000 fd:01 4872985 /lib/libc-2.5.so
b7efe000-b7eff000 r--p 00123000 fd:01 4872985 /lib/libc-2.5.so
b7eff000-b7f01000 rw-p 00124000 fd:01 4872985 /lib/libc-2.5.so
b7f01000-b7f04000 rw-p b7f01000 00:00 0
b7f18000-b7f1b000 rw-p b7f18000 00:00 0
b7f1b000-b7f35000 r-xp 00000000 fd:01 4872978 /lib/ld-2.5.so
b7f35000-b7f36000 r--p 00019000 fd:01 4872978 /lib/ld-2.5.so
b7f36000-b7f37000 rw-p 0001a000 fd:01 4872978 /lib/ld-2.5.so
bf816000-bf82b000 rw-p bffeb000 00:00 0 [stack]
ffffe000-fffff000 r-xp 00000000 00:00 0 [vdso]
$

Let's analyze it:

  • The code (5) and constants (4) fall into the readable and executable (non-writable!) portion of code.
  • BSS (3) is enclosed in the read-write but not executable partition.
  • Heap sits on top of them and is denoted by "[Heap]".
  • ...long long nothing...
  • Stack at the very top, described as "[Stack]". Yahtzee!
It works, great news, but it works differently on different x86 based Operating Systems. Check it out yourself and please let me know if you make an interesting discovery on some other exotic system.
top Linux FreeBSD MacOSX x86 / PPC
WinXP 32
DOS AmigaOS 4.1
Vista Home 32bit
1
stackstackstackheapheap code
bss
2
heapheapheapbssstackheap
const's
3
bssbssbssconstbssbss
code
4
constconstconstcodeconstconst's
heap
5codecodecodestackcodestack
stack


Thanks to Harald Monihart for providing MacOSX PPC data.
Thanks to Anonymous for AmigaOS 4.1 data.

 

/*
* mem_sequence.c / ver 0x01 | (C)opyleft 2008 by oozie | http://blog.ooz.ie/
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* Lists memory areas and their location in descending order.
*
* This program declares example variables in different memory locations, gets
* their addresses, sorts them and prints a list in descending order.
*
* The program is considered free software; you can redistribute and/or modify
* it under the terms of the GNU General Public License version 3 or any later
* version, as published by the Free Software Foundation; If you do modify it,
* please leave the information about the author unchanged. The full text of
* latest GPL licence is available at http://www.gnu.org/licences/gpl.txt
*/

#include <stdio.h>
#include <stdlib.h>

#define MEM_TYPES 5

#define STR_STACK "stack"
#define STR_HEAP "heap"
#define STR_BSS "bss"
#define STR_CONST "const's"
#define STR_CODE "code"

const char const_example[]="constant string";

/*
* defining a 5-element memory structure consisting of a string describing
* memory type {stack, heap, bss, consts, code} and a pointer to an example
* definition. Each element of this array is 12 bytes large (char[8]+*int),
* so the entire table is 60 bytes in size.
*/

struct memtype_ptr {
int *ptr;
char *str;
};

struct memtype_ptr type_pointer[MEM_TYPES];

/* defining a global variable with predefined value (BSS) */
char bss_example[]="A global variable";

/* mem_xchg() will be used later in print_sorted() function */
void mem_xchg(struct memtype_ptr *a, struct memtype_ptr *b) {
struct memtype_ptr tmpmemptr;

tmpmemptr.str = a->str;
tmpmemptr.ptr = a->ptr;

a->str = b->str;
a->ptr = b->ptr;

b->str = tmpmemptr.str;
b->ptr = tmpmemptr.ptr;

}

/* void function print_sorted() contains a local variable "stack_example" */
void print_sorted(int *heap_example, int stack_example) {

int i, j;

/*
* assigning all example variables to the memory type pointer table
* in no particular order
*/

type_pointer[0].str = STR_HEAP;
type_pointer[0].ptr = heap_example;

type_pointer[1].str = STR_BSS;
type_pointer[1].ptr = (int *)&bss_example;

/*
* the address of stack_example, which is a local variable
* points us to the top of the stack
*/

type_pointer[2].str = STR_STACK;
type_pointer[2].ptr = &stack_example;

/*
* the value of stack_example equals to the value of code_example
*/

type_pointer[3].str = STR_CODE;
type_pointer[3].ptr = (int *)stack_example;

type_pointer[4].str = STR_CONST;
type_pointer[4].ptr = (int *)&const_example;

/* buble-sorting the table in descending order */
j=MEM_TYPES;
while(j--)
for (i=0; i<j; i++)
if (type_pointer[i].ptr < type_pointer[i+1].ptr)
mem_xchg(&type_pointer[i],&type_pointer[i+1]);

/* printing the table */
for (i = 0 ; i < MEM_TYPES; i++)
printf("%d.(0x%.8x) %s/n", i+1,
(int )type_pointer[i].ptr,
type_pointer[i].str);

return;
}

/* main */
int main(void) {

int *dyn_allocated, code_example;

/* getting the address of main() in memory */
code_example=(int )&main;

/* allocating dynamic memory on the heap */
dyn_allocated=(int *)malloc(sizeof(int));

/* printing memory addresses in descending order */
print_sorted(dyn_allocated, code_example);
getchar();

return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值