微机原理与接口技术-chapter4.ppt_第1页
微机原理与接口技术-chapter4.ppt_第2页
微机原理与接口技术-chapter4.ppt_第3页
微机原理与接口技术-chapter4.ppt_第4页
微机原理与接口技术-chapter4.ppt_第5页
已阅读5页,还剩111页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

微机原理与接口技术 第四章汇编语言程序设计 主要内容 汇编语言源程序格式指示性语句系统功能调用方法汇编程序设计方法综合举例 汇编语言源程序格式 完整的汇编语言源程序由逻辑段组成 一个汇编语言源程序可以包含若干个代码段 数据段 附加段或堆栈段 段与段之间的顺序可随意排列 需独立运行的程序必须包含一个代码段 并指示程序执行的起始点 一个程序只有一个起始点 通常 程序还需要一个堆栈段 段由若干语句组成 一条语句通常写成一行 一个完整的汇编语言源程序 DATASEGMENTMINUSDB NUMBERDB100DUP DATAENDSCODESEGMENTASSUMECS CODE DS DATACOUNTEQU100START MOVAX DATAMOVDS AXMOVMINUS 0LEASI NUMBERMOVCX COUNTAGAIN MOVAL SI ORAL ALJNSNOT MINUS INCMINUSNOT MINUS LOOPAGAINMOVAH 4CHINT21HCODEENDSENDSTART 汇编语言的语句格式 指令性语句 指令性语句用于表达处理器指令 汇编后对应一条指令代码 目标代码 因而是可执行语句 标号 操作数 注释 指示性语句 指示性语句指示源程序如何汇编 变量怎样定义 过程怎么设置 也称为伪指令 描述性 辅助性 汇编时不产生目标代码 是不可执行语句 名字 参数 注释 每个部分称为 项 或 域 场 标号后有 部分不可缺少 指令与伪指令 指令 Instruction 让CPU产生动作 在程序执行时才处理 指令就是第3章学习的处理器指令 与具体的处理器有关 与汇编程序无关 伪指令 Directive 不产生CPU动作 在程序执行前由汇编程序处理 伪指令与具体的处理器类型无关 但与汇编程序有关 不同版本的汇编程序支持不同的伪指令 指令和伪指令采用易于记忆的符合表达 这就是助记符 标号 名字与标识符 标号是反映指令位置 逻辑地址 和属性的标识符 后跟一个冒号分隔名字是反映伪指令位置 逻辑地址 和属性的标识符 后跟空格或制表符分隔 没有冒号标识符 Identifier 一般最多由31个字母 数字及规定的特殊符号 如 组成 不能以数字开头 默认情况下 汇编程序不区别标识符中的字母大小写一个源程序中 每个标识符的定义是唯一的 还不能是汇编语言采用的保留字和内部寄存器名 保留字 保留字 ReservedWord 是汇编程序已经利用的标识符 也称为关键字 主要有 指令助记符 例如 MOV ADD伪指令助记符 例如 DB DW操作符 例如 OFFSET PTR寄存器名 例如 AX CS 汇编语言大小写不敏感 操作数和参数 处理器指令的操作数可以是立即数 寄存器和存储单元伪指令的参数可以是常量 变量 表达式等 可以有多个 参数之间用逗号分隔 注释 语句中由分号 开始的部分为注释内容 用以增加源程序的可读性必要时 一个语句行也可以由分号开始作为阶段性注释汇编程序在翻译源程序时将跳过该部分 不对它们做任何处理 分隔符 语句的4个组成部分要用分隔符分开标号后用冒号 注释前用分号 操作数之间和参数之间使用逗号分隔其他部分通常采用空格或制表符多个空格和制表符的作用与一个相同 常量 变量和标号 汇编语言的数据可以简单分为常量和变量常量可以作为指令的立即数或伪指令的参数 变量主要作为存储器操作数汇编语言语句中的名字和标号具有逻辑地址和类型属性 主要用做地址操作数 也可以作为立即数和存储器操作数 常量 常量表示一个固定的数值 它又分成多种形式常数字符串符号常量数值表达式 1 常数 指由10 16 2和8进制形式表达的数值 各种进制的数据以后缀字母区分 默认不加后缀字母的是十进制数 2 字符串 字符串常量是用单引号括起来的单个字符或多个字符其数值是每个字符对应的ASCII码值例如 d 等于64H AB 等于4142H Hello Assembly 3 符号常量 符号常量使用标识符表达一个数值用来为常量定义符号名符号定义伪指令有 等价EQU 和 等号 符号名EQU数值表达式符号名 数值表达式EQU不能重复定义符号名 但 允许重复定义 例如 X 7 等效于 Xequ7X X 5 XEQUX 5 是错误的 举例 NUMBEREQU200COUNTEQU6 9ADDREQUES DI 2 MVEQUMOVSTRWEQUWORDPTRSTRINGCOUNT 123COUNT COUNT 1 4 表达式 表达式一般是由运算符连接的各种常量所构成汇编程序在汇编过程中计算表达式 最终得到一个确定的数值 所以也是常量表达式的数值在程序运行前的汇编阶段计算 所以组成表达式的各部分必须在汇编时就能确定经常使用的是加减乘除 例如 movax 3 4 5 等价于 movax 17andax 3and5 等价于 andax 1 变量 变量实质上是指内存单元的数据 虽然内存单元地址不变 但其中存放的数据可以改变变量需要事先定义才能使用变量定义 Define 伪指令为变量申请固定长度为单位的存储空间 并可以同时将相应的存储单元初始化定义后的变量可以利用变量名等方法引用其中的数据 即变量的数值 1 变量的定义 变量定义的汇编语言格式为 变量名伪指令初值表变量名为用户自定义标识符 表示初值表首元素的逻辑地址 常称为符号地址 变量名也可以没有初值表是用逗号分隔的参数 主要由常量 数值表达式或 组成 其中 表示未赋初值多个存储单元如果初值相同 可以用复制操作符DUP进行定义 重复次数DUP 重复参数 变量定义伪指令有DB DW DD等 字节变量的定义DB DB伪指令用于分配一个或多个字节单元 并可以将它们初始化为指定值初值表中每个数据一定是字节量 存放一个8位数据 可以是0 255的无符号数或是 128 127带符号数也可以是字符串常数 字节变量定义实例 数据段Xdb a 5db2dup 100 Ydb ABC 应用 字节变量的应用 moval X 此处X表示它的第1个数据 故AL a decX 1 对X为始的第2个数据减1 故成为 6movY al 现在Y这个字符串成为 aBC 字变量的定义DW DW伪指令用于分配一个或多个字单元 并可以将它们初始化为指定值初值表中每个数据是字量 一个字单元可用于存放任何16位数据 一个段地址一个偏移地址两个字符0 65535之间的无符号数 32768 32767之间的带符号数 字变量定义实例 数据段countdw8000h AB maxintequ64hnumberdwmaxintarraydwmaxintdup 0 双字变量的定义DD DD伪指令用于分配一个或多个双字单元 并可以将它们初始化为指定值初值表中每个数据是一个32位的双字量 可以是有符号或无符号的32位整数也可以用来表达16位段地址 高位字 和16位的偏移地址 低位字 的远指针varddDD0 12345678hfarpointDD00400078h 2 变量的应用 变量具有存储单元的逻辑地址程序代码中通过变量名引用其指向的首个数据通过变量名加减位移量存取以首个数据为基地址的前后数据 变量的定义 bvar1db100 01100100b 64h d 字节变量 不同进制表达同一个数值 内存中有4个64Hminint 5 符号常量 minint数值为5 不占内存空间bvar2db 1 minint minint 5 内存中数值依次为FFH 5 0AHdb 2dup 20h 预留一个字节空间 重复定义了2个数值20Hwvar1dw2010h 4 4 字变量 两个数据是2010H 0010H 共占4个字节wvar2dw wvar2是没有初值的字变量 变量的定义 续 dvardd12347777h 87651111h 双字变量 2个双字数据 一个双字空间abcdb a b c 定义字符 实际是字节变量maxintequ0ah 符号常量 maxint 10stringdb ABCDEFGHIJ 定义字符串 使用字节定义DB伪指令crlfsdb13 10 回车符0DH 换行符0AH和字符 24Harray1dwmaxintdup 0 10个初值为0的字量 可以认为是数组arraydb2dup 2 3 2dup 4 6个字节内容依次为 0203040402030404 变量的应用 代码段movdl bvar1 DL 100decbvar2 1 bvar2 1 4movabc 3 dl abc abcd movax wordptrdvar 取双字到DX AXmovdx wordptrdvar 2addax wordptrdvar 4 加双字到DX AXadcdx wordptrdvar 6movwordptrdvar 8 ax 保存双字的求和结果movwordptrdvar 10 dx 3 变量的定位 汇编程序按照指令的先后顺序一个接着一个分配存储空间定位伪指令ORG控制数据或代码所在的偏移地址ORG参数ORG伪指令是将当前偏移地址指针指向参数表达的偏移地址 例如 ORG100h 从100H处安排数据或程序ORG 10 偏移地址加10 即跳过10个字节空间汇编语言程序中 符号 表示当前偏移地址值 程序计数器 汇编程序有一个当前位置计数器 用来记录正在汇编的数据或指令目标代码存放在当前段内的偏移量 表示位置计数器的当前值 例如 BLOCKDB Hello NUMEQU BLOCK 名字和标号的属性 名字和标号是用户自定义的标识符 名字指向一条伪指令 标号指向一条指令 名字和标号一经使用便具有两类属性 逻辑地址 名字和标号对应存储单元的逻辑地址 含有段地址和偏移地址 类型 变量名的类型可以是BYTE WORD和DWORD等 标号 段名 子程序名的类型可以是NEAR和FAR 分别表示段内或段间调用汇编程序提供操作符TYPE 以便获取这些属性值 1 地址操作符 地址操作符取得名字或标号的段地址和偏移地址 举例 数据段BUFFERDB 代码段MOVBX OFFSETBUFFERMOVBX SEGBUFFER LEABX BUFFER 2 类型操作符 类型操作符对名字或标号的类型属性进行设置类型名PTR名字 标号其中类型名可以是BYTE WORD DWORD 或者是NEAR FAR操作符SHORT对变量 LENGTH操作符获知某变量名指向多少个数据项SIZE操作符获知它共占用多少字节空间TYPE操作符获取变量类型值 举例 数据段BUFFERDW STRINGDB Hello 10DUP RESULTDB10DUP 1 代码段MOVBX TYPEBUFFERMOVBX TYPESTRINGMOVBX TYPERESULT BX 2 BX 1 BX 1 举例 数据段BUFFERDW STRINGDB Hello 10DUP RESULTDB10DUP 1 代码段MOVBX LENGTHBUFFERMOVBX LENGTHSTRINGMOVBX LENGTHRESULT BX 1 BX 1 BX 10 举例 数据段BUFFERDW STRINGDB Hello 10DUP RESULTDB10DUP 1 代码段MOVBX SIZEBUFFERMOVBX SIZESTRINGMOVBX SIZERESULT BX 2 BX 15 BX 20 举例 数据段STUFFDD12345678H 代码段MOVCL BYTEPTRSTUFFMOVCH BYTEPTRSTUFF 1MOVAX WORDPTRSTUFFMOVDX WORDPTRSTUFF 2 CL 78H CH 56H AX 5678H DX 1234H 段名SEGMENT 段名ENDS 段定义语句 1 SEGMENT定义一个逻辑段 并给逻辑段赋予一个段名 2 常见的段名如 CODE DATA STACK ASSUME 格式ASSUME段寄存器名 段名 段寄存器名 段名 如ASSUMECS CODE DS DATA SS STACK作用明确段寄存器与逻辑段之间的关系 并不是给段寄存器赋初值 完整段定义格式 完整段定义利用SEGMENT和ENDS一对伪指令定义逻辑段同时需要配合ASSUME伪指令指明逻辑段是代码段 堆栈段 数据段还是附加段完整段定义的优势是可以指明逻辑段的定位 组合 类别等属性而简化段定义只能采用系统默认的属性 过程定义语句 过程名PROC NEAR FAR RET过程名ENDP调用过程 CALL过程名 伪指令小结 符号定义语句EQU 数据定义语句DBDWDDDUP段定义语句SEGMENT ENDSASSUME过程定义语句PROC ENDP其他ORG END常用运算符ANDORXORNOTOFFSETSEGLENGTHSIZETYPEPTRSHORT 程序开始 为了指明程序开始执行的位置 需要使用一个标号 例题中采用了start标识符 连接程序会根据程序起始点正确地设置CS和IP值 根据程序大小和堆栈段大小设置SS和SP值连接程序没有设置DS和ES值 程序如果使用数据段或附加段 必须明确给DS或ES赋值大多数程序需要数据段 程序的执行开始应是 start movax data data表示数据段的段地址movds ax 设置DS 程序终止 应用程序执行结束 应该将控制权交还操作系统汇编语言程序设计中 有多种返回DOS的方法 但一般利用DOS功能调用的4CH子功能实现 它需要的入口参数是AL 返回数码 通常用0表示程序没有错误 于是 应用程序的终止代码就是 movax 4c00hint21h 汇编结束 汇编结束表示汇编程序到此结束将源程序翻译成目标模块代码的过程源程序的最后必须有一条END伪指令END 标号 可选的 标号 参数指定程序开始执行点 连接程序据此设置CS和IP值 例题中采用了start标识符 不要糊涂 程序终止和汇编结束是两码事 系统功能调用方法 汇编程序提供给汇编语言程序员的功能非常有限程序员需要利用ROM BIOS和操作系统提供的资源系统功能调用是程序设计的一个重要方面 系统功能调用步骤 通常按照如下4个步骤进行 在AH寄存器中设置系统功能调用号 在指定寄存器中设置入口参数 用中断调用指令 INTi8 执行功能调用 根据出口参数分析功能调用执行情况 DOS输入输出功能调用 DOS利用21H号中断提供给用户近百个系统功能 主要包括设备管理 目录管理和文件管理三个方面的功能重点掌握 输入一个字符 01H号功能调用输出一个字符 02H号功能调用输出一个字符串 09H号功能调用 02H号DOS功能调用 输出一个字符 功能调用号 AH 02H 入口参数 DL 欲显示字符的ASCII码 功能调用 INT21H 出口参数 无 显示一个问号 movah 02h 设置功能调用号movdl 设置入口参数int21h 功能调用 例题 回车换行的子程序 crlfprocpushax 保护寄存器pushdxmovah 2movdl 0dh 回车功能的ASCII码是0DHint21hmovah 2movdl 0ah 换行功能的ASCII码是0AHint21hpopdx 恢复寄存器popaxretcrlfendp 09H号DOS功能调用 输出一个字符串 功能调用号 AH 09H 入口参数 DS DX 欲显示字符串在内存中的首地址 逻辑地址形式 DS 段地址 DX 偏移地址 内存中的字符串以ASCII码形式保存 最后必须添加一个 结尾 并不显示 功能调用 INT21H 出口参数 无 例题 在屏幕上显示一段信息 数据段 定义要显示的字符串 stringdb Hello Assembly 0dh 0ah 代码段 显示字符串的程序 movdx offsetstringmovah 9int21h Hello Assembly 01H号DOS功能调用 输入一个字符 功能调用号 AH 01H 入口参数 无 功能调用 INT21H 出口参数 AL 键入字符的ASCII码 输入一个字符movah 01h 设置功能调用号int21h 功能调用movdl al 使用出口参数 结束用户程序的方法 STARTPROCFARBEGIN PUSHDSMOVAX 0PUSHAX RETSTARTENDP 推荐采用第1种方法 顺序程序设计 没有分支 循环等转移指令的程序 会按指令书写的前后顺利依次执行 这就是顺序程序顺序结构是最基本的程序结构完全采用顺序结构编写的程序并不多见 例题 STACKSEGMENTSTACK STACK DW64DUP 定义堆栈段STACKENDSDATASEGMENTXDW0010HYDW0123HZDW7890HVDW3456H 分配变量X Y Z VQRDW 存放商REMAINDERDW 存放余数DATAENDS 要求 计算 V X Y Z 540 X 例 代码段 CODESEGMENTASSUMECS CODE DS DATA SS STACKMAINPROCSTART MOVAX DATAMOVDS AX 初始化DSMOVAX X AX XIMULY DX AX X YMOVCX AXMOVBX DX 暂存在BX CX中MOVAX ZCWD Z扩展ADDCX AXADCBX DX BX CX X Y Z 例 代码段 续1 SUBCX 540SBBBX 0 可能有借位MOVAX VCWD 扩展VSUBAX CXSBBDX BXIDIVXMOVQR AX 保存商MOVREMAINDER DX 保存余数 例 代码段 续2 MOVAH 4CHINT21H 程序结束 返回到DOSMAINENDP 过程结束CODEENDS 码段结束ENDSTART 结束汇编 指定程序入口地址 举例 顺序程序设计实例 datasegmentASCIIdb30h 31h 32h 33h 34h 35h 36h 37h 38h 39h 对应0 9的ASCII码db41h 42h 43h 44h 45h 46h 对应A F的ASCII码hexdb04h 0bh 假设两个数据dataends 采用查表法 实现一位16进制数转换为ASCII码显示 例 代码段 codesegmentassumecs code ds datastart movax datamovds axmovbx offsetASCII BX指向ASCII码表moval hex AL取得一位16进制数 恰好就是ASCII码表中的位移andal 0fh 只有低4位是有效的 高4位清0 xlat 查表 AL DS BX AL 例 代码段 续 movdl al 入口参数 DL ALmovah 2 02号DOS功能调用int21h 显示一个ASCII码字符moval hex 1 转换并显示下一个数据andal 0fhxlatmovdl almovah 2int21hmovah 4chint21hcodeendsendstart 分支程序设计 分支程序根据条件是真或假决定执行与否判断的条件是各种指令 如CMP TEST等执行后形成的状态标志转移指令Jcc和JMP可以实现分支控制分支结构有单分支结构双分支结构多分支结构 单分支结构 条件成立跳转 否则顺序执行分支语句体注意选择正确的条件转移指令和转移目标地址 实例 求绝对值 例 计算AX中有符号数的绝对值 cmpax 0jgenonneg 条件满足 AX 0 转移negax 条件不满足 求补nonneg movresult ax 条件满足 另外一种做法 繁琐cmpax 0jlyesneg 条件满足 AX 0 转移jmpnonnegyesneg negax 条件不满足 求补nonneg movresult ax 条件满足 双分支结构 条件成立跳转执行第2个分支语句体 否则顺序执行第1个分支语句体注意第1个分支体后一定要有一个JMP指令跳到第2个分支体后 实例 显示BX的最高位 例 显示BX的最高位 shlbx 1 BX最高位移入CF标志jcone CF 1 即最高位为1 转移movdl 30h CF 0 即最高位为0 DL 30H 0 jmptwo 一定要跳过另一个分支体one movdl 31h DL 31H 1 two movah 2int21h 显示 可以用JNC替换JC 例 显示BX的最高位 续 shlbx 1 BX最高位移入CF标志jncone CF 0 即最高位为0 转移one movdl 31h CF 1 即最高位为1 DL 31H 1 jmptwo 一定要跳过另一个分支体 one movdl 30h DL 30H 0 two movah 2int21h 显示 转换为单分支结构 例 显示BX的最高位 另解 movdl 0 DL 30H 0 shlbx 1 BX最高位移入CF标志jnctwo CF 0 即最高位为0 转移movdl 1 CF 1 即最高位为1 DL 31H 1 two movah 2int21h 显示 编写分支程序 需留心分支的开始和结束 例 显示BX的最高位 无分支 movdl 0shlbx 1 BX最高位移入CF标志adcdl 30h CF 0 DL 0 30h 0 30H 0 CF 1 DL 0 30h 1 31H 1 two movah 2int21h 显示 例 非压缩的BCD码 显示成压缩BCD码 无前导0 续 数据段BCDdb04h 代码段movdl BCDtestdl 0ffh 如果BCD码为0 显示0jzzero 如果是0 转到zero 双分支结构testdl 0f0h 如果BCD码高位为0 不显示0jzone 单分支结构 例 非压缩的BCD码 显示成压缩BCD码 无前导0 续 movcl 4 处理高位shrdl clordl 30h 转换为ASCII码movah 2 显示高位int21hmovdl BCDanddl 0fhone ordl 30h 处理低位jmptwozero movdl 0 two movah 2int21h 多分支结构 多分支结构是多个条件对应各自的分支语句体 哪个条件成立就转入相应分支体执行 cmpah 0jzfunction0cmpah 1jzfunction1cmpah 2jzfunction2 例 小大写字母转换 如果DL是一个小写字母 则转换为大写cmpdl a 小于小写字母a 不需要处理jbdispcmpdl z 大于小写字母z 也不需要处理jadispsubdl 20h 是小写字母 则转换为大写disp 循环程序设计 循环程序结构是满足一定条件的情况下 重复执行某段程序循环结构的程序通常有3个部分 3要素 循环初始部分 为开始循环准备必要的条件 如循环次数 循环体需要的数值等循环体部分 指重复执行的程序部分 其中包括对循环条件等的修改程序段循环控制部分 判断循环条件是否成立 决定是否继续循环 关键是什么 循环控制 循环结构程序的设计关键是循环控制部分循环控制可以在进入循环之前进行 也可以在循环体后进行 于是形成两种结构 先判断 后循环 结构 先循环 后判断 结构循环结束的控制可以用循环次数 还可以用特定条件等 于是又有 计数控制循环条件控制循环 先循环后判断的循环结构 计数控制循环 计数控制循环利用循环次数作为控制条件易于采用循环指令LOOP和JCXZ实现初始化 将循环次数或最大循环次数置入CX循环体循环控制 用LOOP指令对CX减1 并判断是否为0 例 用二进制显示BL内容 movcx 8 CX 8 循环次数 again shlbl 1 左移进CF 从高位开始显示movdl 0 MOV指令不改变CFadcdl 30h DL 0 30H CF CF若是0 则DL 0 CF若是1 则DL 1 movah 2int21h 显示loopagain CX减1 如果CX未减至0 则循环 计数控制循环先循环后判断 例 求最大最小值 在16位带符号数中找出其中的最大值和最小值 分别放在MAX和MIN单元中 again next1 next2 BX 存储单元地址AX 最大值DX 最小值CX 循环次数 例 求最大最小值 续 DATASEGMENTBUFFERDW100DUP 自定义N个数COUNTEQU BUFFERMAXDW 保存最大值MINDW 保存最小值DATAENDSCODESEGMENTASSUMECS CODE DS DATA 定义数据 例 求最大最小值 续 START MOVAX DATAMOVDS AXMOVCX COUNTSHRCX 1 计算个数字节数除以2LEABX BUFFERMOVAX BX AX 最大值初值MOVDX BX DX 最小值初值DECCX 循环次数减1 初始化 例 求最大最小值 续 AGAIN ADDBX 2 指向下一个数字CMPAX BX 比较JGENEXT1MOVAX BX AX取得更大的数据JMPNEXT2NEXT1 CMPDX BX JLNEXT2MOVDX BX BX取得更小的数据NEXT2 LOOPAGAIN 计数循环MOVMAX AX 保存最大值MOVMIN DX 保存最小值MOVAH 4CHINT21HCODEENDSENDSTART 循环体 again next1 next2 条件控制循环 条件控制循环需要利用特定条件判断循环是否结束条件控制循环用条件转移指令判断循环条件转移指令可以指定目的标号来改变程序的运行顺序 如果目的标号指向一个重复执行的语句体的开始或结束 便构成了循环控制结构 例 显示以0结尾的字符串 数据段stringdb Letushaveatry 0 代码段movbx offsetstringagain movdl bx cmpdl 0jzdone 为0结束movah 2 不为0 显示int21hincbx 指向下一个字符jmpagaindone 条件控制循环先判断后循环 例 记录某个字存储单元数据中1的个数 数据段numberdw1110111111100100B 代码段movbx numberxordl dl 循环初值 DL 0again cmpbx 0 也可以用testbx 0ffffhjzdone 全部是0就可以退出循环 减少循环次数shlbx 1 用指令shrbx 1也可以adcdl 0 利用ADC指令加CF的特点进行计数jmpagain 条件控制循环先判断后循环 子程序设计 把功能相对独立的程序段单独编写和调试 作为一个相对独立的模块供程序使用 就形成子程序子程序可以实现源程序的模块化 可简化源程序结构 可以提高编程效率主程序 调用程序 需要利用CALL指令调用子程序 被调用程序 子程序需要利用RET指令返回主程序 过程定义和子程序编写 汇编语言中 子程序要用一对过程伪指令PROC和ENDP声明 格式如下 过程名PROC NEAR FAR 过程体过程名ENDP可选的参数指定过程的调用属性 没有指定过程属性 则采用默认属性NEAR属性 段内近调用 的过程只能被相同代码段的其他程序调用FAR属性 段间远调用 的过程可以被相同或不同代码段的程序调用 子程序编写注意事项 子程序要利用过程定义伪指令声明 子程序最后利用RET指令返回主程序 主程序执行CALL指令调用子程序 子程序中对堆栈的压入和弹出操作要成对使用 保持堆栈的平衡 子程序开始应该保护使用到的寄存器内容 子程序返回前相应进行恢复 子程序应安排在代码段的主程序之外 最好放在主程序执行终止后的位置 返回DOS后 汇编结束END伪指令前 也可以放在主程序开始执行之前的位置 例 用显示器功能调用输出一个字符的子程序 主程序moval 主程序提供显示字符calldpchar 调用子程序 子程序 显示AL中的字符dpcharproc 过程定义 过程名为dpcharpushax 顺序入栈 保护寄存器pushdxmovdl almovah 02h 02H号输出一个字符功能int21hpopdx 逆序出栈 恢复寄存器popaxret 子程序返回dpcharendp 过程结束 源程序 stacksegmentstack stack db100dup stackendsdatasegmentdataendscodesegmentassumecs code ds data ss stackstart movax datamovds axmoval 主程序提供显示字符calldpchar 调用子程序movax 4c00hint21h 主程序部分 本程序可不需要数据段 源程序 续 子程序部分 dpcharproc 过程定义 过程名为dpcharpushax 顺序入栈 保护寄存器pushdxmovdl almovah 02h 02H号输出一个字符功能int21hpopdx 逆序出栈 恢复寄存器popaxret 子程序返回dpcharendp 过程结束codeendsendstart 子程序安排在主程序执行终止后的位置 子程序编写注意事项 续 子程序允许嵌套和递归 子程序可以与主程序共用一个数据段 也可以使用不同的数据段 注意修改DS 还可以在子程序最后设置数据区 利用CS寻址 子程序的编写可以很灵活 例如具有多个出口 多个RET指令 和入口 但一定要保证堆栈操作的正确性 处理好子程序与主程序间的参数传递问题 提供必要的子程序说明信息 含数据区的子程序 子程序HTOASC 十六进制数转换为ASCII码HTOASCprocpushbxmovbx offsetASCIIandal 0fhxlatCS ASCII 换码 AL CS BX AL popbxret 数据区ASCIIdb30h 31h 32h 33h 34h 35h 36h 37h 38h 39hdb41h 42h 43h 44h 45h 46hHTOASCendp 多出口子程序 子程序HTOASC 十六进制数转换为ASCII码HTOASCprocandal 0fh 清高四位 保留低4位cmpal 9 与9比较jbehtoasc1 小于等于9 跳转addal 37h 是A F 加37Hret 子程序返回htoasc1 add 30h 是0 9 加30Hret 子程序返回HTOASCendp 参数传递 主程序与子程序间一个主要问题是参数传递入口参数 输入参数 主程序调用子程序时 提供给子程序的参数出口参数 输出参数 子程序执行结束返回给主程序的参数参数的具体内容传数值 传送数据本身传地址 传送数据的主存地址常用的参数传递方法寄存器共享变量堆栈 1 用寄存器传递参数 最简单和常用的参数传递方法是通过寄存器 只要把参数存于约定的寄存器中就可以了由于通用寄存器个数有限 这种方法对少量数据可以直接传递数值 而对大量数据只能传递地址 数组首地址 采用寄存器传递参数 注意存有出口参数的寄存器不能保护和恢复 存有入口参数的寄存器可以保护 也可以不保护 但最好能够保持一致 2 用共享变量传递参数 子程序和主程序使用同一个变量名存取数据就是利用共享变量 全局变量 进行参数传递如果主程序还要利用原来的变量值 则需要保护和恢复利用共享变量传递参数 子程序的通用性较差 但特别适合在多个程序段间 尤其在不同的程序模块间传递数据 利用存储单元 变量 传递参数举例 利用子程序来实现数据块间的搬移 设参数传递采用指定内存单元传递方式 且SRCADR中存放源数据块首地址 DSTADR中存放目的数据块首地址 LEN中存放数据块字节数 例 数据块间的搬移 数据块之间的三种情况 数据块之间的三种情况 续 对于 A 的情况可分别从首 末 地址开始传送 而对 B C 两种情况由于有重叠区 应分别对待 当源数据块首址小于目标块首址时 应从数据末址开始传数 如 B 当源数据块首址大于目标块首址时 应从数据首址开始传数 如 C 目的在于避免在传数时将重叠区源数据块的数据冲掉 主程序 STACKSEGMENTPARASTACK STACK DB100DUP DATSRCADRSTACKENDSDATASEGMENTDATDB100DUP SRCADRDDDAT 存放地址的变量DSTADRDDDAT 20 注意有重叠30 LENDW50DSTADRDATAENDSCODESEGMENTASSUMECS CODE DS DATA ES DATA SS STACKSTART MOVAX DATAMOVDS AX 把数据段段基址赋值给段寄存器DS ESMOVES AX 把数据段段基址赋值给段寄存器DS ESCALLMYMOVEMOVAH 4CHINT21H 子程序 MYMOVEPROCLDSSI SRCADR SI 源数据块首地址 偏移地址 LESDI DSTADR DI 目的数据块首地址 偏移地址 MOVCX LEN CX 长度50CLD DF 0 增量CMPSI DI SI 大于 DI 吗 JADONE 大于 则转至DONE 首址传数 如C STD 小于 末址传数 如B DF 1 减量ADDSI CXDECSIADDDI CXDECDIDONE REPMOVSBRETMYMOVEENDPCODEENDSENDSTART 3 用堆栈传递参数 参数传递还可以通过堆栈这个临时存储区 主程序将入口参数压入堆栈 子程序从堆栈中取出参数 子程序将出口参数压入堆栈 主程序弹出堆栈取得它们采用堆栈传递参数是程式化的 它是编译程序处理参数传递 以及汇编语言与高级语言混合编程时的常规方法 利用堆栈传递参数举例 CODESEGMENTASSUMECS CODE DS CODE SS CODESTART JMPMAINDAT1DW100 在代码段定义两个16位的数DAT2DW200SUMDW MAIN MOVAX CODEMOVDS AXMOVAX DAT1 将DAT1压入堆栈PUSHAXMOVAX DAT2 将DAT2压入堆栈PUSHAXCALLADDITION 调用加法子程序MOVSUM AX 存放结果MOVAH 4CHINT21H 返回DOS 例 求两个16位数的和 子程序 ADDITIONPROCNEARMOVBP SPMOVAX BP

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论