我一直认为Delphi功能与C++相比毫不逊色,提供了丰富的控件和类、全部API以及嵌入的汇编。最近小弟在把C版的Huffman压缩改用Delphi写时,顺便“研究”了一下Delphi的位操作和嵌入式汇编,利用嵌入汇编我们可以得到高效的程序代码,完成一些Delphi没有提供的底层功能。借贵报一方宝地与大家分享我的“研究”。

1.Delphi的位操作

  每个学习C的朋友都会被告之C是“中级语言”,其位操作非常方便,而Pascal之流只适用于教学。但是Delphi中提供了一组位操作,可别以过去对Pascal的态度看Delphi。

  • * 按位的逻辑操作:

Delphi中的AND、OR、NOT可不仅仅只对逻辑表达式有作用,它们还可以操作数;

AND:按位与,如:1 AND 2其结果为0

OR:按位或,如:1 OR 2其结果为3

Not:按位取反:如Not 1其结果对于有符号数是-2,对于无符号数是65534

另外,还有按位异或XOR:如:1 XOR 2结果为3

  • * 移位操作

Delphi提供了SHL和SHR进行移位左移和右移:

例如:2 SHR1表示2按位右移一位结果为1。

  • * Delphi中的数

既然有位的操作就一定涉及到数的类型:是有符号数(头一位用0和1表示正负)还是无符号数。

Delphi中:Shortint(8位)、Smallint(16位)、Longint(32位)、Integer(32位)、Int64(64位)是有符号数;而Byte(8位)、Word(16位)、Longword(32位)是无符号数。它们之间可以像C一样强制转换。例如:Smallint类型的-1转换成Word类型就是65535。转换方法是Word(-1)。

怎样,够全吧^_^!什么还不够……!?Delphi还有一招,接招吧……

 
2.   Delphi的嵌入式汇编

  Delphi中提供了几乎全部常用汇编指令的支持:MOV、JE、JMP、CMP、SHL、SHR、SAL、SAR、POP、PUSH、HLT……自己去查吧。至于INT也能识别,不过非法操作或死机可别找我(在最早的Windows95中用Delphi 3似乎可以正确运行中断,但Windows 95 OEM、Windows 98就不对了,大概是16位模块的问题,还搞不清楚)。

* 嵌入式汇编的格式

Delphi是使用ASM……END来标志汇编语句

如:ASM

mov al,1

mov bl,al

END;

* 可操作的寄存器

Delphi可用汇编管理以下寄存器:

32位寄存器    EAX EBX ECX EDX ESP EBP ESI EDI

16位寄存器     AX BX CX DX SP BP SI DI

8位寄存器      AL BL CL DL AH BH CH DH

16位段寄存器CS DS SS ES

以及协处理器寄存器堆栈 ST

* 使用汇编前的工作

教汇编的老师一再强调使用汇编要保存寄存器现场(保存使用前的寄存器状态,使用Push压栈和Pop从栈中弹出),不过这一切对于Delphi的嵌入式汇编是没有必要的(除非你自己要使用Push和Pop),因为Delphi已经帮你做了,不必担心会使数据丢掉。

* Delphi嵌入式汇编的使用方式

1.在一般函数过程中使用汇编

汇编程序段可以嵌套于其它过程中:如:

procedure TForm1.Button1Click(Sender: TObject);

var i:smallint;

begin

i:=1;

asm

mov ax,i

sal ax,1

mov &i,ax

end;

showmessage(inttostr(i));

end;

这个程序段是把16位的变量I进行左移,然后把结果用Mov &I,ax语句放入I变量所在地址返回值。最后显示I 的值是2。

2.独立的汇编程序段

汇编程序段也可以单独写成函数或过程。这就涉及到参数的传递与结果的返回

 
  首先Delphi对于函数的返回有一个约定:

即:整型数据:8位的用AL返回,16位的用AX返回,32位的用EAX返回;

         实型:用ST(0)返回

指针:用EAX返回

长字符串:用EAX返回其所在地址

变量:可用@Result返回

例如:一个用汇编的求和函数

function _Sum(X, Y: Integer): Integer;

asm

MOV EAX,X //把32位的数放入EAX

ADD EAX,Y //进行加法运算

MOV @Result,EAX //返回X+Y

end;

一个把字符转化为大写的函数例子

function _UpCase( ch : Char ) : Char;

asm

CMP AL,'a'

JB @@exit

CMP AL,'z'

JA @@exit

SUB AL,'a' -'A'

@@exit:

end;

值得注意的是第二个例子中,没有象第一个那样把参数用语句放到寄存器中,这是由于Delphi中默认的把Byte(Char)类型放在AL中,不需要用Mov语句,但是这种函数不能是类的成员,否则结果会出错。

3.在汇编中调用其它过程

汇编语句中的Call语句,可以用于调用其它过程,既可以是其它汇编程序段也可以是Delphi中的标准过程:

例如:假设新建一个窗体并在上面加了一个按钮,在Click事件中写入以下代码

procedure TForm1.Button1Click(Sender: TObject);

begin

showmessage(`ok');

end;

再写一个过程_X

function TForm1._x(var i:smallint):integer;

asm

call button1click

end;

执行_x的结果就可以显示消息框。

* 汇编的调试

编好了程序,没错,还好,如果有错,就得用到调试工具:如变量的跟踪、断点、堆栈查看……对于汇编还可以用View菜单的Debug Windows的CPU窗口跟踪。

 
 
 
附代码:
program Project1;

{$APPTYPE CONSOLE}

uses
SysUtils; var
a,b,c,d:Word;
BYTE1:Byte;
word1:Word;
int1:Integer; (*------------------------------------------------------------------------*) function add2value(x1:Integer;x2:Integer):Integer ; (*用汇编写的函数*)
asm
mov eax,x1;
add eax,x2;
mov @result,eax; (* 返回值为 @result *)
end; (*------------------------------------------------------------------------*) begin try
{ TODO -oUser -cConsole Main : Insert code here }
asm
mov a,'A';
mov b,'B';
mov c,'C';
mov d,'D'; end;
Writeln(chr(a) + chr(b) + chr(c) + chr(d)); BYTE1 := $FF;
Writeln(BYTE1 and $0F);
BYTE1 := $0F;
Writeln(BYTE1 or $F0); word1 := 1;
asm
mov ax,word1
sal ax,1 (*左移1位*)
mov &word1,ax
end; Writeln(' i = ' + IntToStr(word1)); int1 := add2value(12,32);
Writeln(int1); except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end; readln;
end.
http://www.cnblogs.com/dabiao/archive/2011/07/17/2108956.html

【Delphi内联汇编学习1】Delphi与汇编的更多相关文章

  1. GCC内联汇编入门

    原文为GCC-Inline-Assembly-HOWTO,在google上可以找到原文,欢迎指出翻译错误. 中文版说明 由于译者水平有限,故译文出错之处,还请见谅.C语言的关键字不译,一些单词或词组( ...

  2. html5--1.16 内联框架

    html5--1.16 内联框架 学习要点: 1.iframe内联框架2.综合实例1 1.iframe内联框架 1.iframe元素用来在文档中添加一个内联框架. 2.iframe为body元素的子元 ...

  3. HTML5: HTML5 内联 SVG

    ylbtech-HTML5: HTML5 内联 SVG 1.返回顶部 1. HTML5 内联 SVG HTML5 支持内联 SVG. 什么是SVG? SVG 指可伸缩矢量图形 (Scalable Ve ...

  4. HTML的内联框架(iframe)

    HTML的内联框架(iframe) 第一种:打开网页就是带内联框架的页面 可以实现在自己的网页内部,打开另一个网页 语法: <!--src:地址frameborder:0为无边框:1为有边框-- ...

  5. MIPS汇编学习

    MIPS汇编学习 mips汇编不同于x86汇编,属于精简指令集,常见于路由器等一些嵌入式设备中. mips汇编没有对堆栈的直接操作,也就是没有push和pop指令,mips汇编中保留了32个通用寄存器 ...

  6. solidity 学习笔记(7)内联汇编

    为什么要有内联汇编? //普通循环和内敛汇编循环比较 pragma solidity ^0.4.25; contract Assembly{ function nativeLoop() public ...

  7. GNU C 内联汇编介绍

    GNU C 内联汇编介绍 简介 1.很早之前就听说 C 语言能够直接内嵌汇编指令.但是之前始终没有去详细了解过.最近由于某种需求,看到了相关的 C 语言代码.也就自然去简单的学习了一下如何在 C 代码 ...

  8. 最牛X的GCC 内联汇编

    导读 正如大家知道的,在C语言中插入汇编语言,其是Linux中使用的基本汇编程序语法.本文将讲解 GCC 提供的内联汇编特性的用途和用法.对于阅读这篇文章,这里只有两个前提要求,很明显,就是 x86 ...

  9. Linux 中 x86 的内联汇编

    工程中需要用到内联汇编,找到一篇不错的文章,趁机学习下. 原文地址:http://www.ibm.com/developerworks/cn/linux/sdk/assemble/inline/ 如果 ...

随机推荐

  1. C++学习笔录3

    1.隐藏:存在于派生类和基类中.只要成员名字相同就叫做隐藏.参数和函数名都相同时,是一种特殊的隐藏,叫做重写,重写只出现在函数中.若需要访问基类中被隐藏的成员,必须访问这种方法:“对象名:类名::隐藏 ...

  2. perl正则表达式第一周笔记

    正则表达式基础 ^ 行首标志 $ 行末标志 如^cat即一整行只有cat这个单词,^则是一个空行 [  ] 字符组,用来匹配若干字符之一 如gr[ae]y,即grey或者gray - 在字符组内部,字 ...

  3. jQuery中的.live()与die()

    翻译原文地址:http://www.alfajango.com/blog/exploring-jquery-live-and-die/ 很多开发者都知道jQuery的.live()方法,他们大部分知道 ...

  4. Facebook React Native 配置小结

    2015 年 9 月 15 号,React Native for Android 发布.至此,React 基本完成了对多端的支持.基于 React / React Native 可以: H5, And ...

  5. Android IT资讯网络阅读器应用源码

    这个是Android IT资讯网络阅读器应用,也是一款通过jsoup解析Html获取内容的网络阅读器,和前面的其实是类似的,也是大学时期闲暇完成,对照CSDN的Web页面元素设计进行解析提取内容,核心 ...

  6. 软件测试学习日志———— round 2 Junit+intellj idea 安装及简单的测试使用

    今天是软件测试的上机,主要内容是对junit的安装以及对一个简单类的测试实践.老师推荐用eclipse,但是我原来一直在 用intellj Idea,所以我试了试intellj Idea对junit的 ...

  7. 源码学习之ASP.NET MVC Application Using Entity Framework

    源码学习的重要性,再一次让人信服. ASP.NET MVC Application Using Entity Framework Code First 做MVC已经有段时间了,但看了一些CodePle ...

  8. Orchard 源码探索(Log)

    简单工厂模式.抽象工厂模式和适配器模式 依赖倒置原则也叫依赖倒转原则,Dependence Inversion Principle,对抽象进行编程,不要对实现进行编程. A.高层次的模块不应该依赖于低 ...

  9. Oracle EBS-SQL (SYS-7):表单个性化查询.sql

    SELECT * FROM FND_FORM_CUSTOM_RULES; SELECT * FROM FND_FORM_CUSTOM_ACTIONS; SELECT * FROM FND_FORM_C ...

  10. Android程序的入口点

    原文:Android程序的入口点 android应用程序,由一到多个Activity组成.每个Activity没有很紧密的联系,因为我们可以在自己的程序中调用其它Activity,特别是调用自己的代码 ...