但是,不同的 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
*pc; { call L1 ; L1: ; pop EBX ; mov pc[EBP],EBX ; }
使循环代码对齐可以使得执行速度得到可观的提升。
{ db 5,6,0x83; ds 0x1234; di 0x1234; dl 0x1234; df 1.234; dd 1.234; de 1.234; db ; ds ; }
支持下面的寄存器。寄存器名都是大写的。
{ rep ; movsb ; }
{ 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 ;
Foo { a,b,c; } bar(Foo *f) { { mov EBX,f ; mov EAX,Foo.b[EBX] ; } }
jmp $ ;会跳转到 jmp 后的那条指令处。
aaa | aad | aam | aas | adc |
add | addpd | addps | addsd | addss |
and | andnpd | andnps | andpd | andps |
arpl | bound | bsf | bsr | bswap |
bt | btc | btr | bts | call |
cbw | cdq | clc | cld | clflush |
cli | clts | cmc | cmova | cmovae |
cmovb | cmovbe | cmovc | cmove | cmovg |
cmovge | cmovl | cmovle | cmovna | cmovnae |
cmovnb | cmovnbe | cmovnc | cmovne | cmovng |
cmovnge | cmovnl | cmovnle | cmovno | cmovnp |
cmovns | cmovnz | cmovo | cmovp | cmovpe |
cmovpo | cmovs | cmovz | cmp | cmppd |
cmpps | cmps | cmpsb | cmpsd | cmpss |
cmpsw | cmpxch8b | cmpxchg | comisd | comiss |
cpuid | cvtdq2pd | cvtdq2ps | cvtpd2dq | cvtpd2pi |
cvtpd2ps | cvtpi2pd | cvtpi2ps | cvtps2dq | cvtps2pd |
cvtps2pi | cvtsd2si | cvtsd2ss | cvtsi2sd | cvtsi2ss |
cvtss2sd | cvtss2si | cvttpd2dq | cvttpd2pi | cvttps2dq |
cvttps2pi | cvttsd2si | cvttss2si | cwd | cwde |
da | daa | das | db | dd |
de | dec | df | di | div |
divpd | divps | divsd | divss | dl |
dq | ds | dt | dw | emms |
enter | f2xm1 | fabs | fadd | faddp |
fbld | fbstp | fchs | fclex | fcmovb |
fcmovbe | fcmove | fcmovnb | fcmovnbe | fcmovne |
fcmovnu | fcmovu | fcom | fcomi | fcomip |
fcomp | fcompp | fcos | fdecstp | fdisi |
fdiv | fdivp | fdivr | fdivrp | feni |
ffree | fiadd | ficom | ficomp | fidiv |
fidivr | fild | fimul | fincstp | finit |
fist | fistp | fisub | fisubr | fld |
fld1 | fldcw | fldenv | fldl2e | fldl2t |
fldlg2 | fldln2 | fldpi | fldz | fmul |
fmulp | fnclex | fndisi | fneni | fninit |
fnop | fnsave | fnstcw | fnstenv | fnstsw |
fpatan | fprem | fprem1 | fptan | frndint |
frstor | fsave | fscale | fsetpm | fsin |
fsincos | fsqrt | fst | fstcw | fstenv |
fstp | fstsw | fsub | fsubp | fsubr |
fsubrp | ftst | fucom | fucomi | fucomip |
fucomp | fucompp | fwait | fxam | fxch |
fxrstor | fxsave | fxtract | fyl2x | fyl2xp1 |
hlt | idiv | imul | in | inc |
ins | insb | insd | insw | int |
into | invd | invlpg | iret | iretd |
ja | jae | jb | jbe | jc |
jcxz | je | jecxz | jg | jge |
jl | jle | jmp | jna | jnae |
jnb | jnbe | jnc | jne | jng |
jnge | jnl | jnle | jno | jnp |
jns | jnz | jo | jp | jpe |
jpo | js | jz | lahf | lar |
ldmxcsr | lds | lea | leave | les |
lfence | lfs | lgdt | lgs | lidt |
lldt | lmsw | lock | lods | lodsb |
lodsd | lodsw | loop | loope | loopne |
loopnz | loopz | lsl | lss | ltr |
maskmovdqu | maskmovq | maxpd | maxps | maxsd |
maxss | mfence | minpd | minps | minsd |
minss | mov | movapd | movaps | movd |
movdq2q | movdqa | movdqu | movhlps | movhpd |
movhps | movlhps | movlpd | movlps | movmskpd |
movmskps | movntdq | movnti | movntpd | movntps |
movntq | movq | movq2dq | movs | movsb |
movsd | movss | movsw | movsx | movupd |
movups | movzx | mul | mulpd | mulps |
mulsd | mulss | neg | nop | not |
or | orpd | orps | out | outs |
outsb | outsd | outsw | packssdw | packsswb |
packuswb | paddb | paddd | paddq | paddsb |
paddsw | paddusb | paddusw | paddw | pand |
pandn | pavgb | pavgw | pcmpeqb | pcmpeqd |
pcmpeqw | pcmpgtb | pcmpgtd | pcmpgtw | pextrw |
pinsrw | pmaddwd | pmaxsw | pmaxub | pminsw |
pminub | pmovmskb | pmulhuw | pmulhw | pmullw |
pmuludq | pop | popa | popad | popf |
popfd | por | prefetchnta | prefetcht0 | prefetcht1 |
prefetcht2 | psadbw | pshufd | pshufhw | pshuflw |
pshufw | pslld | pslldq | psllq | psllw |
psrad | psraw | psrld | psrldq | psrlq |
psrlw | psubb | psubd | psubq | psubsb |
psubsw | psubusb | psubusw | psubw | punpckhbw |
punpckhdq | punpckhqdq | punpckhwd | punpcklbw | punpckldq |
punpcklqdq | punpcklwd | push | pusha | pushad |
pushf | pushfd | pxor | rcl | rcpps |
rcpss | rcr | rdmsr | rdpmc | rdtsc |
rep | repe | repne | repnz | repz |
ret | retf | rol | ror | rsm |
rsqrtps | rsqrtss | sahf | sal | sar |
sbb | scas | scasb | scasd | scasw |
seta | setae | setb | setbe | setc |
sete | setg | setge | setl | setle |
setna | setnae | setnb | setnbe | setnc |
setne | setng | setnge | setnl | setnle |
setno | setnp | setns | setnz | seto |
setp | setpe | setpo | sets | setz |
sfence | sgdt | shl | shld | shr |
shrd | shufpd | shufps | sidt | sldt |
smsw | sqrtpd | sqrtps | sqrtsd | sqrtss |
stc | std | sti | stmxcsr | stos |
stosb | stosd | stosw | str | sub |
subpd | subps | subsd | subss | sysenter |
sysexit | test | ucomisd | ucomiss | ud2 |
unpckhpd | unpckhps | unpcklpd | unpcklps | verr |
verw | wait | wbinvd | wrmsr | xadd |
xchg | xlat | xlatb | xor | xorpd |
xorps |
pavgusb | pf2id | pfacc | pfadd | pfcmpeq |
pfcmpge | pfcmpgt | pfmax | pfmin | pfmul |
pfnacc | pfpnacc | pfrcp | pfrcpit1 | pfrcpit2 |
pfrsqit1 | pfrsqrt | pfsub | pfsubr | pi2fd |
pmulhrw | pswapd |