当前位置:首页 > 技术学院 > 技术前线
[导读]汇编——子程序调用参数传递的三种方式(示例程序:三个数累加求和)

一、子程序定义

子程序名 PROC NEAR|FAR


RET

子程序名 ENDP

子程序名相当于标号,表示本过程的符号地址。过程有NEAR和FAR两种类型,FAR型的过程可供段间调用,NEAR型过程仅供段内调用。

在一个过程中,至少要有一条返回指令RET,它可以书写在过程中的任何位置,但是过程执行的的最后一条指令一定是RET。

二、子程序调用指令

格式:CALL [NEAR PTR] 子程序名

CALL指令的两个作用,1.将断点地址(CALL指令的下一条指令地址)压栈保存,2.转去子程序执行。

[NEAR PTR]可以省略。

三、返回指令

格式:RET [N]

指令作用:实现子程序执行完后返回主程序的指令。从堆栈栈顶弹出一个字数据(段内调用)送入IP作为返回地址。N是立即数,执行完RET之后,再将SP增加N,也叫“平栈”。

四、子程序参数传递的三种方式:

程序示例:假设:N1=1234H,N2=2345H,N3=3456H,计算并显示这3个数的累加和,并用二进制形式显示结果

1.通过寄存器传递参数:调用子程序前,调用程序把入口参数放在约定的寄存器中,子程序执行时,通过约定的寄存器取得入口参数;返回时,子程序把出口参数存放在约定的寄存器中,调用程序通过约定的寄存器中取得出口参数。

DATA SEGMENT

NUM DW 1234H

DW 2345H

DW 3456H

DATA ENDS

STACKS SEGMENT STACK

DB 100 DUP(?)

STACKS ENDS

CODE SEGMENT

ASSUME CS:CODE,DS:DATA,SS:STACKS

BEG: MOV AX,DATA

MOV DS,AX

MOV SI,OFFSET NUM

CALL COMPUTE

XYZ: CALL DISP

MOV AH,4CH

INT 21H

COMPUTE PROC

MOV BX,0

ADD BX,[SI+0]

ADD BX,[SI+2]

ADD BX,[SI+4]

RET

COMPUTE ENDP

DISP PROC

MOV CX,16

LAST: MOV DL,'0'

RCL BX,1

JNC NEXT

MOV DL,'1'

NEXT: MOV AH,2

INT 21H

LOOP LAST

RET

DISP ENDP

CODE ENDS

END BEG

本例程序中调用程序把2号功能入口参数放在DL寄存器中,显示子程序在执行时从DL中取得参数。

2.通过堆栈传递参数:子程序调用前,调用程序把参数依次压入堆栈,构成一个堆栈参数表,当子程序调用时,子程序从堆栈中取出各参数。子程序返回时,要使用 RET n 指令调整SP指针,其中n是堆栈参数表的大小,即使用完堆栈之后删除堆栈参数表,使堆栈恢复到原始状态,也就是文章开始提到的“平栈”。

DATA SEGMENT

NUM DW 1234H

DW 2345H

DW 3456H

DATA ENDS

STACKS SEGMENT STACK 'STACK'

DB 100 DUP(?)

STACKS ENDS

CODE SEGMENT

ASSUME CS:CODE,DS:DATA,SS:STACKS

BEG: MOV AX,DATA

MOV DS,AX

MOV SI,OFFSET NUM

PUSH WORD PTR [SI+0]

PUSH WORD PTR [SI+2]

PUSH WORD PTR [SI+4]

CALL COMPUTE ;注意CALL指令隐含的堆栈操作

XYZ: CALL DISP

MOV AH,4CH

INT 21H

COMPUTE PROC

MOV BP,SP

MOV BX,0

ADD BX,[BP+2] ;栈底处在高地址段

ADD BX,[BP+4]

ADD BX,[BP+6]

RET 6

COMPUTE ENDP

DISP PROC

MOV CX,16

LAST: MOV DL,'0'

RCL BX,1

ADC DL,0

NEXT: MOV AH,2

INT 21H

LOOP LAST

RET

DISP ENDP

CODE ENDS

END BEG

3.通过变量传递参数:如果子程序和调用程序都在同一个源文件中,则双方可以直接访问模块中的变量,从而实现参数传递。

STACKS SEGMENT STACK 'STACK’

DB 100 DUP(?)

STACKS ENDS

CODE SEGMENT

ASSUME CS:CODE,SS:STACKS

BEG: CALL COMPUTE

NUM DW 1234H

DW 2345H

DW 3456H

XYZ: CALL DISP

EXIT: MOV AH,4CH

INT 21H

COMPUTE PROC

MOV BP,SP

MOV SI,[BP+0] ; [BP+0]为断点地址

MOV BX,0

ADD BX,CS:[SI+0]

ADD BX,CS:[SI+2]

ADD BX,CS:[SI+4]

POP AX ;弹出原来的断点地址

MOV AX,OFFSET XYZ ;改变栈顶内容,从而使返回地址改变

PUSH AX

RET ;返回断点XYZ

COMPUTE ENDP

DISP PROC

MOV CX,16

LAST: MOV AL,'0'

RCL BX,1

ADC AL,0

NEXT: MOV AH,0EH ;BIOS功能调用显示一个字符

INT 10H

LOOP LAST

RET

DISP ENDP

CODE ENDS

END BEG

这个例子没有我们常见的数据段,二是把数据定义在了代码段,子程序在执行时,需要用数据时,访问存放数据的内存单元,并且在子程序执行要结束时,改变原来的断点地址,跳过代码段中的数据存储区,到下一片段的执行代码区。

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

LED驱动电源的输入包括高压工频交流(即市电)、低压直流、高压直流、低压高频交流(如电子变压器的输出)等。

关键字: 驱动电源

在工业自动化蓬勃发展的当下,工业电机作为核心动力设备,其驱动电源的性能直接关系到整个系统的稳定性和可靠性。其中,反电动势抑制与过流保护是驱动电源设计中至关重要的两个环节,集成化方案的设计成为提升电机驱动性能的关键。

关键字: 工业电机 驱动电源

LED 驱动电源作为 LED 照明系统的 “心脏”,其稳定性直接决定了整个照明设备的使用寿命。然而,在实际应用中,LED 驱动电源易损坏的问题却十分常见,不仅增加了维护成本,还影响了用户体验。要解决这一问题,需从设计、生...

关键字: 驱动电源 照明系统 散热

根据LED驱动电源的公式,电感内电流波动大小和电感值成反比,输出纹波和输出电容值成反比。所以加大电感值和输出电容值可以减小纹波。

关键字: LED 设计 驱动电源

电动汽车(EV)作为新能源汽车的重要代表,正逐渐成为全球汽车产业的重要发展方向。电动汽车的核心技术之一是电机驱动控制系统,而绝缘栅双极型晶体管(IGBT)作为电机驱动系统中的关键元件,其性能直接影响到电动汽车的动力性能和...

关键字: 电动汽车 新能源 驱动电源

在现代城市建设中,街道及停车场照明作为基础设施的重要组成部分,其质量和效率直接关系到城市的公共安全、居民生活质量和能源利用效率。随着科技的进步,高亮度白光发光二极管(LED)因其独特的优势逐渐取代传统光源,成为大功率区域...

关键字: 发光二极管 驱动电源 LED

LED通用照明设计工程师会遇到许多挑战,如功率密度、功率因数校正(PFC)、空间受限和可靠性等。

关键字: LED 驱动电源 功率因数校正

在LED照明技术日益普及的今天,LED驱动电源的电磁干扰(EMI)问题成为了一个不可忽视的挑战。电磁干扰不仅会影响LED灯具的正常工作,还可能对周围电子设备造成不利影响,甚至引发系统故障。因此,采取有效的硬件措施来解决L...

关键字: LED照明技术 电磁干扰 驱动电源

开关电源具有效率高的特性,而且开关电源的变压器体积比串联稳压型电源的要小得多,电源电路比较整洁,整机重量也有所下降,所以,现在的LED驱动电源

关键字: LED 驱动电源 开关电源

LED驱动电源是把电源供应转换为特定的电压电流以驱动LED发光的电压转换器,通常情况下:LED驱动电源的输入包括高压工频交流(即市电)、低压直流、高压直流、低压高频交流(如电子变压器的输出)等。

关键字: LED 隧道灯 驱动电源
关闭