1 / 59

第 5 章

第 5 章. 基本结构程序设计. 程序的基本结构 程序的基本结构有三种:顺序结构、分支结构 和循环结构。 1) 顺序结构 顺序结构是最简单也是最基本的程序结构。 程序按顺序执行,不发生任何转移。. 语句 1. 语句 2. 。。。. 语句 n. 2) 分支结构 分支结构是指计算机根据实际情况或条件, 作出判断和选择,转而执行不同的程序段的 一种程序结构。. Y. N. N. 条件. 条件. Y. 程序段. 程序段 B. 程序段 A. 多路分支结构 根据某个控制字的各“位”状态实行多路转移.

elvis
Download Presentation

第 5 章

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. 第5章 基本结构程序设计

  2. 程序的基本结构 程序的基本结构有三种:顺序结构、分支结构 和循环结构。 1) 顺序结构 顺序结构是最简单也是最基本的程序结构。 程序按顺序执行,不发生任何转移。 语句1 语句2 . . 。。。 语句n

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

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

  5. 3) 循环结构 任务需要重复执行某一程序段,这种情况采 用循环结构来实现。 初始化 初始化 N 控制部分 循环体 Y 修改部分 循环体 N 控制部分 修改部分 Y

  6. 顺序结构程序设计 例5-1 两个32位无符号数乘法程序 例5-2压缩的BCD码转化成ASCII码 例5-3用直接查表法完成将键盘输入的一位10进数 (0—9)转换成对应的平方值并存放在SQRBUF 单元中

  7. [例5-1] 两个32位无符号数乘法程序 NUM1 DD 12345678H NUM2 DD 5A4BEF06H RESU DD 2 DUP(?) …… MOV EAX, NUM1 MUL NUM2 MOV RESU, EAX MOV RESU+4, EDX

  8. [例5-2]压缩的BCD码转化成ASCII码 BCD_BUF DB 96H ASC_BUF DB 2 DUP(?) BCD_BUF 96H ASC_BUF ‘9’ ‘6’ MOV AL, BCD_BUF MOV CL, 4 MOV BL, AL SHR AL, CL ADD AL, 30H MOV ASC_BUF, AL AND BL, 0FH ADD BL, 30H MOV ASC_BUF+1, BL .......

  9. [例5-3]用直接查表法完成将键盘输入的一位10进数[例5-3]用直接查表法完成将键盘输入的一位10进数 (0—9)转换成对应的平方值并存放在SQRBUF 单元中 SQUTAB DB 0,1,4,9,16,25,36,49,64,81 SQRBUF DB ? …… MOV BX, OFFSET SQUTAB MOV AH, 1 INT 21H SUB AL, 30H XLAT MOV SQRBUF, AL

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

  11. 单重循环程序设计 [例5-4]将以s1为起始地址的26个字母依次 传送到以s2为起始地址的连续单元中。 数据定义如下: DATA SEGMENT S1 DB ‘ABCD……XYZ’ DATA ENDS ESTRA SEGMENT S2 DB 26 DUP(?) ESTRA ENDS

  12. 方法1采用寄存器间接寻址方式 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 ;控制部分

  13. 方法2采用寄存器相对寻址方式 MOV SI, 0 ;初始化 MOV DI, 0 MOV CX, 26 LOP1: MOV AL, S1[SI] ;工作部分 MOV ES:S2[DI], AL INC SI ;修改部分 INC DI LOOP LOP1 ;控制部分

  14. 方法3采用基址变址寻址方式 MOV BX, OFFSET S1 MOV BP, OFFSET S2 MOV SI, 0 ;初始化 MOV DI, 0 MOV CX, 26 LOP1: MOV AL, [BX+SI] ;工作部分 MOV ES:[BP+DI], AL INC SI ;修改部分 INC DI LOOP LOP1 ;控制部分

  15. 方法4采用串处理指令 LEA SI, S1 LEA DI, S2 MOV CX, 26 CLD REP MOVSB

  16. 计数控制法 计数控制法适用于循环次数已知的场合 1、增数法 初始化时循环计数器置0,每执行一次循环体后 计数器加1,并与已知的循环次数比较,如相等则退 出循环。 增数法一般用比较指令和条件转移指令实现循环 转移。 2、减数法 初始化时循环计数器置为循环次数,每执行一 次循环体后计数器减1,并测试循环计数器是否为0, 如为0则终止循环。 减数法一般用循环指令形成循环回路。

  17. 增数法 [例5-5]计算S=1+2+3+···+50, 结果存入AX中 NUM DW 1 ...... MOV CX,0 ;初始化 MOV AX,0 ROTATE: ADD AX, NUM ;累加 INC WORD PTR[NUM] INC CX ;计数器加1 CMP CX,50 ;与已知的循环次数比较 JNZ ROTATE MOV S, AX ......

  18. 减数法 [例5-6]计算S=1+2+3+···+50, 结果存入AX中 NUM DW 1 ...... MOV CX, 50 ;初始化 MOV AX, 0 ADD_1: ADD AX, NUM INC WORD PTR[NUM] LOOP ADD_1;循环求和 MOV S, AX ......

  19. 条件控制法 在许多情况下,事先无法确定循环次数,这时可选用“条件”来控制循环。在问题的求解过程中,找出一个终止循环的条件。 每循环一次,对条件进行一次检测,如满足终止循环的条件,便退出循环,否则继续循环。 利用条件转移指令控制循环是否结束

  20. 条件控制法 [例5-7] 在ADDR单元中存放着数Y的地址,编程把Y中1的个数 存入COUNT单元中。 分析:要统计Y中1的个数,需逐位测试 条件: 用测试数是否为0作为结束条件 定义数据段如下: DATA SEGMENT ADDR DW NUMBER NUMBER DW Y COUNT DW ? DATA ENDS

  21. MOV CX, 0 MOV BX, ADDR MOV AX, [BX] ;AX(Y) REPEAT: TEST AX, 0FFFFH JZ EXIT JNS SHIFT INC CX SHIFT: SHL AX, 1 JMP REPEAT EXIT: MOV COUNT, CX

  22. 逻辑尺控制法 逻辑尺----是由若干有明确意义的二进制位 组成的控制字。 控制字中每一个二进制位对应一次循环,每次循环允许 做不同的事。 控制字的长度根据问题的需要而定。(一个字节、一个字 或几个连续的存储单元) 逻辑尺控制法一般用在多次循环过程分别完成不同操作 的程序中。

  23. [例5-8]已知数据段中有两个长度为8的字节 数组X和Y, 希望编程计算: Z1=X1+Y1 Z2=X2+Y2 Z3=X3-Y3 Z4=X4-Y4 Z5=X5-Y5 Z6=X6+Y6 Z7=X7-Y7 Z8=X8-Y8 Z9=X+Y9 Z10=X10+Y10 分析: 以二进制位0表示加法,1表示减法。将Z1—Z10的10种选择 对应的“0”、“1”组成逻辑尺0000000011011100B (从右到左)。程序中,可用右移指令把逻辑尺的各位 移入CF标志,经分析CF状态完成相应的运算。 定义数据段如下: D_SEG SEGMENT X DB X1,X2,X3,X4,X5,X6,X7,X8,X9,X10 Y DB Y1,Y2,Y3,Y4,Y5,Y6,Y7,Y8,Y9,Y10 Z DB Z1,Z2,Z3,Z4,Z5,Z6,Z7,Z8,Z9,Z10 RULE DB 00DCH D_SEG ENDS

  24. 程序段如下: ...... MOV CX, 10 MOV BX, 0 MOV DX, RULE NEXT: MOV AX, X[BX] ;读取X数组元素 SHR DX,1 JC SUBTRACT ADD AX, Y[BX] ;XI+YI JMP RESULT SUBTRACT: SUB AX,Y[BX] ;XI-YI RESULT: MOV Z[SI], AX ;计算结果 ADD BX, 2 LOOP NEXT ......

  25. [例5-9]将正数N插入一个升序的字数组中, 数组的首地址和末地址为 A_HEAD和A_END X DW ? A_HEAD DW 3,5,23,49,52,65 A_END DW 105 N DW 32 X 3 A_HEAD 5 23 49 52 65 105 A_END 32

  26. MOV AX, N MOV A_HEAD-2, -1 MOV SI, 0 COMPARE:CMP A_END[SI], AX ;从最后一个元素开始比较 JLE INSERT MOV BX, A_END[SI] MOV A_END[SI+2], BX ;后移一个元素 SUB SI, 2 JMP COMPARE INSERT: MOV A_END[SI+2], AX ;插入 .....

  27. [例5-10]附加段中有一个首地址为 LIST的字数组,数组的第一 字中存放该数组长度,数组 首地址在DI中,数X在AX中, 现要在数组中查找X,若找 到则删除。

  28. CLD PUSH DI MOV CX, ES:[DI] ;数组长度送CX ADD DI, 2 ;DI指向第一个元素 REPNE SCASW;串扫描 JE DELETE ;如找到则删除 POP DI ;否则,退出 JMP EXIT DELET: JCXZ DEC_CNT;若CX=0,X为最后一个元素 NEXT_EL: MOV BX, ES:[DI] MOV ES:[DI-2], BX ;向前移动一个元素 ADD DI, 2 LOOP NEXT_EL DEC_CNT: POP DI DEC WORD PTR ES:[DI] ;数组元素个数减1 EXIT: ......

  29. [例5-11]从键盘输入一行字符,要求第1个字符必须是空格,如不是,则退出程序;如是,则接收键入的字符并顺序存放在首地址为的缓冲区中(空格不存),直到接收第2个空格为止。[例5-11]从键盘输入一行字符,要求第1个字符必须是空格,如不是,则退出程序;如是,则接收键入的字符并顺序存放在首地址为的缓冲区中(空格不存),直到接收第2个空格为止。 初始化首地址 置FLAG为0 接收一个字符 修改地址 N 存入缓冲区 是第1个字符 N Y 是空格 置FLAG为1 Y Y 是空格 N

  30. LEA BX, BUFFER MOV FLAG, 0 NEXT: MOV AH, 1 INT 21H TEST FLAG, 01H JNZ FOLLOW CMP AL, 20H JNZ EXIT MOV FLAG, 1 JMP NEXT FOLLOW: CMP AL, 20H JZ EXIT MOV [BX], AL INC BX JMP NEXT EXIT:

  31. 多重循环程序设计 多重循环就其本质而言,就是循环层1 包含循环层2,循环层2可能又包含循环 层3...循环层1位最外层,内层循环是外层 循环的循环体的一部分.

  32. 多重循环程序设计

  33. [例5-12] 有一个首地址为A的N字数组,使该数组中 的数从大到小排序 MOV CX, N DEC CX LOOP1: MOV DI, CX MOV BX, 0 LOOP2: MOV AX, A[BX] CMP AX, A[BX+2] ;比较a(i)与a(i+1) JGE COTINUE XCHG AX, A[BX+2] ;交换 MOV A[BX], AX COTINUE: ADD BX, 2 LOOP LOOP2 MOV CX, DI LOOP LOOP1

  34. [例5-13] 在附加段中有一个字数组,其首地址已存放在DI 寄存器中,数组的第一个字中存放该数组的长度。使数组中的数从小到大排序。 MOV START_ADDR, DI MOV CX, ES:[DI] ;数组长度 MOV SAVE_CNT, CX INIT: MOV BX, 1;交换标志置1 DEC SAVE_CNT JZ SORTED MOV CX, SAVE_CNT MOV DI, START_ADDR

  35. NEXT: ADD DI, 2 MOV AX, ES:[DI] CMP ES:[DI+2], AX ;比较a(i+1)与a(i) JAE CONT XCHG ES:[DI+2], AX ;交换 MOV ES:[DI], AX SUB BX, BX;交换标志置0 CONT: LOOP NEXT CMP BX, 0 JE INIT SORTED: MOV DI, START_ADDR

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

  37. 利用比较和条件转移指令实现程序分支 [例5-14]变量X为一任意有符号字节数, 若X为负数,则将其取补码; 否则,和Y相加,其和存入AX中. ...... MOV AL, X CMP AL, 0 JGE ADDT NEG AL ;X求补 MOV X,AL JMP EXIT ADDT:ADD AL,Y ;X+Y ADC AH,0 EXIT: Y X>=0 X<--X取补 AX<--X+Y

  38. [例5-15]设字节单元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)

  39. 程序如下: MOV AL, N1 MOV AH, N2 TEST AL, 01H ;测试 N1的奇偶 JNE ENDO TEST AH, 01H ;测试 N2的奇偶 JNE L1 ;是奇数,转移 INC AL ;两个均是偶数 INC AH JMP ENDO L1: XCHG AL, AH ;N1是偶数, N2是奇数 ENDO: MOV D1, AL ;存放结果 MOV D2, AH

  40. 利用跳转表实现多路分支 跳转表是在某一内存区域顺序排列的一组 有规律的入口地址。 如是段内分支,每个地址占两个单元(IP的值) 如是段间分支,每个地址占4个单元(CS:IP的值) . TABLE SUB1 TABLE SUB1 SUB2 SUB3 SUB2 IP IP IP CS IP IP CS 段内转移 段间转移

  41. [例5-16]根据AL中哪一位为1(从低位到 高位)把程序转移到8个不同的 程序分支去 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

  42. 方法1 用变址寻址方式 CMP AL, 0 JE DONE MOV SI, 0 L: SHR AL, 1 JNB NOT_YET JMP TABLE[SI] NOT_YET: ADD SI, TYPE TABLE JMP L DONE: ……

  43. 方法2 用寄存器间接寻址方式 CMP AL, 0 JE DONE LEA BX, TABLE L: SHR AL, 1 JNB NOT_YET JMP WORD PTR[BX] NOT_YET: ADD SI, TYPE TABLE JMP L DONE: ……

  44. 方法3 用基址变址寻址方式 CMP AL, 0 JE DONE LEA BX, TABLE MOV SI, 7*TYPE TABLE MOV CX, 8 L: SHL AL, 1 JNB NOT_YET JMP WORD PTR[BX][SI] NOT_YET: SUB SI, TYPE TABLE JMP L DONE: ……

  45. [例5-17] 在附加段中有一个从小到大排序的无符号数数组,其首地址在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)。

  46. ;折半查找 CMP AX, ES:[DI+2] JA CHK_LAST LEA SI, ES:[DI+2] JE EXIT STC JMP EXIT CHK_LAST: MOV SI, ES:[DI] SHL SI, 1 ADD SI, DI CMP AX, ES:[SI] JB SEARCH JE EXIT STC JMP EXIT

  47. SEARCH: MOV LOW_IDX, 1 MOV BX, ES:[DI] MOV HIGH_IDX, BX MOV BX, DI MID: MOV CX, LOW_IDX MOV DX, HIGH_IDX CMP CX, DX JA NO_MATCH ADD CX, DX SHR CX, 1 MOV SI, CX COMPARE:CMP AX, ES:[BX+SI] JE EXIT JA HIGHER

  48. DEC CX MOV HIGH_IDX, CX JMP MID HIGHER: INC CX MOV LOW_IDX, CX JMP MID NO_MATCH: STC EXIT: ……

  49. 在实模式下发挥及其后继机的优势 1、利用高档机32位字长特性 [例5-18] 有两个4字长数分别存放在DATA1和DATA2中, 求它们的和,结果存放于DATA3中。 DATA1 DQ 123456789ABCDEFH DATA2 DQ 0FEDCBA987654321H DATA3 DQ ?

  50. 8086中实现: CLC LEA SI, DATA1 LEA DI, DATA2 LEA BX, DATA3 MOV CX, 4 BACK: MOV AX, [SI] ADC AX, [DI] MOV [BX], AX INC SI INC SI INC DI INC DI INC BX INC BX LOOP BACK

More Related