【发布时间】:2019-09-26 02:22:30
【问题描述】:
我是一名长期的汇编程序员,正在进入 Metal C 的世界。我是一个 C 新手,所以我的术语可能反映了我知道的东西与我正在学习的东西。它肯定会影响我对事物的理解。
我正在尝试将新的 Metal C 代码插入到一些不一定遵循标准入口链接约定的旧组件中。
例如,服务例程将要处理的控制块的地址作为 R1 中的输入。我在关于参数传递的讨论和语言参考中的#pragma 链接讨论中查看了 Metal C 用户指南,似乎没有办法让编译器这样做。
本质上,我想声明一个由以下汇编程序调用的例程:
L R1,MyParm@ Put pointer to Parm into R1
L R15,Routine@ Get address of service routine
BASR R14,R15 Branch to service routine
我意识到我可以采用上述方法,对其进行参数化并将其放入 __asm() 块中,但我希望程序尽可能“干净”。
谢谢, 斯科特
附录 - 2019 年 9 月 26 日
为了回应 Mark Hiscock 在下面的回答,这样的 __asm() 块看起来像:
#define CallwithR1(ParmPtr,RoutinePtr,RC,Rsn) \
__asm( \
" L R1,%2 Get ParmPtr into R1 \n" \
" L R15,%3 Get RoutinePtr into R15 \n" \
" BALR R14,R15 Call the routine \n" \
" ST R15,%0 Save the return code \n" \
" ST R0,%1 Save the reason code \n" \
/* Output variables */ \
: "=m"(RC) /* %0, output only, in-memory */ \
,"=m"(Rsn) /* %1, output only, in memory */ \
/* Input variables */ \
: "m"(ParmPtr) /* %2, input, in-memory */ \
,"m"(RoutinePtr) /* %3, input, in-memory */ \
/* Register clobber list */ \
: "r0" /* R0 clobbered by reason code */ \
,"r1" /* R1 clobbered by linkage code */ \
,"r14" /* R14 clobbered by return addr */ \
,"r15" /* R15 clobbered by return code */ \
);
并且处理起来会简单得多(指令更少,没有绑定时间问题)。我真的在寻找能让编译器“做正确的事”的东西。
斯科特
【问题讨论】:
-
您可能想看看最近在匹兹堡的 SHARE 上发表的这个演示文稿link;你可能会认出主持人????。其中有一个指向云文件夹的链接,其中包含作者如何处理 SMF 出口 IEFACTRT 的示例,不仅 R1 指向一个结构,而且 R0 也具有一个值。 (链接有问题,我会添加评论。)
-
演示文稿中的link 工作正常。请注意,程序中仍有一些我没有时间修复的错误。
-
Ray - 你已经解决了相反的问题,如果使用非标准链接调用 my 程序会怎样。我正在尝试解决我的程序调用 somebody's 程序的问题,该程序期望非标准链接。
-
此外,为了解决“我的外部输入不是标准格式”的问题,我可以通过编写自己的入口序言(如果我的响应是非标准的,则为结语)来解决这个问题。我可能会做一些事情,比如将所有输入放入各种 DSAUSER 字段中,然后在 main 的开头有一个 __asm 来设置指向它们的指针,映射为结构。但我敢肯定还有十几种其他方法...... :-)
-
啊。我现在知道了。除了进入 __asm 并直接拨打电话……是的,不容易。我猜这不是 IBM 服务。 Rocket 已经(或将要发布?)一些用于系统宏的 Metal C API 到 Zowe 项目中。