D语言中的内联汇编在x86平台上的实现
D x86 内联汇编
D,作为一种系统程序设计语言,提供了内联汇编的功能。对于同一个处理器家族来说,D 的内联汇编的实现是标准化了的,例如,Intel Pentium 上的 Win32 D 编译器的内联汇编的语法同 Intel Pentium 上的 Linux D 编译器的语法是一样的。 但是,不同的 D 实现,可以依内存模型、函数调用/返回约定,参数传递约定等的不同而自由实现内联汇编。
本文描述了内联汇编的 x86 实现。
Asm指令: 标志符 : Asm指令 align 整数表达式 even naked db 多个操作数 ds 多个操作数 di 多个操作数 dl 多个操作数 df 多个操作数 dd 多个操作数 de 多个操作数 操作码 操作码 多个操作数 多个操作数 操作数 操作数 , 多个操作数
AsmInstruction: Identifier : AsmInstruction align IntegerExpression even naked db Operands ds Operands di Operands dl Operands df Operands dd Operands de Operands Opcode Opcode Operands Operands Operand Operand , Operands
标号
汇编指令可以向其他语句一样带有标号。它们可以作为 goto 语句的目标。例如: void *pc;
asm
{
call L1 ;
L1: ;
pop EBX ;
mov pc[EBP],EBX ; // pc 现在指向 L1 处的代码
}
align 整数表达式
汇编器使用 NOP 指令进行填充,使下一条指令对齐到 整数表达式 边界上。整数表达式 的值必须是 2 的幂。使循环代码对齐可以使得执行速度得到可观的提升。
even
汇编器使用 NOP 指令进行填充,使下一条指令对齐到偶数边界上。naked
禁止编译器生成函数的建帧和退帧指令。这就意味着责任落到了使用内联汇编的程序员的头上,因此这种用法主要用于那些全部用内联汇编编写的函数。db, ds, di, dl, df, dd, de
这些伪操作用于直接向代码中插入原始数据。db 用于字节,ds 用于 16 位字,di 用于 32 位字,dl 用于 64 位字,df 用于 32 位浮点型,dd 用于 64 位双精度型,de 用于 80 位扩展实数型。它们都可应用于多个操作数。如果有操作数为字符串文字量,汇编器就认为存在一个隐含的 length 操作数,length 表示字符串中有多少了字符。每个操作数会额外使用一个字符。例如: asm
{
db 5,6,0x83; // 插入 byte 0x05、0x06 和 0x83
ds 0x1234; // 插入 byte 0x34、0x12
di 0x1234; // 插入 byte 0x34、0x12、0x00、0x00
dl 0x1234; // 插入 byte 0x34、0x12、0x00、0x00、0x00、0x00、0x00、0x00
df 1.234; // 插入 float 1.234
dd 1.234; // 插入 double 1.234
de 1.234; // 插入 extended 1.234
db "abc"; // 插入 byte 0x61、0x62、and 0x63
ds "abc"; // 插入 byte 0x61、0x00、0x62、0x00、0x63、0x00
}
操作码
本文末尾列出了支持的操作码。支持下面的寄存器。寄存器名都是大写的。
- AL, AH, AX, EAX
- BL, BH, BX, EBX
- CL, CH, CX, ECX
- DL, DH, DX, EDX
- BP, EBP
- SP, ESP
- DI, EDI
- SI, ESI
- ES, CS, SS, DS, GS, FS
- CR0, CR2, CR3, CR4
- DR0, DR1, DR2, DR3, DR6, DR7
- TR3, TR4, TR5, TR6, TR7
- ST
- ST(0), ST(1), ST(2), ST(3), ST(4), ST(5), ST(6), ST(7)
- MM0, MM1, MM2, MM3, MM4, MM5, MM6, MM7
特殊情况
- lock, rep, repe, repne, repnz, repz
- 这些前缀指令不能同它们修饰的指令位于同一语句,它们必须单独写成一条指令。例如:
asm { rep ; movsb ; } - pause
- 内联汇编不支持该操作码,使用
{ rep ; nop ; }代替,效果是相同的。 - 浮点运算
- 使用指令的两操作数形式:
fdiv ST(1); // 错误 fmul ST; // 错误 fdiv ST,ST(1); // 正确 fmul ST,ST(0); // 正确
操作
操作数: Asm表达式 Asm表达式: Asm逻辑或表达式 Asm逻辑或表达式 ? Asm表达式 : Asm表达式 Asm逻辑或表达式: Asm逻辑与表达式 Asm逻辑与表达式 || Asm逻辑与表达式 Asm逻辑与表达式: Asm或表达式 Asm或表达式 && Asm或表达式 Asm或表达式: Asm异或表达式 Asm异或表达式 | Asm异或表达式 Asm异或表达式: Asm与表达式 Asm与表达式 ^ Asm与表达式 Asm与表达式: Asm相等表达式 Asm相等表达式 & Asm相等表达式 Asm相等表达式: Asm关系表达式 Asm关系表达式 == Asm关系表达式 Asm关系表达式 != Asm关系表达式 Asm关系表达式: Asm移位表达式 Asm移位表达式 < Asm移位表达式 Asm移位表达式 <= Asm移位表达式 Asm移位表达式 > Asm移位表达式 Asm移位表达式 >= Asm移位表达式 Asm移位表达式: Asm和表达式 Asm和表达式 << Asm和表达式 Asm和表达式 >> Asm和表达式 Asm和表达式 >>> Asm和表达式 Asm和表达式: Asm积表达式 Asm积表达式 + Asm积表达式 Asm积表达式 - Asm积表达式 Asm积表达式: Asm括号表达式 Asm括号表达式 * Asm括号表达式 Asm括号表达式 / Asm括号表达式 Asm括号表达式 % Asm括号表达式 Asm括号表达式: Asm一元表达式 Asm括号表达式 [ Asm表达式 ] Asm一元表达式: Asm类型前缀 Asm表达式 offset Asm表达式 seg Asm表达式 + Asm一元表达式 - Asm一元表达式 ! Asm一元表达式 ~ Asm一元表达式 Asm基本表达式 Asm基本表达式 整数常量 浮点数常量 __LOCAL_SIZE $ 寄存器 点标志符 点标志符 Identifier 标志符 . 点标志符
Operand: AsmExp AsmExp:

