资源描述:
《第3章 汇编语言程序设计 第4节 汇编语言程序设计ppt》由会员上传分享,免费在线阅读,更多相关内容在教育资源-天天文库。
第四节汇编语言程序设计一、概述1.编写汇编语言程序步骤2.判断程序质量的标准3.几种程序结构二、汇编语言程序设计举例例1将寄存器BX中的内容以十六进制形式显示出来。例2将键盘输入的十进制数据串转换成其相应大小的数值存放在BX寄存器中。 一、概述1.编写汇编语言程序步骤2.判断程序质量的标准3.几种程序结构 一.编写汇编语言程序步骤分析实际问题,抽象描述问题的模型确定解决模型的算法按算法画出程序流程图按流程图编写程序上机调试,运行程序 2.判断程序质量的标准程序的正确性程序的可读性程序的执行时间程序所占内存大小 3.几种程序结构顺序结构分支结构循环结构子程结构 顺序结构 两个分支YN、、、CMPAL,BLJGgreatJMPexitgreat:exit:、、、、、、AL≤BL处理AL>BL处理分支结构 三个分支、、、CMPAL,0JGgreatJLlessJMPexitless:JMPexitgreat:exit:、、、AL=0处理AL>0处理AL<0处理YYNN分支结构 循环结构当型循环(当条件成立进入循环)循环初始设置循环体循环条件判断?YN直到型循环(直到条件成立退出循环)YN循环初始设置循环体循环条件判断? 1.多处调用完成同一功能的子程:codeSEGMENTstart:、、CALLsub、、CALLsub、、CALLsub、、MOVAH,4CHINT21HsubPROC、、、、RETsubENDPcodeENDSENDstart2.模块化程序设计:codeSEGMENTbegin:CALLsub1CALLsub2CALLsub3MOVAH,4CHINT21Hsub1PROC、、RETsub1ENDPsub2PROC、、RETsub2ENDPsub3PROC、、RETsub3ENDPcodeENDSENDbegin子程结构注意返回DOS语句位置 二、汇编语言程序设计举例例1将寄存器BX中的内容以十六进制形式显示出来。例2将键盘输入的十进制数据串转换成其相应大小的数值存放在BX寄存器中。 有关字符、数码转换的处理1.计算机处理字符时,常用的字符编码是ASCII码。2.数字和字母的ASCII码是一个有序序列数字0~9:30H~39H大写字母A~Z:41H~5AH小写字母a~z:61H~7AH 3.计算机处理信息时,其对象都是二进制数。外设(显示器、打印机、键盘等)用ASCII码与CPU进行信息传送。例如:1)在键盘上按下某一字符键(如’9’),键盘接口向键盘缓冲区送去的是该字符的ASCII码(如39H),不是送数字09H。2)在文本方式下,要在显示器上显示某一字符(如’A’),须将该字符的ASCII码(如41H)送显示缓冲区,不是送数字0AH。计算机要利用显示器、键盘等外设时,须据程序设计的需要进行有关转换。 例将CPU运算的结果通过显示器显示时,需将结果转换成其对应的ASCII码才能进行显示。 例CPU要处理从键盘输入的某一数据,需将该数据串进行转换后才能应用。 例1将BX寄存器中的内容以十六进制形式显示出来。BX是一个16位寄存器二进制1010100100111110用十六进制显示时,每4位用一个字符显示,共4个其中0000→’0’30H,1010→’A’41H0001→’1’31H,1011→’B’42H、、、、1001→’9’39H,1111→’F’46H?十六进制A93E屏幕上的显示‘A’‘9’‘3’‘E’对应的ASCII41H39H33H45H 算法:取出要显示的某4位,转换为对应的ASCII码,再调用DOS系统功能进行显示。1)对于0000~1001,先扩展成一个字节,高4位清0,加上30H后,即可得字符’0’~’9’对应的ASCII码。00000001B+30H=31H00001001B+30H=39H0001B‘1’1001B‘9’2)对于1010~1111,先扩展成一个字节,高4位清0,加上30H后,还要再加上07H,才能得到’A’~’F’对应的ASCII码00001010B+30H+07H=41H00001111B+30H+07H=46H1010B‘A’1111B‘F’ codeSEGMENTASSUMECS:codestart:MOVCH,4;字符个数MOVCL,4;循环移位次数next:ROLBX,CL;取显示位的值MOVDL,BL;保存在DL中ANDDL,0FH;清除高4位ADDDL,30H;转变为数字的ASCIICMPDL,39H;大于39H,则应转变JLEprint;为字母A~F的ASCIIADDDL,07Hprint:MOVAH,2H;显示DL中的字符INT21HDECCH;显示结束?JNZnextMOVAH,4CH;返回DOSINT21HcodeENDSENDstart显示字符个数CH=4循环移位次数CL=4BX循环左移4位,将要显示的值移至低4位,保存在DL中清DL的高4位,只保留要显示位的值DL←DL+30H完成数值0~9的ASCII码转换YNDL←DL+07H完成数值A~F的ASCII码转换用02功能显示DL中的字符YN返回DOSDL超出39H?CH←CH-1转换结束?开始 思考:1.例1采用的是大写字母A~F进行显示,若采用小写字符a~f进行显示,程序如何改写?1010001110011110‘A39E’或‘a39e’2.编程将CPU内14个16位寄存器当前的内容分别用十六进制形式显示出来。 编程将CPU内14个16位寄存器当前的内容分别用十六进制形式显示出来。要点:将上例改写为一个子程,入口参数为BX子程中注意寄存器值的保存和恢复注意CS、IP、PSW寄存器值的获取方法 例将CPU内14个16位寄存器当前内容分别用16进制形式显示出来(采用DEBUG下R命令的显示顺序)codeSEGMENTASSUMECS:codestart:PUSHBXMOVBX,AX;显示AXCALLlistbxPOPBX;显示BXCALLlistbxMOVBX,CX;显示CXCALLlistbxMOVBX,DX;显示DXCALLlistbxMOVBX,SP;显示SPCALLlistbxMOVBX,BP;显示BPCALLlistbxMOVBX,SI;显示SICALLlistbxMOVBX,DI;显示DICALLlistbxMOVBX,DS;显示DSCALLlistbxMOVBX,ES;显示ESCALLlistbxMOVBX,SS;显示SSCALLlistbxMOVBX,SEGstartCALLlistbx;显示CSMOVBX,OFFSETstartCALLlistbx;显示IPPUSHFPOPBX;显示PSWCALLlistbxMOVAH,4CH;返回DOSINT21H listbxPROCMOVCH,4MOVCL,4next:ROLBX,CLMOVDL,BLANDDL,0FHADDDL,30HCMPDL,39HJLEprintADDDL,07Hprint:MOVAH,2HINT21HDECCHJNZnextMOVDL,20H;显示空格符MOVAH,02HINT21HRET;子程返回listbxENDPcodeENDSENDstartlistbxPROCPUSHCX;保存寄存器PUSHBXPUSHDXPUSHAXPUSHFPOPF;恢复寄存器POPAXPOPDXPOPBXPOPCXRET;子程返回listbxENDPcodeENDSENDstart用十六进制显示BX内容子程 D:>LIST_REG;在DOS下执行程序0000000000FF0BDF00000912000000000BDF0BDF0BEF0BEF00003202D:>DEBUGLIST_REG.EXE;利用DEBUG检测结果-R;显示当前寄存器内容AX=0000BX=0000CX=007BDX=0000SP=0000BP=0000SI=0000DI=0000DS=128EES=128ESS=129ECS=129EIP=0000NVUPEIPLNZNAPONC129E:000053PUSHBX-G;执行程序00000000007B00000000000000000000128E128E129E129E00007202Programterminatednormally-运行的结果与用R命令显示的结果相同,程序运行结果正确 例2将键盘输入的十进制数据串转换成相应大小的数值存放在BX寄存器中。分析:从键盘输入’1234’(表示1234)用0AH功能输入,则缓冲区存放的内容为:06h04h31h32h33h34h0Dhnum问题:要转换成1234即04D2h存放在BX中,怎么实现?清ASCII码的高4位可得各数位大小值。01h02h03h04h04D2h? 算法一:数值大小=各位值×权值之和1234D=千位×1000+百位×100+十位×10+个位=1×1000+2×100+3×10+4=0000010011010010B=04D2H01h02h03h04h04D2h? 算法二:数值大小=部分和×10+下一位数值1234D=(((0×10+1)×10+2)×10+3)×10+4=0000010011010010B=04D2H部分和从0开始,循环次数等于输入的位数01h02h03h04h04D2h? dataSEGMENTstringDB‘Input:’,’$’numDB6,?,6DUP(?)dataENDSCODESEGMENTASSUMECS:code,DS:datastart:MOVAX,dataMOVDS,AXCALLinputCALLchangeCALLlist_bxMOVAH,4CHINT21H开始初始化DS的值CALLinput显示输入提示,等待从键盘输入十进制数据串CALLchange将数据串转化为相应的数值存放在BX中返回DOS主程序流程图CALLlist_bx将BX内容以16进制显示出来 input子程序流程图调用09功能显示输入提示调用0A功能等待从键盘输入数据RET返回inputPROCLEADX,stringMOVAH,09HINT21HLEADX,numMOVAH,0AHINT21HRETinputENDP0604313233340D00num0000 change子程序流程图(BX)←输入字符的数值大小SI←数据串偏址CX←数据串长度AX←部分和初值0DI←乘数10YNRET返回AX←部分和乘10(AX)←(AX)+(BX)形成新的部分和修改SI指针,指向下一位输入BX←转换结果AXCX←CX-1CX=0?changePROCLEASI,num+2MOVCL,num+1MOVCH,0MOVAX,0MOVDI,10next:MULDIMOVBH,0MOVBL,[SI]ANDBL,0FHADDAX,BXINCSILOOPnextzero:MOVBX,AXRETchangeENDP0604313233340D00num00001234D=(((0×10+1)×10+2)×10+3)×10+4 显示字符个数CH=4循环移位次数CL=4BX循环左移4位,将要显示的值移至低4位,保存在DL中清DL的高4位,只保留要显示位的值DL←DL+30H完成数值0~9的ASCII码转换YNDL←DL+07H完成数值A~F的ASCII码转换用02功能显示DL中的字符YNRET返回DL超出39H?CH←CH-1转换结束?list_bx子程序流程图list_bxPROCMOVCH,4MOVCL,4next:ROLBX,CLMOVDL,BLANDDL,0FHADDDL,30HCMPDL,39HJLEprintADDDL,07Hprint:MOVAH,2HINT21HDECCHJNZnextRET;子程返回list_bxENDPcodeENDSENDstart 编写子程序的注意事项:注意子程中PUSH、POP应成对,否则易造成死机。dataSEGMENTstringDB‘Hello’,’$’dataENDScodeSEGMENTASSUMECS:code,DS:datastart:MOVAX,dataMOVDS,AXCALLinputMOVAH,4CHINT21HinputPROCPUSHAXLEADX,stringMOVAH,09HINT21HRETinputENDPcodeENDSENDstart执行call前SS:SP(AX)执行call后SS:SP(IP)执行push后SS:SP执行ret后SS:SP(IP) 2.子程与主程的参数传送:1)用寄存器传送2)用定义的变量传送(例二)3)用堆栈传送(自学) 例下面程序段,思考是否可以完成AX→CX,BX→DXCODESEGMENTASSUMECS:codestart:MOVAX,dataMOVDS,AXPUSHAXPUSHBXCALLsubMOVAH,4CHINT21HsubPROCPOPDXPOPCX、、、、RETsubENDPcodeENDSENDstart如何用堆栈传送参数,参看教材,或相关参考书。pushax前SS:SP(BX)pushax后SS:SP(AX)pushbx后SS:SP执行ret后SS:SP(IP)callsub后SS:SPSS:SPpopdx后SS:SPpopcx后(DX)(CX)