The following is a list of examples demonstrating various features of Systems/C.
Also - you can try out your own code. We've provided a web-based compilation mechanism to submit source and see the output from the Systems/C compiler (dcc), along with the generated assembly source.
Each example contains the example C source code, the dcc command which compiled it (and any output from that step) and the generated ASM source.
This page is automatically generated. You may want to refer to it again to see any new examples, or improvements in previous ones.
The interesting things to notice in this are not C language features, but rather the generated ASM source. You'll notice the generated source is commented to show exactly what the intent of the source is. Also, notice that the source lines, where meaningful, are included as well.
These comments - as well as all the comments in the generated ASM source, are produced by the compiler. The generated ASM source found here has not been altered in any manner from that produced by the compiler.
You may also notice an aspect of Systems/C code generation; the constant 10 is not loaded from a separate section, but is placed at an appropriate place in the instruction stream.
__register
keyword on variable declarations (which place the declared variable in the
named register) and the __asm
keyword which places the given ASM
source directly in the generated output.
The code in this example demonstrates rather straightforward malloc(), free() and realloc() functions which simply call the system services GETMAIN and FREEMAIN
The offsets are hard-coded, but using some of the more advanced features, these values could be taken directly from the MVS control block DSECTs. Some of the other examples demonstrate how one might do that.
__far
pointer support. Notice in the source how __alet
variables are used to specify which ALET is associated with which __far
pointer. Also, notice that both far_foo_pointer
and far_ip
share the same ALET.
0C1
error to occur, with a particular value in register #2 (in
this case, errno
.)
Thus, when the dump is taken, the register information will display the
value in register #2, letting the user know what errno
contained.
DSECT
s without any
conversion utility.
That is, you can directly reference DSECT
s and their fields
without converting the DSECT
to C source.
In this particular example, we access the current PSA
and then
the current ASCB
to get the current ASCBASID
.
This example is rather high-level; subsequent examples demonstrate more of the "inner workings" of the various macros used.
EQU
values) directly from C
source, with __asmval
constants.
In the source, you'll see two EQUs for foo
and bar
which are referenced several ways.
DSECT
from C code, using
__asmval
to compute the field offsets.
Using this technique; you can allocate storage for DSECT
s,
alter fields, etc... without having to convert the DSECT
into a C
structure representation.
The Systems/C provided __asmref
macro is a much more legible
mechanism to reference DSECT
fields. But, this example is
provided to demonstrate some of the power of __asmval
.
/*
* A small example to demonstrate the generated ASM source
*
* Simply declares some variables, does some assignments.
*/
struct my_struct {
int field1;
int field2;
} ;
main()
{
struct my_struct s;
int f1, f2;
f1 = s.field2;
f2 = f1;
s.field1 = f2;
s.field2 = s.field2 + 10;
}
../dcc -flicense=dignus.freebsd.inf -oasm0001.390 src0001.c
DCC Systems/C 390 compiler - version 1.31.00
(c) Copyright 1999-2000 Dignus, LLC All rights reserved.
DCC is licensed to Dignus, LLC.
DCC Return code 0, elapsed time 0.05 seconds.
*
* Compiled by DCC Version 1.31.00
* on Fri Oct 27 16:43:34 2000
*
@CRT0 ALIAS C'@crt0'
EXTRN @CRT0
*
*
*
* Code Section
*
@CODE ALIAS C'@SRC0001'
@CODE CSECT
@CODE AMODE ANY
@CODE RMODE ANY
@DATA ALIAS C'@src0001'
*
*
*
main ALIAS C'main'
main DCCPRLG CINDEX=6,BASER=12,FRAME=112,ENTRY=YES
* ******* End of Prologue
* *
* *** struct my_struct s;
* *** int f1, f2;
* ***
* *** f1 = s.field2;
LA 4,96(0,13) ; &s
LA 4,4(0,4) ; offset of field2 in my_struct
L 5,0(0,4)
LR 3,5 ; f1
* ***
* *** f2 = f1;
LR 2,3 ; f2
* ***
* *** s.field1 = f2;
LA 4,96(0,13) ; &s
ST 2,0(0,4)
* ***
* *** s.field2 = s.field2 + 10;
LA 4,96(0,13) ; &s
LA 4,4(0,4) ; offset of field2 in my_struct
LA 5,96(0,13) ; &s
LA 5,4(0,5) ; offset of field2 in my_struct
L 6,0(0,5)
A 6,@lit_6_1
ST 6,0(0,4) ; offset of field2 in my_struct
* *** }
@ret_lab_6 DS 0H
* * **** Start of Epilogue
DCCEPIL
* * **** End of Epilogue
DS 0D
@lit_6_1 DC F'10' 0x0000000a
@FRAMESIZE_6 DC F'112'
*
* DSECT for automatic variables in "main"
* (FUNCTION #6)
*
@AUTO#main DSECT
DS XL96
main#s#0 DS 8XL1 ; s
main#f1#0 DS 1F ; f1
main#f2#0 DS 1F ; f2
*
@CODE CSECT
*
* Non-Re-Entrant Data Section
*
@DATA CSECT
@DATA RMODE ANY
@DATA AMODE ANY
*
END
/*
* long-long example
*
* This is a very trivial for() loop, printing
* 100 long-longs.
**/
#include <sys/types.h>
#include <limits.h>
main()
{
long long index;
/* We'll loop for the last 100 long-long values. */
/* QUAD_MAX (from limits.h) defines the largest */
/* signed long long value. */
for( index = QUAD_MAX - 100; index < QUAD_MAX; index ++) {
/* Print the value of 'index'. Note the 'q' */
/* in the printf format specifier, indicating */
/* a 'quad' (long long) decimal type. */
printf("%qd\n", index);
}
}
../dcc -flicense=dignus.freebsd.inf -oasm0002.390 src0002.c
DCC Systems/C 390 compiler - version 1.31.00
(c) Copyright 1999-2000 Dignus, LLC All rights reserved.
DCC is licensed to Dignus, LLC.
cc: src0002.c line 24:Warning #2136: implicit declaration of function `printf'
printf("%qd\n", index);
DCC Return code 0, 1 Warning, elapsed time 0.07 seconds.
*
* Compiled by DCC Version 1.31.00
* on Fri Oct 27 16:43:34 2000
*
@CRT0 ALIAS C'@crt0'
EXTRN @CRT0
*
*
*
* Code Section
*
@CODE ALIAS C'@SRC0002'
@CODE CSECT
@CODE AMODE ANY
@CODE RMODE ANY
@DATA ALIAS C'@src0002'
printf ALIAS C'printf'
EXTRN printf
*
*
*
main ALIAS C'main'
main DCCPRLG CINDEX=10,BASER=12,FRAME=120,ENTRY=YES
* ******* End of Prologue
* *
* *** long long index;
* ***
* ***
* ***
* ***
* *** for( index = ((quad_t)(((u_quad_t)0-1) >> 1)) - 100; index < (\
* (quad_t)(((u_quad_t)0-1) >> 1)); index ++) {
LA 2,@lit_10_1
MVC 96(8,13),0(2) ; index
B @L1
DS 0D
@lit_10_1 DC XL8'7FFFFFFFFFFFFF9B'
@FRAMESIZE_10 DC F'120'
@lit_10_2 DC XL5'6C98841500' .qd..
DC X'00'
@lit_10_4 DC XL8'0000000000000001'
@lit_10_3 DC A(printf)
@lit_10_5 DC H'1' 0x0001
@lit_10_6 DC XL8'7FFFFFFFFFFFFFFF'
@L0 DS 0H
* ***
* ***
* ***
* ***
* *** printf("%qd\n", index);
LA 2,@lit_10_2
ST 2,104(0,13)
MVC 108(8,13),96(13)
LA 1,104(0,13)
L 15,@lit_10_3 ; printf
BALR 14,15
* *** }
L 10,96(0,13)
L 11,100(0,13)
LA 2,@lit_10_4
A 10,0(0,2)
AL 11,4(0,2)
BC 12,@@gen_label0
AH 10,@lit_10_5
@@gen_label0 DS 0H
STM 10,11,96(13) ; index
@L1 DS 0H
L 10,96(0,13)
L 11,100(0,13)
LA 2,@lit_10_6
C 10,0(0,2)
BNE @@gen_label1
CL 11,4(0,2)
@@gen_label1 DS 0H
BL @L0
* *** }
@ret_lab_10 DS 0H
* * **** Start of Epilogue
DCCEPIL
* * **** End of Epilogue
*
* DSECT for automatic variables in "main"
* (FUNCTION #10)
*
@AUTO#main DSECT
DS XL96
main#index#0 DS 8XL1 ; index
*
@CODE CSECT
*
* Non-Re-Entrant Data Section
*
@DATA CSECT
@DATA RMODE ANY
@DATA AMODE ANY
*
END
/*
*
* Example of using __asm and __register.
*
* This provides a rather simplistic malloc()/free() support by
* simply calling the OS to acquire and release memory.
*
* A more sophisticated memory manager (as is used in the Systems/C library)
* would be preferred for any substantial program.
*
*
**/
/* To get builtin definitions of memcpy, you can include */
/* <string.h> */
#include <string.h>
/*
*
*
* *Very* simply malloc - just call GETMAIN
*
*
**/
void *
malloc(size)
unsigned long size;
{
void *retval;
/* We're going to save the size of the allocation */
/* for the subsequent call to FREEMAIN. So we */
/* add 8 bytes to the requested size. Why 8 and */
/* not 4? To keep things double-word aligned. */
size = size + 8;
if(size >= 16777216) {
/* Size is greater than 16 meg - this won't work */
/* because the GETMAIN we're using won't gives us that... */
retval = 0;
} else {
{
__register(1) unsigned long r1;
__register(2) unsigned long r2;
/* Need to declare R0 because GETMAIN uses it */
__register(0) unsigned long r0;
r1 = 0xf0000000;
r2 = size;
/* Note the '12' on the __asm statement */
/* the GETMAIN macro, when expanded, produces */
/* 12 bytes of instructions. This is not required */
/* but helps the compiler properly allocate the space */
/* for the inlined assembly language source. */
__asm 12 {
GETMAIN RU,LV=(2),LOC=BELOW
} ;
retval = (void *)r1;
}
if(retval != 0) {
/* Put in our size for later */
memcpy(retval, &(size), 4);
/* Add 8 to the returned result, we hand */
/* the user a pointer to the space, not */
/* a pointer to our hidden information. */
retval = ((char *)retval + 8);
}
}
/* Return the result */
return retval;
}
/*
*
*
* *Very* simple free - just give the memory back to the OS
* with FREEMAIN
*
*
**/
void
free(ptr)
void *ptr;
{
char *p;
unsigned long size;
p = (char *)ptr;
/* Back the pointer up to point at our hidden */
/* information. */
p = p - 8;
/* Get the original allocation size out of the */
/* hidden information. */
memcpy(&size, p, 4);
{
/* Need to declare R0/R1 because FREEMAIN uses it */
__register(0) unsigned long r0;
__register(1) unsigned long r1;
__register(2) unsigned long r2;
__register(3) unsigned long r3;
r3 = (unsigned long)p;
r2 = size;
__asm 8 {
FREEMAIN RU,LV=(2),A=(3)
} ;
}
}
/*
*
*
* *Very* simple realloc() - we simply always reallocate and
* copy
*
*
**/
void *
realloc(ptr, new_size)
void *ptr;
unsigned long new_size;
{
void *retval;
if(ptr == 0) {
/* If the previous pointer is 0, this is */
/* "just like" malloc() */
return malloc(new_size);
}
/* Get some new space. */
retval = malloc(new_size);
if(retval != 0) {
char *p;
unsigned long old_size;
unsigned long to_copy;
p = ptr;
/* Point to our hidden information so */
/* we can copy the old bytes to the */
/* location. For that copy, we need */
/* to get the size information. */
p = p-8;
memcpy(&old_size, p, 4);
/* Copy the old stuff back */
to_copy = old_size;
if(to_copy > new_size) {
to_copy = new_size;
}
memcpy(retval, ptr, to_copy);
/* Free the old stuff */
free(ptr);
}
/* Return the result */
return retval;
}
../dcc -flicense=dignus.freebsd.inf -oasm0003.390 src0003.c
DCC Systems/C 390 compiler - version 1.31.00
(c) Copyright 1999-2000 Dignus, LLC All rights reserved.
DCC is licensed to Dignus, LLC.
DCC Return code 0, elapsed time 0.07 seconds.
*
* Compiled by DCC Version 1.31.00
* on Fri Oct 27 16:43:34 2000
*
*
*
*
* Code Section
*
@CODE ALIAS C'@SRC0003'
@CODE CSECT
@CODE AMODE ANY
@CODE RMODE ANY
@DATA ALIAS C'@src0003'
*
*
*
malloc ALIAS C'malloc'
malloc DCCPRLG CINDEX=51,BASER=12,FRAME=128,ENTRY=YES
ST 1,80(0,13) ; Save ptr to incoming parm block
* ******* End of Prologue
* *
* *** void *retval;
* *** # 35
* *** size = size + 8;
L 2,0(0,1) ; size
AL 2,@lit_51_1
ST 2,0(0,1) ; size
* *** if(size >= 16777216) {
CL 2,@lit_51_2
BL @L0
* ***
* ***
* *** retval = 0;
LA 3,0(0,0) ; retval
* *** } else {
B @L1
DS 0D
@lit_51_2 DC F'16777216' 0x01000000
@lit_51_1 DC F'8' 0x00000008
@FRAMESIZE_51 DC F'128'
@lit_51_3 DC F'-268435456' 0xf0000000
@L0 DS 0H
* *** {
* *** __register(1) unsigned long r1;
* *** __register(2) unsigned long r2;
* ***
* *** __register(0) unsigned long r0;
* ***
* *** r1 = 0xf0000000;
L 4,@lit_51_3
LR 1,4 ; r1
* *** r2 = size;
L 4,80(0,13)
L 5,0(0,4) ; size
LR 2,5 ; r2
* *** # 55
* *** __asm 12 {
* *** GETMAIN RU,LV=(2),LOC=BELOW
* *** } ;
* inline ASM source (12 bytes)
GETMAIN RU,LV=(2),LOC=BELOW
*
@CODE CSECT
* *** retval = (void *)r1;
LR 3,1 ; retval
* *** }
* ***
* ***
* *** if(retval != 0) {
LR 2,3 ; #0
LA 6,0(0,0)
CR 2,6
BE @L1
* ***
* ***
* *** __memcpy(retval,&(size),4);
LR 2,3
MVC 0(4,2),0(4)
* ***
* ***
* ***
* ***
* *** retval = ((char *)retval + 8);
LA 3,8(0,3)
* *** }
* *** }
B @L1
@L2 DS 0H
* ***
* ***
* *** return retval;
@L1 DS 0H
LR 2,3
LR 15,2
B @ret_lab_51
* *** }
@ret_lab_51 DS 0H
* * **** Start of Epilogue
DCCEPIL
* * **** End of Epilogue
*
* DSECT for automatic variables in "malloc"
* (FUNCTION #51)
*
@AUTO#malloc DSECT
DS XL104
malloc#retval#0 DS 1A ; retval
*
@CODE CSECT
*
*
*
free ALIAS C'free'
free DCCPRLG CINDEX=52,BASER=12,FRAME=128,ENTRY=YES
ST 1,80(0,13) ; Save ptr to incoming parm block
* ******* End of Prologue
* *
* *** char *p;
* *** unsigned long size;
* ***
* *** p = (char *)ptr;
L 2,0(0,1) ; ptr
ST 2,104(0,13) ; p
* ***
* ***
* ***
* *** p = p - 8;
SL 2,@lit_52_5
ST 2,104(0,13) ; p
* ***
* ***
* ***
* *** __memcpy(&size,p,4);
LA 3,108(0,13) ; &size
MVC 0(4,3),0(2)
* ***
* *** {
* ***
* *** __register(0) unsigned long r0;
* *** __register(1) unsigned long r1;
* *** __register(2) unsigned long r2;
* *** __register(3) unsigned long r3;
* *** r3 = (unsigned long)p;
L 4,104(0,13) ; p
LR 3,4 ; r3
* *** r2 = size;
L 5,108(0,13) ; size
LR 2,5 ; r2
* *** __asm 8 {
* *** FREEMAIN RU,LV=(2),A=(3)
* *** } ;
* inline ASM source (8 bytes)
FREEMAIN RU,LV=(2),A=(3)
*
@CODE CSECT
* *** }
* *** }
@ret_lab_52 DS 0H
* * **** Start of Epilogue
DCCEPIL
* * **** End of Epilogue
DS 0D
@lit_52_5 DC F'8' 0x00000008
@FRAMESIZE_52 DC F'128'
*
* DSECT for automatic variables in "free"
* (FUNCTION #52)
*
@AUTO#free DSECT
DS XL104
free#p#0 DS 1A ; p
free#size#0 DS 1F ; size
*
@CODE CSECT
*
*
*
realloc ALIAS C'realloc'
realloc DCCPRLG CINDEX=53,BASER=12,FRAME=136,ENTRY=YES
ST 1,80(0,13) ; Save ptr to incoming parm block
* ******* End of Prologue
* *
L 2,4(0,1)
LR 5,2
* *** void *retval;
* ***
* *** if(ptr == 0) {
L 6,0(0,1) ; ptr
LA 7,0(0,0)
CR 6,7
BNE @L3
* ***
* ***
* *** return malloc(new_size);
LR 7,5
ST 7,120(0,13)
LA 1,120(0,13)
L 15,@lit_53_7 ; malloc
BALR 14,15
B @ret_lab_53
DS 0D
@FRAMESIZE_53 DC F'136'
@lit_53_7 DC A(malloc)
@lit_53_9 DC F'8' 0x00000008
@lit_53_10 DC F'256' 0x00000100
@lit_53_12 DC XL6'D20060008000'
@lit_53_13 DC A(free)
* *** }
* ***
* ***
* *** retval = malloc(new_size);
@L3 DS 0H
LR 6,5
ST 6,120(0,13)
LA 1,120(0,13)
L 15,@lit_53_7 ; malloc
BALR 14,15
LR 4,15 ; retval
* ***
* *** if(retval != 0) {
LR 6,4 ; #0
LA 7,0(0,0)
CR 6,7
BE @L4
* *** char *p;
* *** unsigned long old_size;
* *** unsigned long to_copy;
* ***
* *** p = ptr;
L 6,80(0,13)
L 7,0(0,6) ; ptr
LR 3,7 ; p
* ***
* ***
* ***
* ***
* *** p = p-8;
LR 8,3
SL 8,@lit_53_9
LR 3,8 ; p
* *** __memcpy(&old_size,p,4);
LA 8,112(0,13) ; &old_size
LR 9,3
MVC 0(4,8),0(9)
* ***
* ***
* ***
* *** to_copy = old_size;
L 7,112(0,13) ; old_size
LR 2,7 ; to_copy
* *** if(to_copy > new_size) {
LR 8,2 ; new_size
LR 9,5
CLR 8,9
BNH @L5
* *** to_copy = new_size;
LR 8,5 ; to_copy
LR 2,8 ; to_copy
* *** }
* *** __memcpy(retval,ptr,to_copy);
@L5 DS 0H
LR 6,4
L 7,80(0,13)
L 8,0(0,7) ; ptr
LR 9,2
LR 10,6
@@gen_label5 DS 0H
LTR 9,9
BZ @@gen_label6
CL 9,@lit_53_10
BH @@gen_label7
LR 11,9
B @@gen_label8
@@gen_label7 DS 0H
L 11,@lit_53_10
@@gen_label8 DS 0H
SLR 9,11
BCTR 11,0
EX 11,@lit_53_12
LA 6,1(11,6)
LA 8,1(11,8)
B @@gen_label5
@@gen_label6 DS 0H
* ***
* ***
* *** free(ptr);
L 6,80(0,13)
L 7,0(0,6) ; ptr
ST 7,120(0,13)
LA 1,120(0,13)
L 15,@lit_53_13 ; free
BALR 14,15
* *** }
* ***
* ***
* *** return retval;
@L4 DS 0H
LR 6,4
LR 15,6
B @ret_lab_53
* *** }
@ret_lab_53 DS 0H
* * **** Start of Epilogue
DCCEPIL
* * **** End of Epilogue
*
* DSECT for automatic variables in "realloc"
* (FUNCTION #53)
*
@AUTO#realloc DSECT
DS XL104
realloc#retval#0 DS 1A ; retval
realloc#p#2 DS 1A ; p
realloc#old_size#2 DS 1F ; old_size
realloc#to_copy#2 DS 1F ; to_copy
*
@CODE CSECT
*
* Non-Re-Entrant Data Section
*
@DATA CSECT
@DATA RMODE ANY
@DATA AMODE ANY
*
END
/*
*
* A simple program to retrieve the user name
* on MVS.
*
**/
#include <stdio.h>
#include <string.h>
int main()
{
int flccvt, ascb, asxb, acee, i;
int *ip;
char aceeusri[9];
ip = (int *)0x224; /* PSAAOLD */
ascb = *ip;
ip = (int *)(ascb + 0x6c); /* ASCBASXB */
asxb = *ip;
ip = (int *)(asxb + 0xc8); /* ASXBSENV */
acee = *ip;
ip = (int *)(acee + 0x15); /* ACEEUSRI */
memcpy(aceeusri, ip, 8); /* Get USER ID */
aceeusri[8] = '\0'; /* NULL terminate */
printf("User name is `%s'\n", aceeusri);
}
../dcc -flicense=dignus.freebsd.inf -oasm0004.390 src0004.c
DCC Systems/C 390 compiler - version 1.31.00
(c) Copyright 1999-2000 Dignus, LLC All rights reserved.
DCC is licensed to Dignus, LLC.
DCC Return code 0, elapsed time 0.11 seconds.
*
* Compiled by DCC Version 1.31.00
* on Fri Oct 27 16:43:34 2000
*
@CRT0 ALIAS C'@crt0'
EXTRN @CRT0
*
*
*
* Code Section
*
@CODE ALIAS C'@SRC0004'
@CODE CSECT
@CODE AMODE ANY
@CODE RMODE ANY
@DATA ALIAS C'@src0004'
printf ALIAS C'printf'
EXTRN printf
*
*
*
main ALIAS C'main'
main DCCPRLG CINDEX=118,BASER=12,FRAME=152,ENTRY=YES
* ******* End of Prologue
* *
* *** int flccvt, ascb, asxb, acee, i;
* *** int *ip;
* ***
* *** char aceeusri[9];
* ***
* *** ip = (int *)0x224;
LA 2,548(0,0) ; ip
* *** ascb = *ip;
L 6,0(0,2)
LR 5,6 ; ascb
* ***
* *** ip = (int *)(ascb + 0x6c);
LR 6,5
A 6,@lit_118_1
LR 2,6 ; ip
* *** asxb = *ip;
L 6,0(0,2)
LR 4,6 ; asxb
* ***
* *** ip = (int *)(asxb + 0xc8);
LR 6,4
A 6,@lit_118_2
LR 2,6 ; ip
* *** acee = *ip;
L 6,0(0,2)
LR 3,6 ; acee
* ***
* *** ip = (int *)(acee + 0x15);
LR 6,3
A 6,@lit_118_3
LR 2,6 ; ip
* ***
* *** __memcpy(aceeusri,ip,8);
LA 6,120(0,13) ; &aceeusri
LR 7,2
MVC 0(8,6),0(7)
* *** aceeusri[8] = '\0';
LA 6,120(0,13) ; &aceeusri
LA 6,8(0,6)
LA 7,0(0,0)
STC 7,0(0,6)
* ***
* *** printf("User name is `%s'\n", aceeusri);
LA 6,@lit_118_4
LA 7,120(0,13) ; &aceeusri
STM 6,7,136(13)
LA 1,136(0,13)
L 15,@lit_118_5 ; printf
BALR 14,15
* *** }
@ret_lab_118 DS 0H
* * **** Start of Epilogue
DCCEPIL
* * **** End of Epilogue
DS 0D
@lit_118_4 DC XL8'E4A2859940958194' User.nam
DC XL8'854089A240796CA2' e.is...s
DC XL3'7D1500' ...
DC X'00'
@lit_118_3 DC F'21' 0x00000015
@lit_118_2 DC F'200' 0x000000c8
@lit_118_1 DC F'108' 0x0000006c
@FRAMESIZE_118 DC F'152'
@lit_118_5 DC A(printf)
*
* DSECT for automatic variables in "main"
* (FUNCTION #118)
*
@AUTO#main DSECT
DS XL96
main#flccvt#0 DS 1F ; flccvt
main#ascb#0 DS 1F ; ascb
main#asxb#0 DS 1F ; asxb
main#acee#0 DS 1F ; acee
main#i#0 DS 1F ; i
main#ip#0 DS 1A ; ip
main#aceeusri#0 DS 9CL1 ; aceeusri
*
@CODE CSECT
*
* Non-Re-Entrant Data Section
*
@DATA CSECT
@DATA RMODE ANY
@DATA AMODE ANY
*
END
/*
* __far pointer example.
*
* __far pointers pointer into Hiperspace (via AR registers)
*
* __far pointers may take advantage of the __based() attribute
* to indicate they are based on a particular __alet. Thus,
* several __far pointers may share __alet values. In this case
* the __far pointer only uses 4 bytes of memory.
*
* __far pointers which are not based use 8 bytes of memory and
* have the form:
* +----------+
* | ALET |
* +----------+
* | OFFSET |
* +----------+
*
* The following example declares a few __far __based() pointers and
* demonstrates movements to/from Hiperspace via dereferences of
* these pointers.
*
**/
main()
{
struct foo {
int field1;
int field2;
} ;
__alet base, base2;
__far struct foo __based(base) *far_foo_pointer;
__far struct foo __based(base2) *far_foo_pointer_2;
__far __based(base) *far_ip;
int i;
struct foo f;
/* Move from a __far structure to a local structure. */
f = *far_foo_pointer;
/* Move from a local structure to a __far structure. */
*far_foo_pointer = f;
/* Move one __far structure to another (note the two */
/* different based __alets */
*far_foo_pointer_2 = *far_foo_pointer;
/* Assign from a field in a __far structure */
i = far_foo_pointer -> field2;
/* Assign to a field in a __far structure */
far_foo_pointer -> field2 = 10;
/* Assign an integer to an __alet */
base = 0x0;
/* Simple dereference of a __far integer pointer */
i = *far_ip;
*far_ip = i;
}
../dcc -flicense=dignus.freebsd.inf -oasm0050.390 src0050.c
DCC Systems/C 390 compiler - version 1.31.00
(c) Copyright 1999-2000 Dignus, LLC All rights reserved.
DCC is licensed to Dignus, LLC.
DCC Return code 0, elapsed time 0.04 seconds.
*
* Compiled by DCC Version 1.31.00
* on Fri Oct 27 16:43:34 2000
*
@CRT0 ALIAS C'@crt0'
EXTRN @CRT0
*
*
*
* Code Section
*
@CODE ALIAS C'@SRC0050'
@CODE CSECT
@CODE AMODE ANY
@CODE RMODE ANY
@DATA ALIAS C'@src0050'
*
*
*
main ALIAS C'main'
main DCCPRLG CINDEX=6,BASER=12,FRAME=128,ENTRY=YES
* ******* End of Prologue
* *
* *** struct foo {
* *** int field1;
* *** int field2;
* *** } ;
* ***
* *** __alet base, base2;
* *** __far struct foo __based(base) *far_foo_pointer;
* *** __far struct foo __based(base2) *far_foo_pointer_2;
* *** __far __based(base) *far_ip;
* *** int i;
* ***
* *** struct foo f;
* ***
* ***
* *** f = *far_foo_pointer;
LA 6,120(0,13) ; &f
LR 7,2 ; far_foo_pointer
LR 8,3
SAR 8,7
CPYA 6,12 ; AR 12 is always 0
SAC 512(0) ; AR mode
MVC 0(8,6),0(8)
SAC 0(0) ; Primary mode
* ***
* ***
* *** *far_foo_pointer = f;
LR 6,2 ; far_foo_pointer
LR 7,3
SAR 7,6
LA 6,120(0,13) ; &f
CPYA 6,12 ; AR 12 is always 0
SAC 512(0) ; AR mode
MVC 0(8,7),0(6)
SAC 0(0) ; Primary mode
* ***
* ***
* ***
* *** *far_foo_pointer_2 = *far_foo_pointer;
L 6,100(0,13) ; base2
L 7,108(0,13) ; far_foo_pointer_2
SAR 7,6
LR 8,2 ; far_foo_pointer
LR 9,3
SAR 9,8
SAC 512(0) ; AR mode
MVC 0(8,7),0(9)
SAC 0(0) ; Primary mode
* ***
* ***
* *** i = far_foo_pointer -> field2;
LR 8,2 ; far_foo_pointer
LR 9,3
SAR 9,8
LA 9,4(0,9) ; offset of field2 in foo
SAC 512(0) ; AR mode
L 8,0(0,9)
SAC 0(0) ; Primary mode
LR 4,8 ; i
* ***
* ***
* *** far_foo_pointer -> field2 = 10;
LR 8,2 ; far_foo_pointer
LR 9,3
SAR 9,8
LA 9,4(0,9) ; offset of field2 in foo
LA 8,10(0,0)
SAC 512(0) ; AR mode
ST 8,0(0,9) ; offset of field2 in foo
SAC 0(0) ; Primary mode
* ***
* ***
* *** base = 0x0;
LA 6,0(0,0)
ST 6,96(0,13) ; base
* ***
* ***
* *** i = *far_ip;
LR 8,2 ; far_ip
LR 9,5
SAR 9,8
SAC 512(0) ; AR mode
L 8,0(0,9)
SAC 0(0) ; Primary mode
LR 4,8 ; i
* ***
* *** *far_ip = i;