C语言指针与汇编语言地址
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
55
push ebp
Thank You!
F11、Alt+8、在反汇编窗口中点鼠标右键,勾选显示代码字节
求函数大小(Debug)
代码要素
对应内存地址 字节 55 入口函数main 411300 e9 a2 01 00 00 _fun2 411109 fun2 4112b0 55 _fun1 fun1 _fun3 fun3 size of fun1 411104 411270 41110e 4112e0 40
求函数大小(Release) 代码要素 对应内存地址 入口函数main 401040 fun2 401020 fun1 401000 fun3 size of fun1 size of fun2 401030 20 10 字节 56 56 56 c3 含义 push esi push esi push esi ret fun2-fun1 fun3-fun2
求函数大小和求函数调用者
文件、新建、项目 Win32 控制台应用程序 名称:prj1 位置:d:\prjzz 解决方案名称:prj1 确定 下一步 空项目 完成 项目、属性、配置属性、C/C++、预编译头、预编译头:不使用预编译 头 项目、属性、配置属性、C/C++、代码生成、基本运行时检查:默认值 项目、属性、配置属性、链接器、高级、随机基址:否
e9 67 01 00 00
含义 push ebp Jmp fun2 push ebp Jmp fun1 push ebp Jmp fun3 push ebp fun2-fun1
55
e9 cd 01 00 00
55
size of fun2
30
fun3-fun2
求函数大小
解决方案配置:Release 项目、属性、配置属性、C/C++、预编译头、预编译头:不使用预编译头 项目、属性、配置属性、C/C++、代码生成、基本运行时检查:默认值 项目、属性、配置属性、链接器、高级、随机基址:否
求函数大小和求函数调用者
汇编窗口
内存1 窗口
Alt+8
单步执行
Alt+6
F11
寄存器窗口
内存2 窗口
Alt+5
Ctrl+Alt+M,2
求函数大小
鼠标右键点源文件、添加、现有项、d:\prjzz\prj1\prj1\sizeoffun.c、添加 在sizeoffun.c上双击鼠标左键
#include <stdio.h> void fun1() { int f1=1; printf("fun1\n");printf("fun1\n"); } void fun2() { int f2=2; printf("fun2\n"); } void fun3() {} int main() { #ifdef _DEBUG printf("sizeof(fun1)==%d\n",((int)fun2+5+*(int *)((int)fun2+1))-((int)fun1+5+*(int *)((int)fun1+1))); printf("sizeof(fun2)==%d\n",((int)fun3+5+*(int *)((int)fun3+1))-((int)fun2+5+*(int *)((int)fun2+1))); #else printf("sizeof(fun1)==%d\n",(int)fun2-(int)fun1); printf("sizeof(fun2)==%d\n",(int)fun3-(int)fun2); #endif return 0; }
求函数调用者
鼠标右键点sizeoffun.c、选移除、在弹出的对话框中点移除。 鼠标右键点源文件、添加、现有项、d:\prjzz\prj1\prj1\whocallme.c、添加 在whocallme.c上双击鼠标左键
#include <stdio.h> void whocallme(); void fun1() { printf("in fun1\n");whocallme(); } void fun2() { printf("in fun2\n");whocallme(); } void fun3() {} void whocallme() { int *_ebp; __asm { mov eax,ebp mov _ebp,eax } #ifdef _DEBUG printf("\nfun1,fun2,fun3,_ebp=%08x,%08x,%08x,%08x\n",(int)fun1+5+*(int *)((int)fun1+1),(int)fun2+5+*(int *)((int)fun2+1),(int)fun3+5+*(int *)((int)fun3+1),(int)_ebp); #else printf("\nfun1,fun2,fun3,_ebp=%08x,%08x,%08x,%08x\n",(int)fun1,(int)fun2,(int)fun3,(int)_ebp); #endif printf("ret addr=%08x\n",_ebp[1]); #ifdef _DEBUG if ((int)fun1+5+*(int *)((int)fun1+1)<=_ebp[1] && _ebp[1]<(int)fun2+5+*(int *)((int)fun2+1)) printf("fun1 callme\n"); if ((int)fun2+5+*(int *)((int)fun2+1)<=_ebp[1] && _ebp[1]<(int)fun3+5+*(int *)((int)fun3+1)) printf("fun2 callme\n"); #else if ((int)fun1<=_ebp[1] && _ebp[1]<(int)fun2) printf("fun1 callme\n"); if ((int)fun2<=_ebp[1] && _ebp[1]<(int)fun3) printf("fun2 callme\n"); #endif } int main() { fun2(); fun1(); return 0; }
解决方案配置:Debug 、F11、Alt+8、在反汇编窗口中点鼠标右键,勾选显示代码字节
求函数调用者(Debug) 代码要素 对应内存地址 入口函数main 411430 fun2 4112b0 whocallme 411300 _ebp _ebp[1] fun1 fun3 12fe84 12fe8c 411280 4112e0 字节 55 55 55 88 fe 12 00
含义 push ebp push ebp
fun2
whocallme
_ebp _ebp[1] fun1
401050
12ff30 12ff38 401000
55
34 ff 12 00
36 10 40 00
push ebp
进入函数时ebp寄存器的值
栈底的返回地址401036
55
push ebp
fun3
401040
cc 12 41 00
含义 push ebp push ebp push ebp
进入函数时ebp寄存器的值
栈底的返回地址4112cc
55 55
push ebp push ebp
求函数调用者(Release)
项目、属性、配置属性、C/C++、优化:已禁用 (/Od)
代码要素
入口函数main
对应内存地址 字节 4010e0 401020 55 55
zhao4zhong1 (赵中)
C语言指针与汇编语言地址
教学计划
• 第wenku.baidu.com次课: 演示使用VC2010查看每句C对应的汇编指令和每个C语言成分对应的汇编地址或寄存器。
•
• • • •
第2次课: 通过求函数大小功能和求函数调用者实例了解指针与函数对应的汇编内存地址。
第3、4次课: 通过静态和动态一、二、三维数组实例了解指针与数组对应的汇编内存地址。 第5、6次课: 通过带头节点和不带头节点的单链表实例了解指针与单链表对应的汇编内存地址。 第7、8次课: 通过双向链表和双向循环链表实例了解指针与双向链表对应的汇编内存地址。 第9、10次课:通过十字链表实例了解指针与十字链表对应的汇编内存地址。