初学Delphi嵌入汇编是万一老师写的一个学习Delphi+ASM的系列

// Delphi函数中,使用eax,edx,ecx分别表示前三个参数 // 32位返回值直接由eax返回

function add(x,y: Integer): Integer;
asm
ADD EAX,EDX
end;

记得前面学习过 Delphi 的过程和函数默认的调用约定是 Register , 前三个参数通过寄存器传递, 其他参数存与栈.
它所指的三个寄存器就应该是 EAX ECX EDX 了.

全局变量一样可以在内嵌汇编中使用, 把你的程序修改如下:

在汇编中访问 Delphi 的变量可以使用 & 操作符

在汇编中可以直接用十进制给寄存器赋值,也可以用$10的样子赋值,也可以使用预定义常量,例如:
 n = $10; mov ecx, n   

函数返回值与寄存器 :
  返回类型                      寄存位置
Char、Byte AL                    寄存器
SmallInt、Word AX                寄存器
Integer、LongWord、AnsiString、Pointer、Class EAX    寄存器
Real48 EAX                       寄存器中是栈内返回值的指针
Int64 EDX、EAX                   寄存器对
Single、Double、Extended、Comp   栈首寄存器 ST(0)
短字符串或变体类型               在@Result指向的临时位置中返回

常量可以在汇编语句中运算,但是变量不可以, 方法中的参数也都属于变量
const
  a = 11;
  b = 5;
asm
  mov eax, a-b  {正确}
end;

有符号整数的负数等于相同正数的反码 + 1;
----------------
//自定义记录用于测试
Type
  TMyRec = record
    i: Integer;
    c: Char;
  end;


//在汇编中使用记录的过程
procedure GetRec(Rec: TMyRec);
asm
  mov eax.TMyRec.i, 100 {eax 会接受第一个参数}
  mov eax.TMyRec.c, 'M'
end;

-----------------
//计算 x 的 n 次方的函数
function Fun(x,n: Integer): Integer;
asm
  //mov eax, x           {因为 eax 会先获取第一个参数, 这句可以省略}
  mov ecx, n             {ecx 是个计数寄存器, 会记录循环的次数, 每循环一次 ecx 的值就会减1}
  sub ecx, 1
  @Lable1: add eax, eax  {内部标签必须使用 @ 前缀; 也可以使用 Delphi 的标签}
  loop @Lable1           {循环到标签执行}
end;
-----------------
//准备一个在汇编中要调用的函数
function DelphiFun(x,y: Integer): Integer;
begin
  Result := x + y;
end;


//汇编函数
function AsmFun: Integer;
asm
  mov eax, 1      {eax 对应函数的第一个参数, 这里给第一个参数赋值为 1}
  mov edx, 2      {edx 对应函数的第二个参数, 这里给第二个参数赋值为 2}
  call DelphiFun  {call 是调用命令; 返回值在 eax}
end;
-----------------
//XCHG 指令: 交换寄存器的内容
var
  x,y: Integer;
begin
  x := 1; y := 9;

  asm
    mov eax, x
    mov ecx, y
    xchg eax, ecx {xchg 的参数必须至少一个是寄存器, 不能有 xchg x,y 类似的操作}
    mov x, eax
    mov y, ecx
  end;

  ShowMessage(Format('x=%d, y=%d',[x,y])); {x=9, y=1}
ens;
posted on 2009-07-13 17:46  on_road  阅读(1126)  评论(0编辑  收藏  举报