yidabu 2007-4-26 16:09
26 D语言x86 内联汇编 D x86 Inline Assembler
26 D语言x86 内联汇编 D x86 Inline Assembler知识若不分享 实在没有意义 http://www.d-programming-language-china.org 20070425点击下面网址查看原文:http://www.d-programming-language-china.org by: uFramer D语言论坛 http://www.d-programming-language-china.org from: http://www.digitalmars.com/d/iasm.html version: 基于D 1.013 (Apr 19, 2007) D,作为一种系统程序设计语言,提供了内联汇编的功能。对于同一个处理器家族来说,D 的内联汇编的实现是标准化了的,例如,Intel Pentium 上的 Win32 D 编译器的内联汇编的语法同 Intel Pentium 上的 Linux D 编译器的语法是一样的。 但是,不同的 D 实现,可以依内存模型、函数调用/返回约定,参数传递约定等的不同而自由实现内联汇编。 本文描述了内联汇编的 x86 实现。 QUOTE: 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 Labels标号 汇编指令可以象其他语句一样带有标号。它们可以作为 goto 语句的目标。例如: [Copy to clipboard] [ - ]CODE: void *pc; asm { call L1 ; L1: ; pop EBX ; mov pc[EBP],EBX ; // pc 现在指向 L1 处的代码 } align IntegerExpressionalign 整数表达式 汇编器使用 NOP 指令进行填充,使下一条指令对齐到 整数表达式 边界上。整数表达式 的值必须是 2 的幂。 使循环代码对齐可以使得执行速度得到可观的提升。even 汇编器使用 NOP 指令进行填充,使下一条指令对齐到偶数边界上。nakednaked 禁止编译器生成函数的建帧和退帧指令。这就意味着责任落到了使用内联汇编的程序员的头上,因此这种用法主要用于那些全部用内联汇编编写的函数。( 本文出处: http://www.d-programming-language-china.org )db, ds, di, dl, df, dd, de 这些伪操作用于直接向代码中插入原始数据。db 用于字节,ds 用于 16 位字,di 用于 32 位字,dl 用于 64 位字,df 用于 32 位浮点型,dd 用于 64 位双精度型,de 用于 80 位扩展实数型。它们都可应用于多个操作数。如果有操作数为字符串文字量,汇编器就认为存在一个隐含的 length 操作数,length 表示字符串中有多少了字符。每个操作数会额外使用一个字符。例如: [Copy to clipboard] [ - ]CODE: 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. QUOTE: 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 1 Special Cases 1.1 lock, rep, repe, repne, repnz, repz 这些前缀指令不能同它们修饰的指令位于同一语句,它们必须单独写成一条指令。例如:( 本文出处: http://www.d-programming-language-china.org ) [Copy to clipboard] [ - ]CODE: asm { rep ; movsb ; } 1.2 pause 内联汇编不支持该操作码,使用( 本文出处: http://www.d-programming-language-china.org ) [Copy to clipboard] [ - ]CODE: { rep ; nop ; } 代替,效果是相同的。 1.3 floating point ops 浮点运算 使用指令的两操作数形式: [Copy to clipboard] [ - ]CODE: fdiv ST(1); // 错误 fmul ST; // 错误 fdiv ST,ST(1); // 正确 fmul ST,ST(0); // 正确 Operands操作 QUOTE: 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 语言的记号识别器和简单解析的目标兼容。 1 Operand Types操作类型 QUOTE: AsmTypePrefix: near ptr far ptr byte ptr short ptr int ptr word ptr dword ptr float ptr double ptr real ptr 对于操作数大小模棱两可的情况,如同: [Copy to clipboard] [ - ]CODE: add [EAX],3 ; 可以使用 Asm类型前缀 消除歧义:( 本文出处: http://www.d-programming-language-china.org ) [Copy to clipboard] [ - ]CODE: add byte ptr [EAX],3 ; add int ptr [EAX],7 ; 2 Struct/Union/Class Member Offsets结构/联合/类 成员偏移量 假设指向聚集的指针位于一个寄存器中,如果要访问聚集的成员,应使用成员的限定名: [Copy to clipboard] [ - ]CODE: struct Foo { int a,b,c; } int bar(Foo *f) { asm { mov EBX,f ; mov EAX,Foo.b[EBX] ; } } 3 Special Symbols特殊符号 1.1 $$ 代表下一条指令的开始地址。所以, [Copy to clipboard] [ - ]CODE: jmp $ ; 会跳转到 jmp 后的那条指令处。 1.2 __LOCAL_SIZE 它的值会被局部堆栈帧中的局部字节数替代。当使用 naked 并且手动制定堆栈结构时,这会很方便。Opcodes Supported支持的操作码 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 1 Pentium 4 (Prescott) Opcodes Supported addsubpd addsubps fisttp haddpd haddps hsubpd hsubps lddqu monitor movddup movshdup movsldup mwait 2 AMD Opcodes Supported pavgusb pf2id pfacc pfadd pfcmpeq pfcmpge pfcmpgt pfmax pfmin pfmul pfnacc pfpnacc pfrcp pfrcpit1 pfrcpit2 pfrsqit1 pfrsqrt pfsub pfsubr pi2fd pmulhrw pswapd ( lastupdate:20070426 最新文章请访问http://www.d-programming-language-china.org )关于一大步成功社区:yidabu提倡在交流中学习,在分享中提高收集感兴趣的知识,写下心得,通过网络与别人一起分享理解一点就实践一步,收获什么就分享什么,成功就是这样一点点一步步累积起来的网络只是一个工具,只有自己身心提高才是实实在在的。d-programming-language-china.org为大家提供一个学习交流各种知识的平台