Archive

Archive for the ‘Coding’ Category

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

July 29, 2013 Leave a comment

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.

Categories: Coding, Mainframe

Mixing it up with C and assembler with METALC..

July 27, 2013 4 comments

A few months ago I posted this sample C code to reverse a character string:

// Reverse a string

#include <iostream>
#include <string.h>

using namespace std;

char * reverse( char * p) {
    char * e;
    char * s;                // Copy ptr because I am going to mess with it
    int l = strlen(p);
    s=p;                     // first char ptr
    e = p+l-1;               // last char ptr

    char * m;                // mid point of the string
    m=s+l/2;                 // set it (int arith drops remainder if odd length

    for (;s<m;s++) {         // just need to traverse half the string
        s[0]=s[0]^e[0];      // swap curr leading and current last byte
        e[0]=e[0]^s[0];      // using xor
        s[0]=s[0]^e[0];
        e--;                 // back up 1 from end
        }
    return p;                // return same string back to caller

    }

int main()
{
   char c[21]="12345";             // String to reverse
   cout << reverse(c)<<'\n';       // reverse and print result
   cout << c;                      // orig string also reversed
   reverse(c);                     // reverse in place
   cout <<'\n'<<c;                 // show it is reversed

   return 0;
}

Pretty standard loop driven stuff and ‘adequate’ shall we say.

One of my ‘to do’ items this year is to go through the POP (principles of operation) manual and update my knowledge of a lot of the new instructions in there as it’s been forever since I last did that. Anyway, one of the instructions I came across was MVCIN or Move Inverse. This is a bit like MVC (Move Characters) except that it reverses the string as it moves it. Cool, except that we are in C and that is an assembler instruction and it’s a lot of extra work to write a sub routine you could call from a C program to do that.

But wait, there’s more (otherwise this would be a pointless post!)…

On the z/OS mainframe, the run time environment for C (and other programming languages like Cobol and PL/I) is normally provided by Language Environment (LE). BUT! If you use the C compiler option METALC, you can compile C code that has NO LE dependency. It is completely stand alone. Not only that but you can embed small snippets of ASSEMBLER code directly into your C source code and it compiles just like part of the regular program.

What this means is that I can replace that ugly for loop in the code above with a SINGLE instruction that will do the same thing, and do it far more efficiently than that loop will.

Now bear in mind I have not tried this code yet so it may need some tweaking but this is what I have so far:

// Reverse a string

#include <iostream>
#include <string.h>

using namespace std;

char * reverse( char * in) {

    int l = strlen(in);
    char * work;
    work = new char[l];         // get a temp work area 

    __asm (     
      "    MVCIN %0(%1),0(%2)      \n"  
      :"=m"(work) : r(l), "m"(in[l-1])                         
    );   

    memcpy(in,work,l);       // copy reversed string in work to orig input area
    delete [] work;          // release work area

    return in;               // return same string back to caller

}                                        

    }

int main()
{
   char c[21]="12345";             // String to reverse
   cout << reverse(c)<<'\n';       // reverse and print result
   cout << c;                      // orig string also reversed
   reverse(c);                     // reverse in place
   cout <<'\n'<<c;                 // show it is reversed

   return 0;
}

I have to allocate a work area to receive the reversed string since you cannot overlay the source with the output so the question becomes, is the cost (in CPU time) of allocating that work area and releasing it greater than the saving incurred by switching to a hardware instruction to do the reverse. You could however get around that to some extent by requiring the caller to provide the work area.

The only other downside is that this instruction is limited to 256 character strings so for anything longer you would have to implement some sort of loop but even so, the fact that you could reverse the string in 256 byte chunks must have some performance improvement implications.

In case you are wondering, the %0, %1 and %2 represent the positional parameters below the instruction. The fields after the first colon are output fields and the fields after the second colon are input parameters.

The parameter (“=m”(work) after the first colon tells the compiler this is an output field, it will be modified by the code and that it is a memory reference.

The two parameters (r(1) and “m”(in[l-1]) are input parameters. r(1) means this should be a register and the second memory reference (the source string) is a memory reference. It has to be the address of the LAST character of the source string, not the first, hence the [l-1] after the field name.

As soon as I get a chance I’ll try compiling this and seeing it it actually works. Look for another update soon!

Categories: Coding, Mainframe Tags: , ,

Displaying a PDF file within an App…

July 24, 2013 Leave a comment

As part of the app I am working on I wanted to use a PDF document for the help file. I am using a storyboard and the help displays in a separate view. Since the help document contains multiple pages I wanted to allow the user to be able to navigate through the document using swipe gestures.

This is what I ended up with:

Since I learned so much about how to do this from various places on the Internet, I thought I’d return the favor and show my code. I am sure it could be improved a lot (I am a noob at this Objective-C stuff after all) and I’ll probably cringe if I come back to this in six months but regardless, I offer my code in the hope that it may be of use to someone. Oh, and if you spot any REALLY BAD errors, feel free to let me know. I’m not proud at all and always willing to learn.

My screen consists of a navigation bar with the ‘Done’ button (btnHelpDone) on it and a UIView (pdfView) that fills the rest of the screen. There are also four swipe gesture controllers, one for each direction. The ‘Done’ button just closes the current view and returns to the previous one in the storyboard.

I replaced the UIView’s drawRect with my own which does the bulk of the work to display the PDF.

This the he helpViewController.h file…

//
//  HelpViewController.h
//
//  Created by David Ellis on 2013-07-14.
//  Copyright (c) 2013 David Ellis. All rights reserved.
//

#import <UIKit/UIKit.h>

// see drawHelp
extern NSInteger g_helpDocPageNum;
extern CGPDFDocumentRef g_helpDocRef; 
extern NSInteger g_helpDocMaxPage;

@interface HelpViewController : UIViewController
@property (weak, nonatomic) IBOutlet UIView *pdfView;
- (IBAction)btnHelpDone:(id)sender;
- (IBAction)helpLeftSwipe:(id)sender;
- (IBAction)helpRightSwipe:(id)sender;
- (IBAction)helpUpSwipe:(id)sender;
- (IBAction)helpDownSwipe:(id)sender;

@end

This is the helpViewController.m file

//
//  HelpViewController.m
//
//  Created by David Ellis on 2013-07-14.
//  Copyright (c) 2013 David Ellis. All rights reserved.
//

#import "HelpViewController.h"

@interface HelpViewController  ()

@end

@implementation HelpViewController

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    // self.pdfView.backgroundColor = [UIColor redColor];   // test just to show this code runs
    // NSLog(@"helpviewdidload");

   }

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (IBAction)btnHelpDone:(id)sender {
    [self dismissViewControllerAnimated:YES completion:nil];
}

- (IBAction)helpLeftSwipe:(id)sender {
    // next page
    // NSLog(@"helpLeftSwipe");
    if (g_helpDocPageNum < g_helpDocMaxPage) {
        g_helpDocPageNum=g_helpDocPageNum+1;

        [UIView transitionWithView:self.pdfView duration:1
            options:UIViewAnimationOptionTransitionCurlUp      
            animations:^{
            //     [self.pdfView.layer displayIfNeeded];
            }  completion:nil];

        [self.pdfView  setNeedsDisplay];
    }
}

- (IBAction)helpRightSwipe:(id)sender {
    // prev page
    // NSLog(@"helpRightSwipe");
    if (g_helpDocPageNum > 1) {
        g_helpDocPageNum = g_helpDocPageNum-1;

        [UIView transitionWithView:self.pdfView duration:1
            options:UIViewAnimationOptionTransitionCurlDown
            animations:^{
           //     [self.pdfView.layer displayIfNeeded];
            }  completion:nil];

        [self.pdfView setNeedsDisplay];
    }
}

- (IBAction)helpUpSwipe:(id)sender {
    // same as left swipe = next page
    // NSLog(@"helpUpSwipe");
    [self helpLeftSwipe:sender];
}

- (IBAction)helpDownSwipe:(id)sender {
    // same as right swipe = prev page
    // NSLog(@"helpDownSwipe");
    [self helpRightSwipe:sender];
}

- (void)viewDidUnload {
    [self setPdfView:nil];
    [super viewDidUnload];
}

@end

The helpViewController.m file implements the code to close the view when the Done button is pressed and the gesture controller code. The Up and down gesture code just calls the Left and Right code.

The pdfView UIview is sub classed to the drawHelp class. This is the drawHelp.h file (not much in it as you can see!):

//
//  drawHelp.h
//
//  Created by David Ellis on 2013-07-15.
//  Copyright (c) 2013 David Ellis. All rights reserved.
//

#import <UIKit/UIKit.h>

@interface drawHelp : UIView

@end

And finally, the drawHelp.m class file:

//
//  drawHelp.m
//
//  Created by David Ellis on 2013-07-15.
//  Copyright (c) 2013 David Ellis. All rights reserved.
//

#import "drawHelp.h"

CGPDFDocumentRef g_helpDocRef=NULL;
NSInteger g_helpDocPageNum=1;
NSInteger g_helpDocMaxPage=0;

@implementation drawHelp

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        // Initialization code
    }
    return self;
}

CGPDFDocumentRef MyGetPDFDocumentRef (NSString *filename)
{

    CGPDFDocumentRef document;
    size_t count;

    NSString *path = [[NSBundle mainBundle] pathForResource:filename ofType :@"pdf"];
    NSURL *url = [NSURL fileURLWithPath:path];

    document = CGPDFDocumentCreateWithURL ((__bridge CFURLRef)url);

    count = CGPDFDocumentGetNumberOfPages (document);
    if (count == 0) {
        NSLog(@"`%@' needs at least one page!", filename);
        return NULL;
    }

    return document;
}
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect
{

    // Drawing code

    CGPDFPageRef page;

    // NSLog(@"This is drawRect");

    CGContextRef ctx = UIGraphicsGetCurrentContext();

    // set background color
    CGContextSetRGBFillColor(ctx, 255.0, 255.0, 255.0, 1.0);
    CGContextFillRect(ctx,rect);

    // flip co-ordinates for pdf
    CGContextGetCTM(ctx);
    CGContextScaleCTM(ctx,1,-1);
    CGContextTranslateCTM(ctx,0,-rect.size.height);

    g_helpDocRef=MyGetPDFDocumentRef(@"Help");
    g_helpDocMaxPage=CGPDFDocumentGetNumberOfPages(g_helpDocRef);
    page = CGPDFDocumentGetPage(g_helpDocRef,g_helpDocPageNum);

    CGRect cropRect = CGPDFPageGetBoxRect(page,kCGPDFCropBox);
    CGContextScaleCTM(ctx, rect.size.width / cropRect.size.width, rect.size.height/ cropRect.size.height);
    CGContextTranslateCTM(ctx,-cropRect.origin.x,-cropRect.origin.y);

    CGContextDrawPDFPage(ctx,page);

    CGPDFDocumentRelease(g_helpDocRef);

}

@end

Some global variables (prefixed g_) keep track of the pdf reference, the current page number and the max page number (I’m sure I should be doing those differently but this works for now).

The MyGetPDFDocumentRef routine loads the pdf and returns a reference to it.

The drawRect function function sets up the UIview background color, flips the co-ordinate system for the pdf display, loads the pdf and draws the current page.

You’ll notice that the drawRect function has nothing to do with the paging or the curlup/down animation. That is all handled by the swipe gesture controllers up in the helpViewController.m file. In case it is confusing, a swipe to the right means you want to go BACK a page so the right swipe handler reduces the page number (provided it does not go below 1) while a swipe to the left means you want to go to the next page so it adds one to the page number provided it does not exceed the number of pages in the document.

The gesture controller then sets up the animation (curl up or curl down) and initiates a redraw of the pdfView UIView using [self.pdfView setNeedsDisplay] which triggers the drawRect code to display whatever page is currently selected. iOS handles the actual curl up./down animation.

Categories: Coding, iPhone, xcode Tags: , ,

Stepping back in order to learn …

July 19, 2013 Leave a comment

The little iOS pdf toolkit I found was awesome and very easy to use but it was a pretty big chunk of code and more importantly for me, the look of the rendered page did not match the look I had for my app. There did not appear to be any ‘easy’ way to change the general look (color of the tool bar in particular) without reverting to changing the code so I decided to figure out how to do it myself in order to get the look I wanted, but also to force me to learn more about iOS programming.

I found some example code out there to use as a starting point as well as the Apple documentation so between that lot I did manage to figure it out in the end. Of course it’s not as  simple as just following someone else’s code as their code never quite matched my environment or goal, but the whole process of figuring out which parts of their code you need to take and use as a model for your own is how you learn this stuff.

Overall it has been a worthwhile exercise and while I am no expert yet at iOS app coding, I am a little more educated than I was a week ago.

So now I can get back to the main code for my app.

Categories: Coding, iPhone, xcode

Displaying PDF documents on iOS…

July 13, 2013 Leave a comment

I found this truly awesome (and free) toolkit (also no license limitation on use in commercial projects):

http://www.vfr.org/

I was able to implement it very easily into my project by following the tutorial:

http://mobile.tutsplus.com/tutorials/iphone/reading-displaying-pdf-documents/

There’s a few things I need to change ‘look’ wise either in it, or my own app to get a common look, but that can come later. For now I am very happy with this.

And so on to the next part which involves getting messy with Apple’s CoreMidi amongst other things although I might do some of the UI stuff first since that looks to be ‘easier’!

 

Categories: Coding, iPhone, xcode

Back to the iPhone programming…

July 5, 2013 Leave a comment

Well, my adventures in iPhone programming continue. It’s not being helped at all by the crappiness of using VNC to access the remote MAC I am using. VNC just does not seem to be able to support some of the basic functions like control and drag that I need to use to get the most out of the xcode IDE. OK, so there are work arounds but even so!

Anyway, so far today I’ve managed to crash the iPhone emulator and completely screw up my simple test app (although I did fix it later).

Given the choice between Microsoft’s IDE and xcode I have to say that so far I think the MS one is far better. Maybe it’s just a matter of familiarity but you have to remember I don’t do this for a living (yet!) but I think I found creating applications using the MS IDE far more intuitive than using xcode, or maybe it’s the quality of the tutorials I am following. Mind you, the iPhone coding is not helped at all by the sheer strangeness of the way they have implemented the C ‘code’. It ‘looks’ like C but is it? Who knows. Certainly seems strange to me!

Anyway, onwards we go!

 

Categories: Coding, Development Tools

Anonymous functions in REXX

June 19, 2013 Leave a comment

In this blog post https://www.ibm.com/developerworks/community/blogs/MartinPacker/entry/dragging_rexx_into_the_21st_century?lang=en Martin Packer was experimenting with modernizing REXX on the mainframe. One topic he mentioned but did not resolve was the use of anonymous functions in REXX.

An anonymous function is a block of code that is not associated with an identifier like a function name. It’s just a block of code you can pass to something else (another function) to run. It’s used a lot in things like jQuery to implement ‘callbacks’ from the invoked function back into your own code.

So I got to thinking about this and did a little experimenting. The following is ‘close’ in that I can pass a block of code into a called function and have it execute there. It could implement some sort of ‘callback’ by for example returning data to the original caller on the stack or via an external data set but I did not go that far. I just wanted to see how hard it would be to run some code passed in by the caller. So here’s my solution:

This first program is the caller of some function that will use the anonymous function code block I pass to it. I define the anonymous function in a comment block in the program (makes it easier to write anything longer than a couple of lines) and load it into a variable using sourceline. Notice that each line of the anonymous function has to end with a semicolon since all the lines get concatenated together into one big string.

/* rexx */                                                             

func=loadfunc('MYANONFUNC')                                                                                                               
rc=z67('parm for z67',func,'This is a message')                        
return 0                                                               

/*-------------------------------------------------------------*/      
loadfunc: procedure                                                    
parse arg reqdname                                                     

code=''                                                                

indata=0                                                               
do i = 1 to sourceline()                                               
   line = sourceline(i)                                                
   select                                                              
      when substr(line,1,11)='/*FUNCTION ' then do                      
         parse var line . name .                                       
         if name=reqdname then do                                      
            indata=1                                                   
            end                                                        
         end                                                           
      when substr(line,1,2)='*/' & indata=1 then leave                 
      otherwise do                                                     
         if indata then code = code||line                              
         end                                                           
      end /* select */                                                 
   end /* do i=1 to sourceline() */                                    

return code   
/*-------------------------------------------------------------*/      

/*FUNCTION MYANONFUNC                                                      
trace "I";                                                             
parse arg msg;          
say msg;   
trace "O";              
return 0;                
*/

The following code is the called function (called z67 in this case), It accepts a parameter for its own use (myparm) which is just displays to demo the ability, the function string itself (func) and any data (funcdata) to be passed to the anonymous function from the caller.

/* rexx */                           
parse arg myparm, func, funcdata     
say "myparm is ("myparm")"           
rc=x(funcdata)                       
return rc                            

x: procedure expose func             
interpret func                       
return 0

The code above parses out the three arguments passed in, displays the first one and then calls an internal function (x) passing it the function data for the anonymous function (funcdata). That allows the passed code to parse any arguments passed to it by the original caller. The ‘x’ routine gets to the function code itself by exposing the ‘func’ variable and just executes it using interpret.

Notice that the anonymous function code can also accept arguments from the original caller and do things like turn on trace. It would be quite easy to modify this code so that a variable number of parameters could be passed to the invoked passed function.

Categories: Coding, Mainframe, REXX Tags:

C for z/OS assembler programmers…

June 5, 2013 Leave a comment

A few C Data structures mapped to assembler equivalents:

C                        asm 

int i;                   i       ds    f       uninitialized storage area
int j=0;                 j       dc    f'0'    initialized to zero 
int *name;               name    ds    a       uninitialized 'address of' storage area 
int *name1=0;            name1   dc    a(0)    'address of' initialized to zero 
int *name2=&i;           name2   dc    a(i)    'address of' i 

struct astruct {        astruct        dsect 
int a;                  a        ds    f 
int b;                  b        ds    f 
char c[10];             c        ds    cl10 
}                       @astruct equ *-astruct        length=18 

sizeof(astruct)                  dc    a(@astruct)        length of struct/dsect

union aunion {          aunion   ds    dsect 
int k;                  k        ds    f 
                                org    k 
doube l;                l        ds    d        l overlays k 
                                org    k 
char cl10;              char     ds    cl10     char overlays k and l
                                org , 
}                        @aunion equ *-union        length=10 

sizeof(aunion)                   dc    a(@aunion)   length of the union

 

Categories: Coding, Mainframe

Mixing it up with C and Assembler on z/OS…

June 5, 2013 1 comment

Calling an assembler program from a C program.

Parameter passing conventions

On z/OS (or MVS if you are old enough), programs written in ‘traditional’ mainframe languages such as assembler, Cobol and PL/1 typically pass parameters to each other using the following convention:

zOSLinkageConvention

Basically register 1 points to a list of addresses and each address in the list points to the actual data for that parameter. The end of the address  list is usually (but does not have to be) indicated by the high order bit being on in the last entry. If the last entry is not indicated then only a fixed number of parameters can be passed since the called program has no way of knowing how long a variable length list is.

Since the last entry is indicated, it is very easy to pass a variable number of parameters to a called program.

There is of course NO type checking of the data between the calling and called program. If you pass the wrong type or length of data in a parameter or if you do not pass enough parameters and the called program does not check the end of the list then it is highly likely that things are going to go wrong!

C on the other hand has all sorts of type checking for the parameters being passed between the calling and called program. Typically (and I am sure you already know this) in C, the type and form of the parameters to be passed to another called program are defined in a header (H) file. Something like this:

int mysubrtn(int pntr2Parm1,int Parm2);

Which says the module called ‘mysubrtn’ accepts two parameters, both integers (fullwords on z/OS) and returns an integer.

If you try to call ‘mysubrtn’ with any other types of parameters or with a different number of parameters the code will not compile.

You can tell C that the called program accepts a variable number of parameters by including three periods after the fixed number of parameters (one in this case):

int mysubrtn(int pntr2Parm1,...);

You do however then lose the type checking for the variable parameters.

The main issue when it comes to calling an assembler program is that C does it’s own thing in the way it passes parameters between programs. Basically the problem boils down to the fact that by default, C and assembler do it differently. So the first step in calling an assembler program from a C program is telling the C compiler to generate code that is compatible with the operating systems way of doing things!

The #pragma linkage statement

The #pragma linkage statement tells the C compiler that when the named program is called, it should use the standard OS convention to pass the parameters to the called program. The statement looks like this:

#pragma linkage(myasmrtn,OS)

Typically the named program is the main entry point (usually the CSECT for an assembler program) for the target program but it does not have to be.  In fact there is nothing to stop a program, especially an assembler program, from having multiple entry points declared with each taking different parameters and/or performing different functions. so long as you code a #pragma linkage entry for each entry point, it will work fine.

On it’s own, this is enough to be able to call an assembler program from your C code. In the absence of anything else the default is that the C code expects the assembler code to return an int (fullword), typically a return code. And of course, there is no parameter checking since the C code currently knows nothing about the parameters the assembler code requires.

So you could do something like this:

int rc;
rc=myasmrtn();

Or this:

int rc;
int parm1;
parm1=99;
rc=myasmrtn(parm1);

However you could also call it like this:

rc=myasmrtn(&parm1);

The difference between the last two examples is that the first one creates a data structure like this:

zOSLinkage_1

While the second one creates a data structure like this:

zOSLinkage_2If your called program expect the first form and you use the second form, you are going to be in trouble since you will end up using the address of the parameter as the parameter itself.

Adding parameter checking for the assembler program to  your C code

You do this in exactly the same way that you would do it for a C program, that is by defining a model call statement, either inline or in a header (H) file. For example:

int myasmrtn(int parm1);

Since you have declared the number and type of parameters the the assembler code expects, the following will no longer compile:

int rc;
int parm1;
rc=myasmrtn();

or:

int rc;
int parm1;
rc=myasmrtn(&parm1);

Or even:

int rc;
char parm1[]="some string";
rc=myasmrtn(parm1);

The cools part though is that since we are now defining what parameters the program will accept, we can also define what it will return. For example, instead of returning a simple return code in an int, it could return the address of a work area:

int *myasmrtn(parm1);

Function overloading

Lets assume that you have an assembler program that can accept a variable number of parameters with the first parameter indicating the call type which in turn dictates what the following parameters will be. Now we want to call that program from our C code and just to be safe we’d like to use some form of parameter checking. Just to make things easier, we have the source of the assembler program so we can modify it to help us achieve this goal.

In assembler the executable code typically starts with the CSECT (or RSECT) statement and this also defines the main entry point for a program. You can however define other labels within the code as alternative entry points like this:

         ENTRY ALTENTRY
MYASMRTN CSECT
         Some code
ALTENTRY DS    0H
         Some other code

Or even this:

         ENTRY ALTENTRY
MYASMRTN CSECT
ALTENTRY DS    0H
         Some common code

Notice that in the second example, we have two entry points that both invoke the SAME code. As far as the executable assembler code is concerned this is the same entry point, the actual code would not care. But from a C point of view we can now do something like this:

#pragma linkage(myasmrtn,OS)
#pragma linkage(altentry,OS)
int myasmrtn(int calltype, int parm1, int parm2);
int* altentry(int calltype, char *parm2, int parm2)

When calling ‘myasmrtn’ the C compiler will check that I am passing three integers (fullwords). When calling ‘altentry’, the C compiler will check that I am passing an int, a char string (actually the address of the string) and another int. In addition, when I call ‘myasmrtn’ I expect an integer back (such as a return code). When I call ‘altentry’ I expect the address of an int (although it could actually by anything, even a getmained area) back.

From the assembler perspective, it does not care about all that but from the C perspective, we now have some basic parameter checking at compile time.

Categories: Coding, Mainframe

A little ‘light’ reading…

May 14, 2013 Leave a comment

My current reading…

ReadingList

As much as I am not a fan of C (I must do a post to explain why sometime)  and it’s variants I thought I would give it a chance, especially since I am trying to create an iOS app for the iPad (whose development language is more like smalltalk than C but it’s still ‘close’ in style).

So far I am about half way through the C++ book and I will admit that the presence of the string class alone and thus the removal for the need for functions like strcmp (that results in really strange code in my opinion since the return code logic is backwards as equality gives a zero return code which is ‘false’!) and memcpy (which is just plain dangerous in the wrong hands) is a vast improvement.

Unfortunately for me, most of my day to day work is in z/OS assembler or Metal C (mainly just reading it!) so not much opportunity to do ‘real’ code but hey, it’s all good in the end. No harm in learning new stuff.

As for the iOS book, I am still trying to get up to speed with using the xcode development environment on the remote mac system I am using. The main issue  so far has been that most of the xcode tutorials online use the click and drag method to connect things in the IDE but because I am accessing the machine using vnc, that does not work (apparently vnc does not support that) so I have spent most of tonight just finding alternative ways of achieving the same thing.

Who says us geeks are boring… LOL!

Categories: Coding, Development Tools