其他语言

本类阅读TOP10

·基于Solaris 开发环境的整体构思
·使用AutoMake轻松生成Makefile
·BCB数据库图像保存技术
·GNU中的Makefile
·射频芯片nRF401天线设计的分析
·iframe 的自适应高度
·BCB之Socket通信
·软件企业如何实施CMM
·入门系列--OpenGL最简单的入门
·WIN95中日志钩子(JournalRecord Hook)的使用

分类导航
VC语言Delphi
VB语言ASP
PerlJava
Script数据库
其他语言游戏开发
文件格式网站制作
软件工程.NET开发
D语言中的内联汇编在x86平台上的实现

作者:未知 来源:月光软件站 加入时间:2005-5-13 月光软件站

D x86 内联汇编

Some Assembly RequiredD,作为一种系统程序设计语言,提供了内联汇编的功能。对于同一个处理器家族来说,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:
	    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		;
	

结构/联合/类 成员偏移量

假设指向聚集的指针位于一个寄存器中,如果要访问聚集的成员,应使用成员的限定名:
	struct Foo { int a,b,c; }
	int bar(Foo *f)
	{
	    asm
	    {	mov	EBX,f		;
		mov	EAX,Foo.b[EBX]	;
	    }
	}
	

特殊符号

$
代表下一条指令的开始地址。所以,
	jmp	$  ;
会跳转到 jmp 后的那条指令处。

__LOCAL_SIZE
它的值会被局部堆栈帧中的局部字节数替代。当使用 naked 并且手动制定堆栈结构时,这会很方便。

支持的操作码

aaaaadaamaasadc
addaddpdaddpsaddsdaddss
andandnpdandnpsandpdandps
arplboundbsfbsrbswap
btbtcbtrbtscall
cbwcdqclccldclflush
clicltscmccmovacmovae
cmovbcmovbecmovccmovecmovg
cmovgecmovlcmovlecmovnacmovnae
cmovnbcmovnbecmovnccmovnecmovng
cmovngecmovnlcmovnlecmovnocmovnp
cmovnscmovnzcmovocmovpcmovpe
cmovpocmovscmovzcmpcmppd
cmppscmpscmpsbcmpsdcmpss
cmpswcmpxch8bcmpxchgcomisdcomiss
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
jajaejbjbejc
jcxzjejecxzjgjge
jljlejmpjnajnae
jnbjnbejncjnejng
jngejnljnlejnojnp
jnsjnzjojpjpe
jpojsjzlahflar
ldmxcsrldslealeaveles
lfencelfslgdtlgslidt
lldtlmswlocklodslodsb
lodsdlodswlooploopeloopne
loopnzloopzlsllssltr
maskmovdqumaskmovqmaxpdmaxpsmaxsd
maxssmfenceminpdminpsminsd
minssmovmovapdmovapsmovd
movdq2qmovdqamovdqumovhlpsmovhpd
movhpsmovlhpsmovlpdmovlpsmovmskpd
movmskpsmovntdqmovntimovntpdmovntps
movntqmovqmovq2dqmovsmovsb
movsdmovssmovswmovsxmovupd
movupsmovzxmulmulpdmulps
mulsdmulssnegnopnot
ororpdorpsoutouts
outsboutsdoutswpackssdwpacksswb
packuswbpaddbpadddpaddqpaddsb
paddswpaddusbpadduswpaddwpand
pandnpavgbpavgwpcmpeqbpcmpeqd
pcmpeqwpcmpgtbpcmpgtdpcmpgtwpextrw
pinsrwpmaddwdpmaxswpmaxubpminsw
pminubpmovmskbpmulhuwpmulhwpmullw
pmuludqpoppopapopadpopf
popfdporprefetchntaprefetcht0prefetcht1
prefetcht2psadbwpshufdpshufhwpshuflw
pshufwpslldpslldqpsllqpsllw
psradpsrawpsrldpsrldqpsrlq
psrlwpsubbpsubdpsubqpsubsb
psubswpsubusbpsubuswpsubwpunpckhbw
punpckhdqpunpckhqdqpunpckhwdpunpcklbwpunpckldq
punpcklqdqpunpcklwdpushpushapushad
pushfpushfdpxorrclrcpps
rcpssrcrrdmsrrdpmcrdtsc
repreperepnerepnzrepz
retretfrolrorrsm
rsqrtpsrsqrtsssahfsalsar
sbbscasscasbscasdscasw
setasetaesetbsetbesetc
setesetgsetgesetlsetle
setnasetnaesetnbsetnbesetnc
setnesetngsetngesetnlsetnle
setnosetnpsetnssetnzseto
setpsetpesetposetssetz
sfencesgdtshlshldshr
shrdshufpdshufpssidtsldt
smswsqrtpdsqrtpssqrtsdsqrtss
stcstdstistmxcsrstos
stosbstosdstoswstrsub
subpdsubpssubsdsubsssysenter
sysexittestucomisducomissud2
unpckhpdunpckhpsunpcklpdunpcklpsverr
verwwaitwbinvdwrmsrxadd
xchgxlatxlatbxorxorpd
xorps

支持的 AMD 操作码

pavgusbpf2idpfaccpfaddpfcmpeq
pfcmpgepfcmpgtpfmaxpfminpfmul
pfnaccpfpnaccpfrcppfrcpit1pfrcpit2
pfrsqit1pfrsqrtpfsubpfsubrpi2fd
pmulhrwpswapd



相关文章

相关软件