您的位置:首页 > 其它

data段与bss段

2007-03-19 10:54 253 查看
编译如下程序(test.cpp):
#include <stdio.h>

#define LEN 1002000

int inbss[LEN];
float fA;
int indata[LEN]={1,2,3,4,5,6,7,8,9};
double dbB = 100.0;

const int cst = 100;

int main(void)
{
int run[100] = {1,2,3,4,5,6,7,8,9};
for(int i=0; i<LEN; ++i)
printf("%d ", inbss[i]);
return 0;
}

命令:cl /FA test.cpp 回车 (/FA:产生汇编代码)
产生的汇编代码(test.asm):
TITLE test.cpp
.386P
include listing.inc
if @Version gt 510
.model FLAT
else
_TEXT SEGMENT PARA USE32 PUBLIC 'CODE'
_TEXT ENDS
_DATA SEGMENT DWORD USE32 PUBLIC 'DATA'
_DATA ENDS
CONST SEGMENT DWORD USE32 PUBLIC 'CONST'
CONST ENDS
_BSS SEGMENT DWORD USE32 PUBLIC 'BSS'
_BSS ENDS
_TLS SEGMENT DWORD USE32 PUBLIC 'TLS'
_TLS ENDS
FLAT GROUP _DATA, CONST, _BSS
ASSUME CS: FLAT, DS: FLAT, SS: FLAT
endif
PUBLIC ?inbss@@3PAHA ; inbss
PUBLIC ?fA@@3MA ; fA
PUBLIC ?indata@@3PAHA ; indata
PUBLIC ?dbB@@3NA ; dbB
_BSS SEGMENT
?inbss@@3PAHA DD 0f4a10H DUP (?) ; inbss
?fA@@3MA DD 01H DUP (?) ; fA
_BSS ENDS
_DATA SEGMENT
?indata@@3PAHA DD 01H ; indata
DD 02H
DD 03H
DD 04H
DD 05H
DD 06H
DD 07H
DD 08H
DD 09H
ORG $+4007964
?dbB@@3NA DQ 04059000000000000r ; 100 ; dbB
_DATA ENDS
PUBLIC _main
EXTRN _printf:NEAR
_DATA SEGMENT
$SG537 DB '%d ', 00H
_DATA ENDS
_TEXT SEGMENT
_run$ = -400
_i$ = -404
_main PROC NEAR
; File test.cpp
; Line 13
push ebp
mov ebp, esp
sub esp, 404 ; 00000194H
push edi
; Line 14
mov DWORD PTR _run$[ebp], 1
mov DWORD PTR _run$[ebp+4], 2
mov DWORD PTR _run$[ebp+8], 3
mov DWORD PTR _run$[ebp+12], 4
mov DWORD PTR _run$[ebp+16], 5
mov DWORD PTR _run$[ebp+20], 6
mov DWORD PTR _run$[ebp+24], 7
mov DWORD PTR _run$[ebp+28], 8
mov DWORD PTR _run$[ebp+32], 9
mov ecx, 91 ; 0000005bH
xor eax, eax
lea edi, DWORD PTR _run$[ebp+36]
rep stosd
; Line 15
mov DWORD PTR _i$[ebp], 0
jmp SHORT $L534
$L535:
mov eax, DWORD PTR _i$[ebp]
add eax, 1
mov DWORD PTR _i$[ebp], eax
$L534:
cmp DWORD PTR _i$[ebp], 1002000 ; 000f4a10H
jge SHORT $L536
; Line 16
mov ecx, DWORD PTR _i$[ebp]
mov edx, DWORD PTR ?inbss@@3PAHA[ecx*4]
push edx
push OFFSET FLAT:$SG537
call _printf
add esp, 8
jmp SHORT $L535
$L536:
; Line 17
xor eax, eax
; Line 18
pop edi
mov esp, ebp
pop ebp
ret 0
_main ENDP
_TEXT ENDS
END
----------------------------------------
通过汇编文件可以看到,数组inbss和indata位于不同的段(inbss位于bss段,而indata位于data段)
若把test.cpp中的indata数组拿掉,查看生成的exe文件的大小,可以发现,indata拿掉之后exe文件的大小小了很多。而若拿掉的是inbss数组,exe文件大小跟没拿掉时相差无几。

说明了:
bss段(未手动初始化的数据)并不给该段的数据分配空间,只是记录数据所需空间的大小。
data(已手动初始化的数据)段则为数据分配空间,数据保存在目标文件中。

数据段包含经过初始化的全局变量以及它们的值。BSS段的大小从可执行文件中得到 ,然后链接器得到这个大小的内存块,紧跟在数据段后面。当这个内存区进入程序的地址空间后全部清零。包含数据段和BSS段的整个区段此时通常称为数据区。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: