1 / 73

程序设计方法

S 1. S2. S3. 程序设计方法. 一、顺序结构. 顺序结构:程序顺序执行。. TABLE. 置 DS,SS 寄存器 置 SP 和表指针. 00. 01. 04. 显示提示字符串. 09. 10. 键盘输入数→ AL. 19. 24. 查表 平方值→ AL. 31. 40. 返回 DOS. 51. 例 1 内存中 TABLE 开始存放0~9的平方值,通过人机对话,当任给一个数 X(0 ~ 9) , 查得 X 的平方值,放在 AL 中。. 数据段说明 堆栈段说明. DATA SEGMENT.

amena
Download Presentation

程序设计方法

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. S 1 S2 S3 程序设计方法 一、顺序结构 顺序结构:程序顺序执行。

  2. TABLE 置DS,SS寄存器 置SP和表指针 00 01 04 显示提示字符串 09 10 键盘输入数→AL 19 24 查表 平方值→AL 31 40 返回DOS 51 例1 内存中TABLE开始存放0~9的平方值,通过人机对话,当任给一个数X(0~9),查得X的平方值,放在AL中。 数据段说明 堆栈段说明

  3. DATA SEGMENT TABLE DB 0,1,4,9,16,25,36,49,64,81 BUF DB ‘ Please input one number (0~9):’ DB 0DH,0AH,’$’ DATA ENDS STACK SEGMENT PARA STACK ‘ STACK’ DB 50 DUP (?) TOP LABLE WORD STACK ENDS 数据段说明 堆栈段说明

  4. CODE SEGMENT MAIN PROC FAR ASSUME CS:CODE,DS:DATA,SS:STACK START:MOV AX,DATA 程序段说明 MOV DS,AX MOV AX,STACK MOV SS,AX 置DS,SS寄存器 置SP和表指针 MOV SP,OFFSET TOP MOV BX,OFFSET TABLE 显示提示字符串 NEXT: MOV DX,OFFSET BUF MOV AH,9 INT 21H

  5. MOV AH,1 INT 21H MOV AH,0 AND AL,0FH ADD BX,AX MOV AL,[BX] MOV AH,4CH INT 21H RET MAIN ENDP CODE ENDS END START

  6. 逐个检查 数字 字母 其它 统计 统计 统计 二、分支结构 例2 存储器中有一串字符串,首地址为BUF,字符串长度N在BUF中(小于256),随后是字符串数据。要求分别计算其中数字’0’~’9’,字母’A’~’Z’和其它字符的个数,并分别将它们的个数存放到此字符串后的三个单元中。

  7. 初始化 LP 取待检查数→AH Y <‘ 0 ’ Y ABC >‘ 9 ’ Y <‘ A ’ Y >‘ Z ’ (DH)+1 →DH (DL)+1 →DL NEXT (BX)+1 →BX DH:数字数 N (CH)-1 →CH=0 DL:字母数 其它字符数= 送数字数、字母数 串长-(DH)-(DL) 送其它字符数 结束

  8. DATA SEGMENT 数据段定义 BUF DB 20 DB 01H,38H,47H,60H,…,76H 堆栈段定义 NUM DB 3 DUP (?) DATA ENDS 原数据段地址 入栈保护 CODE SEGMENT MAIN PROC FAR ASSUM CS:CODE,DS:DATA START:PUSH DS 置DS段寄存器 SUB AX,AX PUSH AX MOV AX,DATA 数组长度→CH 数组地址1 →BX 字的个数0→DH 字母个数0→DL MOV DS,AX MOV CH,BUF MOV BX,1 MOV DX,0 初始化

  9. CMP AH,30H JL NEXT CMP AH,39H JG ABC INC DH JUMP NEXT ABC: CMP AH,41H JL NEXT CMP AH,5AH JG NEXT LP: MOV AH,BUF [BX] INC DL

  10. DEC CH JNZ LP MOV BUF[BX],DH MOV BUF[BX+1],DL MOV AH,BUF SUB AH,DH SUB AH,DL MOV BUF[BX+2],AH RET MAIN ENDP CODE ENDS END START NEXT:INC BX

  11. P0低地址 BASE MOV AH,1 P0高地址 INT 21H ;从键盘输入命令 BASE+2 P1低地址 AND AL,0FH;ASCII→数字 P1高地址 MOV BX,OFFSET BASE … … ;取跳转表首地址 MOV AH,0 ADD AL,AL;数字乘 2 ADD BX,AX ;求表地址 BASE+14 P7低地址 JMP WORD PTR [BX] P7高地址 ;转入相应子程序 例3 有8个加工子程序,入口地址分别为P0、P1、…P7。用跳转表实现多分支结构的方法,检测键盘输入命令,使系统分别转向8 个加工子程序。 跳转表 以BASE为首地址的内存中依次存放8个子程序的首地址。

  12. ZF=1 ZF=0 删除M 后者依次上移 数组长度-1 添M 后者依次下移 数组长度+1 例4 设首地址为BUFFER的升序数组,数组的长度为N(=10),在该数组中查找数M(=80),若找到它则从数组中删除,若找不到将它插入正确的排序位置,DX中记录数组最后的长度。 REPNE SCASW

  13. BUF 5 10 25 28 N-1 30 43 53 77 79 80 找到 ZF=1,关键字在串尾(CX)=0 删除M 数组长度-1 DEC DX ;串长度-1

  14. DEL1: MOV BX,[DI] MOV [DI-2] , BX ADD DI,2 LOOP DEL1 NEXT:DEC DX BUF BUF 5 5 BUF 5 10 10 10 32 32 32 47 47 47 BUF 5 53 53 53 (DI)-2→ 10 80 89 89 (DI)→ (DI)→ 32 89 89 106 BX 47 106 106 115 53 115 115 124 89 124 124 124 (DI)-2→ 106 N-1 106 (DI)→ 115 BX 124 找到 ZF=1,关键字在串中间 删除M 后者依次上移 数组长度-1

  15. BUF BUF 5 BUF 5 5 10 10 10 32 32 32 47 47 47 53 53 53 (SI)→ 77 77 80>77 77 (SI+2)→ 89 89 89 106 89 106 115 106 115 (SI)→ (SI)→ 124 80<124 115 124 (SI+2)→ 124 124 没有找到 ZF=0, (CX)=0 添M 后者依次下移 数组长度+1 80

  16. Y ZF=1 DEL SI指向数组尾 Y 尾数据 L1 Y (AX)<((SI)) 数组依次 上移一字 L2 关键字插入 数组下移一字 (SI)-2 →SI NEXT 长度-1 长度+1 结束 二种可能 ZF≠1,(CX)=0 ZF=1,(CX)≠0/(CX)=0 初始化 REPNE SCASW

  17. DATA SEGMENT BUFFER DW 5,10,32,47,53,77,89,106,115,124 N DB 10 M EQU 80 DATA ENDS CODE SEGMENT ASSUME CS:CODE,DS:DATA,ES:DATA MAIN PROC FAR START:PUSH DS ………… MOV AX,M ;关键字(待查数)→AX MOV CX,N ;数据串长度→CX MOV DX,N ;数据串长度→DX(备用) MOV DI,OFFSET BUFFER ;首地址→DI CLD ;串操作增址,执行SCASW指令准备结束 初始化

  18. REPNE SCASW JE DEL DEC DX MOV SI,DX ADD SI,DX ;SI=2(N-1) BUF BUF 5 5 LI: CMP AX,BUFFER[SI] 10 10 JL L2 32 32 80 MOV BUFFER[SI+2],AX 47 47 53 53 JMP L3 (SI)→ 77 80>77 77 L3: ADD DX,2 L2: MOV BX,BUFFER[SI] (SI+2)→ 89 89 JMP NEXT1 MOV BUFFER[SI+2],BX 89 106 106 115 SUB SI,2 ……… (SI)→ 80<124 115 124 JMP L1 NEXT1:RET (SI+2)→ 124 124

  19. 例5: 从键盘输入两个1位十进制数,求两数之和并在屏幕上显示结果。 读入第一个数 处理后保存 读入第二个数 求和 BCD码调整 显示十位 显示个位

  20. MOV AH , 1 ;DOS调用,输入第一个数 INT 21H SUB AL,30H MOV BL , AL ;保存输入的第一个数 MOV AH , 1 INT 21H SUB AL,30H ADD AL , BL ;两个数相加 AAA ; 调整加法结果为非压缩BCD数 MOV DL , AH MOV AH,2 ADD DL , 30H ;转换成ASCII码 MOV AH , 2 ;DOS调用输出到屏幕 INT 21H MOV DL,AL ADD DL,30H MOV AH,2 INT 21H

  21. 入口 入口 初始化 初始化 循环体 循环控制 出口 循环体 修改参数 循环控制 修改参数 出口 先执行后判断 先执行后判断 三、循环程序结构

  22. 入口 初始化 循环体 修改参数 循环控制 出口 先执行后判断 初始化:为循环做准备,置循环次数;置变量初值等。 循环体:循环主体。 修改参数:修改操作数地址为下次循环作准备。 循环控制:修改循环次数值,判循环终点,决定是否结束循环。

  23. BX BUF 9 C 4 6 43 34 C 4 6 9 36 AL 6 9 0 9 3 9 例6 将BX中的16进制数转换为ASCII码,存放到BUF开始的内存单元中,并在屏幕显示出数值。 39 反复操作4次 0~9: +30H 16进制数→ASCII码 A~F:+37H=+30H+07H

  24. MOV SI,OFFSET BUF MOV CH,4 NEXT: MOV CL,4 ROL BX,CL MOV AL,BL AND AL,0FH ADD AL,30H CMP AL,3AH JL STORE ADD AL,7 STORE: MOV [SI],AL MOV AH,2 MOV DL,AL INT 21H INC SI DEC CH JNZ NEXT HLT 最高位可能显示0,一般是0不显示

  25. MOV AL,[SI] DEC CH JNZ NEXT HLT 显示 最高位判断 MOV CH,4 MOV SI,OFFSET BUF MOV AL,[SI] CMP AL,30H JZ NO MOV AH,2 MOV DL,AL INT 21H NEXT: NO:INC SI

  26. 例7:编程将以$结束的字符串中的小写字母改为大写字母。例7:编程将以$结束的字符串中的小写字母改为大写字母。 • DATA SEGMENT • STR DB ‘heLLo,eveRyboBY !’,’$’ • DATA ENDS • …… • LEA BX , STR • A1: MOV AL ,[BX] • CMP AL , ‘$’ ;是$符,则结束 • JE DONE • CMP AL , ‘a’ • JB NEXT ;低于,则为大写字母 • CMP AL ,’z’ • JA NEXT ;高于,则不是字母 • SUB AL , 20H ;将小写字母改为大写 • MOV [BX] , AL • NEXT: INC BX • JMP A1 • DONE: HLT

  27. 自上向下比较(交换),大者在高地址 15 15 15 15 37 比较交换6次 37 比较交换5次 37 37 … 8600 8600 8600 76H 内 循 环 CX A768H A768H 3412H 3412H 1256H 1256H 3412H A768H 1256H 3412H 76H 8600 1256H A768H76H 3412H 3412H 76H A768H A768H A768H 进行6遍(外循环)DX 例8存储器数据段从BUF开始存放一个字数组,数组中第一个字中存放数组的长度N,编制一个程序使此数组中的数据按照从小到大的次序排列。

  28. 初始化 置内循环初值→CX L1 置/改外循环初值→DX L2 字数据指针BX为 修改数据指针+2 取数B[I] 字数据地址与首地址的差值 Y B[I]≤ B[I+2] 交换B[I] B[I+2] CONTI N 内循环结束 置数据指针初值0→BX N 外循环结束 结束

  29. MOV BX,0 MOV CX,BUF[BX] 置内循环初值→CX 置内循环初值→CX DEC CX L2: ADD BX,2 MOV AX,BUF[BX] CMP AX,BUF[BX+2] JBE CONTI XCHG AX,BUF [BX+2] MOV BUF [BX],AX 交换B[I] B[I+2] 交换B[I] B[I+2] MOV CX,DX MOV BX,0 初始化 L1 置/改外循环初值→DX 置/改外循环初值→DX L1: MOV DX,CX L2 修改数据指针+2 取数B[I] 修改数据指针+2 取数B[I] Y B[I]≤ B[I+2] B[I]≤ B[I+2] CONTI CONTI: LOOP L2 N 内循环结束 内循环结束 置数据指针初值→BX 置数据指针初值→BX LOOP L1 N RET 外循环结束 外循环结束 结束 结束

  30. 子程序 主程序 SUB1 PROC SUB1 PROC 转向子程序 CALL SUB1 断点地址 RET RET 返回主程序 四、子程序结构 1、子程序使用 对于多次进行相同的计算机操作,把这些相同的操作编成一个子程序(过程PROC)。使用CALL指令调用,RET指令返回。

  31. 名称 PROC NEAR/FAR … RET… 名称 ENDP 子程序的结构 NEAR段内调用(可缺省)。子程序与主程序在同一代码段。断点为段内有效地址IP。 FAR段间调用(不可缺省)。子程序与主程序不在同一代码段。断点为段内有效地址IP和段地址CS。

  32. 主程序与子程序之间的参数传递 入口参数:主程序向子程序传递初值; 出口参数:子程序向主程序返回结果。 传递参数的媒体:内部寄存器、内存(数据变量、堆栈等)。

  33. 现场保护和恢复 保护和恢复的对象:在子程序中需要使用的内部寄存器。 (1)一定要保护:子程序中使用的寄存器;在返回后主程序需继续使用的寄存器。 (2)一定不能保护:作为子程序的结果传送给主程序的寄存器。 (3)可不必保护:子程序中使用,但不是子程序运算结果,返回主程序后不再使用的寄存器。

  34. 压缩BCD码 二进制数 拾位 个位 拾位×10+个位 例9 编写子程序,将一个字节的压缩BCD码转换为二进制数。 入口参数:AL,存放两位压缩型BCD码 出口参数:AL,存放二进制数 使用寄存器:CX 参数传递:寄存器

  35. MOV CH,AL AND CH,0FH ;CH存放低8位二进制数 MOV CL,4 SHR AL,CL ;取高位BCD码 MOV CL,10 MUL CL ;AL存放高8位二进制数 RET BCD_TO_BIN ENDP 子程序BCD_TO_BIN BCD_TO_BINPROC NEAR PUSH CX ADD AL,CH ;计算最终结果存放AL POP CX

  36. 例10:用子程序调用形式,编写键盘输入4位16进制数的程序。例10:用子程序调用形式,编写键盘输入4位16进制数的程序。 START: MOV CL , 4 ;输入4次 MOV DL , CL ; 转换4次 MOV BX , 0 ;用BX保存输入数 RE1: MOV AH , 1 ; 从键盘输入 INT 21H CALL ZH ;通过子程序转换 SHL BX , CL ;组合成16进制数 ADD BL , AL MOV CL,4 DEC DX JNZ RE1 ;循环输入4个数 MOV AX , 4C00H INT 21H

  37. ZH PROC • CMP AL, ‘0’ • JL A5 ;键入值<’0’判断 • CMP AL , ‘9’ • JBE A3 ;键入值在’0’-‘9’之间 • CMP AL, ‘A’ ;键入值在‘A’-‘F’判断 • JGE A1 • JMP A5 • A1: CMP AL, ‘F’ • JBE A2 • CMP AL, ‘a’ • JL A5 • CMP AL, ‘f’ • JG A5 • SUB AL , 20H ;值在’a’ -‘f’先减20H,再减37H • A2: SUB AL , 7 • A3: SUB AL , 30H

  38. A4: RET • A5: INC DL • JMP A4 • ZH ENDP • CODE ENDS • END START

  39. 入口参数:数组首地址指针SI,数组长度CX 出口参数:和的数据段有效地址指针SI 使用寄存器:SI 例11 在数据段已定义二个字数组ARY1和ARY2。应用子程序,分别实现二个字数组求累加和(不计溢出)。 子程序 SUM 参数传递:内存 (数据段)

  40. 0000 AX ARY1 3529 0211 2447 1935 3529 373A 0088 AX AX 1534 2432 01A4 5B81 AX ←SI ←SI ADD AX,WORD PTR [SI] ←SI 累加次数=数组长度

  41. L1: ADD AX,WORD PTR [SI] ;取数累加一次 INC SI INC SI ;修改指针 LOOP L1 ;判断累加结束 MOV WORD PTR [SI],AX ;送结果 MOV AH,4CH INT 4CH RET DOS的第一层子程序才可返回DOS SUM ENDP 子程序 SUM SUM PROC NEAR XOR AX,AX ;累加和初值清零

  42. DATA SEGMENT ARY1 DW 100 DUP (?) SUM1 DW ? ARY2 DW 100 DUP (?) SUM2 DW ? DATA ENDS LEA SI,ARY1 ;取ARY1指针 MOV CX,LENGTH ARY1 ; ARY1长度送CX CALL SUM ;计算ARY1累加和送SUM1 LEA SI,ARY2 MOV CX,LENGTH ARY2 MOV AH,4CH CALL SUM INT 21H;返回DOS … 主程序部分程序段 参数传递:数据段内存 …

  43. 入口参数:数组首地址指针BX,数组长度CX 出口参数:累加和的数据段有效地址指针BX 使用寄存器:累加和AL,进位AH,参数传递指针BP SP SIZE 数组长度 ARY1 数组首地址 例12 通过堆栈传递参数,实现压缩型BCD码数组求累加和,要求主程序和子程序不在同一个代码段中。 子程序 PADD 参数传递:内存(堆栈段)

  44. SIZE 数组长度 数组首地址 ARY1 子程序PADD PADD PROC FAR PUSH BX PUSH CX PUSH BP MOV BP,SP ;当时堆栈指针存BP PUSHF MOV CX,[BP+10] ;数组长度→CX MOV BX,[BP+12] ;数组首地址→BX MOV AX,0 ;累加和清零 NEXT:ADD AL,[BX] ;计算低8位累加和 DAA ;低8位压缩型BCD调整 MOV DL,AL ;暂存DL MOV AL,0 ADC AL,AH ;高8位加进位 DAA ;高8位压缩型BCD调整 MOV AH,AL ;高8位送AH

  45. NEXT:ADD AL,[BX] ;计算低8位累加和 DAA ;低8位压缩型BCD调整 MOV DL,AL ;暂存DL MOV AL,0 ADC AL,AH ;高8位加进位 DAA ;高8位压缩型BCD调整 MOV AH,AL ;高8位送AH MOV AL,DL ;低8位送AL,一次累加结束 INC BX ;修改指针 LOOP NEXT ;判循环终点 POPF POP BP POP CX POP BX ;现场恢复 RET 4 ;返回主程序 PADD ENDP

  46. 主程序部分程序段 MDATA SEGMENT ARY1 DB 20 DUP (?) SUM1 DW ? ARY2 DB 20 DUP (?) SUM2 DW ? MDATA ENDS 注意: 1、数组属性为DB,累加和属性为DW 2、累加和的地址紧跟数组的地址

  47. 注意: 堆栈的变化 主程序初始化后 数组指针压栈后 段间调用子程序后 SP IP CS SP SP SIZE SIZE SIZE 数组长度 ARY1 ARY1 ARY1 数组首地址 SP MOV AX,OFFSET ARY1 PUSH AX MOV AX,SIZE ARY1 PUSH AX ;将待传递参数送堆栈 CALL FAR PTR PADD

  48. 注意: 进入子程序后堆栈的继续变化 SP PSW 四条压栈指令后 段间调用子程序后 (BP)→ BP CX BX SP IP IP CS CS SIZE SIZE ARY1 ARY1 PADD PROC FAR PUSH BX PUSH CX PUSH BP MOV BP,SP PUSHF

  49. SP PSW 四条压栈指令后 BP → BP CX BX IP CS BP+12 BP+10 SIZE ARY1 PUSHF MOV CX,[BP+10] ;数组长度→CX MOV BX,[BP+12] ;数组首地址→BX MOV AX,0 ;累加和、进位清零 注意:通过堆栈实现主程序与子程序参数传递

  50. 注意: 现场恢复和返回指令后堆栈的恢复 SP PSW 四条压栈指令后 四条出栈指令后 返回指令后 BP BP CX BX SP IP IP IP CS CS CS RET+4 SIZE SIZE SIZE ARY1 ARY1 ARY1 SP LOOP NEXT ;判循环终点 POPF POP BP POP CX POP BX ;现场恢复 RET 4 ;返回主程序

More Related