1 / 94

第 3 章 80x86 汇编语言程序设计 ( 下 )

第 3 章 80x86 汇编语言程序设计 ( 下 ). 3.5 分支结构程序设计. 分支结构是指计算机根据实际情况或条件,作出判断和选择,转而执行不同的程序段的一种程序结构。. Y. N. N. 条件. 条件. Y. 程序段. 程序段 B. 程序段 A. 多路分支结构 根据某个控制字的各“位”状态实行多路转移. 多路条件测试. ……. 程序段 2. 程序段 1. 程序段 n. 3.5.1 无条件转移指令 JMP. 1、 段内转移. 格式1: JMP SHORT OPR ;段内相对短转移

chibale
Download Presentation

第 3 章 80x86 汇编语言程序设计 ( 下 )

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 第3章 80x86汇编语言程序设计(下)

  2. 3.5 分支结构程序设计 分支结构是指计算机根据实际情况或条件,作出判断和选择,转而执行不同的程序段的一种程序结构。 Y N N 条件 条件 Y 程序段 程序段B 程序段A

  3. 多路分支结构 根据某个控制字的各“位”状态实行多路转移 多路条件测试 …… 程序段2 程序段1 程序段n

  4. 3.5.1无条件转移指令 JMP 1、段内转移 格式1:JMP SHORT OPR;段内相对短转移 操作1:IP<--(IP)+disp8 说明:转移范围-128字节至+127字节,操作数OPR为段内某个标号。 段内相对短转移示例 指令JMP SHORT ADDT 存放在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

  5. 格式2:JMP OPR JMP NEAR PTR OPR;段内相对近转移 操作2:IP<--(IP)+disp16 说明:转移范围-32KB至+32KB, 操作数OPR为段内某个标号。 格式3:JMP WORD PTR OPR;段内间接转移 操作3:IP<--(OPR) 说明:OPR是基址/变址寄存器或存储器操作数。 段内间接转移示例 ADDRESS DW 2000H ;定义转移地址 ... LEA SI, ADDRESS ;偏移量-->SI ... JMP WORD PTR[SI];转移到CS:2000

  6. 2、段间转移 格式4:JMP FAR PTR OPR;段间直接转移 操作4:IP<--OAopr CS<--(CS)opr C1段 EA OP码 段间直接转移示例 50 新IP=0250H ;代码段C1 02 …… 00 新CS=2000H JMP FAR PTR NEXT 20 …… ;代码段C2 C2段 20000H …… NEXT: MOV AL,10H … NEXT 20250H

  7. 格式5:JMP DWORD PTR OPR;段间间接转移 操作5:IP<--((DS)*16+OPR) CS<--((DS)*16+OPR+2) 段间间接转移示例 JMP DWORD PTR [4000H] 设(DS)=1000H (14000H)=0010H (14002H)=5000H 执行后 (CS)=5000H (IP)=0010H

  8. 3.5.2 条件转移指令 格式:J条件 标号 操作:测试条件,若满足,则跳转到标号处执行, 即 IP<--(IP)+disp8 ; 否则,执行后续指令 说明:根据上一条指令所设置的条件码判别测试条件 转移范围在-128到+127字节

  9. 条件转移指令(1) 操作符 功能 测试条件 JC 进位标志为1转移 CF=1 JNC 进位标志为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

  10. 条件转移指令(2) A-B 比较情况 无符号数 有符号数 指令 判断条件 指令 判断条件 A>B JA ZF=0,CF=0 JG SF=OF JNBE JNLE 且ZF=0 A>=B JAE ZF=1或 JGE SF=OF JNB CF=0 JNL 或ZF=1 A<B JB ZF=0,CF=1 JL SF<>OF JNAE JNGE 且ZF=0 A<=B JBE ZF=1或 JLE SF<>OF JNA CF=1 JNG 或ZF=1

  11. 条件转移指令示例1 将X中十六进制的ASCII码转换成其所对应的数值,存放到HEX中。如‘A’应转换为10。 注意ASCII中‘0’~‘9’是30H~39H,’A’~’F’是41H~46H MOV AH, X CMP AH, 39H JBE NEXT ;≤39H则转 SUB AH, 7 ;是‘A’--’F’,减7 NEXT: SUB AH, 30H ;减30H MOV HEX, AH

  12. 条件转移指令示例2 CMP AX, 0FFFFH JLE P3 CMP AX,1 JL P2 MOV AX, 1 JMP DONE P2: MOV AX, 0 JMP DONE P3: MOV AX,-1 DONE: Y AX≤(-1) N N Y AX<1 AX<--1 AX<--0 AX<--(-1) 如果条件转移目标地址超出-128~+127的范围怎么办?

  13. 3.5.3 分支结构程序设计 1、比较/转移 利用比较和条件转移指令实现两路分支。 比较结果记录在某些标志位中,条件转移指令 根据约定的条件进行对照,满足条件时转移,不满 足条件时不转移。 2、跳转表转移 利用跳转表实现多路分支。 比较/转移指令可嵌套,但程序结构复杂, 跳转表可使程序结构清晰。 教材上的例子请看P99中的例3.18和例3.19,上机实现例3.18程序。

  14. 有一个首地址为ARRAY的N字数组,将其中正数的个数放在DI中,0的个数放在SI中,负数个数放在AX中有一个首地址为ARRAY的N字数组,将其中正数的个数放在DI中,0的个数放在SI中,负数个数放在AX中 注意:负数个数=N-DI-SI

  15. MOV CX, N MOV BX, 0 ;初始化 MOV DI, BX ; 正数个数计数器初始化 MOV SI, BX ; 0的个数计数器初始化 AGAIN:CMP WORRD PTR ARRAY[BX], 0 ;数组当前元素与0比较 JLE LEEQ;小于等于0转移 INC DI ;正数计数 JMP NEXT LEEQ: JL NEXT;小于0转移 INC SI ;0计数 NEXT: ADD BX, 2 ;数组表指针指向下一元素 DEC CX JNZ AGAIN MOV AX, N ;负数个数=N-DI-SI SUB AX, DI SUB AX, SI

  16. 设字节单元N1、N2中存放无符号数 (1)若两个均是偶数,则分别加1后送D1 、D2中 (2)若两个均是奇数,则直接送D1 、D2中 (3)若一个是奇数,一个是偶数,则把奇数送D1,偶数送D2中 AL<--(N1),AH<--(N2) 注意:根据条件,当N1是奇数时,无论N2是奇数还是偶数,都只需直接送D1、D2 偶 奇 (AL)0=0 偶 奇 (AH)0=0 (AL) (AH) AL<--(AL)+1 AH<--(AH)+1 D1<--(AL),D2<--(AH)

  17. 程序如下: 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的值) TABLE SUB1 TABLE SUB1 SUB2 SUB3 SUB2 IP IP IP CS IP IP CS 段内转移 段间转移

  19. 根据AL中哪一位为1(从低位到高位)把程序转移到8个不同的程序分支去根据AL中哪一位为1(从低位到高位)把程序转移到8个不同的程序分支去 .CODE …… ROUTINE_1: MOV AX,0 …… ROUTINE_2: CMP AL, 3 …… …… ROUTINE_8: CLI .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

  20. 用变址寻址方式 CMP AL, 0 JE DONE MOV SI, 0 L: SHR AL, 1 JNB NOT_YET ; CF=0或ZF=1跳转 JMP TABLE[SI] NOT_YET: JZ DONE ADD SI, TYPE TABLE ;Type Table=2 JMP L DONE: …… 用寄存器间接寻址与基址变址寻址该如何做?

  21. 在附加段中有一个从小到大排序的无符号数字数组,其首地址在DI中,数组的第一个单元存放数组长度。要求在数组中查找(AX),如找到,CF=0,并在SI中给出该元素在数组中的偏移地址;如未找到,CF=1。在附加段中有一个从小到大排序的无符号数字数组,其首地址在DI中,数组的第一个单元存放数组长度。要求在数组中查找(AX),如找到,CF=0,并在SI中给出该元素在数组中的偏移地址;如未找到,CF=1。 • 算法:在R数组中查找K,采用折半查找法 • LOW1, HIGHN; • 若LOW>HIGH,则查找失败,置CF=1,退出程序。否则,计算中点:MID(LOW+HIGH)/2; • (3) K与R[MID]比较。若=R[MID],则查找成功,程序结束; • 若K<R[MID]则转(4);若K>R[MID],则转(5); • (4) HIGHMID-1,转(2); • (5) LOWMID+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型) 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 ; LOW>HIGH,失败 ADD CX, DX SHR CX, 1 ; 折半 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. 3.6 循环结构程序设计 任务需要重复执行某一程序段,这种情况采用循环结构来实现。 初始化 初始化 N 控制部分 循环体 Y 修改部分 循环体 N 控制部分 修改部分 Y

  26. 3.6.1 循环指令 格式:指令码 标号; (CX中存放循环次数) 操作符 操 作 功 能 LOOP CX<--(CX)-1 循环 若(CX)<>0,则循环 LOOPZ CX<--(CX)-1 当CX不为零且 LOOPE 若(CX)<>0且ZF=1,则循环 相等时循环 LOOPNZ CX<--(CX)-1 当CX不为零且 LOOPNE 若(CX)<>0且ZF=0,则循环 不相等时循环

  27. 循环指令示例1 求长度为10的字节数组ARRAY之和,并将和存入TOTAL中 LEA SI, ARRAY ;数组首地址-->SI MOV CX, 10 ;数组长度-->CX MOV AX, 0 AGAIN: ADD AL, [SI] ;求数组和 ADC AH, 0 INC SI ;修改指针 LOOP AGAIN MOV TOTAL, AX ;存和 其中 语句 LOOP AGAIN相当于: DEC CX JNZ AGAIN

  28. 循环指令示例2 在某一字节串中寻找第一个非0字节 设串首地址在DI中,串末地址在BX中 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:

  29. 3.6.2 串操作指令 串——存储器中一序列字或字节单元,单元中的内 容是字符或数据 串操作——对序列字或字节单元中的内容进行某种 操作 串操作指令有7条: 1、MOVS——串传送指令 2、CMPS——串比较指令 3、SCAS——串扫描指令 4、LODS——装入串指令 5、STOS——存储串指令 6、INS——串输入 7、OUTS——串输出

  30. 说明: 每条指令有三种形式,分别对应于字节操作、 字操作和双字操作 如 MOVSB 字节操作 MOVSW 字操作 MOVSD 双字操作 与此配合使用的指令前缀有: REP 重复 REPE/REPZ 相等/为零则重复 REPNE/REPNZ 不相等/不为零则重复

  31. 例:将字节串从源区传送到目的区 源区首偏址-->SI 目的区首偏址-->DI,串长-->CX Y CX=0 N 结束 按SI所指取一字节 按DI所指存此字节 (SI)+1-->SI 用一般传送指令实现 的流程图 (DI)+1-->DI (CX)-1-->CX

  32. 源区首偏址-->SI 目的区首偏址-->DI 串长-->CX,0-->DF Y 源区首偏址-->SI 目的区首偏址-->DI 串长-->CX,0-->DF CX=0 N 串传送指令 结束 带前缀REP的 串传送指令 (CX)-1-->CX 用带前缀的串传送指令实现的流程图 用串传送指令实现 的流程图

  33. 使用串操作指令时微处理器设计有若干约定: 1、源串地址由DS:SI指定 目的串地址在ES:DI中 2、串长送CX寄存器 3、设置方向标志位DF(在EFLAG寄存器中) 当DF=0(指令CLD)时地址为增量修改 (+1 或 +2 或 +4) 当DF=1(指令STD)时地址为减量修改 (-1 或 –2 或 -4)

  34. 方向标志对应的指针移动示意 低地址方向 ‘A’ ... 源串 ‘A’ ‘J’ … 高地址方向 1 n 源串 n 1 ‘J’ ... 目的串 … 目的串 正向传送 反向传送 DF=0 DF=1

  35. 符号 功能 操作 相关前缀 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)(+/-)1 LODS 装入串 AL<--(DS:SI) 一般不联用 SI<--(SI)(+/-)1 STOS 存入串 (ES:DI)<--(AL) REP DI<--(DI)(+/-)1

  36. 符号 功能 操作 相关前缀 INS 串输入 ES:DI((DX)) REP DI(DI)(+/-)1 OUTS 串输出 ((DX))(DS:SI) REP SI(SI)(+/-)1 其中DX寄存器中存放的是接口电路的端口号

  37. 重复前缀 终止条件 否则 REP CX=0 CX<--(CX)-1,继续 SI,DI指向下一元素 REPZ CX=0 或 ZF=0 CX<--(CX)-1,继续 REPE SI,DI指向下一元素 串未结束且串相等时继续 REPNZ CX=0 或 ZF=1 CX<--(CX)-1,继续 REPNE SI,DI指向下一元素 串未结束且串不相等 时继续

  38. 例:REP MOVSB 传送过程如下: (1)(CX)=0? 若等于0,中止传送, 否则执行下一步 (2)CX(CX)-1 (3)串传送 (4)修改指针 (5)转到(1)

  39. 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 ‘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 ‘A’ ‘B’ ‘C’ ‘D’ ‘E’ 源区 目的区 源区 目的区 SI=0050 DI=0100 SI=0055 DI=0105

  40. CMPS指令示例 串String1和String2分别定义在数据段和附加段中。 比较两串,如相等则转移到标号NEXT处。 String1 DB ‘HELP’ ;定义String1 String2 DB ‘HEPP’ ;定义String2 …… CLD ;DF=0 LEA SI, String1 ;源串地址-->SI LEA DI, String2 ;目的串地址-->DI MOV CX, 4 ;重复次数-->CX REPZ CMPSB;重复比较 JZ NEXT ;串相等转移 .... NEXT:

  41. 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:

  42. LODS指令示例 比较SOURCE和DESTIN (串长度为100个字节),并将串中的第一个不匹配元素装入AL寄存器中。 …… LEA SI, SOURCE ;源串偏移量-->SI LEA DI, DESTIN ;目的串偏移量-->DI CLD ;DF=0 MOV CX,100 ;重复比较次数-->CX REPZ CMPSB;重复串比较 JCXZ MATCH ;没有不匹配元素跳转 DEC SI ;指向不匹配元素 LODSB;装入不匹配元素到AL ... MATCH:

  43. STOS指令示例 给首地址为BUF,长度为1000个字节的存储器区域清零。 BUFF DB 1000 DUP(?) ;定义缓冲区 …… CLD ;DF=0 LEA DI, BUFF ;缓冲区首地址-->DI MOV CX, 1000 ;重复次数 MOV AL, 0 ;0-->AL REP STOSB;重复存储串

  44. 综合应用例1 将存储区A到A+i中的数据传送到存储区B到B+i中,要求存放的顺序与原先的顺序相反。 B +1 +2 ‘b’ B+i ‘a’ A ‘a’ +1 ‘b’ +2 ‘c’ A+i

  45. 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

  46. 3.6.3 循环结构程序设计 循环程序的组成: 1、初始化部分 设置初始值 2、循环工作部分 具体的操作和运算 3、循环修改部分 为执行下一循环而修改某些参数 4、循环控制部分 判断循环继续还是结束 循环控制方法有: (1)计数控制法 增数法 减数法 (2)条件控制法

  47. 单重循环程序设计 将以s1为起始地址的26个字母依次传送到以s2为起始地址的连续单元中。 数据定义如下: .DATA S1 DB ‘ABCD……XYZ’ .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 S1 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. 计数控制法 计数控制法适用于循环次数已知的场合 1、增数法 初始化时循环计数器置0,每执行一次循环体后计数器加1,并与已知的循环次数比较,如相等则退出循环。 增数法一般用比较指令和条件转移指令实现循环转移。 2、减数法 初始化时循环计数器置为循环次数,每执行一 次循环体后计数器减1,并测试循环计数器是否为0, 如为0则终止循环。 减数法一般用循环指令形成循环回路。

More Related