1 / 33

第六章 汇编语言程序设计方法

第六章 汇编语言程序设计方法. 编辑. 汇编. 连接. 调试. 文本编辑器,如 EDIT.COM. 汇编程序,如 ML.EXE. 连接程序,如 LINK.EXE. 调试程序,如 DEBUG.EXE. 错误. 错误. 错误. 应用程序. 6.1 汇编语言设计步骤. 源程序:文件名 .asm. 目标模块:文件名 .obj. 可执行文件:文件名 .exe. 错误. 6.2 顺序结构程序设计. 没有分支、循环等转移指令的程序,会按指令书写的前后顺利依次执行,这就是顺序程序 顺序结构是最基本的程序结构 完全采用顺序结构编写的程序并不多见.

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. 第六章 汇编语言程序设计方法

  2. 编辑 汇编 连接 调试 文本编辑器,如 EDIT.COM 汇编程序,如 ML.EXE 连接程序,如 LINK.EXE 调试程序,如 DEBUG.EXE 错误 错误 错误 应用程序 6.1 汇编语言设计步骤 源程序:文件名.asm 目标模块:文件名.obj 可执行文件:文件名.exe 错误

  3. 6.2 顺序结构程序设计 • 没有分支、循环等转移指令的程序,会按指令书写的前后顺利依次执行,这就是顺序程序 • 顺序结构是最基本的程序结构 • 完全采用顺序结构编写的程序并不多见 下例顺序程序设计实例 采用查表法,实现一位16进制数 转换为ASCII码显示

  4. 例题 ;数据段 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 ;假设两个数据

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

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

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

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

  9. 例题:求绝对值 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;条件满足

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

  11. 例题:显示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

  12. 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 ;显示 转换为单分支结构

  13. 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 ;显示 • 编写分支程序,需留心分支的开始和结束

  14. 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 ;显示

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

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

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

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

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

  20. 例题:求数组元素的最大最小值 ;数据段 array dw 10 ;假设一个数组,其中头个数据10表示元素个数 dw -3,0,20,900,587,-632,777,234,-34,-56 ;这是一个有符号字量元素组成的数组 maxay dw ? ;存放最大值 minay dw ? ;存放最小值 初始化:循环次数=元素个数-1 循环体:逐个比较求最大、小值 循环控制:比较完所有数据

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

  22. 例题:显示以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: …… 条件控制循环 先判断后循环

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

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

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

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

  27. 例题:显示以0结尾的字符串的嵌套子程序 ;数据段 msg db 'Well, I made it !',0 ;代码段(主程序) mov si,offset msg ;主程序提供显示字符串 call dpstri ;调用子程序

  28. 多出口子程序 ;子程序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. 参数传递 • 主程序与子程序间一个主要问题是参数传递 • 入口参数(输入参数) :主程序调用子程序时,提供给子程序的参数 • 出口参数(输出参数) :子程序执行结束返回给主程序的参数 • 参数的具体内容 • 传数值:传送数据本身 • 传地址:传送数据的主存地址 • 常用的参数传递方法 • 寄存器 • 共享变量 • 堆栈

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

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

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

  33. 6.6小 结 本章主要内容小结和基本要求(1)学会设计“顺序”、“分支”和“循环”这三种基本结构形式的程序。 (2)在写程序前要画出程序流程图。 (3)掌握“主+子”结构程序的设计方法。 (4)学会使用“DOS系统功能调用”。

More Related