In our class we are using the ASSIST software, which provides a number of extra "pseudo-instructions" for our use. These are not part of the assembly language itself, but they make it easier to do a number of common tasks we need to do. In the actual assembly language, all these things can be done without X-instructions, but some of them are a bit beyond the scope of this course.
We will use XREAD and XPRNT throughout the course, but we will eventually get away from XDECI and XDECO.
XDUMP
XDUMP is intended as a diagnostic tool. We can use it in two ways:
XDUMP
or
XDUMP,N
In the first case, XDUMP by itself will simply print out the values of all 16 registers, 8 on one line in two groups of 4 and then 8 on the next line. The values are printed in hexadecial format, 2 hex digits per byte.
In the second case, XDUMP will print out the values of N bytes in memory starting at the address. It prints these in hexadecimal value, two hex digits per byte. It may print more than N values, as it prints out a minimum of 32 bytes at a time. On the left side of the line, it prints the addresses of the bytes involved, and on the right side, between asterisks, we find the printed version of the bytes; most values do not print as anything useful.
If the length is omitted, a default length of 4 is used. The maximum allowable length appears to be 4095.
XDUMP counts the number of times it is called.
XDUMP actually uses another tool, XSNAP, to do its work, so the output from XDUMP refer to XSNAP.
XREAD
XREAD is used for input. The format for it is:
XREAD address,N
This will read N bytes from "standard input" (a file) and store them in memory in consecutive bytes starting at the given address. Here 1 <= N <= 80. The address is a D(X,B) address.
XREAD will set the condition code:
CC = 0 if all goes well CC = 1 if the end of the file is encountered CC = 2 and CC = 3 are not used
For example:
XREAD CARD,80
This will read 80 bytes and store them in CARD, which has presumably been declared as:
CARD DS 80C
XDECI
Once we have read a line of data, we may want to interpret numbers on that line as binary numbers. XDECI will do this for us. The format for it is:
XDECI register,address
The address is a D(X,B) address.
Suppose we have just read data into CARD, and there should be a number in the data. We use:
XDECI 4,CARD
XDECI will start looking at bytes at the beginning of CARD. It will skip over blanks until it finds a non-blank character. It expects the first non-blank character to be '+' or '-' or a digit. Assume that happens. XDECI then will read up to 9 digits until it finds a non- digit character (such as a blank), and it will convert this number to binary and store it in register 4.
Along the way, what can happen? If the first non-blank character found is not what it should be, we have an error. The value in the register is not changed. Register 1 is set to the address of the bad character.
If more than 9 digits are found, we have an error. The value in the register is not changed. Register 1 is set to the address of the first character found after the digits.
If no error occurs, register 1 will be set to the address of the first character found after the digits.
Notice that XDECI will always change the value of register 1. Do not use 1 as the register in the XDECI instruction.
XDECI will always set the condition code:
CC = 0 if the value is 0 CC = 1 if the value is negative CC = 2 if the value is positive CC = 3 if an error occurs
XDECO
Suppose we have a value in a register and we want to convert it to a printable form. XDECO will do this for us. The format for it is:
XDECO register,address
XDECO will convert the signed 32-bit binary value in the register into printable characters (base 10, with a leading minus sign if needed) and store it in the 12 bytes starting at the given address, right- justifed.
The address is a D(X,B) address.
XPRNT
XPRNT is used for printed output. The format for it is:
XPRNT address,N
This will write the N bytes starting at the address into "standard output" (a file). It is our responsibility to ensure that each byte corresponds to a printable character. Here 2 <= N <= 133. The address is a D(X,B) address.
When we want printed output, we may want to worry about spacing. To handle this, we have carriage-control characters. Suppose we use XPRNT:
XPRNT PLINE,121
The first character in PLINE will be interpreted as a carriage-control character. An actual mainframe printer will know how to make use of this:
Value Action ----- ---------------- blank single-spacing '0' double-spacing '-' triple-spacing '1' advance the page
If the carriage-control character is interpreted, its value is not also printed. Other values are often also interpreted as single- spacing, but this is not guaranteed, and they will also not be printed. To avoid trouble with this, make sure you know what carriage-control character you are using:
PLINE DC C' ' Single-Spacing DS 120C
Sometimes if we have a complex line to print, it is a niusance to add up its length. You can actually have the assembler do this for you. We could have:
PLINE DC C'0' Double-Spacing (complicated stuff) PEND DC 0C
which we can print with:
XPRNT PLINE,(PEND-PLINE)
Here the assembler will evaluate each of PEND and PLINE as an address (a number) and subtract to get the length of PLINE.
Example Program
* This program will read lines until it reaches the end of the file. * Each line contains one integer. The program finds the sum of the * integers and prints it. * * Register Usage: * 4 -- Number just read * 5 -- Sum * 15 -- Base register * IODEMO CSECT USING IODEMO,15 SR 5,5 Set Sum = 0 TOPLOOP XREAD CARD,80 Read a line BC B'0100',ENDLOOP If we found EOF, end the loop XDECI 4,CARD Extract a number from the line BC B'1110',OKAY Do we have an error? XDUMP If so, get a dump and BR B'1111',QUIT end the program now OKAY AR 5,4 Accumulate the Sum BC B'1111',TOPLOOP Repeat the loop ENDLOOP XDECO 5,OUTNUM Put the Sum on the line XPRNT OUTLINE,81 Print the line QUIT BR 14 Return to operating system CARD DS 80C Input record OUTLINE DC C'0' Output line, double-spacing DC 10C' ' DC CL11'The sum is ' OUTNUM DS 12C DC CL47' ' END IODEMO
Work your way through the example and make sure you understand how the pieces fit together.
Read more than one number from a line
Suppose the input line contains several numbers separated by spaces, like this:
___12345______6789___-7813___0___523___
We would like to read each of these numbers. How do we do it? Remember that XDECI sets register 1 = the address of the next character after the digits it reads. We can use that to control a loop, provided some non-digit character is eventually found to end the loop.
So declare CARD as follows:
CARD DS 80C STAR DC CL2' *'
and use two loops:
SR 5,5 Set Sum = 0 TOP1 XREAD CARD,80 Read a line BC B'0100',END1 If we found EOF, end loop 1 XDECI 4,CARD Extract a number to start loop 2 TOP2 BC B'0001',END2 On error, end loop 2 AR 5,4 Accumulate the Sum XDECI 4,0(0,1) Extract next number BC B'1111',TOP2 Repeat loop2 END2 BC B'1111',TOP1 Repeat loop1 END1 XDECO 5,OUTNUM Put the sum on the line XPRNT OUTLINE,81 Print the line
Notice that this version does not check much for bad data.
Why do we have ' *' as the marker at the end of CARD instead of just '*'? The reason is that we might have the last number right at the end of the line, so register 1 would be pointing at '*' anyway. We want to be sure that the inside loop ends when we reach the asterisk.