当前位置:首页 > 网络编程 > 软件语言 > DELPHI > Delphi的嵌入式汇编语言与Windows函数调用

Delphi的嵌入式汇编语言与Windows函数调用

点击次数:43 次 发布日期:2008-11-09 08:39:06 作者:源代码网
源代码网推荐
广告载入中
  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


源代码网推荐

源代码网供稿.
网友评论 (0)
会员中心
网络编程
本站推荐
网络编程之精华