VC++技术细节
文章平均质量分 83
通过反汇编的方式剖析VC++的实现原理
aluluka
这个作者很懒,什么都没留下…
展开
-
VC 在调用main函数之前的操作
在C/C++语言中规定,程序是从main函数开始,也就是C/C++语言中以main函数作为程序的入口,但是操作系统是如何加载这个main函数的呢,程序真正的入口是否是main函数呢?本文主要围绕这个主题,通过逆向的方式来探讨这个问题。本文的所有环境都是在xp上的,IDE主要使用IDA 与 VC++ 6.0。为何不选更高版本的编译器,为何不在Windows 7或者更高版本的Windows上实验呢?我...原创 2018-09-16 13:52:23 · 1233 阅读 · 0 评论 -
C 堆内存管理
在Win32 程序中每个进程都占有4GB的虚拟地址空间,这4G的地址空间内部又被分为代码段,全局变量段堆段和栈段,栈内存由函数使用,用来存储函数内部的局部变量,而堆是由程序员自己申请与释放的,系统在管理堆内存的时候采用的双向链表的方式,接下来将通过调试代码来分析堆内存的管理。 堆内存的双向链表管理下面是一段测试代码#include <iostream>using...原创 2018-09-01 13:16:47 · 958 阅读 · 2 评论 -
为什么C语言会有头文件
前段时间一个刚转到C语言的同事问我,为什么C会多一个头文件,而不是像Java和Python那样所有的代码都在源文件中。我当时回答的是C是静态语言很多东西都是需要事先定义的,所以按照惯例我们是将所有的定义都放在头文件中的。事后我再仔细想想,这个答案并不不能很好的说明这个问题。所以我在这将关于这个问题的相关内容写下来,希望给大家一点提示,也算是一个总结 include语句的本质要回答这个...原创 2018-06-16 11:08:41 · 15263 阅读 · 5 评论 -
C/C++中整数与浮点数在内存中的表示方式
在C/C++中数字类型主要有整数与浮点数两种类型,在32位机器中整型占4字节,浮点数分为float,double两种类型,其中float占4字节,而double占8字节。下面来说明它们在内存中的具体表现形式: 整型: 整型变量占4字节,在计算机中都是用二进制表示,整型有无符号和有符号两种形式。 无符号变量在定义时只需要在相应类型名前加上unsigned 无符号整型变量用32位的二原创 2015-12-27 12:16:00 · 3452 阅读 · 0 评论 -
地址、指针与引用
计算机本身是不认识程序中给的变量名,不管我们以何种方式给变量命名,最终都会转化为相应的地址,编译器会生成一些符号常量并且与对应的地址相关联,以达到访问变量的目的。 变量是在内存中用来存储数据以供程序使用,变量主要有两个部分构成:变量名、变量类型,其中变量名对应了一块具体的内存地址,而变量类型则表明该如何翻译内存中存储的二级制数。我们知道不同的类型翻译为二进制的值不同,比如整型是直接通过数学转原创 2016-01-03 14:11:22 · 469 阅读 · 0 评论 -
C/C++中define定义的常量与const常量
常量是在程序中不能更改的量,在C/C++中有两种方式定义常量,一种是利用define宏定义的方式,一种是C++中新提出来的const型常变量,下面主要讨论它们之间的相关问题;define定义的常量: define是预处理指令的一种,它用来定义宏,宏只是一个简单的替换,将宏变量所对应的值替换,如下面的代码:#define NUM 2int main(){ printf("%原创 2016-02-28 13:21:13 · 6360 阅读 · 0 评论 -
IF和SWITCH的原理
在C语言中,if和switch是条件分支的重要组成部分。if的功能是计算判断条件的值,根据返回的值的不同来决定跳转到哪个部分。值为真则跳转到if语句块中,否则跳过if语句块。下面来分析一个简单的if实例:if(argc > 0){ printf("argc > 0\n");}if (argc <= 0){ printf("argc <= 0\n");}printf(原创 2016-04-10 14:41:11 · 2916 阅读 · 0 评论 -
C语言循环的实现
在C语言中采用3中语法来实现循环,它们分别是while、for、do while,本文将分别说明这三种循环的实现,并对它们的运行效率进行比较。do while首先来看do while的实现:下面是简单的代码:int nCount = 0;int nMax = 10;do { nCount++;} while (nCount < nMax);return 0;原创 2016-04-11 20:26:53 · 957 阅读 · 0 评论 -
C函数原理
C语言作为面向过程的语言,函数是其中最重要的部分,同时函数也是C种的一个难点,这篇文章希望通过汇编的方式说明函数的实现原理。栈结构与相关的寄存器在计算中,栈是十分重要的一种数据结构,同时也是CPU直接支持的一种数据结构,栈采用先进后出的方式。CPU中分别用两个寄存器ebp和esp来保存栈底地址和栈顶地址,在CPU层面只需要ebp的值大于ESP的值两个寄存器所指向的内存的中间的部分就构原创 2016-04-22 22:09:54 · 6226 阅读 · 3 评论 -
C语言中不同变量的访问方式
C语言中的变量大致可以分为全局变量,局部变量,堆变量和静态局部变量,这些不同的变量存储在不同的位置,有不同的生命周期。一般程序将内存分为数据段、代码段、栈段、堆段,这几类变量存储在不同的段中,造成了它们有不同的生命周期。全局变量全局变量的生命周期是整个程序的生命周期,随着程序的运行而存在,随着程序的结束而消亡,全局变量位于程序的数据段。每个应用程序有4GB的虚拟地址空间,在程序开始时系统将这个程序加原创 2016-04-25 20:35:48 · 1763 阅读 · 0 评论 -
数组的剖析
C语言中数组是十分重要的一种结构,数组采用的是连续存储的方式,下面通过反汇编的方式来解析编译器对数组的操作。数组作为局部变量在任意一个函数当中定义的变量都会被当做局部变量,它们的生命周期与函数的调用有关,下面是一个例子:int main(){ int nArray[5] = {1, 2, 3, 4, 5}; int num1 = 1; int num2原创 2016-04-26 21:30:29 · 573 阅读 · 0 评论 -
结构体和类
在C++中类与结构体并没有太大的区别,只是默认的成员访问权限不同,类默认权限为私有,而结构体为公有,所以在这将它们统一处理,在例子中采用类的方式。类对象在内存中的分布在类中只有数据成员占内存空间,而类的函数成员主要分布在代码段中,不占内存空间,一般对象所占的内存空间大小为sizeof(成员1) + sizeof(成员2) + … + sizeof(成员n)但是有几种情况不符合这个公式,比如原创 2016-06-09 11:50:48 · 780 阅读 · 0 评论 -
C++类的构造函数与析构函数
C++中每个类都有其构造与析构函数,它们负责对象的创建和对象的清理和回收,即使我们不写这两个,编译器也会默认为我们提供这些构造函数。下面仍然是通过反汇编的方式来说明C++中构造和析构函数是如何工作的。编译器是否真的会默认提供构造与析构函数在一般讲解C++的书籍中都会提及到当我们不为类提供任何构造与析构函数时编译器会默认提供这样六种成员函数:不带参构造,拷贝构造,“=”的重载函数,析构函数,以及带co原创 2016-06-29 22:11:09 · 5306 阅读 · 0 评论 -
C++多态
面向对象的程序设计的三大要素之一就是多态,多态是指基类的指针指向不同的派生类,其行为不同。多态的实现主要是通过虚函数和虚表来完成,虚表保存在对象的头四个字节,要调用虚函数必须存在对象,也就是说虚函数必须作为类的成员函数来使用。 编译器为每个拥有虚函数的对象准备了一个虚函数表,表中存储了虚函数的地址,类对象在头四个字节中存储了虚函数表的指针。 下面是一个具体的例子class CVirtual{原创 2016-07-05 23:31:04 · 584 阅读 · 0 评论 -
C++继承分析
面向对象的三大特性之一就是继承,继承运行我么重用基类中已经存在的内容,这样就简化了代码的编写工作。继承中有三种继承方式即:public protected private,这三种方式规定了不同的访问权限,这些权限的检查由编译器在语法检查阶段进行,不参与生成最终的机器码,所以在这里不对这三中权限进行讨论,一下的内容都是采用的共有继承。单继承首先看下面的代码:class CParent{public原创 2016-07-09 22:39:48 · 2144 阅读 · 0 评论 -
VC++平台上的内存对齐操作
我们知道当内存的边界正好对齐在相应机器字长边界上时,CPU的执行效率最高,为了保证效率,在VC++平台上内存对齐都是默认打开的,在32位机器上内存对齐的边界为4字节;比如看如下的代码:struct MyStruct{ int i; char c;};int _tmain(int argc, _TCHAR* argv[]){ cout<<sizeof(MyStruct)原创 2015-09-11 00:14:59 · 1354 阅读 · 0 评论