我们都知道一个c语言程序可能会包含.text(代码段)、 .data(数据段)、 .rodata(只读数据段)、 .bss(未初始化段)等,为了搞清楚不同变量的存放位置,我们做一些实验,最后再得出结论
首先我们写一个简单的c语言测试程序,命名asm.c
#include <stdio.h>
#include <string.h>
#define N 10
int a_global;
int a1_global=0;
int a2_global=5;
static int b_global;
static int b1_global=0;
static int b2_global=6;
const int c_global;
const static int c1_global;
const static int c2_global=7;
int main()
{
const char c_local;
const char c1_local='A';
return 0;
}
然后我们写一个简单的makefile将它编译,并且反汇编得到asm.dis这个反汇编文件,
makefile内容如下:
all:
arm-linux-gcc -c -o asm.o asm.c
arm-linux-ld -Ttext 0 -Tdata 0x800 asm.o -o asm.elf
arm-linux-objcopy -O binary -S asm.elf asm.bin
arm-linux-objdump -D asm.elf > asm.dis
clean:
rm *.bin *.o *.elf *.dis
asm.dis文件内容如下:
asm.elf: file format elf32-littlearm
Disassembly of section .text:
00000000 <main>:
0: e1a0c00d mov ip, sp
4: e92dd800 stmdb sp!, {fp, ip, lr, pc}
8: e24cb004 sub fp, ip, #4 ; 0x4
c: e24dd004 sub sp, sp, #4 ; 0x4
10: e3a03041 mov r3, #65 ; 0x41
14: e54b300e strb r3, [fp, #-14]
18: e3a03000 mov r3, #0 ; 0x0
1c: e1a00003 mov r0, r3
20: e89da808 ldmia sp, {r3, fp, sp, pc}
Disassembly of section .data:
00000800 <__data_start>:
800: 00000005 andeq r0, r0, r5
00000804 <b2_global>:
804: 00000006 andeq r0, r0, r6
Disassembly of section .rodata:
00000024 <c2_global>:
24: 00000007 andeq r0, r0, r7
Disassembly of section .bss:
00000808 <a1_global>:
808: 00000000 andeq r0, r0, r0
0000080c <b1_global>:
80c: 00000000 andeq r0, r0, r0
00000810 <b_global>:
810: 00000000 andeq r0, r0, r0
00000814 <c1_global>:
814: 00000000 andeq r0, r0, r0
00000818 <c_global>:
818: 00000000 andeq r0, r0, r0
0000081c <a_global>:
81c: 00000000 andeq r0, r0, r0
Disassembly of section .comment:
00000000 <.comment>:
0: 43434700 cmpmi r3, #0 ; 0x0
4: 4728203a undefined
8: 2029554e eorcs r5, r9, lr, asr #10
c: 2e342e33 mrccs 14, 1, r2, cr4, cr3, {1}
10: Address 0x10 is out of bounds.
分析反汇编文件我们得到 .data段包含初始值非0的全局变量(不管静态还是非静态)
分析反汇编文件我们得到 .rodata段包含被const修饰的初始值非0的全局变量
分析反汇编文件我们得到 .bss段包含初始值为0或未初始的全局变量(不管有没有const修饰也不管是不是静态还是非静态)
局部变量则保存在栈中,它的生存周期仅在所在局部(即所定义的{}内),代码则保存在.text(代码段)
下述链接为本人对C语言程序与进程内存布局的补充说明
https://blog.csdn.net/qq_37120369/article/details/115591115