.TITLE REVERSE - A program to demo simple I/O from MACRO .IDENT /01-000/ ;++ ; ; Facility: REVERSE ; ; Author: Hunter Goatley ; ; Date: May 31, 1991 ; ; Functional Description: ; ; Simple program to read a string from SYS$INPUT and print it in ; reverse order to SYS$OUTPUT. ; ; Modified by: ; ; 01-000 Hunter Goatley 31-MAY-1991 08:02 ; Original version. ; ;-- .DSABL GLOBAL ; Declare external references .ENABL SUPPRESSION ; Don't list unreference symbols .NOSHOW BINARY ; Don't include binary listings ; ; External routines: ; .EXTRN LIB$GET_INPUT ; Read from SYS$INPUT .EXTRN LIB$PUT_OUTPUT ; Print to SYS$OUTPUT ; ; Declare symbols used here (the following macros are stored in the default ; MACRO library SYS$LIBRARY:STARLET.MLB). ; $DSCDEF ; Descriptor symbols $SSDEF ; System service status symbols .SHOW BINARY ; Include binary in listings .PAGE .SBTTL Data storage .PSECT _REVERSE_DATA,NOEXE,WRT,LONG PROMPT: .ASCID /Enter a string: / ; Prompt for input .ALIGN LONG ; Align on longword boundary ; ; Descriptor for input buffer ; INBUFF_L = 256 ; Length of the buffer INBUFF_D: .WORD INBUFF_L ; Length of the buffer .BYTE DSC$K_DTYPE_T ; Text string .BYTE DSC$K_CLASS_S ; Static string .ADDRESS INBUFF ; Address of the buffer INBUFF: .BLKB INBUFF_L ; Reserve space for the buffer ; ; Descriptor for the output buffer ; OUTBUFF_D: .WORD 0 ; Length filled in at run-time .BYTE DSC$K_DTYPE_T ; Text string .BYTE DSC$K_CLASS_S ; Static string .ADDRESS .+4 ; Address of the buffer .BLKB INBUFF_L ; Reserve space for buffer .PAGE .SBTTL The Program .PSECT _REVERSE_CODE,EXE,NOWRT,LONG .ENTRY REVERSE,^M ; ; Call run-time library routine to read input from SYS$INPUT ; PUSHAW INBUFF_D ; Address of word to receive ; ... the length of the input PUSHAQ PROMPT ; Address of the prompt PUSHAQ INBUFF_D ; Address of the input buffer ; ... descriptor CALLS #3,G^LIB$GET_INPUT ; Read input from SYS$INPUT BLBC R0,100$ ; Branch on an error ; ; Now set up some registers to contain the values needed to copy the string ; in reverse order from the input buffer to the output buffer. ; ; First, make R2 point to the end of the input buffer ; MOVAB INBUFF,R2 ; R2 -> input buffer MOVZWL INBUFF_D,R0 ; R0 = length of the input ; ... (converted to longword) ADDL2 R0,R2 ; R2 -> byte past end of buffer ; ; Since the output string will the the same length as the input string, go ; ahead and copy the length of the string the output buffer descriptor. ; MOVW R0,OUTBUFF_D ; Store length in descriptor MOVAB @OUTBUFF_D+4,R1 ; R1 -> output buffer ; ; The following loop copies the input string to the output buffer a byte ; at a time, moving backwards through the input buffer and forward through ; the output buffer. ; ; At this point, the following registers contain the following values: ; ; R0 = Number of character to copy ; R1 = Pointer to beginning of output buffer ; R2 = Pointer to end of input buffer ; 10$: MOVB -(R2),(R1)+ ; Copy byte from input buffer ; ... to the output buffer SOBGTR R0,10$ ; Loop until all copied PUSHAQ OUTBUFF_D ; Print the output buffer CALLS #1,G^LIB$PUT_OUTPUT ; ... to SYS$OUTPUT 100$: RET ; Return to caller .END REVERSE