I have following instructions in an assmebler program.
I a somewhat new to assembler programming .Can you please help me find out what is happening here ?
I assume that
1. 4 bytes of AMRECLN are loaded into R1.
2. Store WSASCNB into R1 (half word) again (wont it override step1)
3. Exclusive Or on WSASCSA
4. Branch to GETMAIN and save address of next instruction in R2.
5. Load address of WSASCSA in R7.
with base address VD2AMDF and Base register R7.
Also, How do we select which registers to use at which point while writing a program. e.g I have
R0 EQU 0 NOT USED
R1 EQU 1 WORK - IOCS
R2 EQU 2 CICS - FIO,FWACBAR - WORK
R3 EQU 3 WORK
R4 EQU 4 WORK
R5 EQU 5 CICS - TIOABAR
R6 EQU 6 CICS - TCTTEAR
R7 EQU 7 SYSTEM WORK AREA - VD2SWADF
R8 EQU 8 LINE CONTROL AREA - VD2ILCDF
R9 EQU 9 WORK
RA EQU 10 BASE REGISTER
RB EQU 11 CICS - EXEC INTERFACE BLOCK
RC EQU 12 NOT USED
RD EQU 13 CICS - DYNAMIC STORAGE REGISTER
RE EQU 14 IOCS - LINKAGE
RF EQU 15 IOCS - LINKAGE
I have read that R12 to be used as Base register and R14 is not used at all. Could you please help.
Joined: 06 Jun 2008 Posts: 8578 Location: Dubuque, Iowa, USA
The address of AMERECLN is loaded into register 1, then half of it is stored in WSASCNB. The first bit of WSASCSA is turned on (presumably to set the end of the parameter list). GETMAIN is invoked (and presumably returns the memory address in WSASCSA). Register 7 is then used to establish addressability to the GETMAIN memory area.
One key thing to learn in assembler is the difference between memory address and memory content -- LA or L =A() do not load the data but rather the address in memory where the data is located.
Amit C, here's my view (essentially what Robert says with one difference)
- Load value at label AMRECLN into R1
- Store right-hand half of R1 into label WSASCNB (a record length I guess)
- Clear storage at label WSASCSA (I must disagree with Robert, this does not set hi bit on)
Then exactly as Robert says,
- Branch to a routine GETMAIN which (presumably) puts address of gotten storage into WSASCSA and returns (final instruction of GETMAIN will be BR R2)
- Load address of gotten storage into R7, which is mapped by a DSECT called VD2AMDF
Regarding register usage, yes, R12 is normally used as Base Register and R14 is normally used to hold a return address, so is important. You can use R14 as a work register if you know what you're doing, but to be safe don't touch it.
Registers 2-11 are generally user-defined i.e. use them for what you want. Looks like the program you're working on has documented how it uses registers. I'd assume the documentation is correct, so the registers are used for the purpose described.
Joined: 30 Nov 2013 Posts: 888 Location: The Universe
Base register. You can use any register you want, except register 0, as a base register. For some reason - I do not know why - many programmers (yes, me too) use register 12 as the base register for their program. Now, there are other, practical issues you must consider.
Registers 0, 1, 14 and 15 are used and destroyed by many system macros. Obviously they are probably a poor choice for use as a base register.
The common I/O macros (GET, PUT, READ, WRITE, CHECK, and others) assume register 13 points to a 72 byte data area called a register save area. Obviously, register 13 is not a good choice. This is more complex than meets the eye. For example, this is perfectly OK, though it is a poor example for other reasons.
CODE ST 13,4(,15)
It depends on the common convention that register 15 contains the address of the program when it is called. The SAVE macro is a standard IBM macro that has been around forever, though the 2015 version of the macro is much different than the 1966 version of the macro. CNOP is a standard feature of IBM assemblers. It inserts "NOP" (instructions that do nothing) until the location meets a storage alignment as specified in the instruction. 0 means byte 0 of a 4 byte alignment. BAL is a 4 byte instruction that is often used to call a subroutine; it stores the address of the next byte in storage in the "link" register, in this case register 15, before it branches. Here, register 15 will contain the address of the new register save area after the instruction completes. The DROP instruction tells the Assembler register 15 is no longer a base register. The three instructions at CODE connect the new save area with the save area provided when EXAMPLE1 was called, and then stores the new save area address in register 13.
loads the address of the save area when EXAMPLE1 was entered into register 13, and the RETURN macro - another standard IBM macro that has been around forever - restores the registers saved by the SAVE macro from the register save area and then returns to the program that called EXAMPLE1.
Now I said this is not considered good practice. Why?
At one level, you are using the register for multiple purposes: the program base register and the program's save area pointer. Currently, the idea is register 13 should just be a save area pointer.
You are mixing data storage (the save area) with the instruction stream. This has always been a bad idea, but there have been times when it is a really bad idea. This was especially true with the first generation z/Architecture systems in 2000. It impaired program performance so badly I understand some IBM customers told IBM to take their shiny new z/Architecture machines back! I always thought the real problem is the designers were computer science graduates who had the idea programs in the real world behaved the way they were taught: data and program text were isolated in storage. This is not true in System/360 type Assembler programming where the instruction stream and data often mix. A prime example is the IBM READ and WRITE macros, in their most common use, mix instructions with a small data area called a DECB. There are others, but READ and WRITE are, in my opinion, the worst offenders.