原文链接:http://blog.csdn.net/sytstarac/archive/2009/08/05/4411519.aspx
编译器:vc++6.0(因为此种实现依赖编译器处理)
此处只简要叙述一下机制。并附部分关键指令序列。
准备:
1,关于EBP:称做栈基址指针。为什么这样说呢?我们先来看看函数调用的过程:
参数从右到左压栈。
call指令执行,该指令将导致EIP压栈。
每个函数前两句必定是:push ebp mov ebp,esp。则call指令后,跳到被调函数出开始执行。保存ebp,即ebp压栈。
局部变量压栈。一般是sub esp,xxx的形式。
这就是将ebp称为基指针的原因:ebp-xx访问的时局部变量;ebp+xx访问的是参数。最左边参数地址是ebp+8h。ebp坐镇中间为基准。
2,函数返回值统一放入eax中。只要放得下。
3,栈扩展方向为从高地址到低地址。结构内的变量存贮方式:低地址对应声明顺序靠前的成员。一定要注意这里的区别!它关系到反汇编生成的代码里面的数字是怎么算出来的。但如果你自己写汇编代码就不用考虑这些了。只取成员名即可。
4,不能直接在两个存储器变量间用mov指令。
主要原理:
当调用一个返回结构体的函数时,在vc++下,是这样处理:
首先sub esp,xx, ......
编译器:vc++6.0(因为此种实现依赖编译器处理)
此处只简要叙述一下机制。并附部分关键指令序列。
准备:
1,关于EBP:称做栈基址指针。为什么这样说呢?我们先来看看函数调用的过程:
参数从右到左压栈。
call指令执行,该指令将导致EIP压栈。
每个函数前两句必定是:push ebp mov ebp,esp。则call指令后,跳到被调函数出开始执行。保存ebp,即ebp压栈。
局部变量压栈。一般是sub esp,xxx的形式。
这就是将ebp称为基指针的原因:ebp-xx访问的时局部变量;ebp+xx访问的是参数。最左边参数地址是ebp+8h。ebp坐镇中间为基准。
2,函数返回值统一放入eax中。只要放得下。
3,栈扩展方向为从高地址到低地址。结构内的变量存贮方式:低地址对应声明顺序靠前的成员。一定要注意这里的区别!它关系到反汇编生成的代码里面的数字是怎么算出来的。但如果你自己写汇编代码就不用考虑这些了。只取成员名即可。
4,不能直接在两个存储器变量间用mov指令。
主要原理:
当调用一个返回结构体的函数时,在vc++下,是这样处理:
首先sub esp,xx,在堆栈上开辟一个空间。大小为结构体大小。
然后l ......
不知不觉已经工作两年了,辞去了原来的工作,又跑回了我上学的地方。今天跑去一家室友介绍的公司面试。问得问题挺简单,但我答的却真不怎么地啊。回来又研究了一下,发现这些问题我应该都理解啊,怎么到别人问起的时候就全忘了一般呢。想想了发现还是学的不到位。不禁又想起了这么多年来,我都学到了什么东西呢。
大学时的啥都不懂,大一就知道上课,晚自习,学校机房(玩游戏,呵呵,魔兽就是从这时开始玩的,记得我跟我哥们都是新手的时候,打一个初级电脑,两个人用了2小时,最后扎的满屏幕全是箭塔)。大二时整个大环境终于将我领上了大学的正途,去网吧玩游戏。从此只是在考试之前学习。大三网游了一年,结果大三毕业六级没过,保研失败。到了大四,想想反正保研没过,有可能读研这条路就不适合我,所以就直接选择了工作。不过还挺顺利,一下子就找着了,顺利进入了东软。
我们当时进去的时候属于特招的那种,就是感觉你很牛,实际上屁也不是的那种。其他人我不知道,反正我进去的时候连用C语言写Hello World都不会,VC是啥我还没听说过,大学只用TC。不过经过两个月培训下来,我也会写代码了,真不简单。不过当时完成的作业都是抄的,因为基础很差 ......
不知不觉已经工作两年了,辞去了原来的工作,又跑回了我上学的地方。今天跑去一家室友介绍的公司面试。问得问题挺简单,但我答的却真不怎么地啊。回来又研究了一下,发现这些问题我应该都理解啊,怎么到别人问起的时候就全忘了一般呢。想想了发现还是学的不到位。不禁又想起了这么多年来,我都学到了什么东西呢。
大学时的啥都不懂,大一就知道上课,晚自习,学校机房(玩游戏,呵呵,魔兽就是从这时开始玩的,记得我跟我哥们都是新手的时候,打一个初级电脑,两个人用了2小时,最后扎的满屏幕全是箭塔)。大二时整个大环境终于将我领上了大学的正途,去网吧玩游戏。从此只是在考试之前学习。大三网游了一年,结果大三毕业六级没过,保研失败。到了大四,想想反正保研没过,有可能读研这条路就不适合我,所以就直接选择了工作。不过还挺顺利,一下子就找着了,顺利进入了东软。
我们当时进去的时候属于特招的那种,就是感觉你很牛,实际上屁也不是的那种。其他人我不知道,反正我进去的时候连用C语言写Hello World都不会,VC是啥我还没听说过,大学只用TC。不过经过两个月培训下来,我也会写代码了,真不简单。不过当时完成的作业都是抄的,因为基础很差 ......
在项目属性页 --> 配置属性 --> C/C++ --> 输出文件里面,将汇编输出的下拉列表从无列表选择为你需要汇编输出的内容,比如“仅列出程序集(/FA)”,如图1-1,图1-2:
图1-1
图1-2
---------------------------------------------------------------------------------------------------------
图1-3是未修改之前Debug目录下的文件:
图1-3
图1-4是修改之后Debug目录下的文件,注意多了两个汇编文件
图1-4
图1-5是汇编文件HelloWorld.asm的具体内容
图1-5
这样,当你搞不懂编译器到底做了些什么,或者某块内存中到底是什么东西,你可以来查看汇编代码。
比如int i = 5;
int a = (++ i) + (++ i) + (++ i) ;
a是等于22还是24,看你编译器了。o(∩_∩)o...
另外,解决运行时窗口一闪而过的办法是:按Ctrl+F5。
或许这些都是很菜的问题,或许是我平时对VS接触的不多,不过遇到问题解决问题,心情大好。
......
在项目属性页 --> 配置属性 --> C/C++ --> 输出文件里面,将汇编输出的下拉列表从无列表选择为你需要汇编输出的内容,比如“仅列出程序集(/FA)”,如图1-1,图1-2:
图1-1
图1-2
---------------------------------------------------------------------------------------------------------
图1-3是未修改之前Debug目录下的文件:
图1-3
图1-4是修改之后Debug目录下的文件,注意多了两个汇编文件
图1-4
图1-5是汇编文件HelloWorld.asm的具体内容
图1-5
这样,当你搞不懂编译器到底做了些什么,或者某块内存中到底是什么东西,你可以来查看汇编代码。
比如int i = 5;
int a = (++ i) + (++ i) + (++ i) ;
a是等于22还是24,看你编译器了。o(∩_∩)o...
另外,解决运行时窗口一闪而过的办法是:按Ctrl+F5。
或许这些都是很菜的问题,或许是我平时对VS接触的不多,不过遇到问题解决问题,心情大好。
......
C和C++编程和学习文档
1 :指针变量名称以p为首字符,这是程序员通常在定义指针时的一个习惯
2 :har * p; (int *)p 把p强制转换为int型
3.1 :指针的问题:指针应用时最好给予定义(初始化)这样可以保证指针的指向是程序员自己能够把握的。
3.2 :指针的越界,这恐怕是最难查出的吧!
3.3 :指针的局部变量问题。局部的指针变量会被程序自动释放,若程序员引用此类指针就会出错。2007-9-1
4.二维指针的应用实例:
#include <stdio.h>
#include <string.h>
void sort(char (*client)[10]);
void main()
{
int temp;
char client[3][10];
& ......
C和C++编程和学习文档
1 :指针变量名称以p为首字符,这是程序员通常在定义指针时的一个习惯
2 :har * p; (int *)p 把p强制转换为int型
3.1 :指针的问题:指针应用时最好给予定义(初始化)这样可以保证指针的指向是程序员自己能够把握的。
3.2 :指针的越界,这恐怕是最难查出的吧!
3.3 :指针的局部变量问题。局部的指针变量会被程序自动释放,若程序员引用此类指针就会出错。2007-9-1
4.二维指针的应用实例:
#include <stdio.h>
#include <string.h>
void sort(char (*client)[10]);
void main()
{
int temp;
char client[3][10];
& ......
n 用标识符代表一个常量,称为符号常量。 n 符号常量与变量不同,它的值在其作用域内不能改变,也不能再被赋值。 n 使用符号常量的好处是: Ø 含义清楚; Ø 能做到“一改全改”。 --话说:不知道c里面有没有全局变量的东东,有的话,这两个的实际用处有啥子区别呢?看看再说 数据结构+算法=程序 终于知道这个著名的公式原来是Nikiklaus Wirth提出的;其实这应该是早期的公式了,因为现代的软件工程应该有另一个公式来表示:业务对象+业务逻辑=软件项目。 ......