Home > Coding, Mainframe > Mixing it up with C and assembler with METALC (Part 2)…

Mixing it up with C and assembler with METALC (Part 2)…

Following on from my earlier post, here’s a version of the reverse string program that is ‘closer’ (but still no cigar yet):

                                                   
#include <stdio.h>                                                      
#include <stdlib.h>                                                     
#include <string.h>                                                     

char * reverse( char * in) {                                            
    int l = strlen(in);                                                 
    char * work;                                                        

    if (l>0) {                                                          
    work = malloc(l);        // get a temp work area                    
       __asm(                                                           
         "      PUSH  USING                     \n"                     
         "      DROP  ,                         \n"                     
         "      BASR  4,0                       \n"                     
         "      USING *,4                       \n"                     
         "      LR    1,%1     LENGTH           \n"                     
         "      LA    2,%0     TARGET           \n"                     
         "      LA    3,%2     SOURCE           \n"                     
         "      BCTR  1,0                       \n"                     
         "      LA    3,0(1,3) LAST CHAR of SRC \n"                     
         "      EX    %1,MVCIN                  \n"                     
         "      J     PASTMOVE                  \n"                     
         "MVCIN MVCIN 0(0,2),0(3)               \n"                     
         "PASTMOVE DS 0H                        \n"                     
         "      POP   USING                     \n"                     
         :"=m"(work) : "r"(l), "m"(in)                                  
         :"r1", "r2","r3","r4"                                          
       );                                                               
    memcpy(in,work,l);       // copy reversed string in work to orig    
    free(work);              // release work area                       
    }                        // input area                              

    return in;               // return same string back to caller       
}                                                                       

int main()                                                              
{                                                                       
   char c[21]="12345";             // String to reverse                 

   printf("input=($s)",c);         // print input string                
   reverse(c);                     // reverse it in place               
   printf("output=($s)",c);        // print revered string              

   return 0;                                                            
}

At Least this compiles although it will not link edit because it seems there is NO printf function in Metal C!

You can see that my little one line of assembler has become somewhat longer as a result of the way you have to pass parameters into the embedded code and the fact that since the MVCIN instruction has the move length encoded in the instruction at assembly time, the only way to make it variable is to use an EXECUTE instruction. I also had to mess around with code base registers and assign this little bit of code it’s own base register so that the execute instruction has addressability to the MVCIN instruction.

At least I added some length checking code so that it did not try to do with move with a zero length which would of course result in a 256 character move and resultant storage overlay.

Still an interesting exercise though.

Advertisements
Categories: Coding, Mainframe
  1. No comments yet.
  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: