第3章 80 x86汇编语言程序设计(下).ppt_第1页
第3章 80 x86汇编语言程序设计(下).ppt_第2页
第3章 80 x86汇编语言程序设计(下).ppt_第3页
第3章 80 x86汇编语言程序设计(下).ppt_第4页
第3章 80 x86汇编语言程序设计(下).ppt_第5页
已阅读5页,还剩89页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、1,第3章 80 x86汇编语言程序设计(下),2,分支结构是指计算机根据实际情况或条件,作出判断和选择,转而执行不同的程序段的一种程序结构。,条件,程序段,条件,程序段A,程序段B,Y,N,Y,N,3.5 分支结构程序设计,3,多路分支结构 根据某个控制字的各“位”状态实行多路转移,多路条件测试,程序段1,程序段2,程序段n,3.5.1无条件转移指令 JMP,1、段内转移,格式1:JMP SHORT OPR ;段内相对短转移 操作1:IP-(IP)+disp8 说明:转移范围-128字节至+127字节,操作数OPR为段内某个标号。,段内相对短转移示例 指令JMP SHORT ADDT 存放在

2、CS:0200H 中, 标号ADDT对于IP指针的偏移量为1DH, 则转移地址为0202H+001DH=021FH JMP SHORT ADDT 0200 E8 1 1D ADDT: MOV AL, 40H 2 ADD AL, BL +1DH 021F B0 0220 1D,4,格式2:JMP OPR JMP NEAR PTR OPR ;段内相对近转移 操作2:IP-(IP)+disp16 说明:转移范围-32KB至+32KB, 操作数OPR为段内某个标号。,格式3:JMP WORD PTR OPR ;段内间接转移 操作3:IP-(OPR) 说明:OPR是基址/变址寄存器或存储器操作数。,段内

3、间接转移示例 ADDRESS DW 2000H;定义转移地址 . LEASI, ADDRESS ;偏移量-SI . JMPWORD PTRSI ;转移到CS:2000,5,2、段间转移,格式4:JMP FAR PTR OPR ;段间直接转移 操作4:IP-OAopr CS-(CS)opr,段间直接转移示例 50 新IP=0250H ;代码段C1 02 00 新CS=2000H JMP FAR PTR NEXT 20 ;代码段C2 C2段 20000H NEXT: MOV AL,10H NEXT 20250H,EA OP码,C1段,6,格式5:JMP DWORD PTR OPR ;段间间接转移

4、操作5:IP-(DS)*16+OPR) CS-(DS)*16+OPR+2),段间间接转移示例 JMP DWORD PTR 4000H 设 (DS)=1000H (14000H)=0010H (14002H)=5000H 执行后 (CS)=5000H (IP)=0010H,7,3.5.2 条件转移指令 格式:J条件 标号,操作:测试条件,若满足,则跳转到标号处执行, 即 IP-(IP)+disp8 ; 否则,执行后续指令,说明:根据上一条指令所设置的条件码判别测试条件 转移范围在-128到+127字节,8,条件转移指令(1) 操作符 功能 测试条件 JC 进位标志为1转移 CF=1 JNC 进位

5、标志为0转移 CF=0 JZ/JE 等于0/相等转移 ZF=1 JNZ/JNE 不等于0/不相等转移 ZF=0 JS 符号标志为1转移 SF=1 JNS 符号标志为0转移 SF=0 JO 溢出转移 OF=1 JNO 无溢出转移 OF=0 JP/JPE 偶状态转移 PF=1 JNP/JPO 奇状态转移 PF=0 JCXZ CX=0转移 CX=0 JECXZ ECX=0转移 ECX=0,9,条件转移指令(2) A-B 比较情况 无符号数 有符号数 指令 判断条件 指令 判断条件 AB JA ZF=0,CF=0 JG SF=OF JNBE JNLE 且 ZF=0 A=B JAE ZF=1或 JGE

6、SF=OF JNB CF=0 JNL 或ZF=1 AOF JNAE JNGE 且ZF=0 AOF JNA CF=1 JNG 或ZF=1,10,条件转移指令示例1 将X中十六进制的ASCII码转换成其所对应的数值,存放到HEX中。如A应转换为10。,MOV AH, X CMP AH, 39H JBE NEXT ;39H则转 SUB AH, 7 ;是A-F,减7 NEXT: SUB AH, 30H ;减30H MOV HEX, AH,注意ASCII中09是30H39H,AF是41H46H,11,条件转移指令示例2 CMP AX, 0FFFFH JLE P3 CMP AX,1 JL P2 MOV A

7、X, 1 JMP DONE P2: MOV AX, 0 JMP DONE P3: MOV AX,-1 DONE:,AX(-1),AX1,AX-1,AX-0,AX-(-1),Y,N,N,Y,如果条件转移目标地址超出-128+127的范围怎么办?,12,13,1、比较/转移 利用比较和条件转移指令实现两路分支。 比较结果记录在某些标志位中,条件转移指令 根据约定的条件进行对照,满足条件时转移,不满 足条件时不转移。,2、跳转表转移 利用跳转表实现多路分支。 比较/转移指令可嵌套,但程序结构复杂, 跳转表可使程序结构清晰。,3.5.3 分支结构程序设计,教材上的例子请看P99中的例3.18和例3.1

8、9,上机实现例3.18程序。,有一个首地址为ARRAY的N字数组,将其中正数的个数放在DI中,0的个数放在SI中,负数个数放在AX中,14,注意:负数个数=N-DI-SI,MOV CX, N MOV BX, 0 ;初始化 MOV DI, BX ; 正数个数计数器初始化 MOV SI, BX ; 0的个数计数器初始化 AGAIN:CMP WORRD PTR ARRAYBX, 0 ;数组当前元素与0比较 JLE LEEQ ;小于等于0转移 INC DI ;正数计数 JMP NEXT LEEQ: JL NEXT ;小于0转移 INC SI ;0计数 NEXT: ADD BX, 2 ;数组表指针指向下

9、一元素 DEC CX JNZ AGAIN MOV AX, N ;负数个数=N-DI-SI SUB AX, DI SUB AX, SI,15,16,设字节单元N1、N2中存放无符号数 (1)若两个均是偶数,则分别加1后送D1 、D2中 (2)若两个均是奇数,则直接送D1 、D2中 (3)若一个是奇数,一个是偶数,则把奇数送D1,偶数送D2中,AL-(N1),AH-(N2),(AL)0=0,(AH)0=0,AL-(AL)+1 AH-(AH)+1,(AL) (AH),D1-(AL),D2-(AH),奇,偶,偶,奇,注意:根据条件,当N1是奇数时,无论N2是奇数还是偶数,都只需直接送D1、D2,17,

10、程序如下: MOV AL, N1 MOV AH, N2 TEST AL, 01H ;测试 N1的奇偶 JNE ENDO ;N1为奇数 TEST AH, 01H ;测试 N2的奇偶 JNE L1 ;N2是奇数,转移 INC AL ;两个均是偶数 INC AH JMP ENDO L1: XCHG AL, AH ;N1是偶数, N2是奇数 ENDO: MOV D1, AL ;存放结果 MOV D2, AH,转上页,18,利用跳转表实现多路分支 跳转表是在某一内存区域顺序排列的一组有规律的入口地址。 如是段内分支,每个地址占两个单元(IP的值) 如是段间分支,每个地址占4个单元(CS:IP的值) TA

11、BLE SUB1 TABLE SUB1 SUB2 SUB3 SUB2,IP,IP,IP,IP,CS,IP,CS,段内转移 段间转移,19,根据AL中哪一位为1(从低位到高位)把程序转移到8个不同的程序分支去,.DATA TABLE DW ROUTINE_1 DW ROUTINE_2 DW ROUTINE_3 DW ROUTINE_4 DW ROUTINE_5 DW ROUTINE_6 DW ROUTINE_7 DW ROUTINE_8,.CODE ROUTINE_1: MOV AX,0 ROUTINE_2: CMP AL, 3 ROUTINE_8: CLI,20,用变址寻址方式,CMP AL,

12、 0 JE DONE MOV SI, 0 L: SHR AL, 1 JNB NOT_YET ; CF=0或ZF=1跳转 JMP TABLESI NOT_YET: JZ DONE ADD SI, TYPE TABLE ;Type Table=2 JMP L DONE: ,用寄存器间接寻址与基址变址寻址该如何做?,21,在附加段中有一个从小到大排序的无符号数字数组,其首地址在DI中,数组的第一个单元存放数组长度。要求在数组中查找(AX),如找到,CF=0,并在SI中给出该元素在数组中的偏移地址;如未找到,CF=1。,算法:在R数组中查找K,采用折半查找法 LOW1, HIGHN; 若LOWHIGH

13、,则查找失败,置CF=1,退出程序。否则,计算中点:MID(LOW+HIGH)/2; (3) K与RMID比较。若=RMID,则查找成功,程序结束; 若KRMID,则转(5); (4) HIGHMID-1,转(2); (5) LOWMID+1,转(2)。,22,CMP AX, ES:DI+2 ;与第一个数比较 JA CHK_LAST ;(AX)(ES:DI+2) 转 LEA SI, ES:DI+2 JE EXIT ;相等,找到,就是第一个数 STC ; 小于第一个数,失败 JMP EXIT CHK_LAST:MOV SI, ES:DI ;取数组长度 SHL SI, 1 ; 长度*2(DW型)

14、ADD SI, DI CMP AX, ES:SI ; 与最后的数比较 JB SEARCH ; 小于则转 JE EXIT ; 相等则结束 STC ; 大于最后一个,失败 JMP EXIT,23,SEARCH: MOV LOW_IDX, 1 ; 给LOW赋初值 MOV BX, ES:DI ; 取数组长度 MOV HIGH_IDX, BX ; 给HIGH赋初值 MOV BX, DI ; BX中放首地址 MID: MOV CX, LOW_IDX MOV DX, HIGH_IDX CMP CX, DX JA NO_MATCH ; LOWHIGH,失败 ADD CX, DX SHR CX, 1 ; 折半

15、MOV SI, CX SHL SI, 1 ; *2 (DW型) COMPARE:CMP AX, ES:BX+SI ; 与中间数比较 JE EXIT ; 相等,找到,24,JA HIGHER ; 大于中间数,转 DEC CX MOV HIGH_IDX, CX ; 调整查找区间到前半部分 JMP MID HIGHER: INC CX MOV LOW_IDX, CX ; 调整查找区间到后半部分 JMP MID NO_MATCH: STC EXIT: ,25,任务需要重复执行某一程序段,这种情况采用循环结构来实现。,初始化,循环体,初始化,修改部分,N,Y,Y,N,修改部分,控制部分,循环体,控制部分

16、,3.6 循环结构程序设计,3.6.1 循环指令 格式:指令码 标号; (CX中存放循环次数) 操作符 操 作 功 能 LOOP CX0,则循环 LOOPZ CX0且ZF=1,则循环 相等时循环 LOOPNZ CX0且ZF=0,则循环 不相等时循环,26,循环指令示例1 求长度为10的字节数组ARRAY之和,并将和存入TOTAL中,其中 语句 LOOP AGAIN 相当于: DEC CX JNZ AGAIN,LEA SI, ARRAY ;数组首地址-SI MOV CX, 10 ;数组长度-CX MOV AX, 0 AGAIN: ADD AL, SI ;求数组和 ADC AH, 0 INC SI

17、 ;修改指针 LOOP AGAIN MOV TOTAL, AX ;存和,27,SUB BX, DI ;串长度在BX中 INC BX MOV CX, BX ; 串字节数-CX DEC DI AGAIN: INC DI ;修改指针 CMP BYTE PTR DI, 0 ;串元素=0? LOOPZ AGAIN ;循环查找 JNZ FOUND ;找到非0字节跳转 FOUND:,循环指令示例2 在某一字节串中寻找第一个非0字节 设串首地址在DI中,串末地址在BX中,28,串存储器中一序列字或字节单元,单元中的内 容是字符或数据 串操作对序列字或字节单元中的内容进行某种 操作,串操作指令有7条: 1、MO

18、VS串传送指令 2、CMPS串比较指令 3、SCAS串扫描指令 4、LODS装入串指令 5、STOS存储串指令,6、INS串输入 7、OUTS串输出,3.6.2 串操作指令,29,与此配合使用的指令前缀有: REP 重复 REPE/REPZ 相等/为零则重复 REPNE/REPNZ 不相等/不为零则重复,说明: 每条指令有三种形式,分别对应于字节操作、 字操作和双字操作 如 MOVSB 字节操作 MOVSW 字操作 MOVSD 双字操作,30,例:将字节串从源区传送到目的区,源区首偏址-SI 目的区首偏址-DI,串长-CX,CX=0,按DI所指存此字节,按SI所指取一字节,(SI)+1-SI,

19、(DI)+1-DI,(CX)-1-CX,结束,Y,N,用一般传送指令实现 的流程图,31,源区首偏址-SI 目的区首偏址-DI 串长-CX,0-DF,CX=0,串传送指令,(CX)-1-CX,结束,源区首偏址-SI 目的区首偏址-DI 串长-CX,0-DF,带前缀REP的 串传送指令,Y,N,用串传送指令实现 的流程图,用带前缀的串传送指令实现的流程图,32,使用串操作指令时微处理器设计有若干约定:,1、源串地址由DS:SI指定 目的串地址在ES:DI中,2、串长送CX寄存器,3、设置方向标志位DF(在EFLAG寄存器中) 当DF=0(指令CLD)时地址为增量修改 (+1 或 +2 或 +4)

20、 当DF=1(指令STD)时地址为减量修改 (-1 或 2 或 -4),33,方向标志对应的指针移动示意 低地址方向 A . 源串 A J 高地址方向,目的串,源串,目的串,1,n,n,.,正向传送 反向传送 DF=0 DF=1,1,J,34,符号 功能 操作 相关前缀 MOVS 串传送 ES:DI-(DS:SI) REP SI-(SI)(+/-)1 DI-(DI)(+/-)1 CMPS 串比较 (DS:SI)-(ES:DI) REPZ/REPNZ SI-(SI)(+/-)1 DI-(DI)(+/-)1 SCAS 串扫描 (ES:DI)-(AL) REPZ/REPNZ DI-(DI)(+/-)

21、1 LODS 装入串 AL-(DS:SI) 一般不联用 SI-(SI)(+/-)1 STOS 存入串 (ES:DI)-(AL) REP DI-(DI)(+/-)1,35,符号 功能 操作 相关前缀 INS 串输入 ES:DI(DX) REP DI(DI)(+/-)1 OUTS 串输出 (DX)(DS:SI) REP SI(SI)(+/-)1,其中DX寄存器中存放的是接口电路的端口号,36,重复前缀 终止条件 否则 REP CX=0 CX-(CX)-1,继续 SI,DI指向下一元素 REPZ CX=0 或 ZF=0 CX-(CX)-1,继续 REPE SI,DI指向下一元素 串未结束且串相等时继

22、续 REPNZ CX=0 或 ZF=1 CX-(CX)-1,继续 REPNE SI,DI指向下一元素 串未结束且串不相等 时继续,37,例:REP MOVSB 传送过程如下: (1)(CX)=0? 若等于0,中止传送, 否则执行下一步 (2)CX(CX)-1 (3)串传送 (4)修改指针 (5)转到(1),38,MOVS指令示例 MOV SI, 0050H ; (DS)=2000H MOV DI, 0100H ; (ES)=3000H MOV CX, 5 CLD ; 地址递增方式 REP MOVSB 执行前 执行后 A 20050 00 30100 A 20050 30100 B 1 00 1

23、 B 1 1 C 2 00 2 C 2 2 D 3 00 3 D 3 3 E 4 00 4 E 4 4 F 5 00 5 F 5 5,源区 目的区 源区 目的区 SI=0050 DI=0100,A,B,C,D,E,SI=0055,DI=0105,39,CMPS指令示例 串String1和String2分别定义在数据段和附加段中。 比较两串,如相等则转移到标号NEXT处。,String1 DB HELP ;定义String1 String2 DB HEPP ;定义String2 CLD ;DF=0 LEA SI, String1 ;源串地址-SI LEA DI, String2 ;目的串地址-D

24、I MOV CX, 4 ;重复次数-CX REPZ CMPSB ;重复比较 JZ NEXT ;串相等转移 . NEXT:,40,SCAS指令示例 在串“That is CAI”中查找字符a,找到,则转到标号FOUND处,String DB That is CAI ;定义串 CLD ;DF=0 LEA DI, String ;串地址-DI MOV AL, a ;查找字符-AL MOV CX, 11 ;重复次数-CX REPNZ SCASB ;重复扫描 JZ FOUND ;找到目的串元素转移 FOUND:,41, LEA SI, SOURCE ;源串偏移量-SI LEA DI, DESTIN ;目

25、的串偏移量-DI CLD ;DF=0 MOV CX,100 ;重复比较次数-CX REPZ CMPSB ;重复串比较 JCXZ MATCH ;没有不匹配元素跳转 DEC SI ;指向不匹配元素 LODSB ;装入不匹配元素到AL . MATCH:,LODS指令示例 比较SOURCE和DESTIN (串长度为100个字节),并将串中的第一个不匹配元素装入AL寄存器中。,42,STOS指令示例 给首地址为BUF,长度为1000个字节的存储器区域清零。,BUFF DB 1000 DUP(?) ;定义缓冲区 CLD ;DF=0 LEA DI, BUFF ;缓冲区首地址-DI MOV CX, 1000

26、;重复次数 MOV AL, 0 ;0-AL REP STOSB ;重复存储串,43,综合应用例1 将存储区A到A+i中的数据传送到存储区B到B+i中,要求存放的顺序与原先的顺序相反。,A a +1 b +2 c A+i,B +1 +2 b B+i a,44,LEA SI, A LEA DI, B ADD DI, I ;DI指向存储区B的末尾 MOV CX, I+1 ;串的长度 LP: CLD ;DF=0 LODSB ;从源区取一数据 STD ;DF=1,改变方向 STOSB ;存入目的区 DEC CX JNZ LP,45,46,循环程序的组成: 1、初始化部分 设置初始值 2、循环工作部分 具

27、体的操作和运算 3、循环修改部分 为执行下一循环而修改某些参数 4、循环控制部分 判断循环继续还是结束,循环控制方法有: (1)计数控制法 增数法 减数法 (2)条件控制法,3.6.3 循环结构程序设计,47,单重循环程序设计 将以s1为起始地址的26个字母依次传送到以s2为起始地址的连续单元中。 数据定义如下: .DATA S1 DB ABCDXYZ .DATA ESTRA S2 DB 26 DUP(?),48,方法1 采用寄存器间接寻址方式 MOV AX, SEG S1 ;初始化部分 MOV DS, AX MOV AX, SEG S2 MOV ES, AX MOV SI, OFFSET S

28、1 MOV DI, OFFSET S2 MOV CX, 26 LOP1: MOV AL, SI ;工作部分 MOV ES:DI, AL INC SI ;修改部分 INC DI LOOP LOP1 ;控制部分,49,方法2 采用串处理指令 MOV AX, SEG S1 ;初始化部分 MOV DS, AX MOV AX, SEG S2 MOV ES, AX LEA SI, S1 LEA DI, S2 MOV CX, 26 CLD REP MOVSB ;工作、修改、控制合为一条指令,50,计数控制法 计数控制法适用于循环次数已知的场合,2、减数法 初始化时循环计数器置为循环次数,每执行一 次循环体后

29、计数器减1,并测试循环计数器是否为0, 如为0则终止循环。 减数法一般用循环指令形成循环回路。,1、增数法 初始化时循环计数器置0,每执行一次循环体后计数器加1,并与已知的循环次数比较,如相等则退出循环。 增数法一般用比较指令和条件转移指令实现循环转移。,51,NUM DW 1 ; . MOV CX,0 ;初始化 MOV AX,0 ROTATE: ADD AX, NUM ;累加 INC WORD PTRNUM INC CX ;计数器加1 CMP CX,50 ;与已知的循环次数比较 JNZ ROTATE MOV S, AX .,增数法 计算S=1+2+3+50, 结果存入AX中,如何做N阶乘N!

30、,52,减数法 将内存中6个十进制数的ASCII码转换为非压缩BCD码,并存放在后继相应单元中,如错,存放0FFH。,ASCBUF DB 35H, 38H, 30H, 4DH, 39H, 32H DB 6 DUP(?) . MOV DI OFFSET ASCBUF MOV CX, 6 LAB_1:MOV BL, 0FFH ; 设置错误标志 MOV AL, DI CMP AL, 3AH JNB OK ;大于等于3A则错 SUB AL, 30H JCOK ; 小于30H也错 MOV BL, AL,OK: MOV AL, BL MOV DI+06H, AL INC DI LOOP LAB1 .,53

31、,条件控制法 在许多情况下,事先无法确定循环次数,这时可选用“条件”来控制循环。在问题的求解过程中,找出一个终止循环的条件。 每循环一次,对条件进行一次检测,如满足终止循环的条件,便退出循环,否则继续循环。 利用条件转移指令控制循环是否结束。 有些情况下为防止死循环,可以附加一个合适的循环次数。,54,条件控制法 求字符串长度。从STRN地址开始有一个字符串,以$作为结束标志,长度不超过100个字节,要求统计该字符串长度并存于LENG单元。 分析:1)设DX存放统计的串长度,为防止程序死循环,可根据串长不超过100作为循环结束的附加条件。 2)如果程序运行过程中找到$则正常退出循环,如找不到$

32、,由于CX的初值为100,故不会使程序死循环。,定义数据段如下: .DATA STRN DB XCVFATTDEQJHI,$ LENG DB 0,55, MOV AX, 0 MOV DX, AX ; DX清零 LEA DI, STRN ; 串指针赋初值 MOV CX, 100 ; 初始值为100 MOV AL, $ LP: CMP AL, DI JE DONE ; 条件控制 INC DX ; 串长+1 INC DI; 串指针后移一个字节 LOOP LP; 附加条件 DONE: MOV LENG, DL; 存字符串长度 ,56,多重循环程序设计 多重循环就其本质而言,就是循环层1包含循环层2,循

33、环层2可能又包含循环层3,循环层1为最外层,内层循环是外层循环的循环体的一部分。,57,多重循环程序设计,如果多重循环都使用LOOP语句,则要保护好外层循环的计数器CX,通常采用压栈或退栈的方法或者转存的方法。,58,有一个首地址为A的N字数组,使该数组中的数从大到小排序,MOV CX, N DEC CX LOOP1: MOV DI, CX ; 暂存外循环计数值 MOV BX, 0 LOOP2: MOV AX, ABX CMP AX, ABX+2 ;比较a(i)与a(i+1) JGE COTINUE XCHG AX, ABX+2 ;交换 MOV ABX, AX COTINUE: ADD BX,

34、 2 LOOP LOOP2 MOV CX, DI ;恢复外循环计数值 LOOP LOOP1,冒泡排序法,59,3.7 子程序设计,子程序调用(返回)指令 过程定义伪指令 子程序的调用和返回 主程序与子程序的连接 子程序调用中的数据保护与恢复 主程序与子程序之间的参数传递 子程序嵌套与递归,3.7.1 子程序调用(返回)指令,格式1: CALL 子程序名 ;段内直接调用 操作1: SP-(SP)-2 (SP)+1,(SP)-(IP) IP-(IP)+disp16,格式2:CALL reg/mem ;段内间接调用 操作2:SP-(SP)-2 (SP)+1,(SP)-(IP) IP-(reg) 或

35、IP-(mem),说明:1)类似于段内无条件转移指令,不同的是需要将返回地址IP入栈 2)也可以在子程序名前使用near ptr 前缀,60,1)CALL 子程序调用指令,格式3:CALL FAR PTR 子程序名 ;段间直接调用 操作3:SP-(SP)-2 (SP)+1,(SP)-(CS) SP-(SP)-2 (SP)+1,(SP)-(IP) IP-子程序名对应的偏移量 CS-子程序所在的段地址,61,格式4:CALL DWORD PTR mem ;段间间接调用 操作4: SP-(SP)-2 (SP)+1,(SP)-(CS) IP-(SP)-2 (SP)+1,(SP)-(IP) IP-(EA

36、) CS-(EA+2),说明:段间调用须保存返回地址IP和CS 386及其后继机型,用EIP代替IP,62,2) RET 子程序返回指令 格式 功能 操作 RET 段内返回 IP-(SP)+1,(SP) SP-(SP)+2 RET 段间返回 IP-(SP)+1,(SP) SP-(SP)+2 CS-(SP)+1,(SP) SP-(SP)+2 RET EXP 带立即数返回 在上述操作之后再做 SP-(SP)+EXP,63,64,格式:过程名 PROC 属性 .; 过程体 RET .; 过程体 过程名 ENDP 说明: 1、过程名是该子程序名,也是指令CALL的目标操作数 2、过程的属性有两种:NE

37、AR和FAR,分别表示段内调用和段间调用。若省略,则默认为NEAR 3、至少有一条RET指令从过程中返回,可在过程中的任何位置,3.5.2 过程定义伪指令,65,主程序 子程序 SUB PROC . . . . . . CALL SUB . (断点) . . . . . RET,3.5.3 子程序的调用和返回,.CODE C_SEG MAIN PROC FAR ;主程序 . CALL SUB_A . MAIN ENDP SUB_A PROC NEAR ;子程序 . RET SUB_A ENDP END MAIN,3.5.4 主程序与子程序的连接,(1)主程序和子程序在同一代码段内,66,67,

38、;模块1 ;模块2 .CODE C_SEG1 .CODE C_SEG2 MAIN PROC FAR SUB_1 PROC FAR CALL FAR PTR SUB_1 RET RET SUB_1 ENDP MAIN END END SUB_1 END MAIN,(2)调用程序与子程序不在同一代码段内,示例 C1段 MAIN CALL FAR PTR PRO_A 0500:1000 C2段 PRO_A CALL NEAR PTR PRO_B 2000:2500 CALL NEAR PTR PRO_C 2000:3700 . RET,PRO_B CALL NEAR PTR PRO_C 2000:4

39、000 RET PRO_C RET,转1,转2,转3,68,2500 1000 0500 4000 2500 1000 0500,00FA,00F8,(4) PRO_B调用PRO_C之后,(3) PRO_A调用PRO_B之后,(1) MAIN调用PRO_A之前,(2) MAIN调用PRO_A之后,0100,SP,00FC,1000 0500,SP,转,69,(5) PRO_C返回PRO_B之后 SP 4000 2500 1000 0500 (6) PRO_B返回PRO_A之后 SP 4000 2500 1000 0500,00FA,00FC,00FA,4000 3700 1000 0500,(

40、7) PRO_A调用PRO_C之后,SP,转,70,(9) PRO_A返回MAIN之后 SP 4000 3700 1000 0500,0100,(8) PRO_C返回PRO_A之后,4000 3700 1000 0500,00FC,SP,转,71,72,利用程序段前缀退出程序的方法,使用DOS功能调用的4CH功能:MOV AH, 4CHINT 21H 使用INT 20H指令 利用程序段前缀法 将主程序设计成一个属性为FAR的过程,由DOS调用该过程执行,由RET指令返回DOS(利用程序段前缀的结构),72,73,操作系统加载EXE程序时自动在程序前加上256字节的程序段前缀,DS指向它,INT

41、 20H DS 程序段前缀区 程序区,程序加载结构,PUSH DS MOV AX,0 PUSH AX 把程序段前缀区第一个字节单元的地址和偏移量压栈保存,这个单元是指令INT 20H,这几句一定要放在主程序开始的位置 RET 指令 把程序段前缀区第一个字节单元的地址和偏移量弹出分别送IP和CS,转去执行INT 20H,从而实现返回DOS,使用程序段前缀 退出程序:,74,存储单元NUM中为一个16位的二进数,统计其中值为1 的位的个数存入RESULT .CODE . MAIN PROC FAR JZ DONE PUSH DS SAL AX, 1 MOV AX,0 JNC NEXT PUSH A

42、X INC CL MOV AX, D_SEG NEXT: JMP LOOP1 MOV DS, AX DONE: MOV RESULT, CL MOV CX,0 RET MOV AX, NUM MAIN ENDP LOOP1: AND AX, AX END MAIN 本程序采用的是用RET返回DOS的方法 循环结束条件是什么?采用这样的条件有什么好处?,75,为避免在主程序和子程序中使用相同的寄存器而引起的冲突,需要在子程序中对这些寄存器进行保护。在子程序返回前,恢复这些寄存器原来的值。 保护和恢复现场最佳的办法就是利用堆栈。 以下就是一个保护和恢复现场的例子: SUBT PROC NEAR P

43、USH AX ;保护现场 PUSH BX PUSH CX POP CX ;恢复现场 POP BX POP AX ; 注意弹出的顺序与压栈顺序相反 RET SUBT ENDP,3.5.5 子程序调用中的数据保护与恢复,76,定义一个过程,它的功能是将AL中的组合BCD码转为ASCII码,再存入BX寻址的连续的两个内存单元中。,TRAN PROC FAR PUSH AX PUSH BX PUSH CX PUSH DX MOV DL, AL MOV CL, 4 SHR AL, CL OR AL, 30H MOV BX, AL INC BX,MOV AL, DL AND AL, 0FH OR AL,

44、30H MOV BX, AL POP DX POP CX POP BX POP AX RET TRAN ENDP,教材上的例子请看P103的例3.21,77,参数传递的方法一般有三种: (1) 寄存器传送 将入口参数和出口参数放在约定的寄存器中 适用于参数个数较少的情况 (2) 存储单元传递 有直接存储单元传递和地址表传递两种方法 (3) 利用堆栈传递参数 应注意避免破坏断点,3.5.6 主程序与子程序之间的参数传递,78,寄存器传递参数示例1 十进制到十六进制数转换。从键盘取得一个十进制数,将其以十六进数形式显示出来。,调用DECIBIN,调用CRLF,调用BINIHEX,调用CRLF,从键

45、盘取得十进制数(小于65536),保存在BX,显示回车和换行,用十六进制形式显示BX中的数,79,主程序:,MAIN PROC FAR REPEAT: CALL DECIBIN CALL CRLF CALL BINIHEX CALL CRLF JMP REPEAT MAIN ENDP,80,DECIBIN PROC NEAR ;出口参数BX PUSH AX ;保护现场 PUSH CX MOV BX, 0 NEWCHAR: MOV AH, 1 INT 21H ;读键盘,输入的ASCII在AL中 SUB AL, 30H JL EXIT ;小于0转 CMP AL, 9 JG EXIT ;大于9转 C

46、BW ; 字节转成字 XCHG AX, BX MOV CX, 10 MUL CX ; 将以前的值乘以10 XCHG AX, BX ADD BX, AX ; 加这一次读的值 JMP NEWCHAR EXIT: POPCX;恢复现场 POPAX RET DECIBIN ENDP,功能:从键盘取得十进制数,保存在BX,81,BINIHEX PROC NEAR ;入口参数BX MOV CH, 4 ;循环4次(BX中有4位16进制数) ROTATE: MOV CL, 4 ROL BX, CL ; 循环左移四位,从最高位输出 MOV AL, BL AND AL, 0FH ADD AL, 30H CMP A

47、L, 3AH JL PRINTIT ;是0-9 ADD AL, 7 ;是A-F PRINTIT: MOV DL, AL MOV AH, 2 INT 21H ;显示(输出)DL中的一个字符 DEC CH JNZ ROTATE RET BINIHEX ENDP,功能:用十六进制形式显示BX中的数,82,CRLF PROC NEAR PUSH AX PUSH DX MOV DL, 0DH ;回车 MOV AH, 2 INT 21H ; 输出DL中的字符 MOV DL, 0AH ; 换行 MOV AH, 2 INT 21H ; 输出DL中的字符 POP DX POP AX RET CRLF ENDP,

48、功能:显示回车和换行,83,寄存器传递参数示例2 求数组元素之和。 .DATA ARRAY DB 10,20,30,5,60 COUNT EQU $-ARRAY ;数组元素个数 .STACK 100H .CODE START: . LEA SI, ARRAY ;参数准备 MOV CX, COUNT CALL SUM1 ;求和 ,84,;子程序:SUM1 ;入口参数:SI=数组首址,CX=数组长度 ;出口参数:AX=数组和 ;使用寄存器:AX, CX, SI SUM1 PROC NEAR CMP CX,0 JZ EXIT XOR AX, AX AGAIN: ADD AL, SI ADC AH,0 INC SI LOOP AGAIN EXIT: RET SUM1 ENDP,85,直接存储单元传送示例 求数组元素之和,结果送SUM单元 .DATA ARRAY DW 100 DUP(?) COUNT DW 100 SUM DW

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论