当前位置:网站首页>VS2013-debug assembly code-generate asm file-structure memory layout-function parameter stack-calling convention
VS2013-debug assembly code-generate asm file-structure memory layout-function parameter stack-calling convention
2022-08-10 07:20:00 【Plugin development】
文章目录
Sometimes you need to look at the writing of the underlying assembly code,Or use a high-level language to write low-level assembly code,这时可以采用C语言或者C++Language ghostwriting,Then look at the generated assembly code.
1.生成asm文件
项目->属性->c/c+±>输出文件->汇编程序输出
There will be a build suffix in the project*.asm 的文件.里面有注释,Useful for program analysis.如下图所示:
生成之后在DebugThe assembly code of the corresponding file is located in the directory,如下图所示:
2.Use disassembly
It can be viewed directly in debug mode,点击调试->>>窗口->>反汇编 快捷键 CTRL+ALT+D.
3.结构体内存布局
一、内存对齐的原因
1.平台原因(移植原因):一些资料上是这样说的,“不是所有的硬件平台都能访问任意地址上的任意数据;某些硬件平台只能在某些特定地址处取某些特定的数据,否则就会抛出硬件异常”.也就是说在计算机在内存读取数据时,只能在规定的地址处读数据,而不是内存中任意地址都是可以读取的.
2.效率原因:正是由于只能在特定的地址处读取数据,所以在访问一些数据时,对于访问未对齐的内存,处理器需要进行两次访问;而对于对齐的内存,只需要访问一次就可以.其实这是一种以空间换时间的做法,但这种做法是值得的.
结构体内存对齐规则:
1.第一个成员在结构体变量偏移量为0 的地址处,也就是第一个成员必须从头开始.
2. 其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处.对齐数 The lesser of the compiler default alignment number and the size of this member.vs中默认值是8 Linux默认值为4(当然可以通过#pragma pack修改),But the modification can only be set to1,2,4,8,16.
3. 结构体总大小为最大对齐数的整数倍.(每个成员变量都有自己的对齐数)
4.如果嵌套结构体,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小就是所有最大对齐数(包含嵌套结构体的对齐数)的整数倍.
struct struct1 {
char c1;
char c2;
int i;
};
int main()
{
struct1 sobj1;
sobj1.c1 = 'a';
sobj1.c2 = 'b';
sobj1.i = 9;
printf("%d", sizeof(struct1));
}
c1是char型,占一个字节,第一个成员即 c1 在结构体变量偏移量为0 的地址处.
c2是char型,占一个字节,要对齐到对齐数的整数倍的位置.对齐数 = 编译器默认的一个对齐数与该成员大小中的较小值,vs中默认值是8,取较小值1,char类型的对齐数是1,所以对齐到1 的整数倍,那就是偏移量为1开始的地址空间.
i是int类型,占四个字节,要对齐到对齐数的整数倍的位置.int类型的对齐数就是 4,所以对齐到4 的整数倍.
4.Calling conventions and function arguments are pushed onto the stack
VC 中默认调用是 __cdecl 方式,Windows API 使用 __stdcall 调用方式,在 DLL 导出函数中,为了跟 Windows API 保持一致,建议使用 __stdcall 方式.
The calling convention is closely related to stack cleanup.If you write an assembly function,给 C/C++ 调用,在 __cdecl 方式下,The assembly function does not need to clear the stack,在 __stdcall 方式下,Assembly functions need to return(RET)Restore the stack before.
C 语言有 __cdecl、__stdcall、__fastcall、naked、__pascal.
C++ 语言有 __cdecl、__stdcall、__fastcall、naked、__pascal、__thiscall,比 C One more language __thiscall 调用方式.
1、__cdecl
__cdecl调用约定又称为 C 调用约定,是 C/C++ 语言缺省的调用约定.参数按照从右至左的方式入栈,函数本身不清理栈,此工作由调用者负责,返回值在EAX中. 由于由调用者清理栈,所以允许可变参数函数存在,如int sprintf(char* buffer,const char* format,…);.
2、__stdcall
__stdcall 很多时候被称为 pascal 调用约定.pascal Language is a very common teaching computer programming language in the early days,Its syntax is rigorous.参数按照从右至左的方式入栈,函数自身清理堆栈,返回值在EAX中.
3、__fastcall
顾名思义,__fastcall 的特点就是快,因为它通过 CPU 寄存器来传递参数.他用 ECX 和 EDX 传送前两个双字(DWORD)或更小的参数,剩下的参数按照从右至左的方式入栈,函数自身清理堆栈,返回值在 EAX 中.
4、naked
naked 是一个很少见的调用约定,一般不建议使用.编译器不会给这种函数增加初始化和清理代码,更特殊的是,你不能用return返回返回值,只能用插入汇编返回结果,此调用约定必须跟 __declspec 同时使用.例如定义一个求和程序,如__declspec(naked) int add(int a,int b);.
5、__pascal
这是 pascal 语言的调用约定,跟 __stdcall 一样,参数按照从右至左的方式入栈,函数自身清理堆栈,返回值在EAX中.VC 中已经废弃了这种调用方式,因此在写 VC 程序时,建议使用 __stdcall 代替.
6、__thiscall
这是 C++ 语言特有的一种调用方式,用于类成员函数的调用约定.如果参数确定,this 指针存放于 ECX 寄存器,函数自身清理堆栈;如果参数不确定,this指针在所有参数入栈后再入栈,调用者清理栈.__thiscall 不是关键字,程序员不能使用.参数按照从右至左的方式入栈.
边栏推荐
- 机器人控制器编程实践指导书旧版-实践一 LED灯(数字量)
- About MongoDb query Decimal128 to BigDecimal problem
- pytest之parametrize参数化
- 调试ZYNQ的u-boot 2017.3 不能正常启动,记录调试过程
- 【Rust指南】使用Cargo工具高效创建Rust项目 | 理解Rust特别的输入输出语句
- navicat for mysql 连接时报错:1251-Client does not support authentication protocol requested by server
- MySQL之InnoDB引擎(六)
- .NET-7.WPF学习经验总结
- 关于数据库中的中文模糊检索探讨
- 什么是长轮询
猜你喜欢
随机推荐
【Event Preview on August 9】Prometheus Summit
navicat for mysql 连接时报错:1251-Client does not support authentication protocol requested by server
MySQL索引事务
ATH10传感器读取温湿度
Please pay attention to me, thank you.
【MySQL】使用MySQL Workbench软件新建表
简单业务类
order by注入与limit注入,以及宽字节注入
Ladies and gentlemen, oracle11g, cdc2.2, flink1.13.6, single-table incremental synchronization.Without adding data
PLSQL学习第二天
Discussion on Chinese Fuzzy Retrieval in Databases
DGIOT支持工业设备租赁以及远程管控
ESP32 485风速
MySQL设置初始密码—注意版本mysql-8.0.30
DGIOT 30 million meters set pressure reading
每日一题,二叉树中增加一行
大佬,oracle单表增量同步时候源库服务器额外占用内存近2g,这不正常吧
如何正确理解线程机制中常见的I/O模型,各自主要用来解决什么问题?
34. 谈谈为什么要拆分数据库?有哪些方法?
uni 小程序腾讯地图polygon背景透明度