delphi与汇编

 我一直认为Delphi功能与C++相比毫不逊色,提供了丰富的控件和类、全部API以及嵌入的汇编。最近小弟在把C版的Huffman压缩改用Delphi写时,顺便“研究”了一下Delphi的位操作和嵌入式汇编,利用嵌入汇编我们可以得到高效的程序代码,完成一些Delphi没有提供的底层功能。借贵报一方宝地与大家分享我的“研究”。
  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还有一招,接招吧……
  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窗口跟踪。
  OK!就谈到这,希望对使用Delphi的朋友有点帮助。
初学 Delphi 嵌入汇编[1] - 汇编语言机器语言 初学 Delphi 嵌入汇编[2] - 汇编语言关键字 初学 Delphi 嵌入汇编[3] - 第一个 Delphi 汇编的例子 初学 Delphi 嵌入汇编[4] - 寄存器在过程函数中的使用 初学 Delphi 嵌入汇编[5] - 寄存器在过程函数中的使用 - 续 初学 Delphi 嵌入汇编[6] - & 操作符 初学 Delphi 嵌入汇编[7] - 使用常量 初学 Delphi 嵌入汇编[8] - 8 位寄存器、16 位寄存器 32 位寄存器 初学 Delphi 嵌入汇编[9] - asm 可以代替 begin 初学 Delphi 嵌入汇编[10] - 函数返回值寄存器 初学 Delphi 嵌入汇编[11] - 用汇编重写一个 Delphi 函数 初学 Delphi 嵌入汇编[12] - 在汇编代码中可以直接使用 Result 初学 Delphi 嵌入汇编[13] - 地址参数用 [] 取值 初学 Delphi 嵌入汇编[14] - 常量变量在汇编中的一个区别 初学 Delphi 嵌入汇编[15] - 需要保护的寄存器 初学 Delphi 嵌入汇编[16] - 进制的表示方法 初学 Delphi 嵌入汇编[17] - 逻辑运算 初学 Delphi 嵌入汇编[18] - SHL SHR 初学 Delphi 嵌入汇编[19] - Delphi 的无符号整数类型 初学 Delphi 嵌入汇编[20] - DelphiInteger 类型 初学 Delphi 嵌入汇编[21] - Delphi 的其他整数类型 初学 Delphi 嵌入汇编[22] - 在汇编代码中使用记录 初学 Delphi 嵌入汇编[23] - LOOP 循环 初学 Delphi 嵌入汇编[24] - 汇编语言的简单数据类型 初学 Delphi 嵌入汇编[25] - 在汇编中调用函数 初学 Delphi 嵌入汇编[26] - 大小写字母转换 初学 Delphi 嵌入汇编[27] - XCHG 指令: 交换寄存器的内容 初学 Delphi 嵌入汇编[28] - 把 EAX 的值置为 0 的三种方法效率 初学 Delphi 嵌入汇编[29] - 寄存器所能接受的数值范围 初学 Delphi 嵌入汇编[30] - 寄存器表
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值