2

我是一名长期的汇编程序员,正在进入 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     */ \
);                                                                                                

并且处理起来会简单得多(指令更少,没有绑定时间问题)。我真的在寻找能让编译器“做正确的事”的东西。

斯科特

4

1 回答 1

0

你可以在 C 程序中尝试这样的事情:

#pragma linkage(MYHLASM,OS)

然后像这样调用函数:

MYHLASM(&pointerToParmWhichBecomesR1);

然后汇编器看起来像这样:

MYHLASM  CSECT ,
MYHLASM  AMODE 64
MYHLASM  RMODE 31
         STG   14,12(13)
         LG    2,0(,1)
         USING *,15
         DO SOMETHING WITH THE PARM ADDR WHICH IS NOW IN R2
         LG    14,12(13)
         BR    14
         LTORG
         END

这是一个 64 位示例,MYHLASM 必须在 C 程序的绑定时可用。

希望这可以帮助,

标记

于 2019-09-26T08:31:42.767 回答