编制汇编语言源程序时,首先要使用段定义伪指令和段寻址内容摘要:

右移 1位 LOOP LL ;循环控制 MOV COUNT,BL ; COUNT← 计数器 BL的值 MOV AH,4CH ;返回 DOS INT 21H CODE ENDS END BEGIN 例 : 将正整数 NUM插入到一个从小到大排列好顺序的正整数字节数组序列中。 分析: 假设该数组的首地址和末地址分别为 ARRAY_HEAD、ARRAY_END, 显然在这里需要插入的是一个数 , 所以不一定要扫描 整个数组。 同时为了插入这个数据 , 必须要空出位置 ,即凡是比它大的数据都应该向地址增大的方向移动一个字节 ,故应该从数组的尾部向头部查找 , 可逐字节取出比较。 值得注意的是 , 应该考虑正整数 NUM大于或小于数组中的所有数的可能 , 即如果 NUM大于数组中所有数 , 则第一次比较就可以结束查找;如果 NUM小于数组 中所有数 , 则必须及时结束查找 , 绝对不允许查找的范围超出数组的首地址 , 当然可以把数组的首地址或循环次数作为结束查找的条件。 根据上述分析 ,可以得出程序流程如 图 : YN修改地址指针:SI←(SI)1循环次数计数:CX←(CX)1NCX=0?结 束Y(ARRAY[SI])与(ARRAY[SI+1])交换ARRAY[SI+1]←ALAL←0插入数据NUMSI←0数组末偏移地址CX←数组元素个数开 始(ARRAY[SI])(AL)?图 例 参考程序: NUM EQU 36H DATA SEGMENT ARRAY DB 12H,24H,48H,60H,72H,84H Y DB ? DATA ENDS CODE SEGMENT ASSUME CS:CODE,DS:DATA BEGIN: MOV AX,DATA MOV DS,AX MOV CX,YARRAY ;循环次数初始化 MOV AL,NUM ;插入值送 AL LEA SI,Y DEC SI ;取得 ARRAY的最后元素的偏移地址 LOP: CMP ARRAY[SI],AL ;比较 JLE INSERT MOV AH,ARRAY[SI] MOV ARRAY[SI+1],AH ;数据交换 DEC SI ;修改偏移地址 LOOP LOP INSERT:MOV ARRAY[SI+1],AL ;插入数据 MOV AH,4CH INT 21H CODE ENDS END BEGIN 167。 子程序设计 167。 子程序的构造 前面我们学习了过程定义伪指令 , 我们也就是用它们来构成的子程序 ,其格式为: 子程序名 PROC ( NEAR/FAR) 保存信息 …… 恢复信息 RET 子程序名 ENDP 167。 子程序的调用与返回 子程序的正确执行是由子程序的正确调用和返回保证的。 IBM PC机的 CALL和 RET指令就分别完成了子程序的调用和返回功能。 : CALL 过程名 执行 CALL指令 , 首先保留断点地址于堆栈中 , 然后转移到目标单元 , 它对 PSW无影响。 : RET 一个子程序执行的最后一条指令必定是返回指令 RET,用以返回到调用子程序的断点处。 但在位置上并不一定就是是最后一条指令。 它的位置灵活,并不是必须要在最后。 只是习惯上我们通常将它置于子程序的最后。 167。 编制子程序的要求 要注意最先压入堆栈的应该最后弹出来 , 值得注意的是:必须搞清楚那些 寄存器是必须保存的 , 那些又是不必要或不应该保存的。 一般来说 , 子程序中用到的寄存器是应该保存的 , 但是 如果主程序和子程序之间使用寄存器传递参数的话 ,该寄存器则不一定需要保存 , 特别是用来向主程序回送结果( 即出口参数 ) 的寄存器 , 则更不应该因保存和恢复该寄存器的内容而破坏了应该向主程序传送的信息。 这种主程序与子程序之间的信息传送称为参数传递 , 它可以有以下三种: ① 用寄存器传递参数 这是最常用的一种方式 , 通常在参量不多的时候使用这种方法。 ② 用地址表传递参数 通过地址表传送参数的方法是在主程序中首先建立一个地址表 , 把要传送给子程序的参数都存放在地址表中 , 然后把地址表的首地址通过寄存器传送到子程序中去; 最后子程序通过地址表取得所需参数。 ③ 用堆栈传递参数 这种方法是在主程序中把要传送给子程序的参数先保存到堆栈中 , 然后子程序再从堆栈中取出参数以达到传送参数的目的。 167。 高级汇编语言技术 167。 宏汇编 1. 宏定义 宏在使用前必须先进行宏定义。 宏定义格式为: 宏指令名 MACRO 形式参数 , 形式参数 , … <宏体> ENDM 其中 , 宏指令名:宏定义的名字 ( 即给宏体中程序段指定一个符号名 ) , 不可缺省 , 宏调用时要使用它 , 第一个符号必须是字母 , 其后可以是字母或数字 MACRO… ENDM:宏定义伪指令助记符 , 不可缺省。 它们成对出现 , 表示宏定义的开始和结束 , ENDM前不带宏指令名。 宏体:一段有独立功能的程序代码段。 形式参数:又称哑元 , 各个哑元之间用逗号隔开 , 可以缺省。 2. 宏调用 经宏定义后的宏指令可以在源程序中调用 , 宏调用格式为: 宏指令名 实参 , 实参 … 宏调用只需要有宏指令名 , 若宏定义中有形参 , 那么宏调用时必须带有实际参数来替代形参 , 实际参数的个数 , 顺序 , 类型与形参一一对应 , 各个实参之间用逗号分开。 原则上实参的个数与形参的个数相等 , 但汇编程序不要求它们必须相等 , 若实参 个数大于形参个数 , 则多余的实参不予考虑 , 若实参个数小于形参个数 , 则多余的形参作“ 空 ” 处理。 3. 宏展开 汇编程序在对源程序汇编时 , 对每个宏调用作宏展开 ,每条插入的宏体指令前带上加号 “ +”。 例 : 不带参数的宏定义 , 用宏指令来实现回车换行。 宏定义: CRLF MACRO MOV DL,0DH。 回车 MOV AH,2 INT 21H MOV DL,0AH。 换行 MOV AH,2 INT 21H ENDM 宏调用: CRLF 宏展开:将下述程序段替换宏调用语句。 + MOV DL,0DH。 回车 + MOV AH,2 + INT 21H + MOV DL,0AH。 换行 + MOV AH,2 + INT 21H 宏定义中的参数可以有多个 , 实参可以是数字 , 寄存器或操作码。 宏定义还可用部分操作码作参数 , 但在宏定义中必须用 “ amp。 ”作分隔符 , amp。 是一个操作符 , 它 在宏定义体中可作为哑元的前缀 , 宏展开时 , 可以把 amp。 前后两个符号合并成一个符。
阅读剩余 0%
本站所有文章资讯、展示的图片素材等内容均为注册用户上传(部分报媒/平媒内容转载自网络合作媒体),仅供学习参考。 用户通过本站上传、发布的任何内容的知识产权归属用户或原始著作权人所有。如有侵犯您的版权,请联系我们反馈本站将在三个工作日内改正。