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,