⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 unit1.pas

📁 一个简单Delphi 中使用汇编的演示程序
💻 PAS
字号:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Edit1: TEdit;
    Edit2: TEdit;
    Button1: TButton;
    Edit3: TEdit;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

{
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
CPU 提供了诸多寄存器, 但在 Delphi 的过程和函数中, 只有 EAX ECX EDX 三个寄存器可以自由使用;
如果改变了其他寄存器, 在过程和函数结束前要给恢复.

记得前面学习过 Delphi 的过程和函数默认的调用约定是 Register , 前三个参数通过寄存器传递, 其他参数存与栈.
它所指的三个寄存器就应该是 EAX ECX EDX 了.
看资料介绍应该是: EAX 先接受第一个参数再接受返回值, ECX EDX 接受后面两个参数.
但我不能进行完整的测试.

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

//计算 x 的 n 次方的函数
function Fun(x,n: Integer): Integer;
asm
  //mov eax, x           {因为 eax 会先获取第一个参数, 这句可以省略
  mov ecx, n             ecx 是个计数寄存器, 会记录循环的次数, 没循环一次 ecx 的值就会减1
  @Lable1: add eax, eax  内部标签必须使用 @ 前缀; 也可以使用 Delphi 的标签
  loop @Lable1           循环到标签执行
end;


}

procedure TForm1.Button1Click(Sender: TObject);

  function add(x,y: Integer): Integer;
  var
    count: Integer;
  begin
    asm
      MOV EAX,x      {把 x 值放入寄存器 EAX}
      MOV ECX,y      {把 y 值放入寄存器 ECX}
      ADD EAX,ECX    {把 EAX + ECX 的值放入 EAX}
      MOV count,EAX  {把 EAX 的值给变量 count}
    end;
    Result := count; {返回值}

  {asm 中每个语句换行即可分句, 无须 ; 在这里加上也没有问题}
  end;

begin
  edit3.Text := IntToStr(Add(StrToIntDef(Edit1.text,0),StrToIntDef(Edit2.text,0)));
end;

procedure TForm1.Button2Click(Sender: TObject);
function Fun(x,n: Integer): Integer;
asm
  //mov eax, x           {因为 eax 会先获取第一个参数, 这句可以省略}
  mov ecx, n             {ecx 是个计数寄存器, 会记录循环的次数, 没循环一次 ecx 的值就会减1}
  @Lable1: add eax, eax  {内部标签必须使用 @ 前缀; 也可以使用 Delphi 的标签}
  loop @Lable1           {循环到标签执行}
end;
begin

  Edit3.Text := iNTTOSTR(Fun(2,10));
end;

end.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -