64-Bit ZOS Assembler Coding
64-Bit ZOS Assembler Coding
David Bond
Tachyon Software LLC
dbond@tachyonsoft.com
As IBM customers have come to expect, major extensions have again been added to
the architecture without impacting older programs. Most OS/360, MVS, MVS/XA
and MVS/ESA programs will run correctly under z/OS in z/Architecture mode
without recompiling or relinking.
z/Architecture Overview
What is changed from ESA/390?
The PSW format was changed to allow instruction addresses above 2 Gigabytes.
However, as long as the instruction address is below 2 Gigabytes, the 128-bit PSW
can be mapped into the ESA/390 64-bit PSW with no loss of information.
The first 33 bits and the last 31 bits of the PSW are the same in both formats with the
following exceptions:
Bit 12: 1 for 64-bit PSW (old S/370 EC-mode bit), 0 for 128-bit PSW.
Bit 31: Always 0 in S/370 and ESA/390.
1 for AMODE 64, 0 for AMODE 24 or 31 in z/Architecture.
LPSW instruction automatically converts a 64-bit PSW to 128-bit format for
z/Architecture. New LPSWE instruction is used to load a 128-bit format PSW.
z/Architecture Overview
Regions
Address Region Region Region
Space First Second Third Segment Page Byte
264 253 242 231 220 212 20
64-bit mode.
Ƃ ESTA code 1 returns the 128-bit PSW mapped to a
SAM64, TAM.
Ƃ And many more...
Halfword Instructions:
And Immediate (NIxx) xx: HH=bits 0-15
Insert Immediate (IIxx) HL=bits 16-31
Load Logical Immediate (LLxx) LH=bits 32-47
Or Immediate (OIxx) LL=bits 48-63
Test Under Mask (TMxx)
z/Architecture Overview
z990 Instructions
Ƃ The z990 processors support “long displacement”
RX-format instructions, with a displacement field range
of -524288 to +524287 (±½Megabyte)
Ƃ All of the z/Architecture RX-format instructions
Assembly of the new z990 instructions and the long displacement versions of the
z/Architecture requires the OPTABLE(UNI) or OPTABLE(YOP) assembler options.
OPTABLE(YOP) is available with HLASM APAR PQ74561 and release 2.2.17 of
the Tachyon z/Assembler.
Long displacements can be explicitly specified or computed automatically from the
assembler's USING statements. The default maximum USING range is 4K times
the number of base registers specified on the USING, so you must specify an
explicit USING range to get a large positive displacement. There is no minimum
to the USING range, so negative displacements are always available. When multiple
address resolutions are available, the smallest negative displacement is only used if a
positive displacement cannot be calculated.
The assembler's USING(LIMIT(xxxx)) option is almost useless when used with long
displacement instructions since the maximum LIMIT value is 4095.
z/OS 64-Bit Overview
Changes
Ƃ Real storage above 2 Gigabytes (as of OS/390 2.10).
Impacts programs doing page fixing, CCW translation.
Expanded storage is no longer available.
ESO Hiperspaces are not supported.
Ƃ Virtual storage above 2 Gigabytes (as of z/OS 1.2).
New IARV64 service to manage storage “above the bar”.
Data spaces are still supported, but are limited to
2 Gigabytes each.
Ƃ Binder and loader support for AMODE 64 (z/OS 1.3).
Both older Load Module Format (LMF) and new
Program Objects can be marked as AMODE 64.
ƂNo support yet for PC routines entered in AMODE 64.
Except for programs performing CCW translation, very few older programs are
impacted by running z/OS in z/Architecture mode. However, there are exceptions.
One example: The VS/PASCAL library routines issue TM 116,X'80' to check if
AMODE 31 is available. Until z/Architecture, this was the high bit of the address
word of the Machine Check New PSW. This bit was 0 for MVS/370 and 1 for
MVS/XA and higher. In z/Architecture mode, location 116 is zero because the
Machine Check New PSW is in a different location and format. So, on a
z/Architecture system, VS/PASCAL programs think they are running on MVS/370
but will fail because the modules are marked RMODE ANY and loaded above the
16 Megabyte line. Lesson: Programs that access the PSA may not work in
z/Architecture mode.
z/OS 64-Bit Overview
RMODE 64?
z/OS is a hybrid 24/31/64-bit operating system. All three
addressing modes are supported and data maybe stored in
any of the three address ranges. Executable instructions
must be in 24-bit or 31-bit addressable storage, even if
running in AMODE 64. RMODE 64 is not yet supported
and may never be.
The TCB, RB, EPIE and SDWA control blocks have
not been changed to allow the 128-bit PSW to be stored.
This means that in order to store the PSW in 64-bit format,
the instruction address must be below the 2 Gigabyte “bar”
or else “bad things” will happen.
Interpreted programs (JAVA, REXX) could be loaded
above 2 Gigabytes.
As long as the instruction address is below 2 Gigabytes, the first 33 bits and last 31
bits of the 128-bit PSW can be mapped into a 64-bit PSW with no loss of
information. However, if the instruction address is above 2 Gigabytes, the address
bits above 31 will be lost when the PSW is saved in the TCB or RB.
If a program executes instructions “above the bar”, it must be disabled for interrupts.
Otherwise, the interrupt handlers may save the program's PSW in 64-bit format and
when the PSW is restored, the program will restart in a different location. This is
usually considered to be a “bad thing”.
z/OS 64-Bit Overview
AMODE 64!
Programs running in AMODE 64 can address all virtual
storage. Programs running in AMODE 31 cannot access
virtual storage above 2G.
Programs can switch to AMODE 64 from 24 or 31-bit mode
using the BSM, BASSM or SAM64 instructions or can be
started in AMODE 64.
When switching from 24 to 31-bit mode, programs had to
ensure that the low 7 bits of the high-order bytes of the
general registers were set to zero. When switching from
31 to 64-bit mode, the high-order 33 bits must be zeroed!
This must be done using the new z/Architecture instructions
(like LLGTR)
CODE31 CSECT
CODE31 AMODE 31
BASR 12,0 Set a base register
USING *,12
LA 13,SAVEAREA Get address of save area
LG 15,=AD(CODE64+1) Get address of CODE64 + AMODE
BASSM 14,15 Call CODE64 in AMODE 64
SVC 3 Done
LTORG
SAVEAREA DC 18F'0'
DROP
CODE64 CSECT
CODE64 AMODE 64
USING *,15 R15 points here
STMH 14,12,SAVEHIGH+12 Save upper register halves
LLGTR 13,13 Ensure R13 has a good address
STM 14,12,12(13) Save lower register halves
* do something interesting here
LMD 14,12,SAVEHIGH+12,12(13) Restore register values
LA 15,0 Set R15 to zero
BSM 0,14 Return to caller
SAVEHIGH DC 18F'0'
END CODE31
z/OS 64-Bit Overview
Data Spaces
For programs that are virtual-storage constrained, 64-bit
virtual storage is an alternative to data spaces.
Data spaces are limited to 2 Gigabytes. At any time only 15
are addressable (using access registers 1-15), limiting the
virtual storage data space to 30 Gigabytes. 64-bit virtual
storage allows over 16,000,000,000 Gigabytes (if there
were only enough disk space on Earth for paging.)
Data spaces still provide better storage isolation since a
valid ALET is required to access them. It is easier for a
cross-memory program to examine and modify another
address space's 64-bit virtual storage area than for it to
examine or modify data space storage.
Note: The 2 Gigabyte limit on the size of each Data Space is imposed by z/OS,
not z/Architecture.
Fun facts:
Time needed to page-in an area at 100 Megabytes per second:
1 Megabyte (Segment) .01 second
2 Gigabytes (Region 3rd) 20 seconds
4 Terabytes (Region 2nd) 12 hours
8 Petabytes (Region 1st) 3 years
16 Exabytes (Address Space) 5845 years
z/OS 64-Bit Overview
IARV64
The IARV64 service is available to AMODE 31 and
AMODE 64 programs to allocate virtual storage “above
the bar”. Storage is allocated in 1 Megabyte blocks.
The storage range between 2 Gigabytes and 4 Gigabytes
is never allocated - the “bar” is 2 Gigabytes wide!
The MEMLIMIT JCL operand of the JOB or EXEC
statement must be set to a non-zero value to allow IARV64
to function. MEMLIMIT can range from 0 to 99999 in
units of Megabytes, Gigabytes, Terabytes or Petabytes or be
set to NOLIMIT.
An allocation unit of 1 Megabyte might seem large but compared to the address
space size, 1 Megabyte is much smaller than the 8 byte allocation unit for “below the
bar” allocations. There is really no point to allocation of space “above the bar”
unless a program uses very large amounts of virtual storage.
z/OS 64-Bit Overview
IARV64 Functions
IARV64 is the “one-stop shopping for all your above-the-bar
virtual storage needs”.
IARV64 service 31-bit service
GETSTORE GETMAIN/STORAGE OBTAIN
DETACH FREEMAIN/STORAGE RELEASE
PAGEIN PGSER LOAD
PAGEOUT PGSER OUT
PAGEFIX PGSER FIX
PAGEUNFIX PGSER FREE
DISCARDDATA PGSER RELEASE
CHANGEGUARD PGSER PROTECT (somewhat)
LIST VSMLIST
GUARD AREA
When a block of virtual storage is allocated, a “guard area” may be allocated either
just above or below the block of virtual storage. The guard area is not addressable
but the virtual storage address range is reserved.
The addressable block may be expanded or reduced in size, reducing or expanding
the size of the guard area. The guard area does not count against the MEMLIMIT,
so you can allocate as large of a guard area as you want.
The guard area allows a virtual storage area to grow contiguously up to a preset
limit without precommitting system resources. This can be very useful for stack-like
(LIFO) storage areas.
z/OS 64-Bit Overview
Changed Services
Watch out for the following services when running in
AMODE 64:
Ƃ Recovery: ESPIE, ESTAE
SYNCH, XCTL.
Ƃ I/O: EXCP
SYSSTATE ASCENV={P|AR},AMODE64={NO|YES},ARCHLVL={0|1|2}
With AMODE64=YES, system macros may get the CVT address using:
LLGT 14,16
instead of:
L 14,16
to ensure that bits 0-33 of the address are valid.
ARCHLVL values:
0: ESA/390
1: ESA/390 with the relative and immediate instructions
required for OS/390 R10 (Architectural Level Set 1)
2: z/Architecture
With ARCHLVL set to 0 or 1, no z/Architecture-only instructions will be generated
by the system macros.
z/OS 64-Bit Overview
Recovery Services
The EPIE control block passed to ESPIE exits and the
SDWA control block passed to ESTAE exits has been
expanded to allow the entire 64-bit general register values to
be captured at the time of the error and to be changed upon
retry. If the error occurred in AMODE 64, the exits need to
be sensitive to the upper 32 bits of the general registers.
ESPIE and ESTAE exits are invoked in the AMODE at
the time the ESPIE or ESTAE was established, not the
AMODE at the time of the error.
Note: the 64-bit SDWA information is only available if
SDWALOC31=YES was specified on the ESTAE macro.
Recovery may need to recognize new Program Check Interruptions, which are
mapped to new S0C4 reason codes. All are caused by references to an invalid virtual
storage address, just like Page Translation (S0C4-00000011) and Segment
Translation (S0C4-00000010). The new codes are:
S0C4-00000038 ASCE Type
S0C4-00000039 Region First
S0C4-0000003A Region Second
S0C4-0000003B Region Third
EPIE Fields:
EPIEFLGS,EPIEUP64 - If set, use the 64-bit register values
EPIEG64 - 16 doubleword register values
Note: the 64-bit Translation Exception Address is in the SCA, not the EPIE.
SDWA fields:
SDWAXEME - Address of SDWARC4 section, containing the 16 64-bit
general register values, the 16 64-bit control register values and the 64-bit
Translation Exception Address. This section is only available if
ESTAE SDWALOC31=YES was specified.
z/OS 64-Bit Overview
Contents Supervision
Programs in one AMODE can ATTACH, LINK, SYNCH or
XCTL to a program with a different AMODE. Programs
need to be careful when passing addresses to AMODE 64
programs since they will expect 64-bit clean addresses.
ATTACHX, LINKX, SYNCHX and XCTLX are supported
in AMODE 64, not ATTACH, LINK, SYNCH and XCTL.
LINKX has two new parameters in z/OS 1.3:
PLIST4|PLIST8 to specify 4-byte or 8-byte parameter
addresses and AMODE64OK=YES|NO to indicate if an
AMODE 31 program can LINK to an AMODE 64 program
without an ABEND.
There are related changes for SYNCHX.
In z/OS 1.3, LOAD has a new parameter that is not directly related to AMODE 64.
The EXTINFO parameter allows LOAD to return information about
RMODE=SPLIT modules and modules larger than 128 Megabytes without the
need for a separate call to the CSVQUERY service. The EXTINFO parameter
area is mapped by the CSVEXTI macro.
z/OS 64-Bit Overview
I/O
I/O buffers and control blocks are not supported “above the
bar”. Usually, buffers can be backed by real storage above 2
Gigabytes. The I/O services have been updated to build
CCW IDAWs that address 64-bit real storage. The IDAWs
themselves must still be below 2 Gigabytes because the
CCW address field is still limited to 31 bits.
EXCPVR does not support real storage addresses above 2
Gigabytes. Buffers must be page fixed in 31-bit addressable
real storage. Also, note that the LRA instruction is often
used in EXCPVR code and will fail if the virtual storage is
backed by real storage above 2 Gigabytes.
Both GETMAIN and STORAGE OBTAIN support the LOC=(,64) option to specify
that the virtual storage can be backed by real storage above 2 Gigabytes. Do not
specify LOC=(,64) for buffers intended to be used for EXCPVR.
The “old” LOC= names are mapped to new values:
BELOW => 24
ANY => 31
Use 24 and 31 instead of BELOW and ANY since 24 and 31 are more explicit in the
64-bit world.
AMODE 64 Linkage
ATTACH
Upon entry from ATTACH, the following registers are set
for AMODE 64 programs:
R1: address of traditional parameter list in LOC=24 storage.
High-order 40 bits are zero.
R13: address of 144-byte save area in LOC=24 storage.
High-order 40 bits are zero.
R14: address of an SVC 3 instruction.
High-order 40 bits are zero.
R15: X'00000000 FFFFF002', indicating that the caller
was in AMODE 64.
Upon entry to an AMODE 64 program, register 15 does not contain the entry
address. An AMODE 64 program is expected to use the LARL instruction or
another method to establish any needed base registers rather than relying on the value
in R15.
The save area pointed to by R13 is 144 bytes and is big enough for a format-4 save
area. However, C'F4SA' is not set at R13+4.
AMODE 64 Linkage
Save Areas
Format 0: traditional 72-byte save area containing only
the low register halves.
Format 1: C'F1SA' in second word indicates that the
registers are saved on the linkage stack.
Format 4: C'F4SA' in second word indicates a 144-byte
save area containing the full 64-bit register values.
Format 5: C'F5SA' in second word indicates a 208-byte
save area used when an AMODE 24 or 31 program calls
an AMODE 64 program. The first 144 bytes are identical
to the Format 4 save area. The upper halves of the caller's
registers 0-15 are saved in the remaining 64 bytes.
System macro IHASAVER maps various save area formats.
This code is very similar to the standard linkage code typically used by AMODE 24
and AMODE 31 programs.
Ƃ FPRs 8 through 15 are unchanged; The Floating Point Control (FPC) Register
is unchanged with the exception of two fields: the IEEE exception flags and the
data exception code (DXC).
Ƃ When return information is provided in GPR 0, 1, and/or 15 (for example return
and reason codes), only bits 32-63 of the register contain the returned value.
AMODE 64 Linkage
Using a Format-5 Save Area
Entry Linkage from AMODE 24/31 caller via BASSM:
STM 14,12,12(13) Save caller's registers
STMH 15,15,8(13) Save high half of R15
LARL 15,SAVEAREA Get new save area address
STMH 0,14,144(15) Save upper register halves
MVC 204(4,15),8(13)Save upper half of R15
LLGTR 13,13 Ensure good address
STG 13,128(,15) Chain to previous save area
ST 15,8(,13) Chain to new save area
LGR 13,15 Set R13 to save area address
LARL 12,DATA Set base register for data
USING DATA,12 Tell the assembler
LLGTR 1,1 Ensure R1 has a good address
Using a Format 5 Save Area for transition between AMODE 24/31 and AMODE 64
is much more complex than standard linkage. The upper register halves cannot be
saved in one instruction because a 64-bit clean register is needed to point to the new
save area.
Note: The Format 5 Save Area must be “below the bar” since there is only a fullword
available in the standard 72-byte save area to point to the next save area.
AMODE 64 Linkage
Using a Format-5 Save Area
Exit Linkage back to AMODE 31/24 caller:
LHI 15,0 Set return code
LG 13,128(,13) Restore caller's R13
ST 15,16(,13) Save return code
MVC 8(4,13),SAVEAREA+196 Save R13 upper half
LMH 0,15,SAVEAREA+144 Restore upper halves
LLGTR 13,13 Ensure R13 has good address
LM 14,12,12(13) Restore lower register halves
LMH 13,13,8(13) Restore upper half of R13
BSM 0,14 Return to caller
Exit code using the Format 5 Save Area is also much more complex than standard
linkage. The code needs to be careful to avoid restoring the upper register halves of
any registers it will use later.
Note: this code does not preserve bit 32 of register 13 because there is no defined
place to save it in the Format 5 Save Area.
AMODE 64 Linkage
Using the Linkage Stack
Entry Linkage from caller via BASSM:
BAKR 14,0 Save caller's registers
LARL 13,SAVEAREA Get dummy save area address
LARL 12,DATA Set base register for data
USING DATA,12 Tell the assembler
* The following code is needed if the caller might have been in AMODE 64:
LA 2,1 Get caller's
ESTA 2,2 PSW
TMLL 2,1 Caller was in AMODE 64?
JNZ Entered Yes: jump
LLGTR 1,1 Ensure R1 has a good address
Entered ds 0h
Exit Linkage back to caller:
LGHI 15,0 Set return code
PR , Return to caller
DATA LTORG Start of data area
SAVEAREA DC 0D'0',F'0',C'F1SA'
Using the linkage stack is much simpler than using save areas. The BAKR and PR
instructions are much slower than using STM and LM for saving registers, but they
are much faster than using GETMAIN/FREEMAIN to obtain and release storage for
a save area.
Also, unlike the previous linkage examples, this code make no assumptions about the
AMODE of the caller. It works if the caller was in AMODE 24, 31 or 64. However,
this code must be entered using BASSM even if the caller is also in AMODE 64 to
ensure that R14 contains the AMODE bits. The BASR instruction does not set the
low bit to indicate that the caller is AMODE 64.
This code fully preserves all 64 bits of registers R2-R14 and all 32 bits of access
registers AR2-AR14. If the upper halves of R0, R1 or R15 or access registers AR0,
AR1 or AR15 must be preserved, use the EREGG instruction before the PR.
Trimodal Code
Code that works in any AMODE
Example of code that works with 3 and 4-byte addresses in
any AMODE:
USING PSA,0 Addressability to PSA
LA R2,0 Needed for AMODE 64
L R2,PSATOLD Get current TCB address
USING TCB,R2 Addressability to TCB
L R2,TCBRBP Get current RB address
USING RBBASIC,R2 Addressability to RB
LOOP DS 0H
TM RBSTAB2,RBTCBNXT First RB found?
BE FOUND yes, branch
ICM R2,7,RBLINKB Get next RB address
B LOOP Check if first RB yet
FOUND DS 0H
This is an example of code that works in any of the three addressing modes. It is
identical to code that might have been written for an MVS/XA AMODE 31 program
except for the addition of the Load Address instruction and it would still work on that
system.
In AMODE 24 and AMODE 31, the LA instruction would clear the low 32 bits of
register 2 before loading the TCB address. This has no effect in AMODE 24 or
AMODE 31 except for the very small overhead of the LA instruction.
In AMODE 64, the LA instruction clears all 64 bits of register 2 before the low 32
bits are loaded. This ensures that register 2 contains a valid 64-bit address.
An LA for address 0 should be used to clear a register before an ICM to get a 3-byte
address. Traditionally an SR, SLR or XR instruction is used to clear the register but
none of these clear the upper register half in AMODE 64. The LA instruction is just
as fast so there is no reason not to use it instead or SR, SLR or XR.
With a little care, it is often not hard to write code that will work in any addressing
mode.
Sample Program
Punch ' MODE RMODE(SPLIT)'
Print NoGen
SYSSTATE AMODE64=YES,ARCHLVL=2
* This OPSYN renames BAS to BRAS to keep OPEN and CLOSE happy
BAS Opsyn BRAS
This example program reverses the records in a sequential data set. This data set can
be quite large - it might be on tape. This program could handle a data set as large as
10 Gigabytes and can handle even larger data sets by changing one statement.
The program reserves a virtual storage address range of 10 Gigabytes and obtains
an initial allocation of 1 Megabyte. The program then opens the data set and copies
the records into the allocated space, increasing the allocation by 1 Megabyte at a
time as needed. Once the records are read, it closes the data set, reopens it for
output and writes the records in reverse order. All I/O is performed using QSAM
in AMODE 31.
Initially and most of the time the program runs in AMODE 64, switching to
AMODE 31 only to perform I/O operations. The program is split into RMODE 24
and RMODE 31 sections. The RMODE 24 section holds the I/O control blocks
(the DCB must still be “below the line”) and all modifiable storage. The RMODE
31 section contains the program logic and the static storage. This program requires
z/OS 1.3 or later because the entry point is AMODE 64.
The entry point is in the RMODE 24 section. The initial code sets up the save area
and branches to the code in the RMODE 31 section.
SaveArea Dc 18FD'0'
Origin Dc AD(0) Starting address of file storage
High Dc AD(0) Ending address of file storage
DcbIn DCB DDNAME=SYSUT1,DSORG=PS,MACRF=(GL),
RECFM=FB,LRECL=1000,DCBE=DcbeIn
DcbeIn DCBE RMODE31=BUFF,EODAD=Eof
DcbOut DCB DDNAME=SYSUT1,DSORG=PS,MACRF=(PL),
RECFM=FB,LRECL=1000,DCBE=DcbeOut
DcbeOut DCBE RMODE31=BUFF
IARV64 MF=(L,Iarv64) IARV64 parameter area
YREGS
Print Gen
Main Rsect Start of RMODE 31 area (program)
Main Amode 64
Main Rmode 31
LARL R12,Static Get static data area address
Using (Static,MainEnd),R12 Tell the assembler
SGR R2,R2 Clear record counter
The I/O control blocks and modifiable storage areas follow the entry logic in the
RMODE 24 section. DCBEs are required to support QSAM buffers and the
EODAD address “above the line”.
“Origin” will contain the starting address of the storage obtained to hold the records.
“High” will contain the ending address (+1) of the area and will be incremented by
1 Megabyte as the area is expanded.
The RMODE 31 section is named “Main”. The code sets up a base register for the
static storage area and then clears the record counter in R2.
IARV64 REQUEST=GETSTOR, Allocate 1 megabyte,
SEGMENTS==AD(MaxSize), but reserve much
GUARDLOC=HIGH, more in case the file
GUARDSIZE==A(MaxSize-1), is very large
ORIGIN=Origin,
MF=(E,Iarv64,COMPLETE)
LG R4,Origin Get starting address
LGR R0,R4 Compute ending address
AGF R0,=A(1024*1024) *
STG R0,High *
GetLoop ds 0h
SAM31 Switch to AMODE 31
LA R1,DcbIn Get DCB address
GET (1) Read next record
SAM64 Switch to AMODE 64
LAY R0,RecordLength(,R4) Get address of next slot
CLG R0,High Room for this record?
JNH MoveIt yes: jump
The program reserves a 10 Gigabyte virtual storage address range “above the bar”
using the IARV64 service. Initially, only the first Megabyte of the range is actually
allocated. “Origin” and “High” are set to the starting and ending addresses of the
allocated area.
The program switches to AMODE 31 to perform the OPEN service on the data set.
It then starts reading the records using QSAM Locate Mode.
After each record is read, the program ensures that the allocated area is large enough
to hold the next record.
LR R3,R1 Save R1
IARV64 REQUEST=CHANGEGUARD, Allocate another
CONVERT=FROMGUARD, Megabyte of storage
CONVERTSIZE==F'1',
MEMOBJSTART=Origin,
MF=(E,Iarv64,COMPLETE)
LR R1,R3 Restore R1
LG R0,High Update the high storage address
AGF R0,=A(1024*1024) to indicate it is
STG R0,High 1 Megabyte larger
MoveIt ds 0h
LLGTR R0,R1 Convert to 64-bit address
LGHI R1,RecordLength Copy record from buffer
LGHI R5,RecordLength *
MoveIn MVCLE R4,R0,0 *
BRC 1,MoveIn *
AGHI R2,1 Increment record count
J GetLoop Go read next record
If there is not enough room in the storage area for the next record, the program uses
the IARV64 REQUEST=CHANGEGUARD service to allocate another Megabyte
from the guard area. The program then updates the ending address in “High”.
Once there is enough room in the storage area for the record, the record is copied
from the QSAM buffer into the next slot in the storage area and the record counter is
incremented.
Upon End-Of-File, the data set is closed and the record counter is checked. If zero
or one records were read, the program ends because there is nothing to reverse.
OPEN (DcbOut,(OUTPUT)),MODE=31 Open data set
PutLoop ds 0h
SAM31 Switch to AMODE 31
LA R1,DcbOut Get DCB address
PUT (1) Get location of next record
SAM64 Switch to AMODE 64
LLGTR R0,R1 Convert to 64-bit address
LAY R4,-RecordLength(,R4) Get address of record
LGHI R1,RecordLength Copy record to buffer
LGHI R5,RecordLength *
MoveOut MVCLE R0,R4,0 *
BRC 1,MoveOut *
LAY R4,-RecordLength(,R4) Get address of record
BRCTG R2,PutLoop Go write next record
To reverse the records in the data set, the program next opens the data set for output.
It then writes the records in reverse order using QSAM Locate Mode. Each record is
copied from the storage area into the QSAM buffer. Once all records are written, the
data set is closed.
Done ds 0h
SAM64 Switch to AMODE 64
IARV64 REQUEST=DETACH, Free the file storage
MEMOBJSTART=Origin,
MF=(E,Iarv64,COMPLETE)
End Entry
When the program is done, it releases the allocated virtual storage and the reserved
address range using IARV64. It then sets the return code to zero and returns to the
caller.
The data set is arbitrarily defined as containing 1000-byte fixed length records for
this example. It could easily be changed to use the LRECL from the DCB instead of
a constant. Also, “MaxSize” can be easily changed to be larger if needed.
The MEMLIMIT parameter of the EXEC JCL statement must be set to a value large
enough to hold the entire data set in virtual storage. This can impact the size of page
data sets if there is not enough real memory to run this program.
Need More Information?
z/OS 1.4 MVS Programming: Assembler Services Guide
SA22-7605-04
z/OS 1.4 MVS Programming: Assembler Services Reference,
Volume 1 SA22-7606-03
z/OS 1.4 MVS Programming: Assembler Services Reference,
Volume 2 SA22-7607-03
z/OS 1.3-1.4 MVS Programming: Extended Addressability Guide
SA22-7614-02
z/Architecture Principles of Operation
SA22-7832-02
Chapter 4 of the z/OS 1.3 and 1.4 MVS Programming: Extended Addressability
Guide is entitled “Using the 64-bit Address Space”. This chapter is probably the
most readable description of how and why to use 64-bit assembler code.