从汇编看c++中extern关键字的使用
在c++中,extern关键字用来声明变量和函数,在声明函数的时候,有和没有extern的效果一样,即下面两条语句具有同样的效果:
代码如下:
extern void fun();
void fun();
但是对于变量,有和没有extern就有区别,当有extern时,只是告知编译器存在这个变量,编译器并不为该变量分配存储空间,即真正的声明;若没有extern,则在声明的同时,编译器也为该变量分配存储空间。
int main() {
extern int i;
}
; 1 : int main() {
push ebp
mov ebp, esp;esp为指向栈顶的一个寄存器,始终指向栈顶 ebp也是一个寄存器,用来在给main函数分配的栈空间上寻访局部变量,因此常常作为基址
;上面两句的作用是将前一个栈的基址保存(压栈),然后让ebp指向当前函数的栈空间,再次作为基址
; 2 : extern int i;
; 3 : }
xor eax, eax
pop ebp
ret 0;这三句是用来退栈用,以及函数的返回
从上面的汇编码可以看出,并没有为变量i在站上分配任何存储空间
int main() {
int i;
}
; 1 : int main() {
push ebp
mov ebp, esp
push ecx;与有extern时的最大的不同就是这一句
;ecx也是一个寄存器,这里讲ecx的值压栈,等同于为变量i在栈上分配了存储空间
;由于ecx中的值不确定,因此,如果我们访问没有初始化的局部变量,常常得到一个奇怪的值
; 2 : int i;
; 3 : }
xor eax, eax
mov esp, ebp
pop ebp
ret 0
可以看出,没有extern关键字时,确实为变量i在栈上分配了存储空间
上面的汇编使用cl指令在命令行产生的,如果用vs2010来产生汇编码,汇编码可能不一样,但意思是一样的。
相关推荐
-
C++中的extern “C”用法详解
简单来说,extern "C"是C++声明或定义C语言符号的方法,是为了与C兼容.说来容易,要理解起来还是得费些周折,首先我们要从C++和C的区别说起. 符号 大家都知道,从代码到可执行程序需要经过编译和链接两个过程,其中编译阶段会做语法检测,代码展开,另外它还会做一件事,就是将变量转成符号,链接的时候其实是通过符号来定位的.编译器在编译C和C++代码时,将变量转成符号的过程是不同的.本文所使用的编译器为gcc4.4.7 我们先来看一段简单的代码 复制代码 代码如下: /* hello
-
C/C++ 中extern关键字详解
C/C++ 中extern关键字详解 在C/C++编程过程中,经常会进行变量和函数的声明和定义,各个模块间共用同一个全局变量时,此时extern就派上用场了. 定义 extern可以置于变量或者函数前,以标示变量或者函数的定义在别的文件中,提示编译器遇到此变量和函数时在其他模块中寻找其定义,不需要分配内存,直接使用. 推荐:在.h中声明,因为在头文件定义的话,其他模块include此头文件,就会报重复定义错误 实验结论 1.在.h中声明 extern int g_a; 在.c中定义 int g_
-
实例详解C/C++中extern关键字
1 基本解释:extern可以置于变量或者函数前,以标示变量或者函数的定义在别的文件中,提示编译器遇到此变量和函数时在其他模块中寻找其定义.此外extern也可用来进行链接指定. 也就是说extern有两个作用,第一个,当它与"C"一起连用时,如: extern "C" void fun(int a, int b);则告诉编译器在编译fun这个函数名时按着C的规则去翻译相应的函数名而不是C++的,C++的规则在翻译这个函数名时会把fun这个名字变得面目全非,可能是f
-
C/C++混合编程之extern “C”的使用示例
前言 本文主要给大家介绍了关于C/C++混合编程extern "C"使用的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧. 首先要明白: C++号称是C语言的超集,也确实,从语言的基本语法上,C++是包含所有C语言的语法的,而且C++为了兼容C,连C语言的标准库也被纳入到C++的标准库中,比如在C++中我们仍然可以使用<stdio.h> ,它就是C++标准库的一部分(注意最好用新的标准<cstdio> ,而不是老的<stdio&g
-
C++中extern "C"的用法
学习过C++的人都知道,extern关键字可以置于变量或者函数前,以标示变量或者函数的定义在别的文件中,提示编译器遇到此变量和函数时在其他模块中寻找其定义.这里起到的是声明作用范围的用处.另外,extern还可以与"C"连用,作为链接指示.本文就此进行实例说明如下: 一.C++名字修饰(Name Mangling) 首先需要从C++的重载说起,在C++中函数重载指的是几个函数的函数名相同,参数列表不同.那么当生成obj中间文件/目标文件的时候,C++编译器如何区分这几个重载函数呢?可以
-
C/C++中extern "C" 的作用分析
我们经常会在C/C++程序中见到extern "C",这是一个很重要的概念.本文就来以实例形式讲述C/C++中extern "C"的作用.分享给大家供大家参考之用.具体分析如下: 作用:实现C和C++混合编程. 原理:C和C++编译器编译之后,函数名会编译成不同的名字,链接阶段名字查找会找不到目标,后面实例中会详解. 用法: ①.c文件中定义的函数,.cpp文件要调用时,该.cpp文件中要用extern "C"声明该函数: ②.反过来,.cpp文
-
深入理解C语言 static、extern与指针函数
1.exit(0)正常退出程序 exit(1)程序异常时退出程序 2.static(静态变量)修饰局部变量 在局部变量使用static修饰,会延长局部变量的存在期.但我们需要注意一下几点: •虽然static修饰变量的生存期很长,但它始终是局部变量,不能在其他函数中使用•static全局变量与普通的全局变量有什么区别?static局部变量和普通局部变量有什么区别?static函数与普通函数有什么区别? 全局变量(外部变量)的说明之前再冠以static 就构成了静态的全局变量.全局变量本身
-
C++中的extern声明变量详解
extern声明变量无外乎如下两种: 1.声明全局变量 2.声明函数 今天我们只谈extern,什么const.static之类等等与之相关或不相关的一律忽略,下面就分别对以上两种情况一一讲解 声明和定义 既然提到extern声明变量,那我们就必须搞清楚声明和定义的区别. 这里我们将普通数据变量和函数统称变量.从内存分配角度来说,声明和定义的区别在于声明一个变量不会分配内存,而定义一个变量会分配内存.一个变量可以被声明多次,但是只能被定义一次. 基于以上前提,我们可以把声明和定义类比为指针和内存
-
浅谈C/C++中的static与extern关键字的使用详解
一.C语言中的static关键字在C语言中,static可以用来修饰局部变量,全局变量以及函数.在不同的情况下static的作用不尽相同.(1)修饰局部变量一般情况下,对于局部变量是存放在栈区的,并且局部变量的生命周期在该语句块执行结束时便结束了.但是如果用static进行修饰的话,该变量便存放在静态数据区,其生命周期一直持续到整个程序执行结束.但是在这里要注意的是,虽然用static对局部变量进行修饰过后,其生命周期以及存储空间发生了变化,但是其作用域并没有改变,其仍然是一个局部变量,作用域仅
-
从汇编看c++中extern关键字的使用
在c++中,extern关键字用来声明变量和函数,在声明函数的时候,有和没有extern的效果一样,即下面两条语句具有同样的效果: 复制代码 代码如下: extern void fun(); void fun(); 但是对于变量,有和没有extern就有区别,当有extern时,只是告知编译器存在这个变量,编译器并不为该变量分配存储空间,即真正的声明:若没有extern,则在声明的同时,编译器也为该变量分配存储空间. 下面是有extern的情形时的c++源码: 复制代码 代码如下: int ma
-
从汇编看c++中的多态详解
在c++中,当一个类含有虚函数的时候,类就具有了多态性.构造函数的一项重要功能就是初始化vptr指针,这是保证多态性的关键步骤. 构造函数初始化vptr指针 下面是c++源码: class X { private: int i; public: X(int ii) { i = ii; } virtual void set(int ii) {//虚函数 i = ii; } }; int main() { X x(1); } 下面是对应的main函数汇编码: _main PROC ; 16 : in
-
从汇编看c++中函数里面的static关键字的使用说明
下面从汇编语言看其原理. 下面是c++源代码: 复制代码 代码如下: void add() { static int i = 1; i++;}int main() { add(); } 下面是main对应的汇编码 复制代码 代码如下: ; 5 : int main() { push ebp mov ebp, esp ; 6 : add(); call ?add@@YAXXZ ; 调用add ; 7 :
-
从汇编看c++中多态的应用
在c++中,当一个类含有虚函数的时候,类就具有了多态性.构造函数的一项重要功能就是初始化vptr指针,这是保证多态性的关键步骤.构造函数初始化vptr指针下面是c++源码: 复制代码 代码如下: class X {private: int i;public: X(int ii) { i = ii; } virtual void set(int ii) {//虚函数 i = ii; }};int main() { X x(1);} 下面
-
从汇编看c++中默认构造函数的使用分析
c++中的源程序: 复制代码 代码如下: class X {private: int i;}; int main() { X x;} 上面的类X没有定义构造函数,仅仅有一个int i. 下面为其汇编程序: 复制代码 代码如下: ; 7 : int main() { push ebp;ebp为一个寄存器,总是指向一个函数调用堆栈的栈底,作为基址,用偏移量来访问该调用栈上的变量,但这里没有任何变量要访问,因此不起作用 mov ebp, esp;这两句的作用是为了
-
从汇编看c++中变量类型的深入分析
全局变量的生命期和可见性是整个程序的运行期间,下面就来用汇编来看一下实际情况: c++源码: 复制代码 代码如下: int i = 2;//全局变量 int main() { int j = i;} 下面是汇编代码: 复制代码 代码如下: PUBLIC ?i@@3HA ; i_DATA SEGMENT?i@@3HA DD 02H ; 全局变量i内存空间_DATA ENDSPUB
-
从汇编看c++中引用与指针的使用分析
首先是引用情形下的c++源码: 复制代码 代码如下: void add(int a, int b, int&c) { c = a + b;} int main() { int a = 1; int b = 2; int c = 0; add(a, b, c); } 下面是main对应的汇编码: 复制代码 代码如下: ; 6 : int main() { push ebp mov ebp, esp sub esp, 12
-
从汇编看c++的默认析构函数的使用详解
c++中,如果没有为一个类提供析构函数,那么编译器会为这个类提供默认的析构的函数.由于析构函数的功能和构造函数相反,因此和默认的构造函数类似,编译器也会提供无用的默认的析构函数,和非无用的析构函数.两者的分析情况一样(对于默认的构造函数分析,请参看<从汇编看c++中默认构造函数的使用分析>).并且编译器会提供非无用的默认析构函数情形和默认构造函数类似: 1 类含有虚成员函数(类继承自虚基类或者继承的基类含有虚成员函数,也属于这种情况) 2 类继承自一个基类,基类含有自定义析构函数(如果基类没有
随机推荐
- DOM属性用法速查手册第1/4页
- Golang开发中常用的代码片段汇总
- Lua源码中字符串类型的实现
- Jquery遍历checkbox获取选中项value值的方法
- JS和Jquery获取和修改label的值的示例代码
- Vue路由跳转问题记录详解
- iOS远程推送Push开发教程
- python rsa 加密解密
- JS基于正则表达式的替换操作(replace)用法示例
- PHP概率计算函数汇总
- ASP所有的Session变量获取实现代码
- Linux中巧妙安装红旗紫光输入法
- JS模板实现方法
- SQL 外链接操作小结 inner join left join right join
- bootstrap和jQuery.Gantt的css冲突 如何解决
- Nginx防止直接用IP访问Web服务器的设置方法
- Android App中实现向右滑动销毁功能的要点解析
- java中如何获取相关参数
- PHP4实际应用经验篇(8)
- Django中ORM表的创建和增删改查方法示例