Movatterモバイル変換


[0]ホーム

URL:


D Logo
Menu
Search

Language Reference

table of contents

Report a bug
If you spot a problem with this page, click here to create a Bugzilla issue.
Improve this page
Quickly fork, edit online, and submit a pull request for this page.Requires a signed-in GitHub account. This works well for small changes.If you'd like to make larger changes you may want to consider usinga local clone.

Inline Assembler

Contents
  1. Asm statement
  2. Asm instruction
  3. Labels
  4. alignIntegerExpression
  5. even
  6. naked
  7. db, ds, di, dl, df, dd, de
  8. Opcodes
    1. Special Cases
  9. Operands
    1. Operand Types
    2. Struct/Union/Class Member Offsets
    3. Stack Variables
    4. Special Symbols
  10. Opcodes Supported
    1. Pentium 4 (Prescott) Opcodes Supported
    2. AMD Opcodes Supported
    3. SIMD
    4. Other
  11. GCC syntax
Some Assembly Required

D, being a systems programming language, provides an inline assembler. The inline assembler is standardized for D implementations across the same CPU family, for example, the Intel Pentium inline assembler for a Win32 D compiler will be syntax compatible with the inline assembler for Linux running on an Intel Pentium.

Implementations of D on different architectures, however, are free to innovate upon the memory model, function call/return conventions, argument passing conventions, etc.

This document describes thex86 andx86_64 implementations of the inline assembler. The inline assembler platform support that a compiler provides is indicated by theD_InlineAsm_X86 andD_InlineAsm_X86_64 version identifiers, respectively.

Asm statement

AsmStatement:asmFunctionAttributesopt{AsmInstructionListopt}
AsmInstructionList:AsmInstruction;AsmInstruction;AsmInstructionList

Assembler instructions must be located inside anasm block. Like functions,asm statements must be anotated with adequate function attributes to be compatible with the caller. Asm statements attributes must be explicitly defined, they are not inferred.

@safe is not allowed as an attribute, as the compiler does no safety checking of assembly statements - use@trusted instead.

void ok()purenothrow @safe @nogc{asmpurenothrow @trusted @nogc    {}}void error() @safe @nogc{asm @nogc// Error: asm statement is assumed to be @system - mark it with '@trusted' if it is not    {}asm @safe @nogc// Deprecation: asm statement cannot be @safe, use @trusted instead    {}}

Asm instruction

AsmInstruction:Identifier:AsmInstructionalignIntegerExpressionevennakeddbOperandsdsOperandsdiOperandsdlOperandsdfOperandsddOperandsdeOperandsdbStringLiteraldsStringLiteraldiStringLiteraldlStringLiteraldwStringLiteraldqStringLiteralOpcodeOpcodeOperands
Opcode:Identifierintinout
Operands:OperandOperand,Operands

Labels

Assembler instructions can be labeled just like other statements. They can be the target of goto statements. For example:

void *pc;asm{    call L1          ;  L1:                ;    pop  EBX         ;    mov  pc[EBP],EBX ;// pc now points to code at L1}

alignIntegerExpression

IntegerExpression:IntegerLiteralIdentifier

Causes the assembler to emit NOP instructions to align the next assembler instruction on anIntegerExpression boundary.IntegerExpression must evaluate at compile time to an integer that is a power of 2.

Aligning the start of a loop body can sometimes have a dramatic effect on the execution speed.

even

Causes the assembler to emit NOP instructions to align the next assembler instruction on an even boundary.

naked

Causes the compiler to not generate the function prolog and epilog sequences. This means such is the responsibility of inline assembly programmer, and is normally used when the entire function is to be written in assembler.

db, ds, di, dl, df, dd, de

These pseudo ops are for inserting raw data directly into the code.db is for bytes,ds is for 16 bit words,di is for 32 bit words,dl is for 64 bit words,df is for 32 bit floats,dd is for 64 bit doubles, andde is for 80 bit extended reals. Each can have multiple operands. If an operand is a string literal, it is as if there werelength operands, wherelength is the number of characters in the string. One character is used per operand. For example:

asm{    db 5,6,0x83;// insert bytes 0x05, 0x06, and 0x83 into code    ds 0x1234;// insert bytes 0x34, 0x12    di 0x1234;// insert bytes 0x34, 0x12, 0x00, 0x00    dl 0x1234;// insert bytes 0x34, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00    df 1.234;// insert float 1.234    dd 1.234;// insert double 1.234    de 1.234;// insert real 1.234    db"abc";// insert bytes 0x61, 0x62, and 0x63    ds"abc";// insert bytes 0x61, 0x00, 0x62, 0x00, 0x63, 0x00}

Opcodes

A list of supported opcodes is at the end.

The following registers are supported. Register names are always in upper case.

Register:ALAHAXEAX
BLBHBXEBX
CLCHCXECX
DLDHDXEDX
BPEBP
SPESP
DIEDI
SIESI
ESCSSSDSGSFS
CR0CR2CR3CR4
DR0DR1DR2DR3DR6DR7
TR3TR4TR5TR6TR7
ST
ST(0)ST(1)ST(2)ST(3)ST(4)ST(5)ST(6)ST(7)
MM0MM1MM2MM3MM4MM5MM6MM7
XMM0XMM1XMM2XMM3XMM4XMM5XMM6XMM7

x86_64 adds these additional registers.

Register64:RAXRBXRCXRDX
BPLRBP
SPLRSP
DILRDI
SILRSI
R8BR8WR8DR8
R9BR9WR9DR9
R10BR10WR10DR10
R11BR11WR11DR11
R12BR12WR12DR12
R13BR13WR13DR13
R14BR14WR14DR14
R15BR15WR15DR15
XMM8XMM9XMM10XMM11XMM12XMM13XMM14XMM15
YMM0YMM1YMM2YMM3YMM4YMM5YMM6YMM7
YMM8YMM9YMM10YMM11YMM12YMM13YMM14YMM15

Special Cases

lock,rep,repe,repne,repnz,repz
These prefix instructions do not appear in the same statement as the instructions they prefix; they appear in their own statement. For example:
asm{    rep   ;    movsb ;}
pause
This opcode is not supported by the assembler, instead use
asm{    rep  ;    nop  ;}
which produces the same result.
floating point ops
Use the two operand form of the instruction format;
fdiv ST(1);// wrongfmul ST;// wrongfdiv ST,ST(1);// rightfmul ST,ST(0);// right

Operands

Operand:AsmExp
AsmExp:AsmLogOrExpAsmLogOrExp?AsmExp:AsmExp
AsmLogOrExp:AsmLogAndExpAsmLogOrExp||AsmLogAndExp
AsmLogAndExp:AsmOrExpAsmLogAndExp&&AsmOrExp
AsmOrExp:AsmXorExpAsmOrExp|AsmXorExp
AsmXorExp:AsmAndExpAsmXorExp^AsmAndExp
AsmAndExp:AsmEqualExpAsmAndExp&AsmEqualExp
AsmEqualExp:AsmRelExpAsmEqualExp==AsmRelExpAsmEqualExp!=AsmRelExp
AsmRelExp:AsmShiftExpAsmRelExp<AsmShiftExpAsmRelExp<=AsmShiftExpAsmRelExp>AsmShiftExpAsmRelExp>=AsmShiftExp
AsmShiftExp:AsmAddExpAsmShiftExp<<AsmAddExpAsmShiftExp>>AsmAddExpAsmShiftExp>>>AsmAddExp
AsmAddExp:AsmMulExpAsmAddExp+AsmMulExpAsmAddExp-AsmMulExp
AsmMulExp:AsmBrExpAsmMulExp*AsmBrExpAsmMulExp/AsmBrExpAsmMulExp%AsmBrExp
AsmBrExp:AsmUnaExpAsmBrExp[AsmExp]
AsmUnaExp:AsmTypePrefixAsmExpoffsetofAsmExpsegAsmExp+AsmUnaExp-AsmUnaExp!AsmUnaExp~AsmUnaExpAsmPrimaryExp
AsmPrimaryExp:IntegerLiteralFloatLiteral__LOCAL_SIZE$RegisterRegister:AsmExpRegister64Register64:AsmExpDotIdentifierthis
DotIdentifier:IdentifierIdentifier.DotIdentifierFundamentalType.Identifier

The operand syntax more or less follows the Intel CPU documentation conventions. In particular, the convention is that for two operand instructions the source is the right operand and the destination is the left operand. The syntax differs from that of Intel's in order to be compatible with the D language tokenizer and to simplify parsing.

Theseg means load the segment number that the symbol is in. This is not relevant for flat model code. Instead, do a move from the relevant segment register.

A dotted expression is evaluated during the compilation and then must either give a constant or indicate a higher level variable that fits in the target register or variable.

Operand Types

AsmTypePrefix:near ptrfar ptrword ptrdword ptrqword ptrFundamentalTypeptr

In cases where the operand size is ambiguous, as in:

add [EAX],3     ;
it can be disambiguated by using anAsmTypePrefix:
addbyte ptr [EAX],3 ;addint ptr [EAX],7  ;

far ptr is not relevant for flat model code.

Struct/Union/Class Member Offsets

To access members of an aggregate, given a pointer to the aggregate is in a register, use the.offsetof property of the qualified name of the member:

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);}

Alternatively, inside the scope of an aggregate, only the member name is needed:

struct Foo// or class{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);}

Stack Variables

Stack variables (variables local to a function and allocated on the stack) are accessed via the name of the variable indexed by EBP:

int foo(int x){asm    {        mov EAX,x[EBP] ;// loads value of parameter x into EAX        mov EAX,x      ;// does the same thing    }}

If the [EBP] is omitted, it is assumed for local variables. Ifnaked is used, this no longer holds.

Special Symbols

$
Represents the program counter of the start of the next instruction. So,
jmp  $  ;
branches to the instruction following the jmp instruction. The $ can only appear as the target of a jmp or call instruction.
__LOCAL_SIZE
This gets replaced by the number of local bytes in the local stack frame. It is most handy when thenaked is invoked and a custom stack frame is programmed.

Opcodes Supported

Opcodes
aaaaadaamaasadc
addaddpdaddpsaddsdaddss
andandnpdandnpsandpdandps
arplboundbsfbsrbswap
btbtcbtrbtscall
cbwcdqclccldclflush
clicltscmccmovacmovae
cmovbcmovbecmovccmovecmovg
cmovgecmovlcmovlecmovnacmovnae
cmovnbcmovnbecmovnccmovnecmovng
cmovngecmovnlcmovnlecmovnocmovnp
cmovnscmovnzcmovocmovpcmovpe
cmovpocmovscmovzcmpcmppd
cmppscmpscmpsbcmpsdcmpss
cmpswcmpxchgcmpxchg8bcmpxchg16b
comisdcomiss
cpuidcvtdq2pdcvtdq2pscvtpd2dqcvtpd2pi
cvtpd2pscvtpi2pdcvtpi2pscvtps2dqcvtps2pd
cvtps2picvtsd2sicvtsd2sscvtsi2sdcvtsi2ss
cvtss2sdcvtss2sicvttpd2dqcvttpd2picvttps2dq
cvttps2picvttsd2sicvttss2sicwdcwde
dadaadasdbdd
dedecdfdidiv
divpddivpsdivsddivssdl
dqdsdtdwemms
enterf2xm1fabsfaddfaddp
fbldfbstpfchsfclexfcmovb
fcmovbefcmovefcmovnbfcmovnbefcmovne
fcmovnufcmovufcomfcomifcomip
fcompfcomppfcosfdecstpfdisi
fdivfdivpfdivrfdivrpfeni
ffreefiaddficomficompfidiv
fidivrfildfimulfincstpfinit
fistfistpfisubfisubrfld
fld1fldcwfldenvfldl2efldl2t
fldlg2fldln2fldpifldzfmul
fmulpfnclexfndisifnenifninit
fnopfnsavefnstcwfnstenvfnstsw
fpatanfpremfprem1fptanfrndint
frstorfsavefscalefsetpmfsin
fsincosfsqrtfstfstcwfstenv
fstpfstswfsubfsubpfsubr
fsubrpftstfucomfucomifucomip
fucompfucomppfwaitfxamfxch
fxrstorfxsavefxtractfyl2xfyl2xp1
hltidivimulininc
insinsbinsdinswint
intoinvdinvlpgiretiretd
iretqjajaejbjbe
jcjcxzjejecxzjg
jgejljlejmpjna
jnaejnbjnbejncjne
jngjngejnljnlejno
jnpjnsjnzjojp
jpejpojsjzlahf
larldmxcsrldslealeave
leslfencelfslgdtlgs
lidtlldtlmswlocklods
lodsblodsdlodswlooploope
loopneloopnzloopzlsllss
ltrmaskmovdqumaskmovqmaxpdmaxps
maxsdmaxssmfenceminpdminps
minsdminssmovmovapdmovaps
movdmovdq2qmovdqamovdqumovhlps
movhpdmovhpsmovlhpsmovlpdmovlps
movmskpdmovmskpsmovntdqmovntimovntpd
movntpsmovntqmovqmovq2dqmovs
movsbmovsdmovssmovswmovsx
movupdmovupsmovzxmulmulpd
mulpsmulsdmulssnegnop
notororpdorpsout
outsoutsboutsdoutswpackssdw
packsswbpackuswbpaddbpadddpaddq
paddsbpaddswpaddusbpadduswpaddw
pandpandnpavgbpavgwpcmpeqb
pcmpeqdpcmpeqwpcmpgtbpcmpgtdpcmpgtw
pextrwpinsrwpmaddwdpmaxswpmaxub
pminswpminubpmovmskbpmulhuwpmulhw
pmullwpmuludqpoppopapopad
popfpopfdporprefetchntaprefetcht0
prefetcht1prefetcht2psadbwpshufdpshufhw
pshuflwpshufwpslldpslldqpsllq
psllwpsradpsrawpsrldpsrldq
psrlqpsrlwpsubbpsubdpsubq
psubsbpsubswpsubusbpsubuswpsubw
punpckhbwpunpckhdqpunpckhqdqpunpckhwdpunpcklbw
punpckldqpunpcklqdqpunpcklwdpushpusha
pushadpushfpushfdpxorrcl
rcppsrcpssrcrrdmsrrdpmc
rdtscrepreperepnerepnz
repzretretfrolror
rsmrsqrtpsrsqrtsssahfsal
sarsbbscasscasbscasd
scaswsetasetaesetbsetbe
setcsetesetgsetgesetl
setlesetnasetnaesetnbsetnbe
setncsetnesetngsetngesetnl
setnlesetnosetnpsetnssetnz
setosetpsetpesetposets
setzsfencesgdtshlshld
shrshrdshufpdshufpssidt
sldtsmswsqrtpdsqrtpssqrtsd
sqrtssstcstdstistmxcsr
stosstosbstosdstoswstr
subsubpdsubpssubsdsubss
syscallsysentersysexitsysrettest
ucomisducomissud2unpckhpdunpckhps
unpcklpdunpcklpsverrverwwait
wbinvdwrmsrxaddxchgxlat
xlatbxorxorpdxorps

Pentium 4 (Prescott) Opcodes Supported

Pentium 4 Opcodes
addsubpdaddsubpsfisttphaddpdhaddps
hsubpdhsubpslddqumonitormovddup
movshdupmovsldupmwait

AMD Opcodes Supported

AMD Opcodes
pavgusbpf2idpfaccpfaddpfcmpeq
pfcmpgepfcmpgtpfmaxpfminpfmul
pfnaccpfpnaccpfrcppfrcpit1pfrcpit2
pfrsqit1pfrsqrtpfsubpfsubrpi2fd
pmulhrwpswapd

SIMD

SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2 and AVX are supported.

GCC syntax

TheGNU D Compiler uses an alternative, GCC-based syntax for inline assembler:

GccAsmStatement:asmFunctionAttributesopt{GccAsmInstructionList}
GccAsmInstructionList:GccAsmInstruction;GccAsmInstruction;GccAsmInstructionList
GccAsmInstruction:GccBasicAsmInstructionGccExtAsmInstructionGccGotoAsmInstruction
GccBasicAsmInstruction:GccAsmStringExpression
GccExtAsmInstruction:GccAsmStringExpression:GccAsmOperandsoptGccAsmStringExpression:GccAsmOperandsopt:GccAsmOperandsoptGccAsmStringExpression:GccAsmOperandsopt:GccAsmOperandsopt:GccAsmClobbersopt
GccGotoAsmInstruction:GccAsmStringExpression::GccAsmOperandsopt:GccAsmClobbersopt:GccAsmGotoLabelsopt
GccAsmStringExpression:StringLiteral(ConditionalExpression)
GccAsmOperands:GccSymbolicNameoptGccAsmStringExpression(AssignExpression)GccSymbolicNameoptGccAsmStringExpression(AssignExpression),GccAsmOperands
GccSymbolicName:[Identifier]
GccAsmClobbers:GccAsmStringExpressionGccAsmStringExpression,GccAsmClobbers
GccAsmGotoLabels:IdentifierIdentifier,GccAsmGotoLabels
Floating Point
Embedded Documentation
Copyright © 1999-2026 by theD Language Foundation | Page generated byDdoc on Sat Feb 21 07:05:57 2026

[8]ページ先頭

©2009-2026 Movatter.jp