インラインアセンブラ

D言語はシステム・プログラミング言語であり、インライン・アセンブラを提供する。 アセンブラを提供している。 インライン・アセンブラは、同じCPUファミリーのD実装で標準化されている。 インライン・アセンブラは、同じCPUファミリーのD実装で標準化されている。 インライン・アセンブラは、Win32 Dコンパイラ用のインライン・アセンブラと構文互換性がある。 インライン・アセンブラと構文互換性がある。
しかし、異なるアーキテクチャー上のD実装は、メモリモデル、関数のコール/リターン規則、アセンブラを自由に変更することができる。 メモリモデル、関数の呼び出し/戻り値の規則、引数の受け渡し規則などを自由に変更することができる、 引数の受け渡し規則などを自由に変更することができる。
この文書では、x86 およびx86_64 のインライン・アセンブラの実装について説明する。 インライン・アセンブラの実装について説明する。コンパイラが提供するインライン・アセンブラ・プラットフォームのサポートは、 および で示される。 が提供するインライン・アセンブラのプラットフォーム・サポートは、それぞれD_InlineAsm_X86 と D_InlineAsm_X86_64 バージョン識別子で示される。
Asmステートメント
AsmStatement: asm FunctionAttributesopt { AsmInstructionListopt } AsmInstructionList: AsmInstruction ; AsmInstruction ; AsmInstructionList
アセンブラ命令は、asm ブロック内に配置されなければならない。 関数と同様に、asm ステートメントは、呼び出し元と互換性があるように、適切な関数属性でアノテーションされなければならない。 asm文の属性は明示的に定義されなければならない。
void func1() pure nothrow @safe @nogc { asm pure nothrow @trusted @nogc {} } void func2() @safe @nogc { asm @nogc // エラー: asm文は@systemであると仮定される - そうでない場合は'@trusted'でマークする {} }
asm命令
AsmInstruction: Identifier : AsmInstruction align IntegerExpression even naked db Operands ds Operands di Operands dl Operands df Operands dd Operands de Operands db StringLiteral ds StringLiteral di StringLiteral dl StringLiteral dw StringLiteral dq StringLiteral Opcode Opcode Operands Opcode: Identifier int in out Operands: Operand Operand , Operands
ラベル
アセンブラ命令には、他の文と同様にラベルを付けることができる。 これらはgoto文のターゲットになることができる。 例えば、次のようになる:
void *pc; asm { call L1 ; L1: ; pop EBX ; mov pc[EBP],EBX ; // pcは現在L1のコードを指している }
整列IntegerExpression
IntegerExpression: IntegerLiteral Identifier
アセンブラに NOP 命令を発行させ、次のアセンブラ命令を IntegerExpression 境界に揃える。 アセンブラに NOP 命令を発行させる。 IntegerExpressionは、コンパイル時に 2 のべき乗である整数に評価されなければならない。 でなければならない。
ループ本体の開始位置を揃えることは、実行速度に劇的な影響を与えることがある。 実行速度に劇的な影響を与えることがある。
でさえある。
アセンブラにNOP命令を発行させ、次のアセンブラ命令を偶数境界に揃える。 アセンブラが次のアセンブラ命令を偶数境界に揃えるようにする。
naked
コンパイラが関数のプロログとエピログを生成しないようにする。 シーケンスを生成しないようにする。これは、インライン アセンブラ・プログラマーの責任であり、通常、関数全体をアセンブラで記述する場合に使用される。 をアセンブラで記述する場合に使用される。
db, ds, di, dl, df, dd, de
これらの擬似オペランドは、生データをコードに直接挿入するためのものである。 コードに直接挿入するためのものである。 db はバイトである、 ds は16ビットワード di は32ビット・ワード用である、 dl は64ビットワードである、 df は32ビット浮動小数点数である、 dd は64ビット倍精度である、 そしてde は80ビット拡張リアルである。 それぞれ複数のオペランドを持つことができる。 オペランドが文字列リテラルの場合、あたかも長さ オペランドがあるのと同じで、長さは文字列の文字数である。 1つのオペランドにつき1文字が使用される。 例:
asm { db 5,6,0x83; // コードにバイト0x05、0x06、0x83を挿入する ds 0x1234; // バイト0x34、0x12を挿入する di 0x1234; // バイト0x34, 0x12, 0x00, 0x00を挿入する dl 0x1234; // バイト0x34, 0x12, 0x00, 0x00, 0x00, 0x00を挿入する df 1.234; // float 1.234を挿入する dd 1.234; // 1.234を挿入する de 1.234; // 1.234を挿入する db "abc"; // バイト0x61、0x62、0x63を挿入する ds "abc"; // バイト0x61、0x00、0x62、0x00、0x63、0x00を挿入する }
オペコード
サポートされているオペコードのリストは最後にある。
以下のレジスタがサポートされている。レジスタ名 は常に大文字である。
Register: 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 XMM0 XMM1 XMM2 XMM3 XMM4 XMM5 XMM6 XMM7
x86_64 はこれらのレジスタを追加する。
Register64: RAX RBX RCX RDX BPL RBP SPL RSP DIL RDI SIL RSI R8B R8W R8D R8 R9B R9W R9D R9 R10B R10W R10D R10 R11B R11W R11D R11 R12B R12W R12D R12 R13B R13W R13D R13 R14B R14W R14D R14 R15B R15W R15D R15 XMM8 XMM9 XMM10 XMM11 XMM12 XMM13 XMM14 XMM15 YMM0 YMM1 YMM2 YMM3 YMM4 YMM5 YMM6 YMM7 YMM8 YMM9 YMM10 YMM11 YMM12 YMM13 YMM14 YMM15
特別なケース
- lock rep, , , 、repe repne repnz repz
- これらのプレフィックス命令は、プレフィックス命令と同じ文には現れない。 これらのプレフィックス命令は、プレフィックス命令と同じステートメントには現れない。 例えば次のようになる:
- pause
- このオペコードはアセンブラではサポートされていない。
asm { rep ; nop ; }
を使う。 - floating point ops
- 命令形式の2オペランド形式を使用する;
fdiv ST(1); // wrong fmul ST; // wrong fdiv ST,ST(1); // right fmul ST,ST(0); // right
asm
{
rep ;
movsb ;
}
オペランド
Operand: AsmExp AsmExp: AsmLogOrExp AsmLogOrExp ? AsmExp : AsmExp AsmLogOrExp: AsmLogAndExp AsmLogOrExp || AsmLogAndExp AsmLogAndExp: AsmOrExp AsmLogAndExp && AsmOrExp AsmOrExp: AsmXorExp AsmOrExp | AsmXorExp AsmXorExp: AsmAndExp AsmXorExp ^ AsmAndExp AsmAndExp: AsmEqualExp AsmAndExp & AsmEqualExp AsmEqualExp: AsmRelExp AsmEqualExp == AsmRelExp AsmEqualExp != AsmRelExp AsmRelExp: AsmShiftExp AsmRelExp < AsmShiftExp AsmRelExp <= AsmShiftExp AsmRelExp > AsmShiftExp AsmRelExp >= AsmShiftExp AsmShiftExp: AsmAddExp AsmShiftExp << AsmAddExp AsmShiftExp >> AsmAddExp AsmShiftExp >>> AsmAddExp AsmAddExp: AsmMulExp AsmAddExp + AsmMulExp AsmAddExp - AsmMulExp AsmMulExp: AsmBrExp AsmMulExp * AsmBrExp AsmMulExp / AsmBrExp AsmMulExp % AsmBrExp AsmBrExp: AsmUnaExp AsmBrExp [ AsmExp ] AsmUnaExp: AsmTypePrefix AsmExp offsetof AsmExp seg AsmExp + AsmUnaExp - AsmUnaExp ! AsmUnaExp ~ AsmUnaExp AsmPrimaryExp AsmPrimaryExp: IntegerLiteral FloatLiteral __LOCAL_SIZE $ Register Register : AsmExp Register64 Register64 : AsmExp DotIdentifier this DotIdentifier: Identifier Identifier . DotIdentifier FundamentalType . Identifier
オペランドの構文は、多かれ少なかれ、インテルCPUのドキュメントに従ったものである。 の規則に従っている。 特に、2オペランド命令では、次のような慣例がある。 ソースは右オペランド、デスティネーションは左オペランドである。 オペランドである。 構文がインテルのものと異なるのは、D言語のトークナイザーと互換性を保つためである。 D言語のトークナイザーと互換性があり、構文解析を簡単にするためである。
seg は、シンボルが含まれるセグメント番号をロードすることを意味する。 をロードすることを意味する。これはフラット・モデル・コードには関係ない。 代わりに、関連するセグメント・レジスタからムーブを行う。
点線式はコンパイル時に評価され、定数を与えるか、上位の変数を示さなければならない。 定数を与えるか、ターゲット・レジスタまたは変数に適合する を示さなければならない。
オペランド型
AsmTypePrefix: near ptr far ptr word ptr dword ptr qword ptr FundamentalType ptr
のように、オペランド・サイズがあいまいな場合である:
add [EAX],3 ;のようにオペランドサイズが曖昧な場合は、AsmTypePrefixを使うことで曖昧さをなくすことができる:
add byte ptr [EAX],3 ; add int ptr [EAX],7 ;
far ptr はフラットモデル・コードには関係ない。
構造体/共用体/クラス・メンバー・オフセット
集合体のメンバにアクセスするには、集合体へのポインタがレジスタにある場合、修飾名 .offsetof へのポインタがレジスタにある場合、メンバの修飾名の"@property" プロパティを使用する。 プロパティを使用する:
struct Foo { int a,b,c; } int bar(Foo *f) { asm { mov EBX,f ; mov EAX,Foo.b.offsetof[EBX] ; } } void main() { Foo f = Foo(0, 2, 0); assert(bar(&f) == 2); }
あるいは、集約のスコープ内では、メンバー名だけが必要となる:
struct Foo // またはクラス { int a,b,c; int bar() { asm { mov EBX, this ; mov EAX, b[EBX] ; } } } void main() { Foo f = Foo(0, 2, 0); assert(f.bar() == 2); }
スタック変数
スタック変数("関数"のローカル変数で、スタック上に確保された変数)は、インデックス付けされた変数名でアクセスされる。 スタック上に確保されたローカル変数)には、EBPでインデックス付けされた変数名でアクセスする。 を介してアクセスされる:
int foo(int x) { asm { mov EAX,x[EBP] ; // パラメータxの値をEAXにロードする mov EAX,x ; // 同じことを行う } }
EBP]が省略された場合、ローカル変数とみなされる。 naked を使用した場合は、この限りではない。
特殊記号
- ドル;
- 次の命令の開始のプログラムカウンタを表す。つまり
jmp $ ;
はjmp命令の次の命令に分岐する。 dollar;は、jmp命令またはcall命令のターゲットとしてのみ使用できる。 命令のターゲットとしてのみ現れる。 - __LOCAL_SIZE
- これは、ローカルスタックフレームのローカルバイト数に置き換えられる。 スタックフレームのローカルバイト数に置き換えられる。naked 。 が呼び出され、カスタム・スタック・フレームがプログラムされている場合に最も便利である。
サポートされるオペコード
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 | cmpxchg | cmpxchg8b | cmpxchg16b | |
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 |
iretq | 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 |
syscall | sysenter | sysexit | sysret | test |
ucomisd | ucomiss | ud2 | unpckhpd | unpckhps |
unpcklpd | unpcklps | verr | verw | wait |
wbinvd | wrmsr | xadd | xchg | xlat |
xlatb | xor | xorpd | xorps |
ペンティアム4(プレスコット)対応オペコード
addsubpd | addsubps | fisttp | haddpd | haddps |
hsubpd | hsubps | lddqu | monitor | movddup |
movshdup | movsldup | mwait |
AMDがサポートするオペコード
pavgusb | pf2id | pfacc | pfadd | pfcmpeq |
pfcmpge | pfcmpgt | pfmax | pfmin | pfmul |
pfnacc | pfpnacc | pfrcp | pfrcpit1 | pfrcpit2 |
pfrsqit1 | pfrsqrt | pfsub | pfsubr | pi2fd |
pmulhrw | pswapd |
SIMD
SSE、SSE2、SSE3、SSSE3、SSE4.1、SSE4.2、AVXがサポートされている。
GCCの構文
GNU Dコンパイラは、インライン・アセンブラにGCCベースの代替構文を使う:
GccAsmStatement: asm FunctionAttributesopt { GccAsmInstructionList } GccAsmInstructionList: GccAsmInstruction ; GccAsmInstruction ; GccAsmInstructionList GccAsmInstruction: GccBasicAsmInstruction GccExtAsmInstruction GccGotoAsmInstruction GccBasicAsmInstruction: AssignExpression GccExtAsmInstruction: AssignExpression : GccAsmOperandsopt AssignExpression : GccAsmOperandsopt : GccAsmOperandsopt AssignExpression : GccAsmOperandsopt : GccAsmOperandsopt : GccAsmClobbersopt GccGotoAsmInstruction: AssignExpression : : GccAsmOperandsopt : GccAsmClobbersopt : GccAsmGotoLabelsopt GccAsmOperands: GccSymbolicNameopt StringLiteral ( AssignExpression ) GccSymbolicNameopt StringLiteral ( AssignExpression ) , GccAsmOperands GccSymbolicName: [ Identifier ] GccAsmClobbers: StringLiteral StringLiteral , GccAsmClobbers GccAsmGotoLabels: Identifier Identifier , GccAsmGotoLabels
DEEPL APIにより翻訳、ところどころ修正。
このページの最新版(英語)
このページの原文(英語)
翻訳時のdmdのバージョン: 2.108.0
ドキュメントのdmdのバージョン: 2.109.1
翻訳日付 :
HTML生成日時:
編集者: dokutoku