Fol*_*den 2 assembly callstack mainframe reentrancy zos
我想编写一个调用自身和其他函数的函数(在hlasm中).
在x86或z80(可能还有其他)上,您只需调用函数,并在其结尾处进行返回.然后处理器将存储和检索返回地址.
指令集有以下指令:BAL reg,func ...将寄存器中的寄存器地址存储在寄存器中,最后你可以将BR寄存器跳转到该寄存器地址.另一个问题是显然没有推/弹指令.
所以我现在有点st ..
问候
在System/360和后继操作系统中,执行此操作的基础结构是所谓的可重入编程的一部分.基本概念是R13指向的保存区域的存储是从操作系统获得的(想想C中的malloc).在程序的最开始使用系统宏调用来获取存储.同样,系统宏调用将存储返回到操作系统,并在程序的出口处进行编码
您还没有提到您正在使用的操作系统.我将对此示例代码进行以下假设:
这个骨架例程是可重入的,因此它也可以递归使用,正如你所提到的那样(有警告说重新调用自身的坏代码最终会导致存储异常终止).代码需要一个基址寄存器,但我建议使用称为"baseless"的现代编码方法,其中代码本身不使用基址寄存器,因为它使用分支的相对和立即指令.(您始终需要一个基本寄存器来存储数据.)
WORKAREA DSECT , Reentrant work area (like C stack)
DS 18F Save area
FIELD1 DS F Some variable
FIELD2 DS F Another variable
WORKLEN EQU *-WORKAREA Length of reentrant work area
SUBRTN1 RSECT , HLASM will perform reentrant checking
STM R14,R12,12(R13) Save registers at entry
LR R12,R15 Set code base register
USING SUBRTN1,R12 Establish code addressability
LGHI R0,WORKLEN Get length of reentrant work area
STORAGE OBTAIN, Obtain reentrant work area X
LENGTH=(0) ..Length is in R0
ST R1,8(,R13) Forward chain in prev save area
ST R13,4(,R1) Backward chain in next save area
L R14,20(,R13) Get R1 at entry (parameters)
LR R13,R1 Set up new save area/reentrant workarea
USING WORKAREA,R13 Establish work area addressability
LM R2,R3,0(R14) Get addresses of parameters
STM R2,R3,FIELD1 Save parameter addresses for later
…
*** Logic goes here
…
LR R1,R13 Address to be released
L R13,4(,R13) Address of prior save area
LGHI R0,WORKLEN Length of storage to release
STORAGE RELEASE, Release reentrant work area X
ADDRESS=(1), ..Address in R1 X
LENGTH=(0) ..Length in R0
LM R14,R12,12(R13) Restore registers
OI 15(R13),X'01' This bit on means this save area is inactive
BR R14 Return to caller
Run Code Online (Sandbox Code Playgroud)
这是一个非常基本的示例,并介绍了一些高级汇编程序概念,如DSECT(虚拟部分),它描述了一个区域,但没有在程序中实际分配存储.RSECT是汇编程序通过在程序试图修改自身时发出警告来强化重入的一种方式.(还有一个汇编程序选项,RENT,但它适用于整个源代码; RSECT仅用于该部分.)
关于这个例子要记住的关键是你有两个基址寄存器,一个寻址代码,一个寻址数据.这与早期的x86架构相似,包括代码段和数据段.在这种情况下,数据段也用作堆栈段.
可重入程序是系统级z/Architecture编程的重要组成部分,因为它实际上是多任务环境所必需的.这是一种重要的技术,可以理解是否可以编写超出典型批处理程序的应用程序(一般意义上).
如果您处于LE环境(COBOL,PL/I,C/C++或汇编程序主程序)中,则应使用LE提供的CEEENTRY和CEETERM宏.LE编译器生成的程序通常是可重入的(即使是带有NORENT选项的COBOL).确保在CEEENTRY宏上编码MAIN = NO,否则会出现各种性能问题和可能的逻辑错误.LE堆栈机制是我在上面演示的技术的高级版本,最值得注意的是分配专用于堆栈使用的大区域,以便后续调用没有调用操作系统来获取存储的开销.
如果您在z/VSE或z/VM环境或非IBM BS2000/OSD环境中工作,我可以修改上面的示例.
请对问题进行评论,我将更新此示例以进一步说明.
| 归档时间: |
|
| 查看次数: |
771 次 |
| 最近记录: |