1 / 40

第 6 章

第 6 章. 第 6 章: 6.2 汇编程序设计. 6.2.1 顺序程序设计 没有分支、循环等转移指令的程序,会按指令书写的前后顺利依次执行,这就是顺序程序 顺序结构是最基本的程序结构 完全采用顺序结构编写的程序并不多见. 例题 6.5 计算表达式 Z=((X+Y)*8-X)/2 例题 6.6 顺序程序设计实例采用查表法,实现一位 16 进制数转换为 ASCII 码显示. 第 6 章:例 6.6(2) 数据段. ; 数据段 ASCII db 30h,31h,32h,33h,34h,35h,36h,37h,38h,39h ;对应 0 ~ 9 的 ASCII 码

Download Presentation

第 6 章

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. 第6章

  2. 第6章:6.2 汇编程序设计 • 6.2.1 顺序程序设计 • 没有分支、循环等转移指令的程序,会按指令书写的前后顺利依次执行,这就是顺序程序 • 顺序结构是最基本的程序结构 • 完全采用顺序结构编写的程序并不多见 例题6.5计算表达式Z=((X+Y)*8-X)/2 例题6.6 顺序程序设计实例采用查表法,实现一位16 进制数转换为ASCII码显示

  3. 第6章:例6.6(2) 数据段 ;数据段 ASCII db 30h,31h,32h,33h,34h,35h,36h,37h,38h,39h ;对应0 ~ 9的ASCII码 db 41h,42h,43h,44h,45h,46h ;对应A ~ F的ASCII码 hex db 04h,0bh ;假设两个数据

  4. 第6章:例6.6(2) 代码段 ;代码段 mov bx,offset ASCII ;BX指向ASCII码表 mov al,hex ;AL取得一位16进制数 ;恰好就是ASCII码表中的位移 and al,0fh ;只有低4位是有效的,高4位清0 xlat ;换码:AL←DS:[BX+AL] XLAT

  5. 第6章:例6.6(2) 代码段(续) mov dl,al ;入口参数:DL←AL mov ah,2 ;02号DOS功能调用 int 21h ;显示一个ASCII码字符 mov al,hex+1 ;转换并显示下一个数据 and al,0fh xlat mov dl,al mov ah,2 int 21h XLAT

  6. 第6章:6.2.2 分支程序设计 • 分支程序根据条件是真或假决定执行与否 • 判断的条件是各种指令,如CMP、TEST等执行后形成的状态标志 • 转移指令Jcc和JMP可以实现分支控制 • 分支结构有 • 单分支结构 • 双分支结构 • 多分支结构

  7. 第6章:单分支结构 • 条件成立跳转,否则顺序执行分支语句体 • 注意选择正确的条件转移指令和转移目标地址 实例:求绝对值

  8. 第6章:计算AX中有符号数的绝对值 cmp ax,0 jge nonneg;条件满足(AX≥0),转移 neg ax;条件不满足,求补 nonneg:mov result,ax;条件满足 ;不恰当的分支 cmp ax,0 jl yesneg;条件满足(AX<0),转移 jmp nonneg yesneg:neg ax;条件不满足,求补 nonneg:mov result,ax;条件满足

  9. 第6章:双分支结构 条件成立跳转执行第2个分支语句体,否则顺序执行第1个分支语句体 注意第1个分支体后一定要有一个JMP指令跳到第2个分支体后 实例:显示BX的最高位

  10. 第6章:显示BX的最高位 shl bx,1 ;BX最高位移入CF标志 jc one;CF=1,即最高位为1,转移 mov dl,30h ;CF=0,即最高位为0:DL←30H=‘0’ jmp two;一定要跳过另一个分支体 one: mov dl,31h ;DL← 31H=‘1’ two: mov ah,2 int 21h ;显示 可以用JNC替换JC

  11. 第6章:显示BX的最高位(续) shl bx,1 ;BX最高位移入CF标志 jnc one;CF=0,即最高位为0,转移 mov dl,31h ;CF=1,即最高位为1:DL←31H=‘1’ jmp two;一定要跳过另一个分支体 one: mov dl,30h ;DL← 30H=‘0’ two: mov ah,2 int 21h ;显示 转换为单分支结构

  12. 第6章:显示BX的最高位(另解) mov dl,’0’ ;DL←30H=‘0’ shl bx,1 ;BX最高位移入CF标志 jnc two;CF=0,即最高位为0,转移 mov dl,’1’ ;CF=1,即最高位为1:DL←31H=‘1’ two: mov ah,2 int 21h ;显示 • 编写分支程序,需留心分支的开始和结束

  13. 第6章:显示BX的最高位(无分支) mov dl,0 shl bx,1 ;BX最高位移入CF标志 adc dl,30h ;CF=0,DL←0+30h+0=30H=‘0’ ;CF=1,DL←0+30h+1=31H=‘1’ two: mov ah,2 int 21h ;显示

  14. Y Y Y fuction0 fuction1 fuction2 AH=0 AH=1 AH=2 N N N 第6章:多分支结构 多分支结构是多个条件对应各自的分支语句体,哪个条件成立就转入相应分支体执行 or ah,ah ;=cmp ah,0 jz function0 dec ah ;=cmp ah,1 jz function1 dec ah ;=cmp ah,2 jz function2

  15. 第6章:6.2.3 循环程序设计 • 循环程序结构是满足一定条件的情况下,重复执行某段程序 • 循环结构的程序通常有3个部分: • 循环初始部分——为开始循环准备必要的条件,如循环次数、循环体需要的数值等 • 循环体部分——指重复执行的程序部分,其中包括对循环条件等的修改程序段 • 循环控制部分——判断循环条件是否成立,决定是否继续循环 关键是什么?

  16. 第6章:循环控制 • 循环结构程序的设计关键是循环控制部分 • 循环控制可以在进入循环之前进行,也可以在循环体后进行,于是形成两种结构: • “先判断、后循环”结构,WHILE_DO • “先循环、后判断”结构,DO_UNTIL • 循环结束的控制可以用循环次数,还可以用特定条件等,于是又有: • 计数控制循环 • 条件控制循环 图示

  17. 初始化 循环的初始状态 循环体 循环的工作部分 及修改部分 修改部分 Y 计数控制循环 条件控制循环 控制条件 N 结束 第6章:先循环后判断的循环结构

  18. 第6章: 计数控制循环 • 计数控制循环利用循环次数作为控制条件 • 易于采用循环指令LOOP和JCXZ实现 • 初始化:将循环次数或最大循环次数置入CX • 循环体 • 循环控制:用LOOP指令对CX减1、并判断是否为0

  19. 第6章:用二进制显示BL内容 初始化 mov cx,8;CX←8(循环次数) again: shl bl,1 ;左移进CF,从高位开始显示 mov dl,0;MOV指令不改变CF adc dl,30h;DL←0+30H+CF ;CF若是0,则DL←' 0 ' ;CF若是1,则DL←' 1 ' mov ah,2 int 21h;显示 loop again ;CX减1,如果CX未减至0,则循环 循环体 计数控制循环 先循环后判断

  20. 第6章:条件控制循环 • 条件控制循环需要利用特定条件判断循环是否结束 • 条件控制循环用条件转移指令判断循环条件 • 转移指令可以指定目的标号来改变程序的运行顺序,如果目的标号指向一个重复执行的语句体的开始或结束,便构成了循环控制结构

  21. 第6章:显示以0结尾的字符串 ;数据段 string db 'Let us have a try !',0 ;代码段 mov bx,offset string again: mov dl,[bx] cmp dl,0 jz done;为0结束 mov ah,2 ;不为0,显示 int 21h inc bx ;指向下一个字符 jmp again done: …… 条件控制循环 先判断后循环

  22. 第6章:6.2.4 子程序设计 • 把功能相对独立的程序段单独编写和调试,作为一个相对独立的模块供程序使用,就形成子程序 • 子程序可以实现源程序的模块化,可简化源程序结构,可以提高编程效率 • 主程序(调用程序)需要利用CALL指令调用子程序(被调用程序) • 子程序需要利用RET指令返回主程序

  23. 第6章:1 过程定义和调用 • 汇编语言中,子程序要用一对过程伪指令PROC和ENDP声明,格式如下: 过程名PROC [NEAR|FAR] …… ;过程体 过程名ENDP • 可选的参数指定过程的调用属性。没有指定过程属性,则采用默认属性 • NEAR属性(段内近调用)的过程只能被相同代码段的其他程序调用 • FAR属性(段间远调用)的过程可以被相同或不同代码段的程序调用

  24. 第6章:1 过程定义和调用 ;在不同段 XSEG SEGMENT : SUBT1 PROC FAR : RET SUBT1 ENDP : CALL SUBT1 : XSEG ENDS YSEG SEGMENT : CALL SUBT1 : YSEG ENDS ;过程和主程序在同一段 CSEG SEGMENT MAIN PROC FAR : CALL SUBT : RET MAIN ENDP SUBT PROC NEAR : RET SUBT ENDP CSEG ENDS

  25. 第6章:子程序编写注意事项 ⑴子程序要利用过程定义伪指令声明 ⑵子程序最后利用RET指令返回主程序,主程序执行CALL指令调用子程序 ⑶子程序中对堆栈的压入和弹出操作要成对使用,保持堆栈的平衡 ⑷子程序开始应该保护使用到的寄存器内容,子程序返回前相应进行恢复 ⑸子程序应安排在代码段的主程序之外,最好放在主程序执行终止后的位置(返回DOS后、汇编结束END伪指令前),也可以放在主程序开始执行之前的位置

  26. 第6章:子程序编写注意事项(续) ⑹子程序允许嵌套和递归 ⑺子程序可以与主程序共用一个数据段,也可以使用不同的数据段(注意修改DS),还可以在子程序最后设置数据区(利用CS寻址) ⑻子程序的编写可以很灵活,例如具有多个出口(多个RET指令)和入口,但一定要保证堆栈操作的正确性 ⑼处理好子程序与主程序间的参数传递问题 ⑽提供必要的子程序说明信息

  27. 第6章:含数据区的子程序 ;子程序HTOASC:十六进制数转换为ASCII码 HTOASC proc push bx mov bx,offset ASCII and al,0fh xlat CS:ASCII ;换码:AL←CS:[BX+AL] pop bx ret ;数据区 ASCII db 30h,31h,32h,33h,34h,35h,36h,37h,38h,39h db 41h,42h,43h,44h,45h,46h HTOASC endp

  28. 第6章:多出口子程序 ;子程序HTOASC:十六进制数转换为ASCII码 HTOASC proc and al,0fh cmp al,9 jbe htoasc1 add al,37h ;是A ~ F,加37H ret ;子程序返回 htoasc1: add,30h ;是0 ~ 9,加30H ret ;子程序返回 HTOASC endp

  29. 第6章:2.参数传递 • 主程序与子程序间一个主要问题是参数传递 • 入口参数(输入参数) :主程序调用子程序时,提供给子程序的参数 • 出口参数(输出参数) :子程序执行结束返回给主程序的参数 • 参数的具体内容 • 传数值:传送数据本身 • 传地址:传送数据的主存地址 • 常用的参数传递方法 • 寄存器 • 共享变量 • 堆栈

  30. 第6章: 用寄存器传递参数 • 最简单和常用的参数传递方法是通过寄存器,只要把参数存于约定的寄存器中就可以了 • 由于通用寄存器个数有限,这种方法对少量数据可以直接传递数值,而对大量数据只能传递地址 • 采用寄存器传递参数,注意带有出口参数的寄存器不能保护和恢复,带有入口参数的寄存器可以保护、也可以不保护,但最好能够保持一致 dpchar dpstri HTOASC

  31. 第6章: 用共享变量传递参数 • 子程序和主程序使用同一个变量名存取数据就是利用共享变量(全局变量)进行参数传递 • 如果变量定义和使用不在同一个源程序中,需要利用PUBLIC、EXTREN声明 • 如果主程序还要利用原来的变量值,则需要保护和恢复 • 利用共享变量传递参数,子程序的通用性较差,但特别适合在多个程序段间、尤其在不同的程序模块间传递数据

  32. 第6章: 通过地址表传送变量地址 • 将要传递的参数地址放入一个特定的区域,形成一个地址表,表中放入的内容不同,所传递的参数就不一样。 • 将地址表的首地址放入一个寄存器等,传递进子程序,子程序从该地址表中取参数出地址进行计算 • 方便灵活

  33. 第6章:用堆栈传递参数 • 参数传递还可以通过堆栈这个临时存储区。主程序将入口参数压入堆栈,子程序从堆栈中取出参数;子程序将出口参数压入堆栈,主程序弹出堆栈取得它们 • 采用堆栈传递参数是程式化的,它是编译程序处理参数传递、以及汇编语言与高级语言混合编程时的常规方法

  34. 6.4 DOS及BIOS功能调用简介 • 软中断可分三部分: • DOS中断 • 占用类型号20H~3FH。目前使用的有20H~27H和2FH,其余保留。 • ROM BIOS中断 • 占用类型号为10H~1FH。 • 自由中断 • 占用类型号40H~FFH,可供系统或应用程序设置开发的中断处理程序用。

  35. 6.4.1 DOS中断及功能调用 • DOS专用中断 • 指INT 22 H、INT 23H、INT 24H三个中断。属于DOS操作时专用,用户不要直接使用 • DOS可调用中断 • 指INT 20H、INT 21H、INT 25H、INT 26H、INT 27H、INT 2FH 6个中断。供用户直接调用,但必须满足一定的入口条件。

  36. 磁盘读写中断25、26H • 用来读或写磁盘上的若干扇区 • 入口参数: • AL置入驱动器号 • CX置入读些扇区数 • DX置入起始扇区的逻辑号 • DS:BX置入内存起始地址 MOV AL,0 MOV CX,7 MOV DX,5 MOV BX,1000H INT 25H JMP 0

  37. 程序退出中断20、27H • 20H为正常退出 • 27H为驻留退出命令,留下的程序被DOS视为自身的一部分,不会被其他程序覆盖。其他用户程序中,可通过使用软中断调用这部分程序 • 假脱机打印文件中断 • INT 2FH用来实现假脱机打印文件命令PRINT • 系统功能调用 • 21H中断是可供系统程序和应用程序调用的一个极其重要的中断,内含近百个系统子功能。操作系统的内核主要由它构成。

  38. 6.4.2 BIOS中断调用 • 基本输入输出子程序—BIOS • 功能与DOS中字符I/O功能相似,可通过软中断方式直接调用 • 其字符I/O功能直接依赖于硬件,因此调用它们比调用DOS字符I/O功能速度更快 • 分类 • 键盘输入子程序INT 16H • 显示程序INT 10H • 打印输出子程序INT 17H

  39. 第6章:教学要求 • 掌握简化段定义源程序格式 • 掌握常量表达、变量定义及应用、变量和标号的属性及操作符 • 掌握汇编语言源程序的编辑、汇编、连接和调试的开发方法 • 掌握基本伪指令和操作符: EQU/=;+-*/;DB/DW/DD、?/DUP;ORG/$、OFFSET/SEG/PTR;.MODEL/.STACK/.DATA/.CODE/END;PROC/ENDP

  40. 第6章:教学要求(续) • 掌握基本的顺序、分支、循环和子程序设计方法 • 熟悉常见程序设计问题: 多精度运算,查表(查代码、特定值等)、ASCII和BCD代码转换;数据范围判断(0~9、A~Z、a~z)、字母大小写转换;字符串传送、比较等操作、求最小最大值、数据求和、统计字符个数

More Related