Передача параметра - нестандартная связь - PullRequest
2 голосов
/ 26 сентября 2019

Я долгое время программист на ассемблере, переезжаю в мир Metal C. Я очень новичок в C, поэтому моя терминология может отражать то, что я знаю, и то, что я изучаю.Это определенно раскрасит то, как я понимаю вещи.

Я пытаюсь вставить новый код Metal C в некоторые старые компоненты, которые не обязательно следуют стандартным соглашениям о связывании записей.

Например, служебная процедура принимает в качестве входа в R1 адрес блока управления для обработки.Я посмотрел в Руководстве пользователя Metal C обсуждение обсуждения передачи параметров и обсуждение связи #pragma в справочнике по языку, и, похоже, нет способа заставить компилятор сделать это.

По сути, я хочу объявить подпрограмму, вызываемую следующим ассемблером:

     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 ​​(), но я бы хотелхотелось бы, чтобы программа была «чистой», насколько это возможно.

Спасибо, Скотт

Приложение - 26 сентября 2019

Чтобы ответить на ответ Марка Хискока ниже, такой __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     */ \
);                                                                                                

, и с ним будет гораздо проще иметь дело (меньше инструкций, нет проблем со связыванием).Я действительно ищу что-то, что позволяет компилятору "делать правильные вещи".

Скотт

1 Ответ

0 голосов
/ 26 сентября 2019

Вы можете попробовать что-то вроде этого в программе на Си:

#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 должен быть доступен во время привязки программы на Си.

Надеюсь, это поможет,

Mark

...