汇编
编辑词条
该词条缺少基本信息栏、词条分类,补充相关内容帮助词条更加完善!立刻编辑>>
汇编(拼音:huì biān)大多是指汇编语言(Assembly Language),汇编程序。把汇编语言翻译成机器语言的过程称为汇编。在汇编语言中,用助记符(Memoni)代替操作码,用地址符号(Symbol)或标号(Label)代替地址码。这样用符号代替机器语言的二进制码,就把机器语言变成了汇编语言。于是汇编语言亦称为符号语言。用汇编语言编写的程序,机器不能直接识别,要由一种程序将汇编语言翻译成机器语言,这种起翻译作用的程序叫汇编程序,汇编程序是系统软件中语言处理的系统软件。
目
录
1词语解释
2汇编简介
3编译环境
4相关现状
5常用命令
数据传送指令
逻辑指令
移位指令
串处理指令
控制转移指令
过程调用及返回指令
中断指令
处理机控制指令
十进制调整指令
6相关教材
《80x86汇编语言基础教程》
《汇编语言》
《新版汇编语言程序设计》
《汇编语言程序设计》
1 词语解释 编辑
huìbiān
1.动词,把资料或文章等编辑在一起
2.名词,编辑在一起的资料,文献
3.名词,一种计算机语言
2 汇编简介 编辑
汇编语言(AssemblyLanguage)是面向机器的程序设计语言。[1]
汇编语言比机器语言易于读写、易于调试和修改,同时也具有机器语言执行速度快,占内存空间少等优点,但在编写复杂程序时具有明显的局限性,汇编语言依赖于具体的机型,不能通用,也不能在不同机型之间移植。
常说汇编语言过时,是低级语言,并不是说汇编语言要被丢弃,相反,汇编语言仍然是程序员必须了解的语言,甚至在某些行业与领域,汇编是必不可少的,非它不可适用。只是,现在计算机最大的领域为IT软件,也是我们常说的Windows编程,在熟练的程序员手里,使用汇编语言编写的程序,运行效率和性能比用其它语言写的程序优秀数倍,但是代价是需要更长的时间来优化,如果对计算机原理及编程基础不扎实,实在是得不偿失,加上高级语言的优秀与跨平台,一个公司不可能让一个团队使用汇编语言来编写所有的东西,因为这要花上几倍甚至几十倍的时间,不如使用其它语言来完成,只要最终结果不比汇编语言编写的差太多,就能抢先一步完成,这是市场经济下的必然结果。
总之,汇编语言是程序员的必修语言。
目前国内较好的汇编网站是“AoGo汇编小站”。其站长aogo,就是一个在工业方面有所成就的工程师,有意者可多参考。
其次就是罗云彬的汇编站点:这个大概是国内建站时间最长的汇编站点,其编写的《Windows环境下32位汇编语言程序设计》一书。是站长十几年的经验的集合,不妨看看。
熟悉指令,可以尝试破解,加强兴趣,参考看雪学院,国内最好的破解组织,其中看雪与众高手打造的破解书《加密解密完全方案》非常有名。汇编语言是一种低级的程序语言可直接控制硬件。
3 编译环境 编辑
汇编的调试环境总的来说比较少,也很少有非常好的编译器。reallychenchi设计的轻松汇编是一款非常适合初学者的汇编编译器。轻松汇编是一个汇编语言集成开发环境,主要面向汇编语言初学者,也可以用它进行开发。除了普通的编辑功能以外,它还可以自动整理格式、高亮显示和编译、链接、调试汇编程序,非常方便实用。
轻松汇编的最大特点是可以格式整理,就像VC6.0一样,可以设置断点调试,省却了使用者的不少工作。它可以在Win98/2k/XP下运行,是一款很优秀的软件。
4 相关现状 编辑
随着现代软件系统越来越庞大复杂,大量经过了封装的高级语言如C/C++,Pascal/ObjectPascal也应运而生。这些新的语言使得程序员在开发过程中能够更简单,更有效率,使软件开发人员得以应付快速的软件开发的要求。而汇编语言由于其复杂性使得其适用领域逐步减小。但这并不意味着汇编已无用武之地。由于汇编更接近机器语言,能够直接对硬件进行操作,生成的程序与其他的语言相比具有更高的运行速度,占用更小的内存,因此在一些对于时效性要求很高的程序、许多大型程序的核心模块以及工业控制方面大量应用。
此外,虽然有众多编程语言可供选择,但汇编依然是各大学计算机科学类专业学生的必修课,以让学生深入了解计算机的运行原理。[2]
5 常用命令 编辑
数据传送指令
一通用数据传送指令
指令 英文全拼 翻译
MOV Move 传送
PUSH Pushontothestack 进栈
POP Popfromthestack 出栈
XCHG Exchange 交换
MOV指令为双操作数指令,两个操作数中不能全为内存操作数
格式:MOVDST,SRC
执行操作:dst=src
注:1.目的数可以是通用寄存器,存储单元和段寄存器(但不允许用CS段寄存器).
2.立即数不能直接送段寄存器
3.不允许在两个存储单元直接传送数据
4.不允许在两个段寄存器间直接传送信息
PUSH入栈指令及POP出栈指令:
堆栈操作是以“后进先出”的方式进行数据操作。
格式:PUSHSRC//Word
执行操作:(SP)<-(SP)-2
((SP)+1,(SP))<-(SRC)
注:1.入栈的操作数除不允许用立即数外,可以为通用寄存器,段寄存器(全部)和存储器。
2.入栈时高位字节先入栈,低位字节后入栈。
格式:POPDST//Word
执行操作:(DST)<-((SP+1),(SP))
(SP)<-(SP)+2
注:1.出栈操作数除不允许用立即数和CS段寄存器外,可以为通用寄存器,段寄存器和存储器。
2.执行POPSS指令后,堆栈区在存储区的位置要改变。
3.执行POPSP指令后,栈顶的位置要改变。
XCHG(eXCHanG)交换指令:
将两操作数值交换。
格式:XCHGOPR1,OPR2//Byte/Word
执行的操作:(OPR1)<-->(OPR2)
注:1.必须有一个操作数是在寄存器中
2.不能与段寄存器交换数据
存储器与存储器之间不能交换数据。
二累加器专用传送指令
指令 英文全拼 翻译
IN Input 输入
OUT Output 输出
XLAT Translate 换码
IN输入指令
长格式为:INAL,PORT(字节)
INAX,PORT(字)
执行的操作:(AL)<-(PORT)(字节)
(AX)<-(PORT+1,PORT)(字)
短格式为:INAL,DX(字节)
INAX,DX(字)
OUT输出指令
长格式为:OUTPORT,AL(字节)
OUTPORT,AX(字)
执行的操作:(PORT)<-(AL)(字节)
(PORT+1,PORT)<-(AX)(字)
短格式为:OUTDX,AL(字节)
OUTDX,AX(字)
执行的操作:((DX))<-(AL)(字节)
((DX)+1,(DX))<-AX(字)
XLAT(TRANSLATE)换码指令:
把一种代码转换为另一种代码。
格式:XLAT(OPR可选)//Byte
执行操作:(AL)<-((BX)+(AL))
注:指令执行时只使用预先已存入BX中的表格首地址,执行后,AL中内容则是所要转换的代码。
三有效地址送寄存器指令
指令 英文全拼 翻译
LEA Loadeffectiveaddress 有效地址送寄存器
LDS LoadDSwithPointer 指针送寄存器和DS
LES LoadESwithPointer 指针送寄存器和ES
LEA(LoadEffectiveAddress):
有效地址传送寄存器指令
格式:LEAREG,SRC//指令把源操作数SRC的有效地址送到指定的寄存器中。
执行操作:(REG)<-SRC
注:1.SRC只能是各种寻址方式的存储器操作数,REG只能是16位寄存器
2.MOVBX,OFFSETOPER_ONE等价于LEABX,OPER_ONE
3.MOVSP,[BX]//将BX间接寻址的相继的二个存储单元的内容送入SP中
4.LEASP,[BX]//将BX的内容作为存储器有效地址送入SP中
LDS(LoadDSwithpointer):
指针送寄存器和DS指令
格式:LDSREG,SRC//常指定SI寄存器。
执行的操作:(REG)<-(SRC)
(DS)<-(SRC+2)
注:把源操作数指定的4个相继字节送到由指令指定的寄存器及DS寄存器中。该指令常指定SI寄存器。
LES(LoadESwithpointer)指针送寄存器和ES指令
格式:LESREG,SRC//常指定DI寄存器
执行的操作:(REG)<-(SRC)
(ES)<-(SRC+2)//与LDS大致相同,不同之处是将ES代替DS而已。
注:把源操作数指定的4个相继字节送到由指令指定的寄存器及ES寄存器中。该指令常指定DI寄存器。
四标志寄存器传送指令
指令 英文全拼 翻译
LAHF LoadAHwithflags 标志送AH
SAHF storeAHintoflags AH送标志寄存器
PUSHF pushtheflags 标志进栈
POPF poptheflags 标志出栈
LAHF(LoadAHwithFlags)
标志位送AH指令
格式:LAHF......
执行操作:(AH)<-(PWS的低字节)
注:将PSW寄存器中的低8位的状态标志(条件码)送入AH的相应位,SF送D7位,ZF送D6位
SAHF(StoreAHintoFlags)
AH送标志寄存器指令
格式:SAHF
执行操作:(PWS的低字节)<-(AH)
注:将AH寄存器的相应位送到PSW寄存器的低8位的相应位,AH的D7位送SF,D6位送ZF。
PUSHF(PUSHtheFlags)
标志进栈指令
格式:PUSHF
执行操作:(SP)<-(SP)-2
SP=SP-1,(SP)=PSW的高8位,SP=SP-1,(SP)=PSW的低8位
注:将标志寄存器的值压入堆栈顶部,同时栈指针SP值减2
POPF(POPtheFlags)
标志出栈指令
格式:POPF
执行操作:(PWS)<-((SP)+1,(SP))
(SP)<-(SP+2)
PSW低8位=(SP),SP=SP+1,PSW高8位=(SP),SP=SP+1
注:与PUSHF相反,从堆栈的顶部弹出两个字节送到PSW寄存器中,同时堆栈指针值加2
算术指令
一加法指令
指令 英文全拼 翻译
ADD add 加法
ADC addwithcarry 带进位加法
INC increment 加1
ADD(ADD)加法指令
格式:ADDDST,SRC//Byte/Word
执行操作:(DST)<-(SRC)+(DST)
注:1.两个存储器操作数不能通过ADD指令直接相加,即DST和SRC必须有一个是通用寄存器操作数。
2.段寄存器不能作为SRC和DST.
3.影响标志位AuxiliaryCrrayFlag,CarryFlag,OverflowFlag,ParityFlag,SignFlag和ZeroFlag,如下所示:
CF根据最高有效位是否有进(借)位设置的:有进(借)位时CF=1,无进(借)位时CF=0.
OF根据操作数的符号及其变化来设置的:若两个操作数的符号相同,而结果的符号与之相反时OF=1,否则为0.
ZF根据结果来设置:不等于0时ZF=0,等于0时ZF=1
SF根据结果的最高位来设置:最高位为0,则SF=0.
AF根据相加时D3是否向D4进(借)位来设置:有进(借)位时AF=1,无进(借)位时AF=0
PF根据结果的1的个数时否为奇数来设置:1的个数为奇数时PF=0,为偶数时PF=1
ADC(ADdwithCarry)带进位加法指令
格式:ADCDST,SRC//Byte/Word
执行操作:(DST)<-(SRC)+(DST)+CF
注:与ADD不同之处是还要加上进位标志位的值。
INC(INCrement)加1指令
格式:INCOPR//Byte/Word
执行操作:(OPR)<-(OPR)+1
注:1.OPR可以是寄存器和存储器操作数,但不能是立即数和段寄存器
2.影响标志位OF,SF,ZF,PF和AF,不影响CF.
二减法指令
指令 英文全拼 翻译
SUB subtract 减法
SBB subtractwithborrow 带借位减法
DEC Decrement 减1
NEG Negate 求补
CMP Compare 比较
SUB(SUBtract)不带借位的减法指令
格式:SUBDST,SRC//Byte/Word
执行操作:(DST)<-(DST)-(SRC)
注:1.DST和SRC寻址方式及规定与ADD相同。
2.影响全部标志位。(判断标志位参见ADD)
SBB(SuBtractwithBorrow)带借位减法指令
格式:SBBDST,SRC//Byte/Word
执行操作:(DST)<-(DST)-(SRC)-CF
DEC(DECrement)减1指令
格式:DECOPR//Byte/Word
执行操作:(OPR)<-(OPR)-1//除CF标志位,其余标志位都受影响。
NEG(NEGate)求补指令
格式:NEGOPR
执行操作:(OPR)<--(OPR)//将操作数按位求反后末位加1.
CMP(CoMPare)比较指令
格式:CMPOPR1,OPR2
执行操作:(OPR1)-(OPR2)//与SUB指令一样执行运算,但不保存结果。
注:该指令与SUB指令一样执行减法操作,但不保存结果,只是根据结果设置条件标志。
比较情况 无符号数 有符号数
A=B ZF=1 ZF=1
A>B CF=0&&ZF=0 SF^OF=0&&ZF=0
A<B CF=1&&ZF=0 SF^OF=1&&ZF=0
A>=B CF=0||ZF=1 SF^OF=0||ZF=1
A<=B CF=1||ZF=1 SF^OF=1||ZF=1
三乘法指令
指令 英文全拼 翻译
MUL UnsignedMultiple 无符号数乘法
IMUL SignedMultiple 带符号数乘法
MUL(unsignedMULtiple)无符号数乘法指令
格式:MULSRC//Byte/Word.
执行操作:字操作:(AX)<-(AL)*(SRC)//字节运算时目的操作数用AL,乘积放在AX中
字节操作:(DX,AX)<-(AX)*(SRC)//字运算时目的操作数用AX,DX存放乘积的高位字,AX放乘积的低位字
注:1.目的数必须是累加器AX或AL,指令中不需写出
源操作数SRC可以是通用寄存器和各种寻址方式的存储器操作数,而绝对不允许是立即数或段寄存器。
IMUL(sIgnedMULtiple)有符号数乘法指令
格式:IMULSRC//与MUL指令相同,但必须是带符号数
四除法指令
指令 英文全拼 翻译
DIV Unsigneddivide 无符号数除法
IDIV Signeddivide 带符号数除法
CBW Convertbytetoword 字节转换为字
CWD Contertwordtodoubleword 字转换为双字
DIV(unsignedDIVide)无符号数除法指令
格式:DIVSRC//Byte/Word其中:SRC的规定同乘法指令MUL
执行操作:字节操作:(AL)<-(AX)/(SRC)的商
(AH)<-(AX)/(SRC)的余数
字操作:(AX)<-(DX,AX)/(SRC)的商
(DX)<-(DX,AX)/(SRC)的余数
注:存储器操作数必须指明数据类型:BYTEPTRsrc或WORDPTRsrc
IDIV(sIgnedDIVied)有符号数除法指令
格式:IDIVSRC
执行的操作:与DIV相同,但操作数必须是带符号数,商和余数也均为带符号数,且余数的符号与被除数的符号相同。
CBW(ConvertBytetoWord)字节转换为字指令
格式:CBW
执行操作:AL中的符号位(D7)扩展到8位AH中,若AL中的D7=0,则AH=00H,若AL中的D7=1,则AH=FFH.
CWD(ConvertWordtoDoubleword)字转换为双字指令
格式:CWD
执行操作:AX中的符号位(D15)扩展到16位DX中,若AX中的D15=0,则DX=0000H,若AX中的D15=1,则DX=FFFFH
注:这两条指令都不影响条件码。
逻辑指令
一逻辑运算指令
指令 英文全拼 翻译
AND and 逻辑与
OR or 逻辑或
NOT not 逻辑非
XOR exclusiveor 异或
TEST test 测试
AND,OR,XOR和TEST都是双字节操作指令,操作数的寻址方式的规定与算术运算指令相同。
NOT是单字节操作指令,不允许使用立即数。
逻辑运算均是按位进行操作,真值表如下:
AND(位与&) OR(位或|) XOR(位异或^)
1&1=1 1|1=1 1^1=0
1&0=0 1|0=1 1^0=1
0&1=0 0|1=1 0^1=1
0&0=0 0|0=0 0^0=0
AND(and)逻辑与指令
格式:ANDDST,SRC//Byte/Word
执行操作:(DST)<-(DST)^(SRC)
注:1.AND指令执行后,将使CF=0,OF=0,AF位无定义,指令执行结果影响SF,ZF和PF标志位。
2.AND指令典型用法A:用于屏蔽某些位,即使某些位为0.
例子:屏蔽AL的高4位:即将高4位和0000B相与,低4位和1111B相与
MOVAL,39H//AL=00111001B[39H]
ADDAL,0FH//AL=00001001B[09H]即00111001B[39H]&00001111B[0FH]=00001001B[09H]
AND指令典型用法B:取出某一位的值(见TEST)
OR(or)逻辑或指令
格式:ORDST,SRC//Byte/Word
执行操作:(DST)<-(DST)|(SRC)
注:1.OR指令执行后,将使CF=0,OF=0,AF位无定义,指令执行结果影响SF,ZF和PF标志位。
2.常用于将某些位置1.
例子:将AL的第5位置1:
MOVAL,4AH//AL=01001010B[4AH]
ORAL,10H//AL=01011010B[5AH]即01001010B[4AH]|00010000B[10H]=01011010B[5AH]
XOR(eXclusiveOR)逻辑异或指令
格式:XORDST,SRC//Byte/Word
执行操作:(DST)<-(DST)^(SRC)
注:1.XOR指令常用于使某个操作数清零,同时使CF=0,清除进位标志。
2.XOR指令使某些位维持不变则与'0'相异或,若要使某些位取反则与'1'相异或。
例子:将AL的高4位维持不变,低4位取反:
MOVAL,B8H//AL=10111000B[B8H]
XORAL,0FH//AL=10110111B[B7H]即10111000B[B8H]^00001111[0FH]=10110111B[B7H]
例子:测试某一个操作数是否与另一确定操作数相等:
XORAX,042EH
JZ....//如果AX==042EH,则ZF=TRUE(1),执行JZ...
NOT(not)逻辑非指令
格式:NOTOPR//Byte/Word
执行操作:(OPR)<~(OPR)//~01100101[65H]=10011010[9AH]
1.操作数不能使用立即数或段寄存器操作数,可使用通用寄存器和各种方式寻址的存储器操作数。
2.NOT指令不影响任何标志位。
例子:将AL各位取反:
MOVAL,65H//AL=01100101B[65H]
NOTAL//AL=10011010B[9AH]即~01100101B[65H]=10011010B[9AH]
TEST(test)指令
格式:TESTOPR1,OPR2//Byte/Word
执行操作:opr1&opr2
注:1.两个操作数相与的结果不保存,结果影响标志位PF,SF和ZF,使CF=0,OF=0,而AF位无定义。
2.TEST指令常用于在不改变原有的操作数的情况下,检测某一位或某几位的条件是否满足。只要令用来测试的操作数对应检测位为1,其余位为0,相与后判断零标志ZF值的真假。
例:检测某位是否为1:
令用来测试的操作数对应检测位为1,其余位为0,TEST指令后,若该位为1则JNZ...
TESTAL,000000001B//测试AL最低位是否为1::令用来测试的操作数对应检测位为1,其余位为0,执行TEST指令
JNZTHER//最低位若为1,则ZF=FALSE(0),执行JNZTHER,否则执行下一条指令。
或者:先对操作数求反,若该位为1则JZ...
MOVDL,AL//将AL传送到DL,主要是不要影响AL的值。以下测试AL的b2位是否为1
NOTDL//先对操作数求反
TEST00000100B//令用来测试的操作数对应检测位为1,其余位为0,执行TEST指令
JZTHER//若AL的b2位为1,则ZF=TRUE(1),执行JZTHER
B:移位指令[所有的移位指令都影响标志位CF、OF、PF、SF和ZF、AF无定义。]
非循环逻辑移位:把操作数看成无符数来进行移位。
移位指令
指令 英文全拼 翻译
SHL shiftlogicalleft 逻辑左移
SAL shiftarithmeticleft 算术左移
SHR shiftlogicalright 逻辑右移
SAR shiftarithmeticright 算术右移
ROL Rotateleft 循环左移
ROR Rotateright 循环右移
RCL Rotateleftthroughcarry 带进位循环左移
RCR Rotaterightthroughcarry 带进位循环右移
SHL(SHiftlogicalLeft)逻辑左移指令
格式:SHLOPR,CNT//Byte/Word
执行操作:使OPR左移CNT位,并使最低CNT位为全0.
1.OPR操作数不能使用立即数或段寄存器操作数,可使用通用寄存器和各种方式寻址的存储器操作数。
2.移位次数由CNT决定。每次将OPR的最高位移出并移到CF,最低位补0.
MOVCL,7//若移位多次,先预置移位次数CL
SHLDX,CL//CNT可取1或CL寄存器操作数
SHR(SHiftlogicalRight)逻辑右移指令
格式:SHROPR,CNT//Byte/Word
执行操作:同SHL,每次将OPR的最低位D0移出并移到CF.最高位补0.
非循环算术移位:将操作数看成有符号数来进行移位。
SAL(ShiftArithmeticLeft)算术左移指令
格式:SALOPR,CNT//Byte/Word
执行操作:SAL指令与SHL指令完全相同
SAR(ShiftArithmeticRight)算术右移指令
格式:SAROPR,CNT//Byte/Word
执行操作:SAR指令每次移位时,将最高位移入次高位的同时最高位值不变,最低位D0移出并移到CF.
循环移位指令
ROL(ROtateLeft)循环左移指令
格式:ROLOPR,CNT//Byte/Word
执行操作:每次移位时,最高位移出并同时移到CF和最低位D0.
ROR(ROtateRight)循环右移指令
格式:ROROPR,CNT//Byte/Word
执行操作:每次移位时,最低位D0移出并同时移到CF和最高位。
带进位循环移位指令
RCL(RotateLeftthroughCarry)带进位循环左移指令
格式:RCLOPR,CNT//Byte/Word
RCR(RotateRightthroughCarry)带进位循环右移指令
格式:RCROPR,CNT//Byte/Word
串处理指令
一与REP相配合工作的MOVS,STOS和LODS指令
指令 英文全拼 翻译
REP repeat 重复操作
MOVS MOVeString 串传送指令
STOS STOreintoString 存入串指令
LODS LOaDfromString 从串取指令
CLD Cleardirectionflag 使地址自动增量
STD Setdirectionflag 使地址自动减量
REP(REPeat)重复操作前缀
格式:REPStringPrimitive
执行的操作:
1)如(CX)=0则退出REP,否则往下执行。
2)(CX)<-(CX)-1
3)执行其中的串操作
4)重复1)~3)
注:其中StringPrimitive可为MOVS,LODS或STOS指令
.MOVS串传送指令
格式:MOVSES:BYTEPTR[DI],DS:[SI]
可有三种
MOVSDST,SRC
MOVSB//字节串传送DF=0,SI=SI+1,DI=DI+1;DF=1,SI=SI-1,DI=DI
MOVSW//字串传送DF=0,SI=SI+2,DI=DI+2;DF=1,SI=SI-2,DI=DI-2
MOVSD//双字串传送DF=0,SI=SI+4,DI=DI+4;DF=1,SI=SI-4,DI=DI-4
MOVSX//符号传送
MOVZX//零传送
执行的操作:
1)如(CX)=0则退出REP,否则往下执行。
2)(CX)<-(CX)-1
3)执行其中的串操作
4)重复1)~3)
.MOVS串传送指令
注:当方向标志DF=1时用,其中第二、三种格式明确地注明是传送字节或字,第一种格式则应在操作数中表明是字还是字节操作,例如:
1)((DI))<-((SI))
2)字节操作:(SI)<-(SI)+(或-)1,(DI)<-(DI)+(或-)1//当方向标志DF=0时用
3)字操作:(SI)<-(SI)+(或-)2,(DI)<-(DI)+(或-)2当方向标志DF=0时用//当方向标志DF=1时用-
该指令不影响条件码。
STOS(STOreintoString)存入串指令
格式:STOSDST
STOSB//存放字节串(DI)=AL
STOSW//存放字串(DI)=AX
执行操作:把AL或AX中的内容存放由DI指定的附加段的字节或字单元中,并根据DF值修改及数据类型修改DI的内容。
字节操作:((DT))←(AL),(DI)←(DI)±1
字操作:((DI))←(AX),(DI)←(DI)±2
注:1.在执行该指令之前,必须把要存入的数据预先存入AX或AL中,必须预置DI的初值。
2.DI所指向的存储单元只能在附加段中,即必须是ES:[DI]
3.该指令把AL或AX的内容存入由(DI)指定的附加段的某单元中,并根据DF的值及数据类型修改DI的内容,当它与REP联用时,可把AL或AX的内容存入一个长度为(CX)的缓冲区中。
LODS(LOaDfromString)从串取指令
格式:LODSSRC
LODSB//从字节串取AL=(SI)
LODSW//从字串取AX=(SI±1)(SI)
执行操作:字节操作:(AL)<-((SI)),(SI)<-(SI)+-1
字操作:(AX)<-((SI)),(SI)<-(SI)+-2
把由SI指定的数据段中字节或字单元的内容送入AL或AX中,并根据DF值及数据类型修改SI的内容。
注:1.在执行该指令之前,要取的数据必须在存储器中预先定义(用DB或DW),必须预置SI的初值。
2.源串允许使用段超越前缀来改变数据存储的段区。
3.该指令把由(SI)指定的数据段中某单元的内容送到AL或AX中,并根据方向标志及数据类型修改SI的内容。指令允许使用段跨越前缀来指定非数据段的存储区。该指令也不影响条件码。
4.一般说来,该指令不和REP联用。有时缓冲区中的一串字符需要逐次取出来测试时,可使用本指令。
CLD(CLearDirectionflag)清除方向标志指令
格式:CLD
执行操作:令DF=0,其后[SI],[DI]执行增量操作
该指令使DF=0,在执行串操作指令时可使地址自动增量
STD(SeTDirectionflag)设置方向标志指令
格式:STD
执行操作:令DF=1,其后[SI],[DI]执行减量操作
该指令使DF=1,在执行串操作指令时可使地址自动减量。
二与REPE/REPZ和REPNZ/REPNE联合工作的CMPS和SCAS指令
指令 英文全拼 翻译
REPE/REPZ RepeatEqualtoZero 等于零时重复操作
REPNE/REPNZ RepeatNotEqualtoZero 不等于零时重复操作
CMPS CoMPareString 串比较指令
SCAS SCAnString 串扫描指令
.REPE/REPZ当相等/为零时重复串操作
格式:REPE(或REPZ)StringPrimitive
其中StringPrimitive可为CMPS或SCAS指令。
执行的操作:
1)如(CX)=0或ZF=0(即某次比较的结果两个操作数不等)时退出,否则往下执行
2)(CX)<-(CX)-1
3)执行其后的串指令
4)重复1)~3)
.REPNE/REPNZ当不相等/不为零时重复串操作
格式:REPNE(或REPNZ)StringPrimitive
执行的操作:
除退出条件(CX=0)或ZF=1外,其他操作与REPE完全相同。
CMPS(CoMPareString)串比较指令
格式:CMPSSRC,DST
CMPSB//字节串比较(SI)-(DI)
CMPSW//字串比较(SI+1)(SI)-(DI+1)(DI)
执行操作:把由SI指向的数据段中的一个字节或字与由DI指向的附加段中的一个字节或字相减,不保留结果,只根据结果置标志位。
1)((SI))-((DI))
2)字节操作:(SI)<-(SI)+-1,(DI)<-(DI)+-1
字操作:(SI)<-(SI)+-2,(DI)<-(DI)+-2
注:指令把由(SI)指向的数据段中的一个字(或字节)与由(DI)指向的附加段中的一个字(或字节)相减,但不保存结果,只根据结果设置条件码,指令的其它特性和MOVS指令的规定相同。
.SCAS(SCAnString)串扫描指令
格式:SCASDST
SCASB
SCASW
执行操作:把AX或AL的内容与由DI指向的在附加段中的一个字节或字相减,不保留结果,根据结果置标志位。
字节操作:(AL)-((DI)),(DI)<-(DI)+-1
字操作:(AL)-((DI)),(DI)<-(DI)+-2
注:该指令把AL(或AX)的内容与由(DI)指定的在附加段中的一个字节(或字)进行比较,并不保存结果,只根据结果置条件码。指令的其他特性和MOVS的规定相同。
控制转移指令
一JMP(JuMP)无条件转移指令
名称 格式 执行操作
段内直接短跳转 JMPSHORTOPR IP=IP+8位偏移量
段内直接近转移 JMPNEARPTROPR IP=IP+16位偏移量
段内间接转移 JMPWORDPTROPR IP=(EA)
段间直接转移 JMPFARPTROPR IP=OPR偏移地址,CS=OPR段地址
段间间接转移 JMPDWORDPTROPR IP=(EA),CS=(EA+2)
1)段内直接短转移
格式:JMPSHORTOPR
执行的操作:(IP)<-(IP)+8位位移量
2)段内直接近转移
格式:JMPNEARPTROPR
执行的操作:(IP)<-(IP)+16位位移量
3)段内间接转移
格式:JMPWORDPTROPR
执行的操作:(IP)<-(EA)
4)段间直接(远)转移
格式:JMPFARPTROPR
执行的操作:(IP)<-OPR的段内偏移地址
(CS)<-OPR所在段的段地址
5)段间间接转移
格式:JMPDWORDPTROPR
执行的操作:(IP)<-(EA)
(CS)<-(EA+2)
1.无条件转移到指定的地址去执行从该地址开始的指令。
2.段内转移是指在同一代码段的范围内进行转移,只需改变IP寄存器内容。
3.段间转移则要转移到另一个代码段执行程序,此时要改变IP寄存器和CS段寄存器的内容。
二条件转移指令:
指令 英文全拼 翻译
JZ/JE Jumpifzero,orequal 结果为零(或相等)则转移
JNZ/JNE Jumpifnotzero,ornotequal 结果不为零(或不相等)则转移
JS Jumpifsign 结果为负则转移
JNS Jumpifnotsign 结果为正则转移
JO Jumpifoverflow 溢出则转移
JNO Jumpifnotoverflow 不溢出则转移
JP/JPE Jumpifparity,orparityeven 奇偶位为1则转移
JNP/JPO Jumpifnotparity,orparityodd 奇偶位为0则转移
JB/JNAE/JC Jumpifbelow,ornotaboveorequal,orcarry 低于,或者不高于或等于,或进位位为1则转移
JNB/JAE/JNC Jumpifnotbelow,oraboveorequal,ornotcarry 不低于,或者高于或者等于,或进位位为0则转移
根据上一条指令所设置的条件码(标志位)来判断测试条件。
JZ(或JE)(Jumpifzero,orequal)结果为零(或相等)则转移
格式:JE(或JZ)OPR
测试条件:ZF=1
.JNZ(或JNE)(Jumpifnotzero,ornotequal)结果不为零(或不相等)则转移
格式:JNZ(或JNE)OPR
测试条件:ZF=0
.JS(Jumpifsign)结果为负则转移
格式:JSOPR
测试条件:SF=1
.JNS(Jumpifnotsign)结果为正则转移
格式:JNSOPR
测试条件:SF=0
.JO(Jumpifoverflow)溢出则转移
格式:JOOPR
测试条件:OF=1
.JNO(Jumpifnotoverflow)不溢出则转移
格式:JNOOPR
测试条件:OF=0
.JP(或JPE)(Jumpifparity,orparityeven)奇偶位为1则转移
格式:JPOPR
测试条件:PF=1
.JNP(或JPO)(Jumpifnotparity,orparityodd)奇偶位为0则转移
格式:JNP(或JPO)OPR
测试条件:PF=0
.JB(或JNAE,JC)(Jumpifbelow,ornotaboveorequal,orcarry)低于,或者不高于或等于,或进位位为1则转移
格式:JB(或JNAE,JC)OPR
测试条件:CF=1
.JNB(或JAE,JNC)(Jumpifnotbelow,oraboveorequal,ornotcarry)不低于,或者高于或者等于,或进位位为0则转移
格式:JNB(或JAE,JNC)OPR
测试条件:CF=0
2)比较两个无符号数,并根据比较的结果转移
.JB(或JNAE,JC)
格式:同上
.JNB(或JAE,JNC)
格式:同上
.JBE(或JNA)(Jumpifbeloworequal,ornotabove)低于或等于,或不高于则转移
格式:JBE(或JNA)OPR
测试条件:CFVZF=1
.JNBE(或JA)(Jumpifnotbeloworequal,orabove)不低于或等于,或者高于则转移
格式:JNBE(或JA)OPR
测试条件:CFVZF=0
根据五个标志位:ZF、SF、OF、PF、CF的两种状态(0FALSE或1TRUE)产生10种测试条件。
名称 简写 格式 Flag==TRUE[3] Flag==FALSE
ZeroFalg ZF JE/JZOPR 结果为零转移JNE/JNZOPR 结果不为零转移
SignFalg SF JSOPR 结果为负转移JNSOPR 结果为正转移
OverflowFlag OF JOOPR 溢出转移JNOOPR 不溢出转移
ParityFlag PF JP/JPEOPR 结果为偶转移JNP/JPOOPR 结果为奇转移
CarryFlag CF JCOPR 有进位转移JNCOPR 无进位转移
情况 指令 满足条件 指令 满足条件
A<B JC CF==1 JL SF^OF==1&&ZF==0
A≥B JNC CF==0 JNL SF^OF==0||ZF==1
A≤B JNA CF==1||ZF==1 JLG SF^OF==1||ZF==1
A>B JA CF==0&&ZF==0 JG SF^OF==0&&ZF==0
三比较两个无符号数,并根据比较的结果转移
指令 英文全拼 翻译
JB/JNAE/JC Jumpifless,ornotgreaterorequal 小于,或者不大于或者等于则转移
JNB/JAE/JNC Jumpifnotless,orgreaterorequal 不小于,或者大于或者等于则转移
JBE/JNA Jumpifbeloworequal,ornotabove 低于或等于,或不高于则转移
JNBE/JA Jumpifnotbeloworequal,orabove 不低于或等于,或者高于则转移
.JB(或JNAE,JC)
格式:同上
.JNB(或JAE,JNC)
格式:同上
.JBE(或JNA)(Jumpifbeloworequal,ornotabove)低于或等于,或不高于则转移
格式:JBE(或JNA)OPR
测试条件:CFVZF=1
.JNBE(或JA)(Jumpifnotbeloworequal,orabove)不低于或等于,或者高于则转移
格式:JNBE(或JA)OPR
测试条件:CFVZF=0
四比较两个带符号数,并根据比较的结果转移
指令 英文全拼 翻译
JL/LNGE Jumpifless,ornotgreaterorequal 小于,或者不大于或者等于则转移
JNL/JGE Jumpifnotless,orgreaterorequal 不小于,或者大于或者等于则转移
JLE/JNG Jumpiflessorequal,ornotgreater 小于或等于,或者不大于则转移
JNLE/JG Jumpifnotlessorequal,orgreater 不小于或等于,或者大于则转移
.JL(或LNGE)(Jumpifless,ornotgreaterorequal)小于,或者不大于或者等于则转移
格式:JL(或JNGE)OPR
测试条件:SFVOF=1
.JNL(或JGE)(Jumpifnotless,orgreaterorequal)不小于,或者大于或者等于则转移
格式:JNL(或JGE)OPR
测试条件:SFVOF=0
.JLE(或JNG)(Jumpiflessorequal,ornotgreater)小于或等于,或者不大于则转移
格式:JLE(或JNG)OPR
测试条件:(SFVOF)VZF=1
.JNLE(或JG)(Jumpifnotlessorequal,orgreater)不小于或等于,或者大于则转移
格式:JNLE(或JG)OPR
测试条件:(SFVOF)VZF=0
五测试CX的值为0则转移指令
.JCXZ(JumpifCXregisteriszero)CX寄存器的内容为零则转移
格式:JCXZOPR//CX==0时转移
测试条件:(CX)=0
注:条件转移全为8位短跳!
六循环指令
LOOP(LOOP)循环指令
格式:LOOPOPR
测试条件:CX≠0//OPR在程序中实际是个标号
.LOOPNZ/LOOPNE当不为零或不相等时循环指令
格式:LOOPNZ(或LOOPNE)OPR
测试条件:(CX)<>0且ZF=0
注:这三条指令的步骤是:
1)(CX)<-(CX)-1
2)检查是否满足测试条件,如满足则(IP)<-(IP)+D8的符号扩充。
过程调用及返回指令
CALL(CALL)过程调用指令
格式:CALLDST//DST在程序中实际是子程序标号
执行操作:先将过程的返回地址(即CALL的下一条指令的首地址)存入堆栈,然后转移到过程入口地址执行子程序。
调用方式 格式 断点保护入栈情况 过程入口地址
段内直接 CALLNEARPTRPR1 (SP-1)(SP-2)←IP,CS不进栈CS值保持不变 IP←DST
段内间接 CALLWORDPTR(EA) (SP-1)(SP-2)←IP,CS不进栈CS值保持不变 IP←(EA)
段间直接 CALLFARPTRPR1 (SP-1)(SP-2)←CS,(SP-3)(SP-4)←IP IP←DST偏移地址CS←DST段地址
段间间接 CALLDWORDPTR(EA) (SP-1)(SP-2)←CS,(SP-3)(SP-4)←IP IP←(EA),CS←(EA+2)
注:为了表明是段内调用,可使用NEARPTR属性操作符作说明。
RET(RETurn)子程序返回指令
格式:RET
RETEXP//带立即数返回
注:子程序返回指令RET放在子程序末尾,它使子程序在执行完全部任务后返回主程序继续执行被打断后的程序。返回地址在子程序调用时入栈保存的断点地址-IP或IP和CS.
中断指令
.INT指令
格式:INTTYPE
或INT
执行的操作:(SP)<-(SP)-2
((SP)+1,(SP))<-(PSW)
(SP)<-(SP)-2
((SP)+1,(SP))<-(CS)
(SP)<-(SP)-2
((SP)+1,(SP))<-(IP)
(IP)<-(TYPE*4)
(CS)<-(TYPE*4+2)
.INTO若溢出则中断
执行的操作:若OF=1则:
(SP)<-(SP)-2
((SP)+1,(SP))<-(PSW)
(SP)<-(SP)-2
((SP)+1,(SP))<-(CS)
(SP)<-(SP)-2
((SP)+1,(SP))<-(IP)
(IP)<-(10H)
(CS)<-(12H)
.IRET从中断返回指令
格式:IRET
执行的操作:(IP)<-((SP)+1,(SP))
(SP)<-(SP)+2
(CS)<-((SP)+1,(SP))
(SP)<-(SP)+2
(PSW)<-((SP)+1,(SP))
(SP)<-(SP)+2
处理机控制指令
一标志处理指令
指令 英文全拼 翻译
CLC Clearcarry 进位位置0指令 CF<-0
CMC Complementcarry 进位位求反指令 CF<-CF
STC Setcarry 进位位置1指令 CF<-1
CLD Cleardirection 方向标志置0指令 DF<-0
STD Setdirection 方向标志置1指令 DF<-1
CLI Clearinterrupt 中断标志置0指令 IF<-0
STI Setinterrupt 中断标志置1指令 IF<-0
二其他处理机控制指令
指令 英文全拼 翻译
NOP NoOpreation 无操作
HLT Halt 停机
WAIT Wait 等待
ESC Escape 换码
LOCK Lock 封锁
处理器控制指令
CLC(CLearCarry)进位位置0指令
格式:CLC//执行操作后,CF=0
CMC(CoMplementCarry)进位位求反指令
格式:CMC//执行操作后,CF=!CF
STC(SeTCarry)进位位置1指令
格式:STC//执行操作后,CF=1
HLT(HaLT)停机指令
格式:HLT
执行操作:使机器暂停工作,使处理器CPU处于停机状态,以等待一次外部中断到来,中断结束后,程序继续执行,CPU继续工作。
注:该指令可使机器暂停工作,使处理机处于停机状态以便等待一次外部中断到来,中断结束后可继续执行下面的程序。
NOP(NoOperetion)无操作指令
格式:NOP//此指令不执行任何操作,其机器码占一个字节单元
该指令不执行任何操作,其机器码占有一个字节,在调试程序时往往用这条指令占有一定的存储单元,以便在正式运行时用其他指令取代。
.WAIT等待指令
该指令使处理机处于空转状态,它也可以用来等待外部中断的发生,但中断结束后仍返回WAIT指令继续执行。
.ESC换码指令
格式ESCmem
其中mem指出一个存储单元,ESC指令把该存储单元的内容送到数据总线去。当然ESC指令不允许使用立即数和寄存器寻址方式。这条指令在使用协处理机(Coprocessor)执行某些操作时,可从存储器指得指令或操作数。协处理机(如8087)则是为了提高速度而可以选配的硬件。
.LOCK封锁指令
该指令是一种前缀,它可与其他指令联合,用来维持总线的锁存信号直到与其联合的指令执行完为止。当CPU与其他处理机协同工作时,该指令可避免破坏有用信息。
十进制调整指令
当计算机进行计算时,必须先把十进制数转换为二进制数,再进行二进制数运算,最后将结果又转换为十进制数输出。
在计算机中,可用4位二进制数表示一位十进制数,这种代码称为BCD(BinaryCodedDecimal).
BCD码又称8421码,在PC机中,BCD码可用压缩的BCD码和非压缩的BCD码两种格式表示。
压缩的BCD码用4位二进制数表示一个十制数,整个十进数形式为一个顺序的以4位为一组的数串。
非压缩的BCD码以8位为一组表示一个十进制数,8位中的低4位表示8421的BCD码,而高4位则没有意义。
指令 英文全拼 翻译
DAA DecimalAdjustforAddition 加法的十进制调整指令
DAS DecimalAdjustforSubtraction 减法的十进制调整指令
AAA ASCIIAdjustforAddition 加法的ASCII调整指令
AAS ASCIIAdjustforSubtraction 减法的ASCII调整指令
DAA(DecimalAdjustforAddition)加法的十进制调整指令
格式:DAA
执行操作:执行之前必须先执行ADD或ADC指令,加法指令必须把两个压缩的BCD码相加,并把结果存话在AL寄存器中。
DAS(DecimalAdjustforSubtraction)减法的十进制调整指令
格式:DAS
执行操作:执行之前必须先执行SUB或SBB指令,减法指令必须把两个压缩的BCD码相减,并氢结果存放在AL寄存器中。
非压缩的BCD码调整指令
AAA(ASCIIAdjustforAddition)加法的ASCII调整指令
格式:AAA
执行操作:执行之前必须先执行ADD或ADC指令,加法指令必须把两个非压缩的BCD码相加,并把结果存话在AL寄存器中。
AAS(ASCIIAdjustforSubtraction)减法的ASCII调整指令
格式:AAS
执行操作:执行之前必须先执行SUB或SBB指令,减法指令必须把两个非压缩的BCD码相减,并氢结果存放在AL寄存器中。
执行操作:[DI]=[SI],将位于DS段的由SI所指出的存储单元的字节或字传送到位于ES段的由DI所指出的存储单元,再修改SI和DI,从而指向下一个元素。
在执行该指令之前,必须预置SI和DI的初值,用STD或CLD设置DF值。
格式:MOVSDST,SRC//同上,不常用,DST和SRC只是用来用类型检查,并不允许使用其它寻址方式来确定操作数。
1.目的串必须在附加段中,即必须是ES:[DI]
2.源串允许使用段跨越前缀来修饰,但偏移地址必须是[SI].
6 相关教材 编辑
《80x86汇编语言基础教程》
基本信息
教材名称:《80X86汇编语言基础教程》
ISBN编号:9787111253822
出版时间:2009-3-1
出版社:机械工业出版社
页数:213
版次印次:1
作者:(美)德特默(Detmer,R.C.)著,郑红,陈丽琼译
开本:16开
装帧:平装
印数:1
内容简介
学会一门具体的汇编语言对理解计算机体系结构是非常有益的,然而,许多关于计算机组成和体系结构的教材对这方面的知识介绍得不多。《80x86汇编语言基础教程(附光盘)》主要针对Intel80x86体系结构介绍汇编语言知识,因此既是计算机组成和体系结构课程的很好的补充教材,同时也适合作为单独的汇编语言课程教材。通过《80x86汇编语言基础教程(附光盘)》的学习,学生能够使用微软的MASM汇编器来编译32位的平面存储模式程序,并在微软的Windbg调试器控制下跟踪程序指令的执行,从中了解计算机内部存储器和寄存器内容的变化。《80x86汇编语言基础教程(附光盘)》附带的软件包为编写和调试控制台应用程序提供了很好的环境。
目录
出版者的话
前言
第1章计算机中数的表示
第2章软件工具和汇编语言语法
第3章基本指令
第4章分支与循环
第5章过程
第6章位运算
第7章浮点运算
附录A十六进制/ASC码转换
附录B有用的MS-DOS命令
附录CMASM6.11保留字
附录D80x86指令(按助记符排列)
附录E80x86指令(按操作码排列)
《汇编语言》
基本信息
教材名称:《汇编语言》(第2版)
ISBN编号:9787302172284
出版时间:2008-4-1
出版社:清华大学出版社
页数:337
版次印次:2
作者:王爽著
开本:16开
装帧:平装
印数:1
字数:527000
内容简介
汇编语言是各种CPU提供的机器指令的助记符的集合,人们可以用汇编语言直接控制硬件系统进行工作。汇编语言是很多相关课程(如数据结构、操作系统、微机原理等)的重要基础。为了更好地引导、帮助读者学习汇编语言,作者以循序渐进的思想精心创作了这本书。本书具有如下特点:采用了全新的结构对课程的内容进行组织,对知识进行最小化分割,为读者构造了循序渐进的学习线索;在深入本质的层面上对汇编语言进行讲解;对关键环节进行深入的剖析。
本书可用作大学计算机专业本科生的汇编教材及希望深入学习计算机科学的读者的自学教材。
目录
第1章基础知识
第2章寄存器
第3章寄存器(内存访问)
第4章第一个程序
第5章[BX]和loop指令
第6章包含多个段的程序
第7章更灵活的定位内存地址的方法
第8章数据处理的两个基本问题
第9章转移指令的原理
第10章CALL和RET指令
第11章标志寄存器
第12章内中断
第13章int指令
第14章端口
第15章外中断
第16章直接定址表
第17章使用BIOS进行键盘输入和磁盘读写
综合研究
附注
《新版汇编语言程序设计》
基本信息
教材名称:《新版汇编语言程序设计》
ISBN编号:9787121026966
出版时间:2007-01-01
出版社:电子工业出版社
作者:钱晓捷主编
装帧:平装
字数:563200
内容简介
本书以Intel80x86指令系统和MASM6.x为主体,全面而系统地介绍16/32位整数、浮点、多媒体指令的汇编语言程序设计方法。全书可分为基础和提高两部分。前5章作为基础部分,以当前“汇编语言程序设计”课程的教学为目标,为读者讲解16位基本整数指令及其汇编语言程序设计的知识。基础部分的主要内容是:汇编语言程序设计的基础知识,8086指令详解,MASM伪指令和操作符,程序格式,程序结构及其设计方法。后4章为提高部分,从不同的方面介绍汇编语言程序设计的深入内容和实际应用知识。提高部分各章的内容相对独立,主要有:32位80x86CPU的整数指令系统及其编程,汇编语言与C/C++的混合编程,80x87FPU的浮点指令系统及其编程,多媒体扩展指令系统及其编程,64位指令简介。本书可作为高等院校《汇编语言程序设计》课程的教材或参考书,主要读者为计算机及相关学科的本科和高职、高专学生。本书内容广博、语言浅显、结构清晰、实例丰富,也适合于电子、自动控制等专业的高校学生和成教学生,计算机应用开发人员,深入学习微机应用技术的普通读者等。
目录
第1章汇编语言基础知识
第2章8086的指令系统
第3章汇编语言程序格式
第4章基本汇编语言程序设计
第5章高级汇编语言程序设计
第6章32位指令及其编程
第7章汇编语言与C/C++的混合编程
第8章80x87浮点指令及其编程
第9章多媒体指令及其编程
第10章64位指令简介
附录A调试程序CodeView
附录B汇编程序MASM的伪指令和操作符
附录C80x86整数指令系统
附录D输入输出子程序库IO.LIB
参考文献
《汇编语言程序设计》
基本信息
产品名称:《汇编语言程序设计》
ISBN编号:9787111272601
出版时间:2009-10-1
出版社:机械工业出版社
页数:340
版次印次:1
作者:何超主编
开本:16开
装帧:平装
印数:1
字数:544000
内容简介
本书共8章,主要讨论汇编语言的编程基础、程序开发过程和调试方法。
本书的主要特点是通俗易懂,遵循由浅入深、由简到繁、循序渐进的原则。力争改变汇编语言难学难教的状况。与本书配套的《汇编语言程序设计实验与习题解答》一书另行出版,该书包含详尽的汇编语言程序设计实验和本书所有习题的解答。本书既可作为高等院校信息类(如计算机、自动控制、电工电子等)专业的本科教材,也可作为工程技术人员的参考书。
目录
出版说明
前言
第1章汇编语言的基本概念
第2章汇编语言程序中的指令与伪指令
第3章汇编语言程序设计初步
第4章子程序设计
第5章汇编语言程序的应用示例
第6章输入输出和中断处理
第7章宏和多模块程序设计
第8章汇编语言程序开发与调试
附录
参考文献
参考资料:
1.
汇编
liyanblog.cn/articles/2012/09/ ...
2.
汇编
liyanblog.cn/articles/2012/09/ ...
3.
汇编
liyanblog.cn/articles/2012/09/ ...