《汇编语言实用教程下.ppt》由会员分享,可在线阅读,更多相关《汇编语言实用教程下.ppt(268页珍藏版)》请在三一办公上搜索。
1、第6章 8086/8088常用指令,6.1 数据传送类指令,6.2 算术运算类指令,6.3 位操作类指令,6.4 处理器控制类指令,6.1 数据传送类指令,6.1.1 通用数据传送指令通用数据传送指令(MOV)是使用得最频繁的指令,它的功能是把一个字节或一个字从源操作数传送至目的操作数,当MOV指令执行后,源操作数和目的操作数将具有相同的内容,源操作数保持不变,MOV指令对标志寄存器各位都没有影响,其格式如下:格式:MOV DEST,SRC,6.1.1 通用数据传送指令,1CPU内部寄存器之间的数据传送例如:MOVAH,AL;字节传送,(AL)AHMOVBX,CX;字传送,(CX)BXMOVB
2、P,SP;字传送,(SP)BPMOVAX,CS;字传送,(CS)AX,6.1.1 通用数据传送指令,2立即数送至通用寄存器或存储单元(各种存储器寻址方式)立即数传送到通用寄存器是指将立即数传送给AX、BX、CX、DX、BP、SP、SI、DI,以及AH、AL、BH、BL、CH、CL、DH、DL寄存器,但不能传送到段寄存器。例如:MOVAL,2MOVSI,-4MOVVARW,1234H;VARW是字变量MOVWORD PTRSI,3482HMOVDL,A;65DLMOV VARBX DI+3,20H;20H同VAR变量的类型一致,6.1.1 通用数据传送指令,3寄存器与存储器之间的数据传送寄存器与
3、存储器之间的数据传送是指除了CS和IP以外的所有寄存器与内存储器之间的数据传送。例如:MOVAL,VAR;(VAR)ALMOVBH,DI;存储器操作数为寄存器间接寻址MOV DI,DX;(DX)(DS)l0H+(DI)MOV BXDI,DL;(DL)(DS)10 H+(BX)+(DI)MOVVARB,BL;VARB是一个字节变量MOV SI,ES:BP;使用段超越前缀,(ES)l0H+(BP)SIMOV AX,10HBX+SI;(DS)10H+(BX)+(SI)+10H)AX,6.1.1 通用数据传送指令,【例6.1】判断如下指令是否正确。MOV1000H,3000HMOVDS,300MOVA
4、X,BLMOVES,DS这四条指令都是错误的,原因是违反了传送指令的规则。第1条指令:错在两个操作数不能同时为存储器操作数;第2条指令:错在立即数不能传送到段寄存器;第3条指令:错在类型不匹配;第4条指令:错在段寄存器不能直接传送段寄存器。,6.1.2 堆栈操作指令,在8086/8088系统中,堆栈是指在存储器中开辟的一个特殊存储区,称为“堆栈段”,如图6.2所示。,6.1.2 堆栈操作指令,1进栈指令PUSH 进栈指令PUSH用于把源操作数压入堆栈,源操作数只能是字,其格式如下:格式:PUSHSRC2出栈指令POP出栈指令POP用于从栈顶弹出一个字数据到目的操作数,SP随着出栈而增大,其格式
5、如下:格式:POPDEST,6.1.2 堆栈操作指令,【例6.2】假设AX=1234H,分别执行“PUSH AX”和“POP BX”指令操作过程是怎样的?堆栈操作指令PUSH和POP的操作示意图如图6.3所示。,6.1.3 数据交换指令,数据交换指令XCHG可以方便地实现通用寄存器与通用寄存器或存储单元之间的数据交换。其格式如下。格式:XCHGOPRD1,OPRD2【例6.3】假设DS=2000H,SI=2479H,AL=86H,DI=1716H,BX=4232H,(2247CH)=55H。问执行下列指令后的结果?XCHGSI+3,AL;存储器与寄存器之间交换数据XCHGDI,BX;寄存器之间
6、交换数据,6.1.4 查表转换指令,查表转换指令XLAT常用来实现单列表格的查表操作,指令有两个隐含操作数BX和AL。其格式如下所示。格式:XLAT或 XLAT OPRD,XLAT指令执行过程示意图,6.1.4 查表转换指令,【例6.4】利用XLAT指令编写查询小写字母的ASCII码一个小程序段。小程序段如下:DATASEGMENT;定义数据段TABLE DB abcdefghijklmnopqrstuvwxyz;定义表格变量(字节字符变量,8位)的首地址DATA ENDSMOV BX,OFFSET TABLEMOV AL,05HXLAT,6.1.5 地址传送指令,1LEA指令(Load Ef
7、fective Address)LEA指令称为有效地址传送指令,把源操作数的有效地址传送至目的操作数寄存器,其格式如下。格式:LEAREG,OPRD【例6.5】假定有DS=1000H,VAR=300H,(10300H)=3278H,其中符号地址VAR可以是变量或标号,执行以下两条指令的结果如何?LEA AX,VARMOV AX,VAR,6.1.5 地址传送指令,2LDS指令(Load pointer into DS)LDS指令是用于把源操作数中包含的32位地址指针段首址部分(高位字)送到数据段寄存器DS,把偏移地址(低位字)送到通用寄存器中。其格式如下:格式:LDSREG,OPRD3LES指令
8、(Load pointer into ES)LES指令用于把源操作数中包含的32位(4字节)地址指针的段首址部分(高位字)送到附加段寄存器ES,把偏移部分(低位字)送到通用寄存器中。其格式如下:格式:LESREG,OPRD,6.1.6 标志位传送指令,1LAHF指令(Load AH with Flags)LAHF指令将标志寄存器的状态标志位SF、ZF、AF、PF、CF传送至AH寄存器的对应位,AH寄存器的其余3位内容不变,LAHF采用固定的寻找方式,其格式如下。格式:LAHFLAHF指令本身不影响这些标志和其他标志,它把标志寄存器的低8位(包括符号标志SF、零标志ZF、奇偶标志PF和进位标志C
9、F)传送到寄存器AH的指定位,即相应地传送到寄存器AH的7、6、4、2和0位,其余3位内容不变,如图6.5所示。,6.1.6 标志位传送指令,2SAHF指令(Store AH into Flags)SAHF指令将AH的指定位(与状态标志对应的位)传送至标志寄存器,与LAHF指令传送方向相反。格式:SAHF该条指令把寄存器AH的指定位送至标志寄存器低8位的SF、ZF、AF、PF和CF标志位,因而这些标志的内容会受到影响。但这条指令不影响溢出标志OF、方向标志DF、中断允许标志IF和追踪标志TF,即不影响标志寄存器的高位字节。其操作示意如图6.6所示。,6.1.6 标志位传送指令,3PUSHF指令
10、PUSHF指令将标志寄存器的内容压入堆栈。先将堆栈指针减2,即(SP)-2SP,然后将整个标志寄存器(16位)的内容压入SP所指向的栈顶。格式:PUSHF4POPF指令POPF指令是将标志寄存器出栈。先将堆栈顶的内容,即((SP)+1,(SP))传送至标志寄存器(16位)中,然后将堆栈指针SP加2,即(SP)+2SP。格式:POPF,6.1.7 端口输入/输出指令,1端口输入指令IN当端口地址为0255范围内的数时,可以使用直接寻址,从指定的外设端口读数据到AL寄存器,其格式如下:格式:IN AL,PORT或 IN AX,PORT当端口地址可以在25665535时,必须使用间接寻址,间接寻址的
11、寄存器一定是DX,从8位端口读入一个字节到AL寄存器中,或从16位端口读入一个字到AX寄存器中。端口地址可以是一个字节,也可以是一个字。其格式如下。格式:MOVDX,PORT;先将端口地址送入DX中IN AL,DX;再将DX内容的低8位送入AL寄存器中或MOV DX,PORT;先将端口地址送入DX中IN AX,DX;再将DX内容送入AX寄存器中,6.1.7 端口输入/输出指令,2端口输出指令OUT当端口地址为0255范围内的数时,使用直接寻址,端口输出指令OUT是将AL或AX寄存器的内容传送到指定的外设端口。格式:OUTPORT,AL或OUTPORT,AX当端口地址为065535范围内的数时,
12、使用间接寻址,将AL中的一个字节写到一个8位端口,或把AX中的一个字写到一个16位端口。端口输出指令OUT是以DX的内容作为端口地址,寄存器一定是DX,将AL或AX寄存器的内容传送到该端口。格式:MOVDX,AL;先将AL内容送入DX中 OUT DX,PORT;再将DX内容的低8位送入端口地址中或 MOV DX,AX;先将AX内容送入DX中 OUT DX,PORT;再将DX内容送入端口地址中,6.1.7 端口输入/输出指令,【例6.6】将数据88H送到3CCH端口中。指令如下:MOVDX,3CCHMOVAL,88HOUTDX,AL,6.2 算术运算类指令,6.2.1 加法指令1不带进位的加法指
13、令ADD不带进位的加法指令ADD是将目的操作数与源操作数相加,结果存入目的操作数所在的寄存器或存储单元中,源操作数内容不变,并会影响OF、SF、ZF和AF、PF、CF标志位。其格式如下。格式:ADDDEST,SRC【例6.7】ADD指令示例。ADDAL,7;将7与AL的内容相加,结果放入AL中ADDAL,AH;将AH与AL的内容相加,结果放入AL中ADDBX+SI,AX;(DS:BX+SI)+(AX)DS:BX+SIADDAX,BX+SI;(DS:BX+SI)+(AX)AXADDBX,VARB;VARB为字节变量ADDVARW,SI;VARW为字变量,6.2.1 加法指令,2带进位的加法指令A
14、DC带进位的加法指令ADC主要用于多字节(或多字)加法运算中,与ADD配合实现多倍精度数的加法。将目的操作数内容加上源操作数内容再加上CF进位标志,并将结果送入目的操作数中。格式:ADC DSET,SRC,6.2.1 加法指令,带符号的多倍精度数在计算机内仍采用补码表示,其最高字节中的最高位为符号位,这样一来,就可将其余各低位字节(或字)中的数看做无符号数。因此,当两个多倍精度数相加时,其低位部分均为无符号数相加(采用ADD指令),只要将产生的进位加到高位字节(或字)即可。其运算的示意图如图6.7所示。,6.2.1 加法指令,【例6.8】现有两个32位无符号数12345678H和8765ABC
15、D相加,其和仍是一个32位无符号数,要求写出代码,使和的高16位送入DX中,和的低16位送入AX中。代码如下:MOVDX,1234HMOVAX,5678HADDAX,0ABCDHADCDX,8765H,6.2.1 加法指令,3加1指令INC加1指令INC是将目的操作数的内容自加1后,结果送至目的操作数,格式如下。格式:INC DEST【例6.9】假设(AX)=023FFH,则执行如下指令后的结果是什么?INC AX结果:(AX)=(AX)+1=02400H,6.2.2 减法指令,1不带借位的减法指令SUB不带借位的减法指令SUB将目的操作数的内容减源操作数的内容,结果存于目的操作数中,而源操作
16、数内容保持不变,其格式如下。格式:SUBDEST,SRC【例6.10】执行如下指令后的结果是什么?MOVAX,5D2FHSUBAH,AL第一条指令执行后(AX)=5D2FH,(AH)=5DH,(AL)=2FH,第二条指令执行后(AH)=2EH,执行情况如下:,6.2.2 减法指令,2带借位减法指令SBB带借位减法指令SBB是将目的操作数的内容减源操作数的内容,再减CF标志位,结果存于目的操作数中,其格式如下。格式:SBB DEST,SRC【例6.11】假设(AL)=56H,(BL)=43H,CF=1。则指令“SBB AL,BL”执行结果是什么?减法实际上是用加法做的。即把源操作数取反求补码,把
17、CF也取反求补码(0的补码为0,-1的补码为1111 1111(8位时)或1111 1111 1111 1111(16位时),然后再做加法。指令执行结果是(AL)=13H,执行情况如下:,6.2.2 减法指令,3减1指令DEC减1指令DEC是将目的操作数内容减1,结果存入目的操作数中,该指令主要用于调整地址指针和计数器,其格式如下。格式:DEC DEST【例6.12】假设(AX)=0D284H,则执行“DEC AX”指令后的结果是什么?结果:(AX)=(AX)-1=0D283H,6.2.2 减法指令,4求补码指令NEG求补码指令NEG也称为求负数指令,是将0减去目的操作数后送至目的操作数,使目
18、的操作数符号变反,其格式如下:格式:NEGDEST求反指令NOT的操作是对操作数按位求反,即FFFFH-DEST。所以假定要对AX寄存器中的操作数进行求补,那么可以有如下几种方法。方法1:NEGAX方法2:NOT AXINC AX方法3:MOV BX,0XCHG AX,BXSUBAX,BX;求补运算的结果应在AX中【例6.13】假设(AX)=0D284H,则执行“NEG AX”指令后的结果是什么?结果:(AX)=FFFFH-(AX)+1=2D7CH,6.2.2 减法指令,5比较指令CMP比较指令CMP主要用于比较两个数的关系,是否相等,谁大,谁小。它将目的操作数内容减源操作数内容,结果不保存,
19、目的操作数内容与源操作数内容保持不变,其格式如下。格式:CMPDEST,SRC,6.2.3 乘法指令,1无符号数乘法指令MUL无符号数乘法指令MUL的功能是如果是“字节”数据相乘,则将源操作数的内容乘以AL寄存器的内容,得到字数据结果送入AX寄存器中;如果是“字”数据相乘,则将源操作数的内容乘以AX寄存器的内容,得到双字数据结果,高字送入DX寄存器中,低字送入AX寄存器中,如图6.8所示。其格式如下。格式:MUL SRC;被乘数隐含在累加器AX(16位)或AL(8位)中,6.2.3 乘法指令,【例6.14】设(AL)=2CH,(BL)=11H,则执行如下指令后的结果是什么?MUL BL结果:使
20、2CH11H,其乘积02ECH存储在(AX)中。,6.2.3 乘法指令,2带符号数乘法指令IMUL带符号数乘法指令IMUL与MUL指令运算过程相同,只是操作对象为带符号的二进制数,其格式如下。格式:IMULSRC;被乘数隐含在累加器AX(16位)或AL(8位)中【例6.15】设(AL)=0B4H,(BL)=11H,则执行如下指令后的结果是什么?IMUL BL结果:(AX)=(0B4H)(11H)=0FAF4H。,6.2.4 除法指令,1无符号数除法指令DIV无符号数除法指令DIV功能是如果是字节除法,就将AX寄存器的内容除以源操作数的内容,商值送AL,余数送AH;如果是字除法,就将DX,AX的
21、内容除以源操作数的内容,商值送AX,余数送DX,其操作如图6.9所示。,6.2.4 除法指令,格式:DIV SRC;被除数隐含在累加器AH(16位)中或两个寄存器AX,DX中【例6.16】设(AX)=0400H,(BX)=0B4H,则执行如下指令后的结果是什么?DIV BL结果:(AL)=05H,(AH)=7CH。,6.2.4 除法指令,2有符号数除法指令IDIV有符号数除法指令IDIV与DIV指令相同,只不过各种数据都是带符号的。格式:IDIVSRC;被除数隐含在累加器AX(16位)或AH和DX(共32位)中【例6.17】设(AX)=0400H,(BX)=0B4H,则执行如下指令后的结果是什
22、么?IDIV BX结果:(AL)=F3H,(AH)=24H。,6.2.5 符号扩展指令,1字节扩展为字指令CBW字节扩展为字指令CBW是将AL中的符号位数据扩展至AH,其格式如下。格式:CBW2字扩展为双字指令CWD字扩展为双字指令CWD是将AX中的符号位数据扩展至DX,其格式如下。格式:CWD,6.2.5 符号扩展指令,【例6.18】假设X、Y和Z均为16位带符号数,分别存放在名为VARX、VARY和VARZ的变量单元中。计算如下表达式的值,计算结果的商保存在AX中,余数保存在DX中。表达式如下:(X*Y+Z-1000)/24部分程序代码如下:MOVAX,VARXIMULVARY;计算XY,
23、结果保存在DX、AX中MOVCX,AX;积的低16位保存到CX中MOV BX,DX;积的低16位保存到BX中MOV AX,VARZCWD;把VARZ扩展成32位ADD AX,CX;计算和ADC DX,BXSUB AX,1000;计算差SBB DX,0MOV CX,24IDIV CX;计算商和余数,商保存在AX中,余数保存在DX中,6.3 位操作类指令,6.3.1 逻辑运算指令1逻辑与指令AND逻辑与指令AND的功能是两个操作数(字节或字)进行按位“逻辑与”运算,结果送回目的操作数。若原来的两个操作数中的对应位均为1,则结果中的该位置为1;否则,该位置为0。其格式如下。格式:ANDDEST,SR
24、C【例6.19】将寄存器AL设置为34H,并将其中的内容高4位清零,低4位保存不变。指令如下:MOVAL,34H;AL=34HANDAL,0FH;AL=04H,6.3.1 逻辑运算指令,2测试指令TEST测试指令TEST用于对两个操作数进行逻辑与运算,但结果并不送至目的操作数,只是影响状态标志。此指令执行后两个操作数都不变。格式:TESTDEST,SRC,6.3.1 逻辑运算指令,3逻辑或指令OR逻辑或指令OR将两个操作数(字节或字)进行按位逻辑“或”操作,并将结果送至目的操作数。如果两个操作数中对应位有一个为1或全为1,则结果的该位为1;否则,结果的该位为0。其格式如下。格式:ORDEST,
25、SRC【例6.20】将寄存器AL设置为34H,并将其中的内容高4位置1,低4位保存不变。指令如下:MOV AL,34H;AL=34HOR AL,0F0H;AL=F4H,6.3.1 逻辑运算指令,4逻辑异或指令XOR逻辑异或指令XOR将两个操作数(字节或字)进行按位逻辑异或操作,即两个操作数对应位不同,则结果对应位为1;否则为0,并将结果送至目的操作数,而源操作数内容保持不变。其格式如下。格式:XORDEST,SRC【例6.21】将寄存器AL设置为34H,并将其中的内容高4位变反,低4位保存不变。指令如下:MOV AL,34H;AL=34HXOR AL,0F0H;AL=C4H,6.3.1 逻辑运
26、算指令,5逻辑非指令NOT逻辑非指令NOT对目的操作数的每一位求反码,并将结果送回目的操作数。其格式如下。格式:NOTDEST【例6.22】将寄存器AL设置为34H,并将其中的内容置反。指令如下:MOV AL,34H;AL=34HNOT;AL=CBH,6.3.2 移位指令,1逻辑左移指令SHL逻辑左移指令SHL将目的操作数左移COUNT次(位)。最高位移入进位标志CF中,而CF中原来的值被覆盖掉。移位后空出的最低位中填0,如图6.10所示。其格式如下。格式:SHLDEST,COUNT;COUNT=1或CL,6.3.2 移位指令,2逻辑右移指令SHR逻辑右移指令SHR将目的操作数向右移COUNT
27、次(位)。每移动一位,向高位补充一个0,而移出的低位送入标志寄存器的CF位,如图6.11所示。格式:SHRDEST,COUNT;COUNT=1或CL,6.3.2 移位指令,【例6.23】将寄存器AL中的内容高4位与低4位互换。指令如下:MOVBL,ALMOVCL,4;设置移位次数为4SHLAL,CL;将低4位移至高4位,同时低4位都为0SHRBL,CL;将高4位移至低4位,同时高4位都为0ORAL,BL;执行或指令OR合并,6.3.2 移位指令,3算术左移指令SAL算术左移指令SAL将目的操作数左移COUNT次(位)。最高位移入进位标志CF中,而CF中原来的值被覆盖掉。移位后空出的最低位中填0
28、,如图6.12所示。其格式如下。格式:SALDEST,COUNT;COUNT=1或CL,【例6.24】设SI为00D3,计算(SI)*8。指令如下:MOVCL,3SALSI,CL,6.3.2 移位指令,4算术右移指令SAR算术右移指令SAR将目的操作数向右移COUNT次(位),每移动一位,向高位补充一个原有值,即最高位若为1,则补充1;若为0,则补充0,而移出的低位送入标志寄存器的CF位,如图6.13所示。格式:SARDEST,COUNT;COUNT=1或CL,6.3.2 移位指令,若移位次数COUNT为l,且移位前后目的操作数的最高位不会发生变化,那么OF置1;否则OF清零。若移位次数COU
29、NT大于1,移位后OF的值则不能确定。例如:MOVAL,2SAR AL,1;将(AL)右移一位MOV CL,3;设置移位位数SAR AL,CL;将(AL)右移3位【例6.25】使用移位指令来计算-47/2。指令如下:MOVAL,-47SARAL,1,6.3.3 循环移位指令,1不带进位标志的循环左移指令ROL不带进位标志的循环左移指令ROL将目的操作数向左移COUNT位,每移动一位,把移出的最高位送入最低位和标志寄存器的CF位,如图6.14所示。其格式如下。格式:ROLDEST,COUNT;COUNT=1或CL,6.3.3 循环移位指令,2不带进位标志的循环右移指令ROR不带进位标志的循环右移
30、指令ROR目的操作数向右移COUNT位,每移动一位,把移出的最低位送入最高位和标志寄存器的CF位,如图6.15所示。其格式如下。格式:RORDEST,COUNT;COUNT=1或CL,6.3.3 循环移位指令,3带进位循环左移指令RCL带进位循环左移指令RCL将目的操作数向左移COUNT位,每移动一位,把标志寄存器的CF位送入最低位,再把移出的最高位送入CF位,如图6.16所示。其格式如下。格式:RCLDEST,COUNT;COUNT=1或CL,6.3.3 循环移位指令,4带进位循环右移指令RCR带进位循环右移指令RCR是将目的操作数向右移COUNT位,每移动一位,把标志寄存器的CF位送入最高
31、位,再把移出的最低位送入CF位,如图6.17所示。其格式如下。格式:RCR DEST,COUNT;COUNT=1或CL,6.3.3 循环移位指令,【例6.26】把AL最低位送BL最高位,但保持AL不变。指令如下:RORBL,1RORAL,1RCLBL,1ROLAL,1,6.4 处理器控制类指令,6.4.1 标志位操作指令1进位标志清零指令CLC进位标志清零指令CLC将进位位CF清零,即CF=0。其格式如下。格式:CLC2进位标志置位指令STC进位标志置位指令STF将进位位CF置1,即CF=1。其格式如下。格式:STC3进位标志取反指令CMC进位标志取反指令CMC将进位位CF变反,即CF=。其格
32、式如下。格式:CMC,6.4.1 标志位操作指令,4方向标志清零指令CLD方向标志清零指令CLD将方向位DF清零,即DF=0。其格式如下。格式:CLD5方向标志置位指令STD方向标志置位指令STD将方向位DF置1,即DF=1。其格式如下。格式:STD6中断标志清零指令CLI中断标志清零指令CLI将中断允许位IF清零,即IF=0。其格式如下。格式:CLI7中断标志置位指令STI中断标志置位指令STI将中断允许位IF置1,即IF=1。其格式如下。格式:STI,6.4.2 CPU控制指令,1空操作指令NOP空操作指令NOP也称为无操作指令,它不执行任何操作,其机器码占有一个字节,在调试程序时往往用这
33、条指令占有一定的存储单元,以便在正式运行时用其他指令取代。NOP空操作指令还可用来达到精确的时间延迟。其格式如下。格式:NOP2停机指令HLT停机指令HLT可使机器暂停工作,使CPU处于停机状态,以便等待一次外部(硬件)中断到来。中断结束后,CPU会退出暂停状态,继续执行下面的程序。系统复位操作也会使CPU退出停机状态。其格式如下。格式:HLT,6.4.2 CPU控制指令,3等待指令WAIT等待指令WAIT指令使CPU处于空转状态,它也可以用来等待外部中断的发生,但中断结束后仍返回WAIT指令继续运行。其格式如下。格式:WAIT4放权指令ESC放权指令ESC把指定存储单元中的内容送到数据总线上
34、,从而将存储器中的指令或数据传送给其他处理器。其格式如下。格式:ESCOPRD,SRC,6.4.2 CPU控制指令,5封锁指令LOCK封锁指令LOCK是一种前缀,它可与其他指令联合,用来维持总线的锁存信号直到与其联合的指令执行完为止(独占直线)。其格式如下。格式:LOCKOP,第7章 基本程序设计,7.1 程序设计方法,7.2 顺序结构程序设计,7.3 分支程序设计,7.4 循环结构程序设计,7.1 程序设计方法,7.1.1 程序设计步骤1分析问题分析问题的目的就是要对问题有一个确切的理解,明确问题的环境限制,弄清已知条件、原始数据、输入与输出要求、对运算精度的要求、对处理速度的要求,以及最后
35、期望获得的结果。正确地分析问题是进行程序设计的基础。2确定解决问题的合理算法汇编程序算法是指用汇编语言在有限步之内求解某一类问题的方法与步骤,它可能依据某一数学模型,也可能直接或间接采用一些现有的计算方法。开始时一般先模拟计算机解决实际问题的过程,根据算法把一个实际问题转化为一个计算机可以处理的问题。,7.1.1 程序设计步骤,3绘制程序流程图流程图是用框图的形式来表示解题的方法、步骤。流程图不仅描述算法清晰、直观,并且可以减少程序逻辑出错的可能性。如果要解决的问题比较复杂,可以先编写比较大的过程框图构成的程序流程图,再逐步细化,直到每一框图都可以很容易编制程序为止。4分配存储空间和工作单元与
36、高级语言程序不同,汇编语言程序要求运行的每一步都能清楚数据的位置,因此,在程序设计过程中,始终要关心如何选用存储空间与如何选择寄存器的问题。一个完整的汇编程序往往由一个或几个段构成,要分别定义程序中所需使用的数据段、堆栈段、代码段及附加段。要根据程序执行过程合理地对每一步及各个阶段所使用的工作单元进行安排,工作单元既可以是存储单元,也可以是数据寄存器。,7.1.1 程序设计步骤,5根据程序流程图编写程序在完成以上准备工作后,就可以根据程序流程图用汇编语句实现算法,这一过程称为编制程序,或称为编码。在编制程序时,必须严格按照汇编语言的语句规则与语法规则书写,还要注意保证源程序的可读性和可维护性。
37、6静态检查及上机调试上机调试程序大致有以下4个步骤。(1)使用编辑程序,输入源程序,并保存成扩展名为.ASM的文件。(2)使用宏汇编程序,把扩展名为.ASM的源程序汇编成目标程序,即生成扩展名为.OBJ的文件。(3)使用连接程序,把扩展名为.OBJ的目标程序连接装配成可执行文件,即生成扩展名为.EXE的文件。(4)使用调试程序,调试扩展名为.EXE的可执行文件。,7.1.2 程序流程图,程序流程图主要由以下几种框图符号组成,框图表示如图7.1所示。,7.2 顺序结构程序设计,7.2.1 顺序程序设计【例7.1】试写出两个字节数据相加的程序。(1)分析问题两个字节数据相加比较简单,可以直接使用加
38、法指令。当然首先要定义2个字节变量X和Y,再定义字变量Z用于存放相加后的结果,这里假设X为3CH,Y为94H。(2)确定算法首先将X读到AL中,再和Y相加,同时AH清零后和进位标志位相加,则AX为相加的结果,再将AX存储到Y中。,7.2.1 顺序程序设计,(3)画程序流程图流程图如图7.2所示。,7.2.1 顺序程序设计,(4)确定程序的基本框架该汇编语言程序的基本框架至少要两个段,即数据段和代码段。数据段中至少定义3个变量,即两个加数变量X、Y,都是DB类型,还有一个和变量Z,是DW类型。和变量Z尚属未知,可以定义一个1个字长的缓冲区。(5)编写程序,7.2.1 顺序程序设计,【例7.2】试
39、写出两个64位无符号数相加的程序。(1)分析问题在Intel 8086/8088 CPU指令系统中,只有8位或16位运算指令,没有32位和64位以上的运算指令。(2)确定算法要进行64位的加法运算,可以利用16位加法指令分别相加4次来实现。,7.2.1 顺序程序设计,(3)画程序流程图流程图如图7.3所示。,7.2.1 顺序程序设计,(4)确定程序的基本框架该汇编语言程序的基本框架至少要两个段,即数据段和代码段。数据段中至少定义3个变量,即两个加数变量X、Y,还有一个和变量SUM,都是DW类型。和变量SUM尚属未知,可以定义一个5个字长(比64位字长大一点)的缓冲区。因为要加4次,需要一个计数
40、器或指针,可选择寄存器BX。(5)编写程序,7.2.2 简单查表法代码转换,【例7.3】编写一个能把十六进制数字码(0,9,A,b,c,d,E,F)转换为对应七段代码的程序。(1)分析问题七段显示数码管(如图7.4所示)的管17对应一个字节数据的第06位,如果假设0表示对应段亮,l表示对应段暗,那么字节数据的第7位无效。假设恒置0,那么数字码0对应以二进制形式表示的代码01000000,数字码l对应以二进制形式表示的代码01111001,这样,数字码F对应以二进制形式表示的代码00001110。,7.2.2 简单查表法代码转换,(2)确定算法因为十六进制数字码与七段代码间的关系难以表示成一个简
41、单的算术表达式,所以利用表的方法实现代码转换较为合适。首先把十六进制数字码(0,9,A,b,c,d,E,F)对应的七段代码制成表格,使用查表指令查找出十六进制数据码所对应的七段代码。(3)画程序流程图流程图如图7.5所示:,7.2.2 简单查表法代码转换,(4)确定程序的基本框架该汇编语言程序的基本框架至少要两个段,即数据段和代码段。在数据段中定义一个表TAB,按(0,9,A,b,c,d,E,F)存放对应的十六进制数据码所对应的七段代码,再定义要转换的十六进制数字码X和存放对应的七段代码Y,都是DB类型。(5)编写程序,7.3 分支程序设计,单分支程序根据条件成立与否,执行某一程序段或跳过该程
42、序段,如图7.6(a)所示,其中Y表示条件成立,N表示条件不成立,它类似于高级语言中的“IF THEN”语句;双分支程序根据条件成立与否分别执行程序段1或程序段2,如图7.6(b)所示,它类似于高级语言中的“IF THEN ELSE”语句。,7.3 分支程序设计,多路分支结构如同高级语言中的“CASE”语句,常常根据各种不同的情况执行多路转移。在指定范围内,每一次条件测试都将执行一路程序,如图7.7所示。,7.3.1 无条件转移指令,1段内直接短转移段内直接短转移是指从当前指令跳转到同一代码段的另一指令(目标标号)处,转移量不超过8位,即距离当前IP位置的-128+127字节之间。其指令格式如
43、下。格式:JMP SHORT TARGET段内直接短转移执行的操作为(IP)(IP)+“TARGET与JMP指令的下一条指令的8位位移量距离”。例如:NEXT:MOVAX,BXJMPSHORTNEXT;转到NEXT处JMPSHORTHELLO;转到HELLO处HELLO:MOVAX,67H,7.3.1 无条件转移指令,【例7.4】设指令“JMP SHORT NEXT”的偏移地址为1254H,NEXT为目标标号,其偏移地址为12D0H。试问汇编程序对该指令进行汇编后,指令机器码中给出的转移量是多少?由于JMP指令的偏移地址为1254H,它的机器码是两个字节,因此它的下一条指令的首地址(在IP中)
44、应该为:IP=1254H+2=1256HJMP SHORT NEXT的执行示意图如图7.8所示。,7.3.1 无条件转移指令,2段内直接近转移段内直接近转移与段内直接短转移基本相同,只是转移量为16位,即-32768+32767字节。该指令相应的机器指令占用3个字节,因此JMP指令的下一条指令的地址应该等于JMP指令的地址加上3。其格式如下。格式:JMPNEAR PTR TARGET段内直接近转移执行的操作为(IP)(IP)+“TARGET与JMP指令的下一条指令的16位位移量”。例如:NEXT:MOVAX,BXJMPNEAR PTRNEXT;转到NEXT处JMPHELLO;转到HELLO处,
45、省略了NEAR PTRHELLO:MOVAX,67H,7.3.1 无条件转移指令,3段内间接转移段内间接转移跳转的目标地址不直接给出,而是由TARGET的寻址方式(寄存器或存储单元的内容)或伪指令DW定义的字变量(符号地址)确定的偏移地址EA确定,然后执行该地址中的相关指令。其执行格式如下。格式:JMP REG或 JMP WORD PTR ADDR,7.3.1 无条件转移指令,4段间直接转移段间直接转移是指从这一代码段转移到另一个代码段中,因此,操作数是一个远标号,在另一个代码段内。其格式如下。格式:JMPFAR PTR TARGET段间直接转移执行的操作如下:(1)(IP)TARGET偏移地
46、址。(2)(CS)TARGET的段地址。例如:CODEl SEGMENTTARGETLABELFARCODEl ENDSCODE2 SEGMENTJMPFAR PTR TARGETCODE2 ENDS,7.3.1 无条件转移指令,5段间间接转移段间间接转移与段间直接转移指令一样,也用于段间转移,只不过当前CS和IP由指令指明的存储器中连续的两个字更新,低位地址的字更新IP,高位地址的字更新CS,存放新IP和CS的存储单元地址由存储器操作数的寻址方式决定。其格式如下。格式:JMP DWORD PTR ADDR指令的操作为:(1)IPADDR的第一个字存储单元中的内容。(2)CSADDR的第二个字
47、存储单元中的内容。例如:JMPDWORD PTR VAR BX;VAR为变量JMPVAR_DWORD;省略了DWORD PTRJMPDWORDPTR BXSI,7.3.2 条件转移指令,1根据单个标志的设置情况进行转移根据单个标志位的状态判断转移条件,该转移指令共有5种(10条),其转移指令如表7.1所示。,7.3.2 条件转移指令,【例7.5】写出程序片段,测试AX的低四位是否全是0,如果均是0,那么使CX=0;否则使CX=-1。代码如下:MOVCX,-1TEST AX,0FH;测试AX的低4位JNZ NEXT;不全为0则转移到NEXTMOV CX,0;全为0时使CX=0NEXT:,7.3.
48、2 条件转移指令,2比较两个无符号数,并根据比较结果的高低转移比较两个无符号数,并根据比较结果的高低转移,假设在条件转移指令前使用比较指令,比较两个无符号数DATA1和DATA2,指令进行的操作是DATA1-DATA2,其转移指令如表7.2所示。,7.3.2 条件转移指令,3比较两个带符号数,并根据比较结果的大小转移对于带符号数的比较,需要使用符号标志位SF、溢出标志位OF和零标志位ZF来判断。假设在条件转移指令前使用比较指令,比较两个无符号数DATA1和DATA2,指令进行的操作是DATA1-DATA2,其转移指令如表7.3所示。,7.3.2 条件转移指令,4测试CX的值为0,则转移测试CX
49、的值为0,则转移;否则不转移。其指令格式如下。格式:JCXZ TARGET,7.3.3 单分支程序设计,【例7.8】编写程序比较两个8位数大小,并把较大的数存入字节变量MAX中。(1)分析问题假设两个8位数存放在变量VARW1和VARW2中,确定分支的条件是判断变量VARW1和VARW2的大小。(2)确定算法采用比较转移指令,在汇编语言中用AL来保存中间结果。这是因为读取寄存器比读取存储器要快,而且汇编语言指令不允许两个操作数都为存储单元。,7.3.3 单分支程序设计,(3)画程序流程图流程图如图7.9所示。,7.3.3 单分支程序设计,(4)分配存储空间和工作单元该汇编语言程序的基本框架至少
50、要两个段:数据段和代码段。数据段中三个数VARW1、VARW2和MAX都是8位数,应选DB类型。(5)编写程序,7.3.4 双分支程序设计,【例7.9】编写一个程序,实现把一位十六进制数转换为对应的ASCII码。(1)分析问题十六进制数码与对应ASCII码的关系如下所示:,假设十六进制数为X,ASCII码为Y,则这种对应关系可表示为一个分段函数:,7.3.4 双分支程序设计,(2)确定算法采用比较转移指令,在汇编语言中用AL来保存中间结果。(3)画程序流程图流程图如图7.10所示。,7.3.4 双分支程序设计,(4)分配存储空间和工作单元该汇编语言程序的基本框架至少要两个段:数据段和代码段。数