第七章 变量的位置

本文介绍C/C++中变量存储的位置:包括 全局变量,静态局部变量,堆变量

#include<stdio.h>
int g_variable1 = 12345;
int g_variable2 = 45678;

int main()
{
	int one =1,two =2;
	scanf("%d,%d",&one,&two);
	printf("%d,%d\n",one,two);
	scanf("%d,%d",&g_variable1,&g_variable2);
	printf("%d,%d\n",g_variable1,g_variable2);
	return 0;
}

编译后的汇编代码

_DATA	SEGMENT
_g_variable1 DD	03039H
_g_variable2 DD	0b26eH
_DATA	ENDS

由上一部分可知 全局变量在data段中


CONST	SEGMENT
??_C@_05BBIB@?$CFd?0?$CFd?$AA@ DB '%d,%d', 00H		; `string'
CONST	ENDS
;	COMDAT ??_C@_06JDIH@?$CFd?0?$CFd?6?$AA@
CONST	SEGMENT
??_C@_06JDIH@?$CFd?0?$CFd?6?$AA@ DB '%d,%d', 0aH, 00H	; `string'
CONST	ENDS
;	COMDAT _main
_TEXT	SEGMENT
_one$ = -4
_two$ = -8
_main	PROC NEAR					; COMDAT

; 6    : {

	push	ebp
	mov	ebp, esp
	sub	esp, 72					; 00000048H
	push	ebx
	push	esi
	push	edi
	lea	edi, DWORD PTR [ebp-72]
	mov	ecx, 18					; 00000012H
	mov	eax, -858993460				; ccccccccH
	rep stosd

; 7    : 	int one =1,two =2;

	mov	DWORD PTR _one$[ebp], 1         ;这里存one
	mov	DWORD PTR _two$[ebp], 2         ;这里存two
; 8    : 	scanf("%d,%d",&one,&two);

	lea	eax, DWORD PTR _two$[ebp]
	push	eax
	lea	ecx, DWORD PTR _one$[ebp]
	push	ecx
	push	OFFSET FLAT:??_C@_05BBIB@?$CFd?0?$CFd?$AA@ ; `string'
	call	_scanf
	add	esp, 12					; 0000000cH

; 9    : 	printf("%d,%d\n",one,two);

	mov	edx, DWORD PTR _two$[ebp]
	push	edx
	mov	eax, DWORD PTR _one$[ebp]
	push	eax
	push	OFFSET FLAT:??_C@_06JDIH@?$CFd?0?$CFd?6?$AA@ ; `string'
	call	_printf
	add	esp, 12					; 0000000cH

; 10   : 	scanf("%d,%d",&g_variable1,&g_variable2);

	push	OFFSET FLAT:_g_variable2
	push	OFFSET FLAT:_g_variable1
	push	OFFSET FLAT:??_C@_05BBIB@?$CFd?0?$CFd?$AA@ ; `string'
	call	_scanf
	add	esp, 12					; 0000000cH

; 11   : 	printf("%d,%d\n",g_variable1,g_variable2);

	mov	ecx, DWORD PTR _g_variable2
	push	ecx
	mov	edx, DWORD PTR _g_variable1
	push	edx
	push	OFFSET FLAT:??_C@_06JDIH@?$CFd?0?$CFd?6?$AA@ ; `string'
	call	_printf
	add	esp, 12					; 0000000cH

由上代码发现:全局变量在数据区,生命周期与模块一致,使用立即数访问;

局部变量在栈区,使用ebp或esp访问(优化后会使用esp访问)


问题:关于局部静态变量:存储位置?初始化方式?

C语言中是不允许对局部静态变量用非常量赋初值的,C++中允许使用


#include<iostream>
void func(int a)
{
        static int b = a;
}
int main()
{
        int a;
        func(a);
        return 0;
}


以下是func中对应的汇编实现


; 4    :         static int b = a;

	xor	eax, eax
	mov	al, BYTE PTR _?$S25@?1??func@@YAXH@Z@4EA
	and	eax, 1	 //eax 与1 做位与运算,
	test	eax, eax
	jne	SHORT $L7353	//测试,不等跳转
	mov	cl, BYTE PTR _?$S25@?1??func@@YAXH@Z@4EA
	or	cl, 1
	mov	BYTE PTR _?$S25@?1??func@@YAXH@Z@4EA, cl   //将 那个地址赋1
	mov	edx, DWORD PTR _a$[ebp]			
	mov	DWORD PTR _?b@?1??func@@YAXH@Z@4HA, edx    //对 b 赋值
$L7353:
; 5    : }




由上可知,比较的标志位是用来让static变量初始化一次的,如果该位为1 ,则说明已经初始化,不需要再初始化。


关于堆变量:数据在new或malloc时,返回数据在堆中的地址,具体读者请自行实验。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章