汇编 |
您所在的位置:网站首页 › 乐高值不值的学 › 汇编 |
汇编-子程序参数传递的三种方式: 寄存器法,堆栈法,参数赋值法 子程序结构如下: 名称 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 |