初学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;