汇编

您所在的位置:网站首页 乐高值不值的学 汇编

汇编

2024-05-30 07:15| 来源: 网络整理| 查看: 265

汇编-子程序参数传递的三种方式: 寄存器法,堆栈法,参数赋值法

子程序结构如下:

名称 PROC FAR|NEAR ;DO SOMETHING RET [N];返回断点地址,N可忽略,加了必须对SP进行 平栈 操作 名称 ENDP

结合此结构,我们来看,

1.寄存器法

这个方法最简单易用,但是要注意对寄存器的选择,一般选ABCD[X]通用寄存器就可以了。 步骤如下:

1.通过MOV指令将参数存到寄存器

2.再在子程序中调用寄存器即可【注意保护寄存器】

样例就不给了。

2.堆栈法

过程是:

1.先将参数入栈 2.然后在子程序中使用SP,BP,SI这三个寄存器,对栈值(参数)进行取出利用

样例如下:

参数压栈:

MOV CX,01H ; 压入初始奇数1参数 PUSH CX ; 压入结束参数50 MOV CX,50 PUSH CX

子程序参数利用:

; 利用栈指针SP取栈值 MOV BP,SP ; 取结束参数50,字 ; 栈底是高地址段 MOV AX,[BP+2] ; 取初始参数1 MOV BX,[BP+4]

注意: 在利用寄存器取值时要注意参数存储的物理结构,本例参数都是字变量,所以以2为单位进行取值 栈的地段的地址段会越来越高 既是:例如取栈顶时: 应当取SP+2,当然写成[SP+2]是错的, 需要:[BP+2]

如上例。

3.参数赋值法

这一个最是麻烦,但是用会了也就没什么了。

原理如下: 代码段CS定义变量进行参数存储,然后供各个程序模块【子程序,同一源文件】使用【特殊的存取】。 将参数存放到CALL指令后的一串单元中,子程序通过返回地址【断点地址】存取参数并修改返回地址。

步骤是: 在CALL指令调用后,在CS定义自己的数据参数 然后利用SP,BP获取CALL指令执行后的断点地址 此时断点地址后就是对应的参数区 可通过SI取得对应参数

最后在RET前修改栈顶的值为参数区后的地址值【不强制规定,但一般都是】, 做PUSH(一定要先将原断点POP) 就能越过参数区做下一步操作

样例如下:

对参数的定义,

; call求和子程序 CALL sumsub ; 参数定义 NUM DW 50;结束参数 DW 1;初始奇数 ; 输出 NEXT: CALL pf

子程序调用参数:

; 获取断点地址做SI MOV BP,SP MOV SI,[BP] ; 取代码段中变量 ;结束50 MOV AX,CS:[SI+0] ; 开始1 MOV BX,CS:[SI+2] ; ; ;参数利用 ; ; ;修改当前断点【修改栈顶的地址断点】 ;清除默认断点地址 POP CX ;取自己要执行的断点位置地址 MOV CX,OFFSET NEXT ;修改 PUSH CX RET

注意: NEXT是程序返回后要执行的位置【在参数定义后】

CX不做固定,根据自己需要可以更换寄存器,只是不能使得入栈的变量是一个立即数罢了。

在子程序取得了当前执行断点后,开始取定义在CS中的参数, 需要修改默认段基址DS为CS

完。 可能写的不好,但还是求赞! 努力!



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3