D语言中的内联汇编在x86平台上的实现

类别:编程语言 点击:0 评论:0 推荐:
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: AsmLogOrExp AsmLogOrExp ? AsmExp : AsmExp AsmLogOrExp: AsmLogAndExp AsmLogAndExp || AsmLogAndExp AsmLogAndExp: AsmOrExp AsmOrExp && AsmOrExp AsmOrExp: AsmXorExp AsmXorExp | AsmXorExp AsmXorExp: AsmAndExp AsmAndExp ^ AsmAndExp AsmAndExp: AsmEqualExp AsmEqualExp & AsmEqualExp AsmEqualExp: AsmRelExp AsmRelExp == AsmRelExp AsmRelExp != AsmRelExp AsmRelExp: AsmShiftExp AsmShiftExp < AsmShiftExp AsmShiftExp <= AsmShiftExp AsmShiftExp > AsmShiftExp AsmShiftExp >= AsmShiftExp AsmShiftExp: AsmAddExp AsmAddExp << AsmAddExp AsmAddExp >> AsmAddExp AsmAddExp >>> AsmAddExp AsmAddExp: AsmMulExp AsmMulExp + AsmMulExp AsmMulExp - AsmMulExp AsmMulExp: AsmBrExp AsmBrExp * AsmBrExp AsmBrExp / AsmBrExp AsmBrExp % AsmBrExp AsmBrExp: AsmUnaExp AsmBrExp [ AsmExp ] AsmUnaExp: AsmTypePrefix AsmExp offset AsmExp seg AsmExp + AsmUnaExp - AsmUnaExp ! AsmUnaExp ~ AsmUnaExp AsmPrimaryExp AsmPrimaryExp IntegerConstant FloatConstant __LOCAL_SIZE $ Register DotIdentifier DotIdentifier Identifier Identifier . DotIdentifier 操作数的语法基本遵从了 Intel CPU 文档的约定。具体来说,就是右边的操作数是源操作数,左边的操作数是目的操作数。同 Intel 存在不同之处主要是为了同 D 语言的记号识别器和简单解析的目标兼容。 操作类型

Asm类型前缀: near ptr far ptr byte ptr short ptr int ptr word ptr dword ptr float ptr double ptr extended ptr

AsmTypePrefix: near ptr far ptr byte ptr short ptr int ptr word ptr dword ptr float ptr double ptr extended ptr 对于操作数大小模棱两可的情况,如同:

add [EAX],3 ; 可以使用 Asm类型前缀 消除歧义:

add byte ptr [EAX],3 ; add int ptr [EAX],7 ; 结构/联合/类 成员偏移量假设指向聚集的指针位于一个寄存器中,如果要访问聚集的成员,应使用成员的限定名:

struct Foo { int a,b,c; } int bar(Foo *f) { asm { mov EBX,f ; mov EAX,Foo.b[EBX] ; } } 特殊符号$ 代表下一条指令的开始地址。所以,

jmp $ ;会跳转到 jmp 后的那条指令处。

__LOCAL_SIZE 它的值会被局部堆栈帧中的局部字节数替代。当使用 naked 并且手动制定堆栈结构时,这会很方便。支持的操作码aaaaadaamaasadcaddaddpdaddpsaddsdaddssandandnpdandnpsandpdandpsarplboundbsfbsrbswapbtbtcbtrbtscallcbwcdqclccldclflushclicltscmccmovacmovaecmovbcmovbecmovccmovecmovgcmovgecmovlcmovlecmovnacmovnaecmovnbcmovnbecmovnccmovnecmovngcmovngecmovnlcmovnlecmovnocmovnpcmovnscmovnzcmovocmovpcmovpecmovpocmovscmovzcmpcmppdcmppscmpscmpsbcmpsdcmpsscmpswcmpxch8bcmpxchgcomisdcomisscpuidcvtdq2pdcvtdq2pscvtpd2dqcvtpd2picvtpd2pscvtpi2pdcvtpi2pscvtps2dqcvtps2pdcvtps2picvtsd2sicvtsd2sscvtsi2sdcvtsi2sscvtss2sdcvtss2sicvttpd2dqcvttpd2picvttps2dqcvttps2picvttsd2sicvttss2sicwdcwdedadaadasdbdddedecdfdidivdivpddivpsdivsddivssdldqdsdtdwemmsenterf2xm1fabsfaddfaddpfbldfbstpfchsfclexfcmovbfcmovbefcmovefcmovnbfcmovnbefcmovnefcmovnufcmovufcomfcomifcomipfcompfcomppfcosfdecstpfdisifdivfdivpfdivrfdivrpfeniffreefiaddficomficompfidivfidivrfildfimulfincstpfinitfistfistpfisubfisubrfldfld1fldcwfldenvfldl2efldl2tfldlg2fldln2fldpifldzfmulfmulpfnclexfndisifnenifninitfnopfnsavefnstcwfnstenvfnstswfpatanfpremfprem1fptanfrndintfrstorfsavefscalefsetpmfsinfsincosfsqrtfstfstcwfstenvfstpfstswfsubfsubpfsubrfsubrpftstfucomfucomifucomipfucompfucomppfwaitfxamfxchfxrstorfxsavefxtractfyl2xfyl2xp1hltidivimulinincinsinsbinsdinswintintoinvdinvlpgiretiretdjajaejbjbejcjcxzjejecxzjgjgejljlejmpjnajnaejnbjnbejncjnejngjngejnljnlejnojnpjnsjnzjojpjpejpojsjzlahflarldmxcsrldslealeaveleslfencelfslgdtlgslidtlldtlmswlocklodslodsblodsdlodswlooploopeloopneloopnzloopzlsllssltrmaskmovdqumaskmovqmaxpdmaxpsmaxsdmaxssmfenceminpdminpsminsdminssmovmovapdmovapsmovdmovdq2qmovdqamovdqumovhlpsmovhpdmovhpsmovlhpsmovlpdmovlpsmovmskpdmovmskpsmovntdqmovntimovntpdmovntpsmovntqmovqmovq2dqmovsmovsbmovsdmovssmovswmovsxmovupdmovupsmovzxmulmulpdmulpsmulsdmulssnegnopnotororpdorpsoutoutsoutsboutsdoutswpackssdwpacksswbpackuswbpaddbpadddpaddqpaddsbpaddswpaddusbpadduswpaddwpandpandnpavgbpavgwpcmpeqbpcmpeqdpcmpeqwpcmpgtbpcmpgtdpcmpgtwpextrwpinsrwpmaddwdpmaxswpmaxubpminswpminubpmovmskbpmulhuwpmulhwpmullwpmuludqpoppopapopadpopfpopfdporprefetchntaprefetcht0prefetcht1prefetcht2psadbwpshufdpshufhwpshuflwpshufwpslldpslldqpsllqpsllwpsradpsrawpsrldpsrldqpsrlqpsrlwpsubbpsubdpsubqpsubsbpsubswpsubusbpsubuswpsubwpunpckhbwpunpckhdqpunpckhqdqpunpckhwdpunpcklbwpunpckldqpunpcklqdqpunpcklwdpushpushapushadpushfpushfdpxorrclrcppsrcpssrcrrdmsrrdpmcrdtscrepreperepnerepnzrepzretretfrolrorrsmrsqrtpsrsqrtsssahfsalsarsbbscasscasbscasdscaswsetasetaesetbsetbesetcsetesetgsetgesetlsetlesetnasetnaesetnbsetnbesetncsetnesetngsetngesetnlsetnlesetnosetnpsetnssetnzsetosetpsetpesetposetssetzsfencesgdtshlshldshrshrdshufpdshufpssidtsldtsmswsqrtpdsqrtpssqrtsdsqrtssstcstdstistmxcsrstosstosbstosdstoswstrsubsubpdsubpssubsdsubsssysentersysexittestucomisducomissud2unpckhpdunpckhpsunpcklpdunpcklpsverrverwwaitwbinvdwrmsrxaddxchgxlatxlatbxorxorpdxorps支持的 AMD 操作码pavgusbpf2idpfaccpfaddpfcmpeqpfcmpgepfcmpgtpfmaxpfminpfmulpfnaccpfpnaccpfrcppfrcpit1pfrcpit2pfrsqit1pfrsqrtpfsubpfsubrpi2fdpmulhrwpswapd

本文地址:http://com.8s8s.com/it/it22968.htm