When using data spaces, you sometimes have large amounts of data to transfer between the address space and the data space. This information contains examples of two subroutines, both named COPYDATA, that show you how to use the Move (MVC) and Move Long (MVCL) instructions to move a variable number of bytes into and out of a data space. (You can also use the examples to help you move data within an address space.) The two examples perform exactly the same function; both are included here to show you the relative coding effort required to use each instruction.
Input: AR/GR 2 Target area location
AR/GR 3 Source area location
GR 4 Signed 32-bit length of area
(Note: A negative length is treated as zero.)
GR 14 Return address
Output: AR/GR 2-14 Restored
GR 15 Return code of zero
The routines can be called in either primary or AR mode; however, during the time they manipulate data in a data space, they must be in AR mode. The source and target locations are assumed to be the same length (that is, the target location is not filled with a padding character).
COPYDATA DS 0D
BAKR 14,0 SAVE CALLER'S STATUS
LAE 12,0(0,0) BASE REG AR
BALR 12,0 BASE REG GR
USING *,12 ADDRESSABILITY
.
LTR 4,4 IS LENGTH NEGATIVE OR ZERO?
BNP COPYDONE YES, RETURN TO CALLER
.
S 4,=F'256' SUBTRACT 256 FROM LENGTH
BNP COPYLAST IF LENGTH NOW NEGATIVE OR ZERO
* THEN GO COPY LAST PART
.
COPYLOOP DS 0H
MVC 0(256,2),0(3) COPY 256 BYTES
LA 2,256(,2) ADD 256 TO TARGET ADDRESS
LA 3,256(,3) ADD 256 TO SOURCE ADDRESS
S 4,=F'256' SUBTRACT 256 FROM LENGTH
BP COPYLOOP IF LENGTH STILL GREATER THAN
* ZERO, THEN LOOP BACK
COPYLAST DS 0H
LA 4,255(,4) ADD 255 TO LENGTH
EX 4,COPYINST EXECUTE A MVC TO COPY THE
* LAST PART OF THE DATA
B COPYDONE BRANCH TO EXIT CODE
COPYINST MVC 0(0,2),0(3) EXECUTED INSTRUCTION
COPYDONE DS 0H
.
* EXIT CODE
LA 15,0 SET RETURN CODE OF 0
PR RETURN TO CALLER
COPYDATA DS 0D
BAKR 14,0 SAVE CALLER'S STATUS
LAE 12,0(0,0) BASE REG AR
BALR 12,0 BASE REG GR
USING *,12 ADDRESSABILITY
.
LA 6,0(,2) COPY TARGET ADDRESS
LA 7,0(,3) COPY SOURCE ADDRESS
LTR 8,4 COPY AND TEST LENGTH
BNP COPYDONE EXIT IF LENGTH NEGATIVE OR ZERO
.
LAE 4,0(0,3) COPY SOURCE AR/GR
L 9,COPYLEN GET LENGTH FOR MVCL
SR 8,9 SUBTRACT LENGTH OF COPY
BNP COPYLAST IF LENGTH NOW NEGATIVE OR ZERO
* THEN GO COPY LAST PART
.
COPYLOOP DS 0H
LR 3,9 GET TARGET LENGTH FOR MVCL
LR 5,9 GET SOURCE LENGTH FOR MVCL
MVCL 2,4 COPY DATA
ALR 6,9 ADD COPYLEN TO TARGET ADDRESS
ALR 7,9 ADD COPYLEN TO SOURCE ADDRESS
LR 2,6 COPY NEW TARGET ADDRESS
LR 4,7 COPY NEW SOURCE ADDRESS
SR 8,9 SUBTRACT COPYLEN FROM LENGTH
BP COPYLOOP IF LENGTH STILL GREATER THAN
* ZERO, THEN LOOP BACK
.
COPYLAST DS 0H
AR 8,9 ADD COPYLEN
LR 3,8 COPY TARGET LENGTH FOR MVCL
LR 5,8 COPY SOURCE LENGTH FOR MVCL
MVCL 2,4 COPY LAST PART OF THE DATA
B COPYDONE BRANCH TO EXIT CODE
COPYLEN DC F'1048576' AMOUNT TO MOVE ON EACH MVCL
COPYDONE DS 0H
.
* EXIT CODE
LA 15,0 SET RETURN CODE OF 0
PR RETURN TO CALLER