C 语言 全局变量和局部变量的区别
/********************031 局部和全局变量************************
* 局部变量和全局变量
* C语言精彩编程百例 第31 */
#include <stdio.h>
int quanju; //全局变量 count
void func1(); //函数声明
void func2();
void main()
{
quanju = 100;
func1();
}
void func1()
{
int temp;
temp = quanju;
func2();
printf("quanju is %d\n",quanju);
func2();
}
void func2()
{
int quanju;
for (quanju=1;quanju<20;quanju++)
printf(".");
printf("\n");
}
担心 count是伪代码或保留字之类的东西, 吧count改为quanju 以便观察, 实际证明
没这回事儿
使用mingw gcc编译器 gcc 031.c -S -o 031.s 得出汇编代码
.file "031.c"
.comm _quanju, 4, 2 #全局变量
.def ___main; .scl 2; .type 32; .endef
.text
.globl _main
.def _main; .scl 2; .type 32; .endef
_main:
LFB10:
.cfi_startproc
pushl %ebp
.cfi_def_cfa_offset 8
.cfi_offset 5, -8
movl %esp, %ebp
.cfi_def_cfa_register 5
andl $-16, %esp
call ___main
movl $100, _quanju # _quanju = 100
call _func1
leave
.cfi_restore 5
.cfi_def_cfa 4, 4
ret
.cfi_endproc
LFE10:
.section .rdata,"dr"
LC0:
.ascii "quanju is %d\12\0"
.text
.globl _func1
.def _func1; .scl 2; .type 32; .endef
_func1:
LFB11:
.cfi_startproc
pushl %ebp
.cfi_def_cfa_offset 8
.cfi_offset 5, -8
movl %esp, %ebp
.cfi_def_cfa_register 5
subl $40, %esp
movl _quanju, %eax
movl %eax, -12(%ebp) #temp = _quanju
call _func2
movl _quanju, %eax
movl %eax, 4(%esp) # printf 函数参数传入
movl $LC0, (%esp) # printf 字符串传入
call _printf
call _func2
leave
.cfi_restore 5
.cfi_def_cfa 4, 4
ret
.cfi_endproc
LFE11:
.globl _func2
.def _func2; .scl 2; .type 32; .endef
_func2:
LFB12:
.cfi_startproc
pushl %ebp
.cfi_def_cfa_offset 8
.cfi_offset 5, -8
movl %esp, %ebp
.cfi_def_cfa_register 5
subl $40, %esp
movl $1, -12(%ebp) # 局部变量 quanju = 1
jmp L4
L5:
movl $46, (%esp) # _putchar参数传入 $46 就是 "."
call _putchar
addl $1, -12(%ebp) # 局部变量 quanju + = 1
L4:
cmpl $19, -12(%ebp) # 比较 quanju 和 19
jle L5 # 小于等于跳
movl $10, (%esp) # 换行
call _putchar
leave
.cfi_restore 5
.cfi_def_cfa 4, 4
ret
.cfi_endproc
LFE12:
.ident "GCC: (GNU) 4.8.1"
.def _printf; .scl 2; .type 32; .endef
.def _putchar; .scl 2; .type 32; .endef
局部变量都是在函数的栈中分配内存并通过 %ebp偏移寻址 。
由此可见两种方式的主要区别:
1. 内存分配的方式。 全局变量在程序的内存空间中直接分配, 局部变量在函数的栈空间分配空间。
2. 寻址方式, 全局变量通过符号链接直接寻址, 局部变量通过%ebp偏移寻址。
编译的汇编代码中出现一些cfi伪指令, 这个东西生产的东西没有出现在代码中,代码反编译的内容和汇编代码还是一致的。
不过反编译内容开头给出的一大堆完全不明白的东西, 从objdump的描述来看是两个部分: exception handler 和 CRTStarup 。
目前这个部分还没开始研究。