Windows内核 语言选择注意点
调用约定:
调用约定指的是函数被调用时,会按照不同规则,翻译成不同的汇编代码。当一个函数被调用时,首先会将返回地址压入堆栈,紧接着会将函数的参数依次压入堆栈。不同的调用约定,会指明不同的参数入栈顺序,还会指明不同的清理堆栈的方法。用C语言或者C++语言编译器编译程序时,会有四种不同的调用约定去编译函数:
C语言的调用约定,函数由__cdecl修饰;
标准调用约定,函数由__stdcall修饰;
快速调用约定,函数由__fastcall修饰;
C++类成员函数的调用约定,函数由thiscall修饰。
不同的调用约定编译后,会产生不同的汇编代码。下面只介绍C语言调用约定和标准调用约定。
C语言调用约定要求在声明函数时用__cdecl对函数进行修饰:
void __cdecl ASCEFunc(int a, int b);
C语言调用会在目标文件中产生一个符号来代表这个函数,此符号形式是:下划线+函数名,且函数体以ret形式返回。即从右至左将参数压入堆栈,执行结束时,以ret返回。此时的堆栈和调用前的堆栈不一致,需要“调用者”恢复堆栈,用add指令将堆栈恢复平衡。
标准调用约定要求在声明函数时用__stdcall对函数进行修饰:
void __stdcall ASCEFunc(int a, int b);
C语言调用会在目标文件中产生一个符号来代表该函数,此符号形式为:下划线+函数名+X,其中X代表清理堆栈时需要的数字,函数以ret X形式返回。即从右至左将参数压入堆栈,当函数调用完,函数以ret 8返回函数。ASCEFunc函数负责恢复堆栈,而“调用者”不负责恢复堆栈,这个是C语言调用和标准调用最重要的区别之一。
一般程序中很少见到用关键字指定函数的调用约定的,因为编译器会选择默认的调用约定进行编译,在VC编译器中,默认使用C语言的调用约定。而在Windows驱动的编写中,需要使用标准调用约定,尤其是入口函数。系统会寻找_DriverEntry@8作为驱动程序的入口点。如果用C语言调用约定,会将DriverEntry编译成_DriverEntry,而不是_DriverEntry@8,那么就会导致链接错误。
函数的导出名:
同样一个函数,用C语言编译器和C++语言编译器编译出来的符号名是不同的。在链接时,链接器不知道源程序的函数名,而只会去目标文件中寻找相应的函数符号表。VC或者DDK提供的编译器c1.exe既可以编译C语言,也可以编译C++语言。默认情况下,编译器会根据源文件的扩展名来判断使用哪种方式。
同样使用标准调用约定编译函数:
void __stdcall ASCEFunc(int a, int b);
在C++编译器中会编译成符号?ASCEFunc@@YGXHH@Z,而在C编译器中会编译成符号_ASCEFunc@8。C++复杂的函数符号名是为了支持函数的重载功能。
Windows驱动程序的入口函数规定为_DriverEntry@8,因此用C++编译器时,会导致符号链接错误。解决办法是采用extern “C”修饰符:
#pragma INITCODE
extern "C" NTSTATUS DriverEntry(
IN PDRIVER_OBJECT pDriverObject,
IN PUNICODE_STRING pRegistryPath);
注意:编译是将源文件变成目标文件的过程,链接是将目标文件变成最终二进制映像的过程。
运行时函数调用:
在Windows驱动程序中,不能使用编译器运行时函数,甚至C语言中的malloc函数和C++语言中的默认的new操作符都不能使用(如果用new,必须重载它)。
编译器厂商一般在发布编译器的同时,会同时将其运行时函数一起发布给用户。运行时函数是一个程序运行时所比不可少的函数。它由编译器提供,针对不同的操作系统实现也有所不同,但接口基本上是标准的。例如malloc就是典型的运行时函数。VC编译器中大部分运行时函数是通过Win32 API实现的,而API是针对Ring3层的程序的,Windows驱动运行在Ring0层。内核模式下的程序是无法调用用户模式提供的API函数的。例如new操作符最终调用的是HeapAlloc函数。
Windows为用户提供了内核态的运行时函数,它可以替代应用程序的运行时函数。在内核态的运行时函数一般形如RtlXXXX。当然,也有一般运行时函数,如strcpy等,它们的实现不依赖于Win32 API,因此,可以直接用作Windows驱动的编写。如果必须在驱动中用到new操作符,必须重载new操作符,当然一定也得重载delete操作符啦!
注意:在驱动开发中,尽量完全使用DDK提供的运行时函数。
Windows内核 语言选择注意点的更多相关文章
- Windows内核 基本汇编指令
1)用VS2010新建Win32 Console Application,工程名为ACECore,工程建立完成后得到打开文件ACECore.cpp,代码如下: #include "stdaf ...
- Windows内核安全与驱动开发
这篇是计算机中Windows Mobile/Symbian类的优质预售推荐<Windows内核安全与驱动开发>. 编辑推荐 本书适合计算机安全软件从业人员.计算机相关专业院校学生以及有一定 ...
- 学习windows内核书籍推荐 ----------转自http://tieshow.iteye.com/blog/1565926
虽然,多年java,正在java,看样子还得继续java.(IT小城,还是整java随意点)应用程序 运行于操作系统之上, 晓操作系统,方更晓应用程序. 主看windows,因为可玩性高,闭源才 ...
- 《天书夜读:从汇编语言到windows内核编程》五 WDM驱动开发环境搭建
(原书)所有内核空间共享,DriverEntery是内核程序入口,在内核程序被加载时,这个函数被调用,加载入的进程为system进程,xp下它的pid是4.内核程序的编写有一定的规则: 不能调用win ...
- 【转载】LINUX 和 WINDOWS 内核的区别
LINUX 和 WINDOWS 内核的区别 [声明:欢迎转载,转载请注明出自CU ACCESSORY http://linux.chinaunix.net/bbs/thread-1153868-1-1 ...
- [转帖]Windows 内核说明
来源:https://zhidao.baidu.com/question/398191459.html 自己的理解. windows 的内核文件 是在 c:\windows\system32 目录下面 ...
- [1]windows 内核情景分析---说明
本文说明:这一系列文章(笔记)是在看雪里面下载word文档,现转帖出来,希望更多的人能看到并分享,感谢原作者的分享精神. 说明 本文结合<Windows内核情景分析>(毛德操著).< ...
- Windows内核编程时的习惯与注意事项
Windows内核分析索引目录:https://www.cnblogs.com/onetrainee/p/11675224.html 一.内核编程注意细节: 在头文件中使用的是 <ntddk.h ...
- 《Windows内核安全与驱动开发》 5.1&5.2 内核与应用方面的编程
<Windows内核安全与驱动开发>阅读笔记 -- 索引目录 <Windows内核安全与驱动开发> 5.1&5.2 内核与应用方面的编程 一.生成控制设备 如果一个驱 ...
随机推荐
- iOS10 UI教程层次结构的事件
iOS10 UI教程层次结构的事件 iOS10 UI教程层次结构的事件,层次结构中存在7个事件,对于这些事件的介绍如表1-3所示.通过这些事件,可以监听视图,当视图在层次结构上发生变化时可以被拦截,也 ...
- LightOJ1036 A Refining Company(DP)
题目大概说有一个n*m的格子地图,每个格子有铀或者镭矿.地图最北面的镭矿加工厂,最西面有铀矿加工厂,而要通过在格子里铺设由南向北(镭)或由东向西(铀)的轨道来送矿物到加工厂.一个格子只能铺设一种轨道, ...
- sparklyr包--实现R与Spark接口
1.sparklyr包简介 Rstudio公司发布的sparklyr包具有以下几个功能: 实现R与Spark的连接: sparklyr包提供了一个完整的dplyr后端,可筛选并聚合Spark数据集,接 ...
- OpenCV 第二课 认识图像的存储结构
OpenCV 第二课 认识图像的存储结构 Mat Mat 类包含两部分,矩阵头和矩阵体.矩阵头包含矩阵的大小,存储方式和矩阵体存储空间的指针.因此,Mat中矩阵头的大小是固定的,矩阵体大小是不定的. ...
- BZOJ4260 Codechef REBXOR 题解
题目大意: 有一个长度为n的序列,求1≤l1≤r1<l2≤r2≤n使得(⊕r1i=l1ai)+(⊕r2i=l2ai)最大,输出这个最大值. 思路: 用Trie求出前缀异或和以及后缀异或和,再求出 ...
- ACM: HDU 1869 六度分离-Dijkstra算法
HDU 1869六度分离 Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u Descri ...
- ACM: HDU 3790 最短路径问题-Dijkstra算法
HDU 3790 最短路径问题 Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u Des ...
- IP地址分类整理
什么是IP地址? IP地址就是计算机在网络中地址. IP地址有多少个? IP地址范围是:0.0.0.0~225.225.225.255,这只是人为了方便记录才转为十进制的,ip地址实际是一个32位地址 ...
- java开发_模仿百度文库_OpenOffice2PDF_注意事项
在模仿百度文库的操作过程中,有很多朋友反映出来的一些问题,是我想起了写这篇blog. 主要是让大家在做的过程中注意一些东西,否则达不到想要的效果. 第一步:我们先从 java开发_模仿百度文库_Ope ...
- xcode 忽然无法真机调试
手机升级了系统后一直没有再进行真机调试,今天要去面试把手机插上后忽然显示iPhone(unavailable),选中自己的设备后运行发现弹出警告could not find developer dis ...