社区
C语言
帖子详情
请教程序在内存存放的问题
lxb365
2006-06-26 10:06:50
我们知道,内存分为代码段,数据段,栈,堆,我想问,所谓栈区,是不是采用的数据结构里面的堆栈方式来存储局部变量,具体是如何存储的,我在编程的时候还遇到参数入栈的不同形式,比如_cdecl和_stdcall,请教相关知识。
...全文
272
4
打赏
收藏
请教程序在内存存放的问题
我们知道,内存分为代码段,数据段,栈,堆,我想问,所谓栈区,是不是采用的数据结构里面的堆栈方式来存储局部变量,具体是如何存储的,我在编程的时候还遇到参数入栈的不同形式,比如_cdecl和_stdcall,请教相关知识。
复制链接
扫一扫
分享
转发到动态
举报
写回复
配置赞助广告
用AI写文章
4 条
回复
切换为时间正序
请发表友善的回复…
发表回复
打赏红包
jixingzhong
2006-06-30
打赏
举报
回复
一篇 老文档:
函数调用约定有多种,这里简单说一下:
1、__stdcall调用约定相当于16位动态库中经常使用的PASCAL调用约定。在32位的VC++5.0中PASCAL调用约定不再被支持(实际上它已被定义为__stdcall。除了__pascal外,__fortran和__syscall也不被支持),取而代之的是__stdcall调用约定。两者实质上是一致的,即函数的参数自右向左通过栈传递,被调用的函数在返回前清理传送参数的内存栈,但不同的是函数名的修饰部分(关于函数名的修饰部分在后面将详细说明)。
_stdcall是Pascal程序的缺省调用方式,通常用于Win32 Api中,函数采用从右到左的压栈方式,自己在退出时清空堆栈。VC将函数编译后会在函数名前面加上下划线前缀,在函数名后加上"@"和参数的字节数。
2、C调用约定(即用__cdecl关键字说明)按从右至左的顺序压参数入栈,由调用者把参数弹出栈。对于传送参数的内存栈是由调用者来维护的(正因为如此,实现可变参数的函数只能使用该调用约定)。另外,在函数名修饰约定方面也有所不同。
_cdecl是C和C++程序的缺省调用方式。每一个调用它的函数都包含清空堆栈的代码,所以产生的可执行文件大小会比调用_stdcall函数的大。函数采用从右到左的压栈方式。VC将函数编译后会在函数名前面加上下划线前缀。是MFC缺省调用约定。
3、__fastcall调用约定是"人"如其名,它的主要特点就是快,因为它是通过寄存器来传送参数的(实际上,它用ECX和EDX传送前两个双字(DWORD)或更小的参数,剩下的参数仍旧自右向左压栈传送,被调用的函数在返回前清理传送参数的内存栈),在函数名修饰约定方面,它和前两者均不同。
_fastcall方式的函数采用寄存器传递参数,VC将函数编译后会在函数名前面加上"@"前缀,在函数名后加上"@"和参数的字节数。
4、thiscall仅仅应用于"C++"成员函数。this指针存放于CX寄存器,参数从右到左压。thiscall不是关键词,因此不能被程序员指定。
5、naked call采用1-4的调用约定时,如果必要的话,进入函数时编译器会产生代码来保存ESI,EDI,EBX,EBP寄存器,退出函数时则产生代码恢复这些寄存器的内容。
naked call不产生这样的代码。naked call不是类型修饰符,故必须和_declspec共同使用。
关键字 __stdcall、__cdecl和__fastcall可以直接加在要输出的函数前,也可以在编译环境的Setting...\C/C++ \Code Generation项选择。当加在输出函数前的关键字与编译环境中的选择不同时,直接加在输出函数前的关键字有效。它们对应的命令行参数分别为/Gz、/Gd和/Gr。缺省状态为/Gd,即__cdecl。
要完全模仿PASCAL调用约定首先必须使用__stdcall调用约定,至于函数名修饰约定,可以通过其它方法模仿。还有一个值得一提的是WINAPI宏,Windows.h支持该宏,它可以将出函数翻译成适当的调用约定,在WIN32中,它被定义为__stdcall。使用WINAPI宏可以创建自己的APIs
haha168_2002
2006-06-30
打赏
举报
回复
栈区,有编译器自动分配释放,存放函数的参数,局部变量等。操作方式类似于数据结构中的栈。
堆区,有程序员分配释放,例:malloc().与数据结构的堆是两回事,分配方式类似于链表。
全局区(静态区),存放全局变量和静态变量。初始化的在一起,未初始化的在另一块。程序结束后系统释放。
文字常量区,存放常量字符串。
程序代码区,存放函数体的二进制代码。
vssql2005
2006-06-26
打赏
举报
回复
这些问题要查看数据结构的书,以及多用VC++进行调试,查看的它的内存占用情况,栈区,在C++中是在内存区域,分划成了很多区域,来存取不同的变量,如:全量变量、局部变量、静态变量等等分别存在不同的区域。栈,就是数据结构中所指出的“后进先出”的数据存储结构。把计算机的软件书多看看。
gongzilv
2006-06-26
打赏
举报
回复
建议参考 看雪学院的《加密解密》里的PE文件格式。
作者段刚,电子工业出版社出版,网上有电子书。
ARM下的
程序
运行
问题
本文强调在
程序
开发过程中,确保在ARM平台上进行测试的重要性,以避免因字节对齐错误导致的
问题
。同时,讨论了
内存
字节
存放
问题
及处理策略,特别是在使用强制类型转换和共用体时的注意事项。
程序
的
内存
分配
本文详细探讨了
程序
内存
的五个主要区域:栈区、堆区、全局/静态区、常量区和代码区。栈区
存放
函数参数和局部变量,由编译器自动分配和释放;堆区则由
程序
员手动管理,
程序
结束时可能由OS回收。全局变量和静态变量存储在一起,初始化和未初始化的分别
存放
。常量区用于存储常量字符串,代码区则
存放
二进制代码。了解这些
内存
区域对于优化
程序
和排查
内存
问题
至关重要。
C++ 解决
内存
溢出、
存放
在栈上、
存放
在堆上的区别
本文介绍了计算机
内存
的存储结构,包括栈和堆的特点。栈主要用于
存放
固定大小的局部变量,而堆则用于动态分配
内存
。
内存
溢出是由于未能有效管理
内存
导致的
问题
,可能由
内存
泄漏或过度分配引起。解决方法包括正确释放
内存
和优化
程序
设计。文章还提供了
存放
在栈和堆上的示例代码,强调了两者在
内存
管理和性能上的差异。
java的
内存
有几个区_JVM中有哪些
内存
区域及其作用
本文主要探讨JVM
内存
区域划分,这是面试常考
问题
。JVM运行代码需多块
内存
,不同
内存
存放
不同数据。介绍了方法区
存放
类信息,
程序
计数器记录字节码执行位置,Java虚拟机栈
存放
局部变量,Java堆
内存
存放
实例化对象,还提及其他
内存
区域,如本地方法栈和堆外
内存
。
程序
的指令和数据为什么分开
存放
?
本文探讨了计算机如何区分指令与数据的
问题
。通过分析进程的操作权限和
内存
管理方式,阐述了
程序
与数据分开
存放
的原因,包括保护指令不被篡改及节省
内存
等关键点。
C语言
70,038
社区成员
243,247
社区内容
发帖
与我相关
我的任务
C语言
C语言相关问题讨论
复制链接
扫一扫
分享
社区描述
C语言相关问题讨论
社区管理员
加入社区
获取链接或二维码
近7日
近30日
至今
加载中
查看更多榜单
社区公告
暂无公告
试试用AI创作助手写篇文章吧
+ 用AI写文章