From: louis@Barra.COM (Louis Dunne)
Newsgroups: comp.os.vms
Subject: Re: Re: PSM$REPLACE with VAXC
Date: 25 Aug 92 17:39:11 GMT
Distribution: world
Organization: BARRA Inc., Berkeley, California.

On Aug 21,  8:02pm, Reece R. Pollack wrote:
> Subject: Re: PSM$REPLACE with VAXC
>
>In article <l+#n1nj.shepperd@netcom.com>, shepperd@netcom.com (David Shepperd) writes:
>|>uugblum@ariel.lerc.nasa.gov (VMScluster Administrator) writes:
>|>: Does anyone have an example of how to use the PSM$REPLACE routine from VAX C?
>|>
>|>Yep:
>|>
>|>[...bla_bla...]
>|>The main thing you need to know is that you cannot have a main() function
>|>defined anywhere in your C code. Having a main() causes the program to call a
>|>bunch of startup code in the VAXCRTL which will die a miserable death because
>|>the symbiont doesn't have the command intrepreter. This means you have to get
>|>control transferred to the C code in another manner. I cheap out and do this
>|>with the following 4 line MACRO32 program:
>|>
>|>.entry tek_main,^M<>
>|>   calls #0,start_c
>|>   ret
>|>.end tek_main
>|>
>|>Don't use any builtin VAXCRTL I/O (like fopen, fread, etc.) or process
>|>functions (fork, etc). They probably won't work because the VAXCRTL startup
>|>code hasn't been executed. I believe you are confined to using RMS,
>|>QIO's, SYS$ and LIB$ calls directly.
>
>I'm not aware of any problem using the VAXCRTL code in print symbionts,
>as long as you don't expect to use functions which depend on the CLI.
>I've written a number of print symbionts in VAX C and never had to play
>the game you're advocating.
>
>Yes, you can use the VAXCRTL I/O functions in your program.
>
>--
>Reece R. Pollack
>Senior Software Engineer
>The Wollongong Group, Inc.
>

	Well, I have two things to add to this...

	Firstly I agree, you can use VAXCRTL routines from within a
	print symbiont, UNLESS the routine depends upon the presence
	of a CLI.

	Secondly, it is not necessary to create a dummy MACRO source
	file, to have a VAX C program without a main(). In otherwords, 
	it is possible, to create a C program, which doesn't call the
	VAXCRTL startup routines, which is what you will want if your
	writing a print symbiont. Strange as it may seem, if you don't
	have a main() in your C source, the linker will generate a
	transfer address, at the first routine in the source file. If
	you link multiple object files, the first routine in the first
	object file will be the transfer address (i.e. will get
	control first when you run the image).

	The following are two list files (generated with CC/MACHINE_CODE=
	AFTER/LIST nomain.c,main.c) which demonstrate that without a main()
	routine the VAXCRTL startup routines will not be invoked. (I've
	edited the .LIS file for clarity)

MAIN.LIS:
---------
    1        	main()
    2        	{
    3    1   	    printf("This is main.c");
    4    1   	}

                      0000	main:
                0000  0000		.entry	main,^m<>
          5E 08 C2    0002		subl2	#8,sp
   00000000* EF 16    0005	     ***jsb	C$MAIN		
    00000000 EF DF    000B		pushal	$CHAR_STRING_CONSTANTS
00000000* EF 01 FB    0011		calls	#1,PRINTF
          50 01 D0    0018	     ***movl	#1,r0
                04    001B		ret	

	Notice the "jsb C$MAIN", which a jump to subroutine to the C
	startup routines. Also notice the "movl #1, r0" which puts
	SS$_NORMAL into r0 to signify normal completion.
	
NOMAIN.LIS:
-----------
    1        	first()
    2        	{
    3    1   	    printf("This is nomain.c");
    4    1   	}

                      0000	first:
                0000  0000		.entry	first,^m<>
          5E 08 C2    0002		subl2	#8,sp
    00000000 EF DF    0005		pushal	$CHAR_STRING_CONSTANTS
00000000* EF 01 FB    000B		calls	#1,PRINTF
                04    0012		ret	

	Notice here, the absence of both statements marked (***) in
	NOMAIN.LIS. There is no jump to the C startup routines, and
	no return code, is deposited into r0.

	If you want, to verify that the linker, sets up this entry point
	as the transfer address, then generate a map file (LINK/MAP) for
	nomain.c, and look at the transfer address, and the address of
	the $CODE.

	Ok, to end all this... If you don't want the startup routines to
	be invoked, don't have a main(), and the linker will setup your
	first routine as the transfer address for the image. Also, is you
	do this make sure you "return" something, otherwise your return
	status will be whatever junk is in r0 (this may not be a concern
	in a print symbiont).

	However, I have never seen this behaviour documented. So it may
	change in the future. As ever, use at your own risk :-)

	Hope this helps...

Louis
        ----------------------------------------------------------------------
       /  Louis Dunne                   /                                   /
      /   VMS/UNIX Systems             /                                   /
     /                                /  Internet:   louis@barra.com      /
    /     BARRA, Inc.                /   Phone:      (510) 649-4229      / 
   /      Suite 400                 /    Fax:        (510) 548-4374     /
  /       1995 University Avenue   /                                   /
 /        Berkeley, CA 94704      /                                   /
----------------------------------------------------------------------

Newsgroups: comp.os.vms