中国IT动力,最新最全的IT技术教程
最新100篇 | 推荐100篇 | 专题100篇 | 排行榜 | 搜索 | 在线API文档 | 网通镜像
首 页 | 程序开发 | 操作系统 | 软件应用 | 图形图象 | 网络应用 | 精文荟萃 | 教育认证 | 硬件维护 | 未整理篇 | 站长教程
ASP JS PHP工程 ASP.NET 网站建设 UML J2EESUN .NET VC VB VFP 网络维护 数据库 DB2 SQL2000 Oracle Mysql
服务器 Win2000 Office C DreamWeaver FireWorks Flash PhotoShop 上网宝典 CorelDraw 协议大全 网络安全 微软认证
硬件维护  CPU  主板  硬盘  内存  显卡  显示器  键盘鼠标  声卡音箱  打印机  机箱电源  BIOS  网卡  C#  Java  Delphi  vs.net2005
  当前位置:> 程序开发 > 编程语言 > Delphi > 综合文章
Delphi的嵌入式汇编语言与Windows函数调用
作者:未知 时间:2005-08-07 20:59 出处:编程爱好者网站 责编:chinaitpower
              摘要:Delphi的嵌入式汇编语言与Windows函数调用
  Delphi是一种基于Pascal的面向对象的可视化程序设计工具,功能强大,编译速度极快,
  性能非常卓越。但是在Delphi中,却不像C语言一样能方便地利用函数指针,对已知地址
  的函数进行调用。
  
    如在Windows环境中用C语言编程,经常碰到如下形式的函数调用:
  
   ...
  
   FARPROC lpGetversion;
  
   ...
  
   lpGetversion=GetProcAddress(hinst,"getVersion");
  
   (*lpGetversion)();
  
   ...
  
    而在Delphi中,对用GetProcAddress获得的32位函数地址,如果采用类似C语言的
  形式调用函数指针,便会在编译时碰到错误,根本无法通过。如:
  
   例1 直接地址调用,错误是91号;
  
   lpGetversion; { error 91 ″:=″ expected}
  
   例2 带空参数直接地址调用,错误是91号;
  
   lpGetversion(); { error 91 ″:=″ expected}
  
   例3 间接地址调用,错误是43号;
  
   lpGetversion^; { error 43 iiiegal assignment}例4 带空参数间接地址调用,错误是43号;
  
   (lpGetversion^)(); { error 43 iiiegal assignment}
  
    在Windows系统的编程实践中,如钩子(HOOK)函数的编写和某些未公开的函数的
  调用等,必须用函数指针来调用函数,那么该怎么调用呢?
  
    答案是必须采用嵌入式汇编语言来调用函数指针,因为在Delphi的Help中,明确指
  出:The only use for procedural pointer is to pass it to an assembly language routine or to use it in  
  a inline statement。所以,如果我们获得了DLL中的函数地址,想利用它来调用该函数,只
  需在程序中插入一小段很简单的汇编程序,就能调用了。举例如下:
  
    ...
  
    var {声明函数指针lpGetVersion}
  
    lpGetVersion :TFARPROC;
  
    ...
  
    lpGetVersion:=getProcAddress(GetModuleHandle(′kernel′),′getversion');
  
    if lpGetVersion=nil then exit; {获得模块kernel 中的函数getVersion的指针lpGetVersion}
  
    ....
  
    asm {用汇编形式调用函数getVersion}
  
    call lpGetVersion {不用;  用; 也可以}
  
    end;  
  
    ... 
  
     现举一个简单的例子,在按钮上单击一下,利用汇编语言调用getversion函数得到
  Windows和DOS 的版本号:
  
    unit Getveru;
  
    interface
  
    uses
  
    SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,
  
    Forms, Dialogs, StdCtrls;
  
    type
  
    TForm1 = class(TForm)
  
     Button1: TButton;
  
     Label1: TLabel;
  
     Label2: TLabel;
  
     Label3: TLabel;
  
     procedure Button1Click(Sender: TObject);
  
    private
  
     { Private declarations }
  
    public
  
     { Public declarations }
  
    end;
  
    var
  
    Form1: TForm1;
  
    implementation
  
    {R *.DFM}
  
    procedure TForm1.Button1Click(Sender: TObject);
  
    var
  
    lpGetVersion:TFARPROC;
  
    version:longint;
  
    versionLowWord:word;
  
    versionHighWord:word;
  
    begin
  
    lpGetVersion:=getprocAddress(GetModuleHandle  
  
    (′kernel′), ′getversion′);  
  
    {GETVERSION 函数在模块 KERNEL中}
  
    {lpGetVersion 存放GETVERSION 的地址}
  
    if lpgetVersion=nil then exit;
  
    label1.caption:=intTostr(selectorof(lpgetversion))
  
    +':' +intTostr(offsetof(lpgetversion));{取32位地址的高16位用selectorof}
  
    {取32位地址的低16位用offsetof }
  
    asm {嵌入式汇编语言标记}
  
    call lpgetversion
  
    mov versionLowWord,ax
  
    {ax寄存器放Windows版本号}
  
    mov versionHighWord,dx  
  
    {dx寄存器放DOS版本号}
  
    end;
  
  
  
    label2.caption:=′Windows Version ′+
  
    intTostr(lobyte(versionLowWord))
  
    +′.′+intTostr(hibyte(versionLowWord)); {取16位 2进制数 的低8位用lowbyte}  
  
    {取16位 2进制数 的高8位用hibyte}  
  
    label3.caption:=′MS-DOS Version ′+
  
     intTostr(hibyte(versionHighWord))
  
     +′.′+intTostr(lobyte(versionHighWord));
  
    end;
  
    end 

关闭本页
 
首页 | 投资与合作 | 服务条款 | 隐私政策 | 收藏本站 | 设为首页 | 新用户注册 | 免责声明 | 使用帮助
Copyright ©2005-2008 chinaitpower.com All rights reserved. www.chinaitpower.com 版权所有