在我的上一篇博文中,我简单的向大家介绍了汇编语言程序设计的三种基本方式。在一个程序中的不同地方,常常需要多次非循环的使用完成特定功能的程序段,这些程序段除了某些变量的赋值不同外,具有相同的指令序列,这时,我们为了减少重复编写程序,缩短目标代码,节省内存空间,把视线这一功能的指令序列组成一个相对独立的程序段。这也就是我们这片文章中所要讨论的子程序。

子程序相当于高级语言(比如C语言)中的过程和函数,在汇编语言中子程序也称为过程。使用子程序的好处:
a、有利于程序模块化、结构化和自顶向下的程序设计方法,简化了程序设计过程。
b、增加了源程序的可读性,便于调试维护
c、减少了目标代码锁占用的空间
d、子程序一旦编制成功,在开发研制各种软件时都可使用,缩短了软件的开发周期。
一、子程序的调用与返回
1、子程序的定义
子程序必须定义在一个逻辑段内,子程序的定义由过程定义伪指令PROC/ENDP来实现,它们分别用在程序的子程序的前后,一般格式如下:
  1. PROC_NAME   PROC    [NEAR/FAR]
  2. ......
  3. PROC_NAME   ENDP
其中PROC_NAME为子程序名,也极为CALL的操作数,自程序具有3个属性:段属性、偏移量属性和类型属性,段属性表示该子程序所在段的段基值。偏移量属性表示该子程序在段中的偏移量。类型属性也称为距离属性,可以是NEAR或FAR,属性为NEAR的子程序只能在本段内调用,属性为FAR的子程序则可以在本段以内以及其他段中调用。
2、调用指令
当主程序属性是NEAR的子程序时,CPU把当前指令指针IP的内容压入堆栈,作为返回地址保存起来,然后将子程序的偏移量送入IP,当从子程序返回时,将从堆栈弹出2个字节的返回地址送入IP,当调用属性是FAR的过程时,CPU把当前的段寄存器CS与指令指针IP的内容都压入堆栈,作为返回地址保存起来,然后将子程序的段基值与偏移量送入CS与IP,当子程序返回时,将从堆栈弹出4个字节的返回地址分别送入IP与CS。
我们容易知道,当主程序和子程序处于同一逻辑段时,可以把类型属性定义为NEAR,也可以把类型属性定义为FAR,然后进行调用。而当主程序与子程序不在同一逻辑段是,只可把过程的类型定义为FAR,然后调用。
二、返回指令
返回指令RET是子程序逻辑上的最后一条指令,也就是最后一条被执行的指令,它使子程序在完成功能后返回到调用它的CALL指令的后续指令处,即返回地址处继续执行。
三、子程序设计的基本要求
1、子程序必须有一定的通用性
2、注意寄存器的保存和恢复
3、正确使用堆栈
4、选用适当的方法在主程序与子程序间进行参数传递
5、编制子程序说明信息文件
四、子程序与主程序间的参数传递
在汇编语言中最常用的参数传递方式有3种,分别是:用寄存器传递参数、用堆栈传递参数和用地址表达式传递参数。
1、用寄存器传递参数
这种方式是通过通用寄存器来传递的参数,即在主程序调用子程序前,将入口参数送到约定的通用寄存器中,子程序可以直接从这些寄存器中取出参数进行加工处理,并将结果放在约定的通用寄存器中,返回主程序,主程序再从约定的寄存器中取出结果,我们一例子来说明问题:
例:将两个给定的二进制数(8位和16位)转换为ASCII码字符串。
分析:主程序提供呗转换的数据和转化后的ASCII码字符串的存储区的首地址。子程序完成二进制的转换。为了提高子程序的代码转换通用性,它可以完成8位或16位数的转换。设调用子程序时,入口参数为:被转换的数在DX中,若位数小于16,则从高到低存放,转换后的ASCII码的存放首地址在DI中。下面给出一种实现方法:
  1. DATA    SEGMENT
  2. BIN1    DB  35H
  3. BIN2    DW  0AB48H
  4. ASCBUF  DB  20H DUP  (?)
  5. DATA    ENDS
  6. STACK1  SEGMENT PARA    STACK
  7. DW  20H DUP  (0)
  8. STACK1  ENDS
  9. CODE    SEGMENT
  10. ASSUME  CS:CODE, DS:DATA, SS:STACK1
  11. BEGIN:  MOV AX, DATA
  12. MOV DS, AX
  13. XOR DX, DX
  14. LEA DI, ASCBUF      ;存放ASCII码的单元首地址送DI
  15. MOV DH, BIN1            ;待转换的第一个数据送DH
  16. MOV AX, 8           ;待转换的二进制数的位数送AX
  17. CALL    BINASC
  18. MOV DX, BIN2
  19. MOV AX, 16
  20. LEA DI, ASCBUF
  21. ADD DI, 8           ;设置下一个数的存放首地址
  22. CALL    BINASC
  23. MOV AH, 4CH
  24. INT     21H
  25. BINASC  PROC
  26. MOV CX, AX
  27. LOP:    ROL DX, 1           ;最高位移入最低位
  28. MOV AL, DL
  29. AND AL, 1           ;保留最低位,屏蔽其他位
  30. ADD AL, 30H
  31. MOV [DI], AL            ;存结果
  32. INC DI          ;修改地址指针
  33. LOOP    LOP
  34. RET
  35. BINASC  ENDP
  36. CODE    ENDS
  37. END BEGIN
2、用堆栈传递参数
这种方法是主程序先将入口参数压入堆栈,子程序从堆栈中把参数读出,进行加工处理。这里要注意从堆栈中读取数据与从堆栈中弹出数据是有区别的,从堆栈中读取数据并不改变堆栈的栈顶指针SP,而从堆栈中弹出的数据,则需修改SP,在使用堆栈传递参数时,要保证堆栈状态的正确。
我们还以上面的例子来说明下问题,这次采用堆栈传递参数
分析:如果使用堆栈,一般用包括:
a、在主程序中,将待转换的数据、存放ASCII码的首地址和转换的位数压入栈中
b、在子程序中保存信息
下面我们依然用程序说明问题,在程序的必要处我已经做了注释
  1. DATA    SEGMENT
  2. BIN1    DB  35H
  3. BIN2    DW  0AB48H
  4. ASCBUF  DB  20H DUP  (?)
  5. DATA    ENDS
  6. STACK1  SEGMENT PARA    STACK
  7. DW  20H DUP  (0)
  8. STACK1  ENDS
  9. CODE    SEGMENT
  10. ASSUME  CS:CODE, DS:DATA, SS:STACK1
  11. BEGIN:  MOV AX, DATA
  12. MOV DS, AX
  13. MOV AH, BIN1
  14. PUSH    AX              ;待转换数据压栈
  15. MOV AX, 8
  16. PUSH    AX              ;待转换位数压栈
  17. LEA DI, ASCBUF
  18. PUSH    DI          ;存放ASCII码的首地址压栈
  19. CALL    BINASC              ;调用转换子程序
  20. MOV AX, BIN2
  21. PUSH    AX
  22. MOV AX, 10H
  23. PUSH    AX
  24. ADD DI, 8
  25. PUSH    DI
  26. CALL    BINASC
  27. MOV AH, 4CH
  28. INT     21H
  29. BINASC  PROC
  30. PUSH    AX
  31. PUSH    CX
  32. PUSH    DX
  33. PUSH    DI
  34. MOV BP, SP
  35. MOV DI, [BP+10]         ;从堆栈取出入口参数
  36. MOV CX, [BP+12]
  37. MOV DX, [BP+14]
  38. LOP:    ROL DX, 1
  39. MOV AL, DL
  40. AND AL, 1
  41. ADD AL, 30H
  42. MOV [DI], AL
  43. INC DI
  44. LOOP    LOP
  45. POP DI
  46. POP DX
  47. POP CX
  48. POP AX
  49. RET 6           ;返回并从堆栈中弹出6个字节
  50. BINASC  ENDP
  51. CODE    ENDS
  52. END BEGIN
3、用地址表传递参数
当要传送的参数较多时,可在主程序中建立一个地址表,在调用子程序前,把所有参数的地址依次存放在该地址表中,然后把地址表的首地址通过寄存器传送到子程序中去,而在子程序中,按照地址表中给出的地址逐个取出参数,用地址表传递参数的方法,在入口参数比较多时很方便,当返回参数较多时,可用同样的方法传递参数,供主程序使用。

转载于:https://blog.51cto.com/yiluohuanghun/940566

那些年,我们一起学过的汇编----之子程序设计相关推荐

  1. 生物系统和疾病的多组学数据整合考虑和研究设计

    生物系统和疾病的多组学数据整合考虑和研究设计 1 生物系统 生物系统--组成 生物系统很复杂,具有许多调节功能,例如DNA,mRNA,蛋白质,代谢物,以及表观遗传功能(例如DNA甲基化和组蛋白翻译后修 ...

  2. 东方时尚网上约车的用户名密码是什么_网站制作要学什么、在现代网页设计中,动效常见的几种用法...

    常听到有人这样问:"网站制作要学什么"和"在现代网页设计中,动效常见的几种用法"有什么关系和内在关联?导航设计是网页可用性的基石.记住,如果用户在您的网站里找不 ...

  3. 学美工、平面设计、UI设计,哪个有前途?

    首先,在分析学美工.平面设计.UI设计,哪一个更有前途的时候,先要对三类设计有一个大概的了解. 比如"学美工.平面设计.UI设计是什么"等知识,才能更好地去进行选择. 01 阐述美 ...

  4. 汇编-循环结构程序设计和子程序设计

    循环结构程序设计和子程序设计 实验内容 算法描述 实验结果 源程序清单 实验内容 设DATA1开始的内存单元中,存放着一串带符号字数据,要求采用冒泡排序算法(Bubble Sort)按照从小到大的顺序 ...

  5. 学美工、平面设计、UI设计,哪个更有前途?

    首先,在分析学美工.平面设计.UI设计,哪一个更有前途的时候,先要对三类设计有一个大概的了解. 比如"学美工.平面设计.UI设计是什么"等知识,才能更好地去进行选择. 01 阐述美 ...

  6. 合肥工业大学宣城校区计算机大赛,合肥工业大学宣城校区“建行杯”计算机设计大赛 颁奖典礼举行...

    4月11日下午,合肥工业大学宣城校区"建行杯"计算机设计大赛颁奖典礼在教学楼114室举行.宣城校区领导陈朝阳.田作淳.蒋传东.胡学钢及各部门负责人.各系部主任,学校教务部副教务长张 ...

  7. 那些年,我们一起学过的汇编----之伪指令

    弄懂了前面几篇关于基础的文章,下面就开始我们真正的汇编之旅了,在这一篇中我们着重来强调下汇编语言的伪指令.伪指令是汇编语言程序设计中的一个主要的部分,属于控制命令,在汇编语言中的数据定义.存储单元分配 ...

  8. 哈哈日语 日语五十音学记资料汇编

    每个小格内从左至右依次为:平假名.片假名.罗马读音.(括号内是与其他重复的) 新人加+日语群:376675070,,每天都有免费课程~! 表的横向称为[行],每行五个假名,共十行. 纵向称为[段],每 ...

  9. ui设计和python哪个容易学_软件开发和ui设计那个容易学?

    感谢邀请,以下是我的一些亲身经历,想和大家分享. 真心的!建议哪怕是念完一个普通高中,也比现在直接去学那些职业技能要好,学历高一点,你面对的选择.能做的选择也会更多一些,能够拓宽你未来的职业路. 初中 ...

  10. 【嵌入式实验】《ARM汇编与接口设计》

    嵌入式实验 一.实验目的 二.实验内容 三.预备知识 四.实验设备及工具(包括软件调试工具) 五.实验步骤 5.1 ADS开发工具安装和使用 插话 5.2 arm-linux-gcc编译工具安装和使用 ...

最新文章

  1. Javapinyin4J实现中文名转拼音
  2. java 连接数据库之一个完整的函数
  3. zend studio for Eclipse注册码及汉化
  4. C# 中奇妙的函数 -- 1. ToLookup
  5. 【数据结构与算法】之深入解析“K个一组翻转链表”的求解思路与算法示例
  6. 搜索旋转排序数组—leetcode31
  7. python字符串截取方法_如何使用python语言中的字符串方法截取字符串
  8. LeetCode 92反转链表||-中等
  9. Java剪切板操作大全
  10. I Think I Can!
  11. 蚂蚁课堂二期视频(每特学院二期)
  12. js通过开始时间和结束时间计算出中间的所有日期
  13. Mac重装Homebrew
  14. [USACO] Team Tic Tac Toe
  15. 计算机社团感恩节免费维修周策划书,【关于感恩节的活动策划】大学感恩节活动策划案_早教感恩节活动策划方案_(2)_亲亲宝贝网...
  16. python Gstreamer 播放不同编码格式的视频文件
  17. linux快速查找文件
  18. KeilC51_v960版201905((含汉字补丁,STC15说明书,stc-isp-15xx-v6.86S).7z
  19. oracle创建视图与生成唯一编号
  20. System.Globalization 命名空间

热门文章

  1. 从零基础入门Tensorflow2.0 ----一、3.4 实战深度神经网络(dropout)
  2. pyinstaller库的使用——将Python语言脚本打包成可执行文件的第三方库
  3. 重写Java中equals和hashcode方法的一般规则
  4. arcpy 创建弧度制与十进制互换的个人工具箱
  5. ArcGIS 地表TIN面数据的符号化
  6. 【ArcGIS|空间分析】图像纠正
  7. PHP kafka消息队列的使用
  8. java 枚举嵌套枚举_java – 如何使用枚举与分组和分组层次/嵌套
  9. 安卓直播详细教程(一)-----bilibili开源播放器
  10. 老码农最后都去哪了?