内联汇编
News
2007-04-24
Category: 更新(update)
Posted by: 刘策(yayv)
新设栏目 D语言高级教程 , 并转贴一篇 深入分析D语言接口与COM接口的关系 精华文章
[更多]
2007-04-24
Category: 更新(update)
Posted by: 刘策(yayv)
新增2篇文章,均是对D语言数组进行探索的。一篇主要探索D语言数组长度修改时产生的影响, 另一篇主要探索D语言数组在多维的情况下如何初始化。
[更多]
[Home] [Search] [D] Last update May 14, 2003
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:操作数的语法基本遵从了 Intel CPU 文档的约定。具体来说,就是右边的操作数是源操作数,左边的操作数是目的操作数。同 Intel 存在不同之处主要是为了同 D 语言的记号识别器和简单解析的目标兼容。
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
操作类型
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 并且手动制定堆栈结构时,这会很方便。
支持的操作码
| 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 |
支持的 AMD 操作码
| pavgusb | pf2id | pfacc | pfadd | pfcmpeq |
| pfcmpge | pfcmpgt | pfmax | pfmin | pfmul |
| pfnacc | pfpnacc | pfrcp | pfrcpit1 | pfrcpit2 |
| pfrsqit1 | pfrsqrt | pfsub | pfsubr | pi2fd |
| pmulhrw | pswapd |
Copyright (c) 1999-2002 by Digital Mars, All Rights Reserved
