win32win32 api编程入门求助----

1043人阅读
C++之旅(96)
因为要经典,不敢写得太多,欢迎大家继续补充。这里只是涉及编程的东东,如果想要关于破解方面的资料请到“工具下载”栏目的置顶帖。&
ps.网上这些书的电子版大都是未经作者同意而发布的,我并不能保证给出的链接长期有效。我的看法是您可以先下载试看;),如果觉得物有所值,还是推荐去买一本纸质书,也是支持一下作者的辛勤劳动。&
有用的网站:&
MSDN Library&
经典书籍:&
=======================&
WINDOWS编程类&
=======================&
Windows程序设计中文版(Programming Windows,Charles Petzold著)&
这个不用我多废话了,地球人都知道的经典,用C语言+WinSDK写成。&
Windows核心编程(Programming Applications for Microsoft Windows, Fourth Edition, Jeffrey Richter著)&
内容较深的一本书,同样经典,如果能通读一遍,可以说基本上就掌握了Windows的精髓。&
Win32 ASM Tutorial Resource Kit&
(解压密码:dREAMtHEATER)&
dREAMtHEATER收集的WIN32ASM教程,内容很全,包括32位汇编的基础知识,Iczelion的经典教程中英文版,罗云彬的32位汇编教程,还有PE格式和VxD的一些内容。&
Windows环境下32位汇编语言程序设计(罗云彬著)&
汇编语言版的Programmin Windows&,可以与上面Iczelion的教程相互参照着学习。&
=======================&
程序设计语言类&
=======================&
C语言程序设计(The C Programming Language (2nd Edition), Brian W.Kernighan & Dennis M.Ritchie著)&
作者是C语言和UNIX系统的发明人,这一本书是如此经典,以至于两位作者名字的缩写
K&R 成了一个专有名词,以至于书里的&Hello,World&这个简单的句子被无数人用无数种程序语言写出来。很薄的一本书,却成了一个不朽的传奇。个人看法,学好C语言,这一本小书足矣。&
C++语言程序设计(The C++ Programming Language (Special Editon),Bjarne Stroustrup著)&
作者是C++语言的发明人,这本书之于C++就好比上本书之于C,不同的是这本书巨厚无比,毕竟C++复杂了太多太多。这本书介绍到了C++的方方面面,巨细无遗,毕竟是作者发明的么,不过我只看了几章就晕得受不了了。&
btw:关于C++的好书还有很多,如&& C++ Primer &&, && Thinking in C++ &&, && Essential C++ &&、&& Effective C++ &&等等,因为我对C++不很感冒,这里不敢妄加评论,请大家多补充。&
再btw:对Java, .Net, Python这些新东东(Java好像也不新了吧,看来是我老了)了解不是很多,也不敢乱写,同样请各位补充。&
=======================&
面用对象WINDOWS编程类&
=======================&
也不知道这么说合适不合适,总之就是像MFC,VCL之类的东东啦。这类图书大概是最多最杂的了,像什么XX从入门到精通啦,XX编程宝典啦, XX编程100例啦……鱼龙混杂,泥沙俱下,也说不出哪个是经典。这里只选出几本有一定深度的,大家基本公认的好书。&
深入浅出MFC(第二版)(侯捷著)&
侯捷网站:&
关于侯先生写的和译的书,赞的人很多,骂的人也有,我是很推荐这本书的,虽然我不喜欢MFC,只硬着头皮看了前几章。感觉如果能通读下来,可以试着自己架一个类库了,呵呵。需要注意的是,读这本书先要有一定的SDK编程的基础,这本书不是教你如何用VC写程序的,好像有许多人不明白这一点,所以来骂侯先生,如果你只想快点用VC写个程序出来,建议去看看《21天VC++无师自通》之类的书。&
btw:侯先生的网站上有很多有趣的东东,顺便推荐一下。&
Delphi源代码分析(周爱民著)&
我只在很早之前玩过Delphi,水平就是只知道Form上放几个Button,Edit,双击两下就开始写代码,因为以前学过Pascal,看着语法很熟悉,玩得不亦乐乎,什么也不管,N久以后才知道有Object
Pascal这回事,汗……因为N多大牛推荐这本书,所以我也推荐一下,虽然里面东西基本都不懂。同样,这本书也不是教你如何画个窗口摆个控件的,那样的书遍地都是……&
=======================&
数据结构与算法类&
=======================&
算法、数据结构,这是计算机程序的灵魂所在。下面介绍的书可以在找到,而且那里有更详细的评论,强烈推荐!&
Introduction to Algorightms (算法导论,Thomas.H.Cormen等著)&
此书简称CLRS(四位作者名字的缩写),被人们称做“计算机算法的圣经”绝不为过,是ACM竞赛的必读书,影印版由高等教育出版社出版,共1180页,厚度约五公分虽然书很厚而且是英文,但是由于大师深入浅出的讲解,反而很好读懂,有时候我学一个算法,看相关中文书看得一头雾水,翻翻这本书却能豁然开朗。&
The Art of Computer Programming vol1,2,3(计算机程序设计艺术I-III卷,Donald.E.Knuth著)&
简称TAOCP,经典中的经典,名气可能比上一本书还大,此系列书原计划出七卷,目前为止只出版了三卷,已经被评为20世纪最重要的20部著作之一。因为里面用一种奇怪的程序语言写成,而且只出了三卷,内容没有CLRS全面,这套我没有买,只在图书馆里翻翻(有中译本),但绝对是值得一看的好书。&
Concrete Mathematics A Foundation for Computer Science (具体数学,Donald.E.Knuth & Ronald L.Graham著)&
同样是ACM竞赛必读书之一,几乎包含了所有计算机科学里涉及到的数学问题,里面有众多的经典问题与经典解法,对开拓人的数学思路有极大的帮助。看这书给我的感觉是,如果你能把每章后面所有的习题都解出来,估计离图灵奖也不远了&
=======================&
关于编程竞赛&
=======================&
下面是几个比较大的在线提交系统(Online Judge)里面有大量历年的竞赛题目,注册一个ID,然后用自己熟悉的语言(一般有Pascal/C /C++/Java)写好源代码提交即可,会实时返回信息告诉你是否正确。采用黑箱测试,系统里有一套标准的输入输出数据(对外保密,而且通常数据很多很怪),你的程序的输出和标准输出完全符合即可。常见的返回信息有AC(Accepted,通过)WA(Wrong
Answer,输出有错误)TLE(Time Limit Exceeded,超时)MLE(Memory Limit Exceeded,内存溢出)RE(Runtime Error,发生实时错误)等,只有AC了才算做对一题。这里只是一个简要介绍,请大家在做题时先看看各网站上的 FAQ,Enjoy it~~~&
浙江大学 Online Judge(ZOJ)&
国内最早也是最有名气的OJ,有很多高手在上面做题。特点是数据比较刁钻,经常会有你想不到的边界数据,很能考验思维的全面性,现在我主要在这个OJ上做题&
北京大学 Online Judge(POJ)&
建立较晚,但题目加得很快,现在题数和ZOJ不相上下,特点是举行在线比赛比较多,数据比ZOJ上的要弱,有时候同样的题同样的程序,在ZOJ上WA,在POJ上就能AC&
同济大学 Online Judge&&
这个OJ题数上不能与上两个相比,推荐这个OJ的原因是它是中文的,这对很多对英文不太感冒的兄弟是个好消息吧。它也因此吸引了众多高中的OIer,毕竟他们的英文还差一些呵呵,上面的题目也更偏向高中的信息学竞赛一些。&
西班牙Valladolid大学 Online Judge(UVA)&
世界上最大最有名的OJ,题目巨多而且巨杂,数据也很刁钻,全世界的顶尖高手都在上面。据说如果你能在UVA上AC一千道题以上,就尽管向IBM、微软什么的发简历吧,绝对不会让你失望的。&
俄罗斯Ural立大学 Online Judge(URAL)&
也是一个老牌的OJ,题目不多,但题题经典,我在高中的时候就在这上面做题的。&&
UsacoGate Online Judge(USACO)&
全美计算机奥林匹克竞赛(USACO)的训练网站,特点是做完一关才能继续往下做,与前面的OJ不同的是测试数据可以看到,并且做对后可以看标准解答,所以如果大家刚开始的时候在上面那些OJ上总WA却找不到原因的话,可以试着来这里做做,看看测试数据一般是从什么地方阴你的。
本文转自:http://blog.csdn.net/TravisLi4891/article/details/4586488
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:255533次
积分:4256
积分:4256
排名:第6108名
原创:132篇
转载:284篇
(1)(5)(25)(27)(14)(22)(13)(16)(36)(40)(14)(25)(16)(8)(23)(36)(36)(24)(11)(9)(11)(3)(2) 上传我的文档
 下载
 收藏
该文档贡献者很忙,什么也没留下。
 下载此文档
正在努力加载中...
win32实验编写程序 在窗口上设计一行文字, 要求文字能
下载积分:1000
内容提示:win32实验编写程序 在窗口上设计一行文字, 要求文字能
文档格式:DOCX|
浏览次数:67|
上传日期: 08:24:13|
文档星级:
该用户还上传了这些文档
win32实验编写程序 在窗口上设计一行文字, 要求文字能
官方公共微信查看: 1397|回复: 6
求助:如何让程序读取的系统时间是我自己指定的时间?
阅读权限10
在线时间53 小时
当前用户组为 梦之起当前积分为 77, 升到下一级还需要 123 点。
主题精华积分
我想从我的程序里创建一个进程,被创建的这个进程的程序读取系统时间是我指定的时间,不HOOK系统函数,能实现吗?&&请教教我或者大家给提提思路。
哎...今天够累的,签到来了...
阅读权限30
在线时间485 小时
当前用户组为 梦之承当前积分为 242, 升到下一级还需要 258 点。
主题精华积分
读取系统时间之前修改时间,读取后再改回来
阅读权限10
在线时间53 小时
当前用户组为 梦之起当前积分为 77, 升到下一级还需要 123 点。
主题精华积分
读取系统时间之前修改时间,读取后再改回来
问题是,不只读一次。
哎...今天够累的,签到来了...
阅读权限100
在线时间497 小时
当前用户组为 版主当前积分为 299, 该用户为特殊用户。
主题精华积分
原谅我这个菜鸟吧!真的不知道你想要做出一个什么样的程序出来,能给我讲讲思路吗?不然不知道你用意何在??
阅读权限10
在线时间53 小时
当前用户组为 梦之起当前积分为 77, 升到下一级还需要 123 点。
主题精华积分
原谅我这个菜鸟吧!真的不知道你想要做出一个什么样的程序出来,能给我讲讲思路吗?不然不知道你用意何在? ...
有一些软件限制是通过时间限制的,但是如果运行多个这样的程序但试用时间不一样,你改一个系统时间只能满足其中一部分,另一部分还是过期,但如果有这样的程序,给每个单独指定时间,那就呵呵了。这种软件已经有了,我就是纳闷他是怎么实现的,所以发帖求教。
(PS:你是菜鸟吗?你在逗我吗?论坛里的网络编程教程我可是有看的,向你学习,希望你继续出更好的教程,顺便吐个槽,下次录制视频能找个好点的麦吗?你不知道听得那叫一个费劲。)
哎...今天够累的,签到来了...
阅读权限100
在线时间497 小时
当前用户组为 版主当前积分为 299, 该用户为特殊用户。
主题精华积分
有一些软件限制是通过时间限制的,但是如果运行多个这样的程序但试用时间不一样,你改一个系统时间只能满 ...
听完你的介绍,我更加晕了~~~~
恩,多谢你的吐槽!我会改的!!你试试看看第七课和第八课还有那个问题没有,如果有那我就真的没办法了~~
《ps 我除了网络方面懂一点点之外,啥也不会~~~嘿嘿嘿..》
阅读权限10
在线时间53 小时
当前用户组为 梦之起当前积分为 77, 升到下一级还需要 123 点。
主题精华积分
自己顶一下,希望有会的人看到,帮助我一下。
哎...今天够累的,签到来了...
Powered by求教 win32API编程问题,关于windows 中的 setfocus()和WM_setfocus 疑问,谢谢大家了!
求教 win32API编程问题,关于windows 中的 setfocus()和WM_setfocus 疑问,谢谢大家了!
发布时间: 22:13:54
编辑:www.fx114.net
本篇文章主要介绍了"求教 win32API编程问题,关于windows 中的 setfocus()和WM_setfocus 疑问,谢谢大家了!
20CSDN]",主要涉及到求教 win32API编程问题,关于windows 中的 setfocus()和WM_setfocus 疑问,谢谢大家了!
20CSDN]方面的内容,对于求教 win32API编程问题,关于windows 中的 setfocus()和WM_setfocus 疑问,谢谢大家了!
20CSDN]感兴趣的同学可以参考一下。
对程序中的代码疑惑?
&LRESULT&CALLBACK&WndProc&(HWND&hwnd,&UINT&message,&WPARAM&wParam,LPARAM&lParam)
&&///&父窗口消息处理程序&&&&&&
&&&&&&&&&&&
&&&&&&&&&&&switch&(message)
&&&&&&&&&&&{
&&&&&&&&&&&&&case&&&WM_SETFOCUS:
&&&&&&&&&&&&&&&&&&SetFocus&(GetDlgItem&(hwnd,&idFocus))&;
&&&&&&&&&&&&&&&&&&return&0&;
&&&&&&&&&}
-----------------------------------------------------------------------------------
&LRESULT&CALLBACK&ChildWndProc&&(HWND&hwnd,&UINT&message,&WPARAM&wParam,LPARAM&lParam)
&&/////&///&子窗口消息处理程序&&&&&&&&&
&&&&&&&&&&&
&&&&&&&&&&&switch&(message)
&&&&&&&&&&&{
&&&&&&&&&&&&&case&&&WM_SETFOCUS:
&&&&&&&&&&&&&&&&&&&&idFocus&=&GetWindowLong&(hwnd,&GWL_ID)&;
&&&&&&&&&&&&&&&&&&return&0&;
&&&&&&&&&}
假设环境是在一个父窗口中罗列几个子窗口,子窗口共享一个窗口类别,共用同一个窗口处理程序(LRESULT&CALLBACK&ChildWndProc&&(HWND&hwnd,&UINT&message,&WPARAM&wParam,LPARAM&lParam),
书上是这么说的
(((((((在CHECKER4中,整体变量idFocus用于保存目前输入焦点窗口的子窗口ID(其实就是个子窗口的标志码自己随便设置,程序中用整数表示ID代表每个子窗口)。我在前面说过,当您在子窗口上面单击鼠标时,它们不会自动获得输入焦点。因此,CHECKER4中的父窗口将通过呼叫下面的函数来处理WM_SETFOCUS消息:
SetFocus&(GetDlgItem&(hwnd,&idFocus))&;
这样设定一个子窗口为输入焦点。))))))))
问题来了&,对以上的代码,我有2种理解,但都想不通?
&(1)&要说是父窗口消息处理程序先处理WM_setfocus把,SetFocus&(GetDlgItem&(hwnd,&idFocus))&中的idFocus&又没有设置好,他怎么知道要把输入焦点传给哪个子窗口?
&&(2)要说是先是子窗口先处理WM_setfocus把,&&idFocus&=&GetWindowLong&(hwnd,&GWL_ID)&;
倒是可以设置idFocus&,但是这样岂不是已经获得输入焦点拉吗?
我觉得是我对消息的发生传递顺序没明白,望大家多多指教~~&谢了!
一、不得利用本站危害国家安全、泄露国家秘密,不得侵犯国家社会集体的和公民的合法权益,不得利用本站制作、复制和传播不法有害信息!
二、互相尊重,对自己的言论和行为负责。
本文标题:
本页链接:Win32编程基础 - eGust - 博客园
本文将对x86平台的Win32位编程基础知识作一个简要的介绍,主要包括:进程空间,虚拟内存,内核态与用户态,模块,线程。实际上,几乎其中每个概念都可以谈很多,并且对于理解CPU、操作系统和应用程序都有很大的帮助。对程序员来说,如果对一些基本概念理解有误的话,处理问题的思路就会有问题。在一些论坛上可以见到不少帖子,问的问题根本不对路,让人完全无法回答&&恐怕大多数人都没兴趣去答一些类似&为什么1+1不等于3&之类的蠢问题。所以,了解这些基础知识,也是初学者能够正确理解自己的&问题&的前提。但限于篇幅所限,我只能尽量简短对我认为最关键的部分进行介绍。
同时,有许多看似神秘,或者初学者比较困惑难以理解的问题,正是由于基础知识不牢。在介绍进一步的知识之前,我也必须向初学者介绍这些基础,不然的话,可能根本就看不懂我在说什么。在这篇文章之后,我将带各位开始真正深入到Delphi的程序里,争取能尽快让各位了解到,编译器对一些看起来很平常的语句做了难些复杂的工作,从而真正了解自己的程序在做什么,避免不必要的麻烦。
在开始介绍之前,再最后强调一下:本文所讲的内容,都是基于WinNT内核的操作系统(主要是Win2000之后),与Win9x及更早的Windows操作系统关系不大,而且今天再研究在这些平台上的编程,已经基本上没什么意义了。
当我们从Windows开始菜单或文件夹中启动一个程序的时候,多数情况下是执行硬盘里的一个exe程序,很快程序就会运行起来。但在程序真正开始运行之前,Windows操作系统会做一些工作,并在系统中很容易看到这些改变。
首先,操作系统会为这个exe文件创建一个进程空间,并且为其分配一些资源。然后将可执行文件按照一定规则加载到该进程空间内,操作系统还会根据可执行文件的&说明&,将相应的动态链接库(DLL)映射进程空间内。接下来,操作系统会为该进程空间创建一个主线程,为该主线程分配一些资源。这一切都妥当了之后,Windows才会真正让主线程从这个exe文件指定的位置开始执行代码,程序才真正跑起来。
这些东西看起来似乎有些复杂,但对于程序的安全性来说,是必不可少的。早期的DOS操作系统中,应用程序都是直接与硬件打交道的,比如直接访问物理内存等等。这样虽说程序员可以完全掌握硬件,但同时也产生了不少问题。比如由于每个程序都能直接访问硬件,因此也可以访问其它程序的内容,甚至直接修改其它程序的内存。同时,操作系统的关键代码也可能遭到破坏,一个不当的程序可以导致操作系统死掉。这样带来了大量的安全隐患,而且也会给使用者带来很多麻烦&&用过Win9x系统的人,对时常出现的蓝屏应该记忆深刻吧。那么,如果每个程序都能够有一个独立的空间,就像在一个沙盒之中运行就好了,如果它出了问题,操作系统直接干掉它,不会影响其它程序岂不是更好呢?Intel CPU很早就在硬件上提供了支持,可以让CPU进入保护模式(Protected Mode)进行工作,利用权限的控制进行32位程序之间的隔离。在保护模式下,CPU的权限分为4个级别,其中ring 0权限级别最高,ring 3最低。当程序在较低权限级别中执行的时候,无法直接转到或访问高的内容。Windows操作系统使用了其中ring 0和ring 3两个级别,其中操作系统内核工作在ring 0中,普通的用户应用程序工作在ring 3中。这样,应用程序的异常,或是刻意的伤害,都不会直接破坏操作系统内核的正常运转。一旦应用程序出现问题,我们就可以杀掉它,而系统自身几乎不受影响。
由于在x86 Windows平台中,一段代码只会在ring 0和ring 3两个状态下执行,而ring 0只由操作系统内核级别的模块操作,因而一般被称为内核态与用户态。内核态主要负责以下几部分的工作:硬件的操作,内核对象的管理,IO管理,内存管理,线程调度等(实际上这些说法并不很严谨,但讲起来比较麻烦并且也不是本文的重点,所以基本上不影响理解就可以了)。
现在回到前面的内容,进程(Process)是内核对象的一种,也就是操作系统负责为一个程序构造一个独立的环境,这个环境内的资源可以相互直接访问,不同的环境之间则无法直接打交道。那么这个环境包括哪些内容呢?由于CPU要执行代码必须要与内存打交道,所以这个环境里一定要有内存空间。前面提到过,用户态的程序是无法直接与硬件打交道的,内存实际上是由操作系统进行管理的,那么我们平时说的&申请内存&之类的是怎么回事呢?同样,也是通过CPU硬件的支持,操作系统给了每个进程32位的平坦的虚拟地址,也就是4G的虚拟内存空间(Virtual Address Space),每个进程在这个受操作系统保护的空间内运行。为了保证操作系统能够正常的运转,Windows会将操作系统的内核数据与代码映射到每个进程的进程空间中。这样,对于一般情况下的应用程序来说,虚拟内存空间被划分为两个部分:一部分是低2GB地址作为用户空间;而高2GB地址则是系统空间,用户态程序无法直接访问。我们平时说的程序里的内存,实际上指的就是这低2GB的虚拟内存。现在暂时先不讲虚拟内存更细的内容,还是回到前面关于程序初始化的工作中来。为了让文章看起来不那么啰嗦,如无特殊说明,今后我会直接使用&内存&指代&虚拟内存&。
要执行的程序与其它映射到该进程空间里的DLL等一样,称为该进程空间中的一个模块(Module)。这些模块就像积木一样,共同成为进程的组成部分,相互之间是透明的。如果将一个程序比作一间工厂的话,进程就相当于厂房,而各个模块相当于设备。现在厂房和设备有了,不给力的话产品还是生产不出来。线程(Thread)则是CPU实际执行任务的环境,负责执行进程空间里的代码,一个进程空间可以有多个线程。当一个进程创建之后,操作系统会自动为它创建一个主线程,用来执行程序代码。每个线程包含一组状态,其中一些用来记录和恢复CPU的执行状态,另一些则是由程序的自行记录的内容,还有一些则是给系统内核使用的。线程也是内核对象之一,操作系统内核会进行线程调度,按照一定规则给每个线程分配CPU时间。一般情况下,同级别的每个线程都会获得一小段很短的时间片,使各个任务看起来像在&同时&运行,直到执行完毕或是采用某种方式暂停或退出为止。此外,对于我们写程序来说,线程还有一个很重要的组成部分&&栈,线程有独立的栈空间。
在计算机科学中,栈(Stack)是一种后进先出(LIFO:Last In First Out)的数据结构,这里的则是指这样的一块内存空间。有的文章或书里也将其称为&堆栈&,但我不推荐这种说法,因为会容易与后面讲到的&堆&弄混。在任何x86程序中,栈空间都是有非常重要的意义的。它是一块固定大小的空间,对于主线程来说,大小可由链接器(Linker)指定,在PE文件头的特定位置进行描述,再由操作系统在创建主线程时进行分配。一般来说,默认指定的大小是1M的一段地址,在初始时指向这段空间较高的地址。在结构化编程语言中,一般情况下,局部变量的空间在栈中分配;很多函数的调用约定要求参数压入栈中传递;并且在调用函数时,CPU会自动将调用方执行到的代码地址压入栈中,用来在函数调用完毕后返回原来的执行位置。参数等数据进入栈空间之后,栈指针同时向更低的地址增长,这个过程叫入栈;在一部分栈空间使用完毕之后,直接增加栈指针使之指向更高的地址,这个过程叫出栈。这样的机制,能够保证最后入栈的数据最先出栈,符合&后进先出&的性质。栈空间是非常宝贵的,并且要小心使用&&如果使用栈时超过了栈的大小,就会产生&栈溢出(Stack Overflow)&的错误;一旦栈的内容被不小心被破坏了,造成的结果对整个线程来说可能是灾难性的。可以把栈想象成一个盒子,每次新东西进来之后,都罗在更上面的位置;要拿的时候,只能拿走最上面的东西。现在东西摆放的高度就是栈指针指向的位置,如果东西堆放超过了盒子的高度,出现的问题就是栈溢出。也就是说,栈只能朝一个方向增长,不能增长的方向一端叫栈底;栈指针指向的位置表示目前已经增长到的位置,当前栈指针指向的位置也叫栈顶。
下面,我来通过一个程序片段,来举例说明栈的主要工作原理,代码如下:
function Sum(x1, x2, x3: Integer): I
Result := x1 + x2 + x3;
function foo: I
var a, b: I
Result := Sum(a, b, 30);
接下来,再来看一看在进入Sum前后,栈中都有哪些变化:
这里,左右两部分是进入Sum前后的栈状态,ESP是指向栈顶的栈指针。在Sum执行完毕后,编译器会生成让当前执行位置回到调用者(foo函数)的位置继续执行,并让ESP指向进入Sum前位置的代码。
可能你要问,操作系统是如何知道&栈溢出&的呢,难道每次都要进行检查么?下面对虚拟内存机制再进行一个简要的介绍。简单来说,用户态的2GB空间并不是可以直接使用的,而是通过CPU的硬件支持把虚拟地址划分为不同的页,页有不同的属性,保护模式下的CPU会根据属性的不同进行不同的反应。一般情况下,Win32按照4KB的粒度将内存分页,也就是说,一次性最少会处理4K的地址空间属性。在进程初始化完成之后,除了加载文件的地址和线程的栈地址外,其余的空间默认是未分配的状态。当程序试图访问未分配的空间时,CPU会引发一个访问异常。如果想使用一块空间,则必须通过系统内核划分一块保留空间,这块空间的属性可以设置成只读、完全访问以及更加复杂等一些状态。这些由应用程序向操作系统申请的空间,可能处于内存中的任何地方,被称为堆(Heap)。
现在再回到前面没有交待的一个问题:我们的程序运行在用户态,许多工作要通过内核态才能完成,那么用户态是如何与内核态进行交互的呢?简单来说,一般通过中断(Interrupt)、异常(Exception)或系统调用(System Call)等方式,才能由用户态进入内核态。由用户态进入内核态的时候,CPU和操作系统需要完成一系列复杂的工作,开销相对来说是比较大的。中断一般由硬件触发,异常也有硬件异常和软件异常,系统调用一般则是通过调用API(Application Programming Interface,应用程序接口)函数完成的。在进入内核态后,用户态应用程序会处于挂起状态,直到下次操作系统分配时间片、并把CPU使用权交给该线程为止。需要注意的是,API是一系列操作系统提供的函数库,主要目的是为了方便编程,并不是所有API都会由用户态进入内核态。
正因为由用户态切换到内核态的开销很高,所以一般的编译器都会对内存管理进行封装,使得一次可以划分到较大的地址,然后再从中分配空间给程序员,或者当内存使用完毕后,并不一定立即将空闲的内存交还操作系统,而是可能留给以后再次分配使用。通过这些机制进行内存管理,从而减少进行系统调用的次数,提高程序运行效率。平时我们提到的堆空间,实际上指的是由应用程序的RTL内存管理器(Memory Manager)划分的空间。明白这个概念非常重要,有许多时候虽然程序的逻辑实际上有问题,比如仍然访问一块已经&释放&了的内存,在运行时没有提示出错,但这不代表程序没问题。而且事实上这种&没出错&是件坏事&&如果能够马上体现出来,那么就很容易去修正。但错误的经验可能养成错误的习惯,有的时候环境变化了或者是处理的数据不同,程序才会出错,这时再去找问题就很困难了,因为那些错误的经验可能让你根本没有考虑到真正出问题的地方。
现在,关于进程、线程、模块、虚拟地址、用户态与内核态的介绍已经基本上讲完了。接下来,再对PE文件映射到进程空间后的段进行一个简单的介绍,然后再给出一张完整的、关于进程空间的图片,帮助各位理解。
PE文件是Windows中可执行文件使用的一种特殊文件结构,它的全称是可移植执行体(Portable Execute),我们平常见到和使用的exe、dll、ocx等都属于这种文件格式。可以把PE文件看到一个包裹,里面放着一些东西,一般来说,其中最主要的就是我们编译后的程序代码。除了代码以外,还有其它的内容,包括PE文件头、资源文件、文件段等。Windows在加载一个PE文件的时候,会根据文件头的描述,按照一定的规则把PE文件中的各个部分映射到进程空间中。例如,代码一般放在代码段中,代码段的属性一般是只读的,由此保证内存中的代码不会被不小心破坏掉。此外还有其它的段,例如我们在程序中声明的全局变量等会储存在PE文件的一个段中(还包括以前讲过的运行期常量,还有哪些内容会在以后的文章中介绍到),这个段会映射到一段可读写的内存地址当中。前文已经提到,映射后的PE文件,就成为进程空间中的一个模块(Module),所以,每个模块都有映射自身PE文件的内存段。有些文章中提到,全局变量是在堆中的,这是个不正确的表述&&堆是由应用程序向系统申请的内存空间,而段空间则是在操作系统加载PE文件时,就已经由内核映射到进程空间中了。
最后,如果有兴趣的话,可以参考《WINDOWS核心编程》的相关章节(内核对象,进程,Windows的内存结构)。
阅读(...) 评论() &

我要回帖

更多关于 win32 串口编程 的文章

 

随机推荐