0% found this document useful (0 votes)
265 views

Assembler Language Programming For IBM Z System Servers

The basic bible regarding assembler language for IBM Z system

Uploaded by

a_houzet
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
265 views

Assembler Language Programming For IBM Z System Servers

The basic bible regarding assembler language for IBM Z system

Uploaded by

a_houzet
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 1313

Assembler Language Programming

for
IBM z System Servers
Version 1.00

John R. Ehrman

IBM Silicon Valley Lab

First Edition (January 2015)


IBM welcomes your comments. Please address them to
John Ehrman
IBM Silicon Valley Lab
555 Bailey Avenue
San Jose, CA 95141
[email protected]
Copyright IBM Corporation 2015
US Government Users Restricted Rights
Contract with IBM Corp.

ii

Use, duplication or disclosure restricted by GSA ADP Schedule

Assembler Language Programming for IBM z System Servers

Version 1.00

Contents
Figures
Tables

xxviii

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

Foreword

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
.
.
.
.
.
.
.

Outline and Overview . . . . . . . . . . . . . . . . . . .


. . . . . . . . . . . . . . .
Programming Environments
Levels of Difficulty (*) . . . . . . . . . . . . . . . . . . .
Exercises and Programming Problems . . . . . . . . . .
Some Observations . . . . . . . . . . . . . . . . . . . . .
Why Program in Assembler Language (and Why Not)?
Assembler Language Misconceptions
. . . . . . . . . .

Index

xvi

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

Chapter I: Getting Started

Chapter II: z System

. . . . . . . . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

3. Conceptual Structure of z System . . . . . . . . .


3.1. Memory Organization . . . . . . . . . . . . .
3.2. Central Processing Unit . . . . . . . . . . . .
3.3. General Registers
. . . . . . . . . . . . . . .
3.4. Floating-Point Registers
. . . . . . . . . . .
3.5. Program Status Word (PSW)
. . . . . . . .
3.6. Other Registers . . . . . . . . . . . . . . . . .
3.7. Input-Output (I/O) . . . . . . . . . . . . . .
3.8. Features, Facilities, and Assists
. . . . . . .
3.9. Microprograms and Millicode (*) . . . . . .
4. Instruction Execution
. . . . . . . . . . . . . . . .
4.1. Basic Instruction Cycle . . . . . . . . . . . .
4.2. Basic Instruction Types . . . . . . . . . . . .
4.3. Instruction Lengths . . . . . . . . . . . . . .
4.4. Some Operation Codes (*) . . . . . . . . . .
4.5. Interruptions (*) . . . . . . . . . . . . . . . .
4.6. Exceptions and Program Interruptions (*) .
4.7. Machine Language and Assembler Language
4.8. Processor Evolution . . . . . . . . . . . . . .
5. Memory Addressing . . . . . . . . . . . . . . . . .

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
. .
. .

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

1
1
2
2
2
2
5
8
11

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
. .
. .
. .

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

13
14
14
15
16
18
18
19
21
24
26
27
27
29
32
33
34
36
38
39
40

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

43
44
45
47
47
48
49
50
50
50
50
52
52
53
55
56
57
59
61
61
63

Contents

iii

. . . . . . . . . . . . . . . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

1. Some Basic Items . . . . . . . . . . . . . . . . . . . . . . . . . . . .


1.1. Notation and Terminology . . . . . . . . . . . . . . . . . . . .
1.2. Instruction Elements
. . . . . . . . . . . . . . . . . . . . . . .
1.2.1. Register Names . . . . . . . . . . . . . . . . . . . . . . . .
2. Binary and Hexadecimal Numbers . . . . . . . . . . . . . . . . . . .
2.1. Positional Notation and Binary Numbers
. . . . . . . . . . .
2.2. Hexadecimal Numbers . . . . . . . . . . . . . . . . . . . . . .
2.3. Converting Integers from One Base to Another (*) . . . . . .
2.4. Examples of General Conversions (*) . . . . . . . . . . . . . .
2.5. Number Representations . . . . . . . . . . . . . . . . . . . . .
2.6. Logical (Unsigned) Representation . . . . . . . . . . . . . . .
. . . . . . .
2.7. Twos Complement (Signed) Representation (*)
2.8. Computing Two s Complements . . . . . . . . . . . . . . . .
2.9. Sign Extension . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.10. Binary Addition
. . . . . . . . . . . . . . . . . . . . . . . . .
2.11. Binary Subtraction . . . . . . . . . . . . . . . . . . . . . . . .
2.12. How Additions and Subtractions Are Actually Performed (*)
2.13. A Circular View of Binary Arithmetic (*) . . . . . . . . . . .
2.14. Logical (Unsigned) and Arithmetic (Signed) Results (*)
. .
2.15. Examples of Representations (*) . . . . . . . . . . . . . . . .

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

5.1. The Addressing Halfword . . . . . . . . . . .


5.2. Examples of Effective Addresses . . . . . . .
5.3. Indexing . . . . . . . . . . . . . . . . . . . . .
5.4. Examples of Indexing . . . . . . . . . . . . .
5.5. Addressing Problems (*) . . . . . . . . . . .
5.6. Address Translation and Virtual Memory (*)
5.7. Summary . . . . . . . . . . . . . . . . . . . .

Chapter III: Assembler Language Programs

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

64
65
65
67
68
69
70

. . . . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

73
74
74
74
75
75
76
78
81
81
82
84
84
87
87
89
91
93
94
95
96
98
98
99
100
102
104
105
108
108
109
110
110
111
113
113
115
115
117
118
118
119
121
122
123
124
125
127
129
130
131
132
134
135

.
.
.
.
.

.
.
.
.
.
.
. .

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

6. Assembler Language . . . . . . . . . . . . . . . . . . . . . . . . . . .
6.1. Processing Your Program . . . . . . . . . . . . . . . . . . . . .
6.1.1. Assembly . . . . . . . . . . . . . . . . . . . . . . . . . . .
6.1.2. Linking . . . . . . . . . . . . . . . . . . . . . . . . . . . .
6.1.3. Loading and Execution . . . . . . . . . . . . . . . . . . .
6.2. Preparing Assembler Language Statements . . . . . . . . . . .
6.3. Statement Fields . . . . . . . . . . . . . . . . . . . . . . . . . .
6.3.1. What s in a Name Field? (*) . . . . . . . . . . . . . . . .
6.4. Writing Programs . . . . . . . . . . . . . . . . . . . . . . . . .
6.5. A Sample Program
. . . . . . . . . . . . . . . . . . . . . . . .
6.6. Basic Macro Instructions . . . . . . . . . . . . . . . . . . . . .
6.7. Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . .
7. Self-Defining Terms and Symbols
7.1. Self-Defining Terms . . . . . . . . . . . . . . . . . . . . . . . .
7.2. EBCDIC Character Representation . . . . . . . . . . . . . . .
7.3. Symbols and Attributes . . . . . . . . . . . . . . . . . . . . . .
7.4. Program Relocatability . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . .
7.5. The Location Counter
7.6. Assigning Values to Symbols . . . . . . . . . . . . . . . . . . .
7.7. Symbols and Variables . . . . . . . . . . . . . . . . . . . . . .
8. Terms, Operators, Expressions, and Operands . . . . . . . . . . . .
8.1. Terms and Operators . . . . . . . . . . . . . . . . . . . . . . .
8.2. Expressions . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.3. Evaluating Assembly-Time Expressions (*)
. . . . . . . . . .
8.4. Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.5. Machine Instruction Statement Operand Formats . . . . . . .
8.6. Details of Expression Evaluation (*)
. . . . . . . . . . . . . .
9. Instructions, Mnemonics, and Operands . . . . . . . . . . . . . . . .
9.1. Basic RR-Type Instructions . . . . . . . . . . . . . . . . . . .
9.2. Writing RR-Type Instructions . . . . . . . . . . . . . . . . . .
9.3. Basic RX-Type Instructions . . . . . . . . . . . . . . . . . . .
9.4. Writing RX-Type Instructions . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . .
9.5. Explicit and Implied Addresses
9.6. Typical RS- and SI-Type Instructions
. . . . . . . . . . . . .
9.7. Writing RS- and SI-Type Instructions
. . . . . . . . . . . . .
9.8. Typical SS-Type Instructions
. . . . . . . . . . . . . . . . . .
9.9. Writing SS-Type Instructions
. . . . . . . . . . . . . . . . . .
9.10. Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
10. Establishing and Maintaining Addressability . . . . . . . . . . . . .
10.1. The BASR Instruction
. . . . . . . . . . . . . . . . . . . . .
10.2. Computing Displacements
. . . . . . . . . . . . . . . . . . .
10.3. Explicit Base and Displacement
. . . . . . . . . . . . . . . .
10.4. The USING Assembler Instruction and Implied Addresses .
10.5. Location Counter Reference . . . . . . . . . . . . . . . . . .
10.6. Destroying Base Registers . . . . . . . . . . . . . . . . . . . .
10.7. Calculating Displacements: the Assembly Process, Pass One
10.8. Calculating Displacements: the Assembly Process, Pass Two
10.9. Multiple USING Table Entries . . . . . . . . . . . . . . . . .
10.10. The DROP Assembler Instruction . . . . . . . . . . . . . .
10.11. Addressability Errors . . . . . . . . . . . . . . . . . . . . . .
10.12. Resolutions With Register Zero (*) . . . . . . . . . . . . . .
10.13. Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
10.13.1. How the Assembler Helps . . . . . . . . . . . . . . . .

iv

Assembler Language Programming for IBM z System Servers

Version 1.00

.
.
.
.
.
.

Chapter IV: Defining Constants and Storage Areas

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

137
138
139
140
140
141
142
143
144
145
145
145
146
148
148
149
151
152
154
156
158
159
161
161
162
164
168
169
171
173
175
176

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

179
180
181
182
184
186
187
189
192
194
195
196
197
198
198
199
199
199
200
201
206
206
207
208
208
208
209
212
214

. . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

11. Defining Constants . . . . . . . . . . . . . . . . . . . . .


11.1. Defining Constants . . . . . . . . . . . . . . . . . .
11.2. DC Instruction Statements and Operands . . . . .
11.2.1. Blanks in Nominal Values . . . . . . . . . . .
11.3. Boundary Alignment . . . . . . . . . . . . . . . . .
11.4. Length Modifiers . . . . . . . . . . . . . . . . . . .
11.5. Duplication Factors and Multiple Operands . . .
11.6. Multiple Nominal Values . . . . . . . . . . . . . .
11.7. Length Attributes . . . . . . . . . . . . . . . . . . .
11.8. Decimal Exponents (*)
. . . . . . . . . . . . . . .
11.8.1. Decimal Exponents . . . . . . . . . . . . . . .
11.8.2. Exponent Modifiers
. . . . . . . . . . . . . .
12. Basic Constants . . . . . . . . . . . . . . . . . . . . . . .
12.1. F-Type and H-Type Constants . . . . . . . . . . .
12.2. A-Type Address Constants . . . . . . . . . . . . .
12.3. Y-Type Address Constants . . . . . . . . . . . . .
12.4. Constants of Types C, B, and X . . . . . . . . . .
12.5. Padding and Truncation . . . . . . . . . . . . . . .
12.6. Literals . . . . . . . . . . . . . . . . . . . . . . . . .
12.7. The LTORG Assembler Instruction . . . . . . . .
12.8. Type Extensions . . . . . . . . . . . . . . . . . . .
13. Data Storage Definition
. . . . . . . . . . . . . . . . . .
13.1. Storage Areas: The DS Assembler Instruction . .
13.2. Zero Duplication Factor . . . . . . . . . . . . . . .
13.3. The EQU Assembler Instruction . . . . . . . . . .
13.4. EQU Instruction Extended Syntax (*) . . . . . . .
13.5. The ORG Assembler Instruction . . . . . . . . . .
13.6. Parameterization . . . . . . . . . . . . . . . . . . .
13.7. Constants Depending on the Location Counter .
13.8. Assembly Time and Execution Time, Revisited (*)
13.9. Summary Observations . . . . . . . . . . . . . . .

Chapter V: Basic Instructions

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
. .

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

14. General Register Data Transmission . . . . . . . . . . . . . . . . . . . . . .


14.1. Load and Store Instructions
. . . . . . . . . . . . . . . . . . . . . . .
14.2. Multiple Loads and Stores
. . . . . . . . . . . . . . . . . . . . . . . .
14.3. Halfword Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . .
14.4. Insert and Store Character
14.5. ICM and STCM Instructions . . . . . . . . . . . . . . . . . . . . . . .
14.6. RR-Type Data Transmission Instructions
. . . . . . . . . . . . . . .
14.7. Load, Store, and Insert for 64-bit General Registers . . . . . . . . . .
14.8. RR-Type Data Transmission Instructions for 64-bit General Registers
14.9. The Load and Test Instructions . . . . . . . . . . . . . . . . . . . . .
14.10. Mixed 32- and 64-bit Operands . . . . . . . . . . . . . . . . . . . . .
14.11. Other General Register Load Instructions (*) . . . . . . . . . . . . .
14.11.1. Load Byte Instructions . . . . . . . . . . . . . . . . . . . . . . .
14.11.2. Load Logical Character Instructions . . . . . . . . . . . . . . .
14.11.3. Load Logical Halfword Instructions
. . . . . . . . . . . . . . .
14.11.4. Load Logical (Word) Instructions . . . . . . . . . . . . . . . . .
14.11.5. Load Logical Thirty One Bit Instructions . . . . . . . . . . . .
14.12. Misunderstandings to Avoid . . . . . . . . . . . . . . . . . . . . . . .
14.13. Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
15. Testing the Condition Code: Conditional Branching . . . . . . . . . . . . .
15.1. The Branch Address . . . . . . . . . . . . . . . . . . . . . . . . . . . .
15.2. The Branch Mask and Branch Condition . . . . . . . . . . . . . . . .
15.3. Examples of Conditional Branch Instructions
. . . . . . . . . . . . .
15.4. No-Operation Instructions
. . . . . . . . . . . . . . . . . . . . . . . .
15.4.1. Special No-Operation Instructions (*) . . . . . . . . . . . . . . .
15.5. Conditional No-Operation
. . . . . . . . . . . . . . . . . . . . . . . .
15.6. Extended Mnemonics . . . . . . . . . . . . . . . . . . . . . . . . . . .
15.7. A Comment on Programming Style . . . . . . . . . . . . . . . . . . .

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

Contents

16.

17.

18.

19.

15.8. A Design Oversight and a Modern Correction (*) .


15.9. Summary . . . . . . . . . . . . . . . . . . . . . . . . .
Fixed-Point Binary Addition, Subtraction, and Comparison
16.1. Signed-Arithmetic Add and Subtract Instructions . .
16.2. Signed-Arithmetic Operations Using 32-Bit Registers
16.3. Signed-Arithmetic Operations Using 64-Bit Registers
16.4. Signed-Arithmetic Compare Instructions . . . . . . .
16.5. Logical-Arithmetic Add and Subtract Instructions . .
16.6. Add With Carry, Subtract With Borrow (*)
. . . . .
16.7. Operations With Mixed 64-Bit and 32-Bit Operands
16.8. Logical-Arithmetic Compare Instructions . . . . . . .
16.9. Retrieving and Setting the Program Mask (*)
. . . .
16.10. Summary . . . . . . . . . . . . . . . . . . . . . . . . .
Binary Shifting . . . . . . . . . . . . . . . . . . . . . . . . . .
17.1. Unit Shifts . . . . . . . . . . . . . . . . . . . . . . . . .
17.2. Single-Length Logical Shifts
. . . . . . . . . . . . . .
17.2.1. Three-Operand Shift Instructions . . . . . . . . .
17.3. Double-Length Logical Shifts . . . . . . . . . . . . . .
17.4. Arithmetic Shift Instructions . . . . . . . . . . . . . .
17.5. Rotating Shifts . . . . . . . . . . . . . . . . . . . . . .
17.6. Calculated Shift Amounts . . . . . . . . . . . . . . . .
17.7. Bit-Length Constants (*) . . . . . . . . . . . . . . . .
17.8. Summary . . . . . . . . . . . . . . . . . . . . . . . . .
Binary Multiplication and Division . . . . . . . . . . . . . .
18.1. Overview of Multiplication Instructions . . . . . . . .
18.2. Arithmetic (Signed) Multiplication Instructions
. . .
18.2.1. Double-Length Arithmetic Products . . . . . . .
18.2.2. Single-Length Arithmetic Products . . . . . . . .
18.3. Logical (Unsigned) Multiplication Instructions . . . .
18.4. How Multiplication Is Done (*) . . . . . . . . . . . .
18.5. Division Instructions . . . . . . . . . . . . . . . . . . .
18.6. Arithmetic (Signed) Division Instructions . . . . . . .
18.6.1. Double-Length Division . . . . . . . . . . . . . .
18.6.2. Single-Length Division . . . . . . . . . . . . . . .
18.7. Logical (Unsigned) Division Instructions . . . . . . .
18.8. How Division Is Done (*)
. . . . . . . . . . . . . . .
18.9. Summary . . . . . . . . . . . . . . . . . . . . . . . . .
Logical Operations
. . . . . . . . . . . . . . . . . . . . . . .
19.1. Logical Operations . . . . . . . . . . . . . . . . . . . .
19.2. Register-Based Logical Instructions . . . . . . . . . .
19.3. Logical AND . . . . . . . . . . . . . . . . . . . . . . .
19.4. Logical OR . . . . . . . . . . . . . . . . . . . . . . . .
19.5. Logical Exclusive OR . . . . . . . . . . . . . . . . . .
19.6. Interesting Uses of Logical Instructions (*) . . . . . .
19.7. Summary . . . . . . . . . . . . . . . . . . . . . . . . .

Chapter VI: Addressing, Immediate Operands, and Loops

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

214
215
218
218
219
222
223
225
229
231
233
235
236
242
243
245
247
248
252
257
258
259
261
264
264
265
265
267
270
272
274
275
275
278
279
280
283
288
289
289
290
291
292
295
298

. . . . . . .
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

301
302
302
302
302
304
306
309
314
314
317
319
319
319
322
322

. . .
. . .
. .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

20. Address Generation and Addressing Modes . . . . . . . . . . . . .


20.1. Address Generation
. . . . . . . . . . . . . . . . . . . . . . .
20.1.1. Address Generation With 12-Bit Displacements . . . .
20.1.2. Address Generation With 20-Bit Displacements . . . .
20.1.3. Address Generation With Relative-Immediate Operands
20.2. Addressing Modes . . . . . . . . . . . . . . . . . . . . . . . .
20.3. Load Address Instructions
. . . . . . . . . . . . . . . . . . .
20.4. 64-Bit Virtual Addresses . . . . . . . . . . . . . . . . . . . . .
20.5. Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
21. Immediate Operands . . . . . . . . . . . . . . . . . . . . . . . . . .
21.1. Insert and Load Instructions with Immediate Operands . . .
21.1.1. Logical-Immediate Insert Instructions . . . . . . . . . .
21.1.2. Arithmetic- and Logical-Immediate Load Instructions .
21.2. Arithmetic Instructions with Immediate Operands . . . . . .
21.2.1. Arithmetic-Immediate Add and Subtract Instructions .

vi

Assembler Language Programming for IBM z System Servers

Version 1.00

.
.
.
.
.
.
.
.
.
.

21.2.2. Arithmetic-Immediate Compare Instructions


21.2.3. Arithmetic-Immediate Multiply Instructions
21.3. Logical Operations with Immediate Operands .
21.3.1. Logical-Immediate AND Instructions . . .
21.3.2. Logical-Immediate OR Instructions . . . .
21.3.3. Logical-Immediate XOR Instructions . . .
21.4. Summary . . . . . . . . . . . . . . . . . . . . . .
22. Branches, Loops, and Indexing . . . . . . . . . . . . .
22.1. Branch Relative on Condition Instructions . . .
22.2. A Simple Example of a Loop . . . . . . . . . . .
22.3. Simple Tables and Array Indexing . . . . . . . .
22.4. Branch on Count Instructions . . . . . . . . . .
. . . . . . . . . . . . . . . .
22.5. Looping in General
22.6. Branch on Index Instructions . . . . . . . . . . .
22.7. Examples Using BXLE . . . . . . . . . . . . . .
22.8. Examples Using BXH . . . . . . . . . . . . . . .
22.9. Specialized Uses of BXH and BXLE (*) . . . .
22.10. Summary . . . . . . . . . . . . . . . . . . . . . .

Chapter VII: Bit and Character Data

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

323
323
324
324
324
325
326
330
330
333
334
335
340
342
344
347
348
350

. . . . . . . . . . . . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

353
354
354
355
355
356
358
360
361
363
364
365
367
367
369
370
372
373
374
374
375
376
378
379
380
384
385
388
390
391
392
393
394
397
404
404
406
408
411
412
414
415
416

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

23. Bit Data and Instructions


. . . . . . . . . . . . . . . . . . . . . . . . . . .
23.1. SI-Type Instructions . . . . . . . . . . . . . . . . . . . . . . . . . . .
23.2. MVI Instructions . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
23.3. NI, OI, and XI Instructions . . . . . . . . . . . . . . . . . . . . . . .
23.4. CLI Instructions . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
23.5. Test Under Mask Instructions . . . . . . . . . . . . . . . . . . . . .
23.6. Bit Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
23.7. Bit-Naming Problems (*) . . . . . . . . . . . . . . . . . . . . . . . .
23.8. A Conversion Example . . . . . . . . . . . . . . . . . . . . . . . . .
23.9. Instruction Modification (*)
. . . . . . . . . . . . . . . . . . . . . .
23.10. Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
24. Character Data and Basic Instructions . . . . . . . . . . . . . . . . . . . .
24.1. Basic SS-Type Instructions . . . . . . . . . . . . . . . . . . . . . . .
24.2. Operand Specifications . . . . . . . . . . . . . . . . . . . . . . . . . .
24.3. Implied Lengths
. . . . . . . . . . . . . . . . . . . . . . . . . . . . .
24.4. Symbol Length Attribute References
. . . . . . . . . . . . . . . . .
24.5. The Encoded Length L (*) . . . . . . . . . . . . . . . . . . . . . .
24.6. The MVC and MVCIN Instructions
. . . . . . . . . . . . . . . . .
24.6.1. MVC: Move Characters . . . . . . . . . . . . . . . . . . . . . .
24.6.2. MVCIN: Move Characters Inverse . . . . . . . . . . . . . . . .
24.6.3. MVCOS: Move Characters With Optional Specifications . . .
. . . . . . . . . . . . . . . . . .
24.7. The NC, OC, and XC Instructions
24.8. The CLC Instruction
. . . . . . . . . . . . . . . . . . . . . . . . . .
24.9. The TR Instruction . . . . . . . . . . . . . . . . . . . . . . . . . . .
24.10. The TRT and TRTR Instructions . . . . . . . . . . . . . . . . . .
24.10.1. T R T
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
24.10.2. T R T R
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
24.11. The Execute Instructions . . . . . . . . . . . . . . . . . . . . . . . .
24.11.1. Execute Instruction Without Target-Instruction Modification
24.11.2. Execute Instruction with Target-Instruction Modification . .
24.11.3. Comments on the Execute Instructions (*) . . . . . . . . . .
24.11.4. Modifiable Parts of Instructions . . . . . . . . . . . . . . . . .
24.12. Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
25. Character Data and Extended Instructions . . . . . . . . . . . . . . . . . .
25.1. Move Long and Compare Logical Long
. . . . . . . . . . . . . . .
25.1.1. MVCL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
25.1.2. CLCL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
25.2. Move Long and Compare Logical Long Extended
. . . . . . . . .
25.2.1. MVCLE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
25.2.2. CLCLE
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
25.3. Special String-Handling Instructions . . . . . . . . . . . . . . . . . .
25.4. Search String Instruction
. . . . . . . . . . . . . . . . . . . . . . . .

Contents

vii

25.5. Move String Instruction . . . . . . . . . . . . . . . . . . . .


25.6. Compare Logical String Instruction . . . . . . . . . . . . .
25.7. Translate Extended Instruction . . . . . . . . . . . . . . . .
25.8. Compare Until Substring Equal Instruction (*)
. . . . . .
25.9. Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . .
26. Other Types of Character Data (*) . . . . . . . . . . . . . . . . .
26.1. Character Representations . . . . . . . . . . . . . . . . . . .
26.1.1. BCD characters . . . . . . . . . . . . . . . . . . . . . .
26.2. EBCDIC Representations and Code Pages . . . . . . . . .
26.3. ASCII . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
26.4. Double-Byte EBCDIC Data (*) . . . . . . . . . . . . . . .
26.4.1. The DBCS Option (*) . . . . . . . . . . . . . . . . . .
26.4.2. G-Type DBCS Constants and Self-Defining Terms (*)
26.4.3. Continuation Rules for DBCS Data (*) . . . . . . . .
26.5. Unicode . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
26.5.1. The Unicode Representation . . . . . . . . . . . . . .
26.5.2. Glyphs and Characters . . . . . . . . . . . . . . . . . .
26.5.3. Unicode Character Constants . . . . . . . . . . . . . .
26.6. Unicode Instructions . . . . . . . . . . . . . . . . . . . . . .
26.6.1. String Search, Compare, and Move
. . . . . . . . . .
26.6.3. Optional Operands . . . . . . . . . . . . . . . . . . . .
26.6.4. Translation
. . . . . . . . . . . . . . . . . . . . . . . .
26.6.5. Conversion Among Transformation Formats . . . . .
26.7. Byte Reversal and Workstation Data
. . . . . . . . . . . .
26.7.1. Byte-Reversing Instructions . . . . . . . . . . . . . . .
26.8. Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . .

Chapter VIII: Zoned and Packed Decimal Data and Operations


27. Zoned and Packed Decimal Representations
. . . . . . . . .
27.1. Zoned Decimal Representation . . . . . . . . . . . . . .
27.1.1. Why Zoned Decimal Is The Way It Is (*)
. . . .
27.2. Zoned Decimal Constants . . . . . . . . . . . . . . . . .
27.3. Packed Decimal Representation . . . . . . . . . . . . .
27.4. Packed Decimal Constants . . . . . . . . . . . . . . . .
27.4.1. Scale Attributes and Packed Decimal Constants (*)
27.5. Converting Between Packed and Zoned . . . . . . . . .
27.6. The PACK Instruction . . . . . . . . . . . . . . . . . .
27.7. The UNPK Instruction . . . . . . . . . . . . . . . . . .
27.8. Packing and Unpacking ASCII and Unicode Data (*)
27.8.1. Packing ASCII and Unicode Data . . . . . . . . .
27.8.2. Unpacking ASCII and Unicode Data . . . . . . .
27.9. Printing Hexadecimal Values . . . . . . . . . . . . . . .
27.10. Summary . . . . . . . . . . . . . . . . . . . . . . . . . .
28. Packed Decimal Arithmetic
. . . . . . . . . . . . . . . . . . .
28.1. General Rules . . . . . . . . . . . . . . . . . . . . . . . .
28.1.1. Precision and Accuracy
. . . . . . . . . . . . . . .
28.2. Decimal Addition and Subtraction . . . . . . . . . . . .
28.3. Decimal Comparison
. . . . . . . . . . . . . . . . . . .
28.4. Decimal Multiplication
. . . . . . . . . . . . . . . . . .
28.5. Decimal Division . . . . . . . . . . . . . . . . . . . . . .
28.6. True Decimal Addition (*) . . . . . . . . . . . . . . . .
28.7. Complement Decimal Addition (*)
. . . . . . . . . . .
29. Packed Decimal Instructions . . . . . . . . . . . . . . . . . . .
29.1. TP Instruction . . . . . . . . . . . . . . . . . . . . . . .
29.2. ZAP Instruction . . . . . . . . . . . . . . . . . . . . . .
29.3. AP and SP Instructions . . . . . . . . . . . . . . . . . .
29.4. CP Instruction . . . . . . . . . . . . . . . . . . . . . . .
29.5. MP Instruction . . . . . . . . . . . . . . . . . . . . . . .
29.6. DP Instruction . . . . . . . . . . . . . . . . . . . . . . .
29.7. SRP Instruction
. . . . . . . . . . . . . . . . . . . . . .
29.7.1. Biased and Unbiased Rounding with SRP
. . . .
29.8. MVO Instruction . . . . . . . . . . . . . . . . . . . . . .

viii

Assembler Language Programming for IBM z System Servers

Version 1.00

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

418
420
422
424
426
429
429
429
430
432
433
435
435
436
437
437
438
439
440
440
442
443
445
448
449
451

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

453
454
454
457
458
459
461
461
463
465
468
471
472
473
475
476
477
477
478
478
480
481
483
484
486
489
490
491
493
496
497
500
502
504
507

.
.
.
.
.
.
.
.
.
.
.
.

29.9. Decimal Shifting Using MVO (*)


. . . . . . . . . . . . .
29.9.1. Shift Right an Odd Number of Digits . . . . . . . .
29.9.2. Shift Left an Odd Number of Digits . . . . . . . . .
29.9.3. Shifting an Even Number of Digits . . . . . . . . . .
29.9.4. Shifting Left an Even Number of Digits . . . . . . .
29.9.5. Shifting Right an Even Number of Digits . . . . . .
29.10. Scaled Packed Decimal Computations: General Rules .
29.10.1. Precision and Scale . . . . . . . . . . . . . . . . . .
29.10.2. General Rules: Addition and Subtraction
. . . . .
29.10.3. General Rules: Multiplication . . . . . . . . . . . .
29.10.4. General Rules: Division (*) . . . . . . . . . . . . .
29.10.5. COBOL and PL/I Notations (*) . . . . . . . . . .
29.11. Example of a Packed Decimal Business Computation
29.11.1. The Wholesalers Calculation . . . . . . . . . . . .
29.11.2. The Retailers Calculation . . . . . . . . . . . . . .
29.11.3. Comments . . . . . . . . . . . . . . . . . . . . . . .
29.11.4. Using Integer and Scale Attributes (*) . . . . . . .
29.12. Summary . . . . . . . . . . . . . . . . . . . . . . . . . . .
30. Converting and Formatting Packed Decimal Data . . . . . . .
30.1. CVD, CVDY, and CVDG Instructions . . . . . . . . . .
30.2. CVB, CVBY, and CVBG Instructions
. . . . . . . . . .
30.3. Editing Overview . . . . . . . . . . . . . . . . . . . . . . .
30.4. Simple Examples of Editing . . . . . . . . . . . . . . . . .
30.5. Single-Field Editing
. . . . . . . . . . . . . . . . . . . . .
30.5.1. Editing Negative Values . . . . . . . . . . . . . . . .
30.5.2. Protecting High-Order Fields . . . . . . . . . . . . .
30.6. The EDMK Instruction . . . . . . . . . . . . . . . . . . .
30.7. Editing Multiple Fields (*) . . . . . . . . . . . . . . . . .
30.8. Summary Comments on Editing (*) . . . . . . . . . . . .

Chapter IX: Floating-Point Data and Operations

. . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.

. . . . . . . . . . . .
31. Floating-Point Number Representation
31.1. Scaled Fixed-Point Arithmetic . . . . . . . . . . . . . .
31.2. Converting Fractions . . . . . . . . . . . . . . . . . . . .
31.3. Mixed Integer-Fraction Representation . . . . . . . . .
31.3.1. Scaled Fixed-Point Binary Arithmetic (*) . . . . .
31.3.2. Scaled Fixed-Point Binary Constants (*) . . . . .
31.4. Why Use Floating-Point Numbers? . . . . . . . . . . .
31.4.1. Precision and Accuracy
. . . . . . . . . . . . . . .
31.5. Floating-Point Representations . . . . . . . . . . . . . .
31.5.1. Some Additional Details (*) . . . . . . . . . . . . .
31.6. z System Floating-Point Representations . . . . . . . .
31.7. z System Floating-Point Registers . . . . . . . . . . . .
31.8. Floating-Point Constants . . . . . . . . . . . . . . . . .
31.9. Representation-Independent Floating-Point Instructions
31.9.1. Register-Storage Instructions . . . . . . . . . . . .
31.9.2. Register-Register Instructions . . . . . . . . . . . .
31.9.3. Load-Zero Instructions
. . . . . . . . . . . . . . .
31.9.4. GPR-FPR Copying Instructions . . . . . . . . . .
31.9.5. Sign-Copying Instruction . . . . . . . . . . . . . .
31.10. Summary . . . . . . . . . . . . . . . . . . . . . . . . . .
32. Basic Concepts of Floating-Point Arithmetic . . . . . . . . .
32.1. Floating-Point Multiplication . . . . . . . . . . . . . . .
32.2. Pre-Normalization of Fraction Operands . . . . . . . .
32.3. Floating-Point Rounding . . . . . . . . . . . . . . . . .
32.4. Guard and Rounding Digits (*)
. . . . . . . . . . . . .
32.5. Integer-Based Representations (*) . . . . . . . . . . . .
32.6. Floating-Point Division . . . . . . . . . . . . . . . . . .
32.7. Floating-Point Addition and Subtraction . . . . . . . .
32.8. Floating-Point Precision . . . . . . . . . . . . . . . . . .
32.9. Floating-Point Range . . . . . . . . . . . . . . . . . . .
32.10. Exponents and Characteristics . . . . . . . . . . . . . .

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

509
509
510
510
511
511
513
513
514
514
515
516
517
517
518
520
520
521
522
522
524
526
528
531
531
532
533
534
535

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

539
540
540
541
543
544
545
547
547
548
550
551
551
554
555
555
555
556
557
557
558
560
560
561
561
562
564
564
565
567
569
571

.
.
.
.
.
.
.
.
.
.
.
.

Contents

ix

32.11. Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
33. Hexadecimal Floating-Point Data and Operations . . . . . . . . . . . . . . . . . .
33.1. Hexadecimal Floating-Point Data . . . . . . . . . . . . . . . . . . . . . . . .
33.2. Writing Hexadecimal Floating-Point Constants
. . . . . . . . . . . . . . . .
33.2.1. Decimal Exponents . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
33.3. Modifiers
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
33.3.1. Length Modifiers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
33.3.2. Scale Modifiers (*) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
33.3.3. Exponent Modifiers
. . . . . . . . . . . . . . . . . . . . . . . . . . . . .
33.4. Subtypes Q and H (*) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
33.4.1. LQ-Type Constants . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
33.4.2. Subtype H . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
33.4.3. Difficult Numbers (*) . . . . . . . . . . . . . . . . . . . . . . . . . . . .
33.5. Basic Hexadecimal Floating-Point Instructions . . . . . . . . . . . . . . . . .
33.6. Hexadecimal Floating-Point RR-Type Data-Movement Instructions . . . .
33.7. Hexadecimal Floating-Point Multiplication . . . . . . . . . . . . . . . . . . .
33.7.1. Exponent Overflow and Underflow. . . . . . . . . . . . . . . . . . . . .
33.8. Hexadecimal Floating-Point Division . . . . . . . . . . . . . . . . . . . . . .
33.8.1. The Halve Instructions (*)
. . . . . . . . . . . . . . . . . . . . . . . . .
33.9. Hexadecimal Floating-Point Addition and Subtraction . . . . . . . . . . . .
33.9.1. Unnormalized Addition and Subtraction
. . . . . . . . . . . . . . . . .
33.9.2. Older Uses of Unnormalized Addition (*) . . . . . . . . . . . . . . . . .
33.10. Adding Operands of Like Sign (*) . . . . . . . . . . . . . . . . . . . . . . .
33.11. Adding Operands of Unlike Sign (*) . . . . . . . . . . . . . . . . . . . . . .
33.11.1. Hexadecimal Floating-Point Complement Addition (*) . . . . . . . .
33.11.2. Implementing Hexadecimal Floating-Point Complement Addition (*)
33.12. Hexadecimal Floating-Point Comparison . . . . . . . . . . . . . . . . . . .
33.13. Rounding and Lengthening Instructions . . . . . . . . . . . . . . . . . . . .
33.13.1. Rounding Instructions . . . . . . . . . . . . . . . . . . . . . . . . . . .
33.13.2. Lengthening Instructions . . . . . . . . . . . . . . . . . . . . . . . . . .
33.14. Converting Between Binary Integers and HFP . . . . . . . . . . . . . . . .
33.14.1. Converting Binary Integers to Hexadecimal Floating-Point . . . . . .
33.14.2. Converting Hexadecimal Floating-Point to Binary Integers . . . . . .
33.15. Hexadecimal Floating-Point Integers and Remainders (*) . . . . . . . . . .
33.16. Square Root Instructions (*) . . . . . . . . . . . . . . . . . . . . . . . . . .
33.17. Multiply and Add/Subtract Instructions (*) . . . . . . . . . . . . . . . . . .
33.18. Some Hexadecimal Floating-Point History (*) . . . . . . . . . . . . . . . .
33.18.1. Zeroing Floating-Point Registers . . . . . . . . . . . . . . . . . . . . .
33.18.2. Hexadecimal Floating-Point to Binary Conversion Comments (*) . .
33.18.3. Initial System/360 Oversights . . . . . . . . . . . . . . . . . . . . . . .
33.19. Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
34. Binary Floating-Point Data and Operations . . . . . . . . . . . . . . . . . . . . . .
34.1. Binary Floating-Point Data . . . . . . . . . . . . . . . . . . . . . . . . . . . .
34.1.1. Data Representations
. . . . . . . . . . . . . . . . . . . . . . . . . . . .
34.1.2. Normal Numbers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
34.1.3. Special Values . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
34.1.4. Range of the Representation . . . . . . . . . . . . . . . . . . . . . . . .
34.2. Writing Binary Floating-Point Constants . . . . . . . . . . . . . . . . . . . .
34.2.1. Decimal Exponents and Exponent Modifiers . . . . . . . . . . . . . . .
34.2.2. Length Modifiers (*) . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
34.3. Binary Floating-Point Arithmetic in General . . . . . . . . . . . . . . . . . .
34.3.1. Rounding Modes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
34.3.2. Denormalized Numbers . . . . . . . . . . . . . . . . . . . . . . . . . . .
34.3.3. Arithmetic with Zero, Infinity, and NaNs . . . . . . . . . . . . . . . . .
34.4. Binary Floating-Point Exceptions, Interruptions, and Controls
. . . . . . .
34.4.1. Binary Floating-Point Exceptions (*) . . . . . . . . . . . . . . . . . . .
34.4.2. FPC Register Instructions (*) . . . . . . . . . . . . . . . . . . . . . . . .
34.4.3. Exception Actions (*) . . . . . . . . . . . . . . . . . . . . . . . . . . . .
34.4.4. Scaled Exponents (*) . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
34.5. Basic Binary Floating-Point Instructions . . . . . . . . . . . . . . . . . . . .
34.6. Binary Floating-Point RR-Type Data Movement Instructions . . . . . . . .
34.7. Binary Floating-Point Multiplication . . . . . . . . . . . . . . . . . . . . . .

Assembler Language Programming for IBM z System Servers

Version 1.00

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

572
573
573
577
578
579
579
579
580
581
581
582
583
584
584
586
589
590
591
592
595
596
598
599
599
601
602
603
603
605
606
607
608
611
613
614
616
616
616
616
617
625
625
626
627
627
628
629
631
632
633
633
634
635
635
636
637
638
639
640
642
644

34.8. Binary Floating-Point Division . . . . . . . . . . . . . . . . . . . . . . . . .


34.9. Binary Floating-Point Addition and Subtraction . . . . . . . . . . . . . . .
34.10. Binary Floating-Point Comparison . . . . . . . . . . . . . . . . . . . . . .
34.10.1. Compare and Signal (*)
. . . . . . . . . . . . . . . . . . . . . . . . .
34.11. Binary Floating-Point Rounding and Lengthening Instructions (*)
. . .
34.11.1. Rounding Instructions (*) . . . . . . . . . . . . . . . . . . . . . . . .
34.11.2. Lengthening Instructions (*) . . . . . . . . . . . . . . . . . . . . . . .
34.12. Converting Between BFP and Binary Integers (*) . . . . . . . . . . . . .
34.12.1. Converting Binary Integers to Binary Floating-Point (*) . . . . . . .
34.12.2. Converting Binary Floating-Point to Binary Integers (*) . . . . . . .
34.13. Binary Floating-Point Integers and Remainders (*)
. . . . . . . . . . . .
34.13.1. Load FP Integer Instructions . . . . . . . . . . . . . . . . . . . . . .
34.13.2. Divide to Integer Instructions (*) . . . . . . . . . . . . . . . . . . . .
34.14. Binary Floating-Point Square Root Instructions (*) . . . . . . . . . . . .
34.15. Binary Floating-Point Multiply and Add/Subtract (*) . . . . . . . . . . .
34.16. Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
35. Decimal Floating-Point Data and Operations . . . . . . . . . . . . . . . . . . . .
35.1. Representations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
35.1.1. Conceptual View of the Decimal Floating-Point Representation . . .
35.2. z System Decimal Floating-Point Data Encoding and Representation (*)
35.2.1. Decimal Floating-Point Data Encoding (*) . . . . . . . . . . . . . . .
35.2.2. Decimal Floating-Point Data Representation (*) . . . . . . . . . . . .
35.2.3. Decimal Floating-Point Combination Field (*) . . . . . . . . . . . . .
35.3. Decimal Floating-Point Constants . . . . . . . . . . . . . . . . . . . . . . .
35.3.1. Rounding-Mode Suffixes for Decimal Floating-Point Constants . . .
35.3.2. Decimal Exponents and Modifiers . . . . . . . . . . . . . . . . . . . .
35.4. Decimal Floating-Point Data Classes (*) . . . . . . . . . . . . . . . . . . .
35.5. Decimal Floating-Point Operations: Rounding, Quanta, and Exceptions .
35.5.1. Rounding . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
35.5.2. Preferred Exponent and Quantum . . . . . . . . . . . . . . . . . . . .
35.5.3. DFP Exceptions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
35.4.4. Overflow/Underflow Scale Factors (*) . . . . . . . . . . . . . . . . . .
35.6. Decimal Floating-Point Data Movement Instructions . . . . . . . . . . . .
35.6.1. Copy Sign . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . .
35.6.2. Copy between General and Floating-Point Registers
35.6.3. Copy Among Floating-Point Registers
. . . . . . . . . . . . . . . . .
35.7. Decimal Floating-Point Arithmetic Instructions . . . . . . . . . . . . . . .
35.7.1. Multiplication . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
35.7.2. Division . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
35.7.3. Addition and Subtraction . . . . . . . . . . . . . . . . . . . . . . . . .
35.8. Decimal Floating-Point Compare Instructions . . . . . . . . . . . . . . . .
35.8.1. Compare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
35.8.2. Compare and Signal . . . . . . . . . . . . . . . . . . . . . . . . . . . .
35.8.3. Compare Biased Exponent . . . . . . . . . . . . . . . . . . . . . . . .
35.9. Converting Decimal Floating-Point To and From Fixed Binary . . . . . .
35.9.1. Convert From Fixed Binary to DFP . . . . . . . . . . . . . . . . . . .
35.9.2. Convert From DFP To Fixed Binary . . . . . . . . . . . . . . . . . .
35.10. Converting Decimal Floating-Point To/From Packed and Zoned Decimal
35.10.1. Convert To/From Signed Packed Decimal . . . . . . . . . . . . . . .
35.10.2. Convert To/From Unsigned Packed Decimal . . . . . . . . . . . . .
35.10.3. Convert To/From Zoned Decimal . . . . . . . . . . . . . . . . . . .
35.11. Decimal Floating-Point Load Operations . . . . . . . . . . . . . . . . . .
35.11.1. Load and Test, Complement, Negative, and Positive . . . . . . . . .
35.11.2. Load Floating-Point Integer . . . . . . . . . . . . . . . . . . . . . . .
35.11.3. Load Lengthened . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
35.11.4. Load Rounded
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
35.12. Decimal Floating-Point Miscellaneous Operations (*) . . . . . . . . . . .
35.12.1. Set Decimal Rounding Mode . . . . . . . . . . . . . . . . . . . . . .
35.12.2. Extract and Insert Biased Exponent
. . . . . . . . . . . . . . . . . .
35.12.3. Extract Significance . . . . . . . . . . . . . . . . . . . . . . . . . . . .
35.12.4. Shift Significand Left/Right . . . . . . . . . . . . . . . . . . . . . . .
35.12.5. Quantize . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

Contents

646
648
649
650
651
651
651
653
653
653
655
655
656
658
659
660
667
668
669
671
671
673
674
676
677
678
679
681
681
682
684
685
686
686
686
686
687
688
689
689
691
691
692
692
693
693
694
696
696
697
698
701
701
702
702
703
704
704
705
706
707
708

xi

35.12.6. Reround . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
35.12.7. Decimal Floating-Point Data Groups (*)
. . . . . . . . . . . . .
35.13. Example of a Decimal Floating-Point Business Computation . . .
35.13.1. The Wholesalers Calculation . . . . . . . . . . . . . . . . . . . .
35.13.2. The Retailers Calculation . . . . . . . . . . . . . . . . . . . . . .
35.13.3. Comparing Packed and Floating Decimal . . . . . . . . . . . . .
35.14. Decimal Floating-Point Binary-Significand Format (*)
. . . . . . . .
35.15. Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
36. Floating-Point Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
36.1. Floating-Point Data Representations
. . . . . . . . . . . . . . . . . . .
36.2. Floating-Point Properties . . . . . . . . . . . . . . . . . . . . . . . . . .
36.3. Floating-Point Exceptions . . . . . . . . . . . . . . . . . . . . . . . . . .
36.4. Defining Floating-Point Constants . . . . . . . . . . . . . . . . . . . . .
36.5. Converting Among Decimal, Hexadecimal and Binary Representations
36.5.1. In-Out Conversions
. . . . . . . . . . . . . . . . . . . . . . . . . .
36.5.2. Out-In Conversions
. . . . . . . . . . . . . . . . . . . . . . . . . .
36.5.3. The PFPO Instruction (*) . . . . . . . . . . . . . . . . . . . . . . .
36.6. Real and Realistic (Floating-Point) Arithmetic . . . . . . . . . . .
36.7. When Does Zero Not Behave Like Zero? (*) . . . . . . . . . . . . . . .
36.7.1. Hexadecimal Floating-Point . . . . . . . . . . . . . . . . . . . . . .
36.7.2. Binary Floating-Point . . . . . . . . . . . . . . . . . . . . . . . . .
36.7.3. Decimal Floating-Point . . . . . . . . . . . . . . . . . . . . . . . .
36.8. Examples of Former Floating-Point Representations and Behaviors (*)
36.9. Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

Chapter X: Large Programs and Modularization

Assembler Language Programming for IBM z System Servers

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

710
712
714
714
715
715
716
717
725
725
727
727
728
729
729
730
731
731
734
734
735
735
736
737

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
. .
. .

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

741
742
742
743
743
745
748
749
751
752
753
754
756
759
759
760
762
763
764
764
765
768
768
770
772
773
773
776
776
778
783
783
784
785
785
786
788

.
.
.
.
.
.
.
.
.

. . . . . . . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

37. Subroutines and Linkage Conventions . . . . . . . . . . . . . . . . . . . . . .


37.1. Basic Concepts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
37.1.1. Linkage
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
37.1.2. The Branch and Save Instructions . . . . . . . . . . . . . . . . . .
37.1.3. Argument Passing
. . . . . . . . . . . . . . . . . . . . . . . . . . .
37.1.4. Returned Values . . . . . . . . . . . . . . . . . . . . . . . . . . . .
37.1.5. Status Preservation . . . . . . . . . . . . . . . . . . . . . . . . . . .
37.2. A General Linkage Convention
. . . . . . . . . . . . . . . . . . . . . .
37.3. Argument Passing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
37.3.1. Variable-Length Argument Lists . . . . . . . . . . . . . . . . . . .
37.3.2. Argument Lists with 64-Bit Addresses . . . . . . . . . . . . . . . .
37.4. Save Areas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
37.4.1. Extended Save Area Conventions (*)
. . . . . . . . . . . . . . . .
37.4.2. Format-4 Save Area Conventions for 64-bit Registers (*) . . . . .
37.4.3. Format-5 Save Area Conventions for 32- and 64-bit Registers (*)
37.5. Additional Conventions (*) . . . . . . . . . . . . . . . . . . . . . . . . .
37.5.1. Entry Point Identifiers (*) . . . . . . . . . . . . . . . . . . . . . . .
37.5.2. Calling Point Identifiers (*) . . . . . . . . . . . . . . . . . . . . . .
37.5.3. Save Area Return Flags (*) . . . . . . . . . . . . . . . . . . . . . .
37.5.4. Return Codes (*) . . . . . . . . . . . . . . . . . . . . . . . . . . . .
37.5.5. Conventions for Floating-Point Registers. . . . . . . . . . . . . . .
37.5.6. Main-Program Parameters . . . . . . . . . . . . . . . . . . . . . . .
37.6. Assisted Linkage (*) . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
37.7. Lowest Level Subroutines . . . . . . . . . . . . . . . . . . . . . . . . . .
37.8. Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
37.8.1. Standard Linkage Conventions . . . . . . . . . . . . . . . . . . . .
38. Large Programs, Control Sections, and Linking . . . . . . . . . . . . . . . . .
38.1. Uniform Addressability for Large Programs
. . . . . . . . . . . . . . .
38.1.1. Other Techniques (*)
. . . . . . . . . . . . . . . . . . . . . . . . .
38.2. Simplifying Addressability Problems in Large Programs
. . . . . . . .
38.2.1. Internal Subroutines Without Local Addressability
. . . . . . . .
38.2.2. Internal Subroutines With Local Addressability
. . . . . . . . . .
38.2.3. Minimizing the Number of Base Registers
. . . . . . . . . . . . .
38.2.4. Relative Branches, Immediate Operands, and Long Displacements
38.2.5. Separating Instructions and Data . . . . . . . . . . . . . . . . . . .
38.3. Separate Assemblies . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

xii

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.

Version 1.00

38.4. Control Sections . . . . . . . . . . . . . . . . . . . . . . . . .


38.4.1. Resuming Control Sections . . . . . . . . . . . . . . . .
38.4.2. Literals in Multi-Section Assemblies (*) . . . . . . . . .
38.4.3. Location Counter Discontinuities (*)
. . . . . . . . . .
38.4.4. Section Alignment (*) . . . . . . . . . . . . . . . . . . .
38.4.5. Threaded Location Counters (*) . . . . . . . . . . . . .
38.4.6. The Location Counter Instruction LOCTR (*) . . .
38.5. External Symbols . . . . . . . . . . . . . . . . . . . . . . . . .
38.5.1. EXTRN and WXTRN Statements
. . . . . . . . . . .
38.5.2. V-Type Address Constants . . . . . . . . . . . . . . . .
38.5.3 E N T R Y Statement . . . . . . . . . . . . . . . . . . . . .
38.5.4. The External Symbol Dictionary Listing
. . . . . . . .
38.5.5. External Symbol Addressing and Residence Modes . .
38.6. Object Modules . . . . . . . . . . . . . . . . . . . . . . . . . .
38.6.1. Relocation Dictionary and External Symbol Dictionary
38.7. Program Linking: Combining Object Modules . . . . . . . .
38.7.1. Assigning COMMON Sections . . . . . . . . . . . . . .
38.7.2. Relocating Address Constants
. . . . . . . . . . . . . .
38.7.3. External Dummy Sections (*) . . . . . . . . . . . . . . .
38.7.4. Loading Object Modules (*)
. . . . . . . . . . . . . . .
38.8. Load Modules and Program Objects
. . . . . . . . . . . . .
38.8.1. External Subroutines and Assisted Linkage: Overlay (*)
38.8.2. Program Objects (*) . . . . . . . . . . . . . . . . . . . .
38.8.3. The Class Attribute Instruction CATTR . . . . . . .
38.8.4. Programming for Program Objects . . . . . . . . . . . .
38.8.5. Comparing Load Modules and Program Objects . . . .
38.9. Loading Saved Modules into Storage . . . . . . . . . . . . .
38.9.1. Loading Load Modules . . . . . . . . . . . . . . . . . .
38.9.2. Loading Program Objects . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . .
38.10. Changing Addressing Modes
38.10.1. The BASSM Instruction . . . . . . . . . . . . . . . . .
38.10.2. The BSM Instruction . . . . . . . . . . . . . . . . . . .
38.10.3. Branch and Return With Addressing Mode Change .
38.11. Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

Chapter XI: Dummy Sections, Enhanced USINGs, and Data Structures

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

788
792
794
794
795
795
796
804
805
806
807
810
813
817
818
819
822
822
823
827
831
833
834
837
840
840
841
841
842
844
845
846
847
851

. .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

855
856
856
859
860
861
866
866
867
867
869
870
870
873
874
874
875
876
876
877
877
880
881
882
886
887
887

Contents

xiii

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

39. Dummy Control Sections and Enhanced USING Statements . . . . . . .


39.1. Dummy Control Sections . . . . . . . . . . . . . . . . . . . . . . . .
39.2. Multiple Data Structures
. . . . . . . . . . . . . . . . . . . . . . . .
39.3. Shortcomings of Ordinary USING Statements . . . . . . . . . . . .
39.3.1. Ordinary USINGs . . . . . . . . . . . . . . . . . . . . . . . . .
39.4. Labeled USING Statements and Qualified Symbols . . . . . . . . .
39.4.1. Qualified Symbols . . . . . . . . . . . . . . . . . . . . . . . . .
39.4.2. Dropping a Labeled USING Statement . . . . . . . . . . . . .
39.4.3. Labeled USING Statement Summary . . . . . . . . . . . . . .
39.5. Dependent USING Statements . . . . . . . . . . . . . . . . . . . . .
39.5.1. Definition of Dependent USING Statements . . . . . . . . . .
39.5.2. Examples of Dependent USING Statements . . . . . . . . . .
39.5.3. Mapping a CSECT as a DSECT . . . . . . . . . . . . . . . . .
39.5.4. Dropping Dependent USINGs . . . . . . . . . . . . . . . . . .
39.5.5. Dependent USING Statement Summary . . . . . . . . . . . .
39.6. Labeled Dependent USING Statements . . . . . . . . . . . . . . . .
39.6.1. Nesting Structures Addressed with Ordinary USINGs . . . . .
39.6.2. Nesting Structures Addressed with Labeled USINGs
. . . . .
39.6.3. Nested Structures Addressed with Labeled Dependent USINGs
39.6.4. Multiple Nesting of Identical Structures . . . . . . . . . . . . .
39.6.5. Mapping an Array of Identical Data Structures . . . . . . . . .
39.6.6. Two MVS Data Control Blocks (DCBs) in a Program . . . .
39.7. Example of a Large Personnel-File Record (*)
. . . . . . . . . .
39.7.1. Personnel-File Record Example: Comparing Birth Dates . . .
39.7.2. Personnel-File Record Example: Comparing Different Dates .
39.7.3. Personnel-File Record Example: Copying Addresses
. . . . .

.
.
.
.
.
.
.

39.8. Summary . . . . . . . . . . . . . . . . .
39.8.1. USING Statement Summary . . .
39.8.2. DROP Statement Summary . . . .
40. Basic Data Structures . . . . . . . . . . . . . .
40.1. One-Dimensional Arrays
. . . . . . . .
40.2. Two-Dimensional Arrays . . . . . . . .
40.3. General Array Subscripts . . . . . . . .
40.3.1. Multi-Dimensional Arrays (*) . . .
40.3.2. Non-Homogeneous Arrays (Tables)
40.4. Address Tables . . . . . . . . . . . . . .
40.5. Searching an Ordered Array . . . . . . .
40.6. Stacks . . . . . . . . . . . . . . . . . . .
40.6.1. An Example Using a Stack . . . .
40.6.2. An Example Implementing a Stack
40.7. Lists . . . . . . . . . . . . . . . . . . . .
40.7.1. List Insertion . . . . . . . . . . . .
40.7.3. List Deletion
. . . . . . . . . . . .
40.7.4. Free Storage Lists
. . . . . . . . .
40.8. Queues . . . . . . . . . . . . . . . . . . .
40.9. Trees . . . . . . . . . . . . . . . . . . . .
40.10. Hash Tables . . . . . . . . . . . . . . .
40.11. Summary . . . . . . . . . . . . . . . . .

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

889
889
890
893
894
896
899
899
900
903
905
908
908
909
913
913
914
915
919
922
927
930

.
. . .
. . .
. .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

935
936
936
937
938
942
943
947
957
961
966
968
968
972
977
979

.
.
.
.
.
.
.
.
.
. .
. .

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

981
981
982
983
986
987
989
997
998
999
1000

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

1001
1001
1002
1002
1003
1003
1005
1006
1006
1006

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

Chapter XII: System Services, Reenterability, and Recursion


41. Using System Services
. . . . . . . . . . . . . . . . . . .
41.1. Invoking System Services . . . . . . . . . . . . . .
41.2. Invoking System Services with Macro Instructions
41.3. Macro Formats: Standard, List, and Execute . . .
41.4. Causing Abnormal Termination . . . . . . . . . .
41.5. Storage Management . . . . . . . . . . . . . . . . .
41.6. Basic Input and Output . . . . . . . . . . . . . . .
41.7. Handling Program Interruptions . . . . . . . . . .
41.8. Abnormal Terminations of Any Kind . . . . . . .
41.9. Summary . . . . . . . . . . . . . . . . . . . . . . .
42. Reenterability and Recursion
. . . . . . . . . . . . . . .
42.1. Reenterability . . . . . . . . . . . . . . . . . . . . .
42.2. Recursion . . . . . . . . . . . . . . . . . . . . . . .
42.3. Summary . . . . . . . . . . . . . . . . . . . . . . .
43. Reserved for Future Expansion . . . . . . . . . . . . . .

Appendix A: Conversion and Reference Tables

. . . . . . . . . . . . .
.
.
.
.
.
.
.

Hexadecimal Digits in Decimal and Binary . . . . . . . . . . . . . . .


Hexadecimal Addition and Multiplication Tables
. . . . . . . . . . .
Powers of 2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Multiples of Powers of Sixteen . . . . . . . . . . . . . . . . . . . . . .
Powers of 10 in Hexadecimal . . . . . . . . . . . . . . . . . . . . . . .
Hexadecimal and Decimal Integers . . . . . . . . . . . . . . . . . . . .
Conversion Tables for Hexadecimal Fractions . . . . . . . . . . . . .
EBCDIC Character Representation in Assembler Language Programs
ASCII Character Representation in Assembler Language Programs .
DC Statement Types . . . . . . . . . . . . . . . . . . . . . . . . . . . .

Appendix B: Simple I/O Macros

. . . . . .
.
.
.
.
.
.
.

Macro Facilities . . . . . . . . . . . . . . .
The READCARD Macro-Instruction
The PRINTLIN Macro-Instruction .
The CONVERTO Macro-Instruction
The CONVERTI Macro-Instruction
The PRINTOUT Macro-Instruction
The DUMPOUT Macro-Instruction
PRINTOUT and DUMPOUT Header
Usage Notes . . . . . . . . . . . . . . .

xiv

Assembler Language Programming for IBM z System Servers

.
.
.
.
.
.
.
.
.
. .

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

Version 1.00

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

Sample Program . . . . . . . . . . . . . . . . . . . . . . . . . . . .
The Macro Instruction Definitions . . . . . . . . . . . . . . . . . .
Operating System Environment and Installation Considerations
READCARD Macro
. . . . . . . . . . . . . . . . . . . . . . .
PRINTLIN Macro . . . . . . . . . . . . . . . . . . . . . . . . .
CONVERTO Macro
. . . . . . . . . . . . . . . . . . . . . . .
CONVERTI Macro . . . . . . . . . . . . . . . . . . . . . . . .
D U M P O U T Macro . . . . . . . . . . . . . . . . . . . . . . . .
P R I N T O U T Macro . . . . . . . . . . . . . . . . . . . . . . . .
$$GENIO Macro . . . . . . . . . . . . . . . . . . . . . . . . . .

Glossary of Terms and Abbreviations


Bibliography

Notices

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

. . . . . . . . . . . . . . . . . . . .
. . . .
. . . .
. . .
. . . .

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

Trademarks
Section
Section
Section
Section
Section
Section
Section
Section
Section
Section
Section
Section
Section
Section
Section
Section
Section
Section
Section
Section
Section
Section
Section
Section
Section
Section
Section
Section
Section
Section
Section
Section
Section
Section
Section
Section

1 Solutions
2 Solutions
3 Solutions
4 Solutions
5 Solutions
6 Solutions
7 Solutions
8 Solutions
9 Solutions
10 Solutions
11 Solutions
12 Solutions
13 Solutions
14 Solutions
15 Solutions
16 Solutions
17 Solutions
18 Solutions
19 Solutions
20 Solutions
21 Solutions
22 Solutions
23 Solutions
24 Solutions
27 Solutions
28 Solutions
29 Solutions
30 Solutions
31 Solutions
32 Solutions
33 Solutions
34 Solutions
35 Solutions
36 Solutions
37 Solutions
38 Solutions

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

1041
1041
1042
1042
1042
1043

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

Suggested Solutions to Selected Exercises and Programming Problems

1007
1008
1008
1010
1010
1011
1011
1012
1012
1014
1025

. . . . . . . . . . . . . . . . . . . . . . . . . . . .

Basic References . . . . . . . . . . . .
System/360 Architecture History . . .
Assembler Design and Implementation
Other General References . . . . . . .

Acknowledgments

. . .
. . .
. .
. . .
. . .
. . .
. . .
. . .
. . .
. . .

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

Contents

1045
1045
1047
1048
1049
1055
1056
1058
1060
1061
1063
1066
1067
1069
1070
1072
1077
1080
1082
1095
1107
1120
1125
1128
1131
1139
1141
1153
1160
1162
1169
1176
1181
1184
1195
1202
1210
1213
1221

xv

Section
Section
Section
Section

Index

39
40
41
42

Solutions
Solutions
Solutions
Solutions

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

1233
1236
1247
1250
1253

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

Figures
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.

xvi

Example of numbering and notation


. . . . . . . . . . . . . . . . . . . . . .
One stage of a binary adder . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Circular representation of twos complement representation . . . . . . . .
Conceptual structure of a typical computer . . . . . . . . . . . . . . . . . . .
Conceptual structure of z System . . . . . . . . . . . . . . . . . . . . . . . .
A byte containing 8 binary digits
. . . . . . . . . . . . . . . . . . . . . . . .
A portion of memory, with addresses shown above each byte . . . . . . . .
A portion of memory . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
A single 64-bit general register . . . . . . . . . . . . . . . . . . . . . . . . . .
All sixteen general registers . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Four Floating-Point Registers . . . . . . . . . . . . . . . . . . . . . . . . . .
Sketch of a Program Status Word . . . . . . . . . . . . . . . . . . . . . . . .
Basic instruction cycle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Instruction formats and data interactions . . . . . . . . . . . . . . . . . . . .
Opcode bit patterns for typical instruction types . . . . . . . . . . . . . . . .
Instruction cycle with interruptions . . . . . . . . . . . . . . . . . . . . . . .
Typical instruction format for old computers
. . . . . . . . . . . . . . . . .
Structure of an addressing halfword . . . . . . . . . . . . . . . . . . . . . . .
Sketch of Effective Address calculation . . . . . . . . . . . . . . . . . . . . .
RX-type instruction, showing index register specification digit . . . . . . . .
Sketch of Effective Address calculation with indexing . . . . . . . . . . . . .
31-bit Virtual Address . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Simple view of Assembler processing . . . . . . . . . . . . . . . . . . . . . .
Simple view of program linking . . . . . . . . . . . . . . . . . . . . . . . . .
Simple view of program loading and execution
. . . . . . . . . . . . . . . .
Assembler Language statement columns . . . . . . . . . . . . . . . . . . . .
Comment statement examples . . . . . . . . . . . . . . . . . . . . . . . . . .
Block comments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Statement fields for machine, Assembler, and macro-instruction statements
A machine instruction statement . . . . . . . . . . . . . . . . . . . . . . . . .
An assembler instruction statement . . . . . . . . . . . . . . . . . . . . . . .
The macro-instruction statement RETURN . . . . . . . . . . . . . . . . . .
A complete Assembler Language program . . . . . . . . . . . . . . . . . . .
RX Instruction with explicit operands
. . . . . . . . . . . . . . . . . . . . .
A simple program segment . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Simple program segment with assembled contents . . . . . . . . . . . . . . .
Same program segment, at different memory addresses . . . . . . . . . . . .
Same program segment, with assembled contents . . . . . . . . . . . . . . .
Program segment with pre-calculated explicit base and displacements
. . .
Program segment with explicit base and Assembler-calculated displacements
Program Segment with USING Instruction
. . . . . . . . . . . . . . . . . .
Sample program segment with erroneous statement . . . . . . . . . . . . . .
Sketch of pass one of an assembly . . . . . . . . . . . . . . . . . . . . . . . .
Sketch of pass two of an assembly . . . . . . . . . . . . . . . . . . . . . . . .
USING Table with one entry
. . . . . . . . . . . . . . . . . . . . . . . . . .
Program segment with second USING statement . . . . . . . . . . . . . . .
USING Table with multiple entries . . . . . . . . . . . . . . . . . . . . . . .
Assembled contents when two USINGs are active
. . . . . . . . . . . . . .
USING Table after DROP statement . . . . . . . . . . . . . . . . . . . . . .

Assembler Language Programming for IBM z System Servers

Version 1.00

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

14
37
38
44
45
45
45
46
47
48
49
49
52
54
55
58
63
64
64
66
66
70
74
75
76
77
78
78
79
80
80
80
83
111
119
120
120
120
121
121
122
124
126
127
128
129
129
130
131

50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.

USING Table after second DROP statement . . . . . . . . . . . . . . . . . . .


Implied and explicit length specifications . . . . . . . . . . . . . . . . . . . . . .
Multiple constants . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
F-type constant with decimal exponent . . . . . . . . . . . . . . . . . . . . . . .
Character, hexadecimal, and binary constants . . . . . . . . . . . . . . . . . . .
Length attribute reference to two constants, one a literal . . . . . . . . . . . . .
Describing fields of a (U.S.) telephone number
. . . . . . . . . . . . . . . . . .
Describing fields of an Assembler Language statement . . . . . . . . . . . . . .
Define a group of words
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Describing fields of an Assembler Language statement using ORG instructions
Describing an Assembler symbol cross-reference listing line . . . . . . . . . . .
32-bit portion of a 64-bit general register . . . . . . . . . . . . . . . . . . . . . .
Sign extension by LH instruction . . . . . . . . . . . . . . . . . . . . . . . . . .
Loss of significant digits using STH/LH
. . . . . . . . . . . . . . . . . . . . . .
Loss of significant digits using STH/LH
. . . . . . . . . . . . . . . . . . . . . .
Action of IC and STC instructions . . . . . . . . . . . . . . . . . . . . . . . . .
Interchanging two bytes with IC and STC . . . . . . . . . . . . . . . . . . . . .
Inserting a small number into a register . . . . . . . . . . . . . . . . . . . . . . .
Examples of some RR-type instructions . . . . . . . . . . . . . . . . . . . . . .
Sign extension by LHR instruction . . . . . . . . . . . . . . . . . . . . . . . . .
64-bit general register . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Sign extension by LGH instruction . . . . . . . . . . . . . . . . . . . . . . . . .
Examples of some RR-type instructions for 64-bit operands . . . . . . . . . . .
Sign extension for instructions with mixed 32- and 64-bit signed operands . . .
Sign extension by Load Byte instructions . . . . . . . . . . . . . . . . . . . . . .
Zero extension by Load Logical Character instructions . . . . . . . . . . . . . .
Operation of Load Logical Halfword instructions . . . . . . . . . . . . . . . . .
Operation of Load Logical word instructions
. . . . . . . . . . . . . . . . . . .
Operation of Load Logical Thirty One Bits instructions . . . . . . . . . . . . .
Examples of conditional branch instructions . . . . . . . . . . . . . . . . . . . .
CNOP alignments and operands . . . . . . . . . . . . . . . . . . . . . . . . . . .
Calculate a sum with an intermediate test
. . . . . . . . . . . . . . . . . . . . .
Calculate the sum of the first N odd integers . . . . . . . . . . . . . . . . . . . .
Example of arithmetic addition and subtraction . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . .
Testing the result of arithmetic instructions
Calculate a 64-bit sum with an intermediate test . . . . . . . . . . . . . . . . . .
Adding two 64-bit numbers
. . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Examples of arithmetic comparisons
. . . . . . . . . . . . . . . . . . . . . . . .
Calculate the sum of N odd integers . . . . . . . . . . . . . . . . . . . . . . . . .
Adding two 64-bit numbers logically . . . . . . . . . . . . . . . . . . . . . . . .
Double-length complementation . . . . . . . . . . . . . . . . . . . . . . . . . . .
Double-length complementation, a simpler way . . . . . . . . . . . . . . . . . .
Double-length addition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Double-length subtraction
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Example of logical addition and subtraction . . . . . . . . . . . . . . . . . . . .
Double-length addition with carry . . . . . . . . . . . . . . . . . . . . . . . . . .
Double-length subtraction with borrow . . . . . . . . . . . . . . . . . . . . . . .
Sign extension for instructions with mixed 32- and 64-bit signed operands . . .
Calculate a 64-bit sum with an intermediate test . . . . . . . . . . . . . . . . . .
Calculate a 64-bit sum with an intermediate test . . . . . . . . . . . . . . . . . .
Sign extension for instructions with mixed 32- and 64-bit unsigned operands .
Examples of logical comparisons . . . . . . . . . . . . . . . . . . . . . . . . . . .
Comparing logically ordered values . . . . . . . . . . . . . . . . . . . . . . . . .
Bit positions used by IPM and SPM instructions (System/360 PSW sketch)
.
Register contents before shifting . . . . . . . . . . . . . . . . . . . . . . . . . . .
Logical unit shift left
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Logical unit shift right . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Arithmetic unit shift right . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Arithmetic unit shift left . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Rounding an integer to the next higher multiple of 8 . . . . . . . . . . . . . . .
A 6-byte data entry . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Storage definitions for a 6-byte data entry
. . . . . . . . . . . . . . . . . . . . .

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

Figures

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

132
142
144
148
152
157
162
163
163
169
173
180
185
185
185
187
187
187
190
191
192
194
195
197
198
199
199
199
200
207
211
219
220
220
220
222
223
224
224
226
227
227
227
228
228
230
230
231
231
231
232
233
234
235
243
244
244
244
244
246
246
246

xvii

112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
171.
172.
173.

xviii

Using shift instructions for a 6-byte data item . . . . . . . . . . . . . . . . . . . . . . . 246


Shifting to make the low-order bit one (1) . . . . . . . . . . . . . . . . . . . . . . . . . 249
Shifting to make the low-order bit one (2) . . . . . . . . . . . . . . . . . . . . . . . . . 249
Four integers packed in a 32-bit word . . . . . . . . . . . . . . . . . . . . . . . . . . . . 249
Extracting one packed integer from a 32-bit word . . . . . . . . . . . . . . . . . . . . . 249
Unpacking four unsigned integers using right shifts . . . . . . . . . . . . . . . . . . . . 250
Unpacking four unsigned integers using left shifts . . . . . . . . . . . . . . . . . . . . . 250
Unpacking four signed integers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 254
Logical rotate unit shift . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 257
Packing four unsigned bit-length constants in a 32-bit word . . . . . . . . . . . . . . . 260
Packing four signed bit-length constants in a 32-bit word
. . . . . . . . . . . . . . . . 260
General layout of multiplication operands . . . . . . . . . . . . . . . . . . . . . . . . . 265
Double-length product of multiply operations . . . . . . . . . . . . . . . . . . . . . . . 266
Calculate the sum of the first 10 cubed integers . . . . . . . . . . . . . . . . . . . . . . 267
Illustration of binary multiplication . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 273
General result of divide operation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 274
Operands of double-length division . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 275
Example of division by 3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 276
Example of rounded integer division
. . . . . . . . . . . . . . . . . . . . . . . . . . . . 276
Example of rounded integer division with signed dividend . . . . . . . . . . . . . . . . 277
Ensuring a valid arithmetic division . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 277
Causing a fixed-point divide interruption . . . . . . . . . . . . . . . . . . . . . . . . . . 277
Operands of single-length division before division . . . . . . . . . . . . . . . . . . . . . 278
Operands of single-length division after division . . . . . . . . . . . . . . . . . . . . . . 278
Example of logical division . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 280
Illustration of binary division . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 282
Logical operations AND, OR, and XOR . . . . . . . . . . . . . . . . . . . . . . . . . . 289
Examples of logical operations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 290
Inserting a new integer value using AND and OR . . . . . . . . . . . . . . . . . . . . . 291
Data masking using Exclusive OR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 292
Rounding to the next multiple of 8 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 293
Rounding to the next multiple of 8 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 293
Complementing a double-length integer
. . . . . . . . . . . . . . . . . . . . . . . . . . 294
Effective Address generation for long-displacement instructions . . . . . . . . . . . . . 303
Addressability range with 12-bit displacements . . . . . . . . . . . . . . . . . . . . . . . 304
Addressability range with 20-bit displacements . . . . . . . . . . . . . . . . . . . . . . . 304
Effective Address formation for relative-immediate instructions . . . . . . . . . . . . . 305
Areas of memory addressed by three AMODEs . . . . . . . . . . . . . . . . . . . . . . 308
z System PSW showing addressing-mode bits . . . . . . . . . . . . . . . . . . . . . . . 308
. . . . . . . . . . . . . . . . . . . 310
Loading integer constants with the LAY instruction
Counting number of shifts to make rightmost bit a 1-bit . . . . . . . . . . . . . . . . . 311
Using LA to set a branch address . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 311
64bit Virtual Address . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 314
64-bit Virtual Address with Region Indexes . . . . . . . . . . . . . . . . . . . . . . . . 314
Instruction classes, including RI, RIL . . . . . . . . . . . . . . . . . . . . . . . . . . . . 317
Four halfwords in a 64-bit general register . . . . . . . . . . . . . . . . . . . . . . . . . 318
Operation of six Insert Immediate instructions . . . . . . . . . . . . . . . . . . . . . . . 319
Operation of LHI instruction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 320
Operation of LGHI instruction
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 320
Examples of load-immediate instructions . . . . . . . . . . . . . . . . . . . . . . . . . . 321
Operation of six logical load instructions . . . . . . . . . . . . . . . . . . . . . . . . . . 321
Extracting an unsigned integer value using AND Immediate . . . . . . . . . . . . . . . 324
Inserting a new integer value using AND Immediate . . . . . . . . . . . . . . . . . . . 324
Data masking using immediate operands . . . . . . . . . . . . . . . . . . . . . . . . . . 325
Data masking using a symbolically defined immediate operand . . . . . . . . . . . . . 325
A simple loop to scan and replace characters . . . . . . . . . . . . . . . . . . . . . . . . 333
A simple loop, using indexing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 334
Indexing into a branch table . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 334
A backward loop to scan and replace characters . . . . . . . . . . . . . . . . . . . . . . 336
Calculate the sum of the first N odd integers . . . . . . . . . . . . . . . . . . . . . . . . 336
Store the cubes of the first 10 integers . . . . . . . . . . . . . . . . . . . . . . . . . . . . 337
Sketch of a Do-Until loop . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 340

Assembler Language Programming for IBM z System Servers

Version 1.00

174.
175.
176.
177.
178.
179.
180.
181.
182.
183.
184.
185.
186.
187.
188.
189.
190.
191.
192.
193.
194.
195.
196.
197.
198.
199.
200.
201.
202.
203.
204.
205.
206.
207.
208.
209.
210.
211.
212.
213.
214.
215.
216.
217.
218.
219.
220.
221.
222.
223.
224.
225.
226.
227.
228.
229.
230.
231.
232.
233.
234.
235.

Sketch of a Do-While loop . . . . . . . . . . . . . . . . . . . . . . .


Store the cubes of the first 10 integers in a different way . . . . . .
Operation of BXH and BXLE instructions . . . . . . . . . . . . . .
Operation of BXH and BXLE instructions . . . . . . . . . . . . . .
Replacing special characters with blanks, using BXLE . . . . . . .
Creating a table of cubed integers using BXLE
. . . . . . . . . . .
Creating a table of cubed integers using BXLE
. . . . . . . . . . .
Creating a table of cubed integers with addresses as controls . . . .
Creating a table of cubed integers using BXH . . . . . . . . . . . .
Creating a table of cubed integers, using BXH in a special way . .
Examples of the MVI instruction . . . . . . . . . . . . . . . . . . .
Examples of the NI instruction
. . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . .
Examples of the OI instruction
Example of the XI instruction . . . . . . . . . . . . . . . . . . . . .
A simpler loop to scan and replace characters . . . . . . . . . . . .
Setting an overflow-indication flag bit . . . . . . . . . . . . . . . . .
Adding alternate list elements twice . . . . . . . . . . . . . . . . . .
Defining bit names safely . . . . . . . . . . . . . . . . . . . . . . . .
Using safely-defined bit names . . . . . . . . . . . . . . . . . . . . .
Converting a binary integer to characters . . . . . . . . . . . . . . .
Adding alternate list elements twice, with program modification . .
Adding alternate list elements twice, without program modification
Assembler Language syntax of basic SS-type instructions
. . . . .
Examples of SS-type instruction operands . . . . . . . . . . . . . .
SS-type instruction using a Length Attribute reference . . . . . . .
Examples of Length Specification Bytes
. . . . . . . . . . . . . . .
Emulated operation of MVC instruction . . . . . . . . . . . . . . .
Example of Move Inverse instruction . . . . . . . . . . . . . . . . .
Emulated operation of MVCIN instruction
. . . . . . . . . . . . .
Example of MVCOS instruction . . . . . . . . . . . . . . . . . . . .
Inserting bits in a word using logical SS-type instructions . . . . .
Emulating the TR instruction . . . . . . . . . . . . . . . . . . . . .
TR instruction to change special characters to blanks . . . . . . . .
Translating hex digits to EBCDIC characters (1) . . . . . . . . . .
Translating hex digits to EBCDIC characters (2) . . . . . . . . . .
Searching for punctuation characters using CLI . . . . . . . . . . .
Searching for punctuation characters using TRT
. . . . . . . . . .
Using TRT to validate numeric characters . . . . . . . . . . . . . .
Using TRT to scan for embedded quotations . . . . . . . . . . . .
Using TRT to scan a string of names and build an occurrence list
Using TRTR to validate numeric characters . . . . . . . . . . . . .
Scanning a string backward using CLI
. . . . . . . . . . . . . . . .
Scanning a string backward using TRTR . . . . . . . . . . . . . . .
Executing a list of instructions . . . . . . . . . . . . . . . . . . . . .
Executing a list of instructions . . . . . . . . . . . . . . . . . . . . .
Constructing an executed instruction . . . . . . . . . . . . . . . . .
Moving a string of bytes of unknown length . . . . . . . . . . . . .
Register use by CLCL and MVCL . . . . . . . . . . . . . . . . . .
Execution of the MVCL instruction . . . . . . . . . . . . . . . . . .
Using MVCL to set a field to blanks . . . . . . . . . . . . . . . . .
Moving a message with padding and length checking . . . . . . . .
Execution of the CLCL instruction . . . . . . . . . . . . . . . . . .
Using CLCL to test for blanks . . . . . . . . . . . . . . . . . . . . .
Comparing two records without padding . . . . . . . . . . . . . . .
Register use by MVCLE and CLCLE
. . . . . . . . . . . . . . . .
Execution of the MVCLE instruction . . . . . . . . . . . . . . . . .
Using MVCLE to set a field to blanks . . . . . . . . . . . . . . . .
Using MVCLE to initialize an area to zero . . . . . . . . . . . . . .
Execution of the CLCLE instruction . . . . . . . . . . . . . . . . .
Using CLCLE to test for all blanks . . . . . . . . . . . . . . . . . .
Registers bounding the SRST search string . . . . . . . . . . . . . .
Execution of the SRST instruction . . . . . . . . . . . . . . . . . .

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

340
341
343
343
344
345
345
345
347
347
355
356
356
356
357
359
359
362
362
363
364
365
368
370
372
373
374
375
375
376
378
381
381
382
382
386
386
386
387
388
388
389
389
391
391
392
393
405
407
407
407
409
409
410
412
413
413
414
414
415
416
417

Figures

xix

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

236.
237.
238.
239.
240.
241.
242.
243.
244.
245.
246.
247.
248.
249.
250.
251.
252.
253.
254.
255.
256.
257.
258.
259.
260.
261.
262.
263.
264.
265.
266.
267.
268.
269.
270.
271.
272.
273.
274.
275.
276.
277.
278.
279.
280.
281.
282.
283.
284.
285.
286.
287.
288.
289.
290.
291.
292.
293.
294.
295.
296.
297.

xx

Execution of the MVST instruction . . . . . . . . . . . . . . . . . . . . . . . . . . . .


Moving a null-terminated string . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Using MVST to isolate comma-separated tokens . . . . . . . . . . . . . . . . . . . .
Execution of the CLST instruction . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Translating characters to upper case with TRE . . . . . . . . . . . . . . . . . . . . .
Examples using the CUSE instruction
. . . . . . . . . . . . . . . . . . . . . . . . . .
Mixed single- and double-byte EBCDIC characters . . . . . . . . . . . . . . . . . . .
Examples of DBCS data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Extended continuation for DBCS data . . . . . . . . . . . . . . . . . . . . . . . . . .
CU-type constant generating Unicode characters
. . . . . . . . . . . . . . . . . . . .
Using MVCLU to initialize an area to Unicode spaces . . . . . . . . . . . . . . . . .
Using CLCLU to test for Unicode spaces . . . . . . . . . . . . . . . . . . . . . . . .
Assembler instruction statement for RRF-type instructions with an optional operand
Using TRTT to translate from DBCS to Unicode
. . . . . . . . . . . . . . . . . . .
Translating a long string with TR and MVC, and with TROO . . . . . . . . . . . .
Bits of a UTF-16 Unicode character
. . . . . . . . . . . . . . . . . . . . . . . . . . .
Bits of a UTF-16 Unicode surrogate pair . . . . . . . . . . . . . . . . . . . . . . . . .
Bits of a UTF-32 Unicode character from a UTF-16 surrogate pair
. . . . . . . . .
Big-Endian storage representation of X 87654321
. . . . . . . . . . . . . . . . . . .
Little-Endian storage representation of X 87654321 . . . . . . . . . . . . . . . . . .
Byte reversal by LRV, LRVR, and STRV instructions . . . . . . . . . . . . . . . . .
Byte reversal by LRVH and STRVH instructions . . . . . . . . . . . . . . . . . . . .
Four integers packed in a Big-Endian 32-bit word . . . . . . . . . . . . . . . . . . . .
The same four integers packed in a Little-Endian 32-bit word . . . . . . . . . . . . .
Zone and numeric digits of a byte . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Example of MVN and MVZ instructions . . . . . . . . . . . . . . . . . . . . . . . . .
Zoned decimal sign conventions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
A zoned decimal number . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Zoned decimal constants with implied lengths . . . . . . . . . . . . . . . . . . . . . .
Zoned decimal constants with explicit lengths . . . . . . . . . . . . . . . . . . . . . .
Representation of a packed decimal number . . . . . . . . . . . . . . . . . . . . . . .
Packed decimal constants with implied lengths
. . . . . . . . . . . . . . . . . . . . .
Packed decimal constants with explicit lengths . . . . . . . . . . . . . . . . . . . . . .
Format of typical two-length SS-type instructions . . . . . . . . . . . . . . . . . . . .
Examples of assembled PACK and UNPK instructions . . . . . . . . . . . . . . . .
Zoned and packed forms of +12345 . . . . . . . . . . . . . . . . . . . . . . . . . . .
PACK instruction operation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Converting from zoned to packed decimal using PACK . . . . . . . . . . . . . . . .
Examples of the PACK instruction . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Digit swap using PACK
Operation of the UNPK instruction . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Example of an UNPK instruction . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Examples of UNPK instructions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Digit swap using UNPK . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Packing ASCII characters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Packing Unicode characters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Unpacking to ASCII and Unicode characters . . . . . . . . . . . . . . . . . . . . . .
Unpacking hex digits (incorrectly) . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Unpacking hex digits (correctly) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Converting hex data to printable characters
. . . . . . . . . . . . . . . . . . . . . . .
Syntax of the TP instruction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Examples of the ZAP instruction . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Using ZAP to initialize a table of packed decimal operands . . . . . . . . . . . . . .
Initializing a table of decimal numbers using MVC . . . . . . . . . . . . . . . . . . .
Examples of the AP and SP instructions . . . . . . . . . . . . . . . . . . . . . . . . .
Adding a table of 50 packed decimal numbers . . . . . . . . . . . . . . . . . . . . . .
Adding positive and negative items separately . . . . . . . . . . . . . . . . . . . . . .
Finding the largest item in a table . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Example of decimal multiplication . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Using MP to square a table of decimal numbers
. . . . . . . . . . . . . . . . . . . .
Using ZAP to set correct decimal multiplicand length
. . . . . . . . . . . . . . . . .
Using ZAP to set correct decimal multiplicand length
. . . . . . . . . . . . . . . . .

Assembler Language Programming for IBM z System Servers

Version 1.00

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

418
419
419
421
423
425
433
434
437
439
441
442
443
445
445
446
446
446
449
449
449
450
450
451
454
455
456
456
458
458
460
461
461
463
464
465
465
465
466
466
468
468
469
469
472
472
473
475
475
475
490
492
492
492
494
494
496
497
498
498
499
499

298.
299.
300.
301.
302.
303.
304.
305.
306.
307.
308.
309.
310.
311.
312.
313.
314.
315.
316.
317.
318.
319.
320.
321.
322.
323.
324.
325.
326.
327.
328.
329.
330.
331.
332.
333.
334.
335.
336.
337.
338.
339.
340.
341.
342.
343.
344.
345.
346.
347.
348.
349.
350.
351.
352.
353.
354.
355.
356.
357.
358.
359.

Generating 0 using MP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Decimal division using DP . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Decimal division using Length Attribute References for operands . . . . . . .
Computing the average of a table of decimal numbers . . . . . . . . . . . . .
Assembler Language format of SRP machine instruction statement
. . . . .
Shifting a decimal operand left 3 places using SRP . . . . . . . . . . . . . . .
Shifting a decimal operand right 2 places using SRP . . . . . . . . . . . . . .
Shifting a decimal operand right 1 place with rounding using SRP . . . . . .
Shifting a decimal operand with an EXecuted SRP . . . . . . . . . . . . . . .
Operation of the MVO instruction
. . . . . . . . . . . . . . . . . . . . . . . .
Two Examples of MVO results . . . . . . . . . . . . . . . . . . . . . . . . . .
Shifting a decimal operand right an odd number of digits
. . . . . . . . . . .
. . . . . . . . . . .
Shifting a decimal operand right an odd number of digits
Shifting a decimal operand left an odd number of digits . . . . . . . . . . . .
Shifting a decimal operand left by one digit
. . . . . . . . . . . . . . . . . . .
Shifting a decimal operand left by three or more digits . . . . . . . . . . . . .
Shifting a decimal operand left an even number of digits . . . . . . . . . . . .
Shifting a decimal operand left an even number of digits . . . . . . . . . . . .
Shifting a decimal operand left an even number of digits . . . . . . . . . . . .
Shifting a decimal operand right an even number of digits . . . . . . . . . . .
Shifting a decimal operand right an even number of digits . . . . . . . . . . .
Ensuring decimal point alignment for packed decimal addition . . . . . . . .
A business calculation in packed decimal, part 1 . . . . . . . . . . . . . . . . .
A business calculation in packed decimal, part 2 . . . . . . . . . . . . . . . . .
A business calculation in packed decimal, part 3 . . . . . . . . . . . . . . . . .
A business calculation in packed decimal, part 4 . . . . . . . . . . . . . . . . .
Integer and Scale Attributes
. . . . . . . . . . . . . . . . . . . . . . . . . . . .
Using Scale Attributes in a SRP instruction . . . . . . . . . . . . . . . . . . .
Converting a 64-bit binary integer to packed decimal . . . . . . . . . . . . . .
Using CVD to format page numbers . . . . . . . . . . . . . . . . . . . . . . .
Converting decimal characters to binary
. . . . . . . . . . . . . . . . . . . . .
Sketch of an editing operation . . . . . . . . . . . . . . . . . . . . . . . . . . .
Representation of an editing pattern . . . . . . . . . . . . . . . . . . . . . . . .
Convert a packed decimal integer to characters using UNPK . . . . . . . . .
. . . . . . . . . . .
Convert a packed decimal integer to characters using ED
Converting a 32-bit binary integer to characters . . . . . . . . . . . . . . . . .
Editing a binary integer with separating commas
. . . . . . . . . . . . . . . .
Editing a signed number
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Using field protection with ED . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . .
Edited result with a floating currency symbol
Edited result with a properly placed floating currency symbol . . . . . . . . .
Integer value with optional sign and separating commas . . . . . . . . . . . .
Editing multiple values . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Logical-operation description of the editing process . . . . . . . . . . . . . . .
ED and EDMK operation . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
A data item containing an integer value . . . . . . . . . . . . . . . . . . . . . .
A packed decimal field containing integer and fraction parts . . . . . . . . . .
A binary word containing integer and fraction parts . . . . . . . . . . . . . . .
Calculating a tax amount in scaled fixed decimal arithmetic . . . . . . . . . .
Calculating a tax amount in scaled fixed binary arithmetic . . . . . . . . . . .
Two binary constants scaled by 2**28
. . . . . . . . . . . . . . . . . . . . . .
Defining a scaled binary constant 10**12 . . . . . . . . . . . . . . . . . . . . .
Multiplying two scaled binary numbers . . . . . . . . . . . . . . . . . . . . . .
Examples of data with widely ranging values . . . . . . . . . . . . . . . . . . .
A typical floating-point representation
. . . . . . . . . . . . . . . . . . . . . .
An example of a floating-point representation using 4 decimal digits . . . . .
Another example of a floating-point representation using 4 decimal digits . .
A floating-point representation showing normalized and unnormalized values
Floating-point numbers with signed exponent . . . . . . . . . . . . . . . . . .
Examples of approximate floating-point representations . . . . . . . . . . . .
Three floating-point data lengths . . . . . . . . . . . . . . . . . . . . . . . . . .
Four floating-point registers
. . . . . . . . . . . . . . . . . . . . . . . . . . . .

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

499
500
501
501
503
504
504
504
504
507
508
509
509
510
510
510
511
511
511
511
512
514
518
518
519
519
520
520
523
523
525
526
527
528
528
530
531
532
532
533
533
534
535
536
537
540
540
541
543
544
545
545
546
547
548
549
549
549
550
550
551
552

Figures

xxi

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

360.
361.
362.
363.
364.
365.
366.
367.
368.
369.
370.
371.
372.
373.
374.
375.
376.
377.
378.
379.
380.
381.
382.
383.
384.
385.
386.
387.
388.
389.
390.
391.
392.
393.
394.
395.
396.
397.
398.
399.
400.
401.
402.
403.
404.
405.
406.
407.
408.
409.
410.
411.
412.
413.
414.
415.
416.
417.
418.
419.
420.
421.

xxii

All sixteen floating-point registers, showing register pairings . . . . . . . .


Integer-based representation of 73 in FPI(10,4) . . . . . . . . . . . . . . .
Illustrating floating-point division corrective right shift . . . . . . . . . . .
Exponent range of representable and computable values . . . . . . . . . .
Hexadecimal floating-point number representations . . . . . . . . . . . . .
Quadword aligned constants and data . . . . . . . . . . . . . . . . . . . . .
Hexadecimal floating-point constants with rounding suffixes . . . . . . . .
. . . . . . . . . . . .
Examples of hexadecimal floating-point instructions
Example of LTXR instruction . . . . . . . . . . . . . . . . . . . . . . . . .
Examples of extended-precision hexadecimal RR instructions . . . . . . .
Short hexadecimal floating-point multiplication . . . . . . . . . . . . . . .
Floating-point registers used for hexadecimal floating-point multiplication
. . . . .
Calculating a table of short hexadecimal floating-point products
Calculating a table of long hexadecimal floating-point products . . . . . .
Floating-point registers used for hexadecimal floating-point multiplication
Example of hexadecimal floating-point divide instructions . . . . . . . . .
Example of hexadecimal floating-point divide instructions . . . . . . . . .
Example of a hexadecimal floating-point halve instruction . . . . . . . . .
Hexadecimal halve instruction causing underflow . . . . . . . . . . . . . .
Example of hexadecimal floating-point addition . . . . . . . . . . . . . . .
Evaluating a hexadecimal floating-point expression . . . . . . . . . . . . .
Evaluating a hexadecimal floating-point inner product . . . . . . . . . . .
Evaluating a polynomial with hexadecimal floating-point arithmetic . . .
Evaluating a quadratic polynomial . . . . . . . . . . . . . . . . . . . . . . .
Converting a binary integer to hexadecimal floating-point . . . . . . . . .
Converting a hexadecimal floating-point number to a binary integer . . .
Rounding a long hexadecimal floating-point number to short . . . . . . .
Rounded inner product of long HFP numbers . . . . . . . . . . . . . . . .
Manually rounding long to short (1)
. . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . .
Manually rounding long to short (2)
Manually rounding long to short (3)
. . . . . . . . . . . . . . . . . . . . .
Converting a 32-bit integer to short hexadecimal floating-point . . . . . .
Converting a 64-bit integer to three hexadecimal floating-point values . .
Early conversion of integer to hexadecimal floating-point
. . . . . . . . .
Format of machine instruction statement for converting HFP to binary .
Calculating a HFP remainder
. . . . . . . . . . . . . . . . . . . . . . . . .
Evaluating a hexadecimal floating-point remainder . . . . . . . . . . . . .
Examples of HFP square root instructions . . . . . . . . . . . . . . . . . .
Three binary floating-point data representations . . . . . . . . . . . . . . .
Range of the binary floating-point representation . . . . . . . . . . . . . .
A view of the binary floating-point representation . . . . . . . . . . . . . .
Examples of short binary floating-point constants . . . . . . . . . . . . . .
Examples of long and extended binary floating-point constants . . . . . .
Rounding indicators for binary floating-point constants
. . . . . . . . . .
Examples of parameterized binary floating-point NaNs . . . . . . . . . . .
Binary floating-point constants with decimal exponents and modifiers . .
Values representable with gradual underflow . . . . . . . . . . . . . . . . .
Floating-Point Control (FPC) register
. . . . . . . . . . . . . . . . . . . .
Examples of binary floating-point data movement instructions . . . . . .
Example of binary floating-point multiply instructions . . . . . . . . . . .
Examples of binary floating-point multiplication overflow and underflow
Examples of binary floating-point multiply instructions
. . . . . . . . . .
Example of binary floating-point denormalized product
. . . . . . . . . .
Example of binary floating-point extended-precision operands . . . . . . .
Examples of binary floating-point division . . . . . . . . . . . . . . . . . .
Examples of binary floating-point division overflow and underflow . . . .
Examples of binary floating-point addition and subtraction . . . . . . . .
Examples of binary floating-point comparison . . . . . . . . . . . . . . . .
Examples of binary floating-point compare and signal instructions . . . .
Examples of binary floating-point rounding instructions . . . . . . . . . .
Examples of BFP load lengthened instructions
. . . . . . . . . . . . . . .
Examples of BFP load lengthened instructions with NaNs . . . . . . . . .

Assembler Language Programming for IBM z System Servers

Version 1.00

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

553
564
565
570
574
581
582
585
585
585
586
587
587
587
588
591
591
592
592
593
594
595
595
595
596
596
604
604
604
605
605
607
607
607
608
612
612
614
626
628
629
629
630
630
631
632
634
636
643
644
645
645
645
645
646
647
648
650
650
651
652
652

422.
423.
424.
425.
426.
427.
428.
429.
430.
431.
432.
433.
434.
435.
436.
437.
438.
439.
440.
441.
442.
443.
444.
445.
446.
447.
448.
449.
450.
451.
452.
453.
454.
455.
456.
457.
458.
459.
460.
461.
462.
463.
464.
465.
466.
467.
468.
469.
470.
471.
472.
473.
474.
475.
476.
477.
478.
479.
480.
481.
482.
483.

Examples of binary integer to binary floating-point instructions . . . . . . . . .


Examples of converting binary floating-point fractions to integers with rounding
Examples of Convert to Fixed instructions . . . . . . . . . . . . . . . . . . . . .
Examples of load FP integer instructions . . . . . . . . . . . . . . . . . . . . . .
Examples of divide to integer instructions
. . . . . . . . . . . . . . . . . . . . .
Example of iterative divide to integer . . . . . . . . . . . . . . . . . . . . . . . .
Iterative execution of a divide to integer instruction . . . . . . . . . . . . . . . .
Examples of binary floating-point square root instructions . . . . . . . . . . . .
Example of binary floating-point multiply and add instructions . . . . . . . . .
Hexadecimal and binary floating-point representations . . . . . . . . . . . . . .
Conceptual decimal floating-point representation . . . . . . . . . . . . . . . . .
Three decimal floating-point representations of the same value . . . . . . . . .
Decimal floating-point data representation . . . . . . . . . . . . . . . . . . . . .
z System decimal floating-point representations . . . . . . . . . . . . . . . . . .
DFP constants with exponent modifiers and decimal exponents . . . . . . . . .
Examples of decimal floating-point Test Data Class instructions . . . . . . . .
Illustration of decimal floating-point rounding candidates
. . . . . . . . . . . .
Illustration of decimal floating-point rounding candidates near zero . . . . . . .
Floating-Point Control (FPC) register
. . . . . . . . . . . . . . . . . . . . . . .
Examples of converting decimal floating-point to fixed binary . . . . . . . . . .
Examples of converting decimal floating-point to binary integer . . . . . . . . .
Converting signed packed decimal to decimal floating-point . . . . . . . . . . .
Converting decimal floating-point to signed packed decimal . . . . . . . . . . .
Converting decimal floating-point to signed packed decimal . . . . . . . . . . .
. . . . . . . . .
Converting unsigned packed decimal to decimal floating-point
Converting decimal floating-point to unsigned packed decimal
. . . . . . . . .
Effect of the mask operand on Convert from Zoned results . . . . . . . . . . .
Examples of converting decimal floating-point to zoned . . . . . . . . . . . . .
DFP arithmetic with short operands
. . . . . . . . . . . . . . . . . . . . . . . .
Floating-Point Control Register showing Decimal Rounding Mode bits . . . .
Example of extracting DFP biased exponent . . . . . . . . . . . . . . . . . . . .
Example of inserting a biased DFP exponent
. . . . . . . . . . . . . . . . . . .
Examples of DFP Extract Significance instructions . . . . . . . . . . . . . . . .
Converting an extended decimal floating-point value to packed decimal . . . .
Calculate price plus tax . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Correctly rounding a cost to two decimal digits . . . . . . . . . . . . . . . . . .
Example of a reround instruction . . . . . . . . . . . . . . . . . . . . . . . . . .
Example of rerounding arbitrary amounts
. . . . . . . . . . . . . . . . . . . . .
Examples of assembled DFP constants using rounding for reround . . . . . . .
Example of DFP binary-significand format . . . . . . . . . . . . . . . . . . . . .
Sketch of short binary-significand format . . . . . . . . . . . . . . . . . . . . . .
BCD-to-DPD encodings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
DPD-to-BCD translation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Degraded precision in adding hexadecimal floating-point pseudo-zeros . . . . .
Trivial example of a subroutine (1) . . . . . . . . . . . . . . . . . . . . . . . . .
Trivial example of a subroutine (2) . . . . . . . . . . . . . . . . . . . . . . . . .
Subroutine linkage using a BAS instruction . . . . . . . . . . . . . . . . . . . .
Subroutine linkage using a BASR instruction . . . . . . . . . . . . . . . . . . .
Subroutine linkage using an address constant
. . . . . . . . . . . . . . . . . . .
Simple shift subroutine (1) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Simple shift subroutine (2) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Simple shift subroutine with named arguments (3) . . . . . . . . . . . . . . . .
Simple shift subroutine (4) using argument addresses . . . . . . . . . . . . . . .
Simple shift subroutine (5) with argument addresses in memory . . . . . . . . .
Subroutine call with inline arguments . . . . . . . . . . . . . . . . . . . . . . . .
Subroutine returning past inline argument . . . . . . . . . . . . . . . . . . . . .
Subroutine call with inline argument addresses . . . . . . . . . . . . . . . . . . .
Subroutine with argument address list . . . . . . . . . . . . . . . . . . . . . . . .
Subroutine saves and restores registers
. . . . . . . . . . . . . . . . . . . . . . .
General argument-passing scheme . . . . . . . . . . . . . . . . . . . . . . . . . .
Subroutine call using an argument address list . . . . . . . . . . . . . . . . . . .
Subroutine called with an argument address list . . . . . . . . . . . . . . . . . .

. .
.
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

Figures

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

653
654
654
656
657
657
658
659
660
668
669
670
673
673
678
680
681
682
685
695
695
696
697
697
698
698
699
700
704
705
705
706
707
708
710
710
711
711
712
716
716
720
721
734
743
743
744
745
745
746
746
746
747
747
747
748
748
749
750
752
752
752

xxiii

484.
485.
486.
487.
488.
489.
490.
491.
492.
493.
494.
495.
496.
497.
498.
499.
500.
501.
502.
503.
504.
505.
506.
507.
508.
509.
510.
511.
512.
513.
514.
515.
516.
517.
518.
519.
520.
521.
522.
523.
524.
525.
526.
527.
528.
529.
530.
531.
532.
533.
534.
535.
536.
537.
538.
539.
540.
541.
542.
543.
544.
545.

xxiv

Constructing an argument address list . . . . . . . . . . . . . . . . . . .


Two variable-length argument lists
. . . . . . . . . . . . . . . . . . . .
Calling a subroutine with a variable-length argument list . . . . . . . .
Subroutine called with a variable-length argument list
. . . . . . . . .
Sketch of a variable-length argument list . . . . . . . . . . . . . . . . .
Sample 64-bit argument list addresses . . . . . . . . . . . . . . . . . . .
Standard save area layout . . . . . . . . . . . . . . . . . . . . . . . . . .
Sample subroutine calling sequence . . . . . . . . . . . . . . . . . . . .
Save area chaining instructions . . . . . . . . . . . . . . . . . . . . . . .
Chained save areas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Reloading registers and returning to a caller . . . . . . . . . . . . . . .
Format-4 save area layout
. . . . . . . . . . . . . . . . . . . . . . . . .
Example of using a Format-4 save area . . . . . . . . . . . . . . . . . .
Format-5 save area layout
. . . . . . . . . . . . . . . . . . . . . . . . .
Saving registers using a Format-5 save area . . . . . . . . . . . . . . . .
Return from a routine using a Format-5 save area
. . . . . . . . . . .
Example of an entry point identifier . . . . . . . . . . . . . . . . . . . .
Example of two calling point identifiers . . . . . . . . . . . . . . . . . .
Setting a return flag . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Setting a return code in register 15 . . . . . . . . . . . . . . . . . . . . .
Testing a return code returned in register 15 . . . . . . . . . . . . . . .
Using a return code as a branch index
. . . . . . . . . . . . . . . . . .
Using a return code as a branch index with relative branch instructions
Checking for valid return code values . . . . . . . . . . . . . . . . . . .
Setting a reason code in register 0 . . . . . . . . . . . . . . . . . . . . .
Using RETURN macros to set return flags and return codes . . . . .
Returning to an error branch without a return code . . . . . . . . . . .
Call with error branch instructions
. . . . . . . . . . . . . . . . . . . .
Convention for passing main-program parameters . . . . . . . . . . . .
Example of calling with assisted linkage . . . . . . . . . . . . . . . . . .
Example of a routine to implement assisted linkage . . . . . . . . . . .
Assisted linkage routine with counters
. . . . . . . . . . . . . . . . . .
Example of a lowest level subroutine . . . . . . . . . . . . . . . . . . .
Establish three base registers (1) . . . . . . . . . . . . . . . . . . . . . .
Establish three base registers (2) . . . . . . . . . . . . . . . . . . . . . .
Establish three base registers (3) . . . . . . . . . . . . . . . . . . . . . .
Establish three base registers (4) . . . . . . . . . . . . . . . . . . . . . .
Establish three base registers (5) . . . . . . . . . . . . . . . . . . . . . .
Establish three base registers with risks (6) . . . . . . . . . . . . . . . .
Establish three base registers (7) . . . . . . . . . . . . . . . . . . . . . .
Establish three base registers (8) . . . . . . . . . . . . . . . . . . . . . .
Establish three base registers (9) . . . . . . . . . . . . . . . . . . . . . .
Calling a subroutine not needing local addressability . . . . . . . . . .
Calling a subroutine not locally addressable . . . . . . . . . . . . . . .
Subroutine with local addressability . . . . . . . . . . . . . . . . . . . .
Replacing based branch instructions with relative-immediates . . . . .
Replacing a based EXecute instruction with EXRL . . . . . . . . . . .
Replacing references to constants with immediate operands . . . . . .
Replacing short unsigned displacements with long signed displacements
A program fragment needing reorganization . . . . . . . . . . . . . . .
A program fragment after reorganization . . . . . . . . . . . . . . . . .
Reorganizing a program to minimize base registers . . . . . . . . . . .
Incorrect implied reference to a different control section . . . . . . . .
Correct implied reference to a different control section . . . . . . . . .
USING Table with two entries
. . . . . . . . . . . . . . . . . . . . . .
Main program and subroutine in one assembly . . . . . . . . . . . . .
Main program, subroutine, and common section in one assembly
. .
Resuming control sections . . . . . . . . . . . . . . . . . . . . . . . . .
Main program and subroutine in one assembly, multiple CSects . . .
Statements with Location Counter discontinuities . . . . . . . . . . . .
Technique for rounding the length of a CSECT . . . . . . . . . . . . .
Rearrangement of source groups by LOCTR
. . . . . . . . . . . . . .

Assembler Language Programming for IBM z System Servers

Version 1.00

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

753
753
753
753
754
754
757
757
758
758
758
760
760
761
762
762
763
764
764
765
766
766
766
766
767
767
767
768
768
770
770
771
772
777
777
777
778
778
778
779
779
779
784
784
785
785
786
786
786
786
787
787
790
790
790
791
792
792
793
794
795
797

546.
547.
548.
549.
550.
551.
552.
553.
554.
555.
556.
557.
558.
559.
560.
561.
562.
563.
564.
565.
566.
567.
568.
569.
570.
571.
572.
573.
574.
575.
576.
577.
578.
579.
580.
581.
582.
583.
584.
585.
586.
587.
588.
589.
590.
591.
592.
593.
594.
595.
596.
597.
598.
599.
600.
601.
602.
603.
604.
605.
606.
607.

Simple example of LOCTR (1) . . . . . . . . . . . . . . . . . .


Simple example of LOCTR (2) . . . . . . . . . . . . . . . . . .
Simple example of LOCTR (3) . . . . . . . . . . . . . . . . . .
A program fragment using LOCTR for reorganization . . . . .
Organizing a program to minimize addressability problems
. .
Organizing a program to minimize addressability problems
. .
Simple example of LOCTR (4) . . . . . . . . . . . . . . . . . .
Example of unexpected LOCTR behavior (1) . . . . . . . . . .
Example of unexpected LOCTR behavior (2) . . . . . . . . . .
Calling ShftRt as an external routine . . . . . . . . . . . . . . .
ShftRt subroutine as a separate assembly . . . . . . . . . . . . .
External references using relative branch instructions . . . . . .
Using WXTRN to test whether a routine was linked . . . . . .
Calling ShftRt as an external routine . . . . . . . . . . . . . . .
ShftRt subroutine in a different CSect
. . . . . . . . . . . . . .
Main program with ENTRY for data . . . . . . . . . . . . . . .
Subroutine using EXTRN to reference data . . . . . . . . . . .
Subroutine using EXTRN and adcons to reference data . . . .
Subroutine with entries for two similar functions . . . . . . . .
Subroutine with two similar functions and some common code
Sample assembly with external symbols . . . . . . . . . . . . . .
External symbol dictionary from sample assembly
. . . . . . .
Program assembled with different SECTALGN options . . . .
Example of ESD listings with different SECTALGN options .
Assigning RMODE and AMODE to a section name . . . . . .
ESD showing RMODE and AMODE of section names . . . .
Example of two source modules to be linked
. . . . . . . . . .
Sketch of object module from source module 1 . . . . . . . . .
Sketch of object module from source module 2 . . . . . . . . .
Composite ESD after reading first object module . . . . . . . .
Composite ESD after loading second object module . . . . . .
Composite ESD after assigning memory addresses
. . . . . . .
Memory layout of loaded program
. . . . . . . . . . . . . . . .
Sample DXD declarations
. . . . . . . . . . . . . . . . . . . . .
External dummy section declaration . . . . . . . . . . . . . . . .
Referencing external dummy items with Q-cons . . . . . . . . .
External dummy items in ESD listing . . . . . . . . . . . . . . .
Separate DXD declaration . . . . . . . . . . . . . . . . . . . . .
Example of a completed External Dummy Section . . . . . . .
. . . . . . . . . .
Retrieving an External Dummy Section item
PL/I technique for loading Pseudo Registers . . . . . . . . . . .
ESDID Translation Table entry for an incoming symbol . . . .
A typical load-time CESD entry . . . . . . . . . . . . . . . . . .
Composite ESD after assigning load module addresses . . . . .
. . . . . . . . . . . . . . . . . . . . . .
Sketch of a load module
A load module after loading . . . . . . . . . . . . . . . . . . . .
Sketch of program object structure
. . . . . . . . . . . . . . . .
Sample program assembled with the GOFF option . . . . . . .
ESD from program assembled with the GOFF option . . . . .
Assigning AMODE to an entry symbol . . . . . . . . . . . . . .
ESD showing AMODE assigned to entry and external symbols
Sample program defining two Sections and three Classes . . . .
Assignment of instructions and data into elements
. . . . . . .
Assembly listing for sample program . . . . . . . . . . . . . . .
External symbol dictionary for sample program . . . . . . . . .
Example of declaring parts in a GOFF class . . . . . . . . . . .
ESD for parts in a GOFF class
. . . . . . . . . . . . . . . . . .
Sketch of virtual memory . . . . . . . . . . . . . . . . . . . . . .
Sample program defining two Sections and three Classes . . . .
Sketch of classes in virtual memory . . . . . . . . . . . . . . . .
z System PSW showing addressing-mode bits . . . . . . . . . .
Important addressing mode bits for BASSM . . . . . . . . . . .

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

Figures

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

797
798
798
798
799
799
800
800
801
805
805
806
806
807
808
808
808
809
810
810
811
811
813
813
814
815
820
820
821
821
822
822
823
824
824
824
824
825
825
826
826
828
828
831
832
833
835
835
836
837
837
837
837
838
838
839
839
842
842
843
844
845

xxv

608.
609.
610.
611.
612.
613.
614.
615.
616.
617.
618.
619.
620.
621.
622.
623.
624.
625.
626.
627.
628.
629.
630.
631.
632.
633.
634.
635.
636.
637.
638.
639.
640.
641.
642.
643.
644.
645.
646.
647.
648.
649.
650.
651.
652.
653.
654.
655.
656.
657.
658.
659.
660.
661.
662.
663.
664.
665.
666.
667.
668.
669.

xxvi

BASSM setting of first-operand register for 24-, 31-, and 64-bit addressing modes
Sketch of residence and addressing modes
. . . . . . . . . . . . . . . . . . . . . .
Example showing why LLGT/LLGTR are necessary . . . . . . . . . . . . . . . .
Example of a dummy control section . . . . . . . . . . . . . . . . . . . . . . . . .
Example using a dummy control section . . . . . . . . . . . . . . . . . . . . . . .
USING Table with two entries, one for a dummy section . . . . . . . . . . . . .
Object code from references to a dummy control section . . . . . . . . . . . . . .
Example using a dummy control section . . . . . . . . . . . . . . . . . . . . . . .
A poor method for describing two instances of a record . . . . . . . . . . . . . .
A better record description with a DSECT . . . . . . . . . . . . . . . . . . . . . .
Ordinary USING statement syntax . . . . . . . . . . . . . . . . . . . . . . . . . .
Copying a field from Old record to New . . . . . . . . . . . . . . . . . . . . . . .
Incorrect addressing with ordinary USING . . . . . . . . . . . . . . . . . . . . . .
Correct but awkward addressing with ordinary USING
. . . . . . . . . . . . . .
Manual coding of base and displacement for a large DSECT . . . . . . . . . . .
Labeled USING statement syntax . . . . . . . . . . . . . . . . . . . . . . . . . . .
Qualified symbol syntax . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Examples of qualifier definitions . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Copying a field with Labeled USINGs . . . . . . . . . . . . . . . . . . . . . . . .
DROP statement for Labeled USING . . . . . . . . . . . . . . . . . . . . . . . .
Concurrently active Ordinary and Labeled USINGs
. . . . . . . . . . . . . . . .
Dummy control section for record address . . . . . . . . . . . . . . . . . . . . . .
Improved definition of a record description
. . . . . . . . . . . . . . . . . . . . .
Mapping a substructure with a second DSECT . . . . . . . . . . . . . . . . . . .
Dependent USING statement syntax . . . . . . . . . . . . . . . . . . . . . . . . .
Anchoring an internal DSECT with a Dependent USING . . . . . . . . . . . . .
Outer DSECT with two nested DSECTs . . . . . . . . . . . . . . . . . . . . . . .
Assembler listing of multiple Dependent USINGs and DSECTs . . . . . . . . .
Three independent data structures with one base register . . . . . . . . . . . . . .
Defining DSECTs for three independent data structures . . . . . . . . . . . . . .
Defining a mapping of three independent but contiguous data structures . . . . .
Example of a message-skeleton CSECT
. . . . . . . . . . . . . . . . . . . . . . .
Example of mapping a CSECT as though it is a DSECT . . . . . . . . . . . . .
Labeled Dependent USING statement syntax . . . . . . . . . . . . . . . . . . . .
Nesting two identical structures within a third . . . . . . . . . . . . . . . . . . . .
Addressing two nested DSECTs with Labeled Dependent USINGs
. . . . . . .
Data in nested DSECTs addressed with Labeled Dependent USINGs . . . . . .
Multiply-Nested Data Structures . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Doubly Nested DSECT definitions . . . . . . . . . . . . . . . . . . . . . . . . . .
Addressing doubly nested DSECT definitions . . . . . . . . . . . . . . . . . . . .
Using the Labeled Dependent USINGs to move data
. . . . . . . . . . . . . . .
Addressing two DCBs with ordinary USINGs . . . . . . . . . . . . . . . . . . . .
Addressing instructions and DCBs with one register
. . . . . . . . . . . . . . . .
Define a personnel-file record
. . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Employee-record Person DSECT . . . . . . . . . . . . . . . . . . . . . . . . . . .
Employee-record Date DSECT . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Employee-record Address DSECT
. . . . . . . . . . . . . . . . . . . . . . . . . .
Employee-record Phone DSECT
. . . . . . . . . . . . . . . . . . . . . . . . . . .
DSECT nesting in an employee record . . . . . . . . . . . . . . . . . . . . . . . .
Anchoring various DSECTs within Employee record . . . . . . . . . . . . . . . .
Manipulating fields within an Employee record . . . . . . . . . . . . . . . . . . .
Addressing DSECTs within Employee record with ordinary USINGs . . . . . .
Comparing dates of birth in Employee record . . . . . . . . . . . . . . . . . . . .
Comparing date fields in different parts of an Employee record . . . . . . . . . .
Copying addresses with an Employee Record . . . . . . . . . . . . . . . . . . . .
Example of a one-dimensional array of halfwords . . . . . . . . . . . . . . . . . .
Sum of array elements with known subscript bounds . . . . . . . . . . . . . . . .
Sum of array elements with unknown subscript bounds . . . . . . . . . . . . . .
Typical arrangement of elements of a matrix . . . . . . . . . . . . . . . . . . . . .
Storing an array in column order
. . . . . . . . . . . . . . . . . . . . . . . . . . .
Storing an array in row order . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Retrieving a specified element of an array
. . . . . . . . . . . . . . . . . . . . . .

Assembler Language Programming for IBM z System Servers

Version 1.00

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

845
849
849
857
857
858
858
858
859
860
860
861
862
862
863
866
866
866
867
867
868
869
869
870
870
871
871
872
872
873
873
873
874
875
876
877
877
877
878
879
880
881
881
882
883
883
883
883
885
884
886
886
886
887
888
894
894
895
896
896
896
897

670.
671.
672.
673.
674.
675.
676.
677.
678.
679.
680.
681.
682.
683.
684.
685.
686.
687.
688.
689.
690.
691.
692.
693.
694.
695.
696.
697.
698.
699.
700.
701.
702.
703.
704.
705.
706.
707.
708.
709.
710.
711.
712.
713.
714.
715.
716.
717.
718.
719.
720.
721.
722.
723.
724.
725.
726.
727.
728.
729.
730.
731.

Retrieving a specified element of an array efficiently


. . . . . . . .
Searching for a matching table entry
. . . . . . . . . . . . . . . . .
Searching for a table entry mapped by a DSECT . . . . . . . . . .
USING Table with two entries, one for a DSECT . . . . . . . . .
Creating a table of addresses . . . . . . . . . . . . . . . . . . . . . .
Creating a better table of addresses . . . . . . . . . . . . . . . . . .
Creating a table of addresses at assembly time . . . . . . . . . . . .
Example of a binary search . . . . . . . . . . . . . . . . . . . . . . .
A stack growing toward higher addresses . . . . . . . . . . . . . . .
A stack implemented as an array . . . . . . . . . . . . . . . . . . . .
Pushing a data item onto a stack
. . . . . . . . . . . . . . . . . . .
Adding top two elements of a stack . . . . . . . . . . . . . . . . . .
A stack growing toward lower addresses . . . . . . . . . . . . . . .
Add top two elements of a stack . . . . . . . . . . . . . . . . . . . .
Sketch of a linked list . . . . . . . . . . . . . . . . . . . . . . . . . .
Inserting an element into a linked list . . . . . . . . . . . . . . . . .
Example of inserting an element into a linked list . . . . . . . . . .
DSECT describing a list element . . . . . . . . . . . . . . . . . . . .
Mapping multiple list elements with Labeled USINGs . . . . . . .
Deleting an element from a linked list . . . . . . . . . . . . . . . . .
Example of deleting an element from a linked list . . . . . . . . . .
Example of deleting an element from a linked list . . . . . . . . . .
Defining a free storage list as an array . . . . . . . . . . . . . . . . .
Initializing a free storage list as an array
. . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . .
Example of a list anchor
DSECT mapping a list anchor . . . . . . . . . . . . . . . . . . . . .
Defining an anchor for a working list . . . . . . . . . . . . . . . . .
Moving a list element from the FSL to the working list . . . . . .
A two-dimensional array to implement a linked list . . . . . . . . .
. .
Initializing a two-dimensional array implementing a linked list
Structure of a queue element . . . . . . . . . . . . . . . . . . . . . .
A queue with several elements . . . . . . . . . . . . . . . . . . . . .
DSECT structure of a typical queue element . . . . . . . . . . . . .
An element to be inserted into a queue . . . . . . . . . . . . . . . .
A queue after insertion of a new element . . . . . . . . . . . . . . .
Instructions to insert a new queue element . . . . . . . . . . . . . .
Insert a new list element with ordinary USINGs
. . . . . . . . . .
Ordinary-USING Code to Insert a New List Element . . . . . . .
Labeled USING example: inserting a new queue element . . . . .
Node of a binary tree . . . . . . . . . . . . . . . . . . . . . . . . . .
DSECT structure of a typical tree element . . . . . . . . . . . . . .
Three nodes of a binary tree . . . . . . . . . . . . . . . . . . . . . .
A growing binary tree with seven nodes
. . . . . . . . . . . . . . .
Entering a new node in a binary tree . . . . . . . . . . . . . . . . .
Retrieving data from a binary tree . . . . . . . . . . . . . . . . . . .
Example of a binary tree of 7 elements . . . . . . . . . . . . . . . .
Example of searching a hash table . . . . . . . . . . . . . . . . . . .
Example of searching a hash table . . . . . . . . . . . . . . . . . . .
Sample macro invocation, Standard form . . . . . . . . . . . . . . .
Generated statements from an OPEN macro . . . . . . . . . . . . .
Sample macro invocation using List form
. . . . . . . . . . . . . .
Generated statements from a List form OPEN macro
. . . . . . .
Sample macro invocation using Execute form . . . . . . . . . . . .
Generated statements from an Execute form OPEN macro . . . .
Sample macro invocation using empty List form . . . . . . . . . .
Generated instructions from empty List form . . . . . . . . . . . .
Sample macro invocation using Execute form . . . . . . . . . . . .
Generated statements from an Execute form OPEN macro . . . .
Another macro invocation using Execute form and same List form
An R-Type macro invocation generating an argument in a register
Generated statements from R-Type macro . . . . . . . . . . . . . .
A macro invocation with arguments in registers . . . . . . . . . . .

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

Figures

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

898
900
901
901
903
903
904
906
909
910
910
910
911
911
913
913
913
914
914
914
914
914
915
915
916
916
916
917
917
918
919
920
920
920
920
921
921
921
922
923
923
923
924
924
926
926
928
929
937
938
938
939
939
939
939
939
939
939
940
940
940
940

xxvii

732.
733.
734.
735.
736.
737.
738.
739.
740.
741.
742.
743.
744.
745.
746.
747.
748.
749.
750.
751.
752.
753.
754.
755.
756.
757.
758.
759.
760.
761.
762.
763.
764.
765.
766.
767.
768.
769.
770.
771.
772.
773.
774.
775.

Generated statements from a Standard-form macro with arguments in registers


A Standard macro invocation specifying MODE=31 . . . . . . . . . . . . . .
. . . . .
Generated statements from a Standard-for macro with MODE=31
Example of a mixed-case positional macro argument . . . . . . . . . . . . . .
Example of mixed-case keyword macro arguments . . . . . . . . . . . . . . .
Example of mixed-case keyword macro arguments . . . . . . . . . . . . . . .
Sample ABEND macro . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . .
Generated statements from an ABEND macro
Sample R=type GETMAIN request . . . . . . . . . . . . . . . . . . . . . . .
Expansion of a sample R-type GETMAIN request . . . . . . . . . . . . . . .
Expansion of a sample VRU-type GETMAIN request . . . . . . . . . . . . .
Example of an R-type FREEMAIN macro . . . . . . . . . . . . . . . . . . .
Sample STORAGE OBTAIN request . . . . . . . . . . . . . . . . . . . . . .
Example of a STORAGE OBTAIN macro expansion . . . . . . . . . . . . .
Sample STORAGE RELEASE request
. . . . . . . . . . . . . . . . . . . . .
Example of a STORAGE RELEASE macro expansion . . . . . . . . . . . .
A Data Set with records you want to read . . . . . . . . . . . . . . . . . . . .
You submitted a job with a program to read the records . . . . . . . . . . . .
Your program, loaded into memory before execution . . . . . . . . . . . . . .
Your program after executing the OPEN macro . . . . . . . . . . . . . . . . .
Your program after executing the GET macro . . . . . . . . . . . . . . . . . .
Your program after executing the CLOSE macro . . . . . . . . . . . . . . . .
Example of typical DCB parameters
. . . . . . . . . . . . . . . . . . . . . . .
Unblocked and blocked F-type record and block formats
. . . . . . . . . . .
Unblocked and blocked V-type record and block formats . . . . . . . . . . .
U-type block formats . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Completion of a DCB during OPEN processing
. . . . . . . . . . . . . . . .
DCBD operands . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
DCBD operands . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . .
Using IHADCB to map two different DCBs simultaneously
A complete sample program . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Instruction cycle with interruptions . . . . . . . . . . . . . . . . . . . . . . . .
Establishing a program interruption exit . . . . . . . . . . . . . . . . . . . . .
Expansion of an ESPIE macro establishing a program interruption exit . . .
Terminating a program interruption exit . . . . . . . . . . . . . . . . . . . . .
Expansion of an ESPIE macro terminating a program interruption exit . . .
ESA/390-mode old PSW in EPIE . . . . . . . . . . . . . . . . . . . . . . . . .
Sketch of interruption handling control flow . . . . . . . . . . . . . . . . . . .
A simple ESTAE macro. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Skeleton form of a reenterable program . . . . . . . . . . . . . . . . . . . . . .
I/O macros in a reenterable program . . . . . . . . . . . . . . . . . . . . . . .
Assembly listing for a simple reenterable program . . . . . . . . . . . . . . . .
Example of a reenterable, recursive routine . . . . . . . . . . . . . . . . . . . .
Assembly listing of the reenterable recursive routine
. . . . . . . . . . . . . .

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

940
940
941
941
941
941
942
942
944
944
945
946
946
946
946
947
947
948
949
949
950
951
954
954
954
954
955
955
956
956
957
958
958
959
959
959
960
962
964
970
972
973
976
976

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

Tables
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.

xxviii

Binary, decimal, and hexadecimal . . . . . . .


Multiples of powers of sixteen (part 1 of 2)
.
Multiples of powers of sixteen (part 2 of 2)
.
Examples of twos complement representation
Examples of sign extension . . . . . . . . . . .
RR-type instruction format . . . . . . . . . . .
RX-type and RS-type instruction format . . .
SI-type instruction format
. . . . . . . . . . .
SS-type instruction format . . . . . . . . . . .
Instruction Length Code and instruction types
General instruction classifications . . . . . . .

Assembler Language Programming for IBM z System Servers

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

Version 1.00

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

20
22
23
31
32
54
54
54
55
56
57

12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.

Punched-card image of a RETURN statement


. . . . . . . . . . . . . . .
Assembler Language EBCDIC character representation
. . . . . . . . . .
Differences between Assembler Language and high-level language symbols
Expressions with absolute and relocatable terms . . . . . . . . . . . . . . .
Typical RR-type instructions . . . . . . . . . . . . . . . . . . . . . . . . . .
RR-type instruction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Typical RX-type instructions . . . . . . . . . . . . . . . . . . . . . . . . . .
RX-type instruction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Operands of RX-type instructions . . . . . . . . . . . . . . . . . . . . . . .
Typical RS- and SI-type instructions . . . . . . . . . . . . . . . . . . . . .
Typical RS-type instruction
. . . . . . . . . . . . . . . . . . . . . . . . . .
Operands of RS-type instructions . . . . . . . . . . . . . . . . . . . . . . .
Typical SI-type instruction . . . . . . . . . . . . . . . . . . . . . . . . . . .
Operands of SI-type instructions . . . . . . . . . . . . . . . . . . . . . . . .
Typical SS-type instructions . . . . . . . . . . . . . . . . . . . . . . . . . .
Typical type SS-1 instruction with one length field . . . . . . . . . . . . .
Operands of type SS-1 single-length instructions . . . . . . . . . . . . . . .
Typical type SS-2 instruction with two length fields . . . . . . . . . . . . .
Operands of type SS-2 two-length instructions . . . . . . . . . . . . . . . .
Examples of truncated and padded constants . . . . . . . . . . . . . . . . .
Truncation/padding rules for some DC operands . . . . . . . . . . . . . .
Truncation and padding rules for some DC operands with extended types
Load/Store instructions for 32-bit general registers
. . . . . . . . . . . . .
Format of an RX-type instruction . . . . . . . . . . . . . . . . . . . . . . .
Multiple load/store instructions for 32-bit general registers . . . . . . . . .
RS-type instruction format . . . . . . . . . . . . . . . . . . . . . . . . . . .
Halfword load/store instructions for 32-bit general registers . . . . . . . .
Character insert/store instructions for 32-bit general registers
. . . . . . .
Insert/Store characters under mask instructions for 32-bit general registers
. . . . . . . . . . . . . .
RS-type instruction format for ICM and STCM
CC settings after ICM instruction . . . . . . . . . . . . . . . . . . . . . . .
Register/register instructions for 32-bit general registers . . . . . . . . . . .
Action of five RR-type general register instructions . . . . . . . . . . . . .
Condition Code settings . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Register/storage instructions for 64-bit general registers . . . . . . . . . . .
RXY-type instruction format . . . . . . . . . . . . . . . . . . . . . . . . . .
RSY-type instruction format.
. . . . . . . . . . . . . . . . . . . . . . . . .
RRE-type instruction format . . . . . . . . . . . . . . . . . . . . . . . . . .
Register/register instructions for 64-bit general registers . . . . . . . . . . .
Action of five RR-type 64-bit general register instructions . . . . . . . . .
Load and Test instructions . . . . . . . . . . . . . . . . . . . . . . . . . . .
Register/register instructions for 64-bit general registers . . . . . . . . . . .
Action of 32-bit-to-64-bit general register instructions
. . . . . . . . . . .
Other general register load instructions . . . . . . . . . . . . . . . . . . . .
Summary of instructions discussed in this section . . . . . . . . . . . . . .
BCR instruction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
BC instruction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Mask bits and corresponding CC values . . . . . . . . . . . . . . . . . . .
CNOP operands . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Extended branch mnemonics and their branch mask values . . . . . . . .
Frequently used add and subtract instructions . . . . . . . . . . . . . . . .
CC settings for arithmetic add and subtract instructions . . . . . . . . . .
Arithmetic compare instructions . . . . . . . . . . . . . . . . . . . . . . . .
CC settings after arithmetic comparisons . . . . . . . . . . . . . . . . . . .
Logical arithmetic instructions . . . . . . . . . . . . . . . . . . . . . . . . .
CC settings for logical add and subtract instructions
. . . . . . . . . . . .
CC indications for logical addition and subtraction . . . . . . . . . . . . .
CC settings after logical addition . . . . . . . . . . . . . . . . . . . . . . . .
CC settings after logical subtraction . . . . . . . . . . . . . . . . . . . . . .
Logical arithmetic instructions with carry/borrow . . . . . . . . . . . . . .
Instructions for mixed-length operands . . . . . . . . . . . . . . . . . . . .
Arithmetic compare instructions . . . . . . . . . . . . . . . . . . . . . . . .

. . .
. . .
. .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

Tables

. .
. .
. .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

80
89
96
101
108
109
110
110
111
113
113
114
114
114
115
115
115
116
116
154
155
160
181
181
182
182
184
186
187
188
189
189
190
190
192
192
192
194
195
195
195
196
196
198
202
207
207
207
210
212
218
219
223
223
225
225
226
229
229
230
231
233

xxix

74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.

xxx

CC settings after logical comparisons . . . . . . . . . . . . . . . . . . . . . . . . .


IPM and SPM instructions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Program Mask bits
Summary of instructions discussed in this section . . . . . . . . . . . . . . . . . .
General register shift instructions
. . . . . . . . . . . . . . . . . . . . . . . . . . .
RS-type shift instruction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
RSY-type instruction format . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . .
CC settings for arithmetic shift instructions
Summary of shift instructions discussed in this section . . . . . . . . . . . . . . .
Binary integer multiply instructions . . . . . . . . . . . . . . . . . . . . . . . . . .
Double-length arithmetic multiply instructions
. . . . . . . . . . . . . . . . . . .
Single-length arithmetic multiply instructions
. . . . . . . . . . . . . . . . . . . .
Logical multiply instructions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Binary divide instructions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Arithmetic divide instructions
. . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Binary divide instructions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Summary of multiply instructions discussed in this section . . . . . . . . . . . . .
Summary of divide instructions discussed in this section . . . . . . . . . . . . . .
Logical operations involving general registers
. . . . . . . . . . . . . . . . . . . .
CC settings by logical instructions . . . . . . . . . . . . . . . . . . . . . . . . . . .
Summary of the logical operations AND, OR, XOR . . . . . . . . . . . . . . . .
Logical-operation instructions discussed in this section . . . . . . . . . . . . . . .
Format of RXY- and RSY-type instructions . . . . . . . . . . . . . . . . . . . . .
Format of R-I instructions with 16-bit immediate operands . . . . . . . . . . . .
Format of R-I instructions with 32-bit immediate operands . . . . . . . . . . . .
PSW addressing-mode bits . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Load Address instructions
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Load Address instructions described in this section . . . . . . . . . . . . . . . . .
RI-type instruction
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
RIL-type instruction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Insert-Immediate instructions
. . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Load and insert instructions with immediate operands . . . . . . . . . . . . . . .
Arithmetic-immediate add and subtract instructions . . . . . . . . . . . . . . . . .
Arithmetic-immediate compare instructions . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . .
Arithmetic-immediate multiply instructions
AND-immediate instructions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
OR-immediate instructions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
XOR-immediate instructions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Load and insert instructions with immediate operands . . . . . . . . . . . . . . .
Arithmetic instructions with immediate operands . . . . . . . . . . . . . . . . . .
Logical instructions with immediate operands . . . . . . . . . . . . . . . . . . . .
Format of the BRC instruction . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Format of the BRCL instruction
. . . . . . . . . . . . . . . . . . . . . . . . . . .
Extended branch relative on condition mnemonics and their branch mask values
Branch on count instructions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Extended mnemonics for branch relative on count instructions . . . . . . . . . .
Branch on index instructions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
RS-type BXH and BXLE instructions . . . . . . . . . . . . . . . . . . . . . . . .
RSY-type BXHG and BXLEG instructions . . . . . . . . . . . . . . . . . . . . .
RSI-type BRXH and BRXLE instructions . . . . . . . . . . . . . . . . . . . . . .
RIE-type BRXHG and BRXLG instructions . . . . . . . . . . . . . . . . . . . .
Extended mnemonics for branch relative on index instructions . . . . . . . . . .
Branch relative on condition instructions . . . . . . . . . . . . . . . . . . . . . . .
Branch instructions for loop control . . . . . . . . . . . . . . . . . . . . . . . . . .
SI-type instruction format
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
SIY-type instruction format
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
SI-type instruction actions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Move Immediate instructions
. . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Logical Storage-Immediate instructions . . . . . . . . . . . . . . . . . . . . . . . .
CC settings by SI-type logical instructions . . . . . . . . . . . . . . . . . . . . . .
Compare Immediate instructions
. . . . . . . . . . . . . . . . . . . . . . . . . . .
CC settings after CLI instruction
. . . . . . . . . . . . . . . . . . . . . . . . . . .

Assembler Language Programming for IBM z System Servers

Version 1.00

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

233
235
236
237
242
243
243
253
261
264
265
268
270
274
275
279
283
283
288
290
298
298
302
304
304
308
309
314
318
318
319
320
322
323
323
324
325
325
327
327
327
330
330
331
335
335
342
342
342
342
342
344
350
350
354
354
355
355
355
356
356
357

136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
171.
172.
173.
174.
175.
176.
177.
178.
179.
180.
181.
182.
183.
184.
185.
186.
187.
188.
189.
190.
191.
192.
193.
194.
195.
196.
197.

Storage-Immediate instructions
. . . . . . . . . . . . . . . . . . . . . . .
CC settings after TM instruction . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . .
Storage-Immediate instructions
Basic character-handling instructions . . . . . . . . . . . . . . . . . . . .
Format of single-length SS-type instructions . . . . . . . . . . . . . . . .
Instruction types and operand formats . . . . . . . . . . . . . . . . . . .
SS-type instructions with explicit length
. . . . . . . . . . . . . . . . . .
SS-type instructions with implied length . . . . . . . . . . . . . . . . . .
Determining the Length Specification Byte . . . . . . . . . . . . . . . . .
Condition Code settings for TRT and TRTR instructions . . . . . . . .
Execute instructions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Modifiable portions of typical EX target instructions . . . . . . . . . . .
Operands of single-length SS-type instructions . . . . . . . . . . . . . . .
Basic instructions for data in storage
. . . . . . . . . . . . . . . . . . . .
Character-handling instructions using padding characters . . . . . . . . .
CC settings after MVCL . . . . . . . . . . . . . . . . . . . . . . . . . . .
CC settings after CLCL . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Format of MVCLE and CLCLE instructions . . . . . . . . . . . . . . .
CC settings after MVCLE
. . . . . . . . . . . . . . . . . . . . . . . . . .
CC settings after CLCLE . . . . . . . . . . . . . . . . . . . . . . . . . . .
Character-handling instructions for terminated strings
. . . . . . . . . .
Format of RRE-type instructions . . . . . . . . . . . . . . . . . . . . . .
CC settings for SRST instruction . . . . . . . . . . . . . . . . . . . . . .
CC settings for MVST instruction . . . . . . . . . . . . . . . . . . . . . .
CC settings for CLST instruction . . . . . . . . . . . . . . . . . . . . . .
CC settings for TRE instruction . . . . . . . . . . . . . . . . . . . . . . .
Compare Until Substring Equal instruction
. . . . . . . . . . . . . . . .
Condition Code settings by CUSE
. . . . . . . . . . . . . . . . . . . . .
Results of examples using the CUSE instruction
. . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . .
Extended instructions for character data
Old BCD character representation . . . . . . . . . . . . . . . . . . . . . .
Sample EBCDIC characters with varying code points among code pages
7-bit ASCII character representation
. . . . . . . . . . . . . . . . . . . .
Japanese DBCS assignments . . . . . . . . . . . . . . . . . . . . . . . . .
DBCS encoding . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Sample Unicode assignments . . . . . . . . . . . . . . . . . . . . . . . . .
Unicode string instructions . . . . . . . . . . . . . . . . . . . . . . . . . .
CC settings for SRSTU instruction . . . . . . . . . . . . . . . . . . . . .
CC settings after MVCLU . . . . . . . . . . . . . . . . . . . . . . . . . .
CC settings after CLCLU . . . . . . . . . . . . . . . . . . . . . . . . . . .
RRE-type instruction . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
RRF-format instruction with an optional operand . . . . . . . . . . . .
Unicode translate instructions . . . . . . . . . . . . . . . . . . . . . . . .
Arguments and translate tables for TRxx instructions . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . .
Registers used by TRxx instructions
Condition Code settings for TRxx instructions
. . . . . . . . . . . . . .
Unicode format conversion instructions . . . . . . . . . . . . . . . . . . .
CC settings after Unicode format conversion instructions
. . . . . . . .
Byte-reversing load and store instructions
. . . . . . . . . . . . . . . . .
Extended instructions for Unicode data . . . . . . . . . . . . . . . . . . .
Unicode-based translate instructions . . . . . . . . . . . . . . . . . . . . .
Unicode format conversion instructions . . . . . . . . . . . . . . . . . . .
Summary of byte-reversing instructions . . . . . . . . . . . . . . . . . . .
Basic packed and zoned decimal instructions . . . . . . . . . . . . . . . .
Examples of zoned decimal data . . . . . . . . . . . . . . . . . . . . . . .
Punched-card image of two numbers, + 12345 and 67890
. . . . . . .
Examples of packed decimal data . . . . . . . . . . . . . . . . . . . . . .
Format of two-length SS-type instructions . . . . . . . . . . . . . . . . .
Operands of two-length SS-type instructions . . . . . . . . . . . . . . . .
Format of PKA and PKU instructions . . . . . . . . . . . . . . . . . . .
Format of UNPKA and UNPKU instructions
. . . . . . . . . . . . . .
CC settings after UNPKA, UNPKU instructions . . . . . . . . . . . . .

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

Tables

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

358
358
366
367
367
369
369
370
371
385
390
395
397
398
404
406
408
411
413
414
416
416
417
418
420
422
424
425
425
426
430
431
432
434
435
438
440
440
441
442
442
442
443
444
444
444
447
447
449
451
451
452
452
454
456
457
460
463
463
472
473
474

xxxi

198.
199.
200.
201.
202.
203.
204.
205.
206.
207.
208.
209.
210.
211.
212.
213.
214.
215.
216.
217.
218.
219.
220.
221.
222.
223.
224.
225.
226.
227.
228.
229.
230.
231.
232.
233.
234.
235.
236.
237.
238.
239.
240.
241.
242.
243.
244.
245.
246.
247.
248.
249.
250.
251.
252.
253.
254.
255.
256.
257.
258.
259.

xxxii

Instructions for moving numeric and zone digits . . . . . . . . . . . . . . . . . .


Instructions for packing and unpacking data . . . . . . . . . . . . . . . . . . . .
CC settings for decimal addition and subtraction . . . . . . . . . . . . . . . . .
CC setting after decimal comparison
. . . . . . . . . . . . . . . . . . . . . . . .
Packed decimal arithmetic instructions . . . . . . . . . . . . . . . . . . . . . . .
Format of the TP instruction
. . . . . . . . . . . . . . . . . . . . . . . . . . . .
Operand formats for TP instruction . . . . . . . . . . . . . . . . . . . . . . . . .
CC settings for the TP instruction . . . . . . . . . . . . . . . . . . . . . . . . . .
CC settings by the ZAP, AP, and SP instructions . . . . . . . . . . . . . . . . .
CC setting by the CP instruction
. . . . . . . . . . . . . . . . . . . . . . . . . .
Format of the SRP instruction . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Summary of decimal instruction behavior
. . . . . . . . . . . . . . . . . . . . .
Instructions used for converting and formatting packed decimal . . . . . . . . .
Format of the ED and EDMK instructions . . . . . . . . . . . . . . . . . . . .
CC settings after ED, EDMK . . . . . . . . . . . . . . . . . . . . . . . . . . . .
ED and EDMK treatment of pattern characters . . . . . . . . . . . . . . . . . .
Basic floating-point instructions . . . . . . . . . . . . . . . . . . . . . . . . . . .
Instructions copying data between FPRs . . . . . . . . . . . . . . . . . . . . . .
Floating-point Load Zero instructions
. . . . . . . . . . . . . . . . . . . . . . .
Instructions moving data between FPRs and GPRs
. . . . . . . . . . . . . . .
Copy Sign instruction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Basic Load/Store instructions for floating-point operands . . . . . . . . . . . .
Instructions moving operands between GPRs and FPRs . . . . . . . . . . . . .
Hexadecimal floating-point data representations . . . . . . . . . . . . . . . . . .
Unnormalized and normalized short hexadecimal floating-point numbers . . .
Short hexadecimal floating-point numbers . . . . . . . . . . . . . . . . . . . . .
Long hexadecimal floating-point numbers . . . . . . . . . . . . . . . . . . . . .
Extended hexadecimal floating-point numbers . . . . . . . . . . . . . . . . . . .
Assembled hexadecimal floating-point constants . . . . . . . . . . . . . . . . . .
Hex floating-point constants with decimal exponents . . . . . . . . . . . . . . .
Length-modified hexadecimal floating-point constants . . . . . . . . . . . . . .
Hexadecimal floating-point constants with modifiers . . . . . . . . . . . . . . .
Hexadecimal floating-point rounding modes with subtype H
. . . . . . . . . .
Symbolic hexadecimal floating-point constants
. . . . . . . . . . . . . . . . . .
Difficult hexadecimal floating-point conversion values . . . . . . . . . . . . .
Data-moving hexadecimal floating-point instructions . . . . . . . . . . . . . . .
Hexadecimal floating-point Multiply instructions . . . . . . . . . . . . . . . . .
Summary of hexadecimal floating-point multiplication results . . . . . . . . . .
Hexadecimal floating-point Divide instructions
. . . . . . . . . . . . . . . . . .
Hexadecimal floating-point Halve instructions . . . . . . . . . . . . . . . . . . .
Hexadecimal floating-point Add/Subtract instructions
. . . . . . . . . . . . . .
Hexadecimal floating-point Compare instructions . . . . . . . . . . . . . . . . .
CC settings for hexadecimal floating-point comparison . . . . . . . . . . . . . .
Hexadecimal floating-point Round instructions . . . . . . . . . . . . . . . . . .
Hexadecimal floating-point Load Lengthened instructions . . . . . . . . . . . .
Hexadecimal floating-point FPR/GPR conversion instructions . . . . . . . . .
Format of HFP to fixed binary instructions . . . . . . . . . . . . . . . . . . . .
Rounding modifiers for HFP-to-binary conversion . . . . . . . . . . . . . . . .
CC settings for HFP-to-binary conversion . . . . . . . . . . . . . . . . . . . . .
Instructions moving/converting binary and hexadecimal floating-point operands
Hexadecimal floating-point instructions generating floating-point integers . . .
Hexadecimal floating-point Square Root instructions . . . . . . . . . . . . . . .
Hexadecimal floating-point Multiply and add/subtract instructions . . . . . . .
Format of RRF-type HFP multiply and add/subtract instructions . . . . . . .
Format of RXF-type multiply and add/subtract instructions
. . . . . . . . . .
Hexadecimal floating-point Move/Test instructions . . . . . . . . . . . . . . . .
Hexadecimal floating-point Multiply instructions . . . . . . . . . . . . . . . . .
Hexadecimal floating-point Divide instructions
. . . . . . . . . . . . . . . . . .
Hexadecimal floating-point Add, Subtract, and Compare instructions . . . . .
Hexadecimal floating-point Round instructions . . . . . . . . . . . . . . . . . .
Hexadecimal floating-point Lengthening instructions . . . . . . . . . . . . . . .
Convert hexadecimal floating-point to binary instructions . . . . . . . . . . . .

Assembler Language Programming for IBM z System Servers

Version 1.00

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

476
476
479
480
489
490
490
490
491
496
503
521
522
526
534
536
555
556
556
557
557
558
558
574
575
575
576
576
578
578
579
581
582
583
583
584
586
588
590
591
593
602
602
603
605
606
608
608
608
609
612
613
614
614
614
617
617
617
618
618
618
618

260.
261.
262.
263.
264.
265.
266.
267.
268.
269.
270.
271.
272.
273.
274.
275.
276.
277.
278.
279.
280.
281.
282.
283.
284.
285.
286.
287.
288.
289.
290.
291.
292.
293.
294.
295.
296.
297.
298.
299.
300.
301.
302.
303.
304.
305.
306.
307.
308.
309.
310.
311.
312.
313.
314.
315.
316.
317.
318.
319.
320.
321.

Convert binary to hexadecimal floating-point instructions . . . . . . . . . .


Form hexadecimal floating-point integer instructions . . . . . . . . . . . . .
Hexadecimal floating-point Square Root instructions . . . . . . . . . . . . .
Hexadecimal floating-point Multiply-Add/Subtract instructions . . . . . . .
Binary floating-point data representations
. . . . . . . . . . . . . . . . . . .
Examples of short-precision binary floating-point normal values . . . . . .
Examples of short-precision binary floating-point denormalized values . . .
Examples of short-precision binary floating-point special values . . . . . . .
Nominal-value operands for binary floating-point special values
. . . . . .
Assembled binary floating-point special-value constants . . . . . . . . . . .
Minimum bit lengths for binary floating-point constants . . . . . . . . . . .
Binary floating-point DXC values . . . . . . . . . . . . . . . . . . . . . . . .
Binary floating-point FPC register control instructions . . . . . . . . . . . .
Invalid operation binary floating-point exception . . . . . . . . . . . . . . .
Divide by zero binary floating-point exception . . . . . . . . . . . . . . . . .
Exponent overflow binary floating-point exception . . . . . . . . . . . . . .
Exponent underflow binary floating-point exception . . . . . . . . . . . . .
Inexact result binary floating-point exception
. . . . . . . . . . . . . . . . .
BFP overflow/underflow scale factors . . . . . . . . . . . . . . . . . . . . . .
Binary floating-point Test Data Class instructions . . . . . . . . . . . . . . .
Test Data Class second-operand bits . . . . . . . . . . . . . . . . . . . . . .
Test Data Class second-operand test-bit/tested-value correspondence . . . .
Binary floating-point RR-type data movement instructions . . . . . . . . .
CC settings for BFP data movement instructions . . . . . . . . . . . . . . .
Binary floating-point Multiply instructions . . . . . . . . . . . . . . . . . . .
Binary floating-point Divide instructions . . . . . . . . . . . . . . . . . . . .
Binary floating-point Add and Subtract instructions
. . . . . . . . . . . . .
CC settings after BFP add/subtract instructions . . . . . . . . . . . . . . . .
Binary floating-point Compare instructions
. . . . . . . . . . . . . . . . . .
CC settings for BFP comparisons . . . . . . . . . . . . . . . . . . . . . . . .
Binary floating-point Compare and Signal instructions . . . . . . . . . . . .
Binary floating-point Round instructions . . . . . . . . . . . . . . . . . . . .
Binary floating-point Lengthening instructions . . . . . . . . . . . . . . . . .
Binary integer to binary floating-point conversion instructions
. . . . . . .
Binary floating-point to integer conversion instructions . . . . . . . . . . . .
Format of BFP Convert To Fixed instructions . . . . . . . . . . . . . . . .
Rounding modifier for BFP convert to fixed instructions
. . . . . . . . . .
CC settings after convert to binary instructions . . . . . . . . . . . . . . . .
Load floating-point integer instructions . . . . . . . . . . . . . . . . . . . . .
Rounding mode modifiers for BFP load integer instructions . . . . . . . . .
Binary floating-point Divide to Integer instructions . . . . . . . . . . . . . .
Format of BFP Divide to Integer instructions . . . . . . . . . . . . . . . . .
CC settings after divide to integer instructions . . . . . . . . . . . . . . . . .
Binary floating-point Square Root instructions
. . . . . . . . . . . . . . . .
Binary floating-point Multiply and Add/Subtract instructions . . . . . . . .
Summary of binary floating-point instructions with uniform operand lengths
Binary floating-point Multiply instructions . . . . . . . . . . . . . . . . . . .
Binary floating-point Round instructions . . . . . . . . . . . . . . . . . . . .
Binary floating-point Lengthening instructions . . . . . . . . . . . . . . . . .
Convert binary floating-point to binary integer instructions . . . . . . . . .
Convert binary integer to binary floating-point instructions . . . . . . . . .
Summary of binary floating-point operations and exceptions
. . . . . . . .
Decimal floating-point data representations
. . . . . . . . . . . . . . . . . .
Declet encoding for BCD digits . . . . . . . . . . . . . . . . . . . . . . . . .
Converting decimal floating-point declets to BCD digits . . . . . . . . . . .
First five bits of special-values Combination Field
. . . . . . . . . . . . . .
First 5 bits of finite-value Combination Field . . . . . . . . . . . . . . . . .
Properties of decimal floating-point representations . . . . . . . . . . . . . .
Assembled decimal floating-point special-value constants
. . . . . . . . . .
Examples of decimal floating-point short precision zeros . . . . . . . . . . .
Assembler rounding-mode suffixes for DFP constants . . . . . . . . . . . .
Decimal floating-point Test Data Class instructions . . . . . . . . . . . . . .

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

Tables

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

618
619
619
619
625
627
627
628
631
631
632
637
638
638
639
639
639
639
640
641
641
641
642
642
644
646
648
648
649
649
650
651
651
653
653
653
654
654
655
656
656
656
657
658
659
660
661
661
661
662
662
662
670
672
672
674
674
675
677
677
677
680

xxxiii

322.
323.
324.
325.
326.
327.
328.
329.
330.
331.
332.
333.
334.
335.
336.
337.
338.
339.
340.
341.
342.
343.
344.
345.
346.
347.
348.
349.
350.
351.
352.
353.
354.
355.
356.
357.
358.
359.
360.
361.
362.
363.
364.
365.
366.
367.
368.
369.
370.
371.
372.
373.
374.
375.
376.
377.
378.
379.
380.
381.
382.
383.

xxxiv

DFP Test Data Class second-operand bits . . . . . . . . . . . . . . . . . . . .


Test Data Class test-bit vs. tested-class correspondence . . . . . . . . . . . . .
Example of DFP rounding modes . . . . . . . . . . . . . . . . . . . . . . . . .
Preferred quanta for some decimal floating-point operations . . . . . . . . . .
Decimal floating-point additional DXC value . . . . . . . . . . . . . . . . . .
Decimal floating-point quantum exception . . . . . . . . . . . . . . . . . . . .
Decimal floating-point scale factors for exponent spills . . . . . . . . . . . . .
Copy Sign instruction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Instructions moving data between FPRs and GPRs
. . . . . . . . . . . . . .
Instructions copying data between FPRs . . . . . . . . . . . . . . . . . . . . .
Decimal floating-point basic arithmetic instructions . . . . . . . . . . . . . . .
Format of DFP arithmetic instructions . . . . . . . . . . . . . . . . . . . . . .
Format of DFP arithmetic instructions with rounding mask . . . . . . . . . .
Instruction-specific rounding mask values
. . . . . . . . . . . . . . . . . . . .
CC settings for Add/Subtract instructions
. . . . . . . . . . . . . . . . . . . .
CC settings for Compare instructions . . . . . . . . . . . . . . . . . . . . . . .
Decimal floating-point Compare instructions
. . . . . . . . . . . . . . . . . .
Decimal floating-point Compare and Signal instructions . . . . . . . . . . . .
Decimal floating-point Compare Biased Exponent instructions . . . . . . . .
CC settings for Compare Biased Exponent instructions
. . . . . . . . . . . .
Decimal floating-point convert to/from fixed binary instructions . . . . . . .
Format of Convert to Fixed Binary instructions . . . . . . . . . . . . . . . . .
Format of Convert to Fixed Binary instructions . . . . . . . . . . . . . . . . .
CC settings for Convert to Fixed instructions . . . . . . . . . . . . . . . . . .
Decimal floating-point convert to/from signed packed decimal instructions .
Format of Convert to Signed Packed instructions . . . . . . . . . . . . . . . .
Decimal floating-point convert to/from unsigned packed decimal instructions
Instructions converting between decimal floating-point and zoned decimal
.
Format of DFP/zoned decimal conversion instructions . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . .
Condition Code settings for Convert to Zoned
Decimal floating-point Load and Test instructions . . . . . . . . . . . . . . .
CC setting after DFP Load and Test instructions . . . . . . . . . . . . . . . .
Instructions copying/complementing data between FPRs
. . . . . . . . . . .
Decimal floating-point Load Floating-point Integer instructions
. . . . . . .
Format of Load FP Integer instructions . . . . . . . . . . . . . . . . . . . . .
Decimal floating-point Load Lengthened instructions . . . . . . . . . . . . . .
Load Lengthened special operand control mask . . . . . . . . . . . . . . . . .
Decimal floating-point rounding/lengthening instructions
. . . . . . . . . . .
Decimal floating-point Set Rounding Mode instruction
. . . . . . . . . . . .
. . . . .
Decimal floating-point Insert/Extract Biased Exponent instructions
Extracted Biased Exponent for DFP special values . . . . . . . . . . . . . . .
DFP Insert Biased Exponent results . . . . . . . . . . . . . . . . . . . . . . . .
Decimal floating-point Extract Significance instructions
. . . . . . . . . . . .
Decimal floating-point Shift Significand instructions . . . . . . . . . . . . . .
Format of DFP shift instructions . . . . . . . . . . . . . . . . . . . . . . . . .
Decimal floating-point Quantize instructions . . . . . . . . . . . . . . . . . . .
Format of decimal floating-point Quantize instructions . . . . . . . . . . . . .
Decimal floating-point Reround instructions . . . . . . . . . . . . . . . . . . .
Decimal floating-point Test Data Group instructions . . . . . . . . . . . . . .
Test Data Group second-operand bits
. . . . . . . . . . . . . . . . . . . . . .
DFP Test Data Class and Test Data Group instructions . . . . . . . . . . . .
DFP Arithmetic and related instructions . . . . . . . . . . . . . . . . . . . . .
DFP length and type conversion instructions
. . . . . . . . . . . . . . . . . .
DFP rounding and lengthening instructions . . . . . . . . . . . . . . . . . . .
DFP data-loading instructions . . . . . . . . . . . . . . . . . . . . . . . . . . .
Instructions copying between FPRs and GPRs . . . . . . . . . . . . . . . . .
Instruction setting decimal rounding mode . . . . . . . . . . . . . . . . . . . .
Non-canonical declets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Summary of z System floating-point representations . . . . . . . . . . . . . .
Adding 0.1 in hexadecimal, binary, and decimal floating-point . . . . . . . . .
Exception behavior for hexadecimal floating-point
. . . . . . . . . . . . . . .
Exception behavior for binary and decimal floating-point
. . . . . . . . . . .

Assembler Language Programming for IBM z System Servers

Version 1.00

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

680
681
682
684
685
685
685
686
686
686
687
687
688
688
690
691
691
692
692
692
693
694
694
695
696
696
697
699
699
700
701
701
701
702
702
702
703
703
704
705
706
706
706
707
707
708
708
710
712
712
718
718
718
718
719
719
719
719
725
727
727
727

384.
385.
386.
387.
388.
389.
390.
391.
392.
393.
394.
395.
396.
397.
398.
399.
400.
401.
402.
403.
404.
405.
406.
407.
408.
409.
410.
411.
412.
413.
414.
415.
416.
417.
418.
419.
420.
421.
422.
423.
424.
425.
426.
427.
428.
429.
430.
431.
432.
433.
434.
435.
436.
437.
438.
439.
440.
441.
442.
443.
444.

Length modifiers of floating-point constants . . . . . . . . . . . . .


Assembler rounding-mode suffixes for floating-point constants . .
. . . . .
Internal precision required for faithful In-Out conversion
Decimal precision required for faithful Out-In conversion . . . . .
Perform Floating-Point Operation instruction . . . . . . . . . . . .
Laws of real and realistic arithmetic . . . . . . . . . . . . . . . . . .
Examples of hexadecimal floating-point pseudo-zeros . . . . . . . .
. . . . . . . . . .
Examples of other floating-point representations
Equivalent decimal and floating-point precisions
. . . . . . . . . .
Branch and Save instructions . . . . . . . . . . . . . . . . . . . . . .
Standard (Format-0) Save Area . . . . . . . . . . . . . . . . . . . .
Standard Format-4 save area . . . . . . . . . . . . . . . . . . . . . .
Standard Format-5 save area . . . . . . . . . . . . . . . . . . . . . .
AMODE values . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
R M O D E values . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Default AMODE and RMODE values . . . . . . . . . . . . . . . .
Valid combinations of AMODE and RMODE values . . . . . . .
Differences in linking COMMONs and External dummy items . .
ESD symbol search types . . . . . . . . . . . . . . . . . . . . . . . .
Matching existing CESD SD symbol to incoming symbols
. . . .
Matching existing CESD LD symbol to incoming symbols . . . .
Matching existing CESD CM symbol to incoming symbols . . . .
Matching existing CESD ER symbol to incoming symbols . . . .
Matching existing CESD ER symbol to incoming symbols . . . .
. . . . . . . . . . .
Comparing load modules and program objects
Instructions to change addressing mode . . . . . . . . . . . . . . . .
CC settings for TAM instruction
. . . . . . . . . . . . . . . . . . .
PSW addressing-mode bits . . . . . . . . . . . . . . . . . . . . . . .
BASSM actions summary
. . . . . . . . . . . . . . . . . . . . . . .
Operation of BSM instruction . . . . . . . . . . . . . . . . . . . . .
BSM actions summary . . . . . . . . . . . . . . . . . . . . . . . . .
Instruction pairs for call/return with possible AMODE change . .
Calling among addressing modes within an assembly . . . . . . . .
LLGT and LLGTR instructions . . . . . . . . . . . . . . . . . . . .
Symbol table entries for DSECT symbols . . . . . . . . . . . . . .
Summary of USING Statements . . . . . . . . . . . . . . . . . . . .
Summary of DROP Statement Behaviors
. . . . . . . . . . . . . .
Example of a non-homogeneous array . . . . . . . . . . . . . . . .
Array addressing with a table of addresses . . . . . . . . . . . . . .
Example of an address tables contents . . . . . . . . . . . . . . . .
Supervisor and Program Call instructions
. . . . . . . . . . . . . .
SVC instruction format . . . . . . . . . . . . . . . . . . . . . . . . .
PC instruction format . . . . . . . . . . . . . . . . . . . . . . . . . .
GETMAIN request options . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . .
FREEMAIN request options
Comparing QSAM and BSAM
. . . . . . . . . . . . . . . . . . . .
Partial contents of Extended Program Interruption Element (EPIE)
Hexadecimal, decimal, and binary . . . . . . . . . . . . . . . . . . .
Hexadecimal Addition Table . . . . . . . . . . . . . . . . . . . . . .
Hexadecimal Multiplication Table . . . . . . . . . . . . . . . . . . .
Integer powers of 2
. . . . . . . . . . . . . . . . . . . . . . . . . . .
Integer powers of 2
. . . . . . . . . . . . . . . . . . . . . . . . . . .
Multiples of powers of sixteen (part 1 of 2)
. . . . . . . . . . . . .
Multiples of powers of sixteen (part 2 of 2)
. . . . . . . . . . . . .
Powers of 10 expressed in hexadecimal . . . . . . . . . . . . . . . .
Assembler Language EBCDIC character representation
. . . . . .
7-bit ASCII character representation
. . . . . . . . . . . . . . . . .
High Level Assembler DC-Statement Constant Types . . . . . . .
ASCII Character Representation . . . . . . . . . . . . . . . . . . . .
Examples of different types of integer division . . . . . . . . . . . .
Comparing five binary floating-point operands
. . . . . . . . . . .

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

Tables

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

728
728
730
730
731
732
734
736
737
744
756
759
761
813
814
814
814
827
827
829
829
829
830
830
841
844
844
844
846
846
847
848
848
849
857
890
890
900
903
904
936
936
937
944
945
952
960
981
982
982
983
984
986
986
987
998
999
1000
1061
1112
1197

xxxv

xxxvi

Assembler Language Programming for IBM z System Servers

Version 1.00

Foreword
FFFFFFFFFFFF
FFFFFFFFFFFF
FF
FF
FF
FFFFFFFF
FFFFFFFF
FF
FF
FF
FF
FF

WW
WW
WW
WW
WW
WW
WW
WW
WW
WW
WW
WW
WW WW WW
WW WWWW WW
WW WW WW WW
WWWW
WWWW
WWW
WWW
WW
WW

Outline and Overview


We will survey many aspects of Assembler Language programming on z System processors.
Chapters I-IV cover basic material needed for almost all programs.
Chapter I introduces some notation well use, and discusses the important topics of binary and
hexadecimal number representations and arithmetic, and conversion among number representations.
Chapter II introduces the Central Processing Unit or CPU. Well survey central memory,
the registers youll use in your programs, and the Program Status Word (PSW). Then well
look at some basic types of instructions and their operation codes, and see how they refer to
data in memory.
Chapter III describes basic properties of the Assembler Language, including symbols, selfdefining terms, and expression evaluation. Then we will see how to write Assembler Language
statements and their components. Last, we discuss the key concept of addressability and the
important USING statement.
Chapter IV describes methods for defining often-used data types, and techniques for organizing
data items in your programs.
The six sections of Chapter V discuss basic instructions, emphasizing those that operate on
data in the general registers, and the important conditional branch instructions.
Chapter VI considers addressing techniques, loops and other iterative processes, and
immediate instructions containing useful operands.
Chapter VII discusses bit and character data and techniques for handling them.
Chapter VIII examines the packed and zoned decimal data representations, instructions for
packed decimal arithmetic, and for conversion between those representations and EBCDIC
characters.
Chapter IX describes general concepts of floating-point arithmetic and the three floating-point
representations supported by z System: hexadecimal, binary, and decimal, and instructions for
manipulating data in and among each of the representations. It concludes with a summary of
important differences between floating-point and mathematicians real arithmetics.
Chapter X discusses large programs and modularization techniques such as subroutines and
common linkage conventions, how to combine separately assembled (or compiled) routines
into a single executable program, and how to change addressing modes.
Chapter XI describes the powerful Dummy Control Section and the enhanced USING
statements, and shows how to apply them to several basic data structures.
Foreword

Chapter XII introduces common techniques for accessing operating system services, basics of
exception handling, and uses of reenterability and recursion.
Appendix A contains reference and conversion tables.
Appendix B describes a set of useful macro instructions that handle simple input, output, conversion, and display operations.

Programming Environments
Every programming language must eventually deal with the environments under which the programs will be run. While we will see many examples of program segments, we will defer complete
programs until later sections.
If you like, browse the solutions to the Programming Problems: these are complete programs
that have been executed successfully, and produce what I believe are correct answers. The simple
conventions used here for communicating with the Operating Systems Supervisor are described in
Appendix B: Simple I/O Macros on page 1001; these may be augmented or replaced as desired.
The conventions and procedures needed to execute an Assembler Language program in your
computing environment should be locally available to you.

Levels of Difficulty (*)


This material varies in depth and detail. Where a detailed portion can be skipped with no loss of
continuity, the heading is tagged with a parenthesized asterisk (*), as in the heading just above.

Exercises and Programming Problems


Exercises and programming problems appear throughout. Some are integral to the material, while
others explore interesting sidelines. Exercises and programming problems are rated in order of
estimated difficulty from 1 to 5; the most useful or illustrative exercises are tagged with a plus ( + ),
and are strongly recommended.
In all cases, the exercises and programming problems are important.
The Exercise and Programming Problem solutions should be considered as samples, and are not
in any way intended to be the correct solutions. If yours are shorter, simpler, or just plain
nicer, so much the better. But if your solutions seem to be two or three times longer than these,
you may want to study them for suggestions of useful approaches to solving a programming
problem.

Some Observations
1. Some exercises ask you to find what is wrong with a statement or instruction sequence.
While it may be poor style (or manners) to show coding errors, I feel justified in doing so on
two grounds: pedagogical value and self-defense.
First, it helps to see wrong or poor ways to do something, as well as correct or better
ways.
Second, some programs may be written by people who learned from examples containing
errors and their programs will be processing my bills, checking my tax returns, and calculating my bank balance. I want your programs and theirs to be as safe, correct,
and reliable as possible.
I trust you will understand. I am of course willing to have you point out my errors. If you
find any, please let me know so I can correct them.
2. This is not intended to be a cookbook. I have tried to give not just occasional recipes for
doing some basic tasks, but a view of some underlying processor structures and the language
closest to the processor, Assembler Language. You may have already been introduced to
programming a computer using a higher-level language, and are probably familiar with

Assembler Language Programming for IBM z System Servers

Version 1.00

concepts such as loops and conditional branching. Because the internal structures of computers have many similarities, I sometimes try to point out not only what a particular
instruction does, but also why it does it that way. Learning to program other processors will
then be a comfortable extension of the concepts and techniques you learned here.
3. This book is too large 1 to be used as a text for a programming class of normal length. I
expect that most instructors will use those portions most useful for their selection of topics;
other portions may have information that can be sampled as desired.
I assume you are interested mainly in writing application-level programs for z/Architecture
processors, not specialized or privileged operating system components. This text therefore
deals with nonprivileged instructions, which in any event are the great majority of
instructions in all programs.
4. I confess that levels of detail may vary depending on my level of interest in a particular topic.
5. Some of this material is based on lecture notes I created for Assembler Language classes
when I was at the Stanford Linear Accelerator Center in Menlo Park, California.

Yes, this book is too long. As my Chinese-restaurant fortune cookie said: You have a love for words, and should
write a book.
Foreword

IIIIIIIIII
IIIIIIIIII
II
II
II
II
II
II
II
II
IIIIIIIIII
IIIIIIIIII

NN
NN
NNN
NN
NNNN
NN
NN NN
NN
NN NN
NN
NN NN NN
NN
NN NN
NN
NN NN
NN
NNNN
NN
NNN
NN
NN
NN
NN

A digital computer can be considered from various viewpoints; here are five possible views, each
treating the computers inner workings in successively less detail.
To an engineer concerned with designing its logical circuits, a computer might be thought of as
a collection of devices for controlling and ordering the flow of electrical signals.
At another level, a person concerned with methods used to make these logical circuits perform
operations such as addition and division might treat a computer as a collection of registers,
switches, and control mechanisms that perform a series of steps leading (say) to the computation of a quotient.
At the next level one might consider a computers basic operations to be single arithmetic
operations, a simple data movement, or a test of a single piece of data.
Another viewpoint (typical of higher-level languages) considers the basic operations to be
moving blocks of data, evaluating and assigning mathematical expressions, and controlling
counting and testing operations.
At yet another level, as in certain applications such as traffic simulation, data reduction, and
network analysis, the computer processes information in a form closely approximating the
problem under consideration, and produces output directly applicable to that problem.
Each of these views is of course not especially distinct from its neighbors. We will be primarily
concerned with the middle level, considering the basic operations or instructions that we want the
computer to perform, such as single arithmetic or logical operations, simple data transmission
operations, etc. We will also consider the computer from neighboring viewpoints: sometimes it
is useful to know some details of the internal sequencing of operations such as multiplication and
branching; at other times it will be convenient to consider groups of instructions such as macroinstructions that perform operations in a larger context.
The level that is our primary concern is usually known as Assembler Language programming or
Assembler coding. 2 The Assembler well describe is the IBM High Level Assembler for z/OS &
z/VM & z/VSE, known as HLASM. It also can be used on IBM Linux for z System.
Getting the desired machine language instructions and data into the computer in executable form
requires the aid of a number of programs: the most important for us is the Assembler. Other
important programs are the linker 3 and the operating system Supervisor. Each will be considered
in the appropriate context.

Some people call it BAL meaning Basic Assembler Language but the language is not basic (nor is it
BASIC) except in the sense that it can be fundamental to understanding the z System processors operations.
The term linker here stands for several important programs that combine and load programs for execution. Their
names vary among operating systems (Binder or Linkage Editor and Program Loader on z/OS, Loader and Link
Editor on z/VM, Linkage Editor on z/VSE, etc.)

Assembler Language Programming for IBM z System Servers

Version 1.00

To give hardware designers greater freedom to implement instructions in the best way, without
your having to be aware of each implementations techniques, IBM describes an architecture.
A processors architecture defines the actions of instructions, I/O, storage, etc. to describe a
known set of behaviors, while giving processor designers flexibility in implementing those behaviors.
It will help to have available a copy of the z/Architecture Principles of Operation manual. It is
easily obtained, and is the reference for basic z System architecture. You should consult it regularly when we discuss individual instructions.
Remember!
The Assembler Language itself is quite simple. The syntax is sparse, there
are few reserved words, and almost no structuring rules. The main
challenge in learning Assembler Language is learning about the processor
for which youre writing programs.

Why Program in Assembler Language (and Why Not)?


Before going any further, ask why youre considering writing programs in Assembler Language.
These are some reasons for programming in Assembler Language:
1. You have to.
Maybe youre taking a course like Assembler Language Programming, or youve been
made responsible for an existing Assembler Language application.
2. You want to.
Its useful to know, or maybe youre just curious about what is really going on inside the
processor when you write high-level language programs. The architecture represented by
System/360 and its modern descendants has pervaded the computing industry since the
mid-1960s, and will continue to do so for many years. Because you may encounter some
modern incarnation of the System/360 family, it helps to be familiar with its architecture.
3. Its educational.
Programming in Assembler Language is the best way to learn how the processor works.
Even if you program in high-level languages, there will be times when understanding the
processors properties will help you understand why certain choices and tradeoffs are made in
programming in those languages.
4. Its fundamental.
A key to writing efficient software is understanding the underlying hardware; no language
other than Assembler Language provides such insights. Even if you dont write much Assembler Language code, writing good high-level language programs often depends on knowing
how to write good Assembler Language programs.
Debugging a problem in high-level language applications may require knowing some machine
language. (You might say that a language needing this kind of debugging isnt very highlevel, but it is necessary at times.)
Assembler Language is also a natural vehicle for recovering lost source code (yes, it
happens!). Object or binary programs can easily be disassembled into Assembler Language
source programs.
5. It can be more efficient.
Efficiency depends on many things. Because you can specify almost the exact instruction
sequences you want, you can do many things to improve program efficiency. If you know
which parts of a program consume the most time, recoding those parts in Assembler Language can often lead to savings.

Foreword

However, pursuing efficiency has limits. Programmers have been known to struggle happily
over a program modification that will save a few seconds of processor execution time over
the programs lifetime.4
There is another objection to using Assembler Language to attain efficiency: some modern
compilers can produce quite efficient code for certain applications.5 However, even clever
coding and powerful compilers cant help a badly implemented algorithm. Also, you may
have difficulty learning the costs of various high-level language statements.
6. Its independent.
Error recovery (and avoidance) can be simpler in Assembler Language than with high-level
languages.
You need not rely on the presence of any run-time environment other than the operating
system environment in which your program will execute. You can access many services that
may not be available to high-level languages.
7. Its more flexible.
There are some processor facilities for which higher-level languages provide limited or no
support. And even when these facilities are supported, their expression in such languages
may be inefficient, restricted, or difficult to use. Assembler Language may be the simplest, or
even the only, way to access those facilities.
Unlike many high-level languages, Assembler Language imposes no assumptions about how
you should (or must) structure your programs. Someone elses program structures or concepts of proper programming technique arent forced on you by the language, and you have
more freedom to choose solutions you like.
8. Its more powerful.
In addition to Assembler Languages efficiency and flexibility, you also have available to you
the entire repertoire of the processors instruction set. New instructions on your CPU are
usable immediately; you dont need to wait for high-level language compilers to catch up
to the latest architecture. (Some instructions, though, may require special privileges such as
executing in supervisor state.)
9. Its more fun.
You can do things your own way. You can define the meanings of each and every piece of
your program, and not have to be satisfied with assurances that the compiler (or the system)
takes care of that for you.
10. Its controllable.
Unlike higher-level languages, the Assembler creates machine language instructions and
data in exactly the form and order you specify. It doesnt try to organize (or re-organize)
anything for you; there are no helpful intermediaries between you and the processor. In a
nutshell, What you write is what you get.
11. Its stable.
You neednt worry about re-translating and re-testing programs with new releases of compilers or run-time libraries; the object code wont change each time you re-assemble.
12. Its parameterizable.
Because Assembler languages have been with us for almost as long as computers, a lot has
been learned about minimizing the pain of modification: we will see that the Assembler Language is very rich in possibilities for parameterization. That is, you can revise a value in just
one place in your program, and the Assembler automatically adjusts the portions of your
program that depend on that value.

And possibly wasting many more seconds of processor time re-assembling and re-linking the program than will be
ever saved during its execution! (Yes, Ive done that...)
Compilers do have occasional errors; finding problems with the generated code is easier if you know Assembler
Language.
Assembler Language Programming for IBM z System Servers

Version 1.00

13. Its extensible.


This is one of the best reasons for programming in Assembler Language: you can define
macro-instructions that have whatever meaning you want them to have. You can design and
create an entire programming language of your own, and then build other languages on top
of that, for as many levels as you like or need. Macro-instructions also provide some
insulation between your program and the habits of the Operating System under whose
control it will run.
Macro instructions are definitely a highly satisfying aspect of Assembler Language programming. Unfortunately, we dont have room here to describe conditional assembly and macros.
Conversely, there are also reasons for not programming in Assembler Language.
1. The language can be verbose.
Economy of expression is not a characteristic of most Assembler Languages except (and this
is an important exception) for the availability of macro-instructions. Usually, you must write
more lines of code to do a simple task than if you had chosen a higher-level language.
This is due mainly to the richness of the z/Architecture processors instruction set, because
the Assembler Language itself is quite simple.
2. The language is very flexible.
It can be too flexible for some users. There are many acceptable ways to use Assembler
Language to solve a given problem, and almost all problems can be solved with a small and
manageable set of instructions.
3. The language is idiosyncratic.
To a large extent, the occasional lapses of regularity and coherence in the syntax and semantics of the Assembler Language are due to irregularities in the z System instruction set and
architecture: instructions that do similar things may have different syntaxes. Thus, the
Assembler Language contains occasional special cases and exceptions to the rules. (This
is of course not unique to Assembler Language!)
4. The languages flexibility means its easier to make errors.
While this reason is implicit in the previous three, it also is part of the price you pay for
being able to specify everything yourself; you have more chances to make mistakes. We will
see that there are good ways to avoid some of the pitfalls that this extra freedom provides.
5. Programs can be harder to debug.
In some cases, programmers may not write programs so they can detect processing errors, or
terminate gracefully. Because programs can be written with great freedom, they might not be
organized so that errors do a minimum amount of damage. Similarly, some programmers are
often reluctant to insert the extra instructions necessary to leave an easily-followed diagnostic
trail for the person (you?) trying to discover why your program did something unexpected.
6. Programs may seem hard to maintain.
Maintenance costs are much more strongly influenced by the structure and clarity of the code
than by the language used to write it. Extensive research has shown little difference in maintenance costs between Assembler Language and high-level languages.
7. Lack of a run-time library.
Assembler Language programs can be written as a component of a high-level language application. But stand-alone Assembler Language applications may not have access to the runtime libraries provided with most high-level languages. By using careful modular design
techniques, this lack can be overcome with a set of routines or macro-instructions that
provide functions shareable among many applications.
Assembler Language programs can access run-time libraries, so long as they adhere to appropriate programming conventions; this can often reduce programming effort.
8. Lack of portability.
Unlike programs written in some high-level languages, Assembler language code is intended
for execution only on the processors for which it is created. (And, high-level language programs are not always easily moved to other processor architectures!)
Foreword

If none of the reasons for programming in Assembler Language has much appeal to you you
dont have to program in Assembler Language, you dont need its efficiency, flexibility, power, or
extensibility, and your sources of amusement (or employment) lie elsewhere then dont. Use
whatever tool will do the job with the least time, effort, and nuisance, and get on to whatever task
comes next.

Assembler Language Misconceptions


These are some common misconceptions about Assembler Language:
Assembler Language is dead.
For many small-environment or short-lived applications, fast implementation is more important than long life, small size or high performance. But many substantial organizations have
made major investments in Assembler Language applications that must be fast, compact, and
can process high volumes of data efficiently; such applications need regular enhancement.
Its hard.
The language itself is trivially simple. Understanding programs in any programming language is
more a matter of clear coding and good style and organization. Any programming task can be
made easy or difficult. (Well offer occasional bits of advice on ways to simplify your programming challenges.)
Assembler Language programs are faster than compiled programs.
That depends more on your choice of algorithms, the high-level language, and its compiler.
You can write slow programs in any language.
Assembler Language programs are hard to read.
Only if you write them that way! But you do need to understand the zSeries instructions.
Its hard to manage all those base registers.
Not at all: careful program organization and appropriate instruction choice easily make it a
non-problem.
Assembler Language is hard to maintain, especially if you dont have the needed skills.
Extensive research shows little difference in maintenance costs among programming languages,
and lack of skills is a problem for any programming language.
Many applications written in Assembler Language can be replaced with out-of-the-box
functionality.
Its rare that a purchased software package does exactly what your organization needs; you
must pay in time and money for negotiating, training, and adaptations that you could complete at home more promptly and cheaply.
You dont need to worry about efficiency, because a faster CPU will be along in a year.
Rarely true, because growing businesses continually need to process more data and their programs must provide new capabilities. Once you fall behind, its difficult to rewrite inefficient
applications.
Converting an Assembler Language application to a high-level language will make it easier to
hire skilled programmers.
There are some critical factors here: research has shown that
1. Changing language has many hidden costs and should be avoided.
2. High-level languages do not improve reliability or maintainability.
3. Problem-domain expertise is often more important than programming-language expertise.
It it much easier to train people who understand your business and business processes in
the language you need, rather than hiring people who have the necessary language skill.
Some further considerations include:

Transition and testing require system stability, which implies possible lost business opportunity.

Assembler Language Programming for IBM z System Servers

Version 1.00

Converting and validating test cases can be a major effort in itself.

High stress levels for bilingual staff.

You cant do Structured Programming in Assembler Language.

By using a set of Structured Programming macros such as those available with the High
Level Assembler, programs can be as fully structured as any high-level language program.

Because you have full control over the separation of code and data into individual modules,
you can have greater flexibility in determining the structure of an application than a typical
high-level language may provide.
Remember!
Whats good about Assembler Language?
Almost everything you do works OK.
Whats bad about Assembler Language?
Almost everything you do works OK.

Exercises
0.1.1.(1) + Why are you interested in Assembler Language?
0.1.2.(0) What is the difficulty level of this exercise?

Foreword

10

Assembler Language Programming for IBM z System Servers

Version 1.00

Index
A
access register
addition
address constant
address generation
address resolution
address translation
addressing
addressing halfword
addressing mode
alignment
architecture
definition 5
arithmetic
ASCII
Assembler 4
assembler instruction statement
Assembler Language 4
assembler option
assembly
attribute
attribute reference
See attribute reference

data structure
decimal floating-point
decimal overflow
See overflow
decimal self-defining term
See self-defining term
definition
dependent USING
division
DROP assembler instruction
DSECT assembler instruction
DXC
See Data Exception Code

E
editing
Effective Address
Encoded Length
exception
See interruption
expression
extended mnemonic
External Symbol Dictionary

binary
binary floating-point
binary self-defining term
See self-defining term
blank

fixed-point binary
fixed-point overflow
See overflow
floating-point
Floating-Point Control Register
floating-point overflow
See overflow
floating-point register
floating-point underflow
See underflow
FPCR
See Floating-Point Control
Register
FPR
See floating-point register
fraction conversion

C
central processing unit (CPU)
character
character self-defining term
See self-defining term
comparison
complementation
Condition Code
constant
control register
control section
See section
conversion
CPU
See central processing unit

G
general register
GPR
See general register

data

hexadecimal

hexadecimal floating-point
hexadecimal self-defining term
See self-defining term
HLASM 4

I
IA
See Instruction Address
IBM High Level Assembler for
z/OS & z/VM & z/VSE 4
ILC
See Instruction Length Code
immediate operand
instruction
Instruction Address
instruction format
Instruction Length Code
instruction operation
instruction register
integer conversion
interruption
interruption code

L
labeled dependent USING
labeled USING
length field
library
linkage convention
Linker
literal
load module
Location Counter
logical

M
machine instruction
macro instruction
memory address
mnemonic
multiplication

N
notation

O
object module
ones complement representation
operand

Index

11

operation code
operator
option
See assembler option
ordinary USING
overflow

Z
z/Architecture 3
zoned decimal

P
packed decimal
pattern
program interruption
See interruption
Program Loader
Program Mask
program object
Program Status Word
PSW
See Program Status Word

Q
quantum

R
recipe
register
relative-immediate
relocatable
relocation attribute
representation
residence mode

S
section
self-defining term
shift
space
See blank
statement
subtraction
symbol

T
term
time
twos complement representation

U
underflow
Unicode
USING assembler instruction

12

Assembler Language Programming for IBM z System Servers

Version 1.00

Chapter I: Getting Started

IIIIIIIIII
IIIIIIIIII
II
II
II
II
II
II
II
II
IIIIIIIIII
IIIIIIIIII

In this chapter, we will look at factors involved in Assembler Language programming, and then
investigate the binary number representation and its arithmetic.
Section 1 looks at some notation, terminology, and conventions well use.
Section 2 describes basic topics about the number representations used in z System processors:
binary and hexadecimal numbers, arithmetic and logical representations, 2s complement arithmetic, and discusses alternative number representations.

Chapter I: Getting Started

13

1. Some Basic Items

11
111
1111
11
11
11
11
11
11
11
1111111111
1111111111

In this section we introduce some basic terms and notations that well use later, and then investigate the important properties of the binary number representation.

1.1. Notation and Terminology


Some diagrams and figures need to show the lengths and positions of parts of the figure. In
Figure 1 we want to show some objects structure, and to indicate the amount of space
required for each of its components. To do this, we place a number above the field to indicate
its length. In cases where we also indicate the numbering and positions of the digits in that
component, we use numbers below the field, at its right and left ends. Two four-digit fields in
an eight-digit area would be as shown in Figure 1:
4
4

Field1 Field2

0
3 4
7

 Field widths

 Start and end positions of fields

Figure 1. Example of numbering and notation

By convention, numbering starts with digit zero on the left. We call the leftmost digit, digits,
or portion of a field the high-order part of the field; the rightmost digit, digits, or portion of the
field the low-order part. Thus, position 0 in this figure is the high-order digit, and position 7 is
the low-order digit.
Standard mathematical symbols such as subscripts and superscripts, and the capital Sigma used
to denote summation are hard to produce, so we sometimes use a slightly different notation.
For subscripted quantities like B k (B-sub-k) we will sometimes use B k, but also either
Bk or the programming-language convention B(k). For quantities like element i,j of
ARRAY or ARRAY-sub-i,j (often written ARRAY i,j) we write ARRAY(i,j). There
are very few places where the juxtaposition of two letters like XY means multiplying X and
Y, but these will be obvious from the context where they appear. In some cases we use superscripts for quantities like 10 5 and B k, but we also use the common notation of paired asterisks
to denote exponentiation, as in 10**5 and B**k.
For the operations of addition, subtraction, multiplication, and division, we use the operators
+, , *, and / respectively. (In some descriptions, we use for multiplication and for

14

Assembler Language Programming for IBM z System Servers

Version 1.00

division.) We use vertical bars or the functional notation ABS() to denote absolute values: |x|
and ABS(x) mean the magnitude of the quantity x.
To denote the contents of something called x, we use c(x) or C(x). Sometimes the object
whose contents were interested in will be an identifiable object such as a register, so that we
might speak of the contents of Register 1 as c(R1). At other times we may speak of the contents of something whose actual form or location is not precisely known, such as an area of
memory that has been given the name AREA; in this case we still use the notation c(AREA).
Some words have similar but different meanings. For example, the word operand is used in
several different senses in most of the literature describing z System and its Assembler Language.
1. In the description of instructions in the z/Architecture Principles of Operation, an operand
is the object being operated on, or is involved in the instruction. For example, in
LM

R1,R3,S2

the contents of GR R 1 is the first operand, and the contents of storage addressed by S2 is
the second operand. Note that operand numbers may not correspond to their sequential
position!
2. In an Assembler Language statement, an operand is defined by its position in the operand
field. For example, in
LM

2,12,SAVE

the first operand is 2, the second operand is 12, and the third operand is the symbol SAVE.
Note the difference in operand numbering compared to the z/Architecture Principles of
Operation description!
3. During execution, an operand is the subject of an operation: an operand is something
being acted on or operated on by an instruction as it is executed in the processor. For
example, in
LM

2,12,SAVE

one operand is the contents of general register 2, and another operand is the contents of
memory named by the symbol SAVE.
Well try to clarify these differences; the intended sense will be usually clear from the context in
which the word appears.
Sometimes we need to indicate positions where a blank or space character should appear.
Rather than use a blank character, we sometimes use a character. For example,
JohnQ.Public
has a blank on each side of the middle initial.
Sometimes we refer to the euro character. Because this document formatter doesnt have
that exact character, we use as the best available approximation.

Exercises
1.1.1.(1) What is the total width of the fields illustrated in Figure 1 on page 14?

1.2. Instruction Elements


We will often refer to parts of a machine instruction. In the z/Architecture Principles of
Operation, you will see notations like
R1,R2

or

D2(X2,B2)

or

M1

or

I2

or

L1

where the subscripted letters specify numeric values appearing in the fields of a machine instruction. They are simply a way to indicate numbers that you or the Assembler must provide. In
particular:

Chapter I: Getting Started

15

A notation like R 1 is simply a number that usually denotes any register, not register
number 1.
G R R 1 means the general register denoted by the number used in place of R1.
GR1 means general register 1.
Well clarify these and other details as we proceed.

1.2.1. Register Names


We refer regularly to registers, using small numbers like 0, 12, etc. Some people like to use
names like R0 and R12 for them. They can be helpful, but can also be very misleading, because
R0 isnt really a register name; its only a name for a number. (Some exercises will help you
understand why it can be misleading.) I dont want you to develop a habit of thinking that names
like R0 always mean register 0. I prefer to use just numbers like 0 or 12 to designate
register names.6 That said, we will sometimes refer to a specific register using terms like R0 and
R12, meaning specifically general registers 0 and 12.
Unlike some other processors and their assemblers, there are no reserved register names or
symbols in the z System Assembler Language.

Exercises
1.2.1.(1) If R 1 has value 9, what register is referenced by GR R 1?

Terms and Definitions


algorithm
A finite sequence of well-defined steps for solving a problem. After al Khwarizmi, a nickname of the 9th century Persian astronomer and mathematician Abu Jafar Muhammad ibn
Musa, who authored many books on arithmetic and algebra. He worked in Baghdad and his
nickname alludes to his place of origin, Khwarizm (Khiva), in present-day Uzbekistan and
Turkmenistan.
architecture
A description of the attributes of a system as seen by the programmer, i.e., the conceptual
structure and functional behavior, as distinct from the organization of the data flow and controls, and the physical implementation. 7
Assembler Language
A lower-level language allowing programmers maximum freedom in specifying processor
instructions, providing powerful macro-instruction facilities supporting encapsulation and
economy of expression.
Assembler
A program that translates programs written in Assembler Language to machine language
instructions and data.
HLASM
IBMs High Level Assembler for z/OS and z/VM and z/VSE. The Assembler we describe
here.

16

One reason for using symbolic register names was that all early assemblers Symbol Cross Reference (a list of all
symbols used in your program) showed the places where the names were used and searching the cross-reference
might be the only way to know which instructions might have referenced specific registers. The IBM High Level
Assembler for z/OS & z/VM & z/VSE provides a Register Cross Reference showing where the general registers
were used, whether or not they were named. So, its no longer necessary to name registers.
G.M. Amdahl, G.A. Blaauw, and F.P. Brooks, Jr. Architecture of the IBM System/360, IBM Journal of Research
and Development Vol. 8 No. 2, 1964, reprinted in IBM Journal of Research and Development Vol. 44 No. 1/2,
January/March 2000.
Assembler Language Programming for IBM z System Servers

Version 1.00

blank
A nonempty, finite-width invisible character; a space. In contexts where explicit blank spaces
appear, we sometimes use the character.
space
A nonempty, finite-width invisible character; a blank character. In contexts where explicit
blank spaces appear, we sometimes use the character.
operator
A character specifying a mathematical operation: + for addition, for subtraction, * or for
multiplication, and / or for division

Chapter I: Getting Started

17

2. Binary and Hexadecimal Numbers

2222222222
222222222222
22
22
22
22
22
22
22
22
22
222222222222
222222222222

In this section we examine number representations and methods for converting numbers in those
representations to and from decimal. Then we examine arithmetic using numbers in the binary
representation.
z System, like most other digital computers, uses binarybase two numbers for most internal
arithmetic. A binary digit takes only values 0 and 1; because it is relatively simple to build a
mechanical or electrical device representing a binary digit, the binary representation is quite
natural. For example, a 1 digit may be represented by the presence of a current through a circuit
component or by the presence of a positive voltage at some point. Facility with binary numbers is
fundamental to understanding the basic operations of z System, so it is important to understand
the binary number representation.
For now, all numbers are assumed to be integers. This means that the decimal point (the
radix point or binary point) lies at the right end of the number. We will discuss nonintegral
(fractional) numbers in Sections 29 and 31.
We are familiar with numbers using radixes other than 10. Times (and angles) measure minutes
and seconds using radix 60; hours are counted using radix 24; and before The United Kingdom
changed to a decimal monetary system: radix 20 for shillings and radix 12 for pence. Binary is
easier.

2.1. Positional Notation and Binary Numbers


In base ten, writing a number such as 1705 means the quantity
1000 + 700 + 00 + 5,
which can also be written as
11000 + 7100 + 010 + 51,
or as
1103 + 7102 + 0101 + 5100.
That is, each digit position as we move to the left is weighted by one more power of the base, ten.

18

Assembler Language Programming for IBM z System Servers

Version 1.00

Similarly, when in binary notation we write 11010 we mean


10000 + 1000 + 000 + 10 + 0,
124 + 123 + 022 + 121 + 020,
116 + 18 + 04 + 12 + 01
which is not the same as what is meant by the decimal number 11010, where powers of ten are
understood. In fact, the binary number 11010 is the representation (in the number system with
base two) of the decimal number 26: the sum in this example is 16+8+2.
To clarify which base is intended we use a notation like the Assemblers: if base 10 is intended,
the digits are written normally; if base 2 is intended, the binary digits are preceded by a B and
an apostrophe, and are followed by an apostrophe. For example:
26 = B11010, 1 = B1, 10 = B1010, 8 = B1000, 999 = B1111100111.
Positional notation can be used for any base (or radix). For example, if humans had only one
hand we might use base 5 for numbering, so that 1413 in base 5 would have decimal value 233 (in
our ten-finger decimal world):
14135 = 153 + 452 + 151 + 350
= 125 + 100 + 5 + 3
= 23310

Exercises
2.1.1.(1) + Determine the decimal value of the following binary numbers: (a) B000010110, (b)
B000101100, (c) B10101010, (d) B1111111.
2.1.2.(1) + Suppose a binary number is represented by a single 1-bit followed by a string of n
zero bits (100...00). What is its value?
2.1.3.(2) Suppose a binary number is represented by a string of n one bits (111...11). What is
its value?

2.2. Hexadecimal Numbers


As values become larger, the number of binary digits required becomes larger also (over three
times as many bits as decimal digits), so we use a more compact notation for binary numbers. If
we consider groups of four binary digits at a time, the possible decimal values that can be represented run from zero to fifteen. If we then represent each of these groups by the digits 0, 1, 2, 3,
4, 5, 6, 7, 8, 9, A, B, C, D, E, F, we can establish the correspondences shown in Table 1 on
page 20. (The letters A through F are a natural choice for digits, but we could actually have
chosen any other six symbols to represent the digits to which we assign the values 10, 11, ...,
15.8)
We use the same positional notation for base 16 number representation as for decimal and binary
numbers. Thus, we can write the base 16 number A97E 16 as
A163 + 9162 + 7161 + E160,
or
10163 + 9162 + 7161 + 14160 = 104096 + 9256 + 716 + 14 = 43390.

In fact, some early computers such as the ILLIAC I used the characters K, S, N, J, F, and L because those letters
had the required binary 4-bit hole combinations on 5-hole punched paper teletype tape. (Remembering those six
letters was helped by the phrase Kind Souls Never Josh Fat Ladies.)
Chapter I: Getting Started

19

Why use something as unfamiliar as a base-sixteen representation for numbers that are binary in
nature? Base 16 is compact and convenient for expressing long strings of binary digits, and a
natural representation for z System. Other groupings are possible; another form is octal, or
base eight, in which the binary digits are grouped by threes.9
Table 1. Binary, decimal, and
hexadecimal

Binary
Digits

Decimal
Value

Hex
Digit

0000
0001
0010
0011
0100
0101
0110
0111
1000
1001
1010
1011
1100
1101
1110
1111

0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

0
1
2
3
4
5
6
7
8
9
A
B
C
D
E
F

The base sixteen digits in the third column are called hexadecimal10 or hex digits, and we use them
in most situations when we need to refer to binary numbers. As with binary numbers, a notation
similar to the Assemblers will denote hexadecimal quantities: the hexadecimal digits are preceded
by an X and an apostrophe, and are followed by an apostrophe. For example:
26 = B11010 = X 1A ,

X26 = B100110 = 38,

1 = B1 = X 1 ,

10 = B1010 = X A ,

B1000 = 8 = X 8 ,

100 = X64 = B1100100.

Converting numbers between binary and hexadecimal representations is easy:


To convert a hexadecimal number to binary, substitute for each hexadecimal digit the four
binary digits it represents.
To convert a binary number to hexadecimal, group the binary digits four at a time starting
from the right (adding extra zeros at the left end if needed), and substitute the corresponding
hexadecimal digit.
For example:
X D5B = B1101 0101 1011

(hexadecimal to binary),

B11 1110 1000 = X 3 E8

(binary to hexadecimal).

In the second example we could add two extra binary zero digits at the left or high-order end of
the number without affecting its value; similarly, we can omit high-order zero digits, and write
X11 = B10001

10

20

(rather than B00010001).

Processors whose word lengths were natural multiples of 3 included the IBM 70x and 709x processors with 36-bit
words, and several Control Data Corporation (CDC) processors with 48-bit words. Most processors now have word
lengths that are a multiple of 8 bits.
The correct term for base 16 is sexadecimal (or even hexadecadic), but you can understand that abbreviating the
term sexadecimal would not be appropriate for dignified corporations.
Assembler Language Programming for IBM z System Servers

Version 1.00

Dont omit zeros on the right! That is, B00111100 /= X F .


Converting between decimal and hexadecimal representations is more cumbersome; it is simplest
to use Tables 2 and 3 starting on page 22 below, and the tables in Appendix A: Conversion and
Reference Tables on page 981. The following section discusses general methods for converting
integers from one base to another; if you are satisfied to use the tables, the next section may be
skipped.
We use these abbreviations regularly: bit means binary digit, and hex is an abbreviation for
hexadecimal.

Exercises
2.2.1.(1) Convert the following hexadecimal numbers to binary: (a) X A , (b) X 2B , (c) X 3 E8 .
2.2.2.(1) Make a table similar to Table 1 on page 20 showing binary, decimal, and octal (base
8) values.
2.2.3.(2) In grouping bits to form hex digits, why cant we start at the left? That is, why do we
begin grouping at the radix point?
2.2.4.(2) + Create addition and multiplication tables for single hexadecimal digits.
2.2.5.(1) Convert the following octal numbers to hexadecimal:
1.
2.
3.
4.
5.

21474
77777
1750
60341303
4631

2.2.6.(3) You may have noticed that the characters in many cartoons and comics have only four
fingers. To help them with cartoon arithmetic, create base-8 (octal) addition and multiplication tables.

2.3. Converting Integers from One Base to Another (*)


In our familiar notation, a string of digits like 73294 in some base A means
7A4 + 3A3 + 2A2 + 9A1 + 4A0.
Using symbols, the digit string
dn ... d3 d2 d1 d0
is the representation in some base A of a number X:
X = dnAn + ... + d3A3 + d2A2 + d1A1 + d0A0.
The subscripts on the digits d match the power of the base A. If A has value 10, then the digit
string 73294 is the familiar decimal number seventy-three thousand, two hundred ninety four.
Suppose we want to convert X from its representation in base A to its representation in a new
base B, with digits e0, e1, e2, etc.:
X = em Bm + ... + e3B3 + e2B2 + e1B1 + e0B0.
We know the old and new bases A and B, and the digits d k of the old representation. To find the
digits e k of the new representation, we use the following scheme;
1. Divide X (in base A notation and arithmetic) by the new base B; save the quotient. The
remainder is the low-order digit e 0. This can be seen from the definition of the quotient and
remainder:
Chapter I: Getting Started

21

X = B Quotient + Remainder
= B [em B(m-1) + ... + e3B2 + e2B1 + e1B0] + e0.
where the term in square brackets is the quotient.
For example, taking A to be 10 and B to be 16, we convert 73294 to hex:
X = 73294 = 16 Quotient + Remainder = 16 4580 + 14,
so e0 = 1 4 = X E .
2. Now, divide the saved quotient by B; save the new quotient, and the new remainder is e 1.
In our example, dividing 4580 by 16 gives quotient 286 and remainder 4, the value of the
next digit, e1.
3. Continue this process until a zero quotient is obtained. The successive remainders are the
desired digits e0, e1, ..., e m ; they were obtained in order of increasing significance, from right
to left.
Continuing to divide by 16 in our example, we obtain remainders 14, 1, and 1; these are the
digits e2, e3, and e 4 respectively. The result of this sample conversion shows that 73294 (base
10) has value 11E4E (base 16).
Our most frequent conversions are between decimal and binary or hexadecimal; use Tables 2 and
3, or the conversion tables in Appendix A.
1. If the number is small enough, find it in the conversion tables.
2. For larger numbers,
a. To convert from hex to decimal, find each digits decimal value in the tables in Tables 2
and 3, and evaluate the sum.
b. To convert from decimal to hex, find the largest power of 16 in the tables that is less
than or equal to your number, subtract that number, and note the corresponding hex
digit. Repeat, writing the hex digits from left to right. The following example shows how
to do this for the decimal value 1000:
1000
-768
232
-224
8
-8
0

hex digit 3
hex digit E
hex digit 8

so that 1000 (decimal) is X 3 E8 .


Table 2. Multiples of powers of sixteen (part 1 of 2)

Hex Digit
1
2
3
4
5
6
7
8
9
A
B
C
D
E
F

22

160
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

161
16
32
48
64
80
96
112
128
144
160
176
192
208
224
240

Assembler Language Programming for IBM z System Servers

162
256
512
768
1,024
1,280
1,536
1,792
2,048
2,304
2,560
2,816
3,072
3,328
3,584
3,840

Version 1.00

163
4,096
8,192
12,288
16,384
20,480
24,576
28,672
32,768
36,864
40,960
45,056
49,152
53,248
57,344
61,440

164
65,536
131,072
196,608
262,144
327,680
393,216
458,752
524,288
589,824
655,360
720,896
786,432
851,968
917,504
983,040

Table 3. Multiples of powers of sixteen (part 2 of 2)

Hex Digit
1
2
3
4
5
6
7
8
9
A
B
C
D
E
F

165
1,048,576
2,097,152
3,145,728
4,194,304
5,242,880
6,291,456
7,340,032
8,388,608
9,437,184
10,485,760
11,534,336
12,582,912
13,631,488
14,680,064
15,728,640

166
16,777,216
33,554,432
50,331,648
67,108,864
83,886,080
100,663,296
117,440,512
134,217,728
150,994,944
167,772,160
184,549,376
201,326,592
218,103,808
234,881,024
251,658,240

167
268,435,456
536,870,912
805,306,368
1,073,741,824
1,342,177,280
1,610,612,736
1,879,048,192
2,147,483,648
2,415,919,104
2,684,354,560
2,952,790,016
3,221,225,472
3,489,660,928
3,758,096,384
4,026,531,840

The binary powers 2 10, 220, and 230 are often abbreviated by the letters K, M, and G.
Thus, it is common to refer to the decimal number 4,096 = 210 as 4K. Similarly, 3220 might
be referred to as 3M. Thus, for example, an area of memory (which well discuss in Section
3.1) containing 8,192 storage locations might be said to contain 8K bytes or 8 K-bytes. 11

Exercises
2.3.1.(2) + Convert these numbers from the given base to the new bases:
1.
2.
3.
4.

26293 (base 10) to bases 2, 4, 8, and 16.


X 2 FACED (base 16) to bases 10 and 2.
X BABEF00D (base 16) to bases 10 and 8.
X C0FFEE (base 16) to bases 10 and 2.

2.3.2.(2) Convert the following to decimal.


1. X 7 FFFFFFF
2. X C1C2C3
3. X4040405C (This digit pattern will reappear in other forms!)
2.3.3.(3) Make a table of the hexadecimal values of the squares of the integers from 1 to 32.
2.3.4.(2) + Convert the following hexadecimal numbers to decimal:
1.
2.
3.
4.
5.
6.

X257
X 7 FFA
X8008
X E000
X FFFA
X E1010

2.3.5.(3) Suppose we must convert a number from its representation in base A to its representation in base B. In which base will it be most convenient to do the arithmetic involved in the
conversion? How does the result depend on the base used for the conversion?

11

More properly, the abbreviations K, M, and G refer to the closest powers of 10: one thousand = 1K = 10 3, one
million = 1M = 10 6, etc. To avoid this confusion, you can use the more precise terms Ki, Mi, and Gi to
refer to the binary powers. But few computer people bother.
Chapter I: Getting Started

23

2.3.6.(2) Convert these octal (base 8) numbers to base 10: (a) 5061, (b) 257, (c) 192. Work
carefully!
2.3.7.(2) What decimal values are represented by the binary numbers 9K, 5M, and 2G?

2.4. Examples of General Conversions (*)


We will use the division methods described in the previous section to illustrate conversions from
one base to another.
1. Convert 19 (base 10) to base 2.
9
2)19
18
1=e0

4
2)9
8
1=e1

2
2)4
4
0=e2

1
2)2
2
0=e3

0
2)1
0
1=e4

Hence, 19 = B10011.
2. Convert 1000 (base 10) to base 16. (The conversion arithmetic is done in base 10.)
62
16)1000
992
8=e0

3
0
16)62
16)3
48
0
14 (X E ) =e1
3=e2

Hence 1000 = X 3 E8 .
3. Convert 627 (base 10) to base 9.
69
9)627
621
6=e0

7
9)69
63
6=e1

0
9)7
0
7=e2

so that 627 (base 10) = 766 (base 9).


4. Convert 766 (base 9) to base 7. First, we convert to base 10, and then do the arithmetic in
decimal:
766 (base 9) = 781 + 69 + 6 = 567 + 54 + 6 = 627 (base 10)
89
7)627
623
4=e0

12
7)89
84
5=e1

1
7)12
7
5=e2

0
7)1
0
1=e3

so that 766 (base 9) = 1554 (base 7).


If you are mathematically inclined:
Just for fun, now do the conversion in base 9:
108
7)766
762
4=e0

13
7)108
103
5=e1

1
7)13
7
5=e2

0
7)1
0
1=e3

Thus 766 (base 9) = 1554 (base 7) again. This shows that you can
do base conversion using any (other) base for the arithmetic.
5. Convert 1413 (base 5) to base 10. This is simplest if we expand the positional notation:
1413 (base 5) = 1125 + 425 + 15 + 3 = 233 10 .

24

Assembler Language Programming for IBM z System Servers

Version 1.00

If you are still (or very) mathematically inclined:


Alternatively, since 10 (base 10) = 20 (base 5), we can do the conversion in base 5 arithmetic:
43
20)1413
130
113
110
3=e0

2
20)43
40
3=e1

0
20)2
0
2=e2

Again, we find 1413 (base 5) = 233 (base 10).


6. Convert X 3 E8 to base 10. In this case it is simpler to evaluate the positional notation:
X 3 E8 = 3162 + 14161 + 8160,
and then evaluate this sum in decimal. Thus we find
X 3 E8 = 3256 + 1416 + 8 = 768 + 224 + 8 = 1000.
This type of conversion can be simpler if you use the table of multiples of powers of 16 in Tables
2 and 3, or the conversion tables in Appendix A.

Exercises
2.4.1.(2) Perform the indicated conversions. For number bases greater than 10, assume that the
digits corresponding to 10, 11, 12, etc., are represented by the letters A, B, C, etc., respectively.
1. Convert 31659 (base 10) to bases 8, 4, and 2.
2. Convert 6917 (base 10) to bases 5, 13, and 16.
3. Convert X EF2A (base 16) to bases 10 and 13.
2.4.2.(2) + Make a table of the hexadecimal representations of the first ten powers of ten, from
100 to 10 9. (Suggestion: use hexadecimal arithmetic, and multiply each term by X A to obtain
the next.)
2.4.3.(3) Make a table like those in Tables 2 and 3, except that the nine multiples of the powers
of ten from 0 to 9 should be expressed in hexadecimal notation.
2.4.4.(3) Convert B1111101000 to base 10 using binary arithmetic (that is, divide by B1010).
2.4.5.(3) Convert 73294 (base 10) to bases 11, 12, 13, 14, and 15. Can you make any use of the
result of converting to base N to help in converting to base N+1?
2.4.6.(3) Make a base seven multiplication table. Use it to perform the following conversions
directly, without first converting to base ten: (1) 526 (base 7) to base 16, (2) 10110 (base 7) to
base 8, (3) 61436 (base 7) to base 8, (4) 666 (base 7) to base 10.
2.4.7.(2) Convert 629 (base 11) to bases 10 and 12.
2.4.8.(3) In converting from some base A to base 10, it is usually most convenient to expand
the positional notation as illustrated in Examples 5 and 6 of Section 2.4. We can also expand
the positional form by rewriting it in nested form:
X = (((...(dnA)+...+d3)A+d2)A+d1)A+d0.
That is, the leftmost digit is multiplied by A, the next digit is added to it and the result is multiplied by A, and so forth until the rightmost digit has been added. Using this technique, perform
the following conversions.
1. 2F3 (base 25) to base 10.
Chapter I: Getting Started

25

2. 61436 (base 8) to base 10.


3. X DEFACE (base 16) to base 10.
4. 999 (base 10) to base 16.
2.4.9.(2) In applying the nested multiplication technique of the previous exercise to conversions from base A to base B, what base should be used for the conversion arithmetic?
2.4.10.(3) Using the base seven multiplication table you made in Exercise 2.4.6, perform the
following conversions in base 7 arithmetic: (1) 526 (base 10) to base 16, (2) 10110 (base 2) to
base 5, (3) 61436 (base 8) to base 10, (4) 666 (base 10) to base 7.
2.4.11.(3) Write the decimal value 8 in bases 8, 7, 6, 5, 4, 3, 2, and 1.
2.4.12.(3) If you have two numbers in bases A and B, what is a necessary relationship between
A and B that will allow you to use the same digit grouping technique you used to convert
between binary and hexadecimal?
2.4.13.(3) Show the value of 1610 in bases 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, and 3.
2.4.14.(4) Using base 7 arithmetic, calculate the sum and product of 435 7 and 64 7. First,
convert those two numbers to base 10 and then add and multiply the results in base 10; then
use those results to test that you have evaluated the base 7 sum and product correctly.
2.4.15.(2) Convert the following decimal values to base 3: 2, 6, 10, 12, 16, 28, 41, 99, 104.

2.5. Number Representations


Now that we know how to convert numbers between binary and hexadecimal, we will see how
they are used in z System for address calculations, indexing, and integer arithmetic. Up to now,
we have examined the binary number representation only for nonnegative numbers; representing
negative numbers requires further consideration.
There are three fixed-point (integer) number representations in common use: the radixcomplement, the sign-magnitude, and the diminished radix-complement representations. In practice, the radix-complement representation is called the twos complement representation, and the
diminished radix-complement representation is called the ones complement representation. 12 Two
of these representations are used in z System: the twos complement form is used for addressing
and integer arithmetic, and the sign-magnitude form is used for floating-point and packed decimal
numbers. A variation of the radix-complement form is used internally for packed decimal arithmetic, which well see in Chapter VIII.
With so many representations, you might wonder why the z System designers settled on twos
complement. The reason follows from the processors architecture: since virtually all computers
use the twos complement representation for address arithmetic, and because in z System the
general registers are used for both arithmetic and addressing, it is natural that ordinary integer
arithmetic has the same form.
We will illustrate the following discussion using 32-bit numbers, corresponding (as we shall see) to
the length of a word in memory and half the length of a general register.13

12

13

26

Why is it called twos complement? The name of the ones complement representation seems obvious: just complement each bit by subtracting it from 1 (or, change 0 to 1 and 1 to 0); but we dont get the twos complement by
subtracting each bit from 2! Well explain this oddity shortly.
z/Architecture provides 64-bit general registers, but for now our examples will use the 32-bit length.
Assembler Language Programming for IBM z System Servers

Version 1.00

2.6. Logical (Unsigned) Representation


To begin, we examine what is represented by the rightmost 32 bits of any nonnegative integer.
This
0
1
130
224 1
231 1
231
32
2 1
232+ 1

is represented
by:
X00000000
X00000001
X00000082
X00FFFFFF
X 7 FFFFFFF
X80000000
X FFFFFFFF
X100000001

Thus, if a number is less than 232, its value can be held correctly in the 32 available bits. If it is
greater than or equal to 232, some significant bits are lost off the left end. (That is, the numbers
value is represented modulo 232.) Some instructions perform unsigned addition and subtraction
with numbers that satisfy the inequalities
0 x 232-1.
Such arithmetic is called logical or unsigned arithmetic; we call this the logical or unsigned representation of binary numbers. If the 32 bits of a logical binary integer are denoted b31,b 30,...,b 1,b 0
(this temporary scheme is the reverse of the field-numbering convention introduced in Figure 1
on page 14), then the value X represented by the binary digits b31 b 30...b 1 b 0 is
X = b31231 + b30230 + ... + b222 + b121 + b020
in the logical representation. This is the most common numeric interpretation of a string of bits.
The representation of a nonnegative 32-bit number less than 2 31 is the same in the signmagnitude, ones complement, and twos complement representations (and is also the same as its
logical representation), no matter which of the three forms is chosen to represent negative
numbers. Since the twos complement representation is used for most integer arithmetic in
z System, we will investigate its properties in detail. Arithmetic using binary numbers in this
representation will be covered shortly.

Exercises
2.6.1.(2) + Give the decimal value of the following hexadecimal numbers in the logical representation:
1. X DEADBEEF
2. X FFFFFFFF
3. X DEC0DED1

2.7. Twos Complement (Signed) Representation (*)


This section describes the mathematical justification for the twos complement representation.
You can skip to Section 2.8 where a simple recipe for calculating the twos complement of a
number is shown on page 29.
Most programs must deal with both positive and negative numbers. A single bit (usually, the leftmost) is used to represent the numbers sign. A 0 bit represents a + sign, and a 1 bit represents
a sign.
First, the twos complement representation of a 32-bit nonnegative binary integer Y satisfying the
inequalities
0 Y 2311 (numbers within that range with a + sign bit)
is the same as the logical representation. 231 1 is the largest integer that can be represented using
31 bits; the remaining (32nd) digit at the left end is zero, the sign digit.
Chapter I: Getting Started

27

Now, consider negative numbers. The twos complement representation of a negative integer Y
satisfying the inequalities
231 Y 1

(numbers within that range with a sign bit)

232 + Y.

is simply
The bit pattern representing this value can be found this way. The leftmost bit
is set to 1 to indicate that the number is negative, and the remaining 31 bits are set to the binary
representation of the nonnegative integer (231+Y). The result therefore satisfies the inequalities
0 231+Y 2311.
The reasons for representing negative numbers this way are not obvious, but we will see that it
leads to very simple rules for performing arithmetic on signed binary numbers.
In effect, we have done the following: if Y is positive, we find its value by adding the individual
terms (bi2i); because the leftmost (sign) bit is zero, it does not contribute to the sum. If Y is
negative, the sum of the rightmost 31 bits is (231+Y), and the leftmost bit is 1. Now, if we assign
value 231 to the sign bit, we can combine these to obtain
Y = (231)b31 + b30230 + ... + b222 + b121 + b020,
where the digits b30 through b 0 are the representation of 231+Y, not the representation of |Y|,
the absolute value of Y. This formula is almost the same as that used for the logical representation, except that the leftmost bit has negative weight. (There are good reasons to assign 231
to the sign bit.)
Finally, we will see how the representations of positive and negative numbers work together. The
relationship between the logical and twos complement representations is seen by examining the
above sum for the logical representation of X:
Xlogical = b31231 + b30230 + ... + b222 + b121 + b020.
If b31 is zero, the logical and twos complement representations yield the same value, and
Yarith = X logical. Now, suppose we are given the 32-bit twos complement representation of a
negative number Y arith , and we want to know the value those 32 bits would represent if we consider them as the logical representation of a number X logical. Since bit b31 is 1, indicating a negative number, and we represent the remaining 31 bits of Yarith by (Yarith + 231), we find that
Xlogical = 231 + (Yarith + 231) = (Yarith + 232) (modulo 232).
This is interesting: because we can only represent numbers less than 232 in the 32-bit logical representation, Y arith + 232 for nonnegative Y must have the same bit pattern as X logical, since the extra
(232) bit is lost. Thus, for
0 Xlogical 2321

and

231 Yarith 2311,

we have the following key relation between the logical and twos complement representations:
Xlogical = (Yarith + 232) (modulo 232).
That is, the bit pattern corresponding to the twos complement representation of any positive or negative number 231 Y + 231 1 is the rightmost 32 bits of the sum 232 + Y (modulo 2 32).
Why it is called two s complement?
This equation is the original source of the term twos complement. In
the earliest computers it was customary to treat binary numbers as fractions: the representation was the same as just described, except that the
binary point or radix point was assumed to lie just to the right of the
sign bit rather than at the right-hand end of the number, so that values
were in the range 1 value < + 1. The equation giving the relationship between logical and arithmetic representations was then written
X = Y + 2 (modulo 2),
so that the representation of a negative number was obtained by finding
its complement with respect to 2: its twos complement.

28

Assembler Language Programming for IBM z System Servers

Version 1.00

Calculating the twos complement representation of a negative number is very cumbersome if we


follow the above steps for any negative number Y: we would first have to calculate the binary
representation of the positive quantity 231+ Y . But calculating (231 1+Y)+1 instead is very
simple, because the representation of 231 1 is exactly 31 one-bits. Now, because Y is negative,
2311 + Y = (2311) |Y|.
Thus |Y|, the magnitude of Y, is subtracted from a string of 31 one-bits. But wherever |Y| has a
one bit, the resulting difference bit will be zero, and vice versa. Thus, there is no need to subtract!
Just change each of the 31 bits of |Y| to its opposite (namely the result of subtracting it from 1),
and we have the value of 231 1 |Y|. This result is called the ones complement of |Y|. Finally,
we add 1 to the rightmost bit position to get 231+Y, set the leftmost bit (the sign bit) to 1, and
we are done.
If Yarith was nonnegative, complementing all 32 bits automatically sets a 1-bit in the sign; and if
Yarith was negative, complementing all 32 bits sets the sign to zero. So, we dont have to do
anything special with the sign bit!
This simple method lets us find the binary representation (in the twos complement representation) of a negative number, as we will see in the next section.

Exercises
2.7.1.(3) Convert X AB0DE to base 15, using hexadecimal arithmetic throughout.
2.7.2.(3) We saw that the radix-complement representation of a number Y in radix r with n
digits is
rn+Y (modulo rn)
Suppose r=10 and n=4. Show the tens-complement representation of the following values,
and indicate which are and are not validly representable.
(a) + 729, (b) 729, (c) 1, (d) + 9999, (e) 5000, (f) + 5000, (g) 9999.
2.7.3.(2) What is the decimal value of the 12-bit binary number 100000000001 in a signed twos
complement representation?
2.7.4.(3) Based on your results of Exercise 2.7.3, give an expression for the value of the n-bit
binary number 10000...000001 in a signed twos complement representation.
2.7.5.(3) + Knowing the logical representation of the three numbers in Exercise 2.6.1, convert
them to their signed decimal representation.

2.8. Computing Two s Complements


A simple scheme for computing twos complements is based on the observation that the representation of a negative number Y is simply 232 |Y|.
Two s-Complementation Recipe
Given a binary number Y, to find the twos complement representation
of Y:
1. Take the ones complement of all bits of Y: change 0 digits to 1,
and 1 digits to 0.
2. Add 1 in the low-order (rightmost) position, and ignore carries out
of the leftmost position.
These two examples do the arithmetic with eight binary digits rather than thirty-two.
1. Find the twos complement representation of 2.
Chapter I: Getting Started

29

(1) representation of +2:


(2) form ones complement:
(3) add one:

0000 0010
1111 1101
+
1
1111 1110

2. Find the twos complement representation of 75.


(1) representation of +75:
(2) form ones complement:
(3) add one:

0100 1011
1011 0100
+
1
1011 0101

This recipe also works in the opposite direction.


3. Find the twos complement representation of B11111110 (2).
(1) form ones complement:
(2) add one:

0000 0001
+
1
0000 0010

This is the binary representation of +2; thus the twos complement of the twos complement of a
number is the original number. So, our recipe for computing complements does not depend on
the sign of the original operand.
Two unusual cases arise during complementation when all the bits except the sign bit are zero:
the complemented result is the same as the original operand.
4. Find the twos complement representation of B00000000.
(1) form ones complement:
1111 1111
(2) add one:
+
1
(carry one off left end) 0000 0000
The result is zero, and the carry of a 1 bit out the left-hand end is lost. Thus the negative of zero
is still zero. This is mathematically satisfying: there is no negative zero.14
5. Find the 8-bit twos complement representation of B10000000.
(1) form ones complement:
(2) add one:

0111 1111
+
1
1000 0000

In this case, the complement of the number is also the same as the original number. This particular number, a negative sign bit with all other bits zero, is called the maximum negative
number. It is well defined, and behaves normally in all arithmetic operations except that is has
no representable negation.
The maximum negative number has no corresponding positive value available for the representable negative value. We say that we have generated an overflow condition the result is too large
to fit into the number of bits allotted for it. Overflow will be treated in more detail in the following sections on twos complement arithmetic.
Some examples of numbers in the 32-bit arithmetic representation are shown in Table 4 on
page 31.

14

30

Some older computers used the ones complement representation for binary integers, so negative zeros were possible.
z System packed decimal and floating-point numbers (discussed in Chapters VIII and IX) support negative zeros.
Assembler Language Programming for IBM z System Servers

Version 1.00

Decimal Value
0
1
256
5000
+ 2147483647 ( + 231 1)
2147483648 ( 231)
2147483647 ( 231+ 1 )
5000
256
2
1

32-bit Twos
Complement
Representation
X00000000
X00000001
X00000100
X00001388
X 7 FFFFFFF
X80000000
X80000001
X FFFFEC78
X FFFFFF00
X FFFFFFFE
X FFFFFFFF

Table 4. Examples of twos complement representation

The number of values with positive sign is the same as the number of values with negative sign,
since every bit may be chosen arbitrarily. Because zero has a positive sign bit, it is sometimes
treated as a positive number, even though (mathematically) it has no sign. If we exclude zero as a
positive number, then there is one fewer member of the set of positive values than of the set of
negative values, since there is no representation for +231. With 32 bits, we can represent 232
values: between 1 and 231 there are 231 values; 0 is a single value; between +1 and +2 31 1
there are 231 1 values. The total number of possible signed values is therefore 231+ 1 + ( 2 31 1),
or 232 .
Unfortunately, the terminology used to describe this process can be confusing. We are actually
describing the mathematical operation of negation that turns a value into its negative. For other
number representations, the operation that forms the negative of a number will be different,
because there are many ways to represent a negative number. However, sometimes
complementation is used to describe the operation of negation! For example, we often talk about
the binary representation of some number, and then say that in negating that quantity we have
formed its twos complement.

Exercises
2.8.1.(1) Why does the simple two-step prescription for computing complements given above
not depend on the sign of the number being complemented?
2.8.2.(2) + Give the decimal values represented by each of the following 16-bit numbers,
assuming that the binary values are in twos complement representation:
1.
2.
3.
4.
5.

X0257
X 7 FFA
X8008
X E000
X FFFA

(See Exercise 2.3.4. also.)


2.8.3.(2) It is sometimes said that the complement of a number X is the same as X. State this
more precisely.
2.8.4.(2) Four 16-bit areas of a program are named A, B, C, and D. Their contents are
c(A)
c(B)
c(C)
c(D)

=
=
=
=

X 7 D40
X D000
X15A2
X800A

If they are the signed 16-bit twos complement binary representations of four decimal numbers,
determine their decimal values.
Chapter I: Getting Started

31

2.8.5.(2) Given the quantities Z = 0, A = 1, B = 9, C = 62, D = 101, E = 255, F = 256,


give the nine-bit (eight bits plus sign) representations of the positive and negative values of each
quantity in the twos complement representation.
2.8.6.(3) Give the 32-bit twos complement representation (in either hexadecimal or binary) of
both the positive and negative values of the following decimal integers: (a) 10, (b) 729, (c)
1000000, (d) 1000000000, (e) 2147483648, (f) 65535, (g) 2147483647.
2.8.7.(3) Sometimes twos complementation is described by these steps:
Subtract 1
Complement all bits
Does this differ from the twos complementation recipe given on page 29? Create examples that
show how this form does or does not differ from that recipe.
2.8.8.(1) Give the 16-bit twos complement binary representation of each decimal number in
hexadecimal:
1. + 13055
2. 9582
2.8.9.(2) + Show the 32-bit hexadecimal value of the twos complement binary representation of
each of the following decimal values:
1.
2.
3.
4.
5.
6.

+5
97
+ 65795
16777158
+ 16777219
78606

2.8.10.(1) + Assuming a 16-bit twos complement representation, give the signed decimal values
of these hexadecimal values:
1.
2.
3.
4.

X B00F
X FFF1
X 0 FFF
X F001

2.9. Sign Extension


In the representation of nonnegative numbers, an arbitrary number of zero bits may be attached
to the left end of a number without affecting its value. For example, the 8-bit and 16-bit representations of +9 are
B0000 1001

and

B0000 0000 0000 1001

respectively. Similarly for negative numbers, we can add any number of 1 bits at the left without
affecting the value. For example, the 8-bit and 16-bit twos complement representations of 9 are
B1111 0111

and

B1111 1111 1111 0111

respectively. Thus, for numbers that can be represented correctly in a given number of bits, the
correct representation using a larger number of bits is found by duplicating the sign bit toward the
left as many places as desired. This is called sign extension, and is illustrated in the following:
Length
8 bits
16 bits
32 bits
64 bits

32

Representation of +1
X 0 1
X0001
X00000001
X0000000000000001

Assembler Language Programming for IBM z System Servers

Version 1.00

Representation of 1
X FF
X FFFF
X FFFFFFFF
X FFFFFFFFFFFFFFFF

Table 5. Examples of sign extension

We will discuss sign extension again when we examine instructions that perform shifting, and
instructions that perform arithmetic on operands of different lengths.

Exercises
2.9.1.(2) Provide the 32-bit sign extensions in binary and hexadecimal notation of the five items
in Exercise 2.8.2.

2.10. Binary Addition


Though number-representation details may vary slightly from one processor to another, the
methods for performing binary arithmetic remain nearly the same for all processors. Thus the following is slightly more general than if only z System is discussed. The rules for adding binary
digits are:
0
+0
0

0
+1
1

1
+0
1

1
+1
10 (carry)

Adding numbers in the logical representation is simplest, because all the bits are numeric digits
and do not represent signs. The only unusual condition is whether or not a carry occurs out of
the leftmost digit position, which would indicate whether the resulting sum is or is not correctly
representable by the number of bits available.
In the twos complement representation, addition is performed in the same way, but the result is
interpreted somewhat differently.
1. All bits of each operand are added, including sign bits, and carries out the left end of the sum
are lost. (This is the same as for adding numbers in the logical representation.)
2. If the result cannot be correctly represented using the number of digits available, a fixed-point
overflow condition occurs. The actions taken when an overflow condition occurs will vary;
sometimes it can be ignored.
Using signed 4-bit binary values, we know that valid values must lie in the range
8 value + 7. we first add B0010 ( + 2) to itself, and then we add B0100 ( + 4) to itself.
0010
+0010
0100 (no overflow)

0100
+0100
1000 (overflow)

In the first case, 2 + 2=4, which lies in the representable range for our 4-bit numbers. But in the
second case, 4 + 4 = 8, because + 8 is not representable. That is, the sum has overflowed.
A fixed-point overflow condition is possible only when adding operands of like sign: adding
numbers with opposite signs always produces a representable result (or, as is often said, the result
is in range). When an overflow occurs, the sign of the result is always the opposite of the sign of
the two operands. The actual method used to detect overflow is simpler, since sign-change
detection would require remembering the signs of both operands for comparison against the sign
of the sum. Here is how its done:
Overflow Detection Recipe
If the carries into and out of the sign bit position disagree, arithmetic
overflow has occurred.
There are two kinds of binary addition: arithmetic and logical. They produce identical bit patterns, as we will see in Section 2.14. Overflow is detected only for arithmetic addition, while
logical addition is concerned only with a possible carry out of the high-order bit position.
Chapter I: Getting Started

33

Exercises
2.10.1.(2) + Consider adding the 8-bit binary number X F5 to itself. There is no carry from
X 5 +X5=X A , but there is a carry from X F +X F=X 1E . Since the carry out of the loworder digit position is different from the carry out of the high-order digit position, has overflow
occurred?

2.11. Binary Subtraction


Subtraction is performed by adding the twos complement of the number to be subtracted, the
second operand. That is, A B is calculated as A + ( B), where ( B) is the twos complement of
B. A few examples using 8-bit binary twos complement arithmetic will help illustrate addition
and subtraction.
While this prescription is essentially correct, there is a minor but important complication well
examine after illustrating the basic scheme. (In Examples 6 and 7, note that the carries into and
out of the high-order bit are different.)
Example 1.
5-3:

0000 0101
-0000 0011

becomes

(carry lost)

0000 0101
+1111 1101
0000 0010 = 2

Example 2.
3-5:

0000 0011
-0000 0101

becomes

(no carry)

0000 0011
+1111 1011
1111 1110 = -2

Example 3.
25-(-17):

0001 1001
-1110 1111

becomes

(no carry)

0001 1001
+0001 0001
0010 1010 = 42

Example 4.
(-17)-25:

1110 1111
-0001 1001

becomes

(carry lost)

34

1110 1111
+1110 0111
1101 0110 = -42

Assembler Language Programming for IBM z System Servers

Version 1.00

Example 5.
-17-(-25):

1110 1111
-1110 0111

becomes

(carry lost)

1110 1111
+0001 1001
0000 1000 = 8

Example 6.
67-(-93):

0100 0011
-1010 0011

becomes

(no carry)

0100 0011
+0101 1101
1010 0000 = -96 (overflow)

Example 7.
(-93)-67:

1010 0011
-0100 0011

becomes

(carry lost)

1010 0011
+1011 1101
0110 0000 = 96 (overflow)

Example 8.
-128-(-93):

1000 0000
-1010 0011

becomes

(no carry)

1000 0000
+0101 1101
1101 1101 = -35

Example 9.
3-3:

0000 0011
-0000 0011

becomes

(carry lost)

0000 0011
+1111 1101
0000 0000 = 0

The above examples illustrate addition and subtraction and give the expected results. However,
there is one case where the method as given above fails to detect correctly the presence or absence
of overflow, and this occurs when the maximum negative number is being subtracted from something. (This is the minor complication mentioned previously.)
Example 10.
1-(-128):

0000 0001
-1000 0000

becomes

(no carry)

0000 0001
+1000 0000
1000 0001 = -127 (no overflow found?)

Example 11.
-1-(-128):

1111 1111
-1000 0000

becomes

(carry lost)

1111 1111
+1000 0000
0111 1111 = +127 (overflow indicated?)
Chapter I: Getting Started

35

In each of these two last cases, the result seems to be arithmetically correct, but our original overflow indication is incorrect. This is because taking the twos complement of the maximum negative number before adding it has already generated an overflow condition. To see how the
processor can still use our overflow detection scheme as originally described (the carries into and
out of the leftmost bit differ), it is worth examining the actual addition process in slightly more
detail. The next section may be omitted if you are uninterested in such details, but be sure to
learn the Binary Subtraction Recipe on page 37.

Exercises
2.11.1.(2) Give the 32-bit integer representation in hexadecimal or binary of the result of the
following operations, where the operands are given as decimal numbers.
1.
2.
3.
4.
5.
6.

10 ( 10)
729 65535
2147483647 + 2
1000000000 + ( 2147483647)
0 ( + 0)
( 10) + 10

Do the arithmetic in the twos complement representation, indicating for each case (1) the presence or absence of overflow, and (2) the presence or absence of a carry out of the leftmost digit
position.
2.11.2.(2) Assume that the values defined in Exercise 2.8.4 are used to compute three 16-bit
numbers X, Y, and Z. Using 16-bit binary arithmetic, determine the final (hex) contents of the
16-bit fields named X, Y, and Z, and whether or not an overflow condition has occurred.
c(X) = c(A) - c(C)
c(Y) = c(B) + c(D)
c(Z) = c(A) + c(D)
2.11.3.(3) Suppose you want to subtract 1 from a binary number. A suggested technique uses
these two steps: (1) change all the rightmost zeros to ones, and (2) change the previous rightmost one to zero. Create examples to show that this technique is or is not correct.
2.11.4.(4) Assume that the method in Exercise 2.11.3 is correct. How can you detect overflow
conditions?
2.11.5.(2) Evaluate each of the following 32-bit sums and differences, and in each case determine (a) whether an arithmetic overflow occurs, and (b) whether there is a carry out of the
leftmost bit.
1.
2.
3.
4.
5.
6.

X 7 D26F071+X B40E99A4
X 7 D26F071 -X B40E99A4
X FFFFF39A+X FFFE4B06
X FFFFF39A -X FFFE4B06
X80000003+X0000007C
X80000003+X8000007C

2.12. How Additions and Subtractions Are Actually Performed (*)


Remember that the twos complement of a number (the twos complement representation of the
negation of a number) is found by inverting each bit of the number and then adding a one in the
low-order position. Digital circuits that invert bits are called NOT circuits. Similarly, adding a 1
bit to the low-order digit position is also easy, because each digit position of an adder circuit must
add the corresponding bits of the two input operands A and B, and the carry bit from the next
lower-order bit position, as illustrated in Figure 2.

36

Assembler Language Programming for IBM z System Servers

Version 1.00


Bit n of
Operand A

Carry bit Adder  Carry bit


to Adder Positionfrom Adder
Position n+1 n
Position n-1

Bit n of
Bit n of
sum A+B 
Operand B

Figure 2. One stage of a binary adder

In the lowest-order position of the adder there will be no carry from a lower-order bit position.
However, if an identical adder circuit is used, it still has a carry input that can be used to insert
the 1 bit to be added to the low-order position during a complementation or subtraction operation! Thus subtraction is simply a matter of passing the second operand through a bit inverter
(forming the ones complement), and then activating the low-order carry input to the adder to add
the required one-bit.
Binary Subtraction Recipe
Subtraction is performed by adding the ones complement of the second
operand and a low-order one-bit to the first operand, in a single operation. The subtraction in Example 10 is evaluated this way:
1-(-128):

0000 0001 first operand


-1000 0000 second operand

becomes
0000 0001 first operand
0111 1111 ones complement of second operand
+
1 complementation bit
(0)1000 0001 (overflow!)
An overflow is indicated because carries into (1) and out of the high-order bit (0) are different.

Exercises
2.12.1.(2) For each of the quantities defined in Exercise 2.8.5, compute the following nine-bit
values, indicating for each case whether or not there is a carry out of the high-order digit position, and whether or not an overflow has occurred. (Some of the values may not be representable; state which.) (a) A + C; (b) D E; (c) Z + ( F); (d) ( E) C; (e) ( B) + A; (f) C Z; (g)
A + ( A).
2.12.2.(3) In the ones complement representation, subtraction is sometimes described this way:
Take the ones complement of the subtrahend (the number to be subtracted), and add the
operands. Cross off the high-order digit and add 1 to the sum.
If the subtrahend is greater than the minuend (the number from which the subtrahend is
subtracted), take the ones complement of the subtrahend, add the operands, then complement the result and put a minus sign in the high-order position.
Construct some examples showing how this process works, for operands of both signs and of
various magnitudes.

Chapter I: Getting Started

37

2.13. A Circular View of Binary Arithmetic (*)


Well use a four-bit binary representation to illustrate some concepts we have been discussing.
The circular diagram in Figure 3 contains all 16 possible four-bit numbers.

o 0100
0101 o

o 0011

0110 o

o 0010

0111 o

o 0001

x overflow point

0000
o
1000

carry point x

1001

1111

1010

1110

1011

1101
1100

Figure 3. Circular representation of twos complement representation

First, suppose the numbers are considered to be the logical representation of the integers from 0
to 15. Counting up from 0000 by one takes us around the circle counter-clockwise from 0000 to
1111 and then back to 0000, as we would expect for numbers modulo 2 4. Adding and subtracting
two numbers can be thought of as adding and subtracting the angles (measured counter-clockwise
from 0000) represented by the numbers. Thus,
0100 + 0110 = 1010,

and

1100 + 0111 = 0011.

A carry condition occurs in addition if we go past the carry point in the counter-clockwise
direction; similarly, a borrow condition occurs in subtraction if we go past the carry point in
the clockwise direction.
For the twos complement representation, the negative of a number is the one vertically opposite
it across the horizontal axis. Thus, the negative of 0011 is 1101, and the negative of 0001 is 1111.
We also see that the numbers 0000 and 1000 are their own negatives, just as we found in examples 4 and 5 of Section 2.8 above.
Now, consider the numbers to be the signed 4-bit twos complement representation of the integers
from 8 to +7. In the figure, the numbers with a zero sign bit are represented by open circles (o),
and the numbers with a sign bit = 1 are represented by the solid black dots (). As before, we
can visualize adding and subtracting numbers by adding or subtracting the corresponding angles
represented by the numbers. Now, however, we can detect overflow conditions as well: if in
adding or subtracting we move in either direction past the overflow point between 1000 and
0111, an overflow condition occurs. Thus if we add
0110 + 0011 = 1001
we generate an overflow by passing the overflow point in a counter-clockwise direction. Similarly,
in the subtraction
1010 - 0110 = 0100
we generate an overflow by passing the overflow point in a clockwise direction.

38

Assembler Language Programming for IBM z System Servers

Version 1.00

Experiment with this diagram; it reveals many properties of twos complement arithmetic.

Exercises
2.13.1.(3) + In many early editions of the System/360 Principles of Operation, the Subtract operation was described as follows: Subtraction is performed by adding the twos complement of
the second operand to the first operand. All 32 bits of both operands participate. If the carries
out of the sign-bit position and the high-order numeric bit position agree, the difference is satisfactory; if they disagree, an overflow occurs.
This differs from the subtraction rule given in Section 2.13. Construct one or more examples
that will show that these two descriptions are not precisely equivalent.

2.14. Logical (Unsigned) and Arithmetic (Signed) Results (*)


We can show that the correct algebraic result is obtained by simply adding all the bits of the
operands in the twos complement representation as though they were logical operands. For
32-bit operands, the logical representation X corresponding to an arithmetic signed integer x satisfies the relation
X = 232 + x (modulo 232),
then the sum of two logical operands X and Y is
(X + Y) = 232 + 232 + (x + y) (modulo 232)
= 232 + (x + y) (modulo 232)
= x + y
Thus the arithmetic and logical sums give the same binary result; the leftmost bits and the highorder two carry bits are just interpreted differently in the two representations.
Logical vs. arithmetic
Logical and arithmetic sums and differences of binary integers produce
identical bit patterns.
We can make a further observation about adding and subtracting numbers in the logical representation. From the examples in Section 2.11, we see that subtraction if the second operand is logically smaller than or equal to the first (see examples 1, 4, 5, 7, 9, and 11) then there will be a
carry out of the leftmost bit position. Conversely, we see (in examples 2, 3, 6, 8, and 10) that if
the first operand is logically smaller than the second operand subtracted from it, there is no carry
out of the left end. In these latter cases we have in some sense generated a negative logical
answer, since the result is not correctly represented to the given number of bits. Well see examples of these cases when we examine instructions that perform logical arithmetic.

Exercises
2.14.1.(2) Assuming an eleven-bit word, give the logical and twos complement representations
of the following quantities: (a) 200, (b) 1023, (c) 1000, (d) 2047, (e) 1, (f) 1024, (g) 1023,
(h) 1024, (i) 0. If a quantity is not representable, indicate that it is not.
2.14.2.(2) + Consider the four five-bit binary numbers
A=11111, B=00010, C=10000, D=01111.
For each pair of values (like A+A, A+B, etc.) determine (a) their sum, (b) whether or not a
carry occurs, and (c) for arithmetic addition, whether or not an overflow occurs. Display the
results in a short table. (Because addition is commutative: X+Y = Y+X you will need to
evaluate only ten sums.)

Chapter I: Getting Started

39

2.14.3.(3) + Using the same values for A,B,C,D in Exercise 2.14.2, determine the result, the carry
condition, and the arithmetic overflow condition for pair-wise subtraction (like A-B, B-A, etc.)
of these values. Display your results in a short table; this time your table will need all 16
entries, because subtraction is non-commutative: X Y Y X.
2.14.4.(2) + Can an overflow be caused by subtracting two numbers of opposite signs?

2.15. Examples of Representations (*)


It may help to see the differences among the sign-magnitude, radix complement (twos complement), and diminished radix-complement (ones complement) representations. 15 All 5-bit binary
numbers with positive and negative values would be represented as shown in the following table.
Binary
Digits
00000
00001
00010
00011
00100
00101
00110
00111
01000
01001
01010
01011
01100
01101
01110
01111
10000
10001
10010
10011
10100
10101
10110
10111
11000
11001
11010
11011
11100
11101
11110
11111

Logical
SignRepresentation Magnitude
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31

Ones
Complement

Twos
Complement

+0
+1
+2
+3
+4
+5
+6
+7
+8
+9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
15
14
13
12
11
10
9
8
7
6
5
4
3
2
1
0

0
+1
+2
+3
+4
+5
+6
+7
+8
+9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
16
15
14
13
12
11
10
9
8
7
6
5
4
3
2
1

+0
+1
+2
+3
+4
+5
+6
+7
+8
+9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

In the sign-magnitude and ones (diminished radix) complement representations, there are two
distinct representations for zero. In the twos (radix complement) representation, there is no representation for +16 corresponding to the valid representation for 16.
The sign bit in the sign-magnitude representation is attached to the (unsigned) magnitude of the
value. However, the sign bit in the twos complement representation is not just an indicator: it
is numerically significant.

15

40

More formally, the representation in radix r of an n-bit negative number X is r n X in the twos complement representation, and (r n 1) X in the ones complement representation.
Assembler Language Programming for IBM z System Servers

Version 1.00

Representing signed numbers in a computer always involves tradeoffs: how should peculiar
cases like these be handled?

Exercises
2.15.1.(2) Suppose your computer uses the tens complement representation for integers. (This
representation was very widely used in mechanical desk calculators, and in many early computers.) Write the following values in tens-complement notation: (a) + 28, (b) 49, (c) + 527,
(d) 333, (e) 1234, (f) + 2469.
2.15.2.(3) Using the representations you calculated in Exercise 2.15.1, evaluate the following
using tens complement arithmetic: (a) + 28 + ( 49), (b) + 527 + ( 333), (c) 1234 + 2469.
2.15.3.(3) Write the values in Exercise 2.15.1 in the diminished radix-complement (nines complement) representation.

Terms and Definitions


bit
A binary digit, taking values 0 and 1.
hexadecimal
A base-16 representation. Its digits are 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F.
hex
See hexadecimal.
logical representation
An unsigned number representation.
arithmetic representation
A signed number representation.
sign-magnitude representation
The familiar signed representation of numbers with prefixed + or signs.
radix-complement representation
A signed representation where the numerically significant high-order digit contains sign information.
twos complement representation
A signed binary representation where the high-order bit contains sign information, and has
weight 2 n 1.
diminished radix-complement representation
A signed representation where negative numbers are represented by subtracting each digit
from (the radix minus 1).
ones complement representation
A signed binary representation where negative numbers are represented by changing each 0
bit to a 1 bit and vice versa.
overflow
The sum, difference, product, or quotient of two numbers is too large to be correctly represented in the number of digits provided.

Chapter I: Getting Started

41

42

Assembler Language Programming for IBM z System Servers

Version 1.00

Chapter II: z System

IIIIIIIIII
IIIIIIIIII
II
II
II
II
II
II
II
II
IIIIIIIIII
IIIIIIIIII

IIIIIIIIII
IIIIIIIIII
II
II
II
II
II
II
II
II
IIIIIIIIII
IIIIIIIIII

This chapters three sections introduce the main features of z System processors:
Section 3 describes basic structures memory organization and addressing, general purpose registers, the Program Status Word (PSW), and other topics.
Section 4 discusses the instruction cycle, basic machine instruction types and lengths,
exceptions and interruptions and their effects on the instruction cycle.
Section 5 covers address calculation, the addressing halfword, Effective Addresses, indexing,
addressing problems, and virtual memory.

Chapter II: z System

43

3. Conceptual Structure of z System

3333333333
333333333333
33
33
33
33
3333
3333
33
33
33
33
333333333333
3333333333

We can describe the structure of most computers in terms of four functional units: memory, arithmetic, control, and input-output. A real computer may not identify components this way, but it
helps us to think of them as distinct units.

Control

Control

Arithmetic  Control  Inputoutput


Unit
Unit

Unit




Data
Data
Data


Memory

Figure 4. Conceptual structure of a typical computer

The solid lines in Figure 4 represent data paths among the various units, and the dashed lines
indicate the flow of control signals. As indicated, the same memory holds instructions for the
control unit and the data used by the arithmetic and input-output units. This gives modern digital
processors their flexibility and power: they can treat instructions as data or data as instructions.
z System makes no special distinction between the arithmetic and control units, and the combination is often called the Central Processing Unit, or CPU.

44

Assembler Language Programming for IBM z System Servers

Version 1.00


Control

Central Processing
  Inputoutput

Unit

Unit



Data
Data

Memory

Figure 5. Conceptual structure of z System

Memory is sometimes called central storage or similar terms. It refers to that part of the
processor holding the directly accessible instructions and data to be manipulated by those
instructions.
As Figure 5 indicates, input and output once initiated by the CPU is performed between
external devices and memory, and does not pass through the CPU. The Input-output Unit communicates the status of its operations to the CPU, indicating error conditions or completion of
the operation.

3.1. Memory Organization


Digital computers deal with data consisting of binary digits, easily and rapidly accessed from
central memory. The basic data item is an eight-bit group called a byte.16 The bits in a byte are
numbered from 0 to 7, beginning on the left with the numerically most significant digit. (The
importance of designating the left side of a byte will be clearer when we consider groups of
bytes.) In Figure 6, the leftmost bit is a 1-bit, and the rightmost bit is a 0-bit.
8 bits

11010010

0
7
Figure 6. A byte containing 8 binary digits

Bytes in memory are arranged so that each byte may be referenced as easily as any other. The
bytes are individually numbered beginning at zero; the number associated with each byte is called
its memory address. Memory may be thought of as a linear string of bits; the bits are grouped
into bytes arranged in order of increasing addresses. Only bytes have addresses; bits within a byte
dont have their own addresses.
.. 701
702
703
704
705
706
707 ..

byte byte byte byte byte byte byte

Figure 7. A portion of memory, with addresses shown above each byte

The bits in a byte are accessed (or read) by the CPU without being changed. Reading the contents of a byte does not affect the contents; the memory provides the CPU with a copy of the

16

Because the eight bits in a byte are often described using two hex digits, some people like to call a half byte hex
digit a cute name like nibble or even nybble. We wont.
Chapter II: z System

45

contents of a byte. Storing (or writing) a new bit pattern into a byte replaces the previous contents.
Many machine instructions referring to memory actually refer to a group of consecutive bytes. In
such situations the group is normally addressed by referring to its leftmost member, the byte with
the lowest address in the group.17 Also, some instructions require the address of a group of bytes
(the address of the leftmost byte) to also be a multiple of the length of the group, in which case
we say that the group is aligned.18 The possible lengths for such groups of bytes are 2, 4, 8, or 16;
we sometimes refer to them as halfwords, words (or fullwords), doublewords, and quadwords
respectively.
8DF 8E0 8E1 8E2 8E3 8E4 8E5 8E6 8E7 8E8 8E9 8EA 8EB 8EC 8ED 8EE 8EF 8F0

halfword halfword halfword halfword halfword halfword halfword halfword


wordwordwordword
doubleworddoubleword
quadword

Figure 8. A portion of memory

When some operation manipulates a group of bytes, we call that group an operand: something
that is operated on. The group always consists of data from consecutively-addressed bytes in
memory.
Some operations treat the operand as a string of bits whose meaning for that operation is independent of the fact that they are arranged into 8-bit bytes in memory. For example, suppose a
halfword operand (a group of two bytes whose address is divisible by 2) is specified for an operation, and the address of the 16-bit operand is X 8EA . Then the 16 bits in the bytes at X 8EA
and X 8EB will be treated as a single 16-bit halfword, and we ignore the fact that they are stored
in memory as two distinct eight-bit bytes. Thus, bit 0 of the halfword operand its leftmost
bit corresponds to bit 0 of the byte at X 8EA , and bit 15 of the halfword operandits rightmost
bit corresponds to bit 7 of the byte at X 8EB .19
Bytes in memory contain only bit patterns. Whether the bit pattern is interpreted as an instruction, or as one of many types of data, depends only on the context of its use; at one time it may
be data, and at another, an instruction. Whatever the interpretation, however, a byte is simply a
group of eight bits.
We now see why we use hexadecimal (base 16) notation for expressing binary numbers instead of
octal (base 8) notation. It is simplest to arrange bits in groups of the same size, and the presence
of eight bits in a byte makes four-bit groups natural. A half-byte contains 4 bits, exactly the
number of bits needed to represent one hex digit. If octal notation is used, a byte would contain
two three-bit octal digits and two extra bits.

Exercises
3.1.1.(2) + An area of memory reserved for data begins at address X 2EC9 and ends with
address X 30A6 (including the start and end bytes!). How many bytes are there in the area,
and how many halfwords, words, and doublewords can be stored in the area?
3.1.2.(1) The memory of z System can be thought of as a continuous string of bits. Does each
individual bit in memory have an address? Explain.

17
18

19

46

This is true with few exceptions, which we will note as they appear. For now, remember leftmost as the rule.
In early System/360 processors, many memory operands had to be aligned on byte boundaries whose addresses were
a multiple of the operands length. While this is no longer required for most (but not all) instructions, proper alignment is always a good programming practice.
z/Architecture processors use what is called big-endian addressing; well examine endianness in detail in Chapter
VII, Section 26.7.
Assembler Language Programming for IBM z System Servers

Version 1.00

3.1.3.(2) Suppose we are interested in the string of contiguous bits starting with bit 5 of
memory address X 1A023 and ending with bit 1 of the byte at memory address X 1A03B
(including the start and end bits). Determine the number of bits in the string.
3.1.4.(1) State which of the following addresses refer to halfwords, words, and doublewords: (1)
X 123456 ; (2) X 234567 ; (3) X 345678 ; (4) X 000BBC .
3.1.5.(1) Determine the number of bits that can be stored in a memory area of the following
sizes: (1) X 20000 bytes, (2) X 8000 bytes, (3) X 200000 bytes.
3.1.6.(1) Express the contents of the byte in Figure 6 in octal notation and in hexadecimal notation.
3.1.7.(1) + If you examine the rightmost hex digit of a memory address, what can you tell about
the alignment of the address?

3.2. Central Processing Unit


The CPU performs the operations specified by your program. An important element of the CPU
is a set of registers, a special and very fast form of memory kept very close to the instruction and
data processing functions of the CPU.
The general registers are used for arithmetic and logical operations, and to hold addresses of
data and instructions; 20
the Floating-Point Registers are used for floating-point arithmetic and data;
the Program Status Word is used by the CPU to control the progress of your program as it is
executed.

3.3. General Registers


There are sixteen general registers, numbered from zero to fifteen. Each is 64 bits (or 16 hex
digits or 8 bytes) long. They are represented schematically in Figures 9 and 10.
 64 bits
 32 bits  32 bits

0
31 32
63
Figure 9. A single 64-bit general register

When we discuss instructions that do 32- and 64-bit arithmetic, well understand why this picture
shows two 32-bit parts of a 64-bit general register.

20

Because the general registers are used for so many activities, they are sometimes called General Purpose Registers.
Chapter II: z System

47

General Register 0

General Register 1

General Register 2

General Register 3

General Register 4

General Register 5

General Register 6

General Register 7

General Register 8

General Register 9

General Register 10

General Register 11

General Register 12

General Register 13

General Register 14

General Register 15

Figure 10. All sixteen general registers

This figure arranges the registers in pairs, the left register being even-numbered and the right being
the next higher odd-numbered register. Some operations require using a pair of registers, and in
such cases it is always an even-odd-numbered pair.
We will often refer to the general registers using a short notation: we sometimes write GRn
(meaning the rightmost 32 bits of a 64-bit register) or GGn (meaning all 64 bits) or simply
Rn to refer to general register n when the register length is clear from context. Thus, in Figure
10, we might use R1 to mean register 1, R14 to mean register 14, and so on.
Be Careful!
R1 (without a subscript) is not the same as the notation R 1 (with a
subscript). This difference will be important when we discuss machine
instructions.

Exercises
3.3.1.(1) Suppose a shifting operation requires the use of a pair of general registers. Is it possible
to perform the shifting operation using both GR7 and GR8? Using GR15 and GR0? Using
GR6 and GR7?
3.3.2.(1) How many bytes can be placed in a pair of general registers?

3.4. Floating-Point Registers


On the earliest System/360 models only four floating-point registers were available, and then only
as an option. Sixteen are always present in z System processors, as we will see in Section 32.7.
Each is 64 bits (16 hex digits, 8 bytes, or 1 doubleword) long. We will look into this more deeply
when we discuss floating-point instructions and data in Chapter IX.

48

Assembler Language Programming for IBM z System Servers

Version 1.00

 64 bits

F0

F2

F4

F6

0
63
Figure 11. Four Floating-Point Registers

Sometimes the floating-point registers contain operands 32 bits long. In this case they use only
the left half of the register, and the rightmost 32 bits are ignored. In other situations, a floatingpoint instruction using 128-bit operands will use a pair of floating-point registers.
We wont mention the floating-point registers until we discuss instructions for floating-point arithmetic. We sometimes use the abbreviations FPRn or FRn or Fn to refer to floating-point
registers.
In some cases we use register to describe a general register or a floating-point register (or some
other type of register); which is meant will be clear from context.

Exercises
3.4.1.(1) How many short (32-bit) floating-point numbers can be held in a floating-point register?
3.4.2.(3) Can you think of any reasons why the designers of System/360 and z System included
a separate set of registers for floating-point arithmetic? That is, why should it not be possible to
use the general registers for binary integer arithmetic, addresses, and floating-point arithmetic?

3.5. Program Status Word (PSW)


Usually, the Program Status Word (PSW) is of no immediate concern, and you need not worry
about its contents. It is another internal register that contains various fields indicating the status of
the program being executed. As the System/360 and z System processors have evolved, the PSW
has taken several forms.
For our purposes, we need to know about only a few parts of a PSW: the Instruction Address
(IA), the Condition Code (CC), the Instruction Length Code (ILC), and the Program Mask
(PM). Of these, the IA is most important now; well see more about the others later.
Figure 12 illustrates these four parts of the PSW (and the System Flags). The IA is always in
the rightmost position; the positions of the other three arent significant.

System
I C
Flags
L C


Pro

Instruction

gram

Address

Mask

(IA)

Figure 12. Sketch of a Program Status Word

The PSW for the currently executing program resides in the CPU, not in memory.
The CC is set (given a value) by some instructionsfor example, to indicate that the result of an
addition operation is a negative number. Other instructions may have no effect on the CC; in
Chapter II: z System

49

such cases we say that it is not set, or that its value is unchanged. Still other instructions can test
the value of the CC and make decisions based on the result.
Among the system flag bits in the PSW is the P bit, which determines whether or not the CPU
will allow certain instructions to be executed. If the P bit is 1, the CPU is in Problem State and
will not execute privileged instructions, such as those specifying Input-Output operations. If you
try to execute a privileged instruction while the CPU is in Problem State, a program interruption
will occur instead. When the P bit is 0, the CPU is in Supervisor State, and it allows any
instruction to be executed. This is how supervisory programs retain control over activities critical
to the smooth operation of a complex programming system.

3.6. Other Registers


In all z System processors, the CPU contains many additional registers including Access Registers
and Control Registers. The Access Registers are used for special types of addressing. The
Control Registers are not normally available to application programs: they are not used for arithmetic or for addressing by a program because they control various execution functions.
Well say more about these and other registers as needed.

3.7. Input-Output (I/O)


Data transmission between main memory and external devices is managed by channels. Channels
transmit bytes of data from an external device to memory, or from memory to an external device,
while allowing the CPU to continue with the execution of a processing program. We will use
some simple forms of I/O later, especially for Programming Problems at the end of each chapter.

3.8. Features, Facilities, and Assists


The z System family of processors has grown from its original System/360 capabilities.21 The
added capabilities are sometimes called features, facilities, or assists. For example, the
long-displacement facility is a recent addition. We assume that your CPU has all the facilities
needed to execute our instructions and program examples.

3.9. Microprograms and Millicode (*)


For the earliest System/360 models, internal operations were controlled by microprograms that
were kept in a special type of read-only memory. The internal circuits were then programmed
by a combination of hardware and micro-instructions to act like a System/360 processor!
Modern processors, in contrast, use a combination of hardware, microcode, and millicode
instructions to execute the instructions you write, and to perform other CPU housekeeping
functions. Millicode instructions are kept in a reserved area of main memory. They are very
similar to your instructions, but can do things that your normal instructions cant do. 22 The set
of millicode instructions is sometimes referred to as firmware.

Terms and Definitions


byte
A group of 8 bits; the basic addressable unit of memory.
CPU
Central Processing Unit

21
22

50

This is quite an understatement.


If youre interested in learning more about millicode, see the article by Lisa Heller and Mark Farrell in the I B M
Journal of Research and Development, Vol. 48 No. 3/4, May/July 2004.
Assembler Language Programming for IBM z System Servers

Version 1.00

GR
General Register
FPR
Floating-Point Register
PSW
Program Status Word, containing information about the current state of a program.
CC
Condition Code, a 2-bit field in the PSW used to indicate the status or result of executing
certain instructions.
Instruction Length Code
Instruction Length Code, a 2-bit field in the PSW indicating the length in halfwords of the
currently executing instruction.
millicode
Internal instructions used by the CPU to perform operations too complex to be done costeffectively in hardware.
problem state
A state in which the CPU disallows the execution of certain privileged instructions.
supervisor state
A state in which the CPU allows the execution of all instructions.

Chapter II: z System

51

4. Instruction Execution

44
444
4444
44 44
44 44
44 44
44444444444
444444444444
44
44
44
44

In this section we see how instructions are executed by the CPU, and then look at examples of
the formats used for five representative classes of instructions.
As we saw in Figure 5 on page 45, instructions executed by the computer reside in memory
along with the data to be processed. Instructions in z System can be 2, 4, or 6 bytes long.
Instructions are always aligned so that the leftmost byte is on a halfword boundary: that is, the
address of an instruction must always be divisible by two. This alignment does not depend on the
length of the instruction; it doesnt matter, for instance, that a 4-byte instruction begins halfway
between two word boundaries. It is more precise to say that instructions are 1, 2, or 3 halfwords
long.
Unlike some types of data, there is no requirement that an instruction start at an address that is a
multiple of its length; only that it start on a halfword boundary.

4.1. Basic Instruction Cycle


The process of executing instructions may be visualized in Figure 13.

 FETCH  DECODE  EXECUTE

Figure 13. Basic instruction cycle

In the fetch portion of the cycle, the CPU locates the instruction beginning at the halfword in
memory whose address is contained in the rightmost part of the PSW (the Instruction Address, or
IA), and places it into an internal register where it is decoded. Though this internal register is not
accessible to programs, we will refer to it as the Instruction Register, or IR. The CPU determines
the length of the instruction by examining its first two bits, as we will see shortly.
To complete the fetch portion of the cycle, the CPU adds the length in bytes of the instruction
now in the Instruction Register to the IA in the PSW, so that the IA will contain the address of
the next instruction to be fetched when the current instruction completes its execution. This

52

Assembler Language Programming for IBM z System Servers

Version 1.00

means that instructions must be packed tightly in memory; there are no leftover bytes or gaps
between instructions executed in sequence.
To decode the instruction, the CPU examines the bit pattern in the IR to see what action is
intended. Since (1) the bytes were brought from memory and (2) the memory contains both data
and instructions, the bytes brought to the IR may actually represent data and not instructions.
The CPU has no way of knowing this; it simply goes to the memory address in the IA portion of
the PSW and fetches those bytes into the IR to be interpreted as an instruction. If this is what
you intended, good; otherwise, strange things can happen.
Not all of the possible bit patterns in the IR might represent valid instructions (i.e., actions the
CPU can execute, or will allow to execute). The decoding mechanism can sometimes detect confused situations (such as data being interpreted as instructions) before too much damage has been
done, and cause remedial actions to be initiated.
Assuming that the bytes in the IR contain a valid instruction, further actions may be necessary
before the decoding is completed, such as calculating addresses of the operands to be manipulated
during the execute portion of the cycle.
During the execution phase, the actual operation is performed. It could cause the contents of one
general register to replace the contents of another, or it may involve many intermediate steps of
complicated logic or arithmetic. If no errors are detected during the execution phase (such as
attempting to divide a number by zero), the CPU resumes the instruction cycle by returning to
the fetch portion of the cycle.
We sometimes refer to the entire cycle of fetching, decoding, and executing an instruction simply
as executing that instruction.
Instructions
The IA portion of the PSW addresses the next instruction to be fetched.
If you didnt intend the fetched bytes to be an instruction, its a mistake
you must correct.

Exercises
4.1.1.(2) How could you build a CPU without a separate Instruction Address (such as in the
z/Architecture PSW)?

4.2. Basic Instruction Types


The instructions provided by the original System/360 processors had five formats:
1.
2.
3.
4.
5.

register-and-register (RR)
register-and-indexed-storage (RX)
register-and-storage (RS)
storage-and-immediate (SI)
storage-and-storage (SS)

Modern z System processors support over 30 instruction formats that well introduce as needed.
These five formats are enough for now, because newer instruction formats are variations on these
basic forms.
The letters RR, RX, RS, SI, and SS are abbreviations that indicate the type, or class, of an
instruction. Individual instructions belonging to each class will be treated in later chapters.
Figure 14 gives a useful way to visualize the behavior of these classes:
RR-type instructions operate on data within registers;
RX- and RS-type instructions operate on data between registers and memory;
Chapter II: z System

53

SS-type instructions operate on data in two memory locations; and


SI-type instructions operate on data in memory using an operand in an instruction.

Registers



RR

RX,

Instruction

RS

SI
SS




Memory

Figure 14. Instruction formats and data interactions

The first byte of an instruction always contains an operation code (often abbreviated opcode),
specifying the operation to be performed. The second byte usually contains data about the
location, type, or length of the data to be operated on. This second byte has several forms: it is
called the register specification byte (for RR, RX, and RS instructions), the immediate data
byte (for SI instructions), or the length specification byte (for SS instructions).23 The interpretation of this second byte therefore depends on the class to which the instruction belongs.
RR-type instructions are always one halfword long.
operation
code

register
specification

Table 6. RR-type instruction


format

RX- and RS-type instructions are always two halfwords long.


operation
code

register
specification

addressing halfword

Table 7. RX-type and RS-type instruction format

The RX- and RS-type instruction formats differ only in the interpretation of the bits in the
Register Specification byte.
SI-type instructions are always two halfwords long.
operation
code

immediate
data

addressing halfword

Table 8. SI-type instruction format

Instead of a register specification, the second byte of an SI-type instruction contains an 8-bit
data item used in executing the instruction.

23

54

In some newer instructions, the second byte may contain another part of the opcode; and in some instructions, part
of the opcode may be in the sixth byte! The CPU knows, so you neednt worry.
Assembler Language Programming for IBM z System Servers

Version 1.00

SS-type instructions are always three halfwords long.


length
specification

operation
code

addressing halfword

addressing halfword

Table 9. SS-type instruction format

For most instructions except RR-type instructions, an addressing halfword is used by the CPU to
compute the address of an operand; this important process is described in 5.1. The Addressing
Halfword, on page 64, and again in Section 20. These classifications are not exhaustive; many
newer instructions are variations on these basic forms.

Exercises
4.2.1.(1) Must a 4-byte RX-type instruction begin on a word boundary?
4.2.2.(1) What is the length of the shortest instruction in z System?
4.2.3.(2) How is it possible for instructions of different lengths to be packed tightly into
memory with no wasted bytes?
4.2.4.(1) + May an instruction begin on a word boundary? On a doubleword boundary?
4.2.5.(2) + Figure 14 implies that both instructions and data reside in the same memory. How
can you tell if a given string of bytes represents instructions or data?

4.3. Instruction Lengths


The first two bits of the operation code tell the CPU how many bytes to fetch from memory.
Since at least two bytes per instruction must always be fetched, the CPU can check the two
leading bits to tell how many more bytes (if any) are required. The bit patterns are shown in
Figure 15; xxxxxx represents the remaining six bits of the eight-bit operation code.
00xxxxxx
01xxxxxx
10xxxxxx
11xxxxxx

2-byte
4-byte
4-byte
6-byte

instructions
instructions
instructions
instructions

such
such
such
such

as
as
as
as

RR-type
RX-type
RS- and SI-type
SS-type

Figure 15. Opcode bit patterns for typical instruction types

If the first two bits of the opcode are 00 the instruction is one halfword long; if the bits are 01 or
10 it is two halfwords long; and if the bits are 11 it is three halfwords long.
Before decoding the instruction, the CPU places the number of pairs of bytes in the instruction
(the number of halfwords: 1, 2, or 3) into an internal two-bit PSW field called the Instruction
Length Code (ILC). It is important to remember that the two bits of the ILC are not the same as
the first two bits of the opcode. Table 10 * shows the relationship between the first 2 bits of the
opcode and the ILC:

Courtesy of Michael Stack.


Chapter II: z System

55

ILC
(decimal)

ILC
(binary)

Instruction
types

Opcode
bits 0-1

0
1
2
2
3

B 00
B 01
B 10
B 10
B 11

RR
RX
RS, SI
SS

B 00
B 01
B 10
B 11

Instruction length
Not available
One halfword
Two halfwords
Two halfwords
Three halfwords

Table 10. Instruction Length Code and instruction types

If an error is detected during decoding or executing the instruction, the PSW at the time of the
error is saved, and the programmer can examine the ILC and the IA of the saved PSW to determine what instruction caused the error. If the ILC was not saved it would not be possible to
determine the exact location of the offending instruction, since the location of the next instruction
to be executed is already in the IA portion of the saved PSW, and the length of the bad instruction could have been 2, 4, or 6 bytes.

Exercises
4.3.1.(1) Is it possible for a six-byte instruction to be mistaken by the CPU for a four-byte
instruction? Explain.
4.3.2.(2) + A program segment consists of the following six operations (only the opcodes are
given): X 05 , X 58 , X 89 , X 5A , X D2 , X 50 . Determine the length in bytes of the
program segment.
4.3.3.(2) For each of the instructions in the previous exercise, determine the value of the
Instruction Length Code after each has been fetched.
4.3.4.(2) By examining Figure 15, deduce a simple formula that can be used to determine, for
any z System instruction, what number should be added to the Instruction Address in the PSW
to give the address of the following instruction.
4.3.5.(2) + Make (and study) a short table of four rows, with the following column headings: (1)
value of first two bits of opcode, (2) instruction type, (3) instruction length, (4) ILC after
instruction fetch is complete, and (5) number of addressing halfwords.
4.3.6.(2) + The following twelve halfwords taken from memory are known to be a sequence of
instructions. (The spaces have been inserted for readability; the bytes in memory are contiguous.)
90EC D00C 0580 50D0 89EA D703 89EE 89EE 18CD 41D0 89E6 1B11
Determine (1) how many instructions there are, (2) their lengths, and (3) their types.
4.3.7.(3) + Suppose you know the PSW and ILC after an execution error has occurred. How do
you determine the address of the instruction that caused the error?
4.3.8.(2) What would happen if gaps are left between instructions?

4.4. Some Operation Codes (*)


Table 11 summarizes the characteristics of some basic instructions, as they depend on the first
four bits of the operation code. As described above, the first two bits determine the type and
length of the instruction. The second pair of bits determines (to some degree) the operand length
or the general functions performed by the instructions. (These groupings are only approximate,
but they may help you to appreciate how opcodes are designed.)
A closer examination of a complete table of operation codes reveals a great deal of symmetry in
the opcodes used for similar functions. For example, the four original System/360 instructions

56

Assembler Language Programming for IBM z System Servers

Version 1.00

that perform the Logical AND operation all have operation codes where the second hex digit is
4 and the first hex digits differ by multiples of 4 (X 14 , X 54 , X 94 , and X D4 ).
Second pair of bits

First pair
of bits

00

00
(RR)

Branching, status
switching

01
(RX)
10
(RS, SI)

Branching,
halfword fixedpoint
Branching,
shifting, status
switching

01
Word logical,
fixed-point
binary
Word logical,
fixed-point
binary

10
Long
hexadecimal
floating-point
Long
hexadecimal
floating-point

11
Short
hexadecimal
floating-point
Short
hexadecimal
floating-point

Fixed-point,
logical, I/O

Logical

Logical

Packed decimal

11
(SS)
Table 11. General instruction classifications

Since we will refer to instructions almost entirely using mnemonics


full names these details are only of minor interest.

short abbreviations for their

Exercises
4.4.1.(2) Examine the operation codes given in Exercise 4.3.2, and determine their general
instruction classifications from Table 11.

4.5. Interruptions (*)


The instruction cycle shown in Section 4.1 on page 52 describes the basic mechanism of instruction sequencing. However, a more workable view requires understanding interruptions, sometimes
called interrupts. Well discuss them briefly here, and in more detail when we describe possible
exceptions caused by instructions.
When an interruption occurs, the CPU stores the PSW that currently controls its operation in a
predefined area of memory, and immediately replaces it with a new one from a different predefined area of memory. Many things can cause this PSW switching: a program may contain an
instruction that causes an interruption to occur, or some external event such as a completed I/O
operation could cause an interruption. The basic mechanism used for handling interruptions is
illustrated in Figure 16.

Chapter II: z System

57

 FETCH  DECODE  EXECUTE

no
Any Interrupts?

yes
no


yes

Any other Load New PSWNote interruption cause,


interrupts?
from Memory
save Old PSW, status info

Figure 16. Instruction cycle with interruptions

The usual cycle of fetching, decoding, and executing will continue undisturbed so long as no interruption occurs. 24 When an interruption condition is present, the CPU first examines bits in the
PSW (or in the Program Mask or in other special registers) to see whether the interruption should
be accepted. If these bits are zero, the interruption condition is said to be masked or disabled,
and the CPU takes a default action before proceeding to the next instruction.
If the interruption is not masked (or is enabled), the CPU places information about the cause of
the condition into a reserved Interruption Code area near the low-address end of memory. The
CPU then stores the current (old) PSW and loads a new PSW. Instruction fetching then
resumes, with the next instruction being fetched from the memory address specified by the IA
portion of the newly-loaded PSW. This will almost always be in the Supervisor.
Normally, the new PSW will disable further interruptions until the Supervisor can save information about the status of the program being interrupted. After this status information (such as
register contents and the old PSW) has been saved, the CPU can be enabled for further interruptions. After the interruptions have been handled, the saved status information is restored and
the interrupted program can be resumed.
These are the six classes of interruptions, with examples of possible causes:
1.
2.
3.
4.
5.
6.

Restart (operator action)


External (timer, clock comparator)
Machine Check 25 (equipment malfunction)
Input-Output (an I/O device has signaled a condition)
Program (exception condition during program execution)
Supervisor Call (program requests an Operating System service)

Corresponding to each class is an area of memory where an old PSW is stored, and an area from
which a new PSW is loaded by the CPU. Thus there are six areas in memory into which old
PSWs are stored, and another six areas from which new PSWs are retrieved. These areas are at
fixed positions in the low-address end of memory; a programmer has no control over where they
are placed.
We sometimes distinguish two different classes of interruption. The first is caused by events whose
occurrence cannot be predicted, or for which a program cannot test in advance: these are sometimes called involuntary or asynchronous interrupts. The first four classes of interruption are involuntary. Except for the restart interruption, all the involuntary interruptions can be masked.

24

25

58

Figure 16 doesnt account for the possibility that an interruption can occur during the fetch or decode phases. In
almost all cases, this distinction is unimportant.
This interruption shouldnt be masked off because the CPU must save diagnostic information before the situation gets
worse.
Assembler Language Programming for IBM z System Servers

Version 1.00

The program and supervisor call interruptions are voluntary or synchronous. They are mutually
exclusive, and cannot both occur at the same time. Program interruptions are caused by many
conditions, as you will discover. A supervisor call interruption occurs only as a result of executing a Supervisor Call (SVC) instruction.
The program and supervisor call interrupts are voluntary because the program can (if it wishes)
know what instruction will be executed next, and what interruption-causing actions that instruction could take.

4.6. Exceptions and Program Interruptions (*)


Programs can create a many types of exception condition. Some of them may not be serious, and
your program can tell the CPU to take some default action (like setting the Condition Code, or
generating a specified default result). Other exception conditions require interrupting the instruction cycle.
We will be most concerned with program interruptions. They may be caused by error conditions
detected during any of the three portions of the instruction cycle. For example, if the IA specifies
that an instruction should be fetched from an odd memory address, no fetch occurs and an interruption is generated instead. During the decode phase, the CPU may discover that the operation
code is invalid. Similarly, an error condition such as attempting to divide a number by zero may
occur during the execution phase.
Exceptions and Interruptions
Exception:

An unusual condition possibly requiring attention; your


program may be able to request the CPU take a default
action and continue execution, or cause an interruption.

Interruption:

An exception condition requiring alteration of the


normal sequence of program execution by passing
control to the Operating System.

For most program interruption conditions, the Operating System provides a brief indication of the
cause of the interruption. Additional diagnostic information may also be given, such as the old
PSW and the contents of the general and floating-point registers, and the contents of various areas
of memory. You can then use this information to try to deduce the cause of the interruption.
The most common types of program interruption are shown below with their associated Interruption Codes. This list is not complete, but may help you find the causes of typical interruptions
generated by your programs.
IC=1

Invalid Operation Code. The decoding phase has found an operation code that cannot
be executed. This could be due to (1) allowing data to be fetched as instructions, or (2)
the programs destroying part of itself.

IC=2

Privileged Operation. The program is trying to execute an instruction not allowed in


problem state.

IC=3

Execute exception. An execute instruction is attempting to execute another execute


instruction.

IC=4

Access, Protection. The program has attempted to refer to some area of memory to
which access is not allowed. There can be other causes, but this is the most common.

IC=5

Addressing. The program has attempted to address a nonexistent memory address.

IC=6

Specification Error. This can be caused by many conditions, but a common cause is
referring to an odd-numbered register when an even-numbered register is required. An
odd IA in the PSW indicates an attempt to access an instruction not starting on a
halfword boundary.

IC=7

Data Exception. This is caused by invalid packed decimal data, or by binary or decimal
floating-point conditions described in Chapter IX.

IC=8

Fixed-Point Overflow. This is caused when a fixed-point binary result is too large.

Chapter II: z System

59

IC=9

Fixed-Point Divide Exception. A binary divide instruction has found that a quotient
would be too big to fit in a register, or a divisor is zero.

IC=A

Decimal Overflow. A packed decimal result is too large to fit in the result field.

IC=B

Decimal Divide. A packed decimal quotient is too large to fit in the result field, or a
divisor is zero.

IC=C

Hexadecimal floating-point exponent overflow. A hexadecimal floating-point result is


too large.

IC=D

Hexadecimal floating-point exponent underflow. A hexadecimal floating-point result is


too small.

IC=E

Hexadecimal floating-point lost significance. A hexadecimal floating-point result has lost


all its significant digits.

IC=F

Hexadecimal floating-point divide exception. A hexadecimal floating-point operation is


attempting to divide by zero.

Four of the fifteen possible program interruption conditions are often regarded as harmless: fixedpoint and decimal overflow exceptions, and hexadecimal floating-point exponent underflow and
lost-significance exceptions. By setting an appropriate mask bit in the Program Mask to zero (see
Figure 12 on page 49), you can use the SPM instruction (described on page 235) to request that
the CPU take a predefined default action and continue execution without causing an interruption.
Other default actions can be requested for many floating-point operations, by setting mask bits in
the Floating-Point Control Register (more about this in Chapter IX).
Thus, exception conditions can sometime cause an interruption, and sometimes take a default
action if the interruption is masked. For example, a fixed-point overflow if enabled will cause an
interruption with interruption code 8; but if masked off, the CPU will set the Condition Code to
3 before fetching the next instruction.
The CPU may seem overly cautious about detecting error conditions: the number of ways to generate interrupts sometimes seems larger than the number of ways to write a correct program!
However, these error-detection mechanisms help catch program errors: an interruption condition
will usually be generated before your program has gone too far, and you will have an indication
that something is wrong before the cause is obscured.
Consider the problem of finding program errors on a CPU in which all bit patterns represent
valid data or operation codes, and where none but the most unusual error conditions were caught.
The processor could offer little help, and you would have to write programs with many internal
checks and tests. In addition to the extra effort needed to write correct programs, the time used
for checking would cause the program to run more slowly. Program interruptions should be seen
as helpful clues from the CPU, and not as an indication that something is wrong with the
processor.

Exercises
4.6.1.(2) + Suppose the contents of the following 8-byte System/360 PSW26 (sketched in
Figure 12 on page 49) was displayed as the result of a program interruption. What error condition is immediately evident? (The xxxxxxxx digits are unimportant for this exercise.)
xxxxxxxx 4017E26F
4.6.2.(3) Suppose the 8-byte Program New PSW area of memory had been initialized with the
following New PSW: (The xxxxxxxx digits are unimportant for this exercise.)
xxxxxxxx 0000A237
What do you suppose would happen if any program interruption occurs?
4.6.3.(1) What caused the following Interruption Codes?

26

60

The modern z/Architecture PSW is quite different!


Assembler Language Programming for IBM z System Servers

Version 1.00

1. 0001
2. 0009
3. 000C

4.7. Machine Language and Assembler Language


Sometimes people refer to Assembler Language programming as machine language or
processor language programming. In the earliest days of digital computers, there were almost
no programming tools like assemblers and compilers, so the instructions and data for programs
had to be created in the form of binary (or decimal or hexadecimal) digits that were loaded
directly into memory for execution, without any intermediate translation.
Thus, we consider machine language to be the processors internal bit patterns representing
instructions and data types. Because its difficult to know (and work with) these bit patterns, we
use assemblers and compilers to convert a program from forms manageable by humans into the
forms needed by the processor.
Even though Assembler Language is considered a lower-level language, we rarely program digital
computers in machine language, so it is no longer accurate to say we program in machine language.27

4.8. Processor Evolution


Since the early days of System/360, many updates, changes, enhancements, and improvements
have been made to the original architecture. These have included 31-bit and 64-bit addressing
(which well see in Section 20), 64-bit registers, and a vast variety of new instructions. Many of
the instructions well see didnt exist in System/360. Each generation of processors has introduced
small and large enhancements; while well start with basic instructions that have been used for
many years, well also see many new forms that can simplify programming chores that were more
difficult or expensive when only the older instructions were available.
IBM has tried very hard to ensure that existing applications continue to execute correctly on each
new generation of processors. This concern with backward compatibility has made it easy for
users to increase the capacity and performance of their systems without having to rewrite and
retest large applications in which they have invested considerable time and effort.
Backward compatibility doesnt apply as uniformly to specialized programs that use systemspecific features, but most such features are typically managed by the operating system.

Terms and Definitions


fetch
The CPU action of bringing halfwords from memory into the Instruction Register to be
interpreted as an instruction.
IR
Instruction Register, a conceptual internal register in the CPU into which fetched instructions
are placed.
decode
The CPU action of analyzing the contents of the IR to determine the validity and type of
instruction.
execute
The CPUs action of performing the operation requested by the instruction in the IR.

27

But some hardy souls still make corrective patches to programs in machine language, or enter machine language
instructions into memory using various testing and debugging techniques.
Chapter II: z System

61

operation code
The portion of an instruction specifying the actions to be performed by the CPU when it
executes the instruction. Often called opcode.
ILC
Instruction Length Code, a 2-bit field in the PSW containing the number of halfwords in the
current instruction.
exception condition
A condition indicating an unusual result. Some exceptions can deliver a default result if an
interruption has been masked off by appropriate settings, while others always cause an interruption.
interruption
A process taking control away from the currently executing instruction stream, saving information about the interrupted program, and giving control to the Operating System Supervisor.
IC
Interruption Code, a value indicating the cause of an interruption.
machine language
The internal representations of instructions and data processed by a computer.
PM
Program Mask, a 4-bit field in the PSW used to control whether or not certain types of
exception condition should cause an interruption, or take a predefined default action.

62

Assembler Language Programming for IBM z System Servers

Version 1.00

5. Memory Addressing

55555555555
555555555555
55
55
555555555
5555555555
555
55
55
555
55555555555
555555555

We now describe how the CPU calculates addresses of data and instructions in memory when it
decodes the instructions of your program.
The addressing technique used in z System differs from that found in many earlier computers,
where the actual memory address (or addresses) of the operand (or operands) was part of the
instruction.

opcode
operand address

Figure 17. Typical instruction format for old computers

When memory sizes were limited, this was a reasonable and efficient choice.28
Because the original System/360 architecture allowed addressing up to 224 bytes of memory, the
older technique of placing actual operand addresses into the instructions would have required at
least a 24-bit field for each such address. Since few processors had as many as 224 bytes of
memory, and because few programs needed as many as 224 bytes of memory to execute, many of
the bits in the 24-bit address field would be wasted by such a direct-addressing technique, and
instructions would be longer than needed.
In z System, the scheme used for addressing memory operands is much more flexible than using
actual operand addresses, and more economical in using the bits allotted to each instruction; but
more complex in the way it determines operand addresses.
The z System family of processors supports three modes of addressing. This section describes a
fundamental type of base-displacement address generation with 24-bit addresses. Section 20 in
Chapter VI describes 31-bit and 64-bit addressing, as well as two other types of address generation.

28

Another reason is that memory was very expensive! A really big machine might have had as many as 128 kilobytes of
memory; modern processors can have billions of times more.
Chapter II: z System

63

5.1. The Addressing Halfword


To refer to data or instructions in memory, a program will almost always use one of the general
registers, because the CPU uses information in a part of many instructions called an addressing
halfword. An addressing halfword always occupies a halfword in memory.
4 bits12 bits

base digit
displacement

0
3 4
15
Figure 18. Structure of an addressing halfword

The first 4 bits of the addressing halfword contain a hex digit called the base register specification
digit, or base digit.29 The base digit specifies a general register called the base register. The 12-bit
field in the rest of the addressing halfword contains an unsigned nonnegative number called the
displacement that takes values from 0 to 4095.
To generate the address of an operand, the CPU does the following:
Step 1:

The 12-bit displacement is put at the right-hand end of an internal register called the
Effective Address Register (abbreviated EAR), and the leftmost bits of the EAR
are cleared to zeros.

Step 2a:

If the base register specification digit is not zero, then the contents of the specified
general register (the base register) are added to the contents of the EAR, and carries
out the left end are ignored.

Step 2b:

If the base register specification digit is zero, nothing is added to the EAR (so that
general register zero will never be used by the CPU as a base register). That is, a
zero base digit means no register.

The result in the EAR is called the Effective Address. It may be used as the address of an
operand in memory, and for many other purposes (such as a shift count). These steps are
sketched in Figure 19.
 General Registers

 Addressing Halfword

b
displacement




General Register b
Adder

EAR
Effective Address

Figure 19. Sketch of Effective Address calculation

This method of generating addresses is called base-displacement addressing. In 24-bit addressing


mode (which were assuming for now), only the rightmost 24 bits of the Effective Address are
used.

29

64

The base register specification digit was sometimes called the base register address, but this is misleading because
the base registers arent addressable like bytes in memory.
Assembler Language Programming for IBM z System Servers

Version 1.00

Remember
An addressing halfword is not an address. It can be used to form an
Effective Address.

Exercises
5.1.1.(2) The use of the term halfword in describing an addressing halfword implies that it
(the addressing halfword) lies on a halfword boundary. Is this true under all circumstances?
5.1.2.(1) How many values may be assumed by the base register specification digit? How many
registers may be used by the CPU as base registers?

5.2. Examples of Effective Addresses


In the following examples, additions are done in both binary and hexadecimal arithmetic.
1. Suppose the addressing halfword of an instruction is 1011 001011010101 in binary (X B2D5 )
and suppose general register 11 contains
1100 0111 0011 1110 1001 0000 1010 1111
in binary (or C73E90AF in hex). Then, assuming we are generating 24-bit addresses, the
Effective Address of the instruction is
0000 0000 0000 0010 1101 0101
+0011 1110 1001 0000 1010 1111
0011 1110 1001 0011 1000 0100

0002D5 (displacement)
3E90AF (base)
3E9384 (Effective Address)

2. Suppose the addressing halfword of the same instruction is X 0468 . Then the Effective
Address is X 000468 , since general register zero is never used as a base register.
3. Suppose the addressing halfword of the same instruction is X B000 , and the contents of
R11 are as before. Then the Effective Address is X 3E90AF ; a zero displacement is valid.

Exercises
5.2.1.(2) + Assume general registers 0, 1, and 2 contain these values:
c(GR0) = X12001038
c(GR1) = X0902A020
c(GR2) = X001AAEA4
Calculate the 24-bit Effective Address for these addressing halfwords: (1) X 206C , (2)
X 1EEC , (3) X 0FB0 .
5.2.2.(2) + Assuming the same register contents as in Exercise 5.2.1, calculate the 24-bit Effective Address for these addressing halfwords: (1) X 1FEF , (2) X 0FC8 , (3) X 2EA4 .

5.3. Indexing
After the displacement has been added to the base (if any), the CPU again checks the type of the
instruction. If the instruction is type RX, an indexing cycle is needed. The second byte of an
RX-type instruction (the register specification in Table 7 on page 54) contains two four-bit
fields: the second is called the index register specification digit or index register digit or index
digit, as shown in Figure 20.

Chapter II: z System

65

8 bits
4 bits 4 bits
16 bits

opcode
operand index

registerregister
addressing halfword

01xxxxxx digit digit

0
7 8
11 12
15 16
31
Figure 20. RX-type instruction, showing index register specification digit

Step 3:

If the instruction is type RX, and the 4-bit index register specification digit is not
zero, then the contents of the general register specified by the index register specification digit are added to the contents of the EAR (again ignoring carries out the left
end). A zero index digit means no register, not general register zero.

The resulting quantity in the EAR is still called the Effective Address (sometimes called the
Indexed Effective Address). These steps are sketched in Figure 21.
 General Registers

 Addressing Halfword

x b displacement





General Register b
Adder




General Register x
Adder

EAR
Effective Address

Figure 21. Sketch of Effective Address calculation with indexing

Modern CPUs add the base and index register contents with a three-input adder, so there is actually only one calculation. The index register specification digit is sometimes called the index digit;
similarly, the specified register is the index register, and the quantity in it is the index.
Indexing is a powerful way to process structures of data items like arrays with uniform and regular
spacing, as we will see in Section 40. The addressing halfword provides the address of a fixed
position, and the index selects a particular item.

Exercises
5.3.1.(1) Draw a picture showing the locations of the base register specification digit, the base
register, and the base address. Then do the same for the corresponding index quantities.
5.3.2.(1) How does the CPU determine that an indexing cycle is needed during address computation?
5.3.3.(2) For each instruction type, determine the maximum number of general registers that
might be accessed by the CPU in calculating Effective Addresses.
5.3.4.(2) Under what circumstances will the CPU not calculate an Effective Address?

66

Assembler Language Programming for IBM z System Servers

Version 1.00

5.4. Examples of Indexing


Continuing the examples of calculating Effective Addresss that we saw in Section 5.2:
4. Suppose an RX-type instruction is X 430A7468 and that GR7 contains X 12345678 and
GR10 contains X FEDCBA98 . (The base register specification digit X 7 means that GR7
is used as the source of the base address.) Again assuming we are generating 24-bit addresses,
the Effective Address is
0000
+0011
0011
+1101
0001

0000
0100
0100
1100
0001

0000
0101
0101
1011
0001

0100
0110
1010
1010
0101

0110
0111
1110
1001
0111

1000
1000
0000
1000
1000

000468
345678
345AE0
DCBA98
111578

(displacement)
(base, from GR7)
(index, from GR10)
(Effective Address)

5. Suppose an RX-type instruction is X 43007468 and that the contents of GR7 are again
X 12345678 . Then the Effective Address is
0000 0000 0000 0100 0110 1000
+0011 0100 0101 0110 0111 1000
0011 0100 0101 1010 1110 0000

000468 (displacement)
345678 (base)
345AE0 (Effective Address)

(No indexing cycle is needed, since the index register specification digit is zero.)
6. Suppose an RX-type instruction is X 43070468 and that GR7 still contains X 12345678 .
Then the Effective Address is
0000
+0000
0000
+0011
0011

0000
0000
0000
0100
0100

0000
0000
0000
0101
0101

0100
0000
0100
0110
1010

0110
0000
0110
0111
1110

1000
0000
1000
1000
0000

000468
000000
000468
345678
345AE0

(displacement)
(base)
(index)
(Effective Address)

In this example the values of the base and index register specification digits were interchanged
from those in example 5, so that the indexing cycle was required to compute the same Effective Address.
In situations where only one register is used to calculate an Effective Address (as above, where the
base digit was 0 and the index digit was 7), be careful not to call that register the base register,
even though it usually behaves like a base register in an RX-type instruction.30

Exercises
5.4.1.(1) Under what circumstances may GR0 be used as a base register? As an index register?
5.4.2.(3) + Assume the hexadecimal contents of the general registers are as shown:
C(GR0)
C(GR1)
C(GR2)
C(GR3)

=
=
=
=

12001028
8902A020
4F1AAEA4
FFFFFFF8

C(GR4)
C(GR5)
C(GR6)
C(GR7)

=
=
=
=

8888000E
12345678
0FDE3B72
92837465

and GR8 through GR15 contain zeros. Now, compute the 24-bit Effective Address of each of
the following instructions, paying careful attention to instruction type: (1) X 9803206C , (2)
X 50F10EEC , (3) X 41133333 , (4) X 7A341DA4 , (5) X 91220166 , (6) X 8F120FB0 .
5.4.3.(3) + Assume that the contents of the general registers are as shown below for GR0
through GR7, and that GR8 through GR15 contain zeros.

30

In the Access Register addressing mode, index and base registers participate differently in calculating Effective
Addresses: only base registers are used to select an Access Register.
Chapter II: z System

67

C(GR0)
C(GR1)
C(GR2)
C(GR3)

=
=
=
=

00000044
000902AE
A20710FC
FFFFFFFF

C(GR4)
C(GR5)
C(GR6)
C(GR7)

=
=
=
=

41800000
00010000
00FFFF00
FF000000

Now, compute the 24-bit Effective Address of each of the following instructions: (1)
X 41726100 , (2) X 920710FC , (3) X 7A333002 , (4) X 5806016C , (5) X 43B00044 , (6)
X 90EC126A , (7) X 86052E4D .
5.4.4.(3) Suppose the contents of the general registers are as shown in Exercise 5.5.2. For each
of the following instructions, determine the Effective Address, paying careful attention to
instruction type: (1) X 58040404 , (2) X 91628DBC , (3) X 44FF7D5C .

5.5. Addressing Problems (*)


The Effective Address in the EAR has many uses, most often to address operands in memory; it
is also used for other purposes such as shifting and branching.
Certain instructions operating on groups of bytes require the address of the leftmost (lowestaddressed) byte of the operand group be exactly divisible by the length of the operand. If this
condition is not satisfied, a program interruption for a specification exception occurs. In early
processors, operand alignment was required for almost all instructions, but the requirement was
relaxed soon after.31 Few instructions in modern processors require strict operand alignment.
When you use base-displacement addressing with 12-bit displacements, the only part of the
memory that can be referenced without using a base register is the area with addresses 0 to
4095 = X F F F , so you will almost always use a base register to refer to operands in memory.
(Well see in Chapter VI, Section 20 that instructions with signed 20-bit displacements make this
4K-byte limitation much less severe.)
You cant put your program into those first 4096 bytes32 because that area of memory (and more)
is reserved by the CPU and the Operating System. This means that if you want to access a byte
in memory at address XX (where XX is greater than 4095), there must be a base register available
one of registers 1 to 15. If a base register contains a base address, and XX lies between that
base address and the base address + 4095, then we say that XX is addressable. If there is no such
number in a register, then the byte at XX is not addressable by your program.
When we place a number in a register to address a 4096-byte region of memory, that register
provides addressability for the region. However, if the number itself must be brought from
another portion of memory that is not currently addressable, we are back where we started,
needing another number to provide addressability for the first number.
Fortunately, there are simple solutions to the problems of establishing addressability. The BASR
instruction is often used (as we will see soon), and the Assemblers address constants also allow us
to refer to other areas of our program. Modern processors provide new ways to minimize these
addressing problems: long displacements and relative addressing. We will turn to them in Section
20 after we have investigated the most often-used instructions.

Exercises
5.5.1.(3) + Suppose the general registers contain the values shown in Exercise 5.2.1. Which of
the following locations in memory (given in hexadecimal) are addressable through the use of
the base-displacement addressing technique? For each location that is addressable, derive an

31

32

68

Because many programs had to manage unaligned data items, extra instructions were needed to isolate and align the
required item. The processor designers were asked (urgently!) to remove the restriction wherever possible. The relaxation of the alignment requirement was called the Byte-Oriented Operand Feature; it soon was known as the
BOOF.
Unless youre writing your own operating system!
Assembler Language Programming for IBM z System Servers

Version 1.00

addressing halfword that can be used to address it. (1) X 02ABCD , (2) X 000A4D , (3)
X 001139 , (4) X 88888E , (5) X 02A010 .
5.5.2.(3) + Suppose the contents of the general registers are as follows:
C(GR0)
C(GR1)
C(GR2)
C(GR3)
C(GR4)
C(GR5)
C(GR6)
C(GR7)

=
=
=
=
=
=
=
=

00010A20
42319B7C
91F0F002
1002340A
00FF00FF
D907C401
12345678
992B42A3

C(GR8)
C(GR9)
C(GR10)
C(GR11)
C(GR12)
C(GR13)
C(GR14)
C(GR15)

=
=
=
=
=
=
=
=

8031B244
00000010
723B94C1
E931AB7F
00000E38
6B005000
80000000
FFFFFFFF

For each of the following memory addresses, determine first whether or not that memory
location is addressable by a program using those registers. If it is addressable, determine an
addressing halfword (base-displacement halfword) that can be used to address the location. (1)
X 010A20 , (2) X F F F F F F , (3) X 6A0054 , (4) X 31AB7E , (5) X 001234 , (6)
X 07D3C4 , (7) X 00A004 , (8) X 31BB65 , (9) X 9ABCDE , (10) X 07C401 .
5.5.3.(3) In Exercise 5.5.2, which locations are addressable through the base-displacement
addressing technique with indexing allowed? Derive an addressing halfword and the accompanying index digit that (in an RX-type instruction) would make the locations addressable.
5.5.4.(3) + Suppose the contents of the general registers are as shown in Exercise 5.1.2 on page
65 (note that registers 8 through 15 contain zeros). For each of the following memory
addresses, determine an addressing halfword that can be used to address that memory position.
If no such addressing halfword exists, say so. (1) X 000EEB , (2) X 001040 , (3) X 072000 .
How many solutions are there for address (1)?
5.5.5.(4) + In Exercise 5.5.1, which locations in memory are addressable through the basedisplacement addressing technique with indexing allowed? Derive an addressing halfword and
the accompanying index digit that (in an RX-type instruction) would make the locations
addressable. (Remember that Exercise 5.5.1 refers to Exercise 5.2.1.)
5.5.6.(1) Suppose a program can be put entirely within the first 4096 bytes of memory. Will it
use GR0 as a base register?
5.5.7.(2) Assume that the contents of the general registers are as shown in Exercise 5.5.2. For
each of the following SS-type instructions, compute both Effective Addresses (there are two
addressing halfwords in an SS instruction, as shown in Table 9 on page 55).
(1) X D2078F1D57C4 , (2) X DCFFDCFF7000 , (3) X F26337390050 , (4)
X D58DFE4FC016 .

5.6. Address Translation and Virtual Memory (*)


All models of z System support address translation, called Dynamic Address Translation (or
DAT). Address translation is invisible to application programs. It provides greater Operating
System flexibility in assigning programs to main memory, a heavily used resource. Address translation takes your programs virtual addresses and maps them invisibly into the real addresses
needed for references to real memory.
Without DAT, a reference to a byte at X 123456 addresses that byte in the physical or real
memory of the processor. When DAT is active, your reference to a byte (at your virtual Effective
Address X 123456 ) is translated into a real address (such as X 27D94FA ) having no obvious
relation to your address; you cant determine the relation of your virtual addresses to the real
addresses to which they are mapped. The Operating System, working with the DAT facilities,
makes it possible for your program to operate as though it is addressing real memory; but only
the Operating System works with real addresses. This is why your addresses are called virtual
they arent real.

Chapter II: z System

69

Address translation is simple in concept but complex in implementation. To illustrate, the virtual
(effective) address supplied by your program is divided into sections; for 31-bit addresses, they are
a segment index, a page index, and a byte index, as illustrated in Figure 22.
11
8
12

segment page
byte

index
index
index

Figure 22. 31-bit Virtual Address

To use these indexes for calculating real addresses, the Operating System first constructs (in a protected area of real memory) two sets of tables, page tables and a segment table, and it places the
address of the segment table (for example, taken from Control Register 1) into an internal field.
Your virtual address is translated into a real address roughly as follows:
Step 1:

The segment table address is retrieved and the segment index is added to it. The result
is the address of one of the entries in a list of segment tables.

Step 2:

The specified segment table entry (which contains the address of one of the entries in
a list of page tables) is retrieved, and the page table index is added to it. The result is
the address of an entry in the specified page table.

Step 3:

The specified entry in the page table is retrieved, and attached to the left (high-order)
end of the byte index. The result is the real address of a byte in main memory.

We will not show examples of translation, since it is invisible to your program.


This description covers only very basic aspects of translation, and does not cover 64-bit virtual
addresses. There are many other details of the process, and (because translation is very heavily
used) the processor has a lot of additional hardware to optimize the process.

Exercises
5.6.1.(3) Some processors use a technique called indirect addressing. If a bit in the instruction
(called the indirect-addressing bit) is nonzero, the CPU uses the Effective Address not to access
an operand, but to access a second instruction. The Effective Address of this new instruction
then becomes the operand address that points to the desired operand. (On some processors, if
the instruction at the indirect address had its indirect-addressing bit set, then the entire
process repeats until an instruction is found without the indirect-addressing bit set.) Can you
think of reasons why indirect addressing is not provided by z System?
5.6.2.(0) Another aspect of early addressing techniques (whereby instructions contained actual
operand addresses) was that the address portions of instructions often had to be modified. Find
a programming old-timer: ask for an explanation of address modification techniques on
processors such as the IBM 7090, and why the method used on z System is so clearly superior.

5.7. Summary
As noted earlier, Effective Addresses are used for many purposes; the most common is to refer to
an operand in memory. Almost always, the operand is referred to by its lowest-addressed byte;
and if the operand is a binary integer, that byte contains the most significant (high-order) byte of
the integer. So, references to low-order and high-order may need to distinguish clearly
between memory addresses, bit ordering, and numeric significance.

Terms and Definitions

70

Assembler Language Programming for IBM z System Servers

Version 1.00

addressing halfword
A halfword containing a base register specification digit in the first 4 bits, and an unsigned
displacement in the remaining 12 bits. A key element of z System addressing.
Effective Address
The address calculated from an addressing halfword, possibly with indexing.
EAR (Effective Address Register)
A (conceptual) internal register used to hold Effective Addresses.
base register specification digit
The first 4 bits of an addressing halfword.
base register
A general register used at execution time to form an Effective Address.
base address
The execution-time contents of a base register.
index register specification digit
4 bits of an RX-type instruction specifying a register with a value to be added to the Effective
Address calculated from an addressing halfword.
index
The contents of an index register.
indexing
Computation of an Effective Address by adding a displacement to the contents of a base register and an index register.
displacement
An unsigned 12-bit integer field in an addressing halfword used in generating Effective
Addresses.33
addressability
A base register and a displacement provide an Effective Address allowing valid reference to a
byte in memory.
real address
The true address of a memory location.
virtual address
The address of a memory location that may physically reside at a different real address.
address translation (Dynamic Address Translation, DAT)
The procedure used by the CPU to convert virtual addresses into real addresses.

33

We will see in Section 20 that z System provides another form of base-displacement addressing with a signed 20-bit
displacement.
Chapter II: z System

71

72

Assembler Language Programming for IBM z System Servers

Version 1.00

Chapter III: Assembler Language Programs

IIIIIIIIII
IIIIIIIIII
II
II
II
II
II
II
II
II
IIIIIIIIII
IIIIIIIIII

IIIIIIIIII
IIIIIIIIII
II
II
II
II
II
II
II
II
IIIIIIIIII
IIIIIIIIII

IIIIIIIIII
IIIIIIIIII
II
II
II
II
II
II
II
II
IIIIIIIIII
IIIIIIIIII

We have seen how the CPU executes instructions and evaluates addresses; now well see how we
write Assembler Language programs.
Section 6 describes typical steps involved in preparing, assembling, linking, and executing programs written in Assembler Language.
Sections 7 and 8 examine the components from which machine, assembler, and macro instruction statements are formed.
Section 9 describes five major machine-instruction types and how we write their operands in
machine instruction statements.
Section 10 introduces the key concept of addressability in Assembler Language programs, a
necessary step for any program executed on z System.

Chapter III: Assembler Language Programs

73

6. Assembler Language

6666666666
666666666666
66
66
66
66
66666666666
666666666666
66
66
66
66
66
66
666666666666
6666666666

The Assembler is the program most used in creating specific instruction sequences for execution
by the processor.
First, we describe how to write programs and see the steps leading to their execution. The conventions and rules for using the Assembler are called Assembler Language, even though there is
little resemblance to what most people mean by language.

6.1. Processing Your Program


First, we consider the steps involved in running an Assembler Language program:
1. assembly
2. linking
3. loading and execution

6.1.1. Assembly
Assembly is represented schematically in Figure 23. The Supervisor places the Assembler in
memory to begin assembling your source program.

System z

Your

Your
Source Assembler Object
Program
Module


Libraries of Macro
Your
Instructions and

Program
other statements

Listing

Figure 23. Simple view of Assembler processing

74

Assembler Language Programming for IBM z System Servers

Version 1.00

The Assembler reads the statements of your Assembler Language program, processes
them possibly with the help of some data in libraries of macro-instructions and other
statements converts your Assembler Language program to machine language, and produces an
object module containing object code. Usually you will want a program listing showing your
source program and the generated object code, with additional information about the Assemblers
processing and indications of errors it may have detected.
The Assembler converts the program from a form convenient for you (statements) to a form convenient for the processor (binary data and instructions), its machine language.

6.1.2. Linking
The Linker 34 combines your object module with any others needed for execution. The linking
step is sketched in Figure 24; the Linker is placed in memory and begins execution.

System z

Your

Your
Object Linker Load
Modules
Module


Libraries

Your
of Object or
Linker
Load Modules
Listing

Figure 24. Simple view of program linking

The output of the Linker is a load module.35 The load module is written to a storage device, and a
listing of information summarizing the linking process is created.
The Linker also accepts load modules as input, allowing you to update or modify existing load
modules without having to reassemble all its components.

6.1.3. Loading and Execution


At execution time, the load module produced in the linking step is loaded into memory. An
essential feature of this process is relocation, which well investigate in Chapter X, Section 38.
The portion of the Supervisor that loads and relocates load modules is called the Program Loader.
Like the Linker, it is a program that treats other programs as data.
After your program has been loaded into memory, the Supervisor transfers control to it by setting
the Instruction Address in the PSW to the address of the instruction where you want execution to
begin. Your program then does whatever processing you told it to do 36 and when it is finished it
returns control to the Supervisor.

34

35

36

Well use Linker to mean any program (such as the Binder and Linkage Editor) that combines object module files
into executable files like load modules.
The output of a Linker has many many different names and forms, depending on the operating system and the
system Linker. For example, on z System the output of the z/OS binder can be a load module or a program
object; the output of the z/VSE Linker is a phase, and the output of the z/VM CMS loader is a module. Well
use load module to mean a data set or file ready to be loaded directly into memory for execution.
Which may not always be what you intended!
Chapter III: Assembler Language Programs

75

System z

Load Program

Module
Loader

Loads, and

then passes

control to

 your program


Your
Your

Your
Program Relocated Program
Data
Program
Output

Figure 25. Simple view of program loading and execution

The last two linking and program-loading steps can be combined by using a Loader instead of the
Linker and Program Fetch routines. The Linker or Loader reads and relocates your object
modules directly into memory, and combines them with any necessary additional object and load
modules from the Libraries of Object or Load Modules.
An Assembler Language program is processed twice: once by the Assembler at assembly time,
and once by the CPU when it is executed at execution time (or run time). The difference between
these two times is important: the Assembler produces object modules with machine language
instructions and data to be placed into memory later; your data is processed only when your
program is finally loaded and your instructions are executed.

Exercises
6.1.1.(1) Draw a diagram combining Figures 23 through 25, to show the relationships between
the inputs and outputs of processing your programs at each step.

6.2. Preparing Assembler Language Statements


You prepare Assembler Language programs in the form of statements. There are four types:
comment statements, machine instruction statements, assembler instruction statements, and macroinstruction statements. All four can be used in creating programs.
1. Comment statements provide explanatory material in the program so it will be easier for you
and others to read and understand. They are displayed in the program listing, but are not
translated into instructions or data and do not appear in the object module.
2. Machine instruction statements are converted by the Assembler into machine language
instructions for the CPU to execute when your program is loaded into memory for execution.
3. Assembler instruction statements provide information to the Assembler. They can be as
simple as statements generating data or specifying a title for the top of each page of the
listing, or can be more complicated, such as statements telling the Assembler that certain registers may be used as base registers. Some Assembler instruction statements cause the
Assembler to generate machine language data; others do not.
4. Macro-instructions provide a compact assembly-time notation for groups of statements. They
are a convenient way to specify sequences of other statements (all four types are allowed) in
which parts of the generated statements can be changed to suit your needs. Macroinstructions are a very powerful and useful feature of the Assembler Language.

76

Assembler Language Programming for IBM z System Servers

Version 1.00

The Assembler processes input records exactly 80 bytes long. Your records may not extend all
the way to 80 characters, but there must still be enough blank or other characters to extend its
length to 80. These 80-character records are often called card-image records.37
Statements occupy positions 1 through 71 of a line. Such positions are called columns.
Column 72 has a special meaning: if it is not blank, the next line is considered to be a continuation of the line with the nonblank character in column 72, in such a way that the character in
column 16 of the second line is treated as following immediately after the character in column 71
of the preceding continued line.38 This is illustrated in Figure 26. These conventionscolumn 72
for the continuation indicator and column 16 where the statement continues are almost always
used for machine instruction and assembler instruction statements.
Columns 73-80 may be used for any purposes (usually, for sequencing data).

first character of a record


last character of a record


1
10
20
30
40
50
60
70
80
....v....|....v....|....v....|....v....|....v....|....v....|....v....|....v....|




continue column (16)


end column (71)
start column (1)
nonblank character if continued
Figure 26. Assembler Language statement columns

Columns 1 through 15 of a continuation line must be blank. (A common error is to write characters in column 72 accidentally, so that the following line is treated as a continuation line, and
processed in an unexpected way.)
Columns 73 through 80 are ignored by the Assembler. Since all 80 columns of the input record
appear on the listing, the last 8 columns are often used for identification or sequencing information. 39
A comment statement is identified by an asterisk (*) in column 1. Any information may appear in
columns 2 through 71. Figure 27 has examples of comment statements:

37

38

39

The choice of 80 characters goes back to the nearly universal use of IBM cards. For many years before and after
the introduction of System/360, programs and data were prepared on 80-column punched cards. So, we still say
column rather than something like position.
You can change these columns with the ICTL Assembler instruction statement. It allows other columns to be used
for the start, end, and continuation columns of a statement. The numbers given are the ones the Assembler uses if it
is not told otherwise. ICTL is almost never used, anyway; if you use ICTL to change those columns, other readers of
your program may be confused.
Even though IBM cards have 80 columns, early computers like the IBM 704 and 709 couldnt read the last 8
columns! Those processors had 36-bit words, so their card readers read alternate groups of 36 bits from the 12 rows
on a card into 24 words. This 72-column custom persists.
Chapter III: Assembler Language Programs

77

1
10
20
30
40
50
60
70
80
....v....|....v....|....v....|....v....|....v....|....v....|....v....|....v....|
* This is a comment statement. It is not continued.
* This comment statement is correctly continued: its continuation
on this next line starts in column 16.

X column 72

* This comment statement is also continued, but is an error:


this continuation line has nonblank characters before column 16.

Figure 27. Comment statement examples

Figure 27 contains some entirely blank lines. They are often used to improve readability; the
Assembler copies them to the program listing, and they have no effect on your program.
Comment statements may be continued onto following lines, as shown in the figure above. This
is generally not a good practice; most programmers avoid column 72 in comment statements.
A common method for adding blocks of comments to a program is illustrated in Figure 28.
*********************************************************************
*
* This is a block of comments documenting the behavior of this
* program. Since we have not written any programs yet, this block
* only illustrates how you can include large amounts of descriptive
* text to your program to help readers and maintainers understand
* what the program does -- at least, what you intended it to do.
*
*********************************************************************
Figure 28. Block comments

Exercises
6.2.1.(1) For the Assembler you use, determine what rules apply to the columns of continued
statements after the first continuation.

6.3. Statement Fields


The machine instruction, Assembler instruction, and macro-instruction statements each have four
parts called fields: the name, operation, operand, and comment or remarks fields.40 An entry in the
operation field must always be present, and for certain statements an entry in some of the other
fields may or must be omitted.
If there is a name field entry in the statement, it must begin with a nonblank character in column
1. It is terminated by the first blank column after column 1. If no name field entry is desired,
column 1 must be left blank.

40

78

Its better to call this the remarks field, to avoid confusion with comment statements.
Assembler Language Programming for IBM z System Servers

Version 1.00

After the name field and separated from it by one or more blanks is the operation field entry; it
ends with the first blank after the start of the operation field. The operation field entry is sometimes called the mnemonic or operation or operation mnemonic. 41
After the operation field entry and separated from it by one or more blanks is the operand field
entry, which, like the name and operation field entries, terminates with the first blank column
detected after the start of the operand field entry, except for one special case (quoted strings)
described in the next section.
The rest of the input line is treated as remarks by the Assembler and is ignored. It does not influence the processing of the statement unless this field extends into column 72, indicating a continuation on the next line. Except for the name field, there is no restriction on the columns where
the other three fields must start; they simply end with a blank column.
This allows free-field statements: you can arrange the information on the input lines of your
program as you like, but the fields must appear in the proper order. These rules are summarized
in Figure 29, where means one or more blanks.

column 1
end by column 71


NameFieldEntry Operation Operands Remarks
usually
optional

required

usually
required

always
optional

Figure 29. Statement fields for machine, Assembler, and macro-instruction statements

Even though any number of blanks can be used to separate the fields of a statement, it is customary to improve program readability by making all operation, operand, and remarks fields
entries start in the same columns. For example, if your name-field entries are eight or fewer characters long, place your operation field entries in column 10; similarly, if the operation field entries
are eight or fewer characters long, start your operand field entries in column 19. Later examples
of program fragments will show how this can be done.
A good programming practice is to use the remarks field to tell the reader what the statement is
supposed to do, and why. (Program comments and remarks sometimes say the program does
one thing, while it actually does something different when the CPU executes it!)
Good Programming Practice
Your programs comments and remarks should help the reader (who may
be you!) understand what each statement and group of statements is
doing, and why.
The term operand can be confusing. Section 3.1 on page 45 stated that an operand is something
in a register or in memory that is operated on during the execution portion of the instruction
cycle. Operand is also used here to describe the components that make up the operand field
entry of a statement! It helps to remember that the first meaning applies to the execution step of
a job, while the second meaning applies only during the assembly step.
Figure 30 illustrates a machine instruction statement in which entries appear in all four fields.

41

Be careful not to call it the opcode! That term is properly used for the bits of an instruction that tell the CPU what
to do. Sometimes people use opcode to mean both the operation field entry of an instruction the mnemonic and
the machine instruction bits, so listen carefully. Which is meant will usually be clear.
Chapter III: Assembler Language Programs

79

LOAD

LR

7,3

Copy c(GR3) to GR7

Figure 30. A machine instruction statement

The operand field entry has two entries, 7 and 3, separated by a comma. If the instruction is
executed in a program, it would cause the contents of general register 7 to be replaced by a copy
of the contents of general register 3.42
The assembler instruction statement in Figure 31 omits the name and comment field entries, and
causes the Assembler to put a title heading on each page of the program listing.
TITLE PROGRAM NO. 1
Figure 31. An assembler instruction statement

Figure 32 shows an example of a macro-instruction statement in which only an operation field


entry appears.
RETURN
Figure 32. The macro-instruction statement R E T U R N

If the RETURN statement above had been prepared in the days of punched cards, the card 43
might look like this:
RETURN

 
000000000000000000000000000000000000000000000000000000000000000000000000000000
11111111111111111111111111111111111111111111111111111111111111111111111111111111
22222222222222222222222222222222222222222222222222222222222222222222222222222222
3333333333333333333333333333333333333333333333333333333333333333333333333333333
4444444444444444444444444444444444444444444444444444444444444444444444444444444
555555555555555555555555555555555555555555555555555555555555555555555555555555
66666666666666666666666666666666666666666666666666666666666666666666666666666666
77777777777777777777777777777777777777777777777777777777777777777777777777777777
88888888888888888888888888888888888888888888888888888888888888888888888888888888
99999999999999999999999999999999999999999999999999999999999999999999999IBM5081
Table 12. Punched-card image of a R E T U R N statement

The Assembler supports mixed-case characters, so you need not write symbols, operation field
entries, and most operand field entries using upper-case letters. (However, the Assembler treats
lower-case and upper-case letters as equivalent when they appear in symbols and operation field
entries; unlike some high-level languages, the Assembler is not case-sensitive except for characters
within quoted strings.) Thus, you could write Figure 32 as
Return

42

43

80

The remarks in this statement are quite useless, because readers can see what the instruction does. Remarks should
explain reasons for doing something, like Copy record count to GR7 for multiplication.
The characters IBM5081 in the bottom right corner of the card were called the electro number, the number of
the plate used for printing the cards. Number 5081 was used for cards with no other information than the row
numbers, zero through nine. The empty two rows at the top were called the twelve row and the eleven row. (This
card was also known as the IBM Model 5081 Data Storage Device.)
Assembler Language Programming for IBM z System Servers

Version 1.00

with the same results.


Mixed Case Names: Be Careful!
The Assembler accepts mixed-case names, but processes them internally
as through they are all in upper case. Thus, a symbol like AbCdEfgh is
considered to be the same as the symbol ABCDEFGH.

6.3.1. What s in a Name Field? (*)


Many items can appear in the name field of an instruction statement, such as:

the name of a machine instruction


the name of a data area
a symbol to be given a value without naming any part of the program
a Labeled USING qualifier (described in Chapter XI, Section 39.4)
in the Conditional Assembler Language, a variable or sequence symbol
characters to be copied to the sequence field of the object module
... and some statement require the name field to be empty!

Some people call the name field entry a label when it is the name of a machine instruction, but
in other contexts this can be very misleading. Its too easy to start thinking of all name-field
symbols as labels when theyre actually used for other purposes.

Exercises
6.3.1.(1) Suppose a program contains the machine instruction statement shown in Figure 30.
During what part of the job processing will the statement be read by the Assembler? During
what part of the job processing will the assembled hexadecimal instruction be fetched by the
CPU?
6.3.2.(1) In what column should the remarks field of a machine instruction statement begin?
6.3.3.(1) In what columns may the operation field entry of a machine instruction statement
begin?
6.3.4.(1) Which field in an assembler instruction statement is required?
6.3.5.(2) + What types of statement may be written without an operation field? Without an
operand field? Without a remarks field?
6.3.6.(2) + Suppose the machine instruction statement in Figure 30 had been written so that
column 1 was blank, and the characters LOAD began in column 2. How would the fields of
the statement be interpreted?
6.3.7.(2) What types of Assembler Language statements may be written without an operation
field? Without a comment field?

6.4. Writing Programs


While these basic rules are nearly complete, you will be able to write executable programs after we
cover a few necessary details.
A program is a sequence of Assembler Language statements. The input to the Assembler should
consist of
1. a START statement,
2. the statements of your program, and
3. an END statement.

Chapter III: Assembler Language Programs

81

The START statement is written


progname START origin
The name-field symbol progname is the name of the program. It will usually have eight or fewer
letters. The origin operand is called the initial location or assumed origin of the program; its
value is used by the Assembler. For now, we will use zero for this initial location. Thus, the first
statement of a program should be something like
TEST

START 0

First statement of program TEST

where TEST is the name of your program.


The last statement of the program must be an END statement telling the Assembler to stop
reading records. It is written
END

progname

Last statement of program

where the progname operand of the END statement should (for now) be the same as the progname
in the name field of the START statement. For our example, we would write
END

TEST

Begin execution at TEST

The progname in the operand field of the END statement specifies the name of the instruction
where execution should start when the program is loaded into memory. The operand field entry
on the END statement may be omitted, but specifying it is a good programming practice, so well
write our sample programs this way.
The Assembler allows no symbol as the name-field entry in an END statement. Assembler Language programs, unlike programs in many high-level languages, must not try to terminate execution by allowing control to reach the END statement. Doing so usually results in some form
of disaster, since the END assembler instruction statement only tells the Assembler to stop
reading records, and is not translated into executable instructions.
The START and END statements, when read by the Assembler, determine the beginning and end
of the statements to be assembled. The START statement may be preceded by a few types of
statements (such as TITLE and comment statements), but for now, assume it is the first statement to be read. The END statement may not be followed by any other statement: it must be
last.
Some programmers like to start their programs with a CSECT (Control SECTion) statement
rather than START. It has the same effect, except that no operand field entry is allowed, so you
cant set the initial location or assumed origin value. Well discuss control sections and the
CSECT instruction thoroughly in Chapter X, Section 38.

6.5. A Sample Program


Here is a little program that prints my name. This set of records is typical of those required on
many z System systems. All statements begin in column 1 and end before column 72. (The
Line n comments are used only for this example; you dont need them for your programs.)

82

Assembler Language Programming for IBM z System Servers

Version 1.00

 80 characters
//JRETEST JOB (A925,2236067977), J.EHRMAN
Line 1
//
EXEC ASMACLG
Line 2
//C.SYSIN DD *
Line 3
Test Start 0
First line of program
Line 4
Print NoGen
Line 5
*
Sample Program
Line 6
BASR 15,0
Establish a base register
Line 7
Using *,15
Inform the Assembler
Line 8
PRINTOUT MyName,* Print name and stop
Line 9
MyName DC
C John R. Ehrman
Define constant with name
Line 10
END Test
Last statement
Line 11
/*
Line 12
Figure 33. A complete Assembler Language program

The first 3 lines and the last are control statements for the Supervisor; they are not part of your
program, and are not read by the Assembler. They tell the operating system to run the Assembler, Linker, and Program Loader, and how to pass your programs statements to the Assembler.
The information on these lines follows the rules of a Job Control Language for an operating
system. Line 1 (the JOB statement) marks the beginning of a job: a unit of work for the computer separate from all other units. Additional information on the JOB statement provides
accounting data such as an account number and a user name.
Line 2 (the EXEC statement) requests that the following program be assembled, linked, and executed; Line 3 indicates that records for the Assembler follow immediately. The last line (the /*
or end-of-file statement) tells the Operating System that no more records are given to the
Assembler.
The Assembler Language program is contained in the remaining lines:
Line 4 is the assembler instruction statement defining the name of your program as Test and
starts a Control Section to contain the machine language data and instructions of your
program when it is executed by the CPU.
Line 5 is an assembler instruction statement; it causes the Assembler not to print statements
generated by the PRINTOUT macro-instruction in Line 9. (More about PRINTOUT and other useful
macro-instructions in Section 6.6 on page 84.)
Line 6 is a comment statement.
Line 7 is a machine instruction statement.
Line 8 is an assembler instruction statement. (Lines 7 and 8 are important: well discuss them
in Section 10.)
Line 9 is a macro-instruction statement that causes some data to be printed, and then returns
control to the Supervisor.
Line 10 is an assembler instruction statement. The Assembler converts the characters enclosed
in the apostrophes into an internal form representing the characters.
Line 11 is an assembler instruction statement. It tells the Assembler that no further statements
will be processed for this program. The operand field entry Test tells the Linker where you
want your program to begin execution.

Exercises
6.5.1.(1) + Determine what control statements are required at your installation for the following
sequences of steps (if they are available): (1) assembling a program, (2) assembling and linking a
program, (3) assembling, linking, and executing a program, (4) assembling, loading, and executing a program, and (5) linking and executing an object module created in a previous
assembly.
6.5.2.(1) At execution time, if control reaches the END statement, will that be the end of the
program?
6.5.3.(1) Examine the Assembler Language program in Figure 33. Which statements have
entries in the name field? In the operation field? In the operand field? In the comment field?
Chapter III: Assembler Language Programs

83

6.6. Basic Macro Instructions


For our sample programs, we need only very simple methods of reading 80-character cardimage records, printing strings of characters, displaying useful information, and displaying or
dumping areas of memory in hexadecimal format.
Your operating system may provide similar facilities already, but you should check to see how or
whether they differ from these. We will use these six macro-instructions, and show how theyre
used in some programming examples.
PRINTOUT

Print formatted information about data and registers

READCARD

Read 80-byte card-image records

PRINTLIN

Print lines of characters

DUMPOUT

Dump memory in hexadecimal format

CONVERTI

Convert decimal characters to a 32- or 64-bit binary integer

CONVERTO

Convert a 32- or 64-bit binary number to decimal characters

The macro instructions and their operands are described in Appendix B: Simple I/O Macros on
page 1001.

6.7. Summary
The Assembler provides many facilities to simplify programming tasks.
1. It automatically resolves addresses into the base-displacement and other forms used by
z System. The Assembler determines the needed base and displacement so that correct Effective Addresses will be calculated at execution time.
2. Rather than remembering that operation code X 43 copies a byte from memory into the
right end of a general register, a mnemonic operation code gives a simple indication of what
the operation code does. (The term operation code is often abbreviated opcode.) The
opcode X 43 has mnemonic IC, which stands for Insert Character.
3. Symbols let you name areas of memory and other objects in your program.
4. Diagnostic messages warn you about possible errors and oversights.
5. The Assembler converts data from convenient external representations into internal forms.
6. It creates relocatable object code to be combined with other programs by the linker.
7. Using macro-instructions, you can define your own instruction names to supplement existing
instructions, and your own macro-instructions can make use of previously defined sequences
of statements, including other macros!
8. It provides lots of other helpful information such as cross-references of symbols, registers, and
macros.

Terms and Definitions


Assembler
A program that converts Assembler Language statements into machine language, in the form
of an object module.
assembly time
The time when the Assembler is processing your programs statements, as distinct from the
time when the machine language instructions created from your Assembler Language
program are executed by the processor.

84

Assembler Language Programming for IBM z System Servers

Version 1.00

statement
The contents of the records read and processed by the Assembler. There are four types:
comment statements, machine instruction statements, assembler instruction statements, and
macro-instruction statements.
statement field
One of the four fields of an Assembler Language statement (other than a comment statement). They are the name, operation, operand, and the remarks fields. Which fields are
required and/or optional depends on the specific statement.
operand
(1) Something operated on by an instruction. (2) A field in a machine instruction statement.
object module
The machine language information created by the Assembler, used as input to the Linker.
object code
The machine language contents of an object module.
load module
Our generic name for the output of a Linker; a mixture of machine language instructions and
data ready to be loaded directly into memory for execution.
Linker
A program that converts and combines object modules and load modules into an executable
load module format ready for quick loading into memory by the Program Loader. The
term Linker can describe several programs:
Binder
The z/OS program that can generate load modules (and a newer form, program objects)
as well as place the linked program directly into memory.
Linkage Editor
The predecessor to the z/OS Binder; its functions are included in the Binder. A Linkage
Editor is used on z/VSE.
Loader
This can have several meanings:
On z/VM systems, a program that can link object modules directly into memory for
execution, or generate a relocatable MODULE.
On older OS/360 systems, a program that links object and load modules into
memory for execution; now called the Batch Loader.
relocation
A procedure used by the Linker and the Program Loader to ensure that addresses in your
loaded program are correct and usable.
Program Loader
The component of the Operating System that brings load modules into memory, makes final
relocations, and transfers control to your program.
execution time
The time when your program has been put in memory by the Program Loader and given
control. This may happen long after assembly time.
origin
A starting value assigned by you (or by the Assembler) needed to calculate offsets and displacements in your program. Because most programs are relocated, its rarely necessary to
specify an origin.
mnemonic
A convenient shorthand for the name of an instruction. For example, the Branch and Save
instruction has mnemonic BASR.
macro instruction
A powerful means to encapsulate groups of statements under a single name, and then generate them (with possible programmer-determined modifications) by using the macroinstruction name as an operation field entry.

Chapter III: Assembler Language Programs

85

Job Control Language


The statements needed to tell your Operating System how to process your program through
the assembly, linking, and execution phases. JCL for short.
code
An informal term for groups of Assembler Language statements.

Programming Problems
Problem 6.1.(2) + Write, assemble, link, and execute a short program (like the one in Figure 33
on page 83) that will print your name. Look through the printed output from the job, and
determine which parts were printed by the Assembler, the Linker, and the executed program. (If
your name contains apostrophes (like O Brien), you must type a pair of them wherever you
want to print one, as in O BRIEN.) Observe what is produced by the Assembler for each type
of statement.
Problem 6.2.(2) + Using your solution to Problem 6.1 as a template, write and execute a
program that will generate a noncontroversial, culturally-sensitive, nonpolitical message such as
Message = C Hello, World!

86

Assembler Language Programming for IBM z System Servers

Version 1.00

7. Self-Defining Terms and Symbols

777777777777
777777777777
77
77
77
77
77
77
77
77
77
77
77

We now investigate two important features of the Assembler Language, self-defining terms and
symbols. Each has a numeric value. In a self-defining term, the value is constant and inherent in
the term, so you can think of them as different ways to write numbers. Self-defining terms are not
data! They are just numbers that can be written in any of several convenient forms; they all result
in 32-bit integer values. Symbols have values assigned by you and by the Assembler.

7.1. Self-Defining Terms


There are four44 basic types of self-defining term: decimal, hexadecimal, binary, and character. The
value of each is treated by the Assembler as a 32-bit twos complement number.
A decimal self-defining term is an unsigned string of decimal digits. 12345, 98, and 007 are
examples of decimal self-defining terms. The size of a decimal self-defining term is determined
by the fact that 32 bits are allotted by the Assembler to hold its value during assembly.
Because it is unsigned, a decimal self-defining term must lie in the range from 0 to + 231 1
(2147483647). Thus, + 2147483647 and 2147483647 are not valid decimal self-defining terms
because they are signed, even though their values can be correctly represented in 32 bits.
A hexadecimal self-defining term is written as the letter X, an apostrophe, a string of
hexadecimal digits, and a second apostrophe. X123456, X FACED , and X001B7 are examples
of hexadecimal self-defining terms. The value of a hexadecimal self-defining term must lie in
the range from 0 to + 232 1, or, between X00000000 and X FFFFFFFF . If fewer than eight
digits are specified, the Assembler assumes that the omitted digits are high-order zeros. If the
high-order digit of an eight-digit hexadecimal self-defining term lies between X 8 and X F , the
value of the term is negative.
Because hexadecimal terms represent just a string of bits, their value can be greater than
231 1, unlike decimal terms.
A binary self-defining term is written as the letter B, an apostrophe, a string of binary digits,
and a second apostrophe. B110010, B0001, and B1111111100001100 are examples of
binary self-defining terms. Because 32 bits are allotted for the value of a self-defining term, at
most 31 binary digits may follow the first 1-bit. (For example,

44

A fifth type of self-defining term, the Graphic type, requires invoking the Assembler with the DBCS option. Its use is
beyond the scope of this section, but well meet it again in Chapter VI, Section 26.4.
Chapter III: Assembler Language Programs

87

B00000000000000001000000000000000000000000 has 41 digits, but only 24 significant digits


follow the first 1.) If fewer than 32 digits are specified, the Assembler assumes that the
omitted digits are high-order zeros.
The value of a binary self-defining term must lie in the range from 0 to 232 1. The value of a
binary self-defining term is negative if the leftmost significant bit of the 32-bit digit string contains a 1-bit.
We will see in Chapter 4 that embedded blanks can be used in decimal, binary, and hexadecimal
constants to improve readability. However, embedded blanks cannot be used in self-defining
terms of those three types.
A character self-defining term is written as the letter C, an apostrophe, a string of up to four
characters (except for two special cases to be described momentarily), and a second apostrophe. Thus, C A , C . . . , and C AB are valid character self-defining terms. (Remember
that we are using to represent a blank.) This last example, in which a blank appears, is
the one exception to the rule mentioned in the previous section that stated that the operand
field is terminated by the first blank column after it starts: if the blank is part of a character
string enclosed in apostrophes, as in a character self-defining term, it doesnt terminate the field
but is part of the operand. A blank terminating the operand field must appear outside of a
character string enclosed in apostrophes.
The two special cases concern the apostrophe ( ) and the ampersand (&). Since apostrophes
are used to delimit the character string, we need a way to get an apostrophe into the generated
character string. (The ampersand has special uses in macro-instructions.) We represent a
single apostrophe or ampersand in a character string by a pair of apostrophes or ampersands.
A character self-defining term containing a single apostrophe or a single ampersand is written
C or C&&. This can lead to cryptic but valid forms like C (for the three characters , giving a term with value X007D7D7D ), and and C&&&& (for the three characters
&&, giving a term with value X00507D50 ). A pair of apostrophes is entered as two characters,
and should not be confused with the quotation mark (), which is a single character.45
Character self-defining terms use the EBCDIC character representation described next.

Exercises
7.1.1.(2) + Which of the following are valid self-defining terms? If you think a term is invalid,
explain why; otherwise, give the hexadecimal value of the term.
(1)
(2)
(3)
(4)
(5)
(6)
(7)

00000012345
B10101010101010101
X0000B4DAD
X B4DAD0000
+65535
B000000000001111000011110000111101
B101011010001111000011110000111101

7.1.2.(1) The maximum value of a decimal self-defining term is 231 1, while the maximum
value a binary or hexadecimal self-defining term is 232 1. Why are they different?

45

88

Unfortunately, people sometimes call the apostrophe or single quote a quotation mark or single quotation mark.
Calling a quotation mark a double quote or doesnt help either, because it might be understood to mean a pair
of apostrophes.
Assembler Language Programming for IBM z System Servers

Version 1.00

7.2. EBCDIC Character Representation


The value assigned to a binary, decimal, or hexadecimal self-defining term is clear, as they are
familiar bit patterns. But what value should we give to a character self-defining term? This
depends on the internal representation or code defined for characters. We could decide that the
value of C A should be the same as X 0A , or X 4 1 , or X 7 4 , or X A1 , or even X C1 .
In z System the conventional character code is called the Extended Binary Coded Decimal Interchange Code, or EBCDIC for short. 46 Each character is represented internally by an eight-bit
number two hexadecimal digitsas indicated in Table 13. The internal bit patterns that represent
external characters are a matter of choice; any mutually agreeable set is about as good as any
other. The Extended BCD code, or EBCDIC, is the code defined by the designers of System/360
for communicating with character-sensitive components of the computer such as the CPU,
printers, graphic display devices, etc. We will see other important character encodings in Chapter
IV, Section 12.8, and again in Chapter VII, Section 26.
This table shows the EBCDIC representation used by the Assembler, Code Page 037. (There
are many other EBCDIC code pages used around the world.)
Table 13. Assembler Language EBCDIC character representation
Char
Hex
Char
Hex
Char
Hex
Char
Hex
Blank
40
e
85
y
A8
S
E2
.

4B

86

A9

E3

4D

87

C1

E4

4E

88

C2

E5

&

50

89

C3

E6

5B

91

C4

E7

5C

92

C5

E8

5D

93

C6

E9

60

94

C7

F0

61

95

C8

F1

6B

96

C9

F2

6D

97

D1

F3

7B

98

D2

F4

7C

99

D3

F5

7D

A2

D4

F6

7E

A3

D5

F7

81

A4

D6

F8

82

A5

D7

F9

83

A6

D8

84

A7

D9

In Table 13 we see that the value associated with the character self-defining term C / is the same
as that of the hexadecimal self-defining term X 6 1 , the binary self-defining term B1100001, and
the decimal self-defining term 97. Similarly, the character self-defining term C has the same
value as the hexadecimal self-defining term X 7D , and C&& has the same value as X 5 0 . Which
type of term you choose is largely a matter of context; in some places, certain types will be more
natural than others.

46

Occasionally it is even called BCD. That term is normally used to denote an older six-bit character code or even a
4-bit encoding of decimal digits; the eight-bit Extended BCD code is used to represent characters on z System.
Chapter III: Assembler Language Programs

89

The value of a character self-defining term is determined by right-adjusting the EBCDIC codes of
the characters in a 32-bit field, and filling with zero bits at the left end if needed. Thus, the value
of C A is X000000C1 , and the value of C ABC is X00C1C2C3 .47
The characters shown in Table 13 are the portion of the EBCDIC character set used in the
Assembler Language (except in character self-defining terms and character constants, where all 256
possible characters are allowed). The codes for other characters are defined in the z/Architecture
Principles of Operation. It is worth remembering that the EBCDIC code for a blank space is
X 4 0 .

Exercises
7.2.1.(2) + Which of the following are valid self-defining terms? If you think a term is invalid,
explain why; otherwise, give the hexadecimal value of the term.
(1)
(2)
(3)
(4)
(5)
(6)

C # @$
C
C AB
C RUD
C 1 2
C 12

(one leading blank)

(three leading blanks)

7.2.2.(2) + Give (in hexadecimal) the value of each of the following character self-defining terms:
(1) C&&, (2) C 7 5 , (3) C , (4) C C , (5) C 0 , (6) C SDT .
7.2.3.(3) Another widely used character representation is the United States of America Standard
Code for Information Interchange, or ASCII. Determine the ASCII representation of the characters in Table 13 on page 89.
7.2.4.(2) + Give (in hexadecimal) the value of each of the following self-defining terms:
(1) C , (2) 1000, (3) B01000, (4) C&&&&, (5) C , , (6) C A=B .
7.2.5.(3) + For each of the following values, display all four self-defining terms that may be used
to represent it. (1) 64, (2) 245, (3) C&&, (4) X405C , (5) X F9F9F9F9 ,
(6) B110001011101100111010001.
7.2.6.(1) What EBCDIC character would be represented by the bit pattern in the byte illustrated in Figure 6 on page 45?
7.2.7.(1) Show the hexadecimal value of each of the following self-defining terms:
(a)
(b)
(c)
(d)

B110010110000010111010110
C A&&B
54721
X B00B00

7.2.8.(1) Consider the 16 bits 1101000111000101:


1. Write them as four hexadecimal digits.
2. Assuming the bits represent an unsigned (logical) binary number, give its value.
3. Assuming the bits represent a signed binary number in the twos complement representation, give its value.
4. Write them as two EBCDIC characters.
7.2.9.(1) Give the hexadecimal value of these self-defining terms:

47

90

In some cases, you might want to use a different character set in character terms. It is possible that the Assembler
might assume that your characters are represented in EBCDIC, and generate the wrong value. If you specify the
TRANSLATE and COMPAT(TRANSDT) options, Assembler will use your chosen representation for character
terms. (See the High Level Assembler Programmer s Guide for details.)
Assembler Language Programming for IBM z System Servers

Version 1.00

1. B110010111000010111011001
2. C R&&Z
3. 51401
7.2.10.(2) + Give the value in hexadecimal of these self-defining terms:
(a) B01110101100010
(b) C +
(c) 10010

7.3. Symbols and Attributes


Many programming problems can be greatly simplified by using symbols. If this were not so, we
might try to dispense with Assemblers and be content with producing programs consisting of
strings of hexadecimal digits; thus we would write the hex digits X 580064EC instead of a
machine instruction statement containing symbols.
Symbols are more interesting than self-defining terms: they let you assign meaningful names to
parts of your program. You can give the name PLUS1 to an area containing the constant +1, and
the name READ to an instruction that reads data.
Three types of symbols are used in the Assembler Language: ordinary symbols, variable symbols,
and sequence symbols. The last two are used only in macro-instructions and in conditional
assembly, so we wont say more about them here.
There are two types of ordinary symbols: internal and external. External symbols are used during
linking to communicate with other programs (and are part of the object module, as well see in
Chapter X, Section 38), while internal symbols are used only during the assembly, and do not
appear in the object module. 48
For now, we assume that all symbols are internal symbols. A word of caution: if you have done
some programming in a high-level language, you may be inclined to think of symbols as variables.
They arent; the differences are described in Section 7.7 on page 96.
A symbol is a string of letters or digits, the first of which must be a letter. The characters $,
_, #, and @ are considered to be letters in the Assembler Language.49 These special characters are not allowed in symbols:
(

&

blank

Early Assemblers restricted symbols to at most eight characters, which is why the customary
operation field of a statement begins in column 10. HLASM allows mixed-case symbols up to 63
characters long, but there is no difference between upper and lower case letters. Thus, NAME, Name,
and name all refer to the same symbol.
The following are all valid symbols.
A
#235
James
$746295

48

49

Agent086
O0@H
KQED
Wonka

A1B2D3C4
ApoPlexy
Prurient
ZYZYGY99

_The_End
The_Utter_Final_Bitter_End
EtCetera
Close_Files

Internal symbols are added to the object module if you specify the Assemblers TEST option, but that option is little
used now. The ADATA option is preferable, because it generates a SYSADATA side file containing much more
useful information that can be used by other programs like debuggers.
If theres any chance your program might be sent (or read or printed) outside the United States, avoid the national
characters #, @, and $. They may look different in other countries, or may even have different EBCDIC representations. Other characters usable in Assembler Language symbols those in Table 13 always have the same EBCDIC
representations.
Chapter III: Assembler Language Programs

91

Note that the first character of the symbol OO@H must be the letter O and not the digit zero 0.
(A good reason to avoid using symbols starting with the letter O!)
The following are not valid symbols, for the reasons given.
$7462.95
(decimal point not allowed)
Bond/007
(special character / not allowed)
Set Go
(no blanks allowed)
Ten*Five
(contains the special character *)
C Wonka
(no apostrophes allowed)
2Faced
(doesn t begin with a letter)
An_Absurdly_Long_Symbol_With_No_Use_Other_Than_To_Illustrate_Excessive_Symbol_Length (!)
Several numeric quantities called attributes are associated with a symbol. Symbols have six
primary attributes: value, relocation, length, type, scale, and integer.50 Of these, the value and
length attributes are most important; the rest will be described as needed. The length attribute is
especially useful, and well see how its defined when we examine constant definitions in Section
11.
The Assembler assigns numeric values to the attributes of a symbol when it encounters the
symbol as the name field entry in a statement. We say that a symbol has been defined when
numeric values have been given to its value, relocation, and length attributes. These three attributes, like all other numeric attribute values, are always nonnegative.
This terminology is clumsy: rather than the numeric value of the value attribute of a
symbol, we simply say the value of the symbol. Similarly, the numeric value of the relocation attribute of a symbol is its relocatability. We say that a symbol whose relocation
attribute is nonzero is relocatable, and a symbol whose relocation attribute has a zero value is
not relocatable, or that it is absolute.51
We call the numeric value of the length attribute of a symbol its length attribute. It
depends on the type of statement named by the symbol. Occasionally someone refers to the
length of a symbol when its length attribute is meant; but the length of a symbol might be
misunderstood to mean the number of characters in the symbol itself, which is rarely interesting. The length attribute is different, and is very useful.
For example, while the symbol A is one character long, it could have length attribute 133!
Symbols are used mainly as names of places in the program. For example, in Figure 30 on
page 80, the symbol LOAD is the name of the instruction. Similarly, in the machine instruction
statement
GETCONST L

0,4(2,7)

the symbol GETCONST is the name of an area of the program containing a machine instruction. In
the Assembler instruction statement
TEN

DC

F 1 0

the symbol TEN is the name of a word area of the program where the Assembler will place a
binary integer constant with decimal value 10.
In the macro-instruction statement
EXIT

RETURN (14,12),T

the symbol EXIT names the area of the program containing the set of instructions generated by
the RETURN macro-instruction.

50

51

92

Conditional assembly supports additional attributes: Assembler, Count, Number, Defined, Opcode, and Program.
The Assembler, Opcode, and Type attributes have nonnumeric values.
A useful definition of the relocation attribute is that a symbol that names a place in a program is relocatable; details
are given in Section 7.6 on page 95. A convenient image is to think of the relocation attribute of a symbol as its
color: the Assembler assigns the same color to all symbols having the same relocation attribute, and no color to
absolute symbols.
Assembler Language Programming for IBM z System Servers

Version 1.00

No symbol can be given a value in a comment statement.


Remember: the attributes of the symbols, and the symbols themselves, exist only at assembly
time. They help in producing the object program; internal symbols and their attributes are discarded when the assembly is complete.52

Exercises
7.3.1.(2) + Which of the following are valid symbols? If you think a symbol is invalid, explain
why.
(1)
(2)
(3)
(4)
(5)
(6)
(7)
(8)
(9)

SuperBOY
Captain Major
KillerWhale
Send400$Soon
#@$!
4Hundred$Sent
?
(Eight)
@9AM

7.3.2.(2) Some Assemblers (for processors other than z System) allow you to define a symbol
as a string of alphanumeric characters at least one of which must be a letter (it neednt be the
first character). Can you think of any reasons why the designers of the Assembler Language
decided not to allow this form of symbol?

7.4. Program Relocatability


Understanding the value and relocation attributes of a symbol is usually not very important. You
can write lots of Assembler Language programs without ever having to know how and why the
Assembler uses these attributes. When things go wrong (and because things will go wrong), it is
worth understanding some basic features of value and relocation.
The most important part of the Assemblers task of converting a program from Assembler Language statements to machine language code is determining the relative positions of all parts of
your program. To do this, the Assembler constructs an accurate model of the program as it will
eventually reside in memory when it is executed.
This model is necessarily incomplete, for two reasons:
1. The Assembler normally has no way to know where the program will eventually be placed in
memory by the Program Loader.
2. There is no way for the Assembler to know the relationship of the program it is assembling
to other programs that will be combined with it in the load module produced by the Linker.
Methods for handling the second reason will be treated when we discuss external linkages and
subroutines in Chapter X, Sections 37 and 38.
Because the Assembler cannot determine in advance what memory addresses will eventually hold
the program, it must produce a machine language program that will work correctly no matter
where it is placed at execution time. That is, the program must be relocatable. Thus, in building
its model of the final form of the program, the Assembler only needs to determine the relative
positions of the parts of the program it is assembling.
The Assembler doesnt know where the program will eventually be placed in memory, so it does
the next best thing:

52

This information can be saved in a SYSADATA side file when you specify the Assemblers ADATA option.
Chapter III: Assembler Language Programs

93

1. It assumes that the program starts at some arbitrary (or programmer-specified) origin, and
generates instructions and data based on that assumption.
2. It includes enough information about its assumptions in the object module, so the Linker
and the Program Loader can tell (a) what starting location was assumed, and (b) what parts
of the program will contain or depend on actual memory addresses at the time the program is
executed.
3. By computing the difference between the programs assembly-time starting location assumed
by the Assembler, and its true starting address assigned at execution time by the Supervisor,
the Program Loader can supply (relocate) the necessary true addresses used at execution
time.
In practice, very few parts of a program depend on knowing actual addresses; these will almost
always involve the use of address constants; well introduce them in Section 12.2 on page 149.
Many programs can be written to contain no address-dependent information.

7.5. The Location Counter


To help clarify the differences between assembly and execution times, we will make a careful and
important distinction between locations and addresses.
Locations refer to positions in the Assemblers model of the program at assembly time.
Addresses refer to the positions in memory, at execution time, where the various parts of the
program reside.
Locations and Addresses
Locations are used at assembly time; addresses are used at execution time.
The relationship between locations and addresses is close; they differ at most by a single constant
value, the difference between the Assemblers assumed assembly-time starting location and the
Supervisors assigned execution-time starting address. This difference is handled by the Program
Loader when it relocates the program just before execution, so we dont have to worry about this
at assembly time. 53
To assign locations to the various parts of your program as it is assembled, the Assembler maintains an internal counter called the Location Counter, or LC. The initial value of the LC is the
initial location or assumed origin specified on the START statement (see Section 6.4 on page
81); or, if no initial location is specified, the Assembler assigns an initial LC value of zero.
As the Assembler reads your program, it determines how many bytes will be required in the
program for the instruction or data generated for each statement. It adds this number to the LC,
and then reads and processes the next statement. In this way, the Assembler determines the
location and length of each part of the program.
It is important to understand the difference between the Assemblers Location Counter and the
C P U s Instruction Address. The LC is a counter used by the Assembler at assembly time to
determine positions within a program; it goes away when the Assembler is removed from memory
at the completion of an assembly. The IA is a part of the CPUs PSW, and contains the address
of the next instruction to be fetched at execution time; it is always in use whenever any program is
being executed.

Exercises

53

94

The Assembler puts the assumed origin into the object module to help the Linker adjust addresses correctly.
Assembler Language Programming for IBM z System Servers

Version 1.00

7.5.1.(3) + In the following program segment, determine (1) the value attributes of all symbols,
and (2) the LC value at the time each statement is read by the Assembler. The length of the
generated instructions and data are given in the comment field of each statement.
EX7_5_1 START
BASR
BEGIN
L
A
ST
DUMMY
DS
N
DC
ONE
DC

X5000
6,0
2,N
2,ONE
2,N
XL22
F 8
F 1

0
2
4
4
4
22
4
4

bytes
bytes
bytes
bytes
bytes
bytes
bytes
bytes

generated
generated
generated
generated
generated
generated
generated
generated

We will revisit this program fragment in Section 10.

7.6. Assigning Values to Symbols


Instructions and data are given names by writing symbols as the name field entry of the statement. When the Assembler encounters such a symbol, it enters it into a Symbol Table containing
the programs symbols and their attributes.
1. The value attribute (or simply, the value) of the symbol is determined from the contents of
the LC at the time the statement was processed, before adding the length of the generated
instruction or data.
2. The relocation attribute will be nonzero, to indicate that the symbol is relocatable. (We will
see shortly how to define absolute symbols that are not relocatable.)
3. The length (in bytes) of the generated instruction or data is assigned as the value of the length
attribute (in most cases).
There are, of course, occasional minor exceptions to these general rules.
There is a simple test to determine whether an internal symbol is relocatable: add a constant to
the initial value of the LC, and re-assemble the program. If the value of the symbol increases by
exactly the same amount, then the symbol is relocatable. If the value doesnt change at all, the
symbol is absolute.
The names of instructions and data areas in a program are relocatable; these are the most frequent
uses of symbols. The numeric value of the relocation attribute of a symbol is assigned by the
Assembler, and can be determined from the Assemblers External Symbol Dictionary, another part
of the object module.
To illustrate how values are assigned to symbols, suppose that when the statement named
GETCONST (on page 92) is read by the Assembler, the value of the LC is X0007B6 . Then the
symbol GETCONST would appear in the Symbol Table with value X0007B6 ; it would be relocatable; and because the statement specifies an RX-type instruction, the length attribute will be 4.
Before reading the next statement, the Assembler increments the LC by the length of the instruction, so that its value will then be X0007BA .
Similarly, if the sample statement named TEN (on page 92) was encountered when the LC value
was X012D88 , then the value of the symbol TEN would be X012D88 ; it would be marked as
relocatable; and its length attribute would be 4. The LC value after incrementing would be
X012D8C .
To define an absolute symbol, we use the EQU assembler instruction statement:
symbol

EQU

self-defining term

This statement causes the value of the self-defining term to be assigned as the value attribute of
the symbol. (More about the EQU assembler instruction is in Section 13.3.) Thus, the statement
ABS425

EQU

425

Chapter III: Assembler Language Programs

95

defines the symbol ABS425 by assigning a value of 425 (X000001A9 ), a relocation attribute of
zero, and (for want of anything better) a length attribute of one. The symbol ABS425 is simply the
name of a number!
Absolute symbols give you great freedom and flexibility in writing your programs. We will find
many ways to use absolute symbols whose values do not change if the initial LC value is changed.

Exercises
7.6.1.(1) Why can a symbol not be given a value in a comment statement?
7.6.2.(1) The symbol TEN on page 91 will be assigned a length attribute of 4 by the Assembler.
What is the length of the symbol?

7.7. Symbols and Variables


In Assembler Language, we make some important distinctions in terminology. In high-level languages such as FORTRAN, COBOL, PL/I, and C, symbols are normally used to name variables:
you can assign new values to them as the program executes. Thus, you might write
BAD = GOOD + 7*(LOG(BETTER)/SQRT(BEST)) ; /* Assign new value to BAD */
and understand it to mean evaluate the quotient of the results of the LOG and SQRT functions,
multiply that by 7, add the result to the current value of the variable GOOD, and assign the result as
the new value of the variable BAD. Assembler Language doesnt work this way! The value of a
symbol is not the value of a variable of the same name.
Assembler symbols
Assembler Language symbols are not variables. There are no variables
in the Assembler Language were describing!54

Some of the differences in the meanings of symbols in high-level languages and Assembler Language are shown in Table 14.
Assembler Language
Used only at assembly time
Names of places in a program
Contents of memory has a value
The name has a location value used by the
Assembler to lay out and organize the program

High-Level Languages
Can be thought of as existing at execution
time
Contain execution-time values
Variable has a value
The name is thought of as naming the value of
a variable

Table 14. Differences between Assembler Language and high-level language symbols

We will have more to say about this in Section 13.8 on page 175.

Terms and Definitions

54

96

The conditional assembly language does have variable symbols, but that topic is beyond what were discussing now.
Assembler Language Programming for IBM z System Servers

Version 1.00

Location Counter (LC)


A counter used by the Assembler at assembly time to build its model of the relative positions
of all components of an assembled program.
self-defining term
One of binary, character, decimal, and hexadecimal. Its value is inherent in the term, and
does not depend on the values of other items in the program.
EBCDIC
Extended Binary Code Decimal Interchange Code. Used to assign numeric values to characters. There are many EBCDIC encodings; they assign different values to some characters, but
all the alphabetic, numeric, and other characters used in the Assembler Language listed in
Table 13 on page 89 are invariant across EBCDIC encodings, except for the characters $,
@, and #.
symbol
A name known at assembly time, to which various values are assigned. The values may be
absolute or relocatable (or even complexly relocatable, as well see in Section 8.3).
defined symbol
A symbol is defined when the Assembler assigns values to its value, relocation, and length
attributes.
symbol attribute
Useful information about the properties of a symbol. Attributes include value, relocation,
length, type, scale, and integer. (Only the first three attributes are important for our current
needs.)
relocatable
A property of a program allowing it to execute correctly no matter where it is placed in
memory by the Program Loader.
relocation
Actions performed by the Linker and Program Loader to ensure that a program in memory
will execute correctly no matter where it is loaded. This may require assigning true executiontime addresses to parts of a program.

Chapter III: Assembler Language Programs

97

8. Terms, Operators, Expressions, and Operands

8888888888
888888888888
88
88
88
88
88
88
88888888
88888888
88
88
88
88
88
88
888888888888
8888888888

In this section we will see how to specify components of the operand field entry of various
instruction statements.
The operand field entry of a typical machine instruction statement is a sequence of operands separated by commas. For example, a typical instruction statement might look like this:
symbol

operation operand1,operand2,...

optional remarks

where the name field symbol is often optional, and the operand field may specify zero to many
operands.
The operands are formed from expressions that are in turn formed by combining terms and operators.

8.1. Terms and Operators


The basic elements of an expression are terms. They can be any of the following items:

a
a
a
a
a

self-defining term
symbol
Location Counter reference
literal
Symbol Attribute reference
Length
Integer
Scale

We will discuss Integer and Scale attributes later; while they arent used frequently, they can be
very helpful in certain situations.

98

Assembler Language Programming for IBM z System Servers

Version 1.00

Terms
Length, integer, and scale attribute references to a symbol are always
absolute terms; a symbol can be either absolute or relocatable; literals
and Location Counter references are always relocatable. A self-defining
term is always absolute.
We have seen how to write symbols and self-defining terms. Literals are special symbols that
provide a convenient way to write constants, and we will discuss them in Section 12.6.
A Location Counter reference is written as a single asterisk; it has the attributes of the Assemblers Location Counter, and a length attribute that depends on the type of statement where it is
used. The value of * as a Location Counter reference therefore changes during an assembly as the
LC value changes.
A symbol length attribute reference is written as a letter L followed by an apostrophe followed by
a symbol (or an asterisk, for a Location Counter reference).
L SYMBOL

or

L *

is an absolute term whose value is the length attribute of the term following the apostrophe.
The operators used for combining terms are + , , *, and /, indicating addition, subtraction, multiplication, and division respectively. A term has no sign; however, + and may be used as
unary or prefix operators, as in +5. In Assembler Language, the asterisk is therefore used in two
ways: to denote a Location Counter Reference and as the multiplication operator. The Assembler can distinguish these two uses.

8.2. Expressions
An expression is an arithmetic combination of terms and operators. In the absence of unary plus
or minus signs or parentheses, an expression must begin and end with a term, and there must be
an operator between each pair of terms. To illustrate, two expressions are
GETCONST+X 4A

and

X+L X

The following expression uses all four types of self-defining term:


X12+C . -B0001010001+7
Parentheses may be used, as in ordinary mathematical use (and as in familiar procedural languages) to indicate groupings. In evaluating expressions, an expression in parentheses is treated as
a term. Thus
(A+2)*(X4780-JJ)
is an expression that is the product of two subexpressions, each of which has two terms and one
operator.
Syntactically, an expression may not contain two multiplication or division operators in succession, or an addition or subtraction operator followed by a multiplication or division operator.
For example:
*+2
-A, +A
A++B, A--B,
A/+B, A/-B,
A+/B, A-/B,
A**B, A*/B,

A+-B,
A*+B,
A+*B,
A/*B,

A-+B
A*-B
A-*B
A//B

valid because * is a Location Counter reference


are valid uses of unary + and are valid (second + and second - are unary operators)
are valid (+ and - are unary operators)
are invalid
are invalid

Some syntactically valid expressions might not be evaluatable if either or both terms is relocatable
(to be described shortly).

Chapter III: Assembler Language Programs

99

An easy way to determine the validity of expressions with sucessive operators is to parenthesize
each operator with its immediately following term, so that A++B becomes A+(+B); because the
unary + in (+B) is equivalent to B, A++B is evaluated as A+B. (See Exercise 8.2.3.)

Exercises
8.2.1.(2) What would you expect to be the result of A--B, A+-B, and A-+B?
8.2.2.(1) What is the value of the expression X12+C . -B0001010001+7?
8.2.3.(2) + Determine the syntactic validity of each of the following expressions; and if the
expression is valid, show its simplified form.
a.
b.
c.
d.
e.

A+-+-B
A*--B
A-*-B
A---B
--A-++B

8.3. Evaluating Assembly-Time Expressions (*)


The rules for evaluating expressions are familiar, with one or two minor exceptions, so its no
surprise that the Assembler evaluates 2+3 as 5.
Remember: we are describing the Assemblers evaluation of assembly-time expressions involving
the values of assembly-time symbols and other terms. This is entirely different from most highlevel languages, where an expression like A+B in a statement is evaluated at execution time, using
the values of the execution-time variables A and B.
The details of the rules can be rather complicated, so dont try to grasp everything on a first
reading. The examples on page 102 will help to illustrate the rules.
1. Each term (along with any preceding unary operator) is evaluated to word precision, 32 bits.
The relocation attribute of each term is noted, so that the relocation attribute of the entire
expression can be evaluated also, as described in rule 10 below.
2. Inner parenthesized subexpressions are evaluated first, using 32-bit twos complement arithmetic. The resulting value is used in computing the rest of the expression. Thus in
(X100+2*(ABS425-420))+1
where ABS425 has value 425 (as defined on page 95), the subexpression (ABS425-420) would be
evaluated first. The value of the whole expression is X0000010B , and is absolute.
3. Multiplications and divisions are done before additions and subtractions. Thus the value of
the expression just given would be evaluated as (X100+(2*(5)))+1 and not as
((X100+ 2 ) * ( 5 ) ) + 1 . Multiplication and division operators may not be combined, as in /*
and */.
4. Relocatable terms or subexpressions may not occur in multiplication or division operations.
5. Operations are performed in left-to-right order within a group of operations of the same priority. Thus 5*2/4 means the same as (5*2)/4, not 5*(2/4); similarly, 5/2*4 means the same as
(5/2)*4, not 5/(2*4).
6. Multiplications yield a 64-bit result, of which the rightmost 32 bits are kept, and the highorder (leftmost) 32 bits are discarded. Significant bits can be lost if the product is too large.
7. Division always yields an integer result; the Assembler always discards remainders when evaluating expressions. Thus 5*2/4 has value 2, and 5*(2/4) has value zero. Division by zero is
permitted, and the result is simply set to zero.

100

Assembler Language Programming for IBM z System Servers

Version 1.00

8. Negative quantities are carried in twos complement representation.


9. When the expression has been completely evaluated, the result is in 32-bit twos complement
form.
10. The relocation attribute of the result is found as follows; assume that the symbol A is relocatable:
If there is an even number of relocatable terms appearing in the expression and they are
paired (that is, they have the same relocation attribute appearing with opposite signs) so
that a change in the relative origin assigned to the program has no effect on the value of
the expression, then the expression is absolute. For example, A-A+2 is an absolute
expression with value 2.
If there is one remaining unpaired term not directly preceded by a minus sign, then the
expression is simply relocatable, and it has the relocation attribute of the unpaired term.
For example, A+2 is a simply relocatable expression.
If there is more than one remaining unpaired relocatable term, or if the remaining term is
preceded by a minus sign, the expression is complexly relocatable. Intentional use of
complexly relocatable symbols is extremely rare. For example, 2-A is a complexly relocatable expression. (Some later examples will show how complex relocatability can happen,
so dont worry if this seems obscure.)
In general, you can determine the relocatability of an expression roughly as follows: first, compute
the value of the expression. Second, add some constant to the initial value of the LC, which will
cause the values of relocatable symbols to change. Third, recompute the value of the expression
using the new values of the symbols. If the new value of the expression is identical to the old
value, the expression is absolute; if the values differ by the amount added to the LC, the
expression is simply relocatable; otherwise it is complexly relocatable.
To summarize the rules for combining terms, let A and R represent respectively an absolute and a
simply relocatable expression. The rules for combining terms are summarized in Table 15.
An expression of this form
A+A, A-A, A*A, A/A

is
absolute

R+A, R-A, A+R

simply relocatable

R+R, A-R

complexly relocatable

R*A, A*R, R/A, A/R, R*R, R/R

forbidden

R-R

absolute or complexly relocatable

Table 15. Expressions with absolute and relocatable terms

R R is absolute only if both expressions have the same relocation attribute. Because this will
almost always be true, we assume (until further notice) that expressions of the form R R are
absolute. Well give a precise definition of the relocation attribute in Chapter X when we discuss
external symbols.
Machine instruction statement operands may never be complexly relocatable.

Exercises
8.3.1.(2) + Suppose R stands for an arbitrary relocatable expression, and A stands for an arbitrary
absolute expression. State which of the following expressions are and are not valid in machine
instruction statement operands.
(1) R+R (2) A+R (3) R+A (4) A+A (5) R-R (6) A-R (7) R-A (8) A-A
(9) R*R (10) A*R (11) R*A (12) A*A (13) R/R (14) A/R (15) R/A (16) A/A
8.3.2.(2) Rule 7 on page 100 states that the Assembler always discards remainders in evaluating
expressions. Does this mean that a program cannot compute a remainder? Explain.

Chapter III: Assembler Language Programs

101

8.3.3.(2) + The last row of Table 15 says that R-R can be complexly relocatable. How can the
difference of two simply relocatable symbols be complexly relocatable?

8.4. Examples
For these examples, we assume that

ABS425 is an absolute symbol of value 425 (or X000001A9 ),


the value of the Location Counter is X00011D46 ,
REL1 is a relocatable symbol of value X00010A20 ,
REL2 is a relocatable symbol of value X00012345 having length attribute 6, and
The Location Counter, REL1, and REL2 have the same relocation attribute.
1. 5*2/4 = 10/4, an absolute expression of value X00000002.
2. 16*16*16*16*16*16 is an absolute expression of value X01000000.
3. 6-ABS425 has value X FFFFFE5D , and is absolute.
4. (REL2-REL1)/(ABS425-B011111) is an absolute expression of value X00000010.
5. REL2+C -+*+L REL2-* is a relocatable expression of value X000123AB .
6. 2*REL2-REL1 is an invalid expression, because a relocatable term (REL2) occurs in a multiply
operation. (If the Assembler was able to evaluate the expression, it would be simply relocatable, and have value X00013C6A .)
7. Even REL1*1 and REL1*0 (as well as REL1/1 and REL1/0) are invalid expressions, even though
their values are perfectly well defined.
8. (1+(1+(1+(1+(1+(1+(1+(1+2)*2)*2)*2)*2)*2)*2)*2)+1 is an absolute expression, and has
value X200.
9. *+6 is a relocatable expression of value X00011D4C .

10. (REL2-*)*L REL2 is an absolute expression of value X000023FA . Note the two distinct uses of
the asterisk!
The example of a machine instruction statement in Figure 30 on page 80 could have been written
LOAD

LR

C 4 5 -(7*X 2 A36 ) + ABS425*B11111-235,18/(Q-Q)+3

though the gain in clarity is not obvious. More reasonable usage is illustrated in the following
statements.
*
R7
R3
LOAD

EXAMPLE 8_4_1
EQU 7
EQU 3
LR
R7,R3

There is a difference between


1. the notational convenience of the symbol R7 defined in the first EQU statement above and
intended to mean general register 7,
2. the definition of an absolute symbol R7 to have the value 7, and
3. the use of the symbol as an operand in the operand field entry of a machine instruction statement where the use of register 7 is intended.
Example 8_4_1 is equivalent to the two below. (The second is considered poor style, for obvious
reasons.)
*
ZORCH
ZILCH
LOAD

EXAMPLE 8_4_2
EQU 3
EQU 7
LR
ZILCH,ZORCH

*
R7
R3
LOAD

EXAMPLE 8_4_3
EQU 3
EQU 7
LR
R3,R7

Expressions can also be used to good advantage in EQU statements. For example, suppose we
need to define a symbol NWords whose value gives the number of words in a table, and we also

102

Assembler Language Programming for IBM z System Servers

Version 1.00

need a symbol NBits whose value is the number of bits in the same table. We could define the
symbols in the following way.
*
NWords
BitsWd
NBits

Example 8_4_4
EQU 75
EQU 32
EQU NWords*BitsWd

EQU with expressions


Table has 75 word entries
Number of bits per word
Number of bits in the table

Exercises
8.4.1.(2) What are the values of the symbols NWords, BitsWd, and NBits in Example 8_4_4
above?
8.4.2.(3) + The following short program segment contains instructions (whose purpose is of no
interest for this exercise) whose operand fields contain various expressions. For each expression,
determine (1) whether the expression is absolute or relocatable, and (2) the value of the
expression. The column headed LOC gives the hexadecimal value of the Location Counter
for each instruction.
LOC
466
46A
46C
470

474

Statement
A
L
BALR
B
ST
C
SLL
USING
R6
EQU
X
DS

4,B+X 1C
R6,0
4,C-A+X-2*(R6/2)
5,2*C - -C A+2
B-2,R6-2
9
F
Define Symbol X

8.4.3.(3) + Assume that the Location Counter, and symbols REL1, REL2, and ABS425 have the
value and relocation attributes defined in the examples on page 102. Determine the value and
relocation attributes of the following expressions.
(1)
(2)
(3)
(4)
(5)
(6)

REL1+C 2 / 2
REL1-REL2+ABS425
C 4 5 -(7*X 2 A36 ) + ABS425*B11111-235
(8/(REL2-REL1)/X107C)+3
ABS425/((REL2-REL1)/X C701+3)
*+ABS425*(*-REL1-4900)

8.4.4.(2) Assuming that the symbols REL1, REL2, and ABS425 have the attributes defined on page
102, determine the validity of each of the following expressions. Explain why you think any
expression is invalid.
(1)
(2)
(3)
(4)
(5)
(6)
(7)
(8)

-2+ABS425
((REL1))*2-2*((REL1))
REL1+C7592*B10110+ABS425
B10221+REL2
ABS425*74239661-2
+X1875
-*+REL2
**1

8.4.5.(3) Assume that the symbols A and B are simply relocatable with the same relocation
attribute, and that they have values X00172B9E and X00173AA6 respectively. Determine the
value and relocation attributes of the following expressions.
(1)
(2)
(3)
(4)
(5)

B-A
A+C .
(A+X00FFF ) -(B-B1101011100001)
(B-A)/10
B+C B / ( B+B101-B)

Chapter III: Assembler Language Programs

103

8.4.6.(3) + The symbols SAM and JOE are simply relocatable with the same relocation attribute,
and have values X00174D0A and X0016FB63 respectively. The symbol BOB is absolute and has
value X000003E8 . First, determine the validity of each of the following expressions. Then
determine the value and relocation of each of the valid expressions.
(1)
(2)
(3)
(4)
(5)
(6)

2*BOB+2*SAM-2*JOE
BOB+(SAM+BOB)-(JOE+BOB)
2*(SAM-JOE)/5
SAM-(B10000*(X0010*(BOB-C H ) ) )
(2*SAM-2*JOE)/5
2*(JOE-SAM)/(SAM-JOE)

8.4.7.(4) Can you think of any reasons why the designers of the Assembler Language did not
allow relocatable terms to appear in multiplications or divisions? Assuming that the final value
of the term must be either relocatable or absolute, what modifications would be needed to
allow such expressions, as in example 6 on page 102?
8.4.8.(1) The symbols A and B are relocatable, and have values X00172B9E and X00173AA6
respectively. Determine the value and relocation of these expressions:
1. B-A
2. A+C .

8.5. Machine Instruction Statement Operand Formats


The operand field entry of a machine instruction statement consists of a sequence of operands
separated by commas, and terminated by a blank not enclosed in apostrophes. For example, the
operand field entry of the LR machine instruction statement in Examples 8_4_1 through 8_4_3
contains two operands, expressions of value 7 and 3 respectively.
An operand of a machine instruction statement has only one of three possible formats:
expr

expr1(expr2)

expr1(expr2,expr3)

where expr is an abbreviation for expression, and the subscripts indicate only that each expr
can be different from the others. To repeat: operands of machine instruction statements have one of
these three formats.
The third operand format has two interesting features. First, the comma between the second and
third expressions does not terminate the operand; it merely separates the expressions within the
parentheses. Second, the first of the expressions within the parentheses, expr2, may sometimes be
omitted, so that
expr1(,expr3)
is a valid form of the third operand format. The Assembler will assume that the omitted
expression is absolute and has value zero. The format expr1(expr2,) is never valid.
Examples of the first expr format are
ABLE

2*(SAM-JOE)/5

X 6D

TWO+2

Examples of the second expr1(expr2) format are


ABLE(4)

X 6D ( POINTER)

P(*-*)

(A-ST)(2+ST)

Multiplication is not implied in the last example!


Finally, examples of the third expr1(expr2,expr3) format are
0(255,12)

8(,3)

X(Y-8,Z/2)

(A-B)(A-B,(A-B))

Again, no multiplication is implied in any example.

104

Assembler Language Programming for IBM z System Servers

Version 1.00

Depending on the machine instruction, one or more operands may be required; for each operand,
one or more of the operand formats may be valid. Also, depending on the type of the instruction,
there may be restrictions on the value and relocation attributes of the expressions in an operand.
One of the most important restrictions is that all operands of a machine instruction statement
must either be absolute or simply relocatable; no complexly relocatable expressions are allowed.
For example, a typical RR-type instruction (as in the examples on page 102) has two operands:
each must be of the form
expr
For such RR-type instructions, the Assembler requires that the expressions must be absolute and
have value between 0 and 15.

Exercises
8.5.1.(2) + For each of the following operands, determine whether it is of the first, second, or
third type. If the operand is invalid, explain why.
(1)
(2)
(3)
(4)
(5)
(6)
(7)
(8)
(9)

A+B(5)
A+(B+(5))
A+C ( ( C ) )
A(C , C )
7+(X BAD / B01101)
(C ( ) ( C ) , , ( C ( , ) ) )
0-0(0,0)
0/0(,0*0)
C ( A) *C A( ( C ) ) -X C *C X) )

8.6. Details of Expression Evaluation (*)


While the rules for writing specific machine instruction statement operands will be covered in the
later sections as new instruction types are introduced, this view of the rules for valid expressions
(stated in the previous section) can be summarized in these diagrams.55
1. An operand can take one of three forms:
operand

expr expr(expr) expr(expr,expr)


2. An expression can take any of these three items involving a factor (this shows how unary
+ and signs are described):
expr

factor factor factorfactor


3. A factor can take any of these three forms (this shows how multiplication and division have
higher priority than addition and subtraction):
factor

primary primary*primary primary/primary


4. A primary is either a term or a parenthesized expression:

55

These five diagrams are pictorial representations of a notation known as BNF, which stands for either Backus
Normal Form (after John Backus, the leader of the team that created the first FORTRAN compiler in 1957), or
Backus-Naur Form (after John Backus and Peter Naur, who worked on defining the ALGOL language in
1958-1960.)
Chapter III: Assembler Language Programs

105

primary

term ( expr )
5. Finally, a term in an expression is one of the following:
term

Symbol Self
Location Literal Symbol
Defining Counter
Attribute
Term
Reference
Reference

L I S
We havent yet described Literals and Symbol Attribute References; they will appear shortly.
The quantities factor and primary do not appear anywhere in the Assembler Language. They
are used here only to help clarify the precedence of multiplication, division, addition, subtraction,
and parentheses.

Terms and Definitions


expression
A combination of terms and operators to be evaluated by the Assembler.
expression evaluation
The procedure used by the Assembler to determine the value of an expression.
operator
One of * (meaning multiplication), / (meaning division), + (meaning addition), or
(meaning subtraction). (The Assembler does not support **, which is sometimes used to
mean exponentiation.)
term
A symbol, self-defining term, Location Counter reference, literal, or symbol attribute reference.
absolute symbol
A symbol whose value behaves in expressions like a self-defining term. Its value does not
change if the assumed origin of the program changes.
Symbol Attribute Reference
A term whose value is that of a symbols attribute. The three most important types of
Symbol Attribute Reference are length, scale, and integer.
Length Attribute Reference
A term whose value is the length attribute of a symbol.
simple relocatability
A property of a symbol or expression whose value changes by the same amount as a change
to the programs assumed origin.
complex relocatability
A property of a symbol or expression whose relocation attribute is neither absolute or simply
relocatable.

Programming Problems
Problem 8.1.(2) Write and execute some test cases with your Assembler to determine whether it
allows you to specify a Length Attribute reference of any term, not just for symbols and
Location Counter References. Are there any cases that dont work? (Some test cases you might
try are L 2 , L ( *-10), L *, L ABS425, L425, L=F 1 , and L L *.)

106

Assembler Language Programming for IBM z System Servers

Version 1.00

Problem 8.2.(2) What is the length attribute of an expression? Suppose A and B are absolute
symbols with value 5 and 3 respectively, and they both have length attribute 1. Determine the
value of each of the following expressions: (1) L A*B, (2) A*L B, (3) L ( A*B). Evaluate them on
your Assembler. This code fragment may help you start:
A
B
C1
C2
C3

Equ
Equ
Equ
Equ
Equ

5
3
L A*B
A*L B
L ( A*B)

Try some similar expressions and see what happens.

Chapter III: Assembler Language Programs

107

9. Instructions, Mnemonics, and Operands

9999999999
999999999999
99
99
99
99
99
99
999999999999
999999999999
99
99
99
99
999999999999
9999999999

We will now see how to write some machine instruction statements, with various instruction
formats and examples of actual code sequences. The instructions in Table 16 and their behavior
will be discussed in detail later, so dont worry now about learning the mnemonics, operation
codes, or descriptions.
Mnemonics are short abbreviations for a word or phrase describing the action of each operation
code. A mnemonic may be as simple as A meaning Add, or BXLE, meaning Branch on
Index Low or Equal. We will look at several classes of instructions, showing how their operands
are written. Abbreviations and notations used to describe operands such as R1, S2, I 2, etc.,
will be explained as we go along.

9.1. Basic RR-Type Instructions


Table 16 illustrates some common RR-type instructions, where Op and Mnem are abbreviations for Operation Code or Opcode, and Mnemonic.
Op
04
06
0D
0F
11
13
15
17
19
1B
1D
1F

Mnem
SPM
BCTR
BASR
CLCL
LNR
LCR
CLR
XR
CR
SR
DR
SLR

Instruction
Set Program Mask
Branch On Count
Branch And Save
Compare Logical Long
Load Negative
Load Complement
Compare Logical
Exclusive O R
Compare
Subtract
Divide
Subtract Logical

Op
05
07
0E
10
12
14
16
18
1A
1C
1E

Mnem
BALR
BCR
MVCL
LPR
LTR
NR
OR
LR
AR
MR
ALR

Table 16. Typical RR-type instructions

108

Assembler Language Programming for IBM z System Servers

Version 1.00

Instruction
Branch And Link
Branch On Condition
Move Long
Load Positive
Load And Test
AND
OR
Load
Add
Multiply
Add Logical

1. Not all of the 64 available bit combinations between X 0 0 and X 3F are used as actual operation codes. For example, IBM has promised not to use X 0 0 as an operation code. 56
2. There are many other RR-type instructions, and several other RR-type instruction formats.
The examples that follow generally apply to all such instructions.

9.2. Writing RR-Type Instructions


For most RR instructions, the operand field entry in a machine instruction statement is written
R1,R2
where the operands R 1 and R 2 designate registers.57 (Some instructions require one or both of
the operands to be even numbers, designating even-numbered registers.)
The numeric subscripts 1 and 2 in the quantities R1 and R 2 distinguish the operand
being referenced. Using the terms first operand, second operand, etc. consistently will help
you remember what actions are being performed by each instruction.
To explain the notation R 1,R 2, refer to the example of a machine instruction statement in
Figure 30 on page 80, where the operation and operand field entries were LR and 7,3,
respectively. In this case, the R1 operand is 7 and the R 2 operand is 3. The quantities
R 1 and R 2 must be absolute expressions between 0 and 15. Thus, we could just as well have
written
LOAD

LR

X 7 , B 1 1

For these basic RR-type instructions, the values of the operand field expressions are placed by the
Assembler into two adjacent hexadecimal digits, called the operand register specification digits
in the second byte of the instruction. This second byte was denoted register specification in
Table 6 on page 54. Table 17 shows the positions of the register specification digits.
opcode

R1

R2

Table 17. RR-type instruction

For most RR instructions the R 1 operand specifies the register that at execution time contains the
first operand. Our notation R 1 means a number specifying the R1 digit of an instruction; no
reference to general register register 1 (possibly denoted by GR1) is implied. You can of course
specify 1 as the value of the R1 operand!
We can now see the difference between (1) the operands of an instruction statement at
assembly time, and (2) the operands of a machine instruction at execution time. The operands
(first meaning) in the operand field entry of the instruction LR 7,3 are the single characters 7
and 3, whereas at execution time the operands (second meaning) of the LR instruction will be the
data found in general registers 7 and 3. Table 16 shows that the operation code corresponding to
the mnemonic LR is X 1 8 , so the two-byte instruction generated by the Assembler would be
X1873.
Programming with RR instructions is easy. Suppose we wish to compute the sum of the contents
of general registers 2 and 14, subtract the contents of GR9 from the sum, and leave the result in
GR0. These statements will do the job.

56

57

X 0 0 has not been assigned as a valid opcode for two reasons. First, unused areas of memory are often set to zero
when programs are initialized; programs that try to execute instructions from those areas will stop immediately
with a program interruption for an invalid instruction. (Sometimes, a programmer will purposely insert a X0000
halfword in a program to force it to stop at an exact position so the contents of registers and memory can be verified.) Also, programs like debuggers sometimes use X 0 0 as breakpoints to halt instruction tracing at a specified
place.
Some instructions have only one or even no explicit operands!
Chapter III: Assembler Language Programs

109

LR
AR
SR

0,2
0,14
0,9

Copy contents of GR2 to GR0


Add contents of GR14 to GR0
Subtract contents of GR9 from GR0

The instructions, their actions, and other properties will be described in subsequent sections.

Exercises
9.2.1.(2) + Which of the following are valid register operands for an RR-type instruction?
(a) 0, (b) B1101, (c) X 1 1 , (d) 4*(X F2 C0)/5+X E , (e) 4*(X F2 C0)/3+X E .
9.2.2.(2) Which of the values in Exercise 9.2.1 are valid operands if the instruction operand
requires an even-numbered register?

9.3. Basic RX-Type Instructions


Table 18 shows examples of some frequently-used RX-type instructions. As in Table 16, not all
of the 64 available digit combinations between X 4 0 and X 7F are used as actual operation
codes. Again, you neednt try to remember them here.
Op
40
42
44
46
48
4A
4C
4E
50
55
57
59
5B
5D
5F

Mnem
STH
STC
EX
BCT
LH
AH
MH
CVD
ST
CL
X
C
S
D
SL

Instruction
Store Halfword
Store Character
Execute
Branch On Count
Load Halfword
Add Halfword
Multiply Halfword
Convert To Decimal
Store
Compare Logical
Exclusive O R
Compare
Subtract
Divide
Subtract Logical

Op
41
43
45
47
49
4B
4D
4F
54
56
58
5A
5C
5E

Mnem
LA
IC
BAL
BC
CH
SH
BAS
CVB
N
O
L
A
M
AL

Instruction
Load Address
Insert Character
Branch And Link
Branch On Condition
Compare Halfword
Subtract Halfword
Branch And Save
Convert To Binary
AND
OR
Load
Add
Multiply
Add Logical

Table 18. Typical RX-type instructions

9.4. Writing RX-Type Instructions


In this and the following section we will introduce some basic concepts, using RX-type
instructions as examples.
The format of an RX-type instruction was shown in Table 7 on page 54. We now look at the
parts of the instruction in Table 19 and describe Assembler Language techniques for specifying
them.
opcode

R1

X2

B2

D2

Table 19. RX-type instruction

110

Assembler Language Programming for IBM z System Servers

Version 1.00

As noted when we reviewed addressing in Section 5.3 on page 65, three components of an RX
instruction are used in computing an Effective Address: the index register specification digit X2,
the base register specification digit B2, and the displacement D2. The operand field entries may be
written in several ways, but they must yield values for the four needed quantities: R 1, X 2, B2, and
D 2. Usually, values for all of these items need not be explicitly given; the Assembler can make
assumptions about what to provide in cases where values are not explicitly given. When the
Assembler provides values for something, we say that the values were specified by default or
specified implicitly.
The operand field entry of RX-type instructions has the general form
R1,address-specification
where address-specification will be described next. The operand register specification digit R1 is
formed according to the same rules given above for the R1 and R 2 digits for RR instructions, and
must be an absolute expression with value between 0 and 15.

9.5. Explicit and Implied Addresses


For an explicit address, you supply the base and displacement; for an implied address, the Assembler determines the base and displacement. (Section 10 will show you how its done.)
Explicit and Implied Addresses
Explicit: you specify the base and displacement.
Implied: the Assembler calculates the base and displacement for you.
How this is done is explained in Section 10.
Suppose we wish to specify explicitly the values assigned to X2, B2, and D 2: we write the second
operand (the address-specification) as
D2(X2,B2)
which is the third of the possible operand formats described in Section 8.5 on page 104. The
instructions in examples 4, 5, and 6 of Section 5.4 on page 67 could be written as shown in Figure
34, where the assembled form is on the left, and the Assembler Language machine instruction
statement is in the center; the displacements have the same value in each instruction.
430A7468
43007468
43070468

IC
IC
IC

0,1128(10,7)
0,1128(0,7)
0,1128(7,0)

D2=1128, X2=10, B2=7


D2=1128, X2=0, B2=7
D2=1128, X2=7, B2=0

Figure 34. RX Instruction with explicit operands

Compare the machine language form of these three instructions to the fields in Table 19.
The four possible forms of the second operand of an RX instruction are shown below, where we
use S2 to mean an implied address (which need not necessarily refer to a symbol, as well see!).
Explicit Address

Implied Address

Not Indexed

D 2(,B2)

S2

Indexed

D 2(X 2,B2)

S2(X 2)

Table 20. Operands of RX-type instructions

In the two cases where an explicit address is written, each of the quantities D2, X 2, and B2 must
be an absolute expression; X2 and B2 must have value less than 16, and D2 must have value less

Chapter III: Assembler Language Programs

111

than or equal to 4095=X FFF .58 The not-indexed form of explicit address implies X2=0, as we
saw earlier; both indexed addresses specify an index digit.
In the two cases where an implied address is written, the quantity S2 may be either an absolute or
a relocatable expression. This means that we can write instructions such as
L
L
LA

0,ANSWER
0,16
2,25*40

Operand forms are R1,S2


Operand forms are R1,S2
Operand forms are R1,S2

and let the Assembler assign the proper base and displacement; this is the subject of Section 10.
Note that the second operand of the first statement is a symbol (that we assume is relocatable),
while the second operand of the other two statements is an absolute expression.
For the moment, suppose the Assembler has sufficient information so that the instruction
IC

0,BYTE

Operand forms are R1,S2

is translated into the hexadecimal digits 43007468, as in Figure 34. Then if the index register is
GR10, the instruction
IC

0,BYTE(10)

Operand forms are R1,S2(X2)

is translated into the hexadecimal digits 430A7468. In the last example in Figure 34 we could
have written the second operand with an indexed implied address of the form S2(X 2), as 1128(7),
where the S2 expression is absolute!
For example, it is common practice to load a small constant into a register using the LA (Load
Address) instruction:
LA

2,10

Put 10 in R2

and the operand 10 is an absolute implied address. This will almost never lead to difficulties; but
to be absolutely safe, you could write instead
LA

2,10(0,0)

Put 10 in R2

and the operand now specifies an explicit address.


The only way the Assembler can decide among the four forms of address specification in Table 20
is (1) by noting whether a left parenthesis follows the first expression (if not, the address is
implied), and (2) if there is a left parenthesis, by noting whether a comma appears before the
matching right parenthesis (if so, the address is explicit). There is of course no effect of commas
and parentheses in character self-defining terms.
It helps to remember that implied addresses almost always involve relocatable expressions, and
explicit addresses always involve absolute expressions. Sometimes we accidentally use a relocatable
expression where it should have been absolute, or an absolute expression where it should have
been relocatable. The Assembler usually (but not always) diagnoses such errors.
The most common form of address specification is an implied address, where the Assembler computes the proper displacement for us. While we have now seen implied addresses in the context of
RX-type instructions, they are used in many other instruction types.

Exercises
9.5.1.(2) In Table 20, use the rules of Section 8.5 to identify the format of each of the four
operands.
9.5.2.(2) + The following are examples of the second operand of an RX-type instruction (the
address-specification). For each operand, determine (1) whether the address is implied or

58

112

In Section 20 we will introduce instructions with signed 20-bit displacements.


Assembler Language Programming for IBM z System Servers

Version 1.00

explicit, and (2) whether indexing is specified. Assume that the symbols A, B, C are relocatable
with the same relocation attribute, and that the symbol N is absolute.
1.
2.
3.
4.
5.
6.

B+X 1C
C-A+B-2(N/2)
2*C - -C A+2(N+N)
B-A((B-A)/2,((B-A)*2))
C A+A(C , -99)
N+N(,N)

9.5.3.(2) Assume that each of the operands in Exercise 8.5.1 on page 105 is used in an RX-type
instruction. Using the rules in Section 9.5, determine whether the addresses are explicit or
implied.

9.6. Typical RS- and SI-Type Instructions


The examples of basic RS-type and SI-type instructions in Table 21 are quite varied in the way
you specify their operand fields.
Op
90
92
86

Mnem Type
STM
RS
MVI
SI
BXH
RS

Instruction
Store Multiple
Move Immediate
Branch On Index High

Op
91
94
95

Mnem Type
TM
SI
NI
SI
CLI
SI

87
97
98
8A
8C
8E
BD

BXLE
XI
LM
SRA
SRDL
SRDA
CLM

RS
SI
RS
RS
RS
RS
RS

96
88
89
8B
8D
8F
BE

OI
SRL
SLL
SLA
SLDL
SLDA
STCM

BF

ICM

RS

Branch On Index Low or Equal


Exclusive OR Immediate
Load Multiple
Shift Right Single
Shift Right Double Logical
Shift Right Double
Compare Logical Characters
Under Mask
Insert Characters Under Mask

SI
RS
RS
RS
RS
RS
RS

Instruction
Test Under Mask
AND Immediate
Compare Logical Immediate
O R Immediate
Shift Right Single Logical
Shift Left Single Logical
Shift Left Single
Shift Left Double Logical
Shift Left Double
Store Characters Under
Mask

Table 21. Typical RS- and SI-type instructions

Some instructions (like Shift Double) require a register operand to be an even number.

9.7. Writing RS- and SI-Type Instructions


We will show the operand field formats for RS-type and SI-type instructions separately, as they
are quite different.
The RS-type instruction format is similar to RX-type format, except that the X2 field is replaced
by an R 3 field, so no indexing is performed when Effective Addresses are formed.
opcode

R1

R3

B2

D2

Table 22. Typical RS-type instruction

Chapter III: Assembler Language Programs

113

The operand fields of Assembler Language instructions specifying RS-type instructions are shown
in Table 23. There are two forms, one with a single Rn operand and the other with two, indicated by RS-1 and RS-2 meaning one or two register operands respectively.
Explicit Address

Implied Address

RS-1

R 1,D 2(B2)

R 1,S2

RS-2

R 1,R 3,D 2(B2)

R 1,R 3,S2

Table 23. Operands of RS-type instructions

Examples of RS-type instructions with explicit and implied addresses are:


SRA
SLDL
LM
STM
BXLE

11,2
6,N
14,12,12(13)
14,12,SaveArea+12
4,1,Loop_3

Explicit
Implied
Explicit
Implied
Implied

address
address
address
address
address

(RS-1
(RS-1
(RS-2
(RS-2
(RS-2

form)
form)
form)
form)
form)

SI-type instructions are different. The I2 operand is contained in the second byte of the instruction, as in this figure:
opcode

I2

B1

D1

Table 24. Typical SI-type instruction

Table 25 gives the operand fields of Assembler Language statements involving SI-type
instructions:
Explicit Address

Implied Address

D 1(B1),I2

S1,I 2

SI

Table 25. Operands of SI-type instructions

Examples of SI-type instructions with explicit and implied addresses are:


MVI
CLI

0(6),C *
Buffer,C 0

Explicit S1 address
Implied S1 address

Exercises
9.7.1.(2) The following are operand fields could be used in RS- and SI-type instructions. Identify the type of instruction (RS-1, RS-2, or SI) for which they are valid, and the components of
the instruction to which each expression applies. State which expressions specify explicit
addresses and which specify implied addresses.
(a)
(b)
(c)
(d)
(e)
(f)

114

1(2),3
4,5(6)
7,8,9
10,11
14,15(16)
100,101

Assembler Language Programming for IBM z System Servers

Version 1.00

9.8. Typical SS-Type Instructions


Table 26 shows some examples of popular SS-type instructions. The column headed Len
shows the number of length fields in the instruction.
Op
D1
D2
D3
D4
D5
D6
D7
DC
DD
DE
DF

Mnem
MVN
MVC
MVZ
NC
CLC
OC
XC
TR
TRT
ED
EDMK

Len
1
1
1
1
1
1
1
1
1
1
1

Instruction
Move Numeric
Move
Move Zone
AND
Compare Logical
OR
Exclusive O R
Translate
Translate And Test
Edit
Edit And Mark

Op
F0
F1
F2
F3

Mnem
SRP
MVO
PACK
UNPK

F8
F9
FA
FB
FC
FD

ZAP
CP
AP
SP
MP
DP

Len
2
2
2
2
2
2
2
2
2
2

Instruction
Shift And Round
Move With Offset
Pack
Unpack
Zero And Add
Compare
Add
Subtract
Multiply
Divide

Table 26. Typical SS-type instructions

ED, EDMK, SRP, and the last six instructions in the right-hand column operate on data stored
in packed decimal format, which is different from the data formats used for the general register
and floating-point instructions. Well learn about them in Chapter VIII.

9.9. Writing SS-Type Instructions


Most SS-type instructions specify two addresses, and may have one or two length fields depending
on whether you must specify the length of only one operand (type SS-1) or of both operands
(type SS-2). Their formats are shown in Tables 27 and 29.
As with explicit and implied addresses, you can also specify explicit and implied lengths in SS-type
instructions. When we use implied lengths the Assembler determines the values put into the
length fields of the instruction, often by using the length attribute of a symbol. Implied lengths
are very useful, and well see many examples.
This is the format of instructions with a single length field.
opcode

L1

B1

D1

B2

D2

Table 27. Typical type SS-1 instruction with one length field

Addresses and lengths may be specified explicitly or implicitly, as summarized in the following
tables. First, we examine the single-length instructions.
SS-1

Explicit Addresses

Implied Addresses

Explicit Length

D 1(N 1,B1),D 2(B2)

S1(N 1),S2

Implied Length

D 1(,B1),D 2(B2)

S1,S2

Table 28. Operands of type SS-1 single-length instructions

Chapter III: Assembler Language Programs

115

When you write an instruction with an explicit length, you provide a Length Expression or
program length, denoted N 1. The Assembler generates object code with an Encoded
Length or machine length denoted by L 1. This seems strange: why are they different?
The Assembler generates the value of L1 by subtracting 1 from the value of N1 (unless N1 is
zero). Well see why this is done when we discuss SS-type instructions starting in Section 24.
Some examples of SS-type instructions with a single length field are:
MVC
CLC
TR
XC

0(80,4),40(9)
Name(24),RecName
OutCh(,15),0(12)
Count,Count

Explicit length and addresses


Explicit length, implied addresses
Implied length, explicit addresses
Implied length and addresses

where the symbol OutCh must be absolute. (This form is rarely used.)
SS-type instructions with two length fields have the format shown in Table 29.
opcode

L1

L2

B1

D1

B2

D2

Table 29. Typical type SS-2 instruction with two length fields

Many more combinations of explicit and implied lengths and addresses are available when you
use SS-type instructions with two length fields. Some of the Assembler Language operand field
combinations are shown below.
SS-2

Explicit Addresses

Implied Addresses

Explicit Lengths

D 1(N 1,B1),D 2(N 2,B2)

S1(N 1),S2(N 2)

Implied Lengths

D 1(,B1),D 2(,B2)

S1,S2

Table 30. Operands of type SS-2 two-length instructions

You can specify explicit lengths and addresses for either of the two operands; see Exercise 9.9.2.
As noted for SS-1 type instructions, the Encoded or machine lengths L1 and L 2 are one less than
the Length Expressions or program lengths N1 and N 2. Well see these again in Chapter VIII.
Some examples of SS-type instructions with two length fields are:
PACK
ZAP
AP
UNPK

0(8,4),40(5,9)
Sum(14),OldSum(4)
Total(,15),Num(,12)
String,Data

Explicit lengths and addresses


Explicit lengths, implied addresses
Implied lengths, explicit addresses
Implied lengths and addresses

The symbols Total and Num must be absolute for the third statement to be valid.
This SS-type instruction copies five bytes from a memory area named AREA to an area of memory
named FIELD:
MVC

FIELD(5),AREA

Exercises
9.9.1.(2) + The following operands could be used in SS-type instructions. State the operand for
which they may be valid, for both SS-1-type and SS-2-type instructions, and whether a length is
explicit or implied. (Validity and form may depend in the relocation attribute of the symbols.)
(a)
(b)
(c)

116

1(2)
4(5,6)
A(L B)

Assembler Language Programming for IBM z System Servers

Version 1.00

(d)
(e)
(f)

Line
Line(80)
XX(,5)

9.9.2.(2) + Make a table to show all possible combinations of explicit and implied addresses,
and implicit and implied lengths, for SS-2 type instructions.

9.10. Summary
When describing the fields of both machine instructions and assembler instruction statements, we
use notations like S2, B1, N, L 2, etc.
Fields denoted S can be absolute or relocatable expressions, and are most often relocatable.
Fields denoted B, D, I, L, N, and X must always be absolute expressions.

Terms and Definitions


explicit address
An address in which you specify the base register specification digit and the displacement as
absolute expressions.
implied address
An address where you expect the Assembler to assign a base register specification digit and a
displacement to an addressing halfword.
explicit length
A length field that you specify explicitly.
implied length
A length field completed by the Assembler based on its analysis of the operand.
mnemonic
A character string representing an instruction, intended to be easier to remember than the
operation code of the instruction.
operation code
The z/Architecture definition of an instructions bit pattern to be decoded by the CPU to
determine what actions it should take.
opcode
An abbreviation for operation code. Occasionally used when the term mnemonic is actually
meant.
Length Expression
A value you write in an SS-type instruction specifying the length of the operand(s).
program length
A Length Expression.
Encoded Length
The contents of a Length Specification Byte; one less than the value of the Length
Expression (unless the Length Expression is zero, in which case the Encoded Length is also
zero).
machine length
An Encoded Length.

Chapter III: Assembler Language Programs

117

10. Establishing and Maintaining Addressability

11
111
1111
11
11
11
11
11
11
11
1111111111
1111111111

00000000
0000000000
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
0000000000
00000000

In Section 5 we saw how the CPU at execution time converts addressing halfwords into Effective
Addresses. Now we will see how the Assembler derives addressing halfwords from the values of
symbolic expressions at assembly time, and answer the question How do we help the Assembler
create addressing halfwords?
This important information is provided in the USING assembler instruction statement.

10.1. The BASR Instruction


The RR-type Branch and Save (Register) instruction with mnemonic BASR is frequently used to
generate a base address that provides addressability.59 For now, we consider what happens when
we write
BASR

R1,0

where the second operand register specification digit R2 is zero. This instruction when executed
replaces the contents of the general register specified by R1 by the Instruction Address (IA)
portion of the PSW. This address will necessarily be the address of the instruction following the
BASR, because the IA was incremented by the BASR instructions length (2 bytes) during the
fetch portion of the instruction cycle.
In this RR-type instruction (unlike many other RR-type instructions), the zero second operand
does not refer to general register zero! Instead, it means that only the described actions will occur
without any branch, as the Branch and Save name implies. (Well see in Chapter X that
BASR is often used for branching, usually in subroutine linkages.)
Suppose the following short sequence of statements is part of a program that has been assembled
and placed in memory to be executed. While we are giving the Assembler Language statements in
Figure 35, the assembled contents of memory will be hexadecimal machine language data, as
shown in Figure 36 on page 120. Suppose the Program Loader has relocated the program so
that the first instruction (the BASR) was placed at memory address X5000.

59

118

The BASR instruction should be used in place of BALR in most situations; the main difference is that BALR inserts
the ILC, CC, and Program Mask in the high-order 8 bits of the first operand register when executing in 24-bit
addressing mode. BALR and BASR work the same way in 31-bit addressing mode.
Assembler Language Programming for IBM z System Servers

Version 1.00

Address

Name

Operation Operand

Remarks

5000
5002
5006
500A
5024
5028

Fragment of a simple program


BASR
6,0
Establish base address
BEGIN L
2,N
Load contents of N into GR2
A
2,ONE
Add contents of ONE
ST
2,N
Store contents of GR2 into N
--twenty-two (X16) additional bytes of instructions, data, etc.-N
DC
F 8
Word integer 8
ONE
DC
F 1
Word integer 1

Figure 35. A simple program segment

For this and the following examples, the instructions following the BASR are intended just to
show how the Assembler creates addressing halfwords. Briefly, their actions are:
L is the mnemonic for the RX-type (4-byte) machine instruction Load. It copies the contents
of a 4-byte (word) area of memory and puts it into a general register.
A is the mnemonic for the RX-type (4-byte) machine instruction Add. It adds a copy of the
contents of a 4-byte (word) area of memory to the contents of a general register.
ST is the mnemonic for the RX-type (4-byte) machine instruction STore. It replaces the contents of a 4-byte (word) area in memory with a copy of the contents of a general register.
DC ( Define Constant) is an Assembler instruction used to create constants. The two DC
statements create word binary integers in memory.
The leftmost column in Figure 35 shows the memory address of each instruction and data item.
For now, well ignore what the instructions actually do, and focus on how they are assembled.

Exercises
10.1.1.(2) Use the lengths of the instructions and constants in Figure 35 to calculate their
addresses in memory, and determine if the values in the figure are correct.

10.2. Computing Displacements


Now, suppose the program has begun execution. After the BASR has been executed, register 6
will contain X00005002. (Remember: BASR places the address of the next instruction into the
register designated by the R1 operand.) We can now use the address in register 6 as a base
address for the instructions following the BASR, so the base register specification digit in subsequent addressing halfwords should be 6.
We can determine the proper displacement in the L instruction at X5002 by using two important
values: the known contents of register 6 (X00005002) and the address of the word area named N.
Using these values, we can now compute a displacement:
X00005024 X00005002 = X022
Then, the assembled machine language instruction (using opcode X 5 8 for the mnemonic L) will
be X58206022. When this instruction is executed, its Effective Address is
X022 + X00005002 = X00005024,
the address of the word named N that we want!
If we continue this way for the rest of the statements, the assembled machine language
instructions and data will give the desired results at execution time. That is, after program loading

Chapter III: Assembler Language Programs

119

is complete, we want the memory areas starting at address X5000 to contain the (hexadecimal)
machine language data shown under Assembled Contents in Figure 36.
Address

Assembled Contents

Original Statement

5000
5002
5006
500A

0D60
58206022
5A206026
50206022

5024
5028

00000008
00000001

BASR
6,0
L
2,N
A
2,ONE
ST
2,N
---------------------------------N
DC
F 8
ONE
DC
F 1
BEGIN

Figure 36. Simple program segment with assembled contents

Remember that when the Assembler processes the BASR statement and produces two bytes of
machine language code containing X 0 D60 , nothing is yet in register 6. It is only when this
machine language instruction is finally executed by the processor that the desired base address will
be placed in register 6.
So far, so good: we have constructed a sequence of instructions that will give a desired result if it
is placed in memory at exactly the right place. You might ask What would happen if the
program is put elsewhere by the Program Loader? So, lets suppose the same program segment
begins at memory address X84E8 , as in Figure 37.
Address
84E8
84EA
84EE
84F2
850C
8510

Statement
BASR
6,0
BEGIN L
2,N
A
2,ONE
ST
2,N
--- the same 22 bytes of odds and ends --N
DC
F 8
ONE
DC
F 1

Figure 37. Same program segment, at different memory addresses

After executing the BASR, register 6 contains X000084EA . To address the contents of the word
named N using register 6 as a base register, the necessary displacement is
X0000850C X000084EA = X022
Similarly, the displacement necessary in the A instruction is
X00008510 X000084EA = X026
After completing the three addressing halfwords, the assembled machine language program would
appear in memory as shown in Figure 38.
Address
84E8
84EA
84EE
84F2
850C
8510

Assembled Contents
0D60
58206022
5A206026
50206022
----------------00000008
00000001

Figure 38. Same program segment, with assembled contents

The identical machine language program is generated in both Figures 36 and 38. We see that so
long as the same fixed relationship is maintained among the various parts of the program segment
(there are 22 bytes between the ST instruction and the word named N), the program segment

120

Assembler Language Programming for IBM z System Servers

Version 1.00

could be placed anywhere in memory and still execute correctly. That is, the program is relocatable.
Indeed, we could have assumed that the program began at memory address zero (even though an
actual program would not be placed there) because the contents of register 6 after the BASR is
executed would be X00000002, and the displacements would be calculated exactly as before.

10.3. Explicit Base and Displacement


Knowing what we need for the assembled program (the machine language instructions shown in
Figures 36 and 38), we now write the instruction statements with explicit addresses in their second
operands. Register 6 is the base register, and the displacements are those we just calculated. Then
we can write the program as in Figure 39, using an assumed origin of zero for the LC.
(Remember: were describing locations at assembly time, not the execution time addresses we saw
in the previous examples.)
Location
0000
0002
0006
000A
0024
0028

Name

Operation Operand

BASR
L
A
ST
--------- 22 bytes
N
DC
ONE
DC
BEGIN

6,0
2,X022(0,6)
2,X026(0,6)
2,X022(0,6)
---------F 8
F 1

Figure 39. Program segment with pre-calculated explicit base and displacements

This example has two shortcomings. First, calculating displacements in advance is tedious (especially in large programs), and certainly error-prone. Second, if the relative positions of the parts
of the program change in any way, we will be forced to recalculate some or all of the displacements.
Thus, our first simplification is to find a way to let the Assembler compute the displacements just
as we did. Now, however, we can make good use of the values assigned by the Assembler to the
symbols BEGIN, N, and ONE. (As noted in Section 7.6 on page 95, the values of the symbols are
the values of the LC when the statement is processed.) Referring to Figure 39, the values
assigned to the three symbols will be the value of the assumed origin plus X0002, X0024, and
X0028, respectively.
The key to this example is that when the program is executing, the base register (register 6) contains the address of the instruction named BEGIN. We use this observation to rewrite the program
segment, as shown in Figure 40.
Location
0000
0002
0006
000A
0024
0028

Name

Operation Operand

BASR
6,0
L
2,N-BEGIN(0,6)
(N-BEGIN = X022)
A
2,ONE-BEGIN(0,6) (ONE-BEGIN = X026)
ST
2,N-BEGIN(0,6)
(N-BEGIN = X022)
------- the usual 22 bytes ------N
DC
F 8
ONE
DC
F 1
BEGIN

Figure 40. Program segment with explicit base and Assembler-calculated displacements

We have eliminated both of the shortcomings of the program segment in Figure 39: the displacements were not calculated in advance, and adding (say) four more bytes of instructions or data
preceding the DC statements would not require the rest of the program to be rewritten. However,
we have created another nuisance, since every instruction containing a reference to a symbol must
now specify two extra items: the symbol BEGIN and the base register (6).
Chapter III: Assembler Language Programs

121

So, we need a way to make the Assembler do the rest of the work for us, after we have told it (1)
which base register to use, and (2) the value that will be in it when the program is executed.

10.4. The USING Assembler Instruction and Implied Addresses


The USING assembler instruction provides exactly the information we need. It is written
USING

base_location,base_register

where base_location is almost always a relocatable expression. (The base_location is sometimes


called the base, but it easy to mistake this for the base_register.) The base_register operand
is an absolute expression between 0 and 15, specifying the register to be used as a base register.
(Zero is very rarely used.)
Thus, the statement
USING BEGIN,6
tells the Assembler to assume that register 6 may be used as a base register that at execution time
will contain the relocated address of the instruction named by the symbol BEGIN. The Assembler
can then calculate displacements relative to the location of BEGIN, and then use this assumption to
create addressing halfwords with base register specification digit 6 and the calculated displacements.
We now rewrite the sample program segment of Figure 40 to include the USING statement in
Figure 41.
BASR
6,0
USING
BEGIN,6
BEGIN L
2,N
A
2,ONE
ST
2,N
----------------------N
DC
F 8
ONE
DC
F 1
Figure 41. Program Segment with USING Instruction

If the initial LC value is zero, the value of the symbol BEGIN will be X0002, and the values of the
symbols N and ONE will be X0024 and X0028 respectively. To complete its derivation of the
addressing halfword of the ST instruction, the Assembler needs only to calculate the difference
between the location of the symbol N and the base_location of BEGIN specified in the USING
instruction:
X0024 X0002 = X022
and this is the required displacement.
Similarly, the implied address of the operand ONE of the A instruction has value X0028; when
the base_location value is subtracted, we find the displacement is X026, as before. We say that
the Assembler has resolved the implied addresses of the L, A, and ST instructions into basedisplacement form. Thus, the machine language generated from this set of statements would
appear exactly as in Figures 36 and 38. (Details about how the Assembler computes displacements and assigns base registers is described starting in Section 10.8.)
If the attempted calculation
displacement = (operand value) (base_location value)
yields a negative result or a value greater than 4095, the location referred to by the symbol is still
not addressable with this base register, and some other solution is needed.60

60

122

Section 20 describes long-displacement and relative-immediate instructions with a larger range of displacement values.
Assembler Language Programming for IBM z System Servers

Version 1.00

It is clear that the Assembler can make use of the information supplied by the USING statement
only for implied addresses. If you provide an explicit base and displacement, the Assembler
simply converts them to their proper binary form.
Two important features of the program segment in Figure 41 on page 122 should be noted.
1. The USING instruction does absolutely nothing about actually placing an address into a register; it merely tells the Assembler what to assume will be there when the program is executed.
That is, your USING statement is a promise to the Assembler that if it computes displacements for you, everything will work properly when the program is executed. (It is very easy
to mislead the Assembler, as well see in Section 10.11 on page 131.)
2. If the BASR instruction had been omitted, the contents of register 6 at execution time is
probably unknown. There is no guarantee that correct Effective Addresses will be computed
when the program is executed.
Remember!
A USING statement is your assembly-time promise to the Assembler
that your program will obey that promise at execution time.

10.5. Location Counter Reference


The Assembler provides a convenient way to refer to the current value of the Location Counter,
the Location Counter Reference. The term * in an expression has the current value of the LC,
and is always relocatable.
We can rewrite the first two statements of our sample program as
BASR 6,0
USING *,6
with the same results as before. Remember that after the BASR instruction is assembled, the LC
will have a value corresponding to the location of the next byte to be assembled. Because BASR
will (at execution time) place the address of the following instruction into register 6, we can use a
Location Counter Reference to specify the base_location, and not have to use a symbol (such as
the symbol BEGIN in Figure 41). to name the instruction following the BASR instruction.
A common technique for specifying base registers in a program is to choose a base register, write
the statements
BASR reg,0
USING *,reg
at the beginning of the program, and then carefully avoid modifying that register. For simple programs, specifying and using base registers is very easy.
Its important to remember that while the value of * changes as your program is assembled, the
value used in the first operand of the USING statement does not: it has the value of the LC at
the time the USING is processed by the Assembler.

Exercises
10.5.1.(2) + A careless programmer inverted the order of his BASR and USING statements as
follows:
USING *,12
BASR 12,0
Why is this wrong? What would you expect to happen?

Chapter III: Assembler Language Programs

123

10.6. Destroying Base Registers


Suppose an error was made in writing the statement with the L instruction, such that it became
BEGIN

6,N

Load contents of N into GR2

The comment in the remarks field is correct; the instruction is wrong, because the first operand
was incorrectly written as 6 instead of 2.
The assembled program would then appear as in Figure 42.
Location

Assembled Contents

Statement

0000

0D60

0002
0006
000A

58606022
5A206026
50206022

0024
0028

00000008
00000001

BASR 6,0
USING BEGIN,6
BEGIN L
6,N
Wrong register!
A
2,ONE
ST
2,N
--------------------------N
DC
F 8
ONE
DC
F 1

Figure 42. Sample program segment with erroneous statement

This program would assemble correctly, since all quantities are properly specified. However, at
execution time, things go wrong quickly.
Suppose again that the program is placed in memory by the Program Loader starting at address
X5000, so that when the L instruction is executed, register 6 contains X00005002. Now, the L
instruction copies a word from memory at the address given by the second operand into the register specified by the first operand. However, the first operand in this case specifies register 6,
instead of register 2 as intended. When the Effective Address of the operand named N is calculated
during instruction decoding, register 6 contains the correct base address; but when the execution of
the L instruction is complete, register register 6 will contain X00000008 and not X00005002,
because the number at N was placed in register 6.
Now the fun begins. When the next instruction (A) is executed, the Effective Address calculated is
X026 + X00000008 = X0000002E
and not X00005028, where the intended operand is found. In this case the Effective Address is
not anywhere within the program, but is somewhere among the predefined fixed fields at the low
end of memory; strange numbers will be added to register 2s initial (and unknown) contents.
Finally, the ST instruction will attempt to store a word at X0000002A , which should cause a
storage protection exception. At this point, the program would stop.
This does not mean that if we accidentally destroy the contents of a base register, the CPU will be
able to detect the error. (See Exercise 10.6.1.) It is partly a matter of chance how much damage
such a program error can cause when the program is executed; indeed, when the CPU finally (if
ever) detects an error, all evidence pointing to the offending instruction may have been lost,
making error tracing difficult. (Register 6 may have been changed several times!) You must be
very careful to guarantee the integrity of the contents of base registers.
Remember also that the Assembler makes no checks for instructions that might alter the contents
of registers designated as base registers in USING statements.

Exercises
10.6.1.(3) + In the erroneous program in Figure 42, consider the possibility that the word at N
contained the decimal integer 20450. If the program began in memory at address X5000, what
would be in that area of memory after the ST instruction is executed?

124

Assembler Language Programming for IBM z System Servers

Version 1.00

10.7. Calculating Displacements: the Assembly Process, Pass One


Now, well examine more closely how the Assembler computes bases and displacements.
You can visualize assembly as making two passes over the program: that is, the Assembler
reads the program twice. On the first pass, the Symbol Table is built; on the second pass, data
in the Symbol Table is used to help generate the desired instructions and data.
First, you will remember that values are assigned to symbols by the Assembler as follows:
1. A statement is read and examined to determine its general character. It is also saved in a
temporary place so it can be read again during the second pass over the program.
2. If the statement will generate instructions or data, the Assembler adjusts the Location
Counter (if necessary) to satisfy alignment requirements, so that instructions begin on
halfword boundaries, words begin on word boundaries, etc.
3. If a symbol appears in the name field of the statement, it is entered into the Assemblers
Symbol Table, and (if it is not an EQU statement) is given the value of the Location
Counter. That is, the symbol is defined, as described in Section 7.6 on page 95. (Of course, it
will be an error if the symbol is already in the table with a value; this is called multiple or
duplicate definition.)
4. The rest of the statement is scanned; if any other symbols are encountered, they are entered
into the Symbol Table (if not there already), but numeric values are not assigned to their
attributes. That is, if the symbol is not yet defined, it remains undefined.
5. The length of the instruction or data to be generated from the statement is then added to the
Location Counter. No data or instructions are generated at this time, however.
This process is repeated for each statement, until the end of the program is reached. Because the
Assembler has made a complete scan or pass over the programs statements, this is called Pass
One of the assembly. At this point the Symbol Table contains all the symbols in the program,
whether or not they are defined.
The first assembly pass is sketched in Figure 43, but the sketch is incomplete in many ways. For
example, an EQU statement lets you assign a value to a symbol, and that value is taken from the
expression in the operand field. Figure 43, however, only shows values being assigned to symbols
using the Location Counter. It also omits any description of macro-instruction statements, and
how symbols are treated in erroneous statements.

Chapter III: Assembler Language Programs

125


Read statement
 and save it

yes

END ? to Pass 2

no
yes
comment?


no

Instruction symbol in is it in

statement? yes name field?yes symtbl?

no
no no
yes


 enter it


Undefined


nodoes it
mnemonic:

have a

note error


value?

set value
yes

 from LC


enter in
note error

table, Ysymbol(s) in

no valueoperand field?


no

increment LC by instruction length

Figure 43. Sketch of pass one of an assembly

Exercises
10.7.1.(2) In the following program segment, resolve the implied addresses into basedisplacement form, and fill in the four blank fields.
Loc
5000
5002
5002
5006
500A
500E
512C
5174
5178
51A0

126

Object Code

Statement

05A0
41D0____
4110____
4DE0____
50______
SAVE
PARM
TBL
SUB

BASR
USING
LA
LA
BAS
ST
- - DS
DC
DS
STM

Assembler Language Programming for IBM z System Servers

10,0
*,10
13,SAVE
1,PARM
14,SUB
0,TBL(15)
18F
A(TBL)
10F
14,12,12(13)

Version 1.00

10.8. Calculating Displacements: the Assembly Process, Pass Two


The Assembler now begins a second pass over the program by retrieving the statements from their
temporary storage place. The Assembler creates machine language object code, converting
instruction mnemonics to operation codes and using data in the Symbol Table to evaluate all
expressions appearing in the statements.
The overall flow of the second pass of the assembly process is sketched in Figure 44. As noted
following Figure 43 on page 126 describing the first pass of the assembly, this is a very abbreviated description, so dont attach great significance to the precise sequence of processing actions
implied by the diagram.

Read, Print
 statement 


yes

comment?

no

yes

USING ? enter data in USING Table

no

yes

DROP ? delete entry from USING Table

no

yes

END ? Create object module;

return to Supervisor

no

yes yes

machine
implied compute

instruction?
address?
value

no
no 


yes

define a convert check USING Table for

constant?
data a valid displacement

no

OK
none


note error


addressability


error

Generate instruction or data

Figure 44. Sketch of pass two of an assembly

When a USING statement is encountered, the Assembler enters the value and relocation attributes of the first operand expression (the base_location), and the value of the second expression
(the base_register number), into a USING Table.

Chapter III: Assembler Language Programs

127

Figure 45 shows an example of a USING Table with one entry. The abbreviations basereg and
RA denote respectively the base_register specified in the second operand of the USING statement, and the relocation attribute of the base_location expression from the first operand of the
USING statement. For now, the only importance of the relocation attribute is that it indicates
whether the symbol is relocatable (RA=01) or absolute (RA=00).

basereg base_location RA

6
00000002 01

Figure 45. USING Table with one entry

When a subsequent instruction operand contains an implied address, the Assembler compares the
value and relocation attribute of that expression to each entry in the USING Table. If a matching
relocation attribute is found, and a valid displacement can be calculated from
displacement = (implied address value) (base_location value)
then the Assembler inserts the computed displacement and the corresponding base_register digit
into the addressing halfword of the instruction. The Assembler has resolved the implied address
into base-displacement form, and the implied address is addressable.
For example, consider the second and third statements in Figure 41 on page 122. If the initial
LC value assigned to the program was zero, the USING Table would contain an entry for register
6, with an associated relocatable base_location value of X00000002, the value of the symbol
BEGIN illustrated in Figure 45.
When the third statement in Figure 41 is processed, the value of the implied address is the value
of the symbol N, or X00000024. The computed displacement is
X00000024 X00000002 = X022
as we saw previously, so the completed addressing halfword is X6022.
Here is a way to summarize the description of operand address resolution: at assembly time, the
Assembler computes a displacement:
displacement = (operand_location) (base_location)
while at execution time, the CPU reverses this computation:
(operand address) = displacement + (base address)
Assembler-calculated displacements
The Assembler at assembly time does the reverse of what the CPU does at
execution time.
It is important to give correct information in a USING statement because it specifies the intimate
connection between the base_location at assembly time and the base address at execution time.
Remember that the difference between assembly-time locations and execution-time addresses in a
relocatable program is only a single constant value,

Exercises
10.8.1.(2) + In the blank fields provided in the six instructions below, show the values and
addressing halfwords provided by the Assembler. Assume that the Location Counter values are
as shown in the column headed LOC.

128

Assembler Language Programming for IBM z System Servers

Version 1.00

Loc
10A20
10A20
10A24
10A28
10A2A
10A2E
10A32
- - 10A76
10A78
10A80
10A84

Object Code

Statement

5830____
4A30____
10__
9034____
4240____
4770____
W
Z
Y
X

USING
L
AH
LPR
STM
STC
BC
- - DS
DS
DC
DC

*,11
3,X
3,Y
4,3
3,4,Z
4,W
7,*+24
X
2F
H -72
A(Z-W)

10.9. Multiple USING Table Entries


You can create more than one entry in the USING Table, so it is possible to have more than one
valid resolution of an implied address into base-displacement form. Suppose we add another
USING statement to the program, as in Figure 46:
Location

Name

0000

Operation Operand

BASR
6,0
USING
*,6
BEGIN L
2,N
USING
*,7
A
2,ONE
ST
2,N
--------------------------N
DC
F 8
ONE
DC
F 1

0002
0006
000A
0024
0028

Remarks

Original USING statement


Added USING statement

Figure 46. Program segment with second USING statement

For now, we ignore the fact that the contents of register 7 are unknown.
When the second USING is processed, the value of the Location Counter is X00000006, so the
Assembler makes a second entry in the USING Table, as shown in Figure 47.

basereg base_location RA

6
00000002 01

7
00000006 01

Figure 47. USING Table with multiple entries

When the next statement


A

2,ONE

is processed, two possible valid resolutions are available for the implied address specified by the
symbol ONE:
If register 6 is used as a base register, the displacement is
X00000028 X00000002 = X026
and the addressing halfword would be X6026 (as in Figure 42).
Chapter III: Assembler Language Programs

129

If register 7 is used as a base register (again, ignoring the fact that its run-time contents are
unknown), the Assembler determines that the displacement is
X00000028 X00000006 = X022
and the addressing halfword would be X7022. (Similarly, the ST instruction could have an
addressing halfword X701E .)
The Assembler must make a choice: which of the two valid resolutions should be selected for the
completed machine language instruction?
The Assembler uses these resolution rules:
1.

Find all USING table entries whose relocation attribute matches that of the implied address
to be resolved.

2.

Choose the base register that leads to the smallest displacement.

3.

If more than one base register provides the same smallest displacement, choose the corresponding highest-numbered register.

Thus, the assembled program would appear as shown in Figure 48 below:


Location

Assembled Contents

00000
00002
00006
0000A

0D60
58206022
5A207022
5020701E
----------------00000008
00000001

00024
00028

Based on register 6
Based on register 7
Based on register 7

Figure 48. Assembled contents when two USINGs are active

At this point, you could (correctly) observe that this program is seriously flawed, because the contents of GR7 at execution time could be anything. When the A and ST instructions are executed, their operand addresses are likely to cause errors (whether or not they are detected
immediately!).
The important lesson in this example is that the Assembler has no way of knowing that the information supplied in the statement
USING *,7
may not be valid. It can only trust that you have provided correct base_location and base_register
data it can use to resolve implied addresses.

10.10. The DROP Assembler Instruction


It is also possible to delete entries from the USING Table. The DROP instruction tells the
Assembler to remove the information corresponding to a given register. Its general form is
DROP register
where the register operand specifies the USING Table entry to be deleted.
For example, if the statement
DROP 6
was inserted after the third statement, the L instruction named BEGIN in Figure 47, the initial
USING Table entry for register 6 would be deleted, and the USING Table would appear as in
Figure 49:

130

Assembler Language Programming for IBM z System Servers

Version 1.00


basereg base_location RA

empty

7
00000006 01

Figure 49. USING Table after D R O P statement

Another form of the DROP statement is


DROP
with no operand! This will cause all USING Table entries to be deleted. While this might seem
odd, its useful: if you have reached a part of your program where no valid base registers will be
available at execution time, DROPping all the USINGs will avoid unexpected or unintended
resolution of implied addresses in later parts of your program.

Exercises
10.10.1.(1) + A frustrated programmer wrote the statements
DEAD

EQU 101
DROP DEAD

How would you expect the Assembler to deal with this impertinence?
10.10.2.(3) + For each statement of the following program segment, show what will appear in
the USING Table following each USING and DROP statement. Then, use that information to
show the assembled machine language object code produced from the program segment.
Assume the program segment begins at location X4000.
BASR
USING
L
BASR
USING
L
DROP
L
DROP
L

9,0
*,9
4,*+54
10,0
*,10
3,*+52
9
2,*+48
10
1,10(0,9)

What would be found in register 1 after the last instruction is executed? How does it depend
on the address where the instructions are loaded into memory?

10.11. Addressability Errors


Addressability errors have many causes. These examples show some of the ways they can arise.
1. An operand value is larger than any USING Table base location value.
BASR 6,0
USING *,6
L
2,*+5000
Suppose the value of the Location Counter after the BASR instruction is X002468. This
means that the value of the operand *+5000 is
X002468 + X1388 = X0037E0
and that the calculated displacement (for register 6) would be

Chapter III: Assembler Language Programs

131

X0037E0 X002468 = X1388


which is too large for a 12-bit displacement field. This means the operand is not addressable
with 16-bit addressing halfwords.
2. An operand value is smaller than any USING Table base_location value. Again assuming
the value of the LC after the BASR instruction is X002468:
BASR 6,0
USING *,6
L
2,*-32
In this case the operand value is X002448, leading to a negative calculated displacement,
X FFFFFFE0 . This means the operand is not addressable with 16-bit addressing halfwords.
3. The USING Table is empty. Suppose a second DROP statement is added after the A
instruction in the program shown in Figure 46, specifying register 7:
DROP 7
Then, the remaining entry in the USING Table would be deleted, and the USING table
would appear as in Figure 50 below.

basereg base_location RA

empty

empty

Figure 50. USING Table after second D R O P statement

Because there are no entries left in the USING Table, there is no way for the Assembler to
resolve the implied addresses of any following instructions, and an addressability error would
be noted for those statements.

Exercises
10.11.1.(3) + Suppose these instructions are assembled and then executed in a program:
B

BASR 6,0
USING *,6
L
2,B

What (if anything) would you expect to appear in GR2?

10.12. Resolutions With Register Zero (*)


Although USING statements specifying absolute base_locations are rare, they are allowed; absolute implied address expressions follow the same resolution rules as relocatable expressions. In
most cases, there is no entry in the USING Table with an absolute base address, so the Assembler proceeds as though a hidden or implied
USING 0,0

Assembler s implicit USING

is always present. You can think of the USING Table appearing like this:

132

Assembler Language Programming for IBM z System Servers

Version 1.00


basereg base_location RA

0
00000000 00 Assembler s hidden USING-Table entry


etc.

Thus, an implied address such as


LA

Implied address = 1000 = X 3 E8

3,1000

would be resolved to the addressing halfword X03E8 , with base register zero.
In the example in Figure 34 on page 111, we saw an instruction with an absolute implied S2
operand:
43000468

IC

0,1128

The generated object code shows that the second operand was resolved with base register zero.
Now, suppose you wrote a USING statement with an absolute base address:
USING 400,9
LA
3,1000

Base Address = 400 = X190


Implied address = 1000 = X 3 E8

so the USING Table would look like this:

basereg base_location RA

0
00000000 00

9
00000190 00


etc.

The Assembler follows its usual resolution rules, and finds that there are two valid resolutions
with addressing halfwords X03E8 and X9258. Since the latter provides the smallest displacement, the Assembler chooses the resolution with base register 9! Fortunately, the Assembler will
issue a diagnostic message whenever a USING with an absolute operand appears to overlap with
its implicit USING 0,0 statement.
If the original resolution using base register zero is required no matter what other USINGs are
active, the operand should be written explicitly, as
LA

3,1000(0,0)

Explicit displacement=1000, base=index=0

Thus, we add one further resolution rule when absolute implied addresses have not been resolved
according to the three previous rules:
4. If no previous resolution has been completed, and the implied operand is absolute and has
value between 0 and 4095, use General Register 0 as the base register and the value of the
implied address expression as the displacement.
This behavior is used often in Assembler Language programs. If any implied address has absolute
nonnegative value, a valid displacement can always be computed only if that value does not
exceed 4095.61

61

Section 20 shows how to use a much larger range of displacement values with long-displacement instructions.
Chapter III: Assembler Language Programs

133

According to the rules for evaluating expressions, attempting to compute a displacement for a
relocatable symbol using an absolute base_location would require that the displacement be relocatable, which is invalid. That is, a valid displacement cannot be calculated from
(absolute) displacement = (relocatable operand) (absolute base_location) (??)
Similarly, an absolute implied address cannot be resolved into base-displacement form using a register whose base_location is relocatable, since a valid displacement cannot be computed from
(absolute) displacement = (absolute base_location) (relocatable operand) (??)
It is possible (but not recommended!) to specify USING statements with register zero as the base
register,62 but the Assembler will always assign a base address of zero to register zero.

Exercises
10.12.1.(1) + The Assembler tries to resolve absolute implied addresses into an addressing
halfword containing a zero base digit, and a displacement of the value of the implied address.
Do you think this is desirable? Would you prefer that the Assembler diagnose absolute implied
addresses as an error?

10.13. Summary
In summary, the ordinary USING statement provides two major features:
1. A base_location relative to which the Assembler can calculate displacements.
2. A base_register to be used in addressing halfwords of implied addresses whose displacements
were calculated as being addressable with this register.
The information conveyed in a USING statement is only, and no more than, a promise that you
make to the Assembler. You are asserting that if it uses the base_location and base_register specified in your USING statement to calculate addressing halfwords at assembly time, then the CPU
will calculate correct Effective Addresses at execution time.
The rules for resolving implied addresses into base-displacement form can be difficult to
remember, and forgetting them can sometimes lead to programming errors that are difficult to
correct.63
USING Resolution Rules
1. The Assembler searches the USING Table for entries with a relocation attribute matching that of the implied address (which will
almost always be simply relocatable, but may be absolute).
2. For all matching entries, the Assembler checks to see if a valid displacement can be derived. If so, it will select as a base register the
register that yields the smallest displacement.
3. If more than one register yields the same smallest displacement, the
Assembler will select the highest-numbered register as a base register.
4. If no resolution has been completed, and the implied address is absolute, try a resolution with register zero and base zero.
A minor addition to these rules will apply when we discuss instructions with long 20-bit signed
displacements in Section 20.

62

63

134

When we discuss Dummy Control Sections in Section 39, we will see that there can be times when specifying a zero
base register is a reasonable practice.
Some programmers note that USING is part of confusing.
Assembler Language Programming for IBM z System Servers

Version 1.00

The relocatability attribute of any given symbol almost always has a single value; it wont matter
if we ignore complex relocatability situations for now, because they dont affect addressability.
However, it is not unusual for programs to use many different relocatability attributes to correctly
describe its symbols.
In Chapter XI we will see powerful extensions to the USING statement Labeled and Dependent
USINGs that give you much greater control over USING resolutions.

10.13.1. How the Assembler Helps


The Assembler simplifies many programming tasks:
1. It automatically resolves addresses into the base-displacement and other forms used by
z System. The Assembler determines the needed base and displacement so that correct Effective Addresses will be computed at execution time.
2. Rather than remembering that operation code X 4 3 places a byte from memory into the
right end of a general register, a mnemonic operation code IC (Insert Character) gives a
simple indication of what the operation code does.
3. Symbols let you name areas of memory and other objects in your program.
4. Diagnostic messages help you find possible errors and oversights.
5. The Assembler converts data from convenient external representations into internal forms.
6. It creates relocatable object code to be combined with other programs by the linker.
7. It provides lots of other helpful information such as symbol and register cross-references.
8. Using macro-instructions, you can define your own instruction names to supplement existing
instructions, and your macro-instructions can make use of previously defined sequences of
statements, including other macros!
9. The High Level Assembler provides an optional summary of all USING Table activity, in
the form of a USING Map. If you specify USING(MAP) as part of the parameter string when
you invoke the High Level Assembler, it will display all USING and DROP activity for the
entire program.

Exercises
10.13.1.(3) Some older assemblers let you redefine symbols in EQU statements. Thus, you
could write
A
A

Equ 6
- - Equ 32
- - -

Define a value for A


Write statements using A s value
Define a new value for A
Statements using A s new value

How would the assemblers treatment of the Symbol Table be changed? What would happen if
any symbol could be redefined?

Terms and Definitions


USING statement
A promise to the Assembler that addressing halfwords can be derived correctly from the
base_location and base address information provided in the instruction.
USING Table
An internal table used by the Assembler to hold information provided in USING
instructions.
DROP assembler instruction
An instruction telling the Assembler to eliminate one or more entries from its USING Table.

Chapter III: Assembler Language Programs

135

base_location
The first operand of a USING instruction at assembly time.
base_register
The second operand of a USING instruction at assembly time.
addressability
The ability of the Assembler to calculate a displacement and assign a base register to an
implicit addressing expression, using information in the USING Table.
addressability error
The inability of the Assembler to derive an addressing halfword for an implicit operand.
Symbol Table
A table used by the Assembler to hold the names, values, and attributes of all symbols in a
program.

Programming Problems
Problem 10.1.(1) Write and assemble a program segment like the one in Figure 41 on
page 122, with the following additional statements:
1. Following the last DC statement, place an Assembler instruction statement with the mnemonic END in the operation field.
2. Replace the dotted line that means twenty-two additional bytes with an Assembler
instruction statement with DS in the operation field and 22X in the operand field.
3. Preceding the first statement place an Assembler instruction statement with the mnemonic
START in the operation field, and X5000 in the operand field.
Assemble the program, and save the Assemblers listing. Then, replace the X5000 operand in
the START statement with the X84E8 , and re-assemble the program, saving the second listing.
Verify that the assembled machine language program is the same in both listings, and that the
same bases and displacements are calculated by the Assembler for all instructions that require
them. If time and budget permit, do the same for the programs in Figures 39 and 40.

136

Assembler Language Programming for IBM z System Servers

Version 1.00

Chapter IV: Defining Constants and Storage Areas

IIIIIIIIII
IIIIIIIIII
II
II
II
II
II
II
II
II
IIIIIIIIII
IIIIIIIIII

VV
VV
VV
VV
VV
VV
VV
VV
VV
VV
VV
VV
VV
VV
VV
VV
VV
VV
VV VV
VVVV
VV

The three sections of this chapter treat the DC (Define Constant) and DS (Define Storage) assembler instruction statements, and methods used to define data and storage areas in Assembler Language programs.
Section 11 describes the Assemblers basic data definition instruction, DC.
Section 12 discusses the most often-used data types, introduces the powerful constantreferencing mechanism provided by literals, and the LTORG instruction to control their
location in your program.
Section 13 demonstrates methods for defining and describing data areas in ways that simplify
data manipulation problems, including the very useful DS, EQU, and ORG instructions.

Chapter IV: Defining Constants and Storage Areas

137

11. Defining Constants

11
11
111
111
1111
1111
11
11
11
11
11
11
11
11
11
11
11
11
11
11
1111111111 1111111111
1111111111 1111111111

In the preceding sections we used the DC assembler instruction to create constants in the
program. Now, well describe basic rules for defining constants of any type.
z System supports a very rich variety of data types, and various lengths and precisions can be
specified for most of them. Among the native data types the Assembler supports are:
1. Fixed-point data (twos complement binary), signed and unsigned

doubleword precision (64 bits)


word precision (32 bits)
halfword precision (16 bits)
byte precision (8 bits)

2. Logical data (binary and hexadecimal)

doubleword (64 bits)


word (32 bits)
one byte (8 bits)
varying-length (1 to 256 bytes)

3. Address-valued (3, 4, and 8 bytes)


4. Character data (1 to 256 bytes) in EBCDIC, Graphic (Double-Byte), ASCII, and Unicode
formats. 64
5. Decimal data (sign-magnitude representation)
zoned decimal (1 to 16 digits)
packed decimal data (1 to 31 digits)
6. Floating-point data (sign-magnitude representation in binary, hexadecimal, and decimal
formats)
short precision (4 bytes)
long precision (8 bytes)
extended precision (16 bytes)

64

138

Well investigate some non-EBCDIC character data types in Section 27.


Assembler Language Programming for IBM z System Servers

Version 1.00

Data for each of these types is defined using the DC (Define Constant) assembler instruction,
with many options for each type.
Be Careful!
The DC instruction doesnt really define an unchangeable constant value,
because you can change it at execution time. (Its only constant if you
dont change it!) The instruction might better be called Define Data
with Initial Value. Well see that literals can help you define what
appear to be true constants In Section 13.9 on page 176.
You will usually write values in data definitions in the external representation most convenient for
you. The Assembler then converts the data into the internal form used by your program, the
CPU, and other devices.
As indicated in previous examples, a DC assembler instruction statement may have name, operation, operand, and remarks field entries; the operation and operand field entries are required.

11.1. Defining Constants


Well start with the F-type constant we saw in several earlier examples. The assembler instruction
statement
F 8

DC

creates a word binary integer constant (X00000008), placed on a word boundary. In this statement, four items were specified or implied:
1. The type of desired conversion from the external form you wrote in the statement, to an
internal representation. For type F, the decimal value is converted to a twos complement
binary integer.
2. The nominal value of the constant, the decimal value 8.
3. The length of the constant, which for type F is implicitly four bytes.
4. The alignment in memory of the constant, implicitly on a word boundary for type F.
Some other types of conversion, and the letters that specify the types, are character (C), binary
(B), hexadecimal (X), halfword binary integer (H), and address constant (A and Y). Here are
examples of some of these types:
H 8
C /
X 6 1
B01100001

DC
DC
DC
DC

halfword binary integer


character constant
hexadecimal constant
binary constant

The last three constants are each one byte long, and contain identical bit patterns.
Important to remember
The binary, character, and hexadecimal self-defining terms use the same
notation as constants of those types. It can be easy to forget that a selfdefining term is just a number, while the operand of a DC statement
defines an initial value in storage.

Exercises
11.1.1.(1) Constants of types B, C, and X are written in a form very much like self-defining
terms of the same types, as in
DC

B11010001,C J , X C5

Constants with decimal values are written as (for example) F-type constants, as in
Chapter IV: Defining Constants and Storage Areas

139

DC

F 8

Why do you think the designers of the Assembler Language made this choice, rather than
allowing you to write this constant in the simpler form
DC

8 ?

Alternative to F8 ?

11.2. DC Instruction Statements and Operands


The operand field entry contains one or more operands separated by commas. An operand of a
DC statement has four parts, with no spaces between them:
1. a duplication factor (if omitted, it defaults to 1)
2. a letter (or pair of letters65) specifying the type of representation
3. zero to four modifiers
4. the nominal value of the constant, enclosed in a pair of delimiters. The delimiters are either
apostrophes or parentheses, depending on the type of the constant.
Of these four parts, only the second (the type) and fourth (the nominal value) are required. In the
example above, F 8 specifies type F and nominal value 8.
The three important modifier types are length, scale, and exponent. 66 Only length will be discussed
here.
DC Operands
This may help you remember the order of of the fields: duplication factor
(d), type (T), modifiers (m), and nominal value (V), where the required
type and value are specified in capital letters: dTmV
The nominal value part of the operand is specified in different ways for different constant types.
For F-type constants, the value is written as a string of decimal digits, preceded by an optional +
or sign and followed by an optional decimal exponent. For B-type constants, the value is
expressed as a string of binary digits, so F110 and B110 are quite different.
The constant type also determines what conversion from external to internal representation should
be performed: the internal representations of F110 (binary word), X110 (hexadecimal constant), E110 (short floating-point), Z110 (zoned decimal), and P110 (packed decimal) are different, even though they all have the same nominal value.

11.2.1. Blanks in Nominal Values


Some constant types delimited by apostrophes (like F 8 ) let you put blank spaces between the
digits to improve readability. For example, you can write either
DC

F12345678

DC

F12 345 678

or
Well see more examples as we investigate various data types.

65
66

140

Well discuss type extensions in Section 12.8.


HLASM supports another constant modifier and attribute, Program. It is used almost entirely in conditional
assembly macro-instruction statements.
Assembler Language Programming for IBM z System Servers

Version 1.00

11.3. Boundary Alignment


Many constant types have natural boundary alignments. For example, the F-type constant is
naturally word-aligned. Other constant types dont have a natural alignment; Tables 32 and 33 in
Sections 12.5 and 12.8 summarize default alignments for many common data types.
There is an important relationship between boundary alignment and the presence of a byte-length
modifier, which helps you align constants and data properly.67 This will be discussed shortly, in
Section 11.4.
By default, the Assembler initializes the Location Counter to zero. If you specify an initial LC
value at the start of the program, the Assembler rounds it up (if necessary) to a multiple of eight
to ensure that the program begins on a doubleword boundary. 68 Then, if a constant must fall on a
specific boundary, the Assembler only needs to be sure that the Location Counter is divisible by
the proper power of two (such as 2, 4, or 8) at the location of the leftmost byte of the constant.
The Linker and Program Loader respect this assumed alignment for the beginning of the
program. This guarantees that data and instructions will be aligned on the desired boundaries
when the program is loaded into memory for execution.
Suppose that after a sequence of instructions has been processed, the value of the LC is X00012E
(on a halfword boundary). If another machine instruction is assembled at this point, it would
begin on this halfword boundary between two word boundaries. But if the next statement is
instead
DC

F 8

the Assembler must place it on a word boundary to force the desired alignment.
Generating the four bytes of this constant beginning at the halfword-aligned location X00012E
could be incorrect, because instructions referring to word constants normally expect the address to
be on a word boundary. To avoid alignment errors, the Assembler automatically skips enough
bytes to obtain the desired alignment. The LC would be increased to X000130 (now wordaligned) before the word constant is assembled. The LC has value X000134 after the constant is
processed; it would be X000132 if automatic alignment was not done.
Automatic alignment is not performed (bytes are not automatically skipped) if:
1. it isnt needed: that is, the LC happens to fall on the desired boundary; or
2. the type of constant specified doesnt require alignment, such as types C, B, or X (among
others); or
3. a length modifier is present.
You can tell the Assembler to do no boundary alignment even if the constant type normally
requires it.69

67

68

69

Well see in Section 17.5 that constants can also have bit-length modifiers, but here we use the term length modifier
to mean byte length modifier.
HLASM provides the SECTALGN option to let you specify even more restrictive boundaries. See the High Level
Assembler Programmer s Guide for details.
For details, consult the High Level Assembler Programmer s Guide for the NOALIGN option. However, few programs use this option.
Chapter IV: Defining Constants and Storage Areas

141

11.4. Length Modifiers


Length modifiers let you specify (within limits) a constants exact length in bytes.70 When used,
we say that an explicit length was specified.
A length modifier is written immediately following the letter specifying the data type, in the form
Ln

or

L(expr)

The quantity n is an unsigned, nonzero decimal self-defining term, and expr is a positive
absolute expression enclosed in parentheses. The length modifier specifies the constants length.
Any symbols appearing in the length modifier expression must be defined before they are used in
the length modifier expression, so that it can be evaluated immediately.71 For example, the statements
DC

FL3 8

DC

FL(2*4-5) 8

and
both cause the three-byte constant X000008 to be assembled at the location specified by the
Location Counter; no boundary alignment is performed. In practice, length modifiers are used
mostly with constants of types C and X, and very rarely with type F and other normally-aligned
constants.
Because alignment is automatic only
(1) when the length is implied (that is, when no length modifier is given), and
(2) for constant types for which alignment is the default action,
the two statements
DC

F 8

DC

FL4 8

and
define the same constant, but the first is automatically aligned and the second is not.
When a symbol appears in the name field of a DC assembler instruction statement, boundary
alignment affects the symbols value. Suppose the value of the LC is X00012E when each of the
statements in Figure 51 is encountered.
Explicit DC
Implied DC

FL4 8
F 8

Explicit length = 4 bytes, not aligned


Implied length = 4 bytes, word aligned

Figure 51. Implied and explicit length specifications

Because no boundary alignment is performed for the first constant, the value of the symbol
Explicit will be X00012E . For the second constant, two bytes must be skipped to achieve the
required word alignment. If we refer to the constant using the symbol Implied, the symbol will
have the value of the location of the first byte of the constant, X000130.
Symbol definition
When a symbol is defined, it is given its value after bytes are skipped for
boundary alignment.

70

71

142

It is also possible to specify a constants length in bits, using a bit-length modifier. They have specialized uses; we will
describe them in Section 17.5 on page 257.
Sometimes the Assembler will let you define symbols after they are used in length modifier expressions, but its safest
to make sure theyre defined before theyre used in length modifiers.
Assembler Language Programming for IBM z System Servers

Version 1.00

As a general rule, the Assembler never automatically assigns the location of skipped bytes as the
value of a symbol.72 This includes cases where a byte must be skipped to ensure that an instruction begins on a halfword boundary. When bytes are skipped to achieve alignment of a following
constant or instruction, the Assembler will insert bytes containing all zero bits into the bytes
skipped.
Proper boundary alignments can be important: some instructions require aligned operands. Also,
operand misalignment can affect the performance of your applications, because the CPU may
need to bring more data from memory than your instruction actually requires.

Exercises
11.4.1.(2) What data is generated by these constants?
(1)
(2)
(3)
(4)

DC
DC
DC
DC

FL1 -127
FL2+128
FL3 -99,+99
FL1+127

11.4.2.(1) + For these constants:


(1)
(2)
(3)

DC
DC
DC

F 1 1 , FL3 1 2 , FL3 1 3
F 2 1 , FL2 2 2 , FL2 2 2
F 3 1 , FL4 3 2 , FL3 3 3

on what boundaries are the constants 13, 23, and 33 aligned?

11.5. Duplication Factors and Multiple Operands


A duplication factor (sometimes called a multiplicity, replication, or repetition factor) specifies the
number of times the constant or constants in the operand will be duplicated; it is written immediately preceding the letter specifying the constant type. It may be either an unsigned decimal selfdefining term, or a nonnegative absolute expression enclosed in parentheses. Any symbols
appearing in the duplication factor expression must be defined prior to their use in the duplication
factor.73 For example, both
Three8s DC

3F 8

Duplication factor 3

and
Three8s DC

(5/2+1)F 8

are equivalent to writing the three statements


Three8s DC
DC
DC

F 8
F 8
F 8

Three statements

You can write more than one operand in the operand field entry of a DC instruction, so you will
get the same result by writing
Three8s DC

F 8 , F 8 , F 8

Three operands

Duplication factors apply only to operands, not to statements.


For example, if you write

72

73

You can find ways to do it if you like, but theres no real value in doing so. (Why refer to something so uninteresting?)
Sometimes the Assembler will let you define symbols after they are used in duplication factor expressions, but its
safest to make sure theyre defined before theyre used in duplication factors.
Chapter IV: Defining Constants and Storage Areas

143

F 7 , 2 F 4 , 3 F 9

DC

the Assembler generates six word-length, word-aligned constants: one with value 7, two with
value 4, and three with value 9.
There are occasionally important uses for DC statement operands with a zero duplication factor.
In such a case, the Assembler first skips as many bytes as necessary to properly align the constant
specified by the operand, and then generates no data for that operand. This means that the
Location Counter is not further incremented for that operand, after alignment (if any). Thus we
could generate a word-aligned 4-byte constant with a statement like
DC

0F 0 , FL4 -1

DC

0F,FL4 -1

or even

Zero duplication factors are discussed further in Section 13.2 on page 162.

11.6. Multiple Nominal Values


For almost all constant types, the nominal value may actually be a sequence of values separated
by commas, as in
F 8 , 8 , 8

Three8s DC

One operand, 3 nominal values

This is equivalent to
Three8s DC

3F 8

One operand, duplication factor 3

F 8 , F 8 , F 8

Three operands

and
Three8s DC

Which format you use is largely a matter of taste and convenience. For example, you could
specify a table of constants with a statement such as:
TABLE

F 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 1 0

DC

Figure 52. Multiple constants

Each generated constant is a word integer, aligned on a word boundary.


In cases where multiple constants are specified, any symbol in the name field (in this example,
TABLE) is given the value and Length Attribute associated with the first constant generated.

Exercises
11.6.1.(2) A meticulous programmer determined that 10 9 is the largest power of ten that will fit
in a word binary integer, and wanted to define a constant of that value. To ensure that he
wrote the constant with the correct number of zeros, he wrote the statement
TEN_to_9 DC

F1,000,000,000

What would be generated? What would you recommend?


11.6.2.(1) What will be generated by this constant?
DC

144

2F 1 , -1

Assembler Language Programming for IBM z System Servers

Version 1.00

11.7. Length Attributes


Although its many benefits will become clear later, we noted in Section 7.3 on page 91 that the
Length Attribute of a symbol can be very useful. Its value is determined by the statement in
which the symbol is defined.
1. The Length Attribute of a symbol naming an instruction is the length of the instruction.
Thus, the Length Attribute of the symbol LOAD in
LOAD

LR

R7,R3

(from Example 8_4_1 on page 102 in Section 8.4.)

is 2, and the Length Attribute of the symbol BEGIN in


BEGIN

2,N

(from Figure 35 on page 119)

is 4.
2. If a symbol is the name of a DC statement, its Length Attribute is the length of the first
generated constant, ignoring duplication factors. Explicit lengths and Length Attributes may
be assigned with a length modifier; otherwise the Length Attribute is the implied length.
Thus, the three symbols in
Implied DC
Explicit DC
Three8s DC

F 8
FL4 8
3F 8

(from Figure 51 on page 142)

all have Length Attribute 4.


3. If the symbol names a DC statement whose first operand contains multiple values, the symbols Length Attribute is the length of the first generated constant, as noted for the symbol
Three8s above. Similarly, the Length Attribute of the symbol TABLE in
TABLE

DC

F 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 1 0

(from Figure 52 on page 144)

is 4, even though the statement defines constants occupying 40 bytes.


4. If the symbol names a DC statement with more than one operand, the Length Attribute
assigned to the symbol is determined from the first operand only, according to the previous
rules. Thus,
TwoCons DC

F 2 , FL2 -2

would assign 4 as the Length Attribute of TwoCons.


5. A symbol defined in an EQU statement to have the value of a self-defining term is assigned a
Length Attribute of 1. Thus, the symbol ZILCH in
ZILCH

Equ

(from Example 8_4_2 in Section 8.4.)

has Length Attribute 1. (The EQU assembler instruction is described further in Section 13.3
on page 164.)

11.8. Decimal Exponents (*)


Some numeric constants can be simplified by using either a decimal exponent or an exponent
modifier. When you want to generate a constant with several trailing zeros, both forms let you
omit the trailing zeros.

11.8.1. Decimal Exponents


A decimal exponent is written as part of the nominal value of the constant. Following the
numeric portion, write the letter E followed by a signed or unsigned integer. For example:
F100A
F100B
F1000
FBillion

DC
DC
DC
DC

F 1 E2
F1000E-1
F 1 E3
F 1 E9

Generates
Generates
Generates
Generates

X00000064
X00000064
X000003E8
X 3 B9ACA00

Chapter IV: Defining Constants and Storage Areas

145

11.8.2. Exponent Modifiers


An exponent modifier is written following the constants type, and following any other modifiers.
For example:
F100A
F100B
F100C
F1000A
F1000B
FBillion

FE2 1
FE-11000
FL4E2 1
FE3 1
FL3E3 1
FE9 1

DC
DC
DC
DC
DC
DC

Generates
Generates
Generates
Generates
Generates
Generates

X00000064,
X00000064,
X00000064,
X000003E8 ,
X0003E8 ,
X 3 B9ACA00 ,

aligned
aligned
unaligned
aligned
unaligned
aligned

You can write constants with both an exponent modifier and a decimal exponent in the nominal
value; the power of 10 applied to the numeric portion of the nominal value is the sum of the two.
For example:
F100A
F100B
F1000A
FBillion

FE1 1 E1
FE-1 1 E3
FE-7 1 E10
FE5 1 E4

DC
DC
DC
DC

Generates
Generates
Generates
Generates

X00000064
X00000064
X000003E8
X 3 B9ACA00

Well see more about scale and exponent modifiers in Section 32.3, on page 561.

Exercises
11.8.1.(2) Show the constants generated by these statements, indicating which are aligned by
default and which are not.
(1)
(2)
(3)
(4)

DC
DC
DC
DC

FE1 2 E3
FE-1 5 E5
FL2E2 1 E2
FL4 8 E1

11.8.2.(1) Rewrite the intended constant in Exercise 11.6.1 using (a) a decimal exponent and (b)
an exponent modifier.
11.8.3.(2) + In following program segment, determine the values assigned to the Location
Counter in the last four statements. Then complete the Object Code column for the four
statements with spaces provided.
Loc
000000
000000
000002
000002
000006
00000A
00000E
000012
000038
______
______
______
______

146

Object Code

05F0
__________
__________
__________
__________

Statement
Ex11_8_3 START
BALR
USING
L
A
S
ST
PRINTOUT
DUMMY
DC
X
DC
Y
DC
Z
DC
RESULT DC

Assembler Language Programming for IBM z System Servers

0
15,0
*,15
2,X
2,Y
2,Z
2,RESULT
RESULT,*
0CL16 GARBAGE
F 2
F 1 5
F 3
F 0

Version 1.00

Terms and Definitions


constant type
A letter specifying the internal data representation for a generated constant.
nominal value
The value you write between delimiters or value separators to specify the assembled value of
a constant.
boundary alignment
The Assemblers action in incrementing the Location Counter so that its value is adjusted to
the boundary required by an instruction or by a constant operand.
duplication factor
The number of times a constant operand should be assembled.
modifier
A value following the constant type, specifying other information about the constants
Length, Scale, and Exponent.
length modifier
A modifier specifying the exact length to be used for a constant, rather than its default length.
exponent modifier
A modifier specifying a positive or negative power of ten to be multiplied by the nominal
value of a constant.
decimal exponent
A letter E attached at the end of the digits of a constant, followed by a positive or negative
integer giving the power of ten by which the value of the digits is multiplied.

Chapter IV: Defining Constants and Storage Areas

147

12. Basic Constants

11
111
1111
11
11
11
11
11
11
11
1111111111
1111111111

2222222222
222222222222
22
22
22
22
22
22
22
22
22
222222222222
222222222222

We now use the general rules of the previous section to describe seven basic constant types used
in many programs F, H, A, Y, C, B, and X and the useful form of constants called
literals.

12.1. F-Type and H-Type Constants


We saw the F-type constant in earlier examples, so we will just summarize its properties here.
The implied length is four, and the default alignment is to a word boundary. If an explicit length
is specified, no alignment is performed and the length may be between 1 and 8 bytes. The
nominal value of the constant is an optionally signed string of decimal digits. Thus, you can write
DC
DC

FL1 -10
FL8 -10

Generates X F6 , not aligned


Generates X FFFFFFFFFFFFFFF6 , not aligned

The H-type constant is similar to type F, specifying twos complement binary integer conversion
to a 16-bit integer in two bytes aligned on a halfword boundary. Thus
DC

H -10

places the constant X FFF6 on the next available halfword boundary. If an explicit length is
given, there is no difference between constants of types F and H, so that FL3 8 and HL3 8
produce identical results.
As we saw in Section 11.8, a decimal exponent can be specified in the nominal values in F- and
H-type constants. It is written as the letter E followed by an optionally signed decimal integer, as
in
DC

F -43E+6

4310**6, generates X FD6FDF40

The decimal exponent specifies the power of ten by which the preceding value is multiplied. You
could define a table of the first six powers of ten with either of the following two statements:
Powers10 DC
Powers10 DC

F1,10,100,1000,10000,100000
F 1 E0,1E1,1E2,1E3,1E4,1E5

Figure 53. F-type constant with decimal exponent

148

Assembler Language Programming for IBM z System Servers

Version 1.00

To improve readability, you can insert blanks among the digits of F-type and H-type constants
(remember: not in decimal self-defining terms!):
F1, 10, 100, 1 000, 10 000, 100 000

Powers10 DC

In practice, decimal exponents are used mainly in floating-point constants, which well discuss in
Chapter IX.
You may sometimes want to create unsigned or logical binary integers constants, as described in
Section 2.6 on page 27. You can define such integers by preceding the nominal value of the
constant with the letter U, as in these examples:
DC
DC
DC
DC
DC

F U2147483648
H U65535
F U4294967295
H 1 , U2
H -1,U32768

X80000000
X FFFF
X FFFFFFFF
X00010002
X FFFF8000

+2**31
+2**161
+2**321
Mixed signed and unsigned
Mixed signed and unsigned

No signs are allowed either before or after the U.

Exercises
12.1.1.(1) + In Exercise 11.6.1 on page 144, our friend wanted to define a word binary integer
constant with value 10 9. Help him by rewriting the constant with a decimal exponent.
12.1.2.(1) + Suppose you modified your table of powers of 10 to generate the first six negative
powers, as in
Powers10 DC

F 1 E-0,1E-1,1E-2,1E-3,1E-4,1E-5

What values will be generated?


12.1.3.(2) Suppose you need a halfword constant with value 1/2, so you write
Half

DC

H 5 E-1

What do you think will be generated?


12.1.4.(1) What will be generated if you write
DC

F2147483648

12.1.5.(2) What would happen to the Location Counter values in Figure 35 on page 119 if
there were now 24 bytes (instead of 22 bytes) between the ST instruction and the first DC
instruction?
12.1.6.!9) + Show the object code generated for these statements:
DC
DC
DC

F -2147483620
H -32594
F+2147483260

12.2. A-Type Address Constants


The type A address constant, sometimes called an adcon, has great power and broad applicability in Assembler Language programs. An address constant is written differently from the other
types we have considered, because the nominal value is delimited by parentheses, as in A(10),
rather than by apostrophes. Address constants are particularly useful because the nominal value

Chapter IV: Defining Constants and Storage Areas

149

within the parentheses may be any expression, either absolute or relocatable.74 Understanding
relocatable address constants involves considering Linker and Program Loader processing, as we
will see in Section 39.
A special case where the nominal value of an A-type constant contains a Location Counter Reference is described in Section 13.6 on page 171.
A-type and F-type constants have similarities: a length of four bytes and word boundary alignment are implied. An explicit length suppresses alignment; thus A(10) and F 1 0 are equivalent
operands, as are AL4(10) and FL4 1 0 . The major difference is that you can write expressions as
the nominal value of constants like A(X00012E ) and A(1+C . ) . In some contexts, these may be
much more natural or convenient than the equivalent F-type constants F302 and F 7 6 .
A-type address constants are especially useful when we want to define word-aligned constants
with types not ordinarily aligned by the Assembler. For example, if we need a word containing
1-bits in the rightmost 12 positions and zeros elsewhere, we could write
DispMask DC

A(X FFF )

X00000FFF

If we had written this DCs operand field as XL4 FFF instead, we cant guarantee it will be word
aligned, even though the same four bytes are generated. Similarly, a word containing the
EBCDIC representation of the letter A could be written
AConst

DC

A(C A )

X000000C1

This is easier to read than F193, even though the same constant is generated. A constant like
Word

DC

A(C WORD )

X E6D6D9C4

can be used as a word-aligned character constant.


Using such expressions can greatly simplify programming tasks. For example, you can define constants using operands such as
Con425

DC

A(ABS425)

where the symbol ABS425 may have been defined in an EQU statement (as in Section 7.6 on page
95) to have a known value. We will see that this technique can provide clarity and simplicity in
your programs.
Address constants let you define an area that will contain the actual address of a byte in memory
when the program is executed. For example, suppose we have written a program that requires
the address of the word integer constant with value 8, in Figure 51 on page 142. We can define
the necessary address constant with the statement
Con8Addr DC

A(Implied)

Exercises
12.2.1.(2) Show the generated constant for each of these address constants:
1. A(X213+C * -B 1 1 )
2. A(92*X F )
3. A(5*C 0 / C )

74

150

The name address constant can be somewhat misleading, because the generated data need not be an address!
Assembler Language Programming for IBM z System Servers

Version 1.00

12.3. Y-Type Address Constants


Y-type address constants bear the same relationship to A-type adcons as H-type constants bear to
F-type constants, except that relocatable Y-type adcons are almost never used. The Y-type adcon
has an implied halfword length and alignment, and is identical to the A-type adcon if an explicit
length is specified. For example, the operands H 1 0 and Y(10) in DC statements define identical
2-byte constants, and the operands YL1(10), AL1(10), HL1 1 0 , and FL1 1 0 all generate X 0A .
If we assume that the symbol Implied is relocatable (as in Figure 51 on page 142), then the
statement
BadCon

DC

Y(Implied)

would fail at linking time, because 3 or more bytes will be required to hold the execution-time
address of Implied.
The main use of Y-type constants is for symbolically-defined constants such as
DC

Y(ABS425)

DC

Y(C A )

or
where the equivalent of a halfword integer is desired. Y-type constants are most often used this
way: to create a halfword value depending on an absolute expression.
Other address constant types are are V, S, and Q. V-type constants are very similar to A-type
constants, and will be treated when we discuss external subroutines in Chapter X. Q-type constants will be described when we examine external data structures. The S-type constant generates
an addressing halfword that need not be part of an instruction: the value of the operand
expression is resolved into base-displacement form. Well defer these types to later sections.

Exercises
12.3.1.(1) What hex data will be generated by these constants?
DC
DC
DC

Y(C A )
Y(X F *C B )
Y(B101*729/C&&)

12.3.2.(3) An S-type address constant is occasionally useful. It has a length of two bytes, which
may be implied or explicit. It is almost always aligned on a halfword boundary. The unusual
property of this constant is that
S(expression)

or

S(expression(expression))

is resolved into an addressing halfword. For the first (implied address) format, sufficient USING
information must be available to the Assembler so that it can resolve the expression into basedisplacement form.
Assuming that A is a relocatable symbol and that N is an absolute symbol, determine the
validity of each of the following constants:
(1) S(A+N), (2) S(A(N)), (3) S(N(7)), (4) S(7(N)), (5) S(N).
For which of these constants will the result depend (a) on USING information, and (b) on the
values of the symbols?

Chapter IV: Defining Constants and Storage Areas

151

12.4. Constants of Types C, B, and X


Constant types C, X, and B differ in an important way from types F, H, A, and Y: no defaults
are assumed for either length or alignment. For example, the five bytes required to store the constant generated by the statement
DC

C12345

will be placed by the Assembler at the next available location given by the current value of the
LC. If a particular boundary alignment is desired, we use a DC or DS statement with zero duplication factor, as well see in Section 13.2 on page 162.
We write these three constant types almost the same way we write character, hexadecimal, and
binary self-defining terms, but the limits on length and value are different. Self-defining terms are
restricted to the range between 231 and + 231 1 while much longer constants can be defined
with the DC instruction. 75 For example, you can define constants as shown in Figure 54.
CharCon DC
Digits DC
ManyBits DC

C This is a long character constant


X8462AFCB975310
B0010111011100011001111011010001011101001

Figure 54. Character, hexadecimal, and binary constants

Note that blanks can be used to separate groups of digits in hexadecimal and binary constants
(but not in self-defining terms!) to improve readability. Thus we could write
Digits DC
ManyBits DC

X84 62AF CB97 5310


B0010 1110 1110 0011 0011 1101 1010 0010 1110 1001

The data generated for character (type C) constants is converted to 8-bit bytes using the EBCDIC
representation shown in Table 13 on page 89. Blanks characters are part of the nominal value, of
course! The special rules concerning the apostrophe and ampersand in character self-defining
terms also apply to character constants: for each ampersand or apostrophe to appear in the generated constant, a pair of ampersands or apostrophes must appear in the nominal value between the
delimiting apostrophes. For example:
DC
DC
DC

C
C&&
C&&&&&&

Generates X 7D
Generates X 5 0
Generates X5050507D

In Section 7 we noted that the value of a character self-defining term is determined by rightadjusting the term in a 32-bit binary field. However, a character constant is generated by starting
at the left end of the character string, and encoding the necessary characters byte by byte. We
sometimes say that each byte of a C-type constant contains a character, but it is more precise to
say that it contains the 8-bit encoding used to represent the character internally.76
Unlike F- and H-type constants, the implied length of C-, B-, or X-type constants is not a fixed
number. Because no length modifier is present, the two constants
Star1
DC
and
Star2
DC

C *

Implied length = 1

C **

Implied length = 2

have implied lengths as shown. The Assembler determines the minimum number of bytes needed
to hold the nominal value of the constant, and assigns that as the implied length of a symbol
naming the constant.
This rule also applies to continued constants. For example, in

75
76

152

Remember: decimal self-defining terms are always nonnegative!


Character representations have many encodings: some are 8, 16, or 32 bits long, and others vary between 1 and 4
bytes! Well meet some of them in Section 26.
Assembler Language Programming for IBM z System Servers

Version 1.00

ManyChar DC

C An example of a very long string of characters intende*


d to illustrate the length attribute of a constant that *
extends over many lines.

the symbol ManyChar has length attribute 134; you certainly dont want to count the characters in
each line manually (and possibly make a mistake). Its much easier to use the Assemblers
Length Attribute, as in L ManyChar, and know its correct.
If we write a statement like
CharData DC

0C Characters

the zero duplication factor means that no data will be generated. (Well discuss this in Section
13.2.) However, the symbol CharData will have Length Attribute 10, the length of the nominal
value. This method of assigning a Length Attribute to a symbol without necessarily reserving
space is often useful.
We will see in Section 27 that the Assembler can generate character constants in other representations such as ASCII and Unicode.

Exercises
12.4.1.(1) + What are the implied lengths of the constants in Figure 54?
12.4.2.(2) How many input lines would be needed to write an Assembler Language statement
that defines a B-type constant with an implied length of 100 bytes?
12.4.3.(1) How can you specify multiple values in a single operand of a C-type constant?
12.4.4.(2) A four-byte area of memory contains the digit pattern X4040405C . What is represented by that pattern? (You should be able to describe two different possibilities.)
12.4.5.(2) Suppose you define the constant
DC

4C

What is its value if these 4 bytes are thought to represent a binary integer?
12.4.6.(1) + What is generated for these constants?
(1)
(2)
(3)

DC
DC
DC

B11110001
B000011111
X0123456

12.4.7.(2) What constants are generated from these statements:


C A B&&C
C A&&B C
C ABCF

1. DC
2. DC
3. DC

12.4.8.(1) + A programmer wanted to generate 16 bytes of EBCDIC characters representing the


16 possible values of a hexadecimal digit, and wrote
EBCHex

DC

X F0 , X F1 , X F2 , X F3 , X F4 , X F5 , X F6 , X F7 , X F8 , X *
F9 , X C1 , X C2 , X C3 , X C4 , X C5 , X C6

Can you save some effort for him, and write this in a simpler way?
12.4.9. What constants are generated by these statements? Explain any differences.

Chapter IV: Defining Constants and Storage Areas

153

A
B

DC
DC

5X 0
XL5 0

C
D

DC
DC

5X 7
XL5 7

E
F

DC
DC

5C
CL5

G
H

DC
DC

5C *
CL5 *

12.4.10. For each of the following sets of statements, the value of the Location Counter is
X000743 when the Assembler encounters the first statement. Give the value and length attributes of all symbols (but not the generated object code).
(1)

A
B

DC
DC

AL3(A)
A(8)

(2)

C
D

DC
DC

C DS C&&
C D DC C DC

12.4.11.(1) + The constant


DC

CL4345

generates which of these constants?


1.
2.
3.
4.

X00000345
X00000159
X F3F4F540
X00F3F4F5

12.5. Padding and Truncation


The Assembler must decide what to do if
1. a constant is too large to fully occupy the number of bytes allocated for it (whether an
explicit length modifier or the default length is used), so some (possibly significant) bits must
be truncated, or
2. a constant is too small, so the generated value must be padded to fit in the allotted space.
Some examples are given in Table 31, with the generated constants. Most of the padded constants could have been fit into smaller fields, if you needed desperately to save a few bytes.
Truncation
Value too large
Assembled Value
H65537
X0001 (with error!)
FL1+300

X 2C

CL3 SMITH

Padding
Value not too large
Assembled Value
H 2
X0002

(with error!)

FL3 -6

X FFFFFA

X E2D4C9 (C SMI )

CL3 S

X E24040

XL256789

X6789

X56789

X056789

BL1100100100

X 2 4 (B00100100)

B101

X 0 5 (B00000101)

AL2(X789AB )

X89AB

A(X789AB )

X000789AB

YL1(X124)

X 2 4

Y(X124)

X0124

Table 31. Examples of truncated and padded constants

154

Assembler Language Programming for IBM z System Servers

Version 1.00

For all of the constants on the left, some part of the value must be truncated to make it fit in the
allotted space, since there is an implied or explicit length in each case. For all these constant
types except C, excess information is dropped at the left end of the constant, and the rightmost
portion is assembled. For character constants, the excess is trimmed off the right end, as in the
CL3 SMITH example above, generating C SMI . Truncated F- and H-type constants are considered
errors by the Assembler.
For the constants on the right side of Table 31 on page 154, more space is allotted either explicitly or implicitly than is needed to hold the significant bits of the given constants. For types H
and F, the assembled value is simply the rightmost part of the twos complement representation
in which the sign bit has been extended to the left. In the character constant CL3 S , the single
letter S has been padded on the right with two EBCDIC blanks (with representation X 4 0 ) to
fill out the constant to the required length of three bytes, generating C S .77
As mentioned in Section 12.4 on page 152, no default length is assumed for constants of types C,
X, and B. In the absence of explicit lengths, the Assembler uses just enough bytes for the constant to ensure that no information is lost, and no more. Thus the lengths of the three constants
in Figure 54 on page 152 are 33, 7, and 5 bytes respectively; no information is lost, and no
padding was required.78
Table 32 summarizes some of the rules for writing operands in DC instructions. A complete set of
rules is given in the High Level Assembler Language Reference. (Well discuss V-type address constants in Chapter X.)
Type
Maximum Length
Implied Length
Implied Alignment
Value Specified by
Delimiters Used
Truncation, Padding
Multiple Values
Note: * The implied length

H
F
Y
A
V
B
8
8
2
4
4
256
2
4
2
4
4
*
2
4
2
4
4
none
dec
dec
absexpr expr
symbol bin


( )
( )
( )

left
left
left
left
left
left
yes
yes
yes
yes
yes
yes
is the minimum number of bytes required to contain

C
X
256
256
*
*
none
none
char
hex


right
left
no
yes
the data.

Table 32. Truncation/padding rules for some D C operands

Section 12.8 on page 159 shows some type extensions that let you write longer constants with
stricter default alignments.

Exercises
12.5.1.(2) + What will the Assembler generate for these two statements? Will the results be different? If so, why?
DC
DC

CL2 ABC
AL2(C ABC )

12.5.2.(2) + Show what will be assembled for each of the following DC statement operands:
(1) F1000, (2) H1000, (3) B1000, (4) XL11000, (5) CL11000, (6) AL1(1000),
(7) YL3(1000). Describe the boundary alignment of each.
12.5.3.(2) + What will be generated for these constants?

77
78

Remember that we use the character to represent a blank space.


I trust you completed Exercise 12.4.1 before reading this sentence!
Chapter IV: Defining Constants and Storage Areas

155

(1)
(2)
(3)
(4)

DC
DC
DC
DC

B011110001
B111100010
X01234
XL2012345

12.5.4.(2) The statement preceding Table 31 says that some of the constants can be fit into
smaller fields. Which ones cannot?

12.6. Literals
We often define data meant to be used only as a constant: it should not be modified during
program execution. In the sample program in Figure 35 on page 119, the two quantities in the
words named N and ONE are defined by DC instructions, but we expect the symbol ONE to mean
that the contents of that word retains the value + 1 throughout program execution. 79
Literals are a simple and convenient way to simultaneously define constants and refer to them. A
literal is a special kind of symbol: the contents of the storage area named by the literal is defined
by the symbol itself.
A literal is written as an equal sign (=) followed by characters conforming to the rules for a single
operand of a DC instruction. These are examples of literals:
=F 1
=H 1
=A(1)

=C LongLiteral
=CL7 BLANK&&
=F 1 , 2 , 3 , 4

=BL2111101
=X765432A
=AL3(5,X D7 / C . )

Literals may be used in most places where symbols are permitted, with the following exceptions:
1. The Assembler indicates an error if an instruction obviously tries to store into or otherwise
modify a constant defined by a literal: thus,
ST

7,=F 1

is invalid, even though its easy to modify constants created by the DC assembler instruction statement without any assembly-time indication. (This error detection at assembly time
is what makes literals more constant than the constants defined by DC statements.)
2. A literal may not be specified in an address constant, so that A(=F 1 ) is invalid.
3. Multiple operands may not be specified, but multiple values may; thus
LM

1,2,=F 1 , 2

is valid, but both


LM
L

1,2,=F 1 , = F 2
1,=H 1 , = H 2

are not, because a literal must be a single operand.


4. The duplication factor may not be zero.
5. The alignment and length of the data described in the literal are implied by the constant type,
so that this L instruction,
L

2,=X 2B

that copies 4 bytes from memory to GR2, will copy unpredictable data into the rightmost
three bytes of GR2 because we cant know precisely where the Assembler will place the
literal, and what might be in the three bytes following the single byte X 2B .

79

You can even write statements like


ONE

DC

F 1 3 7

but this wont make your program easier to understand; and its even more misleading if your program stores varying
values into the word area named ONE.

156

Assembler Language Programming for IBM z System Servers

Version 1.00

This statement is entirely equivalent to


L
2,X2B
- - DC
X 2B
- - -

X2B

(Not aligned!)
Three more (mystery) bytes

except that the symbol X2B is not needed when the literal =X 2B is used.
6. A reference to a literal is always a relocatable implied address (as defined in Section 9.5 on
page 111).
7. A literal may be indexed in RX-type instructions, so that
0,=F 1 , 2 , 3 , 4 , 5 ( 9 )

is valid, and is exactly equivalent to


L
0,FiveInts(9)
- - FiveInts DC
F 1 , 2 , 3 , 4 , 5
If the value of the index in GR9 is 8, the L instruction will put the integer 3 in GR0.
8. You may refer to a portion of a literal, as in
IC

0,=F1+3

but this is considered a very poor programming practice.


9. In most situations, you can use the Assemblers L Attribute Reference notation in an
address constant to refer to the Length Attribute of a literal. (Note that this does not violate
rule 2 above!)
LitLen

DC

A(L=C This is a message )

Generates X00000011

which is equivalent to
Message DC
MsgLen DC

C This is a message
A(L Message)

Named character constant


Length attribute of Message

Figure 55. Length attribute reference to two constants, one a literal

The message character string is 17 bytes long, but we rarely refer to the Length Attribute of
a literal.
Well make frequent use of symbol length attribute references in Chapters VII and VIII.
After reading this apparently long list of restrictions, you might think that literals are fairly useless.
We will see that they can be extremely helpful in writing clear and readable programs, and that
these restrictions make good sense.
To illustrate a typical use of a literal, you could rewrite the program segment in Figure 35 on
page 119:

BEGIN

BASR 6,0
USING BEGIN,6
L
2,N
A
2,=F 1
ST
2,N
--------DC
F 8

Here, you didnt need to define a constant and create a symbol ONE to refer to it.
As literals are encountered in scanning the source program, the Assembler forms a separate
internal table containing the literals, with duplicates eliminated. Eliminating duplicates saves space
and lets you use literals without generating duplicate constants. The constants from the Assemblers literal table are placed into the program at an appropriate location, and the Assembler then
Chapter IV: Defining Constants and Storage Areas

157

assigns addressing halfwords to instructions that reference the literals, just as it does for references
to symbols.
The area of the program where the Assembler deposits its collection of literal constants into your
program is sometimes called a literal pool.
Though the Assembler eliminates duplicate literals, those containing references to the Location
Counter, as in
L
L

2,=A(*)
3,=A(*)

are not eliminated, because Location Counter values may vary for each occurrence.
For the added ease of referring to constants using literals there is a corresponding loss in your
ability to specify exactly where the constant is located, since this is normally determined by the
Assembler. The LTORG instruction gives you some control.

Exercises
12.6.1.(2) What data is generated by the literal =AL3(5,X D7 / C . ) ?
12.6.2.(2) What data is generated by the literal =CL7 BLANK&& ?
12.6.3.(1) + Write and assemble a short program containing the statements
T

DC
DC

2A(*)
2A(*-T)

and examine the generated object code; describe the differences.


12.6.4.(2) + In Figure 55, the constant named Message is followed by the word-aligned A-type
constant named MsgLen. How many bytes might be skipped before the A-type constant?

12.7. The LTORG Assembler Instruction


The LTORG assembler instruction statement lets you control the placement of constants generated by literals. It may have a name-field entry, but no operand field entry. The Assembler aligns
the LC at the next doubleword boundary, 80 defines the name-field symbol (if any), and then
places its collection of literal-defined constants into the program. The order in which they appear
is determined by the Assembler; dont make any assumptions about ordering.
After dumping the contents of its literal table, the Assembler clears the table. Excessive use of
LTORG instructions in a program with many literals might cause duplicate constants to be
defined. For example,
L
0,=F 1
LTORG
L
1,=F 1
LTORG
will cause two identical constants to be generated.
The literals in the literal pool are generated in decreasing order of alignment. Thus, a word literal
like =F 4 will be generated ahead of a halfword literal like =H 2 . This rule applies not only to
literals with implied alignment, but to literals whose length is a power of two. Thus, the literal
=X00000004 will be generated in the same group as =F 4 .

80

158

Or quadword boundary, if the value of the SECTALGN option specifies an alignment stricter than doubleword. See
the High Level Assembler Programmer s Guide for further information.
Assembler Language Programming for IBM z System Servers

Version 1.00

This alignment difference can sometimes be surprising. These two constants, though identical, will
be aligned differently:
L
2,=FL4 4
L
2,FL4Const
- - DS
F,X
FL4Const DC
FL4 4

Explicit length 4, word aligned


Explicit length 4, not word aligned
Align LC off a word boundary
Unaligned constant X00000004

Though rarely a problem, its worth remembering the difference.


In the absence of any LTORG instructions, the Assembler will generate any accumulated literals
at the end of the assembly, so you will need to ensure they are addressable.
We will use literals in many places.
Remember:
A literal is treated by the Assembler as a special symbol with the additional effect of causing it to reserve a storage area containing the specified
constant.
While the Assembler tries to diagnose instructions appearing to modify a literal, its easy for your
program to modify them by writing into the area where theyre stored. (In fact, a program can
modify almost anything thats not memory-protected!) You should think of literals as intended
constants, not as immutable values.

12.8. Type Extensions


As the z System processors have evolved since System/360 was introduced in the mid-1960s,
many enhancements and additions have been made to the instruction set and the data types they
use.
An important enhancement with z/Architecture was the expansion of the 32-bit general registers
to 64 bits, as illustrated in Figure 9 on page 47. To support 64-bit data types, the Assembler
extended several existing data types to provide 64-bit constants. Among these are the F-, A-, V-,
and Q-type constants. This is done by adding a type extension letter following the constant type.
With a D type extension, these constants may be up to 8 bytes long, and by default are aligned
on doubleword boundaries. For example:
DC
DC
DC

FD -1
AD(C ABC )
FD U1E15

X FFFFFFFFFFFFFFFF
X0000000000C1C2C3
X00038D7EA4C68000

We will see many examples of these doubleword constants when we describe instructions using
the 64-bit general registers.
Other type extensions are used for character constants. Many other character representations are
now widely used, including ASCII and Unicode. Like EBCDIC, ASCII characters (defined with
type extension A) are one byte long, while the Unicode characters (with type extension U)
generated by HLASM are two bytes long. For example:
DC
DC
DC
DC

C ABC
CE ABC
CA ABC
CU ABC

X C1C2C3
X C1C2C3
X414243
X004100420043

EBCDIC by default
EBCDIC always
ASCII always
Unicode

Chapter IV: Defining Constants and Storage Areas

159

The E type extension means that the generated constant must use the EBCDIC representation
even if the Assemblers TRANSLATE option 81 requests translation of C-type constants to a different encoding. Well see more about specialized character sets in Section 27.
Other type extensions are used for floating-point data; well learn more about them in Chapter
IX.
Table 33 summarizes some rules for writing operands in DC instructions with operand type
extensions. A complete set of rules is given in the High Level Assembler Language Reference.
Type
Maximum length
Implied length

FD
8
8

AD
8
8

VD
8
8

QD
8
8

CA
256
*

CE
256
*

CU
256
*

Implied alignment
Value specified by
Delimiters used
Truncation, padding

8
dec

left

8
expr
( )
left

8
symbol
( )
left

8
symbol
( )
left

none
char

right

none
char

right

none
char

right

Multiple Values
yes
yes
yes
yes
no
no
no
Note: * The implied length is the minimum number of bytes required to contain the data.
Table 33. Truncation and padding rules for some D C operands with extended types

Terms and Definitions


address constant
A field into which a value is inserted by the Assembler, the Linker, or the Program Loader.
Typically, an address.
literal
A special symbol with the side effect of defining a constant referenced by that symbol.
literal pool
A set of literal-generated constants grouped together by the Assembler. A program may
contain multiple literal pools.
padding
Adding extra bits or bytes to a constant so that it will fill the space allotted to it.
truncation
Removing bits or bytes from a constant so that it will fit in the space allotted to it.
type extension
A second letter following the constant type, providing additional information about the constants length or representation.

81

160

See the High Level Assembler Programmer s Guide for details.


Assembler Language Programming for IBM z System Servers

Version 1.00

13. Data Storage Definition

11
111
1111
11
11
11
11
11
11
11
1111111111
1111111111

3333333333
333333333333
33
33
33
33
3333
3333
33
33
33
33
333333333333
3333333333

In this section we examine methods for defining data areas and data structures that simplify programs manipulating the data, and describe the useful assembler instruction statements DS, EQU,
and ORG.

13.1. Storage Areas: The DS Assembler Instruction


A storage area is often needed in a program that need not be initialized to contain a value, as
done by the DC instruction. This can be done with the DS (Define Storage) assembler instruction; it is almost identical to the DC instruction, except that no data is generated: space in the
program is allocated, but not initialized. The rules for writing the operand field entry are the same
for DC and DS, except that a nominal value (and its enclosing delimiters) is optional for DS.
Thus the statements
DS

Define word storage

DS

F 8

Define word storage

and
both cause the Assembler to reserve a four-byte area on a word boundary, but no constant is
assembled, even though a nominal value is specified in the second statement. Specifying a value
in a DS statement is useful in statements such as
DS

C Message

Define storage for characters

because it will reserve an area whose length is determined from the length of the nominal value (7
bytes, in this case). Large blocks of storage may be reserved:
FW100

DS

100F

Define storage for 100 words

This reserves 100 words and assigns the symbol FW100 to the location of the first. The statements
AREA1
AREA2

DS
DS

80C
CL80

both define storage areas 80 bytes long, but the Length Attributes of the symbols AREA1 and
AREA2 are 1 and 80 respectively, which may be very useful in a program. The length attribute of
the symbol AREA1 is 1 byte; the length of the area it names is the product of the duplication factor
(80) and the length attribute (1).
In the absence of either a constant or an explicit length for types B, C, and X,
Chapter IV: Defining Constants and Storage Areas

161

DS B

and

DS C

and

DS X

each assigns an implied length of one byte and reserves a single byte.

Exercises
13.1.1.(2) Suppose the value of the Location Counter is X012345 when the following three
statements are read by the Assembler:
X
Y
Z

DS
DS
DS

AL(4)
A(4)
AL4

What is generated by these statements? What are the value and Length Attributes of the
symbols X, Y, and Z?

13.2. Zero Duplication Factor


A zero duplication factor may be specified for operands of DS and DC instructions. First,
boundary alignment implied by the storage type is performed if necessary. If a name field symbol
is present, the aligned value of the LC is assigned as its value; the symbols Length Attribute is
determined from the operand. No space is reserved. Thus a DS or DC instruction with a zero
duplication factor can be used to force boundary alignment.
For example, the two sets of statements
WORD

DS
DC

0F
C WORD

DS
DC

0F
C WORD

and
WORD

both serve to define a four-byte character constant on a word boundary named by the symbol
WORD which would not in general have been the case if
WORD

DC

C WORD

WORD

DC

CL4 WORD

or
had been specified.
If a zero duplication factor is used in a DC instruction, it behaves just as would the corresponding
DS instruction. However, when bytes are skipped to perform alignments required by DS statements, the Assembler does not put zeros into the skipped bytes, while skipped bytes are zeroed
when aligning DC instructions if the preceding statement generated instructions or data.
Because constants with zero duplication factors do not advance the Location Counter (except for
possible boundary alignment), they have many uses. For example, suppose we must define a
storage area to hold a (U.S.) ten-digit telephone number:
PhoneNum
AreaCode
Prefix
Local_No

DS
DS
DS
DS

0CL10
CL3
CL3
CL4

Define 10-byte area for full number


Space for area code
Space for prefix
Space for local number

Figure 56. Describing fields of a (U.S.) telephone number

This way we can refer to the entire field using the symbol PhoneNum, or to each component by its
name.
Suppose we are writing a program that scans Assembler Language statements, and we want to
give names to the fields of the statement. Well assume that

162

Assembler Language Programming for IBM z System Servers

Version 1.00

1. name-field symbols begin in column 1,


2. mnemonics start in column 10 and are 5 or fewer characters long,82
3. operands start in column 16 and are less than 20 characters long,
4. remarks lie within columns 36 and 71,
5. column 72 is the continuation column, and
6. columns 73-80 contain sequencing data.
Then, we can name each of the fields of an 80-byte area named Statemnt that contains the statement and assign appropriate Length Attributes, as shown in Figure 57.
Statemnt DS
Name
DS
DS
Mnemonic DS
Mnemopnd DS
DS
Operand DS
DS
Comment DS
Continue DS
Sequence DS

0CL80
0CL8
CL9
0CL5
0CL25
CL6
0CL19
CL20
CL36
C
CL8

Define 80-column record area


Define name-field symbol
Reserve space for name-field symbol + blank
Define 5-character mnemonic field
Define both mnemonic and operands
Reserve space for mnemonic + blank
Define 19-character operand field
Reserve space for operand field + blank
Allocate 36 columns for comments
Define continuation-indicator column
Define sequencing columns

Figure 57. Describing fields of an Assembler Language statement

The first DS statement defines Statemnt to be 80 characters long, but reserves no space.
Similarly, the second DS defines an 8-byte Name field beginning at the same location.
The third DS then causes the Location Counter to be incremented by 9 bytes, so that the
symbol Mnemonic has a value corresponding to column 10 of the record.
Because we might refer to the mnemonic and the operands together, the symbol Mnemopnd has
the same location, but its length of 25 bytes includes both fields.
The rest of the definitions are similar.
We make this (apparently additional) effort because a program containing these declarations can
now refer to the desired fields by name. For example, we can use the symbol Operand instead of
the expression Statemnt+15 to refer to the start of the operand field. While this may not seem an
important difference, consider what modifications would have to be made to the program if the
Mnemonic field is changed to be six characters long: every statement in the program containing a
reference to expressions like Statemnt+15 would have to be found and changed.
By using this technique, only the DS statements need changing before the program is reassembled; the statements referring to the various fields in our Assembler Language statement need
not be changed. Another big advantage of this style of definition is that the symbols have useful
Length Attributes; we will see in Chapters VII and VIII how instructions can make good use of
that information.
As another example, suppose we wish to reserve space for three words that are also regarded as a
single group of twelve bytes named FWGroup. We can do this with these statements:
DS
FWGroup DS
DS

0F
0XL(3*4)
3F

Align to word boundary


Define start of 3-word group
Reserve space for the three words

Figure 58. Define a group of words

82

But: many newer mnemonics can be as many as 8 (or more!) characters long, so you may want to adjust your
column positions appropriately. Similarly, the names of some macro-instructions we use (like PRINTOUT) are at most 8
characters long.
Chapter IV: Defining Constants and Storage Areas

163

Exercises
13.2.1.(2) Assemble the statement in Figure 57 to verify the locations and lengths of each field.
(Remember to add an END statement.)
13.2.2.(3) + Assume the Assemblers Location Counter is X345 when it reads each of the following sets of statements. For each symbol, give its value and Length Attribute.
J
K
L

DS
DS
DS

3H
1X
0F

P
Q
R

DC
DC
DC

C A B
2C ABA
2A(C . )

T
V
W

DS
DC
DC

XL2234567
4Y(37)
0F 1 , 2

13.2.3.(2) + For each of the following, assume that the Location Counter value is X345 when
the initial statement is processed by the Assembler. Give the value and Length Attributes of the
symbol A.
1. A

DC

F 2

2.
A

DS
DC
DC

0H
C *
C Asterisk

DC
DC

0F 1
0XL27 0

4. A

DC

A(A)

5.
A

DS
DC

19H
X12345

DC
DC

3CL4 ABCDE
C A&&B

DS
DC

CL400
F12,34,56

3.

6.
7.

13.3. The EQU Assembler Instruction


Two other assembler instruction statements are often useful in defining and describing data areas,
EQU and ORG. When we write
symbol

Equ

expression

the Assembler assigns the attributes of the expression in the operand field (including value, relocatability, and length) to the symbol in the name field.
The EQU instruction reserves no storage and generates no data or machine language; it only
defines a symbol by assigning it an assembly-time value. EQU is a powerful tool for simplifying
and understanding programs.
Suppose a program needs a storage area of 75 words, and a word integer constant whose value
gives the number of words reserved. The two statements

164

Assembler Language Programming for IBM z System Servers

Version 1.00

NItems
Table

F 7 5
75F

DC
DS

Number of words
Table of words

define the necessary items. However, if we decide to change the table size, both statements must
be changed before re-assembling the program. If we had written instead
TblSiz
NItems
Table

Equ
DC
DS

75
A(TblSiz)
(TblSiz)F

Define table size


Number of words
Table of words.

then only the EQU statement would have to be modified before re-assembling. If we also want to
refer to the word in the middle of the table, we can write
MidTbl

Equ

Table+(TblSiz/2)*4

where the factor 4 is the length of each table entry. This illustrates using EQU to define a relocatable symbol.
A better programming practice is to use the length attribute of Table as in L Table, instead of 4.
Here is why: Suppose we can save space in the program by defining halfword table entries
instead of words. If we define the symbol Table as
Table

DS

(TblSiz)H

Table of halfwords.

the position of the new tables middle item will still be determined correctly, because the length
attribute of Table is now 2 instead of 4.
You cannot use EQU instructions to assign more than one value to a symbol. 83 For example, the
second statement in this example is invalid:
X

Equ 5
- - Equ 10

Define X
Invalid duplicate definition

Exercises
13.3.1.(1) + Why is the Length Attribute of the symbol MidTbl equal to 4?
13.3.2.(2) A programmer wished to conserve space in his program. He needed both a halfword
and a fullword binary constant of value +8. He wrote the statements
FW8
HW8

DC
Equ

F 8
FW8+2

and referred to the halfword value with the symbol HW8. Can you think of any circumstances in
which this might be unsafe?
13.3.3.(2) Suppose the definition of the symbol Midtbl had been written in the following forms:
MidTbl
MidTbl
MidTbl
MidTbl

Equ
Equ
Equ
Equ

Table+TblSiz*4/2
Table+4*TblSiz/2
Table+TblSiz/2*4
Table+(TblSiz/2)*4

Are these equivalent? Why and why not? Why would you choose one in preference to the
others?
13.3.4.(2) Describe the differences among the following statements. (It may help to assemble
them!) (See Exercise 11.7.1 also.)

83

Some very early assemblers let you use multiple EQU statements to change the value assigned to a symbol. For
z System assemblers, the values of ordinary symbols are not changed at assembly time. Symbols whose values may
be re-assigned at assembly time are called variable symbols; they are used in conditional assembly and macros.
Chapter IV: Defining Constants and Storage Areas

165

A1
A2
A3
A4
A5

Equ
DC
Equ
Equ
Equ

5
F 5
A2
=F 5
A1

13.3.5.(2) An EQU statement like


NFS

Equ

135

is sometimes described by saying (a) it assigns a constant to NFS, (b) it assigns an assembly-time
constant to NFS, or (c) it assigns the name NFS to a constant. Which of these descriptions is
preferable, and why? What would be a better one?
13.3.6.(3) What would you expect to happen when the Assembler encounters the following
three statements?
A
B
C

Equ
Equ
Equ

B
C
A

13.3.7.(2) What would you expect to happen when the Assembler processes each of the following pairs of statements?
ABLE
BAKER

Equ
Equ

2
ABLE+2

BAKER
ABLE

Equ
Equ

ABLE+2
2

13.3.8.(2) + For each of the following two sets of statements, assume that the Location Counter
value is X01DBC5 when the first statement is encountered. Determine the value, relocatability,
and Length Attributes of all symbols.
1. ST
W
X

DS
DS
DS

0CL8
2F
2F

2. P
Q
R
S

DS
DS
DC
Equ

0F
0H
4X 0
*

13.3.9.(5) Suppose the symbols A and B have absolute values, and were defined by complicated
expressions whose values are not immediately evident. Write a set of EQU statements that will
set the value of the symbol MaxOfA_B to the greater of A and B, or to either if they are equal.
13.3.10.(2) Suppose the symbol A has value X291B in each of these sequences of statements.
Give the value and Length Attribute of the symbol B.

166

1. A
X
B

Equ
DS
DS

*
3H
0F

2. A
B

Equ
DC

*
CL3 Okay

3. A
F
X
B

Equ
DC
DC
Equ

*
F11,22
X123
X-A

Assembler Language Programming for IBM z System Servers

Version 1.00

13.3.11.(3) + In each of the following sets of statements, give the value and Length Attribute of
each symbol, assuming that the Location Counter value is X12345 when the first statement of
each set is read by the Assembler.
1. A
B
C

DS
DS
DS

F
2H
2CL2

2. F
G
H

DC
DC
DC

A(F)
3AL3(F,G,H)
Y(*-F,275)

3. P
Q
R

DC
DC
DS

2C3&&
2A(C3&&)
3XL3 FEDCBA93

4. X
Y
Z

DC
DC
DC

0FL55,10,20
FL35,10,20
2C5,10,20

13.3.12.(3) Assuming the same statements as in the previous exercise, show the hex data values
assembled for the constants having these names: F, G, H, P, Q, and Y.
13.3.13.(2) + In each of the following sets of statements, give the value and Length Attribute of
each symbol, assuming that the Location Counter value is X01DBC5 when the first statement
of each set is read by the Assembler.
1. STR
W
X

DS
DS
DS

0CL8
2F
2F

2. P
Q
R
S

DS
DS
DC
EQU

0F
0H
4X 4 0
*-P

13.3.14.(3) + For each of the following sequences of statements, assume that the value of the
LC is X125 when the first statement is encountered. For each sequence, give the value and
Length Attributes of all symbols, the assembled machine language constants (in hex) and their
locations, and the LC value after the last statement in the sequence.
1.

A
B

DC
DC

F -17
H 3 3

2.

D
C

DC
DC

FL4+17
H -33

3.

E
F

DC
DC

C ABCDEFGH
F1000

4.

G
H

DS
DC

2H
A(X129E )

5.

J
K
L
M
N

DS
DS
DS
DC
DC

0H
0X
0F
0FL6 1 5
F -1000

6.

P
Q

DC
DC

3C A B
2A(C A B )

7.

R
S

DS
DS

100F
10CL80

8.

AB

DC

F 9 0 0 , HL52147483650,H 1
Chapter IV: Defining Constants and Storage Areas

167

9.

BC
CD

DC
DC

3XL2 7 , 0 CL3 ABCD , B 1


H16383,H -16383

10.

DE
EF

DS
Equ

2F,0D,2CL6
*,L DE

11.

T
V
W

DC
DC
DC

X CAB
2B101011100
(V-T)CL(W-T+2) CAB

12.

Y
X

DS
DC

H
(X-Y)AL(X-Y)(X-Y)

13.

Z
ZZ

DC
DC

CL2 ZZ
(ZZ-Z)A(ZZ-Z)

13.3.15.(2) + You are given a number N in the range 0 N 14 and you must use it to
assign a pair of symbols REven and ROdd to an even-odd pair of 32-bit general registers, respectively. Write EQU statements to assign the symbols.
13.3.16.(3) In Exercise 13.3.14, some expressions may be difficult for an Assembler to resolve.
Which do you think they are, and why?

13.4. EQU Instruction Extended Syntax (*)


HLASM supports an Extended EQU Syntax, allowing you to specify up to five operands.
symbol

Equ

expression1,expression2,expression3,expression4,keyword

which we understand to mean


symbol

Equ

value,length,type,program-attribute,assembler-attribute

We have been using only the first operand, expression1. The second and third operands let you
override default values for the length and type attributes.
length (expression2)
Assigns a new Length Attribute to symbol, overriding the Length Attribute assigned from
expression1.
type (expression3)
Assigns a type attribute to symbol. If no type operand is present, the Assembler assigns
type U (Unknown)
program-attribute (expression4)
Assigns a programmer-defined Program Attribute to symbol.
assembler-attribute (keyword)
A four-character Assembler-defined keyword providing additional information about the
expected behavior of symbol.
The High Level Assembler Language Reference describes the operands in detail. (The last three
operands are used mainly for conditional assembly, so we wont discuss them further here.)
The most common use of the Extended EQU statement is to assign specific Length Attributes to
symbols. For example, you could write
InRec DS
OutRec Equ

XL80
*,L InRec

Length attribute = 80

that defines the location of OutRec and its Length Attribute, even though the Length Attribute of
the Location Counter Reference * would otherwise default to 1 in an EQU statement.

168

Assembler Language Programming for IBM z System Servers

Version 1.00

Exercises
13.4.1.(2) + Assuming that the symbol Result is at location X2000, give the value and Length
Attributes of each symbol.
Result
Pfx
Prod
Cost
Desc
Fill
LFill

DS
Equ
Equ
Equ
Equ
Equ
Equ

XL133
Result,24
Pfx+L Pfx,12
Prod+L Prod,8
Cost+L Cost,60
Desc+L Desc,(L Result-L Pfx-L Prod-L Cost-L Desc)
L Fill

13.5. The ORG Assembler Instruction


The ORG instruction lets you modify the Location Counter. Like EQU, it generates no
instructions or data. The statement
ORG

expression

sets the LC to the value of the expression in the operand field of the statement. The relocatability
attribute of the expression must match that of the LC.
We can use the ORG statement to rewrite the data area described in Figure 57 on page 163, as in
Figure 59. Note that none of the DS statements uses a zero duplication factor.
Statemnt DS
ORG
Name
DS
ORG
Mnemonic DS
ORG
Mnemopnd DS
ORG
Operand DS
ORG
Comment DS
Continue DS
Sequence DS

CL80
Statemnt
CL8
Name+9
CL5
Mnemonic
CL25
Mnemonic+6
CL19
Statemnt+35
CL36
C
CL8

Define 80-column record area


Reset to start
Define name-field symbol
Move to column 10
Define 5-character mnemonic field
Back up the LC
Define both mnemonic and operands
Move back to column 16
Define 19-character operand field
Move forward to column 36
Allocate 36 columns for comments
Define continuation column
Define sequencing columns

Figure 59. Describing fields of an Assembler Language statement using O R G instructions

After these statements have been processed, the LC will have the value of the expression
Statemnt+80, and we can continue assembling as though the LC had never been adjusted by the
ORG statements.
Now, suppose we want to check for possible comment statements by defining Column1 as a new
field, so we add the statements
ORG
Column1 DS

Statemnt
CL1

Back to column 1
To check for asterisks

at the end of Figure 59. Any statements following the last statement in the figure would begin
assembling at Statemnt+1, which is undoubtedly not what you intended.
To rectify such a mistake, you can do either of two things. First, you could place the statement
ORG

Statemnt+80

Move LC to end of Statement field

after all the other statements. A second way is to write


Chapter IV: Defining Constants and Storage Areas

169

ORG

Set LC to its highest value

The Assembler interprets the missing, or null, operand (indicated by the comma) to mean that the
LC should be set to the highest value it has attained so far in the assembly.
This example assumes that Statemnt+80 is the highest location at this point in the assembly; if
not, other instructions and data might be assembled in the wrong places. This possible error is
one reason why the technique shown in Figure 57 on page 163 is generally preferred.
The ORG instruction also supports an extended form:
ORG

expression,boundary,offset

The Assembler first sets the LC to the location given by expression, then rounds it up to the
next higher boundary (it must be a power of two between 2 and 4096), and then adds the value
of offset to determine the final LC setting. For example, suppose the current value of the LC is
X12345. If we write
ORG

*+4,8,-3

the Assembler first adjusts the LC to X12349, then rounds it up to the next doubleword
boundary X12350, and finally subtracts 3, setting the LC value to X1234D .
In practice, ORG statements are used infrequently. Their usual applications are to construct data
areas that share storage or overlay one another, as in Figure 59 on page 169.84

Exercises
13.5.1.(2) The programmer mentioned in Exercise 13.3.2 wanted to be as cautious as possible,
and changed his constant definitions to
FW8
HW8

DC
ORG
DS

F 8
FW8+2
H

Is this better than the technique used in Exercise 13.3.2? Why or why not?
13.5.2.(2) A programmer didnt know about using a null operand in an ORG statement to reset
the LC to its highest value. In trying to do this, he observed that * represents the value of the
LC, and therefore wrote
Here

Equ *
ORG AnyWhere
- - Equ Here

Assemble somewhere elsewhere


Set LC back to Here

What is wrong with this technique? Solve his problem without using an ORG statement with a
null operand.
13.5.3.(3) + In each of the three following code segments, the symbol A has value X982E .
Determine the value and Length Attributes of the symbol B.
A
B

DS
Equ

29H
A+L A

DS
ORG
DS

7CL5
A+10
2D

84

170

In higher-level languages, the overlaying of one data definition on another is sometimes called a union or a
redefinition.
Assembler Language Programming for IBM z System Servers

Version 1.00

DC
DS
DS

0CL40 *
5CL8,3CL3
3F

13.5.4.(3) With the same assumptions as in Exercise 13.5.3, determine the value, length, and
relocatability attributes of the symbol B.
A

B
A

DC
ORG
DC
ORG
DC

FL7 8
A+2
HL7 8

Equ
ORG
DS
Equ

*
A+4*L A
(C * ) CL(C * ) *
*

HL5 -8

13.5.5.(3) Using suitable DC and ORG statements, find a way to cause the Assembler to assign
the location of some skipped bytes as the value of a symbol SKIP3. For example, three bytes
are skipped in
DC

F 1 , X 2 , F 3

13.5.6.(2) Suppose a programmer wrote the statement


ORG

Set LC to its highest value

without a comma to separate the operation and comment fields. What do you expect will
happen? Why?
13.5.7.(3) In the code sequences illustrated in Figures 57 and 59, suppose you placed the statement
StmtLen Equ

*-Statemnt

following the last statement (with name-field symbol Sequence). What value is assigned to the
symbol StmtLen? What value should be assigned to StmtLen?
A bonus question: how could you induce the Assembler to detect the difference between the
actual and desired values assigned to StmtLen?

13.6. Parameterization
We have seen how we use EQU statements to define quantities such as table sizes, string lengths,
and duplication factors; these quantities are assembly-time constants, so they are not part of the
data whose values may be changed at execution time. The following examples illustrate this.
1. EQU is often used to set a value for defining several storage areas. For example, if you need
to process multiple records having the same length, you could define
RecLen
InRec

Equ 80
DS
CL(RecLen)
- - OutRec DS
CL(RecLen)
- - WorkRec DS
CL(RecLen)

Define record length


Space for input record
Space for output record
Space for record work area

Then, if the length of the record areas must be changed, you need to modify only the EQU
statement and reassemble the program.
2. Suppose a table of five words is stored starting at FTable, and we need to copy the last word
of the table into general register 5. We could do this by writing
L

5,FTable+16

Get last word of FTable

Chapter IV: Defining Constants and Storage Areas

171

but we have mixed the data definition (the fact that the word at FTable+16 is indeed the last
in the table!) with the processing of the data by the L instruction. The +16 term is a
hidden data description.
This program fragment will be easier to understand and modify if we write something like the
following:
NWords

Equ 5
Number of words in Table
L
5,LastWord
Get last word of Table
- - FTable DS
(NWords)F
Define name and space for Table
LastWord Equ FTable+(NWords-1)*4
Define last word
We can now change the length of the table by modifying the EQU statement, without
changing the instructions that reference the data. There was nothing in the expression
FTable+16 clearly relating it to the number of words in the table. Indeed, if the number of
words in the table is less than five, FTable+16 refers to data beyond the end of the table!
3. In Figure 58 on page 163, we might need to change the number of words in the group
named FGroup. By defining a symbol NWords giving the number of words, we can rewrite the
example:
NWords
FGroup
Words

Equ
DS
DS
DS

5
0F
0XL(4*NWords)
(NWords)F

Five-word group this time


Align to word
Length of group
Reserve space for Words

4. Suppose we want to define a table containing a number of character strings, all of the same
length. Suppose also that our program processes these strings, without knowing in advance
either how many there will be or how long they will be. Let NST and STL be symbols whose
values specify respectively the number of strings and the length of each. Then we can reserve
storage space for the data with the statement
Strgs

DS

(NST)CL(STL)

NST strings each of length STL

Then, if we need the addresses of the first and last strings in the block of data, we can define
the constants
AFirst
ALast

DC
DC

A(Strgs)
A(Strgs+STL*(NST-1))

Address of first string


Address of last string

Similarly, if we need halfword integer constants containing the length of each string and the
number of strings, we can define these Y-type address constants:
HWStL
HWNSt

DC
DC

Y(STL)
Y(NST)

Length of a string
Number of character strings

Having written the program to make all its references to the data counts and lengths through
these constants, we can finally assign values to the symbols NST and STL by defining two
EQU statements:
NST
STL

Equ
Equ

219
43

Number of data strings


Length of a data string

As a final example of symbolically-defined data areas, suppose we have written our own Assembler, and have a routine which prints symbol-table information at the end of an assembly. Each
line to be printed contains (1) a single carriage-control character to control vertical printer
spacing, (2) a symbol up to 8 characters long, (3) a 4-character field for the symbols length attribute, (4) a 2-character relocatability attribute field, (5) a 4 or 5-character field for the number of
the statement in which the symbol was defined, and (6) the rest of the line contains 4 or
5-character fields giving the numbers of the statements whose operand fields refer to the symbol.
The fields are to be separated by spaces. In addition, we are to write the definition of the print
line so it will work with printers that accept 121 or 133 characters (both are common print-line
lengths).
First, we will define the symbols LineLen to give the line length (121 or 133), and StNoLen to give
the number of characters needed to print a statement number (4 or 5). Then, space is reserved for

172

Assembler Language Programming for IBM z System Servers

Version 1.00

the fixed parts of the line. Finally, we divide the amount of space remaining in the line by the
width needed for each reference entry, to determine the number of entries that will fit.
LineLen
StNoLen
*
StLine
StCC
StSymb
StLenAt
StRA
StDefn
*
NXrefs
*
StRefs

EQU
EQU

133
4

Assume 133-character print line


Assume 4-character statement numbers

DS
0CL(LineLen) Start of line
DS
C
Carriage control character
DS
CL8,C
Symbol and trailing space
DS
CL4,C
Length attribute and a space
DS
CL2,C
Relocatability attribute and a space
DS
CL(StNoLen),C Space for defining statement number
Number of entries that will fit on rest of line
EQU ((StLine+LineLen-*)/(StNoLen+1))
Define space for references on rest of line
DS
(NXrefs)CL(StNoLen+1) That s all

Figure 60. Describing an Assembler symbol cross-reference listing line

The program that uses this print line definition will probably need a constant containing the
number of cross-reference entries in the line, so we should also define a constant like
MaxRefs DS

Y(NXrefs)

Maximum number of references

to be used while the line is being formatted by the program.


This symbolic technique is important for several reasons.
1. The dependence of individual instructions and constants on the number and length of the
data items is more evident when we examine them.
2. If any change must be made to such EQU-dependent quantities, only one statement the
defining EQU statement needs to be changed, and the Assembler will re-calculate all the
other quantities depending on it.
3. Statements using the EQU-defined symbols will appear in the Assemblers symbol crossreference listing.
Experience shows that
Programs are simpler when the definition of data objects is cleanly separated from the instructions that manipulate those objects.

Exercises
13.6.1.(2) Suppose the example above that defines the group of words named FGroup was
written
NWords Equ
FGroup DS
LastWord DS

5
(NWords-1)F
F

Five-word group this time


Space for group
Reserve space for LastWord

Determine if this definition gives the same or different results.

13.7. Constants Depending on the Location Counter


We often define address constants with the name of a data item, particularly when we need to
provide that address to another program, as in
DC

A(MyData)

Address of MyData

While its rare to need the address of a position in a program, as in

Chapter IV: Defining Constants and Storage Areas

173

DC

A(*)

This address

we often need the offset of one part of a program relative to another. For example, sometimes it
is useful to define constants whose values depend on one another in some regular way. For
example, suppose we need a table of 32 bytes containing the binary values 31, 30, 29, ..., 2, 1, 0.
We can define the table with an A-type constant:
DownTbl DC

32AL1(DownTbl+31-*)

When the first byte is to be generated, * has the same value as the symbol DownTbl, so the
expression in the constant has value 31. The Assembler does not generate 32 copies of this constant: when a Location Counter Reference appears in an expression in the nominal value of
A-type and Y-type constants, the expression is re-evaluated before generating each constant.
As each byte is generated, the value of * increases by 1 because the explicit length modifier specifies length 1. Thus the last (32nd) byte will be at DownTbl+31, and the expression will evaluate to
0 as desired.
As another example, suppose we want to build a table of halfword binary integers containing the
squares of the integers from 1 to 40. We can write
Sqrs

DC

40Y((*-Sqrs+2)*(*-Sqrs+2)/4)

where the division by 4 is needed because halfword constants are being generated, so each
Location Counter Reference * increases by 2 for each constant generated.
We will find other uses for LC-dependent constants when we discuss data structures in Chapter
XI.

Exercises
13.7.1.(3) The Assembler lets you specify an Exponent Modifier for some types of constant, as
described in Section 11.8. It is written with the letter E and the value of the modifier immediately preceding the delimiter before the nominal value of the constant. It specifies a power of
ten multiplying the nominal value of the constant.
Suppose you want to generate a table of the first ten powers of 10 (starting at 10 0) and you
write the statements
POWERS

DS
DC

0F
10FE((*-POWERS)/4) 1

What do you think will happen? Can the Assembler generate the desired constants? If not,
what would have to be done to make the Assembler do what you want?
13.7.2.(3) + Assume the Assemblers Location Counter is X12345 when it reads each of the
following sets of statements. For each of the five symbols, give its value and Length Attribute,
and show the generated constants (omitting any initial zero bytes inserted by the Assembler for
alignment).
A
B

C
D
E
F

DC
DC
DS
DC
DC
DC
Equ
DC

C U&&I
A(*)
0XL7C
H137
(B 1 0 ) AL(B 1 0 ) ( B 1 0 )
C A( ) , A(C )
*
2Y(*-F)

13.7.3.(2) Analyze the DC statement named Sqrs above to determine how it correctly generates
a table of squares. Then, write a short program to assemble the statement.
13.7.4.(3) Suppose you want to create a table of 256 bytes in which each byte contains the
number of 1-bits in the number representing the bytes offset from the start of the table. For

174

Assembler Language Programming for IBM z System Servers

Version 1.00

example, the byte at offset 19 should contain 3, the number of 1-bits in B10011. Consider the
following:
T

DC

256AL1(*-T-(*-T)/2-(*-T)/4-(*-T)/8-(*-T)/16-(*-T)/32-(*-X
T)/64-(*-T)/128)

Assemble the statement and verify that it generates the correct values. Then, explain why they
are correct.

13.8. Assembly Time and Execution Time, Revisited (*)


We will soon investigate many z System instructions that manipulate data, so it is worth
reviewing some concepts relating assembly and execution times. Suppose we have an area of a
program
area of program

that will eventually contain some data. At assembly time, we give the area a name,
area of program
name of area

 FDATA

and the Assembler assigns a location.


area of program
name of area

assembly
 FDATA
time

location


12468

We might also specify a bit pattern for the initial contents of the area.
area of program
name of area

 FDATA
assembly

time


location

contents


12468
DC F12

The name of the area has attributes such as value, length, and relocatability, all of which are distinct from the value we assign to the bit pattern that is the contents of the area.
area of program
name of area

 FDATA
assembly

time



location

contents

attributes of name



12468
DC F12
length, val, reloc

Chapter IV: Defining Constants and Storage Areas

175

When the program is executed, this assembly-time information is gone. During loading by the
Program Loader, the area of the program is assigned an address in memory. Its contents may
have changed as the program is executed.
executiontime
execution-time
address
contents of memory

9470A0 X4040405C

The value of the contents of the area now depends on the context in which it is used. The
contents might be treated as instructions, as data of various types, or as commands to be obeyed
by an input-output device. The interpretation of the bit pattern depends only on how those bits
are used, and is not inherent in the bits themselves, nor in any characteristics you assigned to
them at assembly time. In this example, the contents of the area of memory may be validly interpreted as (1) an instruction, (2) a word binary integer, (3) a floating-point number, (4) a 9-digit
packed decimal number, (5) a character string, and (6) a four-byte bit pattern, among others!
Ideally, the execution-time interpretation of the bit pattern will be the same as the assembly-time
interpretation. Instructions will be interpreted only as instructions and not as data, character
strings will be used as character strings and not as floating-point numbers, and so on. Assembler
Language programming does not always achieve this ideal in practice; but it also gives you much
more flexibility.85

13.9. Summary Observations


As mentioned in the footnote on page 139, the name of the assembler instruction Define
Constant can be misleading, because the generated machine language data may not be constant
during the execution of your program. And even if you intended the data to remain constant,
your program may accidentally change its value. (Review the example in Figure 42 on page 124!)
In fact, you can define a constant that is actually a machine instruction. For example, if the
data generated by the statement
DC

X 1 A22

is executed as an instruction, it will add the contents of GR2 to itself.


Another source of confusion may be the fact that you can specify a nominal value in a DS statement, as in
NoData

DS

C This won t generate any machine language data

There are other contexts where DC statements generate no machine language data, such as
Dummy Control Sections (DSECTs) and Common (COM) sections that well discuss in
Chapter XI.
There are also potentially misleading names for machine instructions. For example the MVC
instructions name is Move Characters, but its operation actually copies bytes that may or not
be character data.
In summary: dont take the names of Assembler and machine instructions too literally. Follow
the old advice to Watch what they do, not what they say.

85

176

Some say Assembler Language gives you more rope you can use to hang yourself, but thats part of what makes
Assembler Language programming fun.
Assembler Language Programming for IBM z System Servers

Version 1.00

Terms and Definitions


zero duplication factor
A duplication factor that causes LC alignment without generating a constant. Skipped bytes
are zeroed for DC instructions if the immediately preceding byte contains object code.
EQU Extended Syntax
Additional operands on EQU instructions that provide additional information about the
attributes of the symbol defined by the EQU statement.
ORG Extended Syntax
Additional operands on ORG statements that allow LC alignment to a specific power-of-two
boundary, and an offset from that position.
parameterization
A valuable technique for adding flexibility and generality to program definitions, typically by
defining assembly-time constants in EQU statements.

Programming Problems
Problem 13.1.(2) + Write a program to assemble the DC statements in Section 13.7 on page
173, and verify that the expected constants are generated.
Problem 13.2.(1) + Write a program in which you define this set of four four-byte binary integers:
Ints

DC

F -1046306171,-1803381883,-1723823710,1082565781

Then, define a 16-byte character string named Chars occupying the same storage as the four
integers. Then, display the 16 bytes of the character string as EBCDIC characters.

Chapter IV: Defining Constants and Storage Areas

177

178

Assembler Language Programming for IBM z System Servers

Version 1.00

Chapter V: Basic Instructions

VV
VV
VV
VV
VV
VV
VV
VV
VV
VV
VV
VV
VV
VV
VV
VV
VV
VV
VV VV
VVVV
VV

The six sections of this chapter treat instructions basic to almost all Assembler Language programs.
Section 14 discusses typical instructions that move data between memory and the general registers, and among the general registers. (Well explore instructions that use data in the FloatingPoint Registers in Chapter IX.)
Section 15 describes the important Branch on Condition instructions that let you make decisions about alternate execution paths in your program.
Section 16 introduces the instructions that perform binary addition, subtraction, and comparison using signed and unsigned binary integer operands.
Section 17 examines instructions that shift binary numbers in the general registers.
Section 18 continues our investigation of binary arithmetic operations, examining instructions
that multiply and divide numbers in the general registers.
Section 19 describes instructions performing the logical operations AND, OR, and Exclusive
OR on bits in the general registers.
The instructions in this chapter operate on binary data in the general registers, except those in
Section 15, which do not involve data.
A comment on terminology: we have used terms like halfword and word (or fullword) to
mean data items 2 bytes or 4 bytes long. This has been common usage for many years. However,
the z/Architecture Principles of Operation uses these terms much more precisely: a halfword must
be aligned on a 2-byte boundary, and a word must be aligned on a 4-byte boundary, and similarly
for doublewords and quadwords. Please understand that we may use terms like word and
halfword inexactly.86 Very few instructions require strict alignment of their operands; we will
point out those instructions that do require operand alignment.

86

Correct alignment is always a recommended practice, so our less-than-precise usage isnt usually harmful.
Chapter V: Basic Instructions

179

14. General Register Data Transmission

11
44
111
444
1111
4444
11
44 44
11
44 44
11
44 44
11
44444444444
11
444444444444
11
44
11
44
1111111111
44
1111111111
44

This section introduces instructions that transmit data among the general registers, and between
the registers and memory. We will see instructions that handle data in the 32-bit portion of a
64-bit register, and in the full length of a 64-bit register. (You will remember from Figure 9 in
Section 3.3 that data items in general registers are frequently manipulated in 32-bit or 64-bit
lengths.)
The instructions described here transfer data:
between the rightmost 32 bits of general registers and memory
among the rightmost 32 bits of general registers87
between 64-bit general registers and memory
among the 64-bit general registers.
Well sample some typical instructions here; there are other well see later. The first two groups
of instructions leave the high-order half of a 64-bit register unchanged, as illustrated in Figure 61.
 64 bits
 32 bits  32 bits

 untouched by 32bit ops


active

0
31 32
63
Figure 61. 32-bit portion of a 64-bit general register

The high-order half is invisible to the first groups of instructions described here. The z System
architects wanted to ensure compatibility with programs that use only 32-bit registers, so that the
presence of the high-order bits of the 64-bit register would have no effect on existing programs.
Note: The terms and notations used for various portions of a general register can sometimes be
confusing. The z/Architecture Principles of Operation uses High and Low to refer to the

87

180

We will occasionally use the older term 32-bit general register to mean the rightmost 32 bits of a 64-bit general
register. In z System, all general registers are 64 bits long; before z/Architecture was introduced, general registers
were 32 bits long, so the older terminology is still useful for instructions introduced prior to z/Architecture.
Assembler Language Programming for IBM z System Servers

Version 1.00

left/top/upper and right/bottom/lower portions respectively; but the letters H and L are also used
in other contexts with (sometimes) different meanings.
We will use GR R 1 to mean the general register referenced by the R1 operand of a machine
instruction statement, and GRn to mean general register n.
The next several sections will describe instructions that affect only the rightmost 32 bits of a
64-bit general register. Well examine instructions that affect all 64 bits of a register starting in
Section 14.7 on page 192.

14.1. Load and Store Instructions


We first examine instructions that transmit data between general registers and memory. The most
important are L (Load) and ST (Store), shown in Table 34.
Op
58

Mnem
L

Type Instruction
R X Load

Op
50

Mnem
ST

Type Instruction
R X Store

Table 34. Load/Store instructions for 32-bit general registers

We saw these two instructions in several earlier examples; the operands Effective Address should
be divisible by 4, indicating a word operand.88 Neither instruction changes the Condition Code.
As a reminder, an RX-type instruction has the form shown in Table 35.
opcode

R1

X2

B2

D2

Table 35. Format of an RX-type instruction

The Load instruction L copies 4 bytes of data from memory, starting at the Effective Address,
to bits 32-63 of a general register. When executed,
L

R1,D2(X2,B2)

places a copy of the word at the Effective Address of the assembler instruction statements
second operand from memory into GR R 1. The original contents of GR R 1 are lost, and the
word in memory is unchanged. (Remember, operand here means both (1) the assembly
time operand field in the assembler instruction statement, and (2) the data referenced at execution time by the instruction.)
For example, to set the contents of GR9 to zero, we could write
L

9,=F 0

(this is definitely not the best way to zero a register, as we will see). To set it to the maximum
negative number, we could write
L

9,=F -2147483648

The Store instruction ST copies data from a general register to memory. It is written explicitly
as
ST

R1,D2(X2,B2)

When executed, it causes a copy of the contents of bits 32-63 of GR R 1 to replace the word in
memory at the Effective Address of the second operand. The contents of the register are
unchanged, and the original contents of the word area are lost.

88

In the original System/360 systems, correct boundary alignment was required. This requirement was annoying or
inconvenient to many programmers, so IBM introduced the Byte-Oriented Operand Facility (or BOOF) to relax
the stringent alignment requirement. Correct alignment is still recommended because misaligned operands can sometimes cause programs to run much slower.
Chapter V: Basic Instructions

181

For example, to put a copy of the contents of the word at A into the word at B, we could write
L
ST

0,A
0,B

and to exchange the contents of the words at A and B, we could write


L
L
ST
ST

1,B
0,A
0,B
1,A

L
L
ST
ST

or

0,A
1,B
0,B
1,A

L
L
ST
ST

or

0,A
1,B
1,A
0,B

but
not

L
ST
L
ST

0,A
0,B
0,B
0,A

assuming that GR1 is not being used as the programs base register!
L and ST, like other instructions referencing addresses in memory, are subject to interruptions due
to addressing and memory protection, which provides some control over the areas of memory
accessible to a program.

Exercises
14.1.1.(1) What is the difference at assembly and execution times between
L
5,BBB
EQU 8

BBB
and

L
DC

BBB

5,BBB
F8
?

14.2. Multiple Loads and Stores


We sometimes want to transmit groups of 32-bit words between memory and the right halves of
several registers. This can be done with a sequence of L or ST instructions, as in
L
L
L

1,A
2,A+4
3,A+8

ST
ST
ST

and

1,B
2,B+4
3,B+8

If we use more than a very few registers, this is cumbersome and slow. Instead, we use the LM
(Load Multiple) and STM (Store Multiple) instructions shown in Table 36. Neither instruction
changes the Condition Code.
Op
98

Mnem
LM

Type Instruction
RS
Load Multiple

Op
90

Mnem
STM

Type Instruction
RS
Store Multiple

Table 36. Multiple load/store instructions for 32-bit general registers

Each is RS-type, for which three operands must be specified in the operand field of the assembler
instruction statement, as follows:
LM (or STM)
LM (or STM)

R1,R3,D2(B2)
R1,R3,S2

(explicit address)
(implied address)

The components of the assembled instruction are pictured in Table 37.


opcode

R1

R3

B2

D2

Table 37. RS-type instruction format

182

Assembler Language Programming for IBM z System Servers

Version 1.00

As usual, the assembler instruction statements R 1 and R 3 operands must be absolute expressions
between 0 and 15. The base and displacement may be given explicitly, or derived by the Assembler from an implied address.
Beginning with GR R 1, the CPU stores the contents of registers (for STM) or loads the contents
of registers (for LM) in order of increasing register number into or from successive words in
memory starting at the Effective Address of the second operand, until GR R 3 has been stored or
loaded. If R3 is less than R1, then registers GR R 1 through GR15 will be stored/loaded followed
by registers GR0 through GR R 3. Thus, register 0 may be considered to follow after register
15, so that the general registers wrap around from highest to lowest numbered.
Thus, STM 15,0,X will store c(GR15) at X and c(GR0) at X+4, and LM 15,0,X will load GR15
from c(X) and GR0 from c(X+4).
For example,
2,6,=5F 0

LM

will cause the contents of general registers 2, 3, 4, 5, and 6 to be set to zero. Similarly,
STM

0,15,SAVE

will cause the contents of all sixteen registers to be stored beginning at SAVE. The symbol SAVE
could have been defined in a statement such as
SAVE

DS

16F

This DS instruction ensures correct boundary alignment for the second operand address of the
STM instruction. If we assume that GR1 contains the address of a list of four words, we can load
them into registers 7 through 10 by executing
LM

7,10,0(1)

Similarly, if we assume that register 13 contains the address of a block of 18 contiguous words,
then
STM

14,12,12(13)

will store registers 14, 15, 0, ..., 12 in successive words, beginning with the fourth word of the
given area. While these last two examples may seem contrived, they illustrate parts of common
conventions for communicating with subprograms.
As a final example of LM and STM, suppose we wish to exchange the contents of GR0 through
GR7, as a group, with the contents of GR8 through GR15. We could write

SAVE

STM 0,15,SAVE
LM
8,7,SAVE
- - DS
16F

or
SAVE

STM 8,7,SAVE
LM
0,15,SAVE
- - DS
16F

This ignores one important detail: one of the general registers must have been specified as a base
register so that the symbol SAVE can be addressed. The STM and LM instructions will work correctly, because the CPU calculates the Effective Address before the execute phase of the LM
instruction cycle begins. When execution is completed, however, the base register has probably
been changed, so either we must inform the Assembler that the base register is changed (with a
DROP statement, or a new USING statement), or the correct value must somehow be put back
in the original base register.

Exercises
14.2.1.(1) + Describe the differences between these two instructions:
STM
ST

0,0,XXX
0,XXX

14.2.2.(2) In describing the STM instruction, we said that

Chapter V: Basic Instructions

183

STM

14,12,12(13)

stores registers 14 through 12 beginning with the fourth word of the save area. Explain why it
isnt the third, as the displacement value 12=3*4 might imply.
14.2.3.(1) What is the maximum number of general registers whose contents can be modified by
a single instruction?
14.2.4.(1) Describe the effect of each of the following instructions:
(1)
(2)
(3)

LM 15,15,X
STM 0,0,X
LM 0,0,X

14.2.5.(5) Suppose two symbols have been defined with the statements
A
B

EQU
EQU

4
9

Then, the instruction STM A,B,X stores registers GR4 through GR9 starting at X, and we can
compute the number of registers stored with the statement
NREGS

EQU

B-A+1

On the other hand, if we had defined A and B with


A
B

EQU
EQU

9
4

then the instruction STM A,B,X would store registers GR9 through GR15 and GR0 through
GR4. We can then compute the number of registers stored with the statement
NREGS

EQU

B-A+17

Thus, the value assigned to NREGS depends on what values are assigned to the symbols A and B.
Write an expression in the operand field of the EQU statement that defines NREGS such that its
value will always tell how many registers were stored by the STM, no matter what values
(between 0 and 15) are assigned to the symbols A and B.

14.3. Halfword Data


Table 38 shows the two instructions described in this section; neither instruction changes the
Condition Code.
Op
48

Mnem
LH

Type Instruction
R X Load Halfword

Op
40

Mnem
STH

Type Instruction
R X Store Halfword

Table 38. Halfword load/store instructions for 32-bit general registers

Transmitting halfword data between memory and registers is somewhat more complicated,
because a 16-bit halfword requires only half of a 32-bit general register. This may seem obvious,
but we need to know (1) which half of the register, and (2) what happens to the other half of the
register.
The instructions LH (Load Halfword) and STH (Store Halfword) are similar to L and ST; both
are RX-type instructions, and the operand field entry is exactly the same.
STH is simpler: the rightmost 16 bits of GR R 1 replace the halfword in memory at the Effective
Address of the second operand, and GR R 1 remains unchanged. If the 32-bit contents of the
register is an integer too large to be correctly represented as a 16-bit twos complement integer,
the high-order 16 bits are truncated, and significance is lost. No indication is made that the
halfword in memory may not have the desired value!
When LH transmits data from memory to a general register, the CPU assumes you want to
perform arithmetic operations on it, so the result should occupy the entire 32-bit register with the

184

Assembler Language Programming for IBM z System Servers

Version 1.00

least significant bit at the right-hand end. To give a correct representation in the 32-bit register,
copies of the sign bit of the 16-bit halfword are sign-extended to the left to occupy the left half of
the first-operand general register.89 This is illustrated in Figure 62.

 signextended s
GR R1

32

63

s
Halfword in memory

0
15
Figure 62. Sign extension by L H instruction

For example, the two statements


LH

0,=H 1

(=H1 = X0001), c(GR0) = X00000001

LH

0,=H -1

(=H -1 = X FFFF ) , c(GR0) = X FFFFFFFF

and
set the contents of GR0 to X00000001 and X FFFFFFFF , as indicated. So long as the value of a
halfword operand X from memory satisfies
-215 c(X) < 215
it can be represented correctly in 16 bits, it will be correctly transmitted by LH and STH
instructions. Otherwise, the problems illustrated in the next two examples can occur.
Suppose we execute the instructions in Figure 63. The contents of the registers is given in the
remarks fields of the instruction statements.

L
STH
LH
- DS

0,=F65537
0,A
1,A
H

c(GR0)=X00010001 +65537 = 216+1


c(A) =
X0001 Lost high-order bit!
c(GR1)=X00000001 Lost significance!

Figure 63. Loss of significant digits using STH/LH

The contents of GR0 and GR1 will be different because the quantity in GR0 stored by the
second instruction is too large.
A more awkward result is illustrated in Figure 64.

L
0,=F65535
STH 0,A
LH
1,A
- - DS
H

c(GR0)=X0000FFFF
c(A) =
X FFFF
c(GR1)=X FFFFFFFF

+65535
No lost bits, but wrong sign
(1!) Worse lost significance!

Figure 64. Loss of significant digits using STH/LH

In this case, the result in GR1 has sign and magnitude different from the original operand.
You can see that when you use halfword data, you must be careful to understand what might
happen when storing, loading, or doing (implicitly word) arithmetic with such quantities.

89

We will see many uses of sign extensioncopying the sign bit into the higher-order bit positions of a general
registerso its important to understand its behavior.
Chapter V: Basic Instructions

185

Exercises
14.3.1.(3) Suppose the STH instruction was modified so that it stored the sign bit and the rightmost 15 bits of the 32-bit R1 register, so the result contains bits 0 and 17-31 of the original
operand. By considering operands like those in Figures 63 and 64, determine whether this form
of the instruction will solve some of the problems in using halfword data weve discussed here.
14.3.2.(2) Suppose GR1 contains X12345678. What will be in GR2 after executing these
instructions?
ST
LH

1,A
2,A+2

Now, suppose GR1 contains X FEDCBA98 ; what will be in GR2 after executing the same
instructions?
14.3.3.(2) + Suppose an area of memory contains X4040405C . Is it an instruction or data?
Explain.
14.3.4.(1) What similarities can you find among the opcodes assigned to L, LH, and LM compared to those of ST, STH, and STM?
14.3.5.(3) + The inequality following Figure 62 on page 185 says that values 215 or
< 215 1 can cause problems when used as operands of LH and STH instructions. Write and
execute program segments like that in Figure 63 on page 185 to test this assertion.

14.4. Insert and Store Character


The IC (Insert Character) and STC (Store Character) instructions shown in Table 39 transmit a
single byte between a general register and memory.
Op
43

Mnem
IC

Type Instruction
RS
Insert Character

Op
42

Mnem
STC

Type Instruction
RS
Store Character

Table 39. Character insert/store instructions for 32-bit general registers

The operand field entry is written as for L and ST, but you need not worry about boundary alignment for the address of the second operand, since only a single byte of data is being moved.
The instruction
STC

R1,D2(X2,B2)

stores the rightmost byte of GR R 1 in memory at the Effective Address of the second operand.
The contents of GR R 1 and the Condition Code are both unaffected.
The reverse operation, IC, is called Insert Character rather than Load Character, because the
byte from memory is inserted into the rightmost byte of the register without disturbing the other
bytes. No sign extension is done.
Figure 65 illustrates the actions of IC and STC.

186

Assembler Language Programming for IBM z System Servers

Version 1.00


 unchanged
GR R1

32
 63


Byte in memory

0
7
Figure 65. Action of IC and STC instructions

As an example, the instructions in Figure 66 can be used to copy the two characters in the character constant at X, and store them in reverse order at Y.
IC
0,X
STC 0,Y+1
IC
0,X+1
STC 0,Y
- - DC
C AB
DS
CL2

X
Y

Get 1st byte of constant


Store at 2nd byte of Y
Get 2nd byte of constant
Store byte at Y

Becomes C BA

Figure 66. Interchanging two bytes with IC and STC

If memory space is at a premium, you can use a single byte to contain a small integer constant. It
can be placed in a register using these instructions:

LitlCon

L
1,=F 0
IC
1,LitlCon
- - DC
FL1 5 3

Clear GR1
Insert character
Explicit length, no alignment

Figure 67. Inserting a small number into a register

but for small constants it is much better to use other available instructions.

Exercises
14.4.1.(3) Write an instruction sequence that will replace the byte at XX with a byte that contains in binary the number of one-bits that were present in the original byte. For example, if
the initial contents of XX was X 4 8 , the final contents should be X 0 2 . (Hint: define a
carefully-constructed 256-byte constant, and use an indexed IC instruction. Show only enough
of the constant to clarify how you constructed it.)

14.5. ICM and STCM Instructions


ICM and STCM are very flexible RS-type instructions. They are generalizations of the normal
load/store and insert/store character instructions, because you can specify exactly which bytes of a
register participate in the insert or store operation. Table 40 lists the two instructions:
Op
BF

Mnem
ICM

Type Instruction
RS
Insert Characters Under
Mask

Op
BE

Mnem
STCM

Type Instruction
RS
Store Characters Under
Mask

Table 40. Insert/Store characters under mask instructions for 32-bit general registers

The final M character on these two mnemonics does not mean Multiple as in LM and STM,
but Mask instead.

Chapter V: Basic Instructions

187

The instruction format of ICM and STCM is very similar to that of LM and STM, as shown in
Table 37 on page 182, but the R 3 digit is now interpreted as a mask digit M 3, as illustrated in
Table 41. The M 3 operand is a bit pattern, not a register number.
opcode

R1

M3

B2

D2

Table 41. RS-type instruction format for ICM and STCM

The machine instruction statement operand formats for ICM and STCM are like those of LM
and STM:
ICM (or STCM)
ICM (or STCM)

R1,M3,D2(B2)
R1,M3,S2

(explicit address)
(implied address)

The four bits in the mask digit correspond to the four bytes of the rightmost 32 bits of the general
register designated by GR R 1. The leftmost bit of the mask M3 (bit 12 of the instruction) corresponds to the leftmost byte of the 32-bit register, the next bit corresponds to the second byte, and
so forth. If all mask bits are zero, nothing is inserted or stored.
The CPU executes the STCM instruction by first calculating the Effective Address. Then, where
one-bits in the mask appear, the corresponding bytes in GR R 1 are stored into memory in contiguous bytes, starting at the Effective Address. Even though separate bytes in GR R 1 may be
stored, they are not separated in memory. STCM does not change the Condition Code, and no
boundary alignment is required for the second operand.
Suppose the four-byte area of memory named AA contains X01020304, GR12 contains
X FFD0A061 , and we execute this STCM instruction:

AA

STCM 12,B0101,AA
- - DC
X01020304

Store bytes 2 and 4 at AA, AA+1

The M 3 mask specifies that the second and fourth bytes of GR12 are to be stored into the first
two bytes starting at AA, so the contents of memory will become X D0610304 .
STCM can be considered a generalization of the STC, STH, and ST instructions: the three
instructions
STC
STH
ST

12,AA
12,BB
12,CC

Store rightmost byte at AA


Store 2 rightmost bytes at BB
Store all 4 bytes at CC

behave just like these three STCM instructions:


STCM 12,B0001,AA
STCM 12,B0011,BB
STCM 12,B1111,CC

Store rightmost byte at AA


Store 2 rightmost bytes at BB
Store all 4 bytes at CC

except that now the data areas named by the symbols BB and CC are not expected to be halfword
and word aligned, as recommended for STH and ST. A possible disadvantage of STCM is that it
cannot be indexed, since it is not an RX-type instruction.
The ICM instruction performs the inverse operation to STCM, and also does not expect the
second operand to be aligned; however, ICM does set the Condition Code. As above, suppose the
contents of the four bytes in memory in an area named AA contain X01020304, and GR12 initially contains X FFD0A061 . Then if we execute the instruction

AA

ICM 12,B0101,AA
- - DC
X01020304

Insert into bytes 2 and 4 of GR12

the contents of GR12 will become X FF01A002 .


If all the mask bits are zero, or if all the inserted bytes are zero, the CC is set to zero. Otherwise,
the leftmost bit of the first byte inserted anywhere into GR R 1 is inspected: if the leftmost bit is a

188

Assembler Language Programming for IBM z System Servers

Version 1.00

one-bit, the CC is set to 1; otherwise the CC is set to 2. The settings are summarized in Table
42.
CC
0
1
2

Meaning
M 3 = 0, or all inserted bytes are zero
Leftmost bit of first inserted byte = 1
Leftmost bit of first inserted byte = 0

Table 42. CC settings after ICM instruction

This method of setting the CC is easier to understand if we consider the case when the mask digit
is all one-bits, meaning that four bytes are brought from memory and placed into GR R 1. If we
execute these three instructions, the CC settings are as indicated.
ICM
ICM
ICM

1,15,=F 0
2,15,=F -1
3,15,=F+1

CC set to 0, c(GR1) is zero


CC set to 1, c(GR2) is negative
CC set to 2, c(GR3) is positive

Exercises
14.5.1.(2) Write a sequence of two instructions (using ICM and STCM) that will set the CC to
zero if the middle two bytes of GR1 are zero. For example, if c(GR1) = X A2000064 , the CC
should be set to zero.

14.6. RR-Type Data Transmission Instructions


We now examine RR-type instructions that transmit data among the 32-bit right halves of the
general registers; four of them set CC. The instructions are LR (Load Register), LTR (Load and
Test Register), LCR (Load Complement Register), LNR (Load Negative Register), and LPR
(Load Positive Register). We saw the LR instruction in the machine instruction statement in
Figure 30 on page 80; it and LHR are the only ones that do not set the CC.
Op
18
11
13

Mnem
LR
LNR
LCR

Type
RR
RR
RR

Instruction
Load Register
Load Negative Register
Load Complement Register

Op
10
12
B927

Mnem
LPR
LTR
LHR

Type
RR
RR
RRE

Instruction
Load Positive Register
Load and Test Register
Load Halfword

Table 43. Register/register instructions for 32-bit general registers

The RRE instruction format will be described in Section 14.8.


The operand field entry of all six instructions is written
R1,R2
where R 2 need not differ from R1. For example,
LCR

0,0

Complement c(GR0)

forms the twos complement of the contents of GR0 without affecting any other register.
The action of the first five instructions is summarized in Table 44, where the arrow means
replaces and the vertical bars |...| mean absolute value. As noted above, only the rightmost 32 bits of the registers are involved.

Chapter V: Basic Instructions

189

Mnemonic
LR

Action
c(GR R1) 

c(GR R2)

CC Values
Not changed

LTR

c(GR R1) 

c(GR R2)

0,1,2

LCR

c(GR R1) 

c(GR R2)

0,1,2,3

LPR

c(GR R1) 

c(GR R2)

0,2,3

LNR

c(GR R1)  c(GR R2)

0,1

Table 44. Action of five RR-type general register instructions

The CC is set to indicate the status of the result in GR R 1, as shown in Table 45.
CC
0
1
2
3

Meaning
Result is zero
Result is negative
Result is positive
Result has overflowed

Table 45. Condition Code settings

You can see in Table 44 that the actions of LR and LTR are identical except that LTR sets the
CC. We often test the contents of a register by writing instructions like
LTR

4,4

that has no effect other than setting the CC. We test the CC with the important Branch on
Condition instructions well see in Section 15.
For LCR, LPR, and LNR, the arithmetic operations use 32-bit twos complement representation.
Overflow can occur during execution of LCR or LPR only if c(GR R 2) is the maximum negative
number 231. (It may help to review the discussion of overflow in Section 2.8 on page 29.)
If the overflow condition causes a program interruption, the Interruption Code is set to 8, indicating a Fixed-Point Overflow.90 No overflow can occur executing LNR because all representable
positive values have valid twos complement representations of their negative values.
This example illustrates possible uses of these instructions.
*

First, initialize GR2 and GR3


LM
2,3,=F 1 , 0
c(GR2)=1,
LR
7,3
c(GR7)=0,
LTR 2,2
c(GR2)=1,
LNR 1,3
c(GR1)=0,
LCR 4,2
c(GR4)=-1,
LPR 0,4
c(GR0)=+1,
LNR 5,2
c(GR5)=-1,

c(GR3)=0, CC not set


CC not set
CC=2
CC=0
CC=1
CC=2
CC=1

Figure 68. Examples of some RR-type instructions

We saw in Section 14.5 on page 187 that these three ICM instructions set the Condition Code as
indicated in the comment fields:
ICM
ICM
ICM

90

190

1,15,=F 0
2,15,=F -1
3,15,=F+1

CC set to 0, c(GR1) is zero


CC set to 1, c(GR2) is negative
CC set to 2, c(GR3) is positive

This condition is called fixed-point overflow, to distinguish it from floating-point and decimal overflow. It is one of
four program interruptions you can allow or disallow by setting bits in the Program Mask sketched in Figure 12 on
page 49. We sometimes say that such disallowed interruption conditions are masked or disabled, and when
allowed they are unmasked or enabled. Well see in Section 16.2.1 how the SPM instruction lets you control
these four program interruptions.
Assembler Language Programming for IBM z System Servers

Version 1.00

These CC settings are exactly what we would have obtained if we had written the six instructions
L
LTR
L
LTR
L
LTR

1,=F 0
1,1
2,=F -1
2,2
3,=F+1
3,3

CC
CC
CC
CC
CC
CC

unchanged
set to 0, c(GR1) is zero
unchanged
set to 1, c(GR2) is negative
unchanged
set to 2, c(GR3) is positive

That is, an ICM instruction whose mask is all one-bits is equivalent to a L instruction followed
by an LTR instruction,.
Unfortunately, this parallel is invalid for the LH instruction, because ICM does not extend the
sign bit to the left to fill the register as does LH. The ICM instruction in
L
ICM

1,=F 0
1,B0011,=H -1

Set GR1 to zero, CC unchanged


Sets GR1 to X0000FFFF , CC = 1

sets the CC to 1 (indicating a one-bit at the left end of the first inserted byte), but the leftmost
two bytes of GR1 are still zero. Conversely, the instruction
LH

1,=H -1

Set GR1 to X FFFFFFFF

does not affect the CC, but GR1 will contain all one-bits.
LHR is similar to LR, and their operand field entries are the same. It takes the rightmost 16 bits
of the R 2 register, extends the sign bit to the left to form a 32-bit result, and places the result in
the R 1 register. This is illustrated in Figure 69; note its similarity to Figure 62 on page 185. The
R 1 and R 2 registers need not be distinct.

 signextended s
GR R1

32

63

s
Rightmost 16 bits of GR R2

0
15
Figure 69. Sign extension by L H R instruction

For example:
L
LHR

1,=X456789AB
2,1

c(GR2)= X FFFF89AB

We saw in Figure 63 on page 185 that large fullword values can be yield incorrect values if truncated to halfwords. The same problem can occur with LHR:
L
0,=F65537
LHR 1,0

c(GR0)=X00010001
c(GR1)=X00000001 Lost significance!

Exercises
14.6.1.(2) What changes to the Assembler would be needed to let you use a (nonexistent)
STR opcode (that is, Store Register, in the same sense as Load Register)?
14.6.2.(2) For each instruction in Table 43 on page 189, what operands in GR R 2 can result
in the CC being set to 3?
14.6.3.(2) Can you think of a reason why an LHR instruction would be used with identical
register operands?
14.6.4.(2) + Suppose GR1 contains X12345678. What will be in GR2 after executing this
instruction?
Chapter V: Basic Instructions

191

LHR

2,1

Now, suppose GR1 contains X FEDCBA98 ; what will be in GR2 after executing the same
instruction?

14.7. Load, Store, and Insert for 64-bit General Registers


Well now look at instructions that manage data using the full 64 bits of a general register. Contrast Figure 70 below with the 32-bits-only view in Figure 61 on page 180.
 64 bits 

0
63
Figure 70. 64-bit general register

The instructions are shown in Table 46:


Op
E304
E315
EB04
EB96
EB80

Mnem
LG
LGH
LMG
LMH
ICMH

Type
RXY
RXY
RSY
RSY
RSY

Instruction
Load
Load Halfword (6416)
Load Multiple
Load Multiple High
Insert Characters Under
Mask (High)

Op
Mnem
E324 STG
B907 L G H R
EB24 STMG
EB26 STMH
EB2C STCMH

Type
RXY
RRE
RSY
RSY
RSY

Instruction
Store
Load Halfword (6416)
Store Multiple
Store Multiple High
Store Characters Under Mask
(High)

Table 46. Register/storage instructions for 64-bit general registers

The letter G is used in almost all the instructions involving 64-bit registers. For example, LG
and STG are the 64-bit equivalents of L and ST.91
Here, we introduce two variations on the RX and RS formats. RXY-type instructions behave
just like RX-type instructions, except that they provide a longer, and signed, displacement field.
as shown in Table 47.
opcode

R1

X2

B2

DL 2

DH2

opcode

Table 47. RXY-type instruction format

Another instruction type is RSY. Its format and behavior are very similar to RS-type
instructions, and it shares the long-displacement format with RXY-type instructions.
opcode

R1

R3

B2

DL 2

DH2

opcode

Table 48. RSY-type instruction format.

For now, well treat both RXY-type and RSY-type instructions as though they are identical to
RX-type and RS-type instructions, because they do very similar things. Also note that the first
four bytes of RX-type and RS-type instructions have the same format as the first four bytes of
RXY-type and RSY-type instructions, respectively.

91

192

In my opinion, G was chosen for two reasons. First, it was the least-used letter among the nearly 500 instruction
mnemonics supported by Enterprise System/390 architecture, the predecessor of z System. Second (and anecdotally),
the largest size latte sold at a coffee shop near IBM in Poughkeepsie, New York was called a Grande, so it seemed
natural to say the new large registers were similarly Grande. Other more descriptive letters like L (meaning
Long) were already used in many other mnemonics, where L can mean Logical, or Long, or Low.
Assembler Language Programming for IBM z System Servers

Version 1.00

Well investigate the added usefulness of the long-displacement instructions and their DL2
and DH 2 fields (and how the Assembler handles them) in Section 20.1 on page 302.
Weve seen instructions that manipulate data only in the low-order 32 bits of a general register,
while others deal with all 64 bits. To help us distinguish these two views of a general register, we
introduce another notation, GR G n. Thus, GG R 1 will mean the 64-bit general register referenced by an R 1 operand, while GR R 1 will continue to mean the 32-bit general register referenced
by an R 1 operand. Similarly, GGn will mean the specific register referenced by GR G n, and
GRn will mean the specific register referenced by GR R n .
The LG, STG, LMG, and STMG instructions do for 64-bit registers exactly the same actions as
their 32-bit equivalents L, ST, LM, and STM.
1. To illustrate STMG, suppose we save 64-bit general registers GG0 through GG3 at Save0123:
STMG 0,3,Save0123
- - Save0123 DS
4D

Save 64-bit GG0 through GG3


Reserve 4 doublewords

In memory, these would appear like this:

Save0123+0
c(GG0)

Save0123+8
c(GG1)

Save0123+16
c(GG2)

Save0123+24
c(GG3)

Then, to restore the contents of the registers, we execute


LMG

0,3,Save0123

Restore GG0 through GG3

2. The other two LM/STM instructions in Table 46 end in H, referring to the 32-bit highorder half of a 64-bit general register.92 They do the same actions for the high-order halves of
64-bit general registers that LM and STM do for the low-order halves. LMH and STMH
might seem unnecessary, since LMG and STMG manage both halves of a 64-bit register in
one operation. The reason they exist is history.93
For example, to store and load only the high-order halves of general registers 5 and 6, we can
write

High56

STMH 5,6,High56
- - LMH 5,6,High56
- - DS
2F

Save high-order half of GG5 and GG6


Restore high-order half of GG5 and GG6
Save area for two 32-bit words

3. LGH is the 64-bit equivalent of LH: it sign-extends the 16-bit integer at the Effective Address
in memory to 64-bits, and and places the result into GG R 1; LGHR uses the rightmost 16
bits of the second operand register. Sign extension is indicated by the notation (6416) in
Table 46. Figure 71 shows its resemblance to LH seen in Figure 62 on page 185.

92
93

The letter H is used in mnemonics with many meanings, such as High, Halfword, etc.
Because 64-bit general registers were introduced after many years of program development using only 32-bit general
registers, conventions for saving and restoring the 32-bit registers are embedded in many programs. To minimize the
changes needed, programs can save the low-order register halves using existing conventions, and then save the highorder halves elsewhere using STMH. The LMD instruction, as we will see, lets you restore both halves of 64-bit
registers from two separate save areas in one operation.
Chapter V: Basic Instructions

193


 signextended s
GG R1

0

63

Halfword in memory s

0
15
Figure 71. Sign extension by L G H instruction

4. The remaining two instructions in Table 46 are ICMH and STCMH. They behave exactly
like ICM and STCM, except that the four M 3 mask bits now refer to the four bytes in the
high-order or left half of GG R 1. The Condition Code settings are the same as in Table 42
on page 189.
To illustrate, suppose you want to swap the first and fourth bytes of GG0
high-order and low-order bytes of the high-order half of the register.

that is, the

1 2 3 4 5 6 7 8 Bytes in GG0



swap
These three instructions show one way to do this:

Temp

STCMH
ICMH
ICMH
- - DS

0,B1001,Temp
0,B1000,Temp+1
0,B0001,Temp

Save bytes 1 and 4 of 64-bit GG0


Insert original byte 4 at left end
Insert original byte 1 into 4th byte

XL2

Two-byte temporary storage

Exercises
14.7.1.(1) + There is a LGH instruction, but no STGH instruction. Why not?
14.7.2.(2) Write a sequence of instructions to exchange the high-order and low-order halves of
GG0.

14.8. RR-Type Data Transmission Instructions for 64-bit General Registers


As the original System/360 architecture evolved, there were not enough one-byte RR-type
opcodes available for new register-to-register instructions, so new two-byte opcodes were assigned
using a new instruction type, RRE. RRE-type instructions are four bytes long (while
traditional RR-type instructions are two bytes long). The 8-bit unused field is set to zero by
the Assembler.
opcode

unused

R1

R2

Table 49. RRE-type instruction format

The instructions in Table 50 are RRE-type.

194

Assembler Language Programming for IBM z System Servers

Version 1.00

Op
B904
B903

Mnem
LGR
LCGR

Type Instruction
R R E Load Register (64)
R R E Load Complement Register
(64)

B901

LNGR

R R E Load Negative Register (64)

Op
Mnem
B902 L T G R
B900 L P G R

Type Instruction
R R E Load and Test Register (64)
R R E Load Positive Register (64)

Table 50. Register/register instructions for 64-bit general registers

The actions of the instructions in Table 51 are the same as for their 32-bit equivalents in
Table 44 on page 190.
Mnemonic
LGR

Action
c(GG R1) 

c(GG R2)

CC Values
Not changed

LTGR

c(GG R1) 

c(GG R2)

0,1,2

LCGR

c(GG R1) 

c(GG R2)

0,1,2,3

LPGR

c(GG R1) 

c(GG R2)

0,2,3

LNGR

c(GG R1)  c(GG R2)

0,1

Table 51. Action of five RR-type 64-bit general register instructions

The instructions in Figure 68 on page 190 dealt with data in 32-bit registers; their equivalents for
64-bit registers are shown in Figure 72.
*

First, initialize GG2 and GG3 (all 64 bits)


LMG 2,3,=FD 1 , 0
c(GG2)=1, c(GG3)=0, CC not set
LGR 7,3
c(GG7)=0, CC not set
LTGR 2,2
c(GG2)=1, CC=2
LNGR 1,3
c(GG1)=0, CC=0
LCGR 4,2
c(GG4)=-1, CC=1
LPGR 0,4
c(GG0)=+1, CC=2
LNGR 5,2
c(GG5)=-1, CC=1

Figure 72. Examples of some RR-type instructions for 64-bit operands

If we compare Figures 72 and 68, we see that these equivalent instructions behave similarly and
produce identical CC settings.

14.9. The Load and Test Instructions


In Section 14.6 on page 189, we saw two ways to transfer a data item from memory to a general
register and set the CC depending on its sign:
ICM

R1,B1111,dataname

L
LTR

R1,dataname
R1,reg

and

ICM cannot be indexed nor can it be used for 64-bit operands, because ICM and ICMH set the
CC separately for the low-order and high-order halves of GG R 1, respectively. The L/LTR and
LG/LTGR instruction pairs can be indexed, but two instructions are needed.
To eliminate these inconveniences, z System provides the LT and LTG instructions, as shown in
Table 52:
Op
E312

Mnem
LT

Type Instruction
RXY Load and Test (32)

Op
Mnem
E312 L T G

Type Instruction
RXY Load and Test (64)

Table 52. Load and Test instructions

Chapter V: Basic Instructions

195

Their behavior is identical to the instruction pairs L/LTR and LG/LGTR, respectively.

Exercises
14.9.1.(1) How can the L/LTR and LG/LTGR instruction pairs be indexed?
14.9.2.(1) What operand values can cause LT or LTG to set CC=3?

14.10. Mixed 32- and 64-bit Operands


To make it easy to use 32-bit binary operands in 64-bit operations, z System provides a set of
instructions that automatically sign-extend a 32-bit operand to 64 bits. In Table 53, The LGF
instruction is RXY-type and the others are RRE-type. The notation (6432) indicates the
extension of the 32-bit second operand to a 64-bit first operand.
Op
E314
B912
B910

Mnem
Type Instruction
LGF
RXY Load (6432)
L T G F R R R E Load and Test Register
(6432)
L P G F R R R E Load Positive Register
(6432)

Op
Mnem
Type Instruction
B914 L G F R
R R E Load Register (6432)
B913 L C G F R R R E Load Complement Register
(6432)
B911 L N G F R R R E Load Negative Register
(6432)

Table 53. Register/register instructions for 64-bit general registers

The actions of these instructions are almost the same as their 64-bit equivalents that we saw in
Table 51, except that no instruction sets the CC to 3.
Mnemonic
LGF

Action
c(GG R1) 

c(Word in memory)

CC Values
Not changed

LGFR

c(GG R1) 

c(GR R2)

Not changed

LTGFR

c(GG R1) 

c(GR R2)

0,1,2

LCGFR

c(GG R1) 

c(GR R2)

0,1,2

LPGFR

c(GG R1) 

c(GR R2)

0,2

LNGFR

c(GG R1)  c(GR R2)

0,1

Table 54. Action of 32-bit-to-64-bit general register instructions

In each case, the 32-bit second operand is first sign-extended internally, and then treated as a
64-bit operand. For example, the single instruction
LCGFR 0,1

Sign extend, complement GR1 to GG0

is equivalent to the two instructions


LGFR 0,1
LCGR 0,0

Sign extend GR1 to GG0


Two s complement of GG0

(See Exercise 14.10.2!)

196

Assembler Language Programming for IBM z System Servers

Version 1.00


 signextended s
GG R1

0

63

32bit second operand s


GR R2

0
31
Figure 73. Sign extension for instructions with mixed 32- and 64-bit signed operands

The instructions in Table 53 on page 196 all have the letter F in their mnemonics, to indicate
that the second operand is a 32-bit, 4-byte Fullword. The first operand (designated by R1) is
the 64-bit general register that receives the sign-extended (and possibly complemented) second
operand.

Exercises
14.10.1.(1) Compare the opcodes of the five RRE-type instructions in Table 53 to those in
Table 50. What similarities and differences do you see?
14.10.2.(2) + What would happen in the (6432) instructions in Table 53 if complementation
is done before sign extension?
14.10.3.(2) + The Condition Code values shown in Table 51 are not the same as those shown in
Table 54. How and why are they different?
14.10.4.(2) Consider the 32-bit maximum negative number X80000000. Show the contents of
general register 0 and the CC setting after each of these instruction sequences:
(1)

L
LPR

0,=X80000000
0,0

(2)

L
0,=X80000000
LGFR 0,0

(3)

L
0,=X80000000
LPGFR 0,0

(4)

L
0,=X80000000
LNGFR 0,0

14.10.5.(2) + Why can none of the instructions in Table 53 set the CC to 3?

14.11. Other General Register Load Instructions (*)


The previous sections examined the most frequently used load instructions; z System supports
many others. For example, many programs need to insert a byte into the rightmost 8 bits of a
general register; a common instruction pattern is
L
IC

1,=F 0
1,Byte

Clear GR1 to zero


c(GR1) = X000000xx

SR
IC

1,1
1,Byte

Set c(GR1) to zero (subtract from itself)


c(GR1) = X000000xx

or

An extra instruction is needed to set GR1 to zeros before the IC instruction. (The SR instruction
subtracts c(GR1) from itself; well review it in more detail in Section 16.2.)

Chapter V: Basic Instructions

197

The LLC instruction (Load Logical Character) does both operations: the byte is loaded into
the last 8 bits of the GR1 operand, and the rest of GR1 is cleared to zero:
LLC

1,Byte

c(GR1) = X000000xx

Table 55 gives a summary of the instructions well review. Well see that they are arranged in
simple groups with repeating patterns.
Op
E376
E377

Mnem
LB
LGB

Type Instruction
RXY Load Byte (328)
RXY Load Byte (648)

Op
Mnem
B924 LBR
B906 LGBR

Type Instruction
R R E Load Byte (328)
R R E Load Byte (648)

E394

LLC

RXY Load Logical Character


(328)

B994 LLCR

R R E Load Logical Character


(328)

E390

LLGC

RXY Load Logical Character


(648)

B984 L L G C R R R E Load Logical Character


(648)

E395

LLH

B995 L L H R

E391

LLGH

RXY Load Logical Halfword


(3216)
RXY Load Logical Halfword
(6416)

E317

LLGT

E316

LLGF

RXY Load Logical Thirty One Bits


(6431)
RXY Load Logical (6432)

B917 L L G T R R R E Load Logical Thirty One


Bits (6431)
B916 L L G F R R R E Load Logical (6432)

R R E Load Logical Halfword


(3216)
B985 L L G H R R R E Load Logical Halfword
(6416)

Table 55. Other general register load instructions

For example, the four instructions in the first two rows are arithmetic loads: the high-order bit of
the second operand is sign-extended to the length of the first operand (as illustrated in Figure 62
on page 185 and Figure 71 on page 194); the others are logical load instructions that zero-extend
the second operand to the length of the first.
None of the instructions in Table 55 change the Condition Code.

14.11.1. Load Byte Instructions


The LB, LBR, LGB, and LGBR instructions treat the second operand as a signed 8-bit number,
and sign-extend it to the 32- or 64-bit length of the R1 general register operand. For the LGB and
LGBR instructions, this is illustrated in Figure 74.

 LGB  LB s
GG R1

0
(unchanged by LB)
31 32
 63

Byte in memory or register s

0
7
Figure 74. Sign extension by Load Byte instructions

For the LB and LBR instructions, the R 1 first operand is a 32-bit general register, and the highorder 32 bits of the 64-bit register are unchanged. For example:
LB
LGB

3,=FL1 -7
5,=FL1 -7

c(GR3)=X FFFFFFF9
c(GG5)=X FFFFFFFF FFFFFFF9

14.11.2. Load Logical Character Instructions


The second operand of these instructions is called an unsigned character to distinguish it from
the (signed) byte operand of the Load Byte instructions. Each of LLC, LLCR, LLGC, and
LLGCR does the same as the Byte instructions above, except that the rest of the R1 first
operand register is set to zeros. To illustrate LLGC and LLGCR:

198

Assembler Language Programming for IBM z System Servers

Version 1.00


 (zeroed by LLGC, LLGCR)  zeros
GG R1

0
(unchanged by LLC, LLCR)
 63

Character in memory or register

0
7
Figure 75. Zero extension by Load Logical Character instructions

LLC and LLCR affect only the 32 low-order bits of the 64-bit R1 register; the high-order 32-bits
are unaffected.
These four instructions can eliminate the need to clear a register before inserting a character for
processing.

14.11.3. Load Logical Halfword Instructions


The four instructions LLH, LLHR, LLGH, and LLGHR all load the 16-bit halfword operand
into the low-order 16 bits of the R1 register, and clear the preceding 16 bits of the 32-bit register
(for LLH and LLHR) or the preceding 48 bits of the 64-bit register (for LLGH and LLGHR).

 (zeroed by LLGH, LLGR)  zeros


GG R1

0
(unchanged by LLH, LLHR)

63

Halfword in memory or register

0
15
Figure 76. Operation of Load Logical Halfword instructions

These four Load Logical Halfword are closely related to the arithmetic Load Halfword
instructions, except that the logical loads fill the rest of the 32- or 64-bit R1 register with zeros,
rather than sign-extending the high-order bit of the loaded halfword.

14.11.4. Load Logical (Word) Instructions


The LLGF and LLGFR instructions load the 32-bit second operand from memory or from
G R R 2 into the low-order 32 bits of the 64-bit GG R 1 register, as illustrated in Figure 77:

 zeros
GG R1

0

63

Word in memory or register

0
31
Figure 77. Operation of Load Logical word instructions

In effect, LLGF and LLGFR are like L and LR, followed by setting the high-order half of the
G G R 1 register to zero. The R 1 operand is always a 64-bit register.

14.11.5. Load Logical Thirty One Bit Instructions


The LLGT and LLGTR are unusual: the second operand is 32 bits long, but its high-order bit is
ignored! This is illustrated in Figure 78:

Chapter V: Basic Instructions

199


 zeros 0bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb GG R1

0

63

Word in memory or register xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb

0
31
Figure 78. Operation of Load Logical Thirty One Bits instructions

The R 1 operand is always a 64-bit register.


Why ignore the high-order bit of the 32-bit second operand? When we discuss addressing
modes and instructions that both change and depend on addressing mode in Section 20, well see
that the high-order bit of a 32-bit address was often used to indicate which mode was desired; it
can be important to set that bit to zero. 94

Exercises
14.11.1.(1) How would you simulate the action of the Load Logical Character instructions with
other instructions already described?
14.11.2.(1) How would you simulate the action of the Load Logical (Word) instructions with
other instructions already described?

14.12. Misunderstandings to Avoid


Two common errors made by beginning programmers are
1. confusing the LR and L instructions, and
2. trying to use a Store Register or STR instruction to store one register into another.
First: by substituting L for LR, you can occasionally create an error that cant be detected by the
Assembler, and sometimes is difficult to find. For example, suppose you intended to load GR5
from GR8 with a LR instruction. If the symbols R5 and R8 have values 5 and 8, then both
L

5,8

Load GR5 with value 8 (??)

R5,R8

Load GR5 from GR8 (??)

and
are valid instructions referring to memory at address 8. This is probably not what was intended
for the second instruction, even though it looks like it is loading GR5 from GR8. This can be
seen by checking the machine language object code generated for the two instructions:
000000 5850 0008
000004 5850 0008

L
L

5,8
R5,R8

Load GR5 with value 8 (??)


Load GR5 from GR8 (??)

Exactly the same instruction will be executed.


Warning
Symbols like R8
register!

94

200

an R followed by a number

might not refer to a

This unusual behavior is difficult to justify now, but well see in Section 37 that there are good reasons to have these
instructions.
Assembler Language Programming for IBM z System Servers

Version 1.00

To help you remember the difference between related instructions of different types, note that
almost all RR-type instruction mnemonics end in the letter R, while the RX-, SI-, and RS-type
instruction mnemonics end in other letters.
Second: there is no STR instruction. To store data from one general register to another, you
must use a LR-like instruction. (See Exercise 14.6.1.)

14.13. Summary
You can think of load-type instruction statements as moving data from right to left: that is, the
second operand replaces the first operand. For example, consider this assembler instruction statement:
L

0,X

c(GR0)  c(X)

Right to left

This way of visualizing actions applies to most instructions. The primary exceptions are the
store-type instructions, where you can visualize data moving from the first operand to the second,
or from left to right in the assembler instruction statement. For example:
ST

0,X

c(GR0) c(X)

Left to right

It also helps to remember how short operands are extended to the length of the target operand.
Operand Extension
When a source operand in a register or in memory is moved to a target
register longer than the operand, the operand is extended to the length of
the target register. Arithmetic loads extend the sign bit, and logical loads
extend with zero bits.
Examples of arithmetic load instructions are LH, LGH, and LGFR; examples of logical load
instructions are LLH, LLGH, and LLGFR.
Weve seen a lot of new instructions in this section, and keeping track of them can be difficult.
The following table provides a compact summary to help you understand how they are grouped
and related.
Dont try to memorize!
The z System processors are very complex, and youll learn the instruction mnemonics a few at a time. The tables at the end of each section
summarizing the mnemonics and their opcodes are primarily for reference
(and to help you in solving some of the Exercises).

Chapter V: Basic Instructions

201

Function

Oprnd1
Oprnd2

8 bits
8 bits

Load Arithmetic
(from memory)

8 bits
LB

32 bits
16 bits
LH

LBR

LHR

LLC
LLCR

8 bits
LGB

16 bits
LGH

LR
LTR
LPR
LNR
LCR

LGBR

LGHR

LLH

LLGC

LLGH

LLGT

LLGF

LLHR

LLGCR

LLGHR

LLGTR

LLGFR

Load Arithmetic
(from register)
Load Logical
(from memory)
Load Logical
(from register)
STC
Store

64 bits
31 bits

32 bits
L
LT
LM

STH

ST
STM
STCM

32 bits
LGF
LMH

64 bits
LG
LTG
LMG

LGFR
LTGFR
LPGFR
LNGFR
LCGFR

LGR
LTGR
LPGR
LNGR
LCGR

STMH
STCMH

STG
STMG

ICM
ICMH
Table 56. Summary of instructions discussed in this section
Insert

IC

Well use tables like this to summarize other instructions as they are introduced. (This one is
more complex than most!)
In Table 56 you might say that the ICM/ICMH and STCM/STCMH instructions deal with one
byte at a time; but because they might move up to 4 bytes, they are shown in the column with
32-bit second operands.
It is difficult to remember all these mnemonics, but they will become more familiar with regular
use. You might ask why the z System architects didnt choose more descriptive mnemonics like
LoadRegister and InsertCharactersUnderMask. Here are two reasons why not.
1. When you write Assembler Language programs, long mnemonics would require a lot of extra
work that is saved by using short abbreviations.
2. In the early years of System/360, programs were prepared on 80-column punched cards, of
which only 71 columns were available for Assembler Language statements. This meant that
shorter mnemonics provided more space for name-field symbols, operands, and comments.
The instruction mnemonics and opcodes are shown in the following table:

202

Assembler Language Programming for IBM z System Servers

Version 1.00

Mnemonic
IC

Opcode
43

Mnemonic
LLC

Opcode
E394

Mnemonic
LPGR

Opcode
B900

ICM

BF

LLCR

B994

LPR

10

ICMH

EB80

LLGC

E390

LR

18

58

LLGCR

B984

LT

E312

LB

E376

LLGF

E316

LTG

E302

LBR

B926

LLGFR

B916

LTGFR

B912

LCGFR

B913

LLGH

E391

LTGR

B902

LCGR

B903

LLGHR

B985

LTR

12

LCR

13

LLGT

E317

ST

50

LG

E304

LLGTR

B917

STC

42

LGB

E377

LLH

E395

STCM

BC

LGBR

B906

LLHR

B995

STCMH

EB2C

LGF

E314

LM

98

STG

E324

LGFR

B914

LMG

EB04

STH

40

LGH

E315

LMH

EB96

STM

90

LGHR

B907

LNGFR

B911

STMG

EB24

LGR

B904

LNGR

B901

STMH

EB26

LH

48

LNR

11

LHR

B927

LPGFR

B910

Chapter V: Basic Instructions

203

The instruction opcodes and mnemonics are shown in the following table:
Opcode
10

Mnemonic
LPR

Opcode
B907

Mnemonic
LGHR

Opcode
E314

Mnemonic
LGF

11

LNR

B910

LPGFR

E315

LGH

12

LTR

B911

LNGFR

E316

LLGF

13

LCR

B912

LTGFR

E317

LLGT

18

LR

B913

LCGFR

E324

STG

40

STH

B914

LGFR

E376

LB

42

STC

B916

LLGFR

E377

LGB

43

IC

B917

LLGTR

E390

LLGC

48

LH

B926

LBR

E391

LLGH

50

ST

B927

LHR

E394

LLC

58

B984

LLGCR

E395

LLH

90

STM

B985

LLGHR

EB04

LMG

98

LM

B994

LLCR

EB24

STMG

B900

LPGR

B995

LLHR

EB26

STMH

B901

LNGR

BC

STCM

EB2C

STCMH

B902

LTGR

BF

ICM

EB80

ICMH

B903

LCGR

E302

LTG

EB96

LMH

B904

LGR

E304

LG

B906

LGBR

E312

LT

We will use tables like these to summarize instruction mnemonics and their operation codes as
they are introduced.

Terms and Definitions


GR R n
A notation referring to the rightmost 32 bits of the general register specified by R n .
GR G n
A notation referring to the full 64 bits of the general register specified by R n .
GRn
A notation referring to the rightmost 32 bits of general register n.
GGn
A notation referring to 64-bit general register n.
insert
Place one or more bytes into a register without changing other bytes.
load operation
Replace the contents of a register with a copy of data from a memory address or from
another register. Other parts of the register may contain sign-extended bits (for arithmetic
loads), or zero-extended bits (for logical loads). The original contents of the target register
are not preserved.
Mn

204

The field of a machine instruction designating a mask.

Assembler Language Programming for IBM z System Servers

Version 1.00

Rn

The field of a machine instruction designating the number of a general register.

sign extension
The process of making copies of the sign bit of a shorter operand and extending it to the left,
to the length of a target field.
store operation
Place a copy of part or all of a registers contents into memory.
zero extension
The process of adding zero bits to the left of a shorter operand, to extend it to the length of a
target field.

Chapter V: Basic Instructions

205

15. Testing the Condition Code: Conditional Branching

11
111
1111
11
11
11
11
11
11
11
1111111111
1111111111

55555555555
55555555555
55
55
555555555
55555555555
555
55
55
555
55555555555
555555555

Branch instructions let you choose alternative actions in your program, depending on tests or
computed results whose status was indicated in the Condition Code.
The Condition Code is a two-bit field in the PSW (see Figure 12 on page 49), so its value is 0, 1,
2, or 3. To test the CC value we use a Branch on Condition instruction. The most common
are the RX-type instruction BC and the RR-type instruction BCR. The result of testing the value
of the CC determines whether or not the branch condition is met.
Well start with the basic forms of conditional branch instructions; newer forms are discussed in
Section 22. Other instructions whose actions depend on the value of the Condition Code are
described later.

15.1. The Branch Address


If the condition for branching is not met (well see how to determine this in a moment), no action
is taken and execution proceeds normally to the next sequential instruction following the Branch
on Condition instruction.
If the branch condition is met, the branch address is determined:
1. For the BC instruction, the branch address is the Effective Address, determined from the displacement, base, and index fields of the instruction.
2. For the BCR instruction, the branch address is contained in the general register specified by
the R 2 digit of the instruction. However, if the R2 digit is zero, no branch ever occurs: that
is, if R2=0, the branch condition is never met.
To complete execution of a branch instruction, the IA portion of the PSW is replaced by the
branch address. The next instruction to be fetched then comes from the address specified by the
branch address. Branch instructions are also called transfer instructions, in the sense that
control is transferred to the instruction at the branch address.
A successful branch instruction alters the normal sequencing of instruction fetching. If the IA is
not changed by the branch instruction, the next instruction fetched follows the branch instruction,
and we say that the branch was not taken.

206

Assembler Language Programming for IBM z System Servers

Version 1.00

15.2. The Branch Mask and Branch Condition


The branch condition is determined by examining a single bit of the third hex digit of the instruction denoted R 1 in Table 17 on page 109 and in Table 19 on page 110. For the BCR and BC
instructions this digit does not refer to GR R 1, but is treated as a bit pattern called a mask, M 1,
as we saw in Section 14.5 for the ICM and STCM instructions. The instructions have these
formats:
07

M1

R2

Table 57. BCR instruction

47

M1

X2

B2

D2

Table 58. BC instruction

For both the RR and RX instructions, M 1 is the mask digit. Thus, we could write
BCR

9,4

M1 = B1001

BC

7,4(8,2)

M1 = B0111

and
Figure 79. Examples of conditional branch instructions

where the mask fields are B1001 and B0111 respectively.


The CPU matches the value of the CC to one of the mask bits, as shown in Table 59. If a 1-bit
in the mask field position corresponds to the value of the CC, the branch condition is met; if the
CC value matches a 0-bit in the mask, the branch condition is not met and no branch occurs.
CC value
tested
0
1
2
3

Instruction bit
position
8
9
10
11

Mask bit
position

Mask bit
value

0
1
2
3

8
4
2
1

Table 59. Mask bits and corresponding CC values

Thus in Figure 79, the BCR 9,4 instruction would branch if the CC had values of 0 or 3, and the
BC 7,4(8,2) instruction would not branch if the CC had value 0.

Exercises
15.2.1.(2) Show how the value of the CC can be used as a bit index in determining which bit of
the mask digit to test.
15.2.2.(1) + Why does a mask value of 15 imply an unconditional branch?
15.2.3.(1) + What happens when BC 15,0 is executed?
15.2.4.(3) If 0 n 15, what will be the result of executing this instruction?
BC

n,n(n,n)

15.2.5.(1) + Using the information in Table 59, create a table with four rows of Condition Code
values (0, 1, 2, and 3) and columns of 16 BC mask values that show at each intersection
whether or not a branch will occur. (Feel free to transpose rows and columns if necessary.)

Chapter V: Basic Instructions

207

15.3. Examples of Conditional Branch Instructions


Here are some examples of conditional branching:
1. Branch to XX if the CC is zero.
The BC instruction mask field has value B1000, so the branch condition will be met only if
the CC is zero.
2. Branch to XX if the CC is not 0.
BC

M1 = B0111

7,XX

The mask has value B0111, so the branch condition will be met if the CC is 1, 2, or 3.
3. Branch to the instruction whose address is contained in GR14.
BCR

15,14

M1 = B1111

BC

15,0(0,14)

M1 = B1111

or
When all mask bits are one, the CC value must match a one-bit in the mask, so a branch
always occurs: this is called an unconditional branch. We could also have written the BCR
instruction as
BCR

X F , 1 4

BCR

B1111,14

or
M1 is very clear here!

4. Branch to XX if the CC is 1 or 3.
BC

5,XX

M1 = B0101

15.4. No-Operation Instructions


We noted in example 3 above that a mask of all 1-bits means the branch is unconditional,
because the branch condition is always met. Sometimes it is useful to execute an instruction that
has no effect, so we usually use a conditional branch instruction with a zero mask field. Thus,
BC

0,x

BCR

0,any

and
have no effect, because the branch condition can never be met. They are sometimes called nooperation or no-op instructions, and the Assembler provides special extended mnemonics for
them. The instructions
NOP

S2

and
NOPR R2
are treated by the Assembler as being the same as
BC

0,S2

BCR

0,R2

and
respectively. Only a single operand is specified for each NOP or NOPR instruction, and the
Assembler automatically provides the zero mask digit.

15.4.1. Special No-Operation Instructions (*)


One special type of no-operation instruction has an unusual side-effect. It has the form
BCR

208

15,0

M1 is B1111

Assembler Language Programming for IBM z System Servers

Version 1.00

Modern processors are highly pipelined. That is, the fetch, decode, and execute phases are processed internally in many smaller steps called stages.
Pipelining allows one instruction to begin its execution phase while the next is being decoded, and
the instruction after that is being fetched.95 Occasionally, it may be necessary to prevent this overlapped type of execution; this form of BCR instruction blocks execution of the following instruction until all preceding instructions have completed execution. This is sometimes called
draining or flushing the pipeline, and it can cause programs to execute more slowly.
BCR operands can be interpreted this way: 96
BCR
BCR
BCR
BCR
BCR

0,0
15,0
0,x
x,0
x,y

Branch
Branch
Branch
Branch
Branch

never nowhere
always nowhere (pipeline synchronization)
never somewhere (when x > 0)
sometimes nowhere (when 0 < x < X F )
sometimes somewhere (when 0 < x,y < X F )

Exercises
15.4.1.(2) + In trying to ensure that a BASR instruction was followed immediately by a word
address constant, a programmer wrote the following instructions as part of his program:
DS
NOPR
BASR
DC

0F
0
8,11
A(Anywhere)

Align to fullword boundary


2-byte No-op
2-byte BASR instruction
Properly aligned fullword constant

Explain why this might create an unexpected problem.


15.4.2.(2) What other instructions could be used in place of NOPR and NOP?
15.4.3.(1) Suppose you execute the instruction
BCR

15,0

Will an unconditional branch occur? If so, from what address will the next instruction be
fetched?
15.4.4.(2) Explain the execution-time differences between these two pairs of instructions:
L
BCR

1,=F 0
15,1

L
BCR

0,=F 0
15,0

15.5. Conditional No-Operation


An important use of no-operation instructions is to ensure a desired boundary alignment for a
particular instruction in a stream of other executable instructions. (We have already seen how to
obtain boundary alignments for data.) For example, we may require that an RR-type instruction
such as
BASR 8,11

95

96

The CPU is designed so that exception conditions at any stage are correctly recognized and handled as though each
instruction is completely processed (or prevented from executing) before the next is fetched. Early pipelined
processors couldnt always do this, and were subject to what were called imprecise interruptions. The CPU set the
Instruction Length Code (ILC) to zero, meaning that both it (and you) werent certain which instruction caused the
interruption.
This is not an official description.
Chapter V: Basic Instructions

209

be followed immediately (with no wasted space) by an aligned word constant such as an address
constant. While it is best not to mix instructions and data this way, there are times where such a
technique is useful.97
Since BASR is an RR-type instruction, we need to ensure that its location lies on a halfword
boundary between two word boundaries. In a small program, it may be easy to determine the
location of the BASR by counting LC values: if the BASR falls on a word boundary, insert a
NOPR

instruction just before it. But if the program is large or if changes must be made somewhere preceding the BASR, it is difficult to know whether the NOPR should be inserted or not.
To do this automatically, the Assembler provides the CNOP (Conditional No-Operation) assembler instruction. If the LC is already on the desired boundary, nothing is inserted. Otherwise,
CNOP inserts as many NOPR 0 and NOP 0 instructions as are needed to give the desired
alignment.
The operand field entry of a CNOP instruction is written
CNOP boundary,width
where boundary and width are absolute expressions. The boundary operand may have any
multiple-of-two value between 0 and 14, and its value must be less than the value of width,
which is 4, 8, or 16. A name field symbol is allowed, and its Length Attribute is always 1.
The width operand specifies the boundary relative to which alignment is performed, and
boundary specifies the desired halfword relative to that boundary, as shown in Table 60.98
Instruction
CNOP 0,4
CNOP 2,4
CNOP 0,8
CNOP 2,8
CNOP 4,8
CNOP 6,8
CNOP 0,16
CNOP 2,16
CNOP 4,16
CNOP 6,16
CNOP 8,16
CNOP 10,16
CNOP 12,16
CNOP 14,16

Location Counter Alignment


beginning of a word
middle of a word
beginning of a doubleword
second halfword of a doubleword
middle of a doubleword
fourth halfword of a doubleword
beginning of a quadword
second halfword of a quadword
second word of a quadword
fourth halfword of a quadword
second doubleword of a quadword
sixth halfword of a quadword
third word of a quadword
eighth halfword of a quadword

Table 60. CNOP operands

To achieve the alignment desired for the BASR in our example, we would write

97

98

Modern CPUs maintain high-speed buffers known as caches, one for fast access to instructions and another for
fast access to data items. If data items appear in the instruction cache, the CPU must stop pre-processing
instructions, load the data into the data cache (probably displacing useful data already there), and resume processing.
This can cause significantly slower execution, so you should avoid close mixing of instructions and data.
More precisely,
CNOP

boundary,width

causes the Assembler to insert enough NOPR 0 or NOP 0 instructions as may be needed to increment the LC (if
necessary) so that the new value of the LC satisfies boundary = LC (modulo width).

210

Assembler Language Programming for IBM z System Servers

Version 1.00

CNOP 2,4
BASR 8,11
DC
A(AnyWhere)

Align to middle of a word


Two-byte instruction
No intervening bytes

Note that we should not write


DS
0H
BASR 8,11
DC
A(AnyWhere)

No (??) intervening bytes

because alignment to a halfword boundary is automatically performed by the Assembler for


instructions. Thus, the BASR could still fall on a word boundary, and the Assembler would then
zero-fill the two bytes between the BASR and the address constant (because A-type constants
have an implied word alignment). Similarly, we could not write
BASR 8,11
DS
0F
DC
A(AnyWhere)
since the BASR could again fall on a word boundary, leaving two bytes between it and the constant that would be skipped by the Assembler. The contents of the two skipped bytes at execution
time are arbitrary, since the Supervisor does not always clear or otherwise initialize the area into
which a program is about to be loaded.
Name field symbols on CNOP instructions are rarely used, because branch-target symbols typically are given to instructions immediately preceding or following the CNOP. Thus, you could
write a symbol that is the name of nothing:
DS
0F
CNopName CNOP 0,4
CallSub BASR 14,15
- - -

Align on word boundary


Align on word boundary (again?)
Go to a subroutine

The two symbols CNopName and CallSub will have the same LC value even though CNopName
doesnt name anything different; it will have length attribute 1.
Figure 80 illustrates the alignment action of CNOP.

halfword1 halfword2 halfword3 halfword4 halfword5 halfword6 halfword7 halfword7


word1word2word3word4
doubleword1doubleword2
quadword
0,4
2,4
0,4
2,4
0,4
2,4
0,4
2,4
0,4
0,8
2,8
4,8
6,8
0,8
2,8
4,8
6,8
0,8
0,16
2,16
4,16
6,16
8,16
10,16
12,16
14,16
0,16
Figure 80. CNOP alignments and operands

Exercises
15.5.1.(2) + Suppose the Location Counter value is X0246 when each of these CNOP
instructions is processed by the Assembler. Determine the value of the LC after each CNOP is
processed.
(1)
(2)
(3)
(4)
(5)
(6)

CNOP
CNOP
CNOP
CNOP
CNOP
CNOP

2,4
0,4
6,8
10,16
4,16
2,8

Chapter V: Basic Instructions

211

15.5.2.(3) + For each of these sets of statements the value of the Location Counter is X000743
when the first statement is read by the Assembler. Give the length and value attributes of all
symbols.
1. A

DC
AL3(A)
CNOP 2,4
DC
A(B)

B
2. C
D

DC
C DS C&&
CNOP 0,4
DC
C D DC D DC

E
F

CNOP 2,8
DC
2F100
DC
(X F ) X F

3.

15.5.3.(1) In Exercise 15.5.2, what machine language data is generated by the statement named
D?
15.5.4.(2) + For each of the following, assume that the Location Counter value is X345 when
the initial statement is processed by the Assembler. Give the value and length attributes of the
symbol A.
1.
A

CNOP 2,4
LM
2,6,0(1)

CNOP 2,8
BC
10,Smith

2.

15.5.5.(2) + What will be generated by a CNOP 6,8 statement?

15.6. Extended Mnemonics


Conditional branch instructions are used frequently. It can be difficult to remember the Condition Code values and mask bit values associated with possible branch conditions, so the Assembler provides extended mnemonics for conditional branch instructions. They let you imply the
value of the mask field M1 of a BC or BCR instruction by using an extended mnemonic. For
example, an unconditional branch to an instruction named XX can be written
B

XX

which is easier and clearer than writing


BC

15,XX

Table 61 gives the extended mnemonics associated with the BC and BCR instructions. The
notations (A), (C), and (T) refer to the contexts in which each extended mnemonic is most
often used. The A mnemonics are typically used after Arithmetic instructions, C after Comparisons, and T after Tests.
Table 61 (Page 1 of 2). Extended branch mnemonics and their branch mask values

212

RX Mnemonic
B
BNO

RR Mnemonic
BR
BNOR

BNH
BNP
BNL
BNM

BNHR
BNPR
BNLR
BNMR

Assembler Language Programming for IBM z System Servers

Mask
15
14
13
13
11
11

Version 1.00

Meaning
Unconditional Branch
Branch if Not Ones (T)
Branch if No Overflow (A)
Branch if Not High (C)
Branch if Not Plus (A)
Branch if Not Low (C)
Branch if Not Minus (A)
Branch if Not Mixed (T)

Table 61 (Page 2 of 2). Extended branch mnemonics and their branch mask values

RX Mnemonic
BE
BZ
BNE
BNZ
BL
BM

RR Mnemonic
BER
BZR
BNER
BNZR
BLR
BMR

Mask
8
8
7
7
4
4

BH
BP
BO

BHR
BPR
BOR

2
2
1

NOP

NOPR

Meaning
Branch if
Branch if
Branch if
Branch if
Branch if
Branch if
Branch if

Equal (C)
Zero(s) (A,T)
Not Equal (C)
Not Zero (A,T)
Low (C)
Minus (A)
Mixed (T)

Branch if High (C)


Branch if Plus (A)
Branch if Ones (T)
Branch if Overflow (A)
No Operation

As this table indicates, the RR forms of the extended mnemonics are formed by adding the letter
R to the equivalent RX mnemonic.
Each of these instructions needs only a single operand field entry. Because the mask digit is
implied by the extended mnemonic, the operand may take any of the forms allowed for the
second operand of an RX- or RR-type instruction.
For example, we could write example 1 of Section 15.3 on page 208 as
BZ

XX

and example 2 could be written


BNZ

XX

There is no extended mnemonic corresponding to a mask value of 5, so there is no convenient


way to rewrite example 4.

Exercises
15.6.1.(2) + Programmers sometime write programs that contain instruction sequences like this:
Loop

Finish

- - - - BNZ Finish
B
Loop
- - -

Do something in the loop


Now make a test, set the CC
Exit the loop if something s nonzero
Otherwise repeat the loop
Rest of program

Why is this wasteful? How can it be made shorter, simpler, and (very probably) faster?
15.6.2.(1) Sometimes the conditional branch instructions are described as follows: The operation code for an unconditional branch is X47F , for a branch-on-zero is X478, etc. Is this an
accurate description?
15.6.3.(2) The word at VAL contains a 32-bit binary integer. Write an instruction sequence that
will branch to POS if c(VAL) is greater than zero, to NEG if c(VAL) is less than zero, and to
ZERO if c(VAL) is zero.
15.6.4.(2) A programmer accidentally wrote the operand of a branch instruction so that the
branch target was a constant containing a string of space characters:

Chapter V: Basic Instructions

213

B
Target
- - DC
CL132

Target

He meant to go elsewhere...
132 bytes containing X 4 0

What would you expect to happen?

15.7. A Comment on Programming Style


For short instruction sequences, it is sometimes tempting to avoid the effort of writing the name
of a target symbol. For example, sometimes a programmer may write
LTR 0,0
BZ
*+6
LR
0,5
- - -

instead of

LTR 0,0
BZ
Next
LR
0,5
Next - - -

The operand *+6 means the programmer knows that the lengths of BZ and LR are 4 and 2 bytes
respectively, and this has saved him the task of writing the symbol Next in two places.
However: suppose the logic of these statements needs to be updated, and extra instructions must
be added following the BZ instruction. If the operand of BZ (which was not the cause of the
change) isnt updated, it will branch into the added instructions and not to the intended target. 99
A Programming Practice to Avoid
Do NOT write operands of branch instructions using the Location
Counter value * number.

Exercises
15.7.1.(2) + A programmer wanted to be sure that the target of his branch instruction was at the
correct location, so he wrote

*+18

BZ
*+18
- - EQU *

Branch to known target location


More instructions
Define the target location.

Can he now be sure his BZ instruction will branch to the intended target?

15.8. A Design Oversight and a Modern Correction (*)


Due to a peculiarity in the original design of System/360 and System/370, invalid branch addresses
were not detected during the execute phase of the instruction cycle at the time the CPU finds the
branch condition is met. (Odd addresses produce specification errors, and excessively large
addresses can produce addressing exceptions.) The error is found only when the bad address is
presented, as the IA portion of the PSW, at the next instructions fetch cycle. The error is duly
detected and an interruption results, but the IA then contains the invalid address rather than the
address of the instruction that attempted the improper branch. This means that looking at the
Old PSW cant tell you where the error was caused, so such errors in a program are often very
difficult to correct. You must specify branch addresses accurately to avoid this particular error.
The Breaking Event Address Register (sometimes called the BEAR) was added to
z/Architecture. Whenever an instruction causes a break in normal sequential execution (such as a
successful branch), the address of the instruction causing the break or discontinuity is placed in
the BEAR. If the break causes a program interruption, the contents of the BEAR are stored in
a fixed address where error detection and diagnosis routines can use the break address to help you
find the instruction that caused the interruption.

99

214

A clever programmer knew instruction lengths so well that he avoided writing name-field symbols on statements by
coding instructions like B *+24 and BNZ *-20. Fixing errors in his code was very tedious.
Assembler Language Programming for IBM z System Servers

Version 1.00

Unfortunately, although the BEAR is accessible to ordinary problem-state programs, its contents
arent of much use unless its contents are captured at the moment an interruption occurs. So, to
answer questions like How did my program start executing instructions here?, we must depend
on the operating systems Supervisor to save the BEARs contents so the information can be used
for problem diagnosis.

Exercises
15.8.1.(1) + Explain why an odd branch address is invalid.

15.9. Summary
This section described the BC and BCR instructions and their forms as extended mnemonics.
There are many other types of branch instructions, but their most important features are based on
the concepts weve seen here; the others can be thought of as variations on the theme of this
section. Newer forms of conditional branch instructions will be described in Section 22.1.

Exercises
15.9.1.(1) How could you design a CPU without a Condition Code or similar indicators?
15.9.2.(1) + Can an instruction generate multiple CC values in a single execution?
The instruction mnemonics and opcodes are shown in the following table:
Mnemonic
BC

Opcode
47

Mnemonic

Opcode

BCR

07

The instruction opcodes and mnemonics are shown in the following table:
Opcode
07

Mnemonic
BCR

Opcode

Mnemonic

47

BC

Terms and Definitions


branch condition
The CPUs decision whether to alter the normal sequential execution of instructions by
fetching instructions at the branch address.
branch address
The address from which the next instruction will be fetched if the branch condition is met.
branch mask
A 4-bit field in a Branch on Condition instruction used to test the value of the Condition
Code. If a 1-bit in the branch mask matches the CC value, the branch condition is met.
no-operation instruction
An executable instruction having no effect other than to occupy space.
conditional no-operation
An Assembler CNOP instruction that may generate NOP and NOPR instructions, causing
the Location Counter to be aligned on a specified even boundary.
extended mnemonic
An instruction mnemonic provided by the Assembler allowing you to specify a branch mask
implicitly.

Chapter V: Basic Instructions

215

pipeline
A technique used in modern CPUs to speed instruction execution by dividing the fetch.
decode, and execute phases into smaller stages that can be occupied by more than one
instruction.

216

Assembler Language Programming for IBM z System Servers

Version 1.00

Chapter V: Basic Instructions

217

16. Fixed-Point Binary Addition, Subtraction, and Comparison

11
111
1111
11
11
11
11
11
11
11
1111111111
1111111111

6666666666
666666666666
66
66
66
66
66666666666
666666666666
66
66
66
66
66
66
666666666666
6666666666

This section describes instructions for fixed-point twos complement binary addition, subtraction,
and comparison in the general registers, and between the general registers and memory. Because
the instructions occur in very regular groups and patterns, understanding their basic behavior
makes it easier to understand related instructions.

16.1. Signed-Arithmetic Add and Subtract Instructions


As we noted in Section 2.14 on page 39, logical addition and subtraction produce exactly the
same bit patterns as arithmetic addition and subtraction, but the resulting CC settings have different meanings. Well investigate logical-arithmetic instructions in Section 16.5 on page 225.
The instructions are shown in Table 62. The first six generate 32-bit results, and the others
produce 64-bit results.
Op
5A
5B
4A

Mnem
A
S
AH

Type
RX
RX
RX

Instruction
Add (32)
Subtract (32)
Add Halfword (3216)

E308
E309

AG
SG

RXY Add (64)


RXY Subtract (64)

Op
1A
1B
4B

Mnem
AR
SR
SH

B308 A G R
B309 SGR

Table 62. Frequently used add and subtract instructions

218

Assembler Language Programming for IBM z System Servers

Version 1.00

Type
RR
RR
RX

Instruction
Add Register (32)
Subtract Register (32)
Subtract Halfword (3216)

R R E Add Register (64)


R R E Subtract Register (64)

16.2. Signed-Arithmetic Operations Using 32-Bit Registers


All the instructions in Table 62 set the Condition Code as indicated in Table 63.
Operation
c(GR R 1) = c(GR R 1) c(GR R 2)
c(GR R 1) = c(GR R 1) c(Word in memory)

CC Setting and Meaning


0: Result is zero
1: Result is < zero
2: Result is > zero
3: Result has overflowed

Table 63. CC settings for arithmetic add and subtract instructions

Table 63 shows that these add and subtract instructions (like the LCR and LPR instructions in
Table 44 on page 190) can cause a fixed-point overflow exception. Well see in Section 16.9 on
page 235 how to set the Program Mask to enable or disable an interruption.
We begin with the six add/subtract instructions A/AR, S/SR, and AH/SH. In each case, the
second operand is added to or subtracted from the first operand, and the result replaces the first
operand.
For the halfword operations AH and SH, the 16-bit second operand is brought from memory to
an internal register, extended to a word in length, and then used for the indicated operation (as we
saw in the description of LH in Section 14.3 on page 184). The notation (3216) in Table 62
means that the 16-bit operand is extended to 32 bits.
To illustrate arithmetic addition and subtraction, suppose we must store at ANS the sum of c(X)
and c(Y), unless the sum is negative, in which case we must also add c(Z) and subtract 17. If we
assume that X, Y, and Z name word areas of the program, then the following instructions will
calculate the required value (assuming no overflows occur).

ST
X
Y
Z
ANS

L
6,X
A
6,Y
BNM ST
A
6,Z
SH
6,=H 1 7
ST
6,ANS
- - DC
F 7 1
DC
F -220
DC
F284
DS
F

Copy c(X) into GR6


c(GR6) = c(X) + c(Y)
Branch if sum is not negative
It was negative; add c(Z)
Subtract 17
Store answer at ANS

Computed answer

Figure 81. Calculate a sum with an intermediate test

All the machine instructions are RX-type, and all but BNM refer to data operands in memory.
The characters ST are used both as a symbol and as an instruction mnemonic. No confusion is
possible, since the Assembler identifies a mnemonic only by its appearance as an operation field
entry.
Now, suppose we want to store the sum of the first N odd numbers at the word named Sum
where the positive integer N is stored in the halfword integer at NN.

Chapter V: Basic Instructions

219

AddUp

NN
Sum

LH
LM
AR
AR
SR
BNZ
ST
- - DC
DS

3,NN
6,9,=F 0 , 2 , 1 , 1
6,8
8,7
3,9
AddUp
6,Sum

Get the value of N from c(NN)


Load GR6-GR9 with 0,2,1,1
Add odd integer to sum in GR6
Next odd integer in GR8
Decrease N by 1
Branch back (N-1) times
Store result in GR6 at SUM

H 6
F

Number of odd numbers to add


Sum of the first c(NN) odd numbers

Figure 82. Calculate the sum of the first N odd integers

In this example, the calculations inside the loop100 (the AR and SR instructions beginning at
Addup) are RR-type instructions; no memory references are needed. This technique is useful in
programs where processing speed is important, and enough registers are available to allow frequently referenced operands to be carried in registers instead of in memory.101
To give another simple example of using some of these instructions, suppose we wish to compute
the quantity NewStock from the formula
NewStock = OldStock + Received - Sold
where all quantities are word integers small enough in value to guarantee that no overflows will
occur. These statements will compute the desired result.
L
A
S
ST

2,OldStock
2,Received
2,Sold
2,NewStock

Get c(OldStock) in GR2


Add number of items received
Subtract number of items sold
Store result at NewStock

Figure 83. Example of arithmetic addition and subtraction

Although we assumed that no overflows can occur, it may be possible that values calculated elsewhere in the program could cause an overflow here. Thus, to be careful, the above code sequence
might continue with the instructions
- - ST
2,NewStock
BZ
ReOrder
BM
OverSold
BO
Disaster

(As above)
(As above)
None left, must order more!
Reorder now! Sold more than stock!
Error! More than 2**31 items??

Figure 84. Testing the result of arithmetic instructions

The instructions at ReOrder and OverSold will probably do similar things, except that at OverSold
the order for new items would likely be given higher priority so our customers can receive their
previously ordered products more promptly.

Exercises
16.2.1.(2) In Figure 81, what will be stored at ANS if overflow occurs?
16.2.2.(3) Show that the sum of the first N odd integers is the same as N 2.

100

101

220

A loop is a sequence of instructions executed repeatedly until some condition is satisfied. Well see in Section 22 how
other instructions help us write efficient loops.
Dont be too impressed, however: the example is mathematically futile, because we have expended all this effort to
calculate the square of N, when a single multiply instruction would have worked just as well. (See Exercise 16.2.2 for
some mathematical background.)
Assembler Language Programming for IBM z System Servers

Version 1.00

16.2.3.(2) + In Figure 82, we assumed that the positive integer N in c(NN) is 2 or greater.
Rewrite the instructions to handle the possibility that N may be as small as 1.
16.2.4.(2) + In a large program, a programmer wanted to decrement the value of an integer variable at VARBL by 1, so he wrote the instructions
Load

VARBL
ONE

L
S
ST
- B
- DC
DC

2,VARBL
2,ONE
2,ONE
(Error! Meant to use VARBL !)
Load
Try again
F 4
F 1

Unfortunately, the ST instruction stores the result in the wrong place! The program went into
an infinite loop that included the three instructions above. What sequence of values appeared
in the word named ONE?
16.2.5.(3) + Given a word integer stored at Data, write an instruction sequence that will count
the number of 1-bits in the word, and store the result in the halfword named NBits.
16.2.6.(3) + Given a word integer stored at Data, write an instruction sequence that will determine the maximum power of 2 in the word, and store the result in the halfword named MaxPow.
For example, the largest power of 2 in 9=B1001 is 3. If c(Data) is zero, store 1, and if
c(Data) is negative, store 31.
16.2.7.(2) In Figure 82, what would happen if we had written
NN

DC

F 6

16.2.8.(3) + Complete the assembly of this program segment by showing the generated object
code and its locations.
Loc

Object Code

5000
____
____
____
____
____
____
____
____
____

0D40_________
_____________
_____________
_____________
_____________
47___________
_____________
_____________
_____________
_____________

Assembler Language Statements


Ex16_2_8 Start X5000
BASR 4,0
Using *,4
SR
2,2
IC
2,XX+3
LTR 0,2
BZ
Looper
STH 0,XX
Looper B
*
Loop forever here
YY
DC
CL4 Ugh
XX
DC
F -10

16.2.9.(4) When the program in Exercise 16.2.8 is stopped (because it is in an unending


loop), what will be the hexadecimal contents of the word at XX?
16.2.10.(2) + Can an arithmetic operation using AH or SH cause fixed-point overflow? Explain.
16.2.11.(3) + Suppose two constants are defined as follows:
X
Y

DC
DC

FL31234567
FL37654321

Write a sequence of instructions that will add the two numbers and store their sum as a 24-bit
twos complement number in the three-byte field starting at W. If the sum overflows (it cant
be represented correctly in 24 bits), branch to Over.
16.2.12.(2) In Exercise 16.2.11, what data is generated for the constant named Y?
16.2.13.(2) Explain the differences between these instruction pairs:
Chapter V: Basic Instructions

221

SR
BCR

1,1
15,1

and

SR
BCR

0,0
15,0

16.2.14.(3) + Complete the assembly of this (nonsensical) program segment by showing the
generated object code and its locations.
Loc
8000
____
____
____
____
____
____
____
____
____
____
____
____

Object Code
_____________
_____________
_____________
_____________
_____________
_____________
_____________
_____________
_____________
_____________
_____________
_____________

Assembler Language Statements


Ex16_2_E Start X8000
BASR 4,0
Using *,4
LM
1,2,Value
STCM 2,B 1 1 1 , First
LCR 0,1
BC
10,*+8
STH 0,Last(1)
BCR 15,14
Value
DC
F 4
DC
F -6
First
DS
F
Last
DS
H -10

16.2.15.(2) + Show the contents of GR2 and the Condition Code setting after executing each of
the following instruction sequences:
1.

L
AR

2,=A(X89ABCDEF )
2,2

2.

L
A

2,=F 2
2,=A(X 7 FFFFFFF )

3.

L
A
ICM

2,=F 2
2,=A(X123345)
2,2,=X12345

16.3. Signed-Arithmetic Operations Using 64-Bit Registers


We now investigate the instructions in the second group pictured in Table 62 on page 218. The
AG/AGR and SG/SGR instructions are 64-bit analogs of the 32-bit instructions A/AR and S/SR
illustrated above. To illustrate, suppose we revise the example in Figure 81 to use 64-bit operands:
LG
6,XX
AG
6,YY
BNM ST
AG
6,ZZ
SG
6,=FD 1 7
ST
STG 6,DAnswer
- - XX
DC
FD7569241038
YY
DC
FD -94226701151
ZZ
DC
FD137
DAnswer DS
FD

c(GG6) = c(XX) + c(YY)


Branch if sum is not negative
It was negative; add c(ZZ)
Subtract 17 (doubleword literal)
Store result

Computed result

Figure 85. Calculate a 64-bit sum with an intermediate test

In this example, we cannot use the literal =H 2 because the z System instruction set does not
(now) provide the AGH and SGH instructions. 102 (See Exercises 16.3.1 and 16.3.2.)

102

222

At the time of this writing. But new instructions like AGHI (that well see in Section 21) are added regularly to the
z System architecture, so check the Principles of Operation.
Assembler Language Programming for IBM z System Servers

Version 1.00

Suppose we add these two large numbers:

A
B
C

LG
0,A
Get c(A)
AG
0,B
... and c(B)
STG 0,C
Store sum at C
- - DC
FD9223372036854775807 = 2**63-1
DC
FD9223372036854775807
DS
FD
Result =X FFFFFFFFFFFFFFFE = -2, CC=3

Figure 86. Adding two 64-bit numbers

Because a fixed-point overflow has occurred, the result is arithmetically invalid.

Exercises
16.3.1.(2) Suppose you need to add a halfword value stored in memory at HW to a 64-bit value
in GG0, and the CPU has no AGH instruction. What alternative instruction sequences could
you use?
16.3.2.(2) Do the same as in Exercise 16.3.1, but now consider subtracting the HW operand from
the 64-bit operand in GG0.

16.4. Signed-Arithmetic Compare Instructions


Table 64 lists the arithmetic compare instructions well examine:
Op
49
59
E359

Mnem
CH
C
CY

Type
RX
RX
RXY

Instruction
Compare Halfword (3216)
Compare (32)
Compare (32)

E320

CG

RXY Compare (64)

Op
Mnem
E379 CHY
19
CR

Type Instruction
RXY Compare Halfword (3216)
R R Compare (32)

B920 C G R

R R E Compare (64)

Table 64. Arithmetic compare instructions

These instructions compare the magnitudes of two arithmetic operands. Thus, all positive
numbers are greater than all negative numbers, and 2 is greater than 4. (We will see that
logical comparisons behave differently.) The results of an arithmetic comparison are indicated in
the CC setting, as shown in Table 65.
CC
0
1
2

Meaning
Operand 1 = Operand 2
Operand 1 < Operand 2
Operand 1 > Operand 2

Table 65. CC settings after arithmetic comparisons

The CC cannot be set to 3 as a result of a compare instruction.


For the CR, C, and CH instructions, the CC setting is the same as would result from performing
SR, S, and SH instructions with the same operands, assuming that no overflow occurs. In fact,
this is how the comparison is done by the CPU: a subtraction is performed internally, and the
CC is set to reflect the sign and magnitude of the difference (that would then have been placed
back in GR R 1 or GG R 1 for a subtract instruction). Further analysis of the original operands is
required in the CPU if the internal result overflows. (See Exercise 16.4.2.)
To illustrate arithmetic comparisons, consider these instructions and their comment fields:

Chapter V: Basic Instructions

223

LM
0,3,=F 1 , 0 , -1,-2147483647 Initialize registers GR0-GR3
c(GR0) = -1, c(GR1) = 0, c(GR2) = +1, c(GR3) = X80000001
CR
1,3
CC = 2
0 > -2147483647
CR
0,2
CC = 2
1 > -1
CR
2,3
CC = 2
-1 > -2147483647
LPR 4,3
CC = 2
+2147483647 > 0
CR
4,3
CC = 2
+2147483647 > -2147483647
CR
1,0
CC = 1
0 < 1
C
0,=F 1
CC = 0
1 = 1
CH
1,=H 5
CC = 1
0 < 5

Figure 87. Examples of arithmetic comparisons

As an example of the use of a compare instruction, let us recalculate the sum of the first N odd
integers, using a different scheme from the one in Figure 82 on page 220.

Test

Store

LH
LR
CH
BE
LR
AR
AH
AR
AH
B
ST

4,=H 1
7,4
7,NN
Store
0,7
0,0
0,=H 1
4,0
7,=H 1
Test
4,Sum

c(GR4) = accumulated sum


c(GR7) = count of additions
Compare count to c(NN)
Branch if equal, N terms added
Compute next odd integer
Counter + counter = 2N
Add 1, giving next odd term
Add term to sum
Increment count by 1
Branch back to see if finished
Store result

Figure 88. Calculate the sum of N odd integers

This example is cumbersome but yields the desired result.103


The arithmetic comparison instructions for 64-bit registers do exactly the same operations as the
equivalent instructions do for 32-bit registers. If the second operand is shorter than the R1 register, it is sign-extended internally to the length of the first operand before doing the comparison.

Exercises
16.4.1.(1) + Why can the CC not be set to 3 in a comparison operation?
16.4.2.(3) In executing arithmetic compare instructions, the CPU performs an internal subtraction. By examining the possible combinations of signs and magnitudes for the two operands, determine (1) when an internal overflow might occur as a result of the internal
subtraction, and (2) what the CPU must do to set the CC correctly in such cases.
16.4.3.(2) Suppose a programmer had written the last instruction in Figure 87 as
CH

1,=F 5

(Rather than =H 5 )

What would the CC setting be?


16.4.4.(2) + In the following program, some pieces of data are missing, as indicated by the ____
spaces. Using the available information, fill in those spaces.

103

224

There are often many ways to perform the same computation. Programming is as much an art as a science, since
you can write many different programs of varying degrees of efficiency, effectiveness, or elegance to achieve a given
objective. A key consideration is that your program be understandable by others who may have to enhance (or fix) it
in the future.
Assembler Language Programming for IBM z System Servers

Version 1.00

Loc

Object Code

4800
4802
4802
4806
480A
480E
4824
4828
482C
4854
4858
485C

_____________
_____________
_________A056
_____________
5000_________
<other ops>
59___________
47___________
<other ops>
00000000
00000001
_____________

Assembler Language Statements


Ex16_4_4 Start X4800
BASR 10,0
Using *,10
Loop
L
0,________
A
0,One
ST
0,Number
PrintOut Number
C
0,Ten
BL
Loop
PrintOut *
Number DC
F 0
One
DC
F 1
Ten
DC
F 1 0
End Ex16_4_4

16.5. Logical-Arithmetic Add and Subtract Instructions


Logical-arithmetic instructions are used less often than signed-arithmetic instructions. They are
typically used for extended-length or multiple-precision arithmetic (well see some examples), and
on occasions when a sum or difference must be found without any possibility of a fixed-point
overflow interruption. (The CPU calculates Effective Addresses using logical arithmetic, but does
not set the Condition Code.)
Table 66 lists the logical arithmetic instructions we examine here:
Op
5E
5F

Mnem
AL
SL

Type Instruction
R X Add Logical (32)
R X Subtract Logical (32)

Op
1E
1F

Mnem
ALR
SLR

Type Instruction
R R Add Logical (32)
R R Subtract Logical (32)

E30A
E30B

ALG
SLG

RXY Add Logical (64)


RXY Subtract Logical (64)

B90A ALGR
B90B SLGR

R R E Add Logical (64)


R R E Subtract Logical (64)

Table 66. Logical arithmetic instructions

The CC settings we saw in Table 62 on page 218 for signed arithmetic are different for logical
arithmetic. The Condition Code settings shown in Table 67 apply to all logical arithmetic
instructions, so that references to c(GR R 1) also apply to c(GG R 1).
Operation
c(GR R 1) = c(GR R 1) c(GR R 2)
c(GR R 1) = c(GR R 1) c(Word in memory)

CC Setting and Meaning


0: Zero result, no carry
1: Nonzero result, no carry
2: Zero result, carry
3: Nonzero result, carry

Table 67. CC settings for logical add and subtract instructions

In Table 67, the CC settings for the logical arithmetic instructions depend only on whether a carry
occurs out of the leftmost position of the R1 register, and whether the result is zero. (Note that
CC3 does not mean an overflow has occurred!) By referring to the examples in Sections 2.6 and
2.14, we see that the following rules hold:
1. A CC zero setting is possible for AL and ALR, and for ALG and ALGR, only if the first
and second operands are both zero.
2. It is not possible to have a CC setting of zero for SL and SLR, or for SLG and SLGR. After
the ones complement of the second operand and a low-order 1-bit are added to the first
operand, a carry must have occurred if the result is zero.

Chapter V: Basic Instructions

225

To illustrate the differences between arithmetic and logical addition and subtraction, consider
examples 1 and 2 of Section 2.11 on page 34.
Example 1. For unsigned operands, the result of 5 3=2 is representable.
5-3:

0000 0101
-0000 0011

becomes

(carry lost)

0000 0101
+1111 1101
0000 0010 = 2

When we logically subtract unsigned operands, the presence of a carry means that the result
was valid, and that there was no need to borrow from any higher-order digit positions.
Example 2. For unsigned operands, the result of 3 5 cannot be correctly represented without
borrowing from higher-order digit positions (negative values dont exist in this 8-bit representation).
3-5:

0000 0011
-0000 0101

becomes

(no carry)

0000 0011
+1111 1011
1111 1110 = -2 (arithmetically, not logically!)

Thus, when logically subtracting unsigned operands, the absence of a carry means that we need
to borrow from a higher-order digit position.
Table 68 summarizes these observations:
Operation
Logical
Addition
Logical
Subtraction

Carry

No Carry

Carry to higher-order position

No carry to higher-order position

No borrow from higher-order position

Borrow from higher-order position

Table 68. CC indications for logical addition and subtraction

As in Figure 86, we can use logical arithmetic to add the same two numbers:

A
B
C

LG
0,A
Get c(A)
ALG 0,B
... and c(B)
STG 0,C
Store sum at C
- - DC
FD9223372036854775807
DC
FD9223372036854775807
DS
FD
Result =X FFFFFFFFFFFFFFFE , CC=3

Figure 89. Adding two 64-bit numbers logically

The result at C is the same as before, but now there is no fixed-point overflow.
In the next section we will see how the presence or absence of a carry condition is used when we
add and subtract long or multiple-precision numbers.
To illustrate a typical use of logical arithmetic, suppose we must add and subtract 64-bit integers
represented by pairs of 32-bit integers: that is, double-length integers two words long. (Doublelength integers are also encountered as products and dividends.) That is, we must do integer
arithmetic with operands longer than a single general register.
First, consider how we find the twos complement (the negative) of such a 64-bit number. Since
we know that the twos complement is found by adding a low-order 1-bit to the ones complement of the number, we might proceed as follows. The number to be complemented is stored in a

226

Assembler Language Programming for IBM z System Servers

Version 1.00

doubleword at ARG, and c(GR0,GR1) means the contents of the double-length register pair
formed by GR0 and GR1.
L
0,=F -1
All one bits in GR0
LR
1,0
c(GR0,GR1) is now all 1-bits
SL
0,ARG
Ones complement of high-order part
SL
1,ARG+4
Ones complement of low-order part
AL
1,=F 1
Now add the low-order 1 bit
BC
B1100,NoCarry
Branch if no carry out of GR1 occurs
AL
0,=F 1
Propagate the carry bit to GR0
NoCarry STM 0,1,ARG
Store final result back at ARG
- - ARG
DC
FD123456787654321 64-bit integer
Figure 90. Double-length complementation

The first AL instruction must be used rather than an A instruction because the high-order bit of
GR1 is not a sign bit, but an arithmetically significant bit with weight 231 . If a carry out of GR1
occurs, it must be detected and propagated into the low-order bit of GR0.
The same complementation is performed by the following code sequence, but more directly (and
less obviously).

XXX
ARG

LM
0,1,ARG
Get double-length operand
LCR 0,0
Complement high-order half
LCR 1,1
Complement low-order half
BZ
XXX
Jump if c(GR1) was 0
SL
0,=F 1
Subtract 1 from GR0
STM 0,1,ARG
Store result at ARG
- - DC
FD123456787654321 64-bit integer

Figure 91. Double-length complementation, a simpler way

The first LCR instruction forms the twos complement of the high-order 32 bits in c(GR0); that
is, we have already added a low-order 1-bit to the ones complement of c(GR0). The following
LCR complements the low-order 32 bits, and sets the CC. If c(GR1) had been zero, its ones
complement would have been all 1-bits, and adding a low-order one would cause a carry out the
left end of R1; the first LCR has already propagated a carry into GR0. For any other bit
pattern, no such carry would have occurred, so we must correct c(GR0) by subtracting off the
low-order bit that was automatically added during the execution of the first LCR. 104
Adding the two double-length integers at A and B is straightforward: the instructions are explained
in the comments.
LM
0,1,A
AL
1,B+4
BC
B1100,NoCarry
AL
0,=F 1
NoCarry AL
0,B
STM 0,1,Sum
- - Sum
DS
FD
A
DC
FD888777666555
B
DC
FD222333444555

Load A into c(GR0,GR1)


Add low-order part of B
Branch if no carry
Propagate carry to high-order word
Add high-order part of B
Store the double-length sum
8 bytes, aligned

Figure 92. Double-length addition

104

This instruction sequence has a minor defect: if either of the LCR instructions complements the maximum negative
number X80000000, a fixed-point overflow exception could occur. (See Exercise 16.6.5.)
Chapter V: Basic Instructions

227

Subtracting 64-bit operands is done the same way, except that the condition code setting after the
first logical subtraction requires explanation.
LM
SL
BC
SL
NoBorrow SL
STM
- Diff
DS
A
DC
B
DC

0,1,A
1,B+4
B0011,NoBorrow
0,=F 1
0,B
0,1,Diff

Get first operand as c(GR0,GR1)


Subtract low-order parts
Branch if there s a carry
Reduce c(GR0) by 1 (i.e., borrow 1)
Subtract high-order parts
Store 64-bit difference

FD
FD234567898765432
FD123456787654321

Figure 93. Double-length subtraction

In performing a subtraction, the ones complement of the second operand and a low-order 1-bit
are added to the first operand. If a carry occurs out of the high-order bit position of the low-order
register, then the result is correctly represented. If a carry does not occur the result is not correctly
represented, in the sense that we have tried to generate a negative integer in the logical representation. Hence we must borrow a 1-bit from the next higher bit position, so we subtract =F1
if the branch condition is not met.
It might help to review the examples in Section 2.11 on page 34 to clarify the relationship
between carries and overflow in the arithmetic and logical representations. The instructions in
Section 16.6 greatly simplify these operations.
Using 32-bit registers to calculate 64-bit results is unnecessary if you need only 64-bit results,
because you can use 64-bit operations instead. But if you need to calculate the 128-bit sum of two
64-bit operands, these techniques are useful. (See Exercise 16.7.4.)
To see how logical arithmetic can provide possibly misleading arithmetic results, consider the
example in Figure 83 on page 220, revised to use logical add and subtract instructions:
L
AL
SL
ST

2,OldStock
2,Received
2,Sold
2,NewStock

Get c(OldStock) in GR2


Add number of items received
Subtract number of items sold
Store result at NewStock

Figure 94. Example of logical addition and subtraction

These instructions (using logical add and subtract) are not recommended, for two reasons. First,
although the result stored at NewStock is the same in both cases, the CC setting is not; if we
follow the ST instruction by conditional branch instructions that depend on the arithmetic sign of
the result (as in Figure 84 on page 220), the branch instructions may not go to the intended
targets.

Exercises
16.5.1.(2) Suppose the instruction sequence in Figure 94 is followed by the three branch
instructions in Figure 84 on page 220. What results will cause branching to each of the three
target symbols?
16.5.2.(2) + In the complementation instructions shown in Figures 90 and 91, what additional
instructions would be needed to cause a branch to OverFlow if the 64-bit result of the
complementation overflowed?
16.5.3.(3) + In the addition instructions shown in Figure 92, what additional instructions would
be needed to cause a branch to OverFlow if the 64-bit result of the addition overflowed?

228

Assembler Language Programming for IBM z System Servers

Version 1.00

16.5.4.(2) + In the subtraction instructions shown in Figure 93, what additional instructions
would be needed to cause a branch to OverFlow if the 64-bit result of the subtraction overflowed?
16.5.5.(2) In Figure 91, if either 32-bit operand is the maximum negative number,
complementation by the LCR instructions will cause a fixed-point overflow condition. Revise
the instructions to produce the 64-bit twos complement without any overflow condition.
16.5.6.(3) Examine the instructions in Figures 92 and 93. Make a short table indicating all the
possible CC settings, and the operands that produce them.
16.5.7.(3) Examine the instructions in Figures 92 and 93. Revise them to set the contents of the
word at CCode to contain the correct CC setting after addition and subtraction. If you can
make the actual CC setting correct, so much the better.
16.5.8.(3) Write a sequence of instructions that form the twos complement of a 64-bit integer
represented as a pair of 32-bit words, that also set the CC to the same value as LCGR does for
the same 64-bit integer.
16.5.9.(3) In the examples of the addition and subtraction of double-length numbers in Figures
92 and 93, make modifications to the code such that if the final double-length result overflows,
control will be transferred to OVER. The register contents need not be correct if such a transfer
is made.
16.5.10.(4) Do the same as for Exercise 16.5.9, but after the addition or subtraction, the word
named CCode should reflect the condition of the double-length result, which should also be correctly represented to 64 bits. That is, using 32-bit registers, compute the 64-bit sum as though
a 64-bit addition is performed. Extra credit: make the actual CC setting correct,
16.5.11.(2) + Write an instruction sequence using ALC to add two 128-bit numbers represented
as two groups of four fullwords each.
16.5.12.(2) + For the logical add and subtract instructions, each bit of the CC has a particular
meaning. Make a table with two rows and two columns summarizing the meanings of the four
possible CC values as a function of the values of its two bits.
16.5.13.(1) If a logical subtraction is performed with two operands that are identically zero, why
is the resulting CC setting not zero?

16.6. Add With Carry, Subtract With Borrow (*)


Referring to Table 67, we can represent the Condition Code settings for logical addition in a different way, as shown in Table 69.
CC bit
Left
Right

0
No carry
Zero result

1
Carry
Nonzero result

Table 69. CC settings after logical addition

Thus, the leftmost bit of the CC can be thought of as the carry bit. Similarly, referring to Table
68, another way to represent the CC settings for logical subtraction is provided in Table 70.
CC bit
Left
Right

0
Borrow (no carry)
Zero result

1
No borrow (carry)
Nonzero result

Table 70. CC settings after logical subtraction

Chapter V: Basic Instructions

229

The instructions in Table 71 take advantage of the leftmost CC bit to minimize the number of
instructions needed to do double-length (or multiple-length) arithmetic 105 by using the CC bit to
propagate a carry or borrow to the next higher-order operand.
Op
E398
E388

Mnem
ALC
ALCG

Type Instruction
RXY Add Logical with Carry (32)
RXY Add Logical with Carry (64)

Op
Mnem
Type Instruction
B998 ALCR
R R E Add Logical with Carry (32)
B988 ALCGR R R E Add Logical with Carry (64)

E399

SLB

B999 SLBR

E389

SLBG

RXY Subtract Logical with Borrow


(32)
RXY Subtract Logical with Borrow
(64)

R R E Subtract Logical with


Borrow (32)
B989 SLBGR R R E Subtract Logical with
Borrow (64)

Table 71. Logical arithmetic instructions with carry/borrow

Now, we can use these instructions to improve the examples of double-length addition and subtraction shown in Figures 92 and 93. First, consider addition: now, the intermediate branch and
addition of a low-order 1 are unneeded.

Sum
A
B

LM
0,1,A
AL
1,B+4
ALC 0,B
STM 0,1,Sum
- - DS
FD
DC
FD888777666555
DC
FD222333444555

Load A in register pair


Add low-order part of B
Add high-order part of B with carry
Store the double-length sum
8 bytes, aligned

Figure 95. Double-length addition with carry

Similarly, the double-length subtraction can be rewritten:

Diff
A
B

LM
SL
SLB
STM
- DS
DC
DC

0,1,A
1,B+4
0,B
0,1,Diff

Get first operand


Subtract low-order parts
Subtract high-order parts with borrow
Store 64-bit difference

FD
FD234567898765432
FD123456787654321

Figure 96. Double-length subtraction with borrow

Exercises
16.6.1.(2) + Repeat Exercise 16.5.9, using Add Logical With Carry and Subtract Logical With
Borrow instructions as appropriate.
16.6.2.(3) Repeat Exercise 16.5.9, using Add Logical With Carry and Subtract Logical With
Borrow instructions as appropriate, this time storing the proper Condition Code value at CCode.
16.6.3.(3) + Suppose two 256-bit integers are stored as eight consecutive words (or four consecutive doublewords) in memory starting at A256 and B256 respectively. Using Add Logical With
Carry and Subtract Logical With Borrow instructions, write instructions to store their sum and
difference at Sum256 and Diff256 respectively.

105

230

Multiple-precision arithmetic is used intensively in cryptographic applications for data security.


Assembler Language Programming for IBM z System Servers

Version 1.00

16.6.4.(3) In Exercise 16.6.3, the add and subtract instructions do logical arithmetic. How
would you detect an arithmetic overflow?

16.7. Operations With Mixed 64-Bit and 32-Bit Operands


The instructions in Table 72 all involve a 64-bit first operand and a 32-bit second operand.
Op
B318
B309
E31A
E31B
E330

Mnem
AGF
SGF
ALGF
SLGF
CGF

Type
RXY
RXY
RXY
RXY
RXY

Instruction
Add (6432)
Subtract (6432)
Add Logical (6432)
Subtract Logical (6432)
Compare (6432)

Op
B318
B319
B91A
B91B
B930

Mnem
AGFR
SGFR
ALGFR
SLGFR
CGFR

Type
RRE
RRE
RRE
RRE
RRE

Instruction
Add Register (6432)
Subtract Register (6432)
Add Logical (6432)
Subtract Logical (6432)
Compare (6432)

Table 72. Instructions for mixed-length operands

The AGF and SGF instructions are similar to AH and SH, except that instead of sign-extending a
16-bit memory operand to 32 bits, a 32-bit memory operand is extended to 64 bits before participating in the 64-bit operation, as illustrated in Figure 97.

 sign extended s
GG R1

0

63

32bit second operand s

0
31
Figure 97. Sign extension for instructions with mixed 32- and 64-bit signed operands

Using SGF, we can modify the example in Figure 85 to use a word literal:

ST

LG
AG
BNM
AG
SGF
STG
- - -

6,XX
6,YY
ST
6,ZZ
6,=F 1 7
6,DAnswer

c(GG6) = c(XX) + c(YY)


Branch if sum is not negative
It was negative; add c(ZZ)
Subtract 17 (word literal)
Store result
etc.

Figure 98. Calculate a 64-bit sum with an intermediate test

The AGFR and SGFR instructions use the same sign-extension process for 32-bit second operands in general registers as AGF and SGF do for 32-bit second operands in memory. For
example, if we must use only a halfword operand such as =H 1 7 , we can rewrite Figure 98 as
follows:

ST

LG
AG
BNM
AG
LH
SGFR
STG
- - -

6,XX
6,YY
ST
6,ZZ
0,=H 1 7
6,0
6,DAnswer

c(GG6) = c(XX) + c(YY)


Branch if sum is not negative
It was negative; add c(ZZ)
Load 17 into GR0 (32 bits)
Extend; then subtract GR0 from GG6
Store result
etc.

Figure 99. Calculate a 64-bit sum with an intermediate test

Chapter V: Basic Instructions

231

This approach requires an additional register (GR0) as a temporary register, which may be
inconvenient. Figure 99 is also one instruction and two bytes longer (counting the literal) than
Figure 98, so we could have used a word operand such as =F 1 7 .
Because logical arithmetic uses unsigned nonnegative operands, all bits have positive weight.
Thus, when an instruction requires unsigned operands with mixed lengths, the shorter operand is
always sign-extended with zero bits, as shown in Figure 100.


zeros

GG R1

0

63

32bit second operand

0
31
Figure 100. Sign extension for instructions with mixed 32- and 64-bit unsigned operands

For example:
(1)

LG
ALG

0,=AD(X0123456789ABCDEF )
0,=AD(X123456789ABCDEF0 ) c(GG0)=X13579BE02468ACDF , CC=1

Adding the two operands causes no overflow and the result is nonzero, so CC=1.
(2)

LG
0,=AD(X0123456789ABCDEF )
ALGF 0,=A(X87654321)
c(GG0)=X0123456811111110, CC=1

As in (1), but the second operand is first extended with zeros.


(3)

LG
0,=AD(X0123456789ABCDEF )
SLGF 0,=A(X87654321)
c(GG0)=X0123456702468ACE , CC=3

Subtracting the second operand causes a carry and the result is nonzero, so CC=3.
(4)

SR
1,1
SGR 0,0
SLGFR 0,1

c(GR1)=0
c(GG0)=0
c(GG0)=X0000000000000000, CC=2

Subtracting the second operand causes a carry and the result is zero, so CC=2.

Exercises
16.7.1.(2) Revise the instructions shown in Figure 91 on page 227 to complement a pair of
64-bit integers, giving a 128-bit result.
16.7.2.(2) Revise the instructions shown in Figure 92 on page 227 to add a pair of 64-bit integers, giving a 128-bit sum.
16.7.3.(2) Revise the instructions shown in Figure 93 on page 228 to subtract a pair of 64-bit
integers, giving a 128-bit difference.
16.7.4.(3) Write instructions to form the 128-bit sum and difference of the pair of 64-bit integers
stored starting at Two64s. Store the sum at Sum128 and the difference at Diff128.
16.7.5.(1) Show the CC values after executing
SLR

0,0

and
SLGR 0,0
and after executing

232

Assembler Language Programming for IBM z System Servers

Version 1.00

SR

0,0

SGR

0,0

and

16.8. Logical-Arithmetic Compare Instructions


The logical compare instructions are shown in Table 73.
Op
55
E321
E331

Mnem
CL
CLG
CLGF

Type
RX
RXY
RXY

BD

CLM

RS

EB21

CLMY

Instruction
Compare Logical (32)
Compare Logical (64)
Compare Logical (6432)

Op
15
B921
B931

Compare Logical Characters


under Mask (32)
RSY Compare Logical Characters
under Mask (32)

Mnem
CLR
CLGR
CLGFR

EB20 C L M H

Type
RR
RRE
RRE

Instruction
Compare Logical (32)
Compare Logical (64)
Compare Logical (6432)

RSY Compare Logical Characters under Mask (32)

Table 73. Arithmetic compare instructions

As we saw in Section 14.7 on page 192, RXY- and RSY-type instructions behave the same way
as RX- and RS-type instructions.
The logical compare instructions test the relative magnitudes of two operands, using an unsigned
comparison instead of the signed-arithmetic comparison used for arithmetic comparisons. The
results of all logical comparisons are indicated in the CC setting, as shown in Table 74 (youll
note that its identical to Table 65 on page 223).
CC
0
1
2

Meaning
Operand 1 = Operand 2
Operand 1 < Operand 2
Operand 1 > Operand 2

Table 74. CC settings after logical comparisons

Logical comparisons do not give the same results as arithmetic comparisons, since numbers in the
logical representation are always nonnegative. The following instruction sequence may help to
show the differences. (Following the LM instruction, the contents of R3 will be X80000001.)
The 64-bit logical comparison instructions behave the same way as their 32-bit equivalents. Carefully compare the CC settings in Figure 101 with those in Figure 87 on page 224.
LM
CLR
CLR
CLR
LPR
CLR
CL
CH

0,3,=F 1 , 0 , -1,-2147483647 Initialize registers GR0-GR3


1,3
CC = 1
X00000000 < X80000001
0,2
CC = 1
X00000001 < X FFFFFFFF
2,3
CC = 2
X FFFFFFFF > X80000001
4,3
CC = 2; (now, c(GR4) = X 7 FFFFFFF )
4,3
CC = 1
X 7 FFFFFFF < X80000000
2,=F+2
CC = 2
X FFFFFFFF > X00000002
1,=H 5
CC = 1
X00000000 < X00000005

Figure 101. Examples of logical comparisons

The CLM and CLMH instructions are unlike the other compare instructions, because the entire
first operand might not be used. Instead, they operate on selected bytes in the register, as determined by 1-bits in the M3 mask field of the instruction (just as we saw for the ICM/ICMH
instructions in Section 14.5 on page 187). The selected bytes in the register are compared to the
string of bytes in memory beginning at the second operand address. The comparison is performed
Chapter V: Basic Instructions

233

by considering the two strings to be unsigned logical numbers of length 8, 16, 24, or 32 bits. If the
mask digit M3 is zero, the CC is set to zero and no comparison is performed.
CLM and CLMY compare selected bytes in the first operand register (either in a 32-bit register
or in the rightmost 32 bits of a 64-bit register) to the storage operand. For example:
L
CLM
CLM
CLM
CLM

0,=A(X00010203)
0,B0000,=X0123
0,B0001,=X0123
0,B0100,=X0123
0,B0110,=X0123

Initialize GR0
CC = 0, because
CC = 2, because
CC = 0, because
CC = 1, because

mask is
X 0 3 >
X 0 1 =
X0102

0
X 0 1
X 0 1
< X0123

CLMH does exactly the same as CLM, except that it compares bytes in the high-order half of
a 64-bit register to bytes in memory. For example:
LG
CLMH
CLMH
CLMH
CLMH

0,=AD(X0001020304050607)
0,B0000,=X0123
CC = 0,
0,B0001,=X0123
CC = 2,
0,B0100,=X0123
CC = 0,
0,B0110,=X0123
CC = 1,

Initialize GG0
because mask is
because X03 >
because X01 =
because X0102

0
X 0 1
X 0 1
< X0123

The bytes in the low-order half of the 64-bit register are ignored.
Sometimes the logical compare instructions are used to test the ordering of values that are regularly incremented. For example, if Value has been saved at different times, we could find that
Oldest
Later
Newest

DC
DC
DC

X789ABCDE
X89ABCDEF
X 9 ABCDEF0

Oldest value
A later value
Most recent value

and we can use logical comparisons to determine their ordering, as in


L
0,Oldest
L
1,Later
L
2,Newest
- - CLR 1,0
CLR 2,1

Compare Later to Oldest


Compare Newest to Later

Figure 102. Comparing logically ordered values

then both CLR instructions will give the correct ordering of the three values.
But if the values can wrap around from X FFFFFFFF to zero, we must be more careful. For
example, suppose the three values are
Oldest
Later
Newest

DC
DC
DC

X FFFFFFFE
X FFFFFFFF
X00000001

Oldest value
A later value
Most recent value

Then if we compare them as previously, the second comparison will fail, because the value at
Newest will be logically less than the value at Later.
To avoid this problem, we can write instead
LR
SLR
LTR

3,1
3,0
3,3

Copy Later value to GR3


Subtract Oldest value
Test result

and the Condition Code will indicate that c(Later) is indeed greater than c(Oldest). Similarly, if
we write
LR
SLR
LTR

3,2
3,1
3,3

Copy Newest value to GR3


Subtract Later value
Test result

the CC will again indicate the correct ordering.

234

Assembler Language Programming for IBM z System Servers

Version 1.00

Exercises
16.8.1.(2) Show how the CC settings after SL and SLR are related to those after CL and CLR.
16.8.2.(2) Suppose GG0 contains X1122334455667788, and you must compare bytes 2 through
5 (containing X33445566) to a 4-byte memory operand named StgOp. Write an instruction or
sequence of instructions to do this.
16.8.3.(2) + Suppose c(GR0) is X87654321 and c(GR1) is X01234567. What is the CC setting
and the apparent ordering of the operands after executing each of these two instructions?
CR
CLR

0,1
0,1

Compare c(GR0) to c(GR1)


Compare c(GR0) to c(GR1)

Now, suppose the sign bit of each operand has been inverted, so that c(GR0)=X07654321
and c(GR1)=X81234567. What is the CC setting and the apparent ordering of the operands
after executing each of the two instructions? Why might this sign-bit inversion be useful?
16.8.4.(2) Make a table showing the first and second comparison operands in Figures 87 and
101, and the CC settings from their arithmetic and logical comparisons. For which operands are
they the same, and why?
16.8.5.(2) What differences will occur if two binary numbers are compared using arithmetic and
then logical compare instructions?
16.8.6.(2) + Write an execute a small program to verify the assertions about correctly-ordered
logical comparisons in the examples starting with Figure 102 on page 234.

16.9. Retrieving and Setting the Program Mask (*)


The IPM and SPM instructions in Table 75 let you retrieve and set the value of the Condition
Code and the Program Mask:
Op
B222

Mnem
IPM

Type Instruction
R R E Insert Program Mask

Op
04

Mnem
SPM

Type Instruction
R R Set Program Mask

Table 75. IPM and SPM instructions

Both instructions have a single operand:


IPM
SPM

R1
R1

Insert CC and Program Mask into GR R1


Set CC and Program Mask from GR R1

IPM inserts the Condition Code and Program Mask into bits 34-39 of register R1, in the positions shown in Figure 103; the remaining bits of the R1 register are unchanged. Conversely, SPM
sets the Condition Code (CC) and Program Mask from the same bit positions, and ignores the
rest of the R1 register.
unchanged
unchanged

/////////////////////////////////////////CCFDUS//////////////////////////////// R1

0
63
Figure 103. Bit positions used by I P M and SPM instructions (System/360 PSW sketch)

The four mask bits in the Program Mask (FDUS in Figure 103) control the behavior of the four
exceptions described in Section 4.6 on page 57 correspond to the bit positions shown in Table 76:

Chapter V: Basic Instructions

235

Bit
36 (F)
37 (D)
38 (U)
39 (S)

Exception Condition Controlled


Fixed-point overflow
Decimal overflow
Hexadecimal floating-point underflow
Hexadecimal floating-point lost significance

Int. Code
8
A
D
E

Table 76. Program Mask bits

Setting a mask bit to 1 enables the corresponding interruption. If the mask bit is 0, the CPU takes
a default action without an interruption.
In practice, many programmers choose to set the Program Mask to zero initially, and trust to
luck that nothing goes wrong. For example:
SR
SPM

0,0
0

Set c(GR0) to zero


Set CC and Program Mask bits to zero

Careful placement of tests for overflow can help justify such faith, but it is generally better to test
in advance for possible errors, and let a program interruption catch the unexpected and truly
exceptional cases.
For now, we are concerned only with fixed-point overflow. The result of an instruction causing a
fixed-point overflow is the same whether or not an interruption occurs; the Condition Code is set
to 3.

Exercises
16.9.1.(4) For each of the conditions controlled by a bit in the Program Mask, determine what
actions are taken by the CPU (including CC settings) when the PM bit is zero or one. (You
may need to consult the z/Architecture Principles of Operation.)
16.9.2.(2) + Write instructions that will turn off the Lost-Significance mask bit in the Program
Mask, without affecting the settings of the other mask bits.
16.9.3.(2) Assume you are executing in 24-bit addressing mode. The fullword integer at CCode
has a value of 0, 1, 2, or 3. Set the Condition Code to that value, without affecting the setting
of the Program Mask.
16.9.4.(2) Assume you are executing in 24-bit addressing mode. Store the current value of the
program mask in the rightmost four bits of the byte at PMask the remaining 4 bits of the byte
should be zero.
16.9.5.(2) Assume you are executing in 24-bit addressing mode. Store the current value of the
Condition Code in the word at CCode without changing the Condition Code.

16.10. Summary
Operands used in arithmetic and logical operations may be extended, as we noted in Sections
14.10 and 16.7.
Operand Extension
When a source operand in a register or in memory is used as an operand
in an arithmetic instruction whose target register is longer than the
operand, the operand is extended internally to the length of the target
register:
arithmetic operands are sign-extended
logical operands are extended with zeros.

236

Assembler Language Programming for IBM z System Servers

Version 1.00

Examples of arithmetic instructions doing sign extension are AH, AGH, CGFR, and SGFR;
examples of logical instructions that extend with zeros are ALGF, CLGF, and CLGFR.
In this section we examined some frequently-used instructions for addition, subtraction, and comparison; they are summarized in Table 77.
Operand1
Operand2

Function

4 bytes
A
S

4 bytes
AGF
SGF

8 bytes
AG
SG

Arithmetic Add and Subtract


(from register)

AR
SR

AGFR
SGFR

AGR
SGR

Logical Add and Subtract


(from memory)

AL
SL
ALC
SLB

ALGF
SLGF

ALG
SLG
ALCG
SLBG

Logical Add and Subtract


(from register)

ALR
SLR
ALCR
SLBR

ALGFR
SLGFR

ALGR
SLGR
ALCGR
SLBGR

CGF

CG

CR

CGFR

CGR

Logical Compare
(to memory)

CL
CLM

CLGF
CLMH

CLG

Logical Compare
(to register)

CLR

CLGFR

CLGR

Arithmetic Add and Subtract


(from memory)

Arithmetic Compare
(to memory)
Arithmetic Compare
(to register)

2 bytes
AH
SH

8 bytes

CH

4 bytes

Table 77. Summary of instructions discussed in this section

The instruction mnemonics and opcodes are shown in the following table:
Mnemonic
A

Opcode
5A

Mnemonic
C

Opcode
59

Mnemonic
SGF

Opcode
E319

AG

E308

CG

E320

SGFR

B919

AGF

E318

CGF

E330

SGR

B909

AGFR

B918

CGFR

B930

SH

4B

AGR

B908

CGR

B920

SL

5F

AH

4A

CH

49

SLB

E399

AL

5E

CL

55

SLBG

E389

ALC

E398

CLG

E321

SLBGR

B989

ALCG

E388

CLGF

E331

SLBR

B999

ALCGR

B988

CLGFR

B931

SLG

E30B

ALCR

B998

CLGR

B921

SLGF

E31B

ALG

E30A

CLM

BD

SLGFR

B91B

ALGF

E31A

CLMH

EB20

SLGR

B90B

ALGFR

B91A

CLR

15

SLR

1F

ALGR

B90A

CR

19

SR

1B

ALR

1E

5B

AR

1A

SG

E309
Chapter V: Basic Instructions

237

The instruction opcodes and mnemonics are shown in the following table:
Opcode
15

Mnemonic
CLR

Opcode
B90A

Mnemonic
ALGR

Opcode
E30A

Mnemonic
ALG

19

CR

B90B

SLGR

E30B

SLG

1A

AR

B918

AGFR

E318

AGF

1B

SR

B919

SGFR

E319

SGF

1E

ALR

B91A

ALGFR

E31A

ALGF

1F

SLR

B91B

SLGFR

E31B

SLGF

49

CH

B920

CGR

E320

CG

4A

AH

B921

CLGR

E321

CLG

4B

SH

B930

CGFR

E330

CGF

55

CL

B931

CLGFR

E331

CLGF

59

B988

ALCGR

E388

ALCG

5A

B989

SLBGR

E389

SLBG

5B

B998

ALCR

E398

ALC

5E

AL

B999

SLBR

E399

SLB

5F

SL

BD

CLM

EB20

CLMH

B908

AGR

E308

AG

B909

SGR

E309

SG

Terms and Definitions


addend
see augend
augend
When two numbers are added, the number being augmented (the first operand) is the
augend, to which the addend (the second operand) is added.
logical arithmetic
Binary arithmetic and comparison operations with unsigned operands.
minuend
see subtrahend
subtrahend
When one number is subtracted from another, the number being diminished (the first
operand) is the minuend, and the number being subtracted (the second operand) is the
subtrahend.

Programming Problems
Problem 16.1. Write a program that computes three word quantities X, Y, and Z that occupy
successive words in memory. Also define a 12-byte character string to occupy the same storage.
Compute the contents of the three words as follows:
c(X) = B100000000000000 + X C7A98 - 231471192,
c(Y) = X C0FFEE - C @#$ - 694895668, and
c(Z) = 1073741823 + X F194F6 + X ABCD .

238

Assembler Language Programming for IBM z System Servers

Version 1.00

Treat all the quantities as words whose values are self-defining terms. A hint: this means that
the simplest way to create them is as A-type constants.
Print the hexadecimal and character forms of the 12-byte result (using the PRINTOUT macro, for
example).
Problem 16.2. Write a program that computes four values stored in successive words at W, X,
Y, and Z. The values are to be computed according to the relations
c(W) = c(WA) +
c(WA)
c(WB)
c(X) = c(XA) +
c(XA)
c(XB)
c(Y) = c(YA) +
c(YA)
c(YB)
c(YC)
c(Z) = c(ZA) +
c(ZA)
c(ZB)
c(ZC)

c(WB) - 929065920, where


= B100000000000000 and
= X1230000.
50344169 + c(XB), where
= X 5 CF17 and
= C 0 0 0 .
c(YB) + c(YC), where
= B11111111,
= X1261F02 , and
= C ABCD .
c(ZB) - c(ZC), where
= X CAF75A ,
= B1000011, and
= 511686493.

All the quantities used in the calculations are four-byte word-aligned constants in memory.
Define symbols having length attribute 16 and types C and X to name the same 16 bytes of
memory. Calculate W, X, Y, and Z, and print the results of your calculation in character and
hexadecimal form (using the PRINTOUT macro, for example).
Problem 16.3. Do as in Problem 16.2, but the four quantities W, X, Y, and Z are defined this
time by
c(W) = c(WA) +
c(WA)
c(WB)
c(X) = c(XA) c(XA)
c(XB)
c(Y) = c(YA) +
c(YA)
c(YB)
c(YC)
c(Z) = c(ZA) +
c(ZA)
c(ZB)

c(WB) - 759375551, where


= B100000000000000,
= X CBA98 .
c(XB) + 1386388536, where
= X C0FFEE ,
= C @#$ .
c(YB) + c(YC), where
= B11111111,
= X 1 F7C05 ,
= C ABCD .
c(ZB) - 975583924, where
= X FFFF ,
= -65536.

As before, print the 16 bytes of the result as a character string and as a string of 32 hexadecimal
digits.
Problem 16.4. Consider the sequence of integers starting
0, 1, 2, 3, 6, 11, 20, 37, ...,
where (after starting with 0, 1, and 2) each successive term is generated by adding the previous
three terms together.
Write a program that will compute and print the first 25 terms of this sequence. (A hint: an
appropriate choice of starting values will make it unnecessary to take special actions to print the
first few terms.)
Problem 16.5. Suppose you are given three integers A, B, and C, and you are told that they are
three successive terms in a sequence. Each term of the sequence was generated by adding the
previous three terms together.

Chapter V: Basic Instructions

239

Write a program that will generate the previous 25 terms of the sequence, for various values of
A, B, and C. As a check, you might start with values you found in solving Problem 16.4.
Problem 16.6. Write a program to do the calculations in Figures 92 through 96 for various
values of the operands. Use the PRINTOUT macro to display the values of the 64-bit results. For
example,
PRINTOUT 17,18
displays c(GG1) and c(GG2) in both hex and decimal.
Problem 16.7.(2) + The Fibonacci 106 series is defined by the relation
F(n+1) = F(n) + F(n-1)

with F(0)=0 and F(1)=1

Write a program to calculate and display the numbers in the Fibonacci series starting with F(1)
up to the largest value that does not exceed one million.
Problem 16.8.(2) + Do the same as in Problem 16.7, but now calculate and display the
Fibonacci series up to the largest positive value representable in a signed 32-bit binary fullword.
Problem 16.9.(3) + Do the same as in Problem 16.8, but format and print the results using the
CONVERTO and PRINTLIN macros.
Problem 16.10.(3) Calculate the numbers in the Fibonacci series (described in Problem 16.7) up
to the maximum positive value representable using 64-bit binary arithmetic, and format and
print the results using the CONVERTO and PRINTLIN macros.
Problem 16.11.(2) + Assemble the following program:
P16_11

X
Exit

CSect
Using
LR
A
BASR
DC
DC
BR
L
B
End

,
*,12
12,15
15,X
12,15
F 1 8
F 4
14
10,X-4
X-4(10)
P16_11

Study the object code carefully, and explain what each instruction does and how it does it.

106

240

Named after Leonardo of Pisa, known as Fibonacci.


Assembler Language Programming for IBM z System Servers

Version 1.00

Chapter V: Basic Instructions

241

17. Binary Shifting

11
777777777777
111
777777777777
1111
77
77
11
77
11
77
11
77
11
77
11
77
11
77
11
77
1111111111
77
1111111111
77

The multiplication and division instructions in Section 18 are often combined with shift operations, so well start with instructions that shift data within a single general register or pair of
general registers.
The general register shift instructions are summarized in Table 78. Nine operate on data in 32-bit
registers, and five operate on 64-bit registers. The notation (32+32) means that 64 bits are
shifted in an even-odd pair of 32-bit general registers. There are no double-length shifts of 128-bit
operands (64 + 64) in an even-odd pair of 64-bit general registers.107
We say that single-length shifts operate on bits in a single 32- or 64- bit register, and doublelength shifts operate on bits in an even-odd pair of registers.
Op
88
8A

Mnem
SRL
SRA

8C

SRDL

8E

SRDA

EB0C
EB0A

SRLG
SRAG

EB1C

RLLG

Type Instruction
RS
Shift Right Logical (32)
RS
Shift Right Arithmetic
(32)
RS
Shift Right Double
Logical (32+32)
RS
Shift Right Double
Arithmetic (32+32)

Op
89
8B

Mnem
SLL
SLA

Type Instruction
RS
Shift Left Logical (32)
RS
Shift Left Arithmetic (32)

8D

SLDL

RS

8F

SLDA

RS

RSY Shift Right Logical (64)


RSY Shift Right Arithmetic
(64)
RSY Rotate Left Logical (64)

EB0D
EB0B

SLLG
SLAG

RSY Shift Left Logical (64)


RSY Shift Left Arithmetic (64)

EB1D

RLL

RSY Rotate Left Logical (32)

Shift Left Double Logical


(32+32)
Shift Left Double
Arithmetic (32+32)

Table 78. General register shift instructions

These RS-type instructions differ from other RS-type instructions: the shaded portion of the
instruction (where the R3 register specification digit would be) in Table 79 is ignored when the
instructions are executed.

107

242

At the time of this writing. But new instructions are added regularly to the z System architecture, so check the Principles of Operation.
Assembler Language Programming for IBM z System Servers

Version 1.00

opcode

R1

B2

D2

Table 79. RS-type shift instruction

Thus, the Assembler makes no provision for specifying a value in that field, and sets it to zero.
The operand field entry for shift instructions is written in either of the two forms
R1,D2(B2)
R1,S2

(explicit address)
(implied address)

and no R 3 operand is specified.


The RSY-type shift instructions do have an R 3 operand, as shown in Table 80. For these
instructions, the source operand is in the R3 register and the result goes into the R1 register. Well
see examples using the R3 operand when we discuss these instructions.
opcode

R1

R3

B2

DL 2

DH2

opcode

Table 80. RSY-type instruction format

When executed, none of the logical shift instructions change the CC setting, while all of the arithmetic shifts treat the shifted data as signed, and set the CC to indicate the status of the result.
For all shift instructions, the number of bit positions to be shifted is determined from the loworder six bits of the Effective Address; this allows actual shift amounts only between 0 and 63.
That is, the shift count is the remainder obtained when the Effective Address is divided by 64:
shift count = Effective Address (modulo 64).
This means, for example, that a shift amount specified by an Effective Address of 66 actually
shifts only 2 positions when executed.
Shift Amounts
Shift instructions can specify at most 63 shifts.
First, well describe the unit shift, and then look at the eight RS-type instructions, all of which
involve 32-bit registers.

17.1. Unit Shifts


To illustrate the behavior of various shift instructions, well assume that the source register starts
with the contents illustrated in Figure 104.

a b c d
w x y z Before

0
1
2
3
n-4 n-3 n-2 n-1
Figure 104. Register contents before shifting

The bit positions are numbered from 0 to n 1, where n is the number of bits participating in the
shift.
The basic shift operation is the unit shift, in which each bit moves right or left by one bit position. The digit position at the right (low-order) end of the register behaves identically for logical
and arithmetic left and right shifts, but the bit at the left (high-order) end of the register is treated
differently.
For logical shifts, the vacated bit position at either end of a register is always set to zero, and the
bit shifted off the opposite end is lost and ignored. This is illustrated in Figures 105 and 106.

Chapter V: Basic Instructions

243


 b c d e  x y z 0 0

a
bit bucket

After

Figure 105. Logical unit shift left

The bit bucket doesnt really exist; it just means that the lost bit vanishes.108

0 0 a b c v w x y After

z
bit bucket
Figure 106. Logical unit shift right

For arithmetic right shifts, the rightmost bit is lost and ignored, and the sign bit is duplicated to
preserve the arithmetic integrity of the operand. This is illustrated in Figure 107.

s s b c v w x y After



z

bit bucket
Figure 107. Arithmetic unit shift right

For arithmetic left shifts, the vacated bit position at the right end is set to zero, and the sign bit is
not shifted; it doesnt move. However, the bit immediately to the right of the sign bit is lost. This
is illustrated in Figure 108.

s c d e  x y z 0 0


b
bit bucket

After

Figure 108. Arithmetic unit shift left

Again, the sign of the operand is preserved. Because arithmetic left shifts may lose a significant
bit, an overflow condition can occur; well see how this happens when we look at the arithmetic
shift instructions in Section 17.4.
To illustrate unit shifts, suppose c(GR8) is X87654321, or
1000 0111 0110 0101 0100 0011 0010 0001
in binary, and a unit logical left shift in GR8 is executed. Each of the bits moves one position to
the left, and the result in GR8 will be
0000 1110 1100 1010 1000 0110 0100 0010
in binary, or X 0 ECA8642 . The leftmost one-bit was lost, and a zero-bit was introduced at the
right. Similarly, if we again start with X87654321 and execute a unit logical right shift in GR8,
each bit moves one position to the right, and the result will be
0100 0011 1011 0010 1010 0001 1001 0000

108

244

When I took my first programming class, we were all taken to see the computer; its operation was slowed so we
could watch it shift, add, etc. After showing the shifts the instructor paused, because a student always asked What
happens to the bits shifted off the end? An engineer would then open a door on the end of the machine and hold up
a small silver bucket, saying gravely that the bits had to be emptied after every 8 hours of operation. Some of us
never realized it was a joke.
Assembler Language Programming for IBM z System Servers

Version 1.00

in binary, or X43B2A190 .
The execution of a shift instruction is simple: it simply performs the number of unit shifts specified by the low-order 6 bits of its Effective Address.

Exercises
17.1.1.(1) What shift amounts are represented by each of the following Effective Addresses?
1.
2.
3.
4.
5.
6.
7.

X EDCBA987
X12345678
X87654321
X00000FED
X FFFFFFFF
X27A49FC1
X6789ABC0

17.2. Single-Length Logical Shifts


The simplest shifting instructions are SRL (Shift Right Logical) and SLL (Shift Left Logical). In
most of the following examples, bit patterns will be represented in hexadecimal.
To perform a unit logical left shift of the contents of R8, we can execute the instruction
SLL

8,1(0)

Shift GR8 left 1 bit position

Suppose GR8 again contains X87654321 and GR3 contains X82F3A2B5 , executing the logical
right-shift instruction
SRL

8,16(3)

first causes the Effective Address to be computed as


X82F3A2B5 + X010 = X82F3A2C5
of which the rightmost six bits are B000101. Thus it shifts right five bit positions, leaving
0000 0100 0011 1011 0010 1010 0001 1001
in binary, or X043B2A19 as the result in GR8.
In these examples, we saw that the original contents of GR8 were not preserved: that is, the shifts
can be thought of as destructive. All the RS-type shifts use the same register (or register pair) as
the source and target of the operation. The RSY-type shifts let you preserve the original source
operand if you like.
The SLL instruction is the most commonly used logical shift. It is often used to multiply index
values by a power of two (such as the length of an operand in memory) prior to executing an
RX-type instruction for which the shifted register is the index register. We will see many such
uses in discussing looping and indexing in Section 22.
Suppose the word at Index contains a small positive integer N that is to be used to index into
a table of words starting at the word named Tab. To load the N-th of those words into GR0,
we could write a sequence of instructions like the following:
L
1,Index
SLL 1,2
L
0,Tab-4(1)

Get index word


Shift left 2 bits (multiply by 4)
Load N-th word into GR0

The shift left by two bit positions is needed so that we access the N-th word (not the N-th
byte) in the table; and we must address the table at Tab-4 because if the integer at Index is 1,
we should access the first word at Tab. If N is 1, indexing will add 4 to Tab-4, giving the
address of Tab as desired.

Chapter V: Basic Instructions

245

Suppose we want to set the leftmost seven bits of register 8 to zero, leaving the other bits
unchanged. Then we could execute the two instructions
SLL
SRL

8,7
8,7

Shift left 7 places, drop off bits


Shift right 7 places, bring in zeros

and the leftmost 7 bits are replaced by zeros.


As another example, suppose we need to align the address in GR6 to a doubleword boundary.
That is, we will force the value in GR6 to be a multiple of 8 in such a way that if it is not
already so, the next higher multiple of 8 will be chosen.
This can be done very simply:
AL 6,=F 7
SRL 6,3
SLL 6,3

Force carry if possible


Drop off three bits
Multiply by 8

Figure 109. Rounding an integer to the next higher multiple of 8

The presence of any 1-bit in the three rightmost bits of the original number in GR6 will cause
a carry into the 2 3 bit position (bit number 28 of GR6).
Suppose we have a large table of six-byte data items containing a mix of integer and character
data. Each table entry is aligned on a halfword boundary. Suppose also that the data is
arranged so that the first three bytes contain a signed 24-bit twos complement integer, and the
remaining three bytes contain the character data (see Figure 110).
 3 bytes  3 bytes

integer data

character data

xx
yy
zz

Figure 110. A 6-byte data entry

Space for typical table entry might have been reserved with DS statements such as
Entry
DS
IntPart DS
CharPart DS

0XL6
FL3
CL3

Define name of 6-byte data entry


Give name to integer part
And to the character part

Figure 111. Storage definitions for a 6-byte data entry

We want to retrieve the integer value from a data entry and place it into GR5 where it will be
used for some purpose in the program, and then store it from GR5 back into memory in the
format illustrated in Figure 110. We can see that L and ST instructions cannot be used,
because the operands are neither 4 bytes long nor correctly aligned in memory; similarly, LH
and STH handle only two of the three bytes.
Now, suppose GR12 contains the address of the first byte of a data entry. The instructions
needed to load the integer value into GR5 are shown in Figure 112. (Assume for the moment
that the data entry contains X F01234xxyyzz ; for now, well ignore the three characters represented by xxyyzz.)
LH
5,0(0,12)
SLL 5,8
IC
5,2(0,12)
- - STC 5,2(,12)
SRL 5,8
STH 5,0(0,12)

c(GR5) = X FFFFF012 , leftmost 16


c(GR5) = X FFF01200 , move left 8
c(GR5) = X FFF01234 , insert last
- - do some calculations with the
Store rightmost 8 bits
Position remaining 16 Bits
Store high-order part

Figure 112. Using shift instructions for a 6-byte data item

246

Assembler Language Programming for IBM z System Servers

Version 1.00

bits
bits
8 bits
value

The arrangement of data in memory usually depends on the requirements of the application,
as well as on considerations of ease of programming or speed of execution.
This example might tempt you to manipulate characters by inserting and shifting them in the
general registers. Resist that that temptation until after we have examined instructions designed
specifically for managing character data in Section 25.

17.2.1. Three-Operand Shift Instructions


SRLG and SLLG are the 64-bit equivalents of SRL and SLL. They behave exactly as the 32-bit
shifts, with a useful extension: rather than specifying only a single operand register (as in Table 79
on page 243), these two RSY-type instructions specify separate source and target registers. The
source operand is taken from GG R 3, shifted by the specified amount, and placed into the target
operand, GG R 1. The operand field is is written
R1,R3,D2(B2)
R1,R3,S2

(explicit address)
(implied address)

Table 80 on page 243 shows the format of an RSY-type instruction.


If you specify different register numbers for R3 and R 1, the shift is nondestructive because the
source operand in GG R 3 is unchanged. If you specify the same register number for both R3 and
R 1, the shift is destructive, just like the shifts in 32-bit general registers.
To illustrate, consider these instructions:
L
SLL

0,=A(X12345678)
0,9

c(GR0) initialized
c(GR0) = X68ACF000

and the contents of GR0 is changed. For these instructions:


LG
1,=XL8123456789ABCDEF0
c(GG1) initialized
SLLG 0,1,9
c(GG0) = X68ACF135 79BDE000
LG
1,=XL8123456789ABCDEF0
c(GG1) initialized
SRLG 0,1,9
c(GG0) = X00091A2B 3C4D5E6F
in both cases, the contents of the GG1 source register is unchanged. Otherwise, the instructions
for shifting operands in 64-bit registers behave the same way as their equivalents for 32-bit registers.

Exercises
17.2.1.(2) + Suppose the string of bytes beginning at BStrg is to be considered as a string of bits.
Given an integer K stored in the word at KK, write a code sequence to place in GR0 the value
of bit K of the string. (Remember to start numbering the bits at zero.)
17.2.2.(2) A word integer at K has value between 0 and 7. Write a code sequence using shifts
that will store at KthBit a byte containing a single 1-bit at a position determined by the integer
at K. That is, if c(K)=6, then c(KthBit) = X 0 2 . (Remember that bits in a byte are numbered
from 0 to 7!)
17.2.3.(2) Rewrite Exercise 17.2.2 to use no shifts, but define an appropriate 8-byte table.
Which code sequence is shorter? Simpler?
17.2.4.(1) + The SLL instruction shifts data in a 32-bit general register. How many bit positions will be shifted if you specify
SLL

0,33

17.2.5.(2) The word at DPG contains 4 bytes; write instructions to put those four bytes into GR1
in reverse order. Thus, if c(DPG) is X12345678, c(GR1) will be X78563412.

Chapter V: Basic Instructions

247

17.2.6.(2) + GR0 contains a positive, nonzero number. Write a set of instructions that will shift
the number to the left until there is a 1-bit in bit position 1 of GR0 (the bit immediately to the
right of the sign bit). In GR1, put the number of positions shifted. Remember that the number
in GR0 must be positive when the instruction sequence terminates.
17.2.7.(2) + Given these two constants at X and Y:
X
Y

DC
DC

FL31234567
FL37654321

Write instructions to add the two numbers and store their sum as a 24-bit number at W. If the
sum overflows and cannot be represented correctly, branch to OverFlo.
What are the hexadecimal representations of the constants at X and Y? What is the representation of the result stored at W, and does the sum overflow?
17.2.8.(2) What will be the result of executing this instruction?
SLL

n,n(n)

17.2.9.(2) + In the example following Figure 109 on page 246, does it matter if the 3-byte
integer data is signed or unsigned? Explain.

17.3. Double-Length Logical Shifts


The double-length logical shift instructions SLDL (Shift Left Double Logical) and SRDL (Shift
Right Double Logical) work in exactly the same way as SLL and SRL, except they shift the 64
bits in a pair of even-odd 32-bit registers. The register specified by the first operand (R1) must be
an even-numbered register; otherwise a specification exception will occur. The next highernumbered register is the low-order half of the double-length register pair. Bits right-shifted out of
the right end of GR R 1 enter the left end of GR R 1+1, and vice versa for left shifts. (Figure 10
on page 48 shows paired general registers.)
Revisiting the example in Figure 109, here is another way to round an integer to the next higher
multiple of 8 if it is not already a multiple of 8.

SR
SRDL
LTR
BZ
A
SLL

7,7
6,3
7,7
A
6,=F 1
6,3

Clear GR7 to zero


Shift three bits into GR7 from GR6
Test whether the bits are zero
Branch if yes
If not, add 1 to GR6
Finally, multiply GR6 by 8

First, we clear GR7 by subtracting it from itself, a fast and simple way to do this. Then, we use a
shift instruction to divide by 8. The double-length shift moves the three remainder bits into the
three high-order bit positions of GR7. The BZ instruction branches only if the remainder bits are
all zero: that is, if the number in GR6 was already a multiple of 8. If any remainder bit is
nonzero, 1 is added to GR6. Finally, GR6 is shifted left 3 bit positions to give the correct multiple of 8.
As another example, suppose a positive nonzero integer word at N is to be shifted right as many
places as necessary to ensure that its rightmost bit is nonzero. Here are two ways we might do
this:
1. Shift left from GR5 into GR4, until only zero-bits remain in GR5. That is, if two right shifts
of the integer at N were actually needed, we will do 30 double-length left shifts.

248

Assembler Language Programming for IBM z System Servers

Version 1.00

ShiftL

L
L
SLDL
LTR
BNZ
ST

5,N
4,=F 0
4,1
5,5
ShiftL
4,N

Get integer from N


Clear GR4
Shift left one bit position
Test remaining bits in GR5
Repeat if not zero
Store result

Figure 113. Shifting to make the low-order bit one (1)

2. This time, we shift right, testing lost bits:


ShiftR

L
SRDL
LTR
BNM
SLDL
ST

4,N
4,1
5,5
ShiftR
4,1
4,N

Get integer from N


Shift right once
Test sign bit of GR5
Branch if not minus
Move the bit back
Store result

Figure 114. Shifting to make the low-order bit one (2)

This second example will also work for negative integers if arithmetic shift instructions are
used.
These examples illustrate simple loops, instructions that are repeated as many times as necessary
to obtain a desired result or condition. Loops are an important aspect of programming; special
z System branch instructions simplify coding of loops.109
Suppose that in a certain application we need to store some integer data in a very compact
format. The integer values are unsigned and are small enough that we can squeeze four integers
into a 32-bit word as shown in Figure 115. (Section 17.6 will describe how you can define these
four values in a word.)
9 bits
4 bits
13 bits
6 bits

aaaaaaaaa bbbb ccccccccccccc dddddd

A B C D
Figure 115. Four integers packed in a 32-bit word

Suppose the four packed integers are stored at DataWord and we want to extract the second integer
(the four bbbb bits) and store their value in the word at BVal. We can do this with the
instructions in Figure 116:
L
SLL
SRL
ST

0,DataWord
0,9
0,28
0,BVal

Load 32 bits
c(GR0)=bbbbcccccccccccccdddddd000000000
c(GR0)=0000000000000000000000000000bbbb
Store value of b-bits

Figure 116. Extracting one packed integer from a 32-bit word

The SLL instruction shifts all the a bits off the left end of GR0, and the SRL instruction shifts all
but the four b bits off the right end of GR0, leaving only the four bbbb bits right-adjusted in
GR0.
To illustrate a more general technique, we will write instructions that extract the integers from
their compacted word format in a memory area named DataWord, separating them into individual
words named First, Second, Third, and Fourth. In Figure 117, the comment statements show
the binary contents of registers GR0 and GR1; the integers to be unpacked are named A, B, C,
and D as shown in Figure 115. In Figure 117, a letter x represents a bit whose value is

109

These special Branch on Index and Branch on Count instructions neither examine nor change the CC. We will
investigate them in Section 22.
Chapter V: Basic Instructions

249

unknown, and 0 is a zero bit. We will shift each integer from the right end of GR0 into GR1,
where it will be right-justified in GR1 and stored. This example uses only right shifts.
As mentioned in Section 13.3 on page 164, the EQU instruction assigns the value of the operand
to the name-field symbol. This symbolic technique is very useful if the sizes of the fields must be
changed, because the shift instruction operands will be adjusted automatically by the Assembler.
LA
LB
LC
LD
* c(GR0)
* c(GR1)
* c(GR0)
* c(GR1)
* c(GR1)

* c(GR0)
* c(GR1)
* c(GR1)

* c(GR0)
* c(GR1)

* c(GR1)

EQU 9
Define bit length of integer A
EQU 4
Length of B
EQU 13
Length of C
EQU 6
Length of D
L
0,DataWord
Load data fullword into GR0
= B aaaaaaaaabbbbcccccccccccccdddddd
= B xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
SRDL 0,LD
Shift 6 bits in both registers
= B000000aaaaaaaaabbbbccccccccccccc
= B ddddddxxxxxxxxxxxxxxxxxxxxxxxxxx
SRL 1,32-LD
Move D to right end of GR1
= B00000000000000000000000000dddddd
ST
1,Fourth
Store fourth integer D at FOURTH
SRDL 0,LC
Shift 13 bits in both registers
= B0000000000000000000aaaaaaaaabbbb
= B ccccccccccccc0000000000000000000
SRL 1,32-LC
Move C to right end of GR1
= B0000000000000000000ccccccccccccc
ST
1,Third
Store third integer C at THIRD
SRDL 0,LB
Shift 4 bits in both registers
= B00000000000000000000000aaaaaaaaa
= B bbbb0000000000000000000ccccccccc
ST
0,First
Store first integer A from GR0
SRL 1,32-LB
Position second integer B in GR1
= B0000000000000000000000000000bbbb
ST
1,Second
Store second integer B at Second

Figure 117. Unpacking four unsigned integers using right shifts

We can also shift the integers left, from the left end of GR1 into the right end of GR0, but we
must clear GR0 each time before shifting.
SR
L
LR
SLDL
ST
LR
SLDL
ST
LR
SLDL
ST
SRL
ST

2,2
1,DataWord
0,2
0,LA
0,First
0,2
0,LB
0,Second
0,2
0,LC
0,Third
1,LA+LB+LC
1,Fourth

Constant zero for clearing GR0


Get data fullword in GR1
Clear GR0
Shift 9 bits into GR0 from GR1
Store first integer
Clear GR0
Shift 4 bits into GR0
Store second integer
Clear GR0
shift 13 bits into GR1 into GR0
store third integer
Reposition fourth integer in GR1
Store fourth integer

Figure 118. Unpacking four unsigned integers using left shifts

We have used LR instructions to clear GR0, rather than subtracting it from itself. Similarly, in
this example the final SRL 1,LA+LB+LC shift replaces the LR and SLDL used in the first three
steps, because it results in less code and faster execution. The overall saving is quite small, but this
illustrates a small economy that could result in significant savings if this sequence is frequently
executed.

250

Assembler Language Programming for IBM z System Servers

Version 1.00

Exercises
17.3.1.(2) + Suppose your CPU has only single-length logical shift instructions (SLL, SRL). A
word at DataWord is to be shifted logically to the left, as though it was the high-order word of a
pair of general registers. Write an instruction sequence that simulates a double-length left shift
of N bit positions, where N is a halfword integer at NShifts. Assume 0 N < 32, and that the
simulated low-order register contains zero. Store the result at a doubleword named DWord.
17.3.2.(2) Do the same as in Exercise 17.3.1, and again assume you must do a double-length
logical left shift of a 32-bit word in the high-order half. This time, assume 0 N < 64.
17.3.3.(2) + Do the same as in Exercise 17.3.1, but simulate a double-length logical right shift of
N places, where 0 N < 32, again assuming that the low-order half of the original 64-bit operand
is zero.
17.3.4.(2) Do the same as in Exercise 17.3.3, but now assume 0 N < 64.
17.3.5.(3) + Do the same as in Exercise 17.3.1, but now assume the initial data is in a
doubleword at DWData, and store the left-shifted result at DWord.
17.3.6.(3) + Do the same as in Exercise 17.3.5, but now assume the initial data is in a
doubleword at DWData, and store the right-shifted result at DWord. (Remember that 0 N < 32.)
17.3.7.(2) Do the same as in Exercise 17.3.5, but now assume 0 N < 64.
17.3.8.(2) Do the same as in Exercise 17.3.6, but now assume 0 N < 64.
17.3.9.(3) There is a word at OLD into which four positive integers have been packed as illustrated in Figure 115 on page 249. Write a code sequence to rearrange the four unsigned integers into a new word format, in which the first integer occupies the first seven bits, the second
integer occupies the next two, the third is expanded to occupy the next fifteen bits, and the
fourth integer occupies the last eight bits. Store the result at NEW.
17.3.10.(3) + Suppose four unsigned integers are stored in the words named FIRST, SECOND,
THIRD, and FOURTH. Write a code sequence that will pack the integers from those words into a
word at NEW in the format illustrated in Figure 115.
17.3.11.(3) As in Exercise 17.3.10, assume we wish to pack the four integers at FIRST, SECOND,
THIRD, and FOURTH into a word at NEW. The number of bits to be allocated to each integer in its
packed form is given as the value of the four positive halfword integers stored at L1, L2, L3,
and L4 respectively. We know that
c(L1) + c(L2) + c(L3) + c(L4) = 32.
The integers to be packed are stored in the logical representation.
17.3.12.(3) Rewrite Exercise 17.3.11 assuming that the values are to be stored in the arithmetic
representation.
17.3.13.(2) What will happen in Figures 113 and 114 if c(N)=0?
17.3.14.(3) + A common mathematical notation is the ceiling function. If a number x has
integer part p and fraction part q, we write p.q to represent x. The ceiling function is
defined as:
if q = 0, Ceiling(x) = p,
if q > 0, Ceiling(x) = p+1.
Suppose there is a nonnegative integer N stored in the word at NN. Write a code sequence that
will leave Ceiling(N+N/2) in GR1.

Chapter V: Basic Instructions

251

17.3.15.(4) + Rewrite Exercise 17.3.10 to repack the four unsigned integers into a new word, but
include tests to check that the values will fit into the fields provided for them in the packed
word. To indicate whether or not each of the integers fits into its allotted field, set the bytes at
FLAG1, FLAG2, FLAG3, and FLAG4 zero if the value will fit, and to nonzero if the value will not fit.
17.3.16.(2) GR0 contains a 32-bit number considered as a bit pattern. Write a code sequence
that will place the same bit pattern into GR1, but reversed from right to left within the register.
17.3.17.(2) + The word at Data contains information to be shifted circularly: that is, bits shifted
off one end of the register should reappear at the other end. For example, a circular left shift of
the operand X12345678 by 12 bit positions would produce X45678123. Write instructions
(not using RLL!) to shift c(Data) circularly to the left by N places, where N is a nonnegative
word integer stored at NShifts. Can you do this using only single-length shifts?
17.3.18.(2) + Modify the coding of Exercise 17.3.17 so that if N is negative, the shift is a circular
right shift instead.
17.3.19.(3) + A programmer wanted to display the hex digits in a byte string starting at Hex as a
string of EBCDIC characters starting at Chars, with each EBCDIC character representing a
single hexadecimal digit. The length of the byte string with the hex digits is stored as a halfword
binary integer stored at Len. He wrote:
LH
0,Len
Get length of source string
LA
2,Hex
Addr of start of hex string
LA
3,Chars
Addr of start of character string
GetAByte SR
4,4
Clear GR4
IC
4,0(,2)
Get a byte from hex string
SRDL 4,4
Move high-order hex digit in GR4
SRL 5,28
And low-order hex digit in GR5
IC
4,Chars(4)
Get character form of high digit
IC
5,Chars(5)
Get character form of low digit
SLL 4,8
Make room in GR4 for second byte
ALR 4,5
Now have both characters in GR4
STCM 4,B0011,0(3)
Store both chars in output string
LA
2,1(,2)
Increment input pointer
LA
3,2(,3)
Increment output pointer
SH
0,=H 1
Reduce input byte count by 1
BP
GetAByte
If count > 0, do another byte
- - Chars
DC
C0123456789ABCDEF
EBCDIC form of hex digits
Does this work? Explain.

17.4. Arithmetic Shift Instructions


The arithmetic shift instructions are similar to the logical shift instructions, except for the setting
of the CC and the treatment of the sign bit. The instructions are SLA (Shift Left Arithmetic),
SRA (Shift Right Arithmetic), SLDA (Shift Left Double Arithmetic), and SRDA (Shift Right
Double Arithmetic). The CC settings after arithmetic shift instructions are the similar to those for
arithmetic add and subtract instructions:

252

Assembler Language Programming for IBM z System Servers

Version 1.00

Operation
Left shift

Right shift

CC Setting and Meaning


0:
1:
2:
3:
0:
1:
2:
3:

Result is zero
Result is < zero
Result is > zero
Result has overflowed
Result is zero
Result is < zero
Result is > zero
Cannot occur

Table 81. CC settings for arithmetic shift instructions

As we saw in Figure 107 on page 244, for right shifts the sign bit is duplicated (or extended) in
the vacated sign position after each unit shift, to preserve the arithmetic integrity of the shifted
operand.
To illustrate the difference between logical and arithmetic shifts, suppose a right shift of two bits
is performed on a register containing X FFFFFFF8 :
L
SRL

0,=F -8
0,2

L
SRA

0,=F -8
0,2

After the SRL logical shift, c(GR0)=X 3 FFFFFFE , because two zero bits were inserted at the left;
after the SRA arithmetic shift, c(GR0)=X FFFFFFFE , because the sign bit has been duplicated.
For positive operands, the SRL and SRA instructions will leave identical results in the register;
SRA will set the CC as shown in Table 81, but SRL will leave the CC unchanged. The SRDA
instruction is similar to SRA, except that an even-odd register pair is shifted as a single 64-bit
entity.
A typical use of SRDA is to create a correctly-signed 64-bit dividend for a fixed-point divide
instruction, as we will see in Section 18:
L
0,Dividend
SRDA 0,32
D
0,Divisor

32-bit number in GR0


Sign-extend to 64-bit length in (GR0,GR1)
Divide by 32-bit number

The sign bit of the word at Dividend has been extended by the SRDA instruction to fill GR0.
For arithmetic left shifts, the situation is a little more complicated, as we saw in Figure 108 on
page 244. When an operand is shifted left one or more significant bits may be lost; though lost,
they are not ignored! An arithmetic left shift (1) always retains the original sign bit, and (2) indicates an overflow if any bit shifted out of the position just to the right of the sign is different from
the sign bit. This is a fixed-point overflow, and may cause a program interruption with the Interruption Code set to 8.
The following instructions will produce the results indicated in the remarks fields:
L
SRL
SLA

0,=F -8
0,2
0,4

c(GR0)=FFFFFFF8, CC unchanged
c(GR0)=3FFFFFFE, CC unchanged
c(GR0)=7FFFFFE0, CC set to 3 (Overflow)

When executing the SLA instruction, one 0-bit and three 1-bits are shifted out of the bit position
immediately to the right of the sign bit. Because the sign bit is zero after the SRL instruction, the
first one-bit to be shifted out of the bit position just to the right of the sign signals the overflow
condition, since it differs from the sign.
We can use the ICM, STCM, and SRA instructions to simplify the example in Figure 112 on
page 246:
ICM 5,B1110,0(12)
SRA 5,8
- - STCM 5,B0111,0(12)

c(GR5) = X F01234??
c(GR5) = X FFF01234
Compute something
Store result back

Chapter V: Basic Instructions

253

As indicated in Table 81, a CC value of 3 is not possible after the SRA and SRDA instructions,
because there can be no overflow. For SLDA and SRDA, the result tested is a double-length
operand, so these instructions provide a simple way to test whether both registers contain zero.
Both SRDA 0,0 and SLDA 0,0 will set the CC to zero if the register pair (GR0,GR1) both
contain zeros.
An important use of the arithmetic shift operations is to multiply by positive and negative powers
of two. Since the bits of an operand shifted left by a unit shift appear with a weight (in the sum
forming the value of the operand) that has increased by two, so long as no significant bits are lost
and no overflow occurs, an arithmetic left shift of n places corresponds to multiplication by 2 n .
Similarly, for a unit right shift, each bit has a weight that has decreased by two, so that an arithmetic right shift of n places corresponds to division by 2 n . Because such a division might seem
to produce fractional results, we must check what happens when bits are lost. Consider these
sequences:
L
SRA

3,=F 5
3,1

c(GR3) = 00000005 = +5
c(GR3) = 00000002 = +2 (1-bit lost)

L
SRA

3,=F -5
3,1

c(GR3) = FFFFFFFB = -5
c(GR3) = FFFFFFFD = -3 (1-bit lost)

As we expect, the lost bit in the first case results in the fractional part of (5/2) being discarded, so
the result is simply 2. In the second case the result is 3, not 2; this is because the truncation
of the fraction part of a number in the twos complement representation has the effect of always
forcing the result to the next algebraically lower integer value. (See Exercises 17.4.9 and 17.4.14.)
As a simple example, suppose we wish to truncate the integer in GR9 to the next algebraically
lower multiple of 16, unless it is already a multiple of 16. Both of the following achieve the
desired result.
SRA
SLA

9,4
9,4

SRL
SLL

9,4
9,4

Either the logical or arithmetic shifts can be used, because whatever bit is shifted out of the sign
position by the SRL instruction will be put back by the SLL. If a CC setting is desired to indicate
the status of the result, arithmetic shifts must be used.
To conclude our discussion of shifting, we revisit the problem of retrieving the data packed in the
word pictured in Figure 115 on page 249, but now assuming that each of the four integers is
signed rather than logical. The following code segment separates and stores the four signed integers as required; we again use the symbols LA, LB, LC, and LD to represent the bit lengths of
the fields, as in Figure 117.
L
SRDA
SRA
ST
SRDA
SRA
ST
SRDA
SRA
ST
ST

0,DataWord
0,LD
1,32-LD
1,Fourth
0,LC
1,32-LC
1,Third
0,LB
1,32-LB
1,Second
0,First

Get data word into GR0


Shift 6 bits into GR1
Sign-extend to right
Store fullword result D
Shift off 13 more bits into GR1
Shift with sign extension
Store signed result of C
Shift off next 4 bits for B
Sign-extend second integer
Store final result of B
Store correct first integer A

Figure 119. Unpacking four signed integers

As noted in Section 17.2, the instructions for shifting operands in 64-bit registers behave just like
the equivalent instructions for shifting operands in 32-bit registers. To illustrate, consider these
right shift instructions:
L
SRA

254

0,=A(X12345678)
0,9

c(GR0) initialized
c(GR0) = X00091A2B

Assembler Language Programming for IBM z System Servers

Version 1.00

The contents of GR0 is changed. For these instructions,


LG
1,=AD(X123456789ABCDEF0 ) c(GG1) initialized
SRAG 0,1,9
c(GG0) = X00091A2B 3C4D5E6F
the contents of the source register, GG1, is unchanged. If we initialize the source register with a
negative number, the sign bit is propagated:
L
SRA

0,=A(X87654321)
0,9

c(GR0) initialized
c(GR0) = X FFC3B2A1

and the contents of GR0 is changed. For these instructions,


LG
1,=XL8 FEDCBA9876543210
c(GG1) initialized
SRAG 0,1,9
c(GG0) = X FFFF6E5D 4C3B2A19
GG1 is again unchanged.
Left arithmetic shifts may cause overflow:
L
SLA

0,=A(X87654321)
0,9

c(GR0) initialized
c(GR0) = X CA864200 , CC=3

LG
1,=XL8 FEDCBA9876543210
c(GG1) initialized
SRAG 0,1,9
c(GG0) = X B97530EC A8642000 , CC=3
Double-Length Shifts
The double-length shift instructions (SRDA, SLDA, SRDL, SLDL)
always require an even-odd pair of general registers.

Exercises
17.4.1.(2) Suppose your CPU has only single-length arithmetic shift instructions (SLA, SRA).
There is a word at DataWord that is to be shifted arithmetically to the left, as though it was the
high-order word of a pair of general registers. Write an instruction sequence that simulates a
double-length arithmetic left shift of N bit positions, where N is a halfword integer at NShifts.
Assume 0 N < 32, and that the simulated low-order register contains zero. Store the result at
a doubleword named DWord. If you can, show whether or not the CC setting is correct at the
end of your instruction sequence.
17.4.2.(3) Do the same as in Exercise 17.4.1, and again assume you must do a double-length
arithmetic left shift of a 32-bit word in the high-order half. This time, assume 0 N < 64.
17.4.3.(3) + Do the same as in Exercise 17.4.1, but simulate a double-length arithmetic right
shift of N places, where 0 N < 32, and still assuming that the low-order half of the original
operand is zero.
17.4.4.(3) Do the same as in Exercise 17.4.3, but now assume 0 N < 64.
17.4.5.(3) + Do the same as in Exercise 17.4.1, but now assume the initial data is in a
doubleword at DWData, and store the left-shifted result at DWord.
17.4.6.(3) + Do the same as in Exercise 17.4.5, but now assume the initial data is in a
doubleword at DWData, and store the right-shifted result at DWord. (Remember that 0 N < 32.)
17.4.7.(3) Do the same as in Exercise 17.4.5, but now assume 0 N < 64.
17.4.8.(3) Do the same as in Exercise 17.4.6, but now assume 0 N < 64.
17.4.9.(3) In mathematics it is occasionally useful to define the integer-part-of or floor
function, that yields the largest integer not exceeding its argument. It is usually written with
square brackets like this:

Chapter V: Basic Instructions

255

[X]

is the largest integer X.

Show that in the twos complement binary representation, the result of arithmetically rightshifting a number Z by n bit positions gives the result [Z/(2**n)].
17.4.10.(3) Rewrite the code sequence of Exercise 17.3.9 assuming that the integers may be positive or negative (that is, they are stored in the arithmetic representation rather than the logical
representation).
17.4.11.(2) + Suppose there is a positive nonzero word integer stored at the word at NUM. Write
an instruction sequence that leaves a number in GR0 that the largest power of two less than or
equal to the given number. That is, compute 2**N such that 2**N c(NUM). (For example,
if c(NUM)=9, c(GR0) will be 8.)
17.4.12.(3) In Exercise 17.4.11, you wrote instructions to leave a number in GR0 that was the
largest power of two less than or equal to the nonzero positive number at NUM. Write another
instruction sequence, assuming that the number at NUM may be positive or negative. Leave a
number in GR0 that is either zero (if c(NUM) is), or is the largest power of two less than or
equal to the magnitude of c(NUM).
17.4.13.(3) In Exercise 17.4.11, you wrote instructions to leave a number in GR0 that was the
largest power of two less than or equal to the nonzero positive number in the word at NUM.
Write another code sequence that will leave the exponent of that power of two in GR0. (That
is, if the number left in GR0 in Exercise 17.4.11 is 2**N, c(GR0) is N.)
17.4.14.(3) + In describing the shift instructions on page 254, it was stated that a right shift of N
places was equivalent to a division by 2**N. This is sometimes true, and sometimes not true.
When is it true, and when not?
17.4.15.(2) Rewrite Exercise 17.3.15 assuming that the values are to be stored in the arithmetic
representation.
17.4.16.(2) Write a sequence of instructions that will count the number of 1-bits in the byte at
XX and replace the byte with its bit count.
17.4.17.(2) Suppose the initial contents of GG0 is X FEDCBA9876543210 before executing each of
these instructions:
(a)
(b)
(c)
(d)

SRAG
SLAG
SRA
SRLG

0,0,20
0,0,28
0,18
0,0,18

What result will be in GG0 after executing each instruction, and what will be the resulting CC
setting?
17.4.18.(2) + Suppose GR0 contains X87654321 before executing each of these instructions.
What will be in GR0 after it is executed, and what will be the CC setting?
1. SRA 0,20
2. LPR 0,0
3. SLA 0,28
17.4.19.(2) Suppose you want to display the individual bits in a byte at Byte in character form.
Write a program segment that will spread out the bits into eight EBCDIC characters starting
at Char so that the eight characters faithfully represent the bits in the byte.
17.4.20.(3) + Suppose your CPU supports logical but not arithmetic shifts. Write instructions
using logical shift instructions to perform the functions of SRDA, including setting the Condition Code correctly. The double-length operand to be shifted is in (GR0,GR1) and the shift
amount is in GR2. Other registers may be used as needed.

256

Assembler Language Programming for IBM z System Servers

Version 1.00

17.4.21.(2) + You can use SRA to divide a number by 2. But if the number is negative, the
result isnt always what you expect. For example:
L
SRA
L
SRA

0,=F+5
0,1
0,=F -5
0,1

c(GR0)
C(GR0)
c(GR0)
C(GR0)

=
=
=
=

X00000005
X00000002
X FFFFFFFB
X FFFFFFFD

=
=
=
=

+5
+2
-5
-3

In both cases the result is rounded downward, toward infinity. What should you do to be
sure right-shifting a negative number will give the same result (except for sign) when you divide
by 2 as for positive numbers?
17.4.22.(1) + Show how you can use a shift instruction to test the sign of the contents of a
general register without affecting its value.
17.4.23.(2) + An arithmetic right shift of a binary number makes it smaller in magnitude, except
for two values. What are they?

17.5. Rotating Shifts


Unlike the shift instructions weve seen, the rotating shift instructions RLL and RLLG neither
lose nor introduce bits. A rotate unit shift takes the leftmost bit of the register, shifts all the other
bits left one position, and inserts the previous leftmost bit at the right end of the register, as illustrated in Figure 120.

 b c d e  x y z a 

After

Figure 120. Logical rotate unit shift

As shown in Table 80 on page 243, the source operand in R 3 and the target operand in R1 can
be the same or different registers. If they are the same, the shift does not preserve the original
operand.
The rotating shift instructions are sometimes used in data compression algorithms. In applications
where speed of rotation is not important, their functions can be emulated using logical shifts.
(See Exercises 17.5.1 and 17.5.2.)
To illustrate a rotating shift, suppose we rotate the 32-bit operand X56789ABC left by 10 bit positions:
L
RLL

0,=A(X56789ABC )
1,0,10

Load initial data into GR0


Rotate 10 bits, result in GR1

Then c(GR1) will be X E26AF159 . Similarly, if we rotate the 64-bit operand X56789ABCDEF01234
left by 10 bit positions:
LG
0,=AD(X56789ABCDEF01234 )
Initialize GG0
RLLG 1,0,10
Rotate 10 bits, result in GG1
Then c(GG1) will be X E26AF37BC048D159 .

Exercises
17.5.1.(2) + Suppose your CPU has only single-length logical shift instructions (SLL, SRL). A
32-bit word at DataWord is to be rotated. Write an instruction sequence that simulates the RLL
instruction by doing a logical rotation of N bit positions, where N is any nonnegative number
stored in a halfword at NN. Store the result at RotateWd.

Chapter V: Basic Instructions

257

17.5.2.(3) Do the same as in Exercise 17.5.1, but now simulate the RLLG instruction using
SLDL and SRDL to do a double-length rotating shift of N places. Assume the initial data is in
a doubleword at DWData, and store the rotated double-length result at RotatDWd.
17.5.3.(1) Show how you can use a rotating shift to exchange the halves of a 64-bit general
register.

17.6. Calculated Shift Amounts


As we saw in Section 17.2, the number of bit positions shifted can be specified during program
execution, because the number of shifts in any shift instruction is determined from its Effective
Address. For example,
SLL

9,0(4)

will shift GR9 by an amount determined by the rightmost six bits of the contents of GR4.
Suppose GR1 contains a nonnegative integer less than 31; call it n. Then, to leave 2 n in GR0,
we could write
L
SLL

0,=F 1
0,0(1)

Put 2**0 = 1 in GR0


Shift left n places to form 2**n

The shift amount in GR1 could have been previously calculated or loaded into GR1 from
memory.
We can use shifts to illustrate an amusing (but not recommended!) application of the USING
statement. As with relocatable implied addresses, the Assembler computes displacements and
assigns base registers for absolute implied addresses. If we write the statements below, the
instructions would be assembled as indicated in the remarks fields of the last three statements.
USING 6,2
EQU 10

A
*

SLL
SLL
SLL

Absolute expression for base


Symbol with absolute value
Assembled instructions:
8990 2006 (implied address)
8990 000C (explicit address)
8990 2004 (implied address)

9,12
9,12(0)
9,A

in GR2

12 shifts
12 shifts
10 shifts

Thus we can vary the number of shifts at execution time by placing appropriate values in the
base register, GR2. This is a very poor programming technique; its far better to use an instruction like
SLL

9,0(2)

There are very few occasions where an absolute expression is used as the first operand in a
USING instruction. The need for caution is apparent when you consider what would happen to
a program with the implied-address shift instructions above, and then someone changed the contents of GR2.

Exercises
17.6.1.(2) + What will happen at both assembly and execution times if the following sequence of
three statements appears in a program:
A

USING *,2
EQU *
SLL 9,A

17.6.2.(2) + What number of shifts is specified by


SLL 9,*

Is that number fixed within any one program?

258

Assembler Language Programming for IBM z System Servers

Version 1.00

17.6.3.(2) + What number of shifts is specified by these instructions?


SLL 9,AAA
- - DC F 1 2

AAA

17.6.4.(2) Describe and evaluate the usefulness of each of the following methods for clearing a
32-bit general register x to zero: (1) SLL x,32 (2) L x,=F 0 (3) LH x,=H 0 (4)
SLDL x,32 (5) SRL x,32 (6) SRDL x,32 (7) SRDA x,32 (8) SLDA x,32.
17.6.5.(1) + In the mnemonics for the 32-bit (single-length) shift instructions, a consistent convention is used to indicate (1) the type, (2) the direction, and (3) the length of the shift. Make
a table that displays this convention.
17.6.6.(1) Can you think of any reason to perform a logical shift of more than 31 bit positions
in a single register? An arithmetic shift?
17.6.7.(2) + We wish to generate a pair of bytes containing the EBCDIC characters corresponding to the 2 hex digits in the byte at DATA. That is, if c(DATA) = X 4A , the generated
pair of bytes will contain X F4C1 . Write a code sequence that will store the two characters at CH
and CH+1, for any values in the byte at DATA. (Hint: construct a 16-byte character table, and
access it with an indexed IC instruction.)
17.6.8.(2) + Most z System instructions expect that their operands will be found in memory at
addresses satisfying a specific boundary alignment. This usually means that the Effective
Address of an instruction should be divisible by some number. For each of the following
instructions, show the number by which the Effective Address should be divisible.
1.
2.
3.
4.
5.
6.
7.
8.

L
BC
LH
ICM
LR
SRDA
STM
STC

17.6.9.(1) How many bit positions are shifted by this instruction?


SRL

7,=F 1 5

17.7. Bit-Length Constants (*)


In Figures 117, 118, and 119 we saw examples of using shift instructions to extract and insert
small binary constants in various fields within a 32-bit word. You can define constants with such
lengths using bit-length constants.
We first encountered length modifiers for binary constants in Section 11.4 on page 142, where we
defined constants like
DC

FL3 8

Such length modifiers determine the byte length of the constant.


You can also define the bit length of a constant by writing a length modifier specifying the
number of bits allotted to its assembled value; follow the modifier letter L with a period and the
number of bits. For example:
DC
DC

FL3 8
FL.24 8

can also be written

Chapter V: Basic Instructions

259

The same constant will be generated in both cases, aligned on the current location counter
boundary (not necessarily a word boundary).
The general form of a length modifier is either
LByteLength

as in L3

L(ByteLengthExpr)

as in L(2+1)

L.BitLength

as in L.24

L(BitLengthExpr)

as in L.(16+8)

or
or
or
but unfortunately you cannot combine the two by writing
LByteLength.BitLength

as in L2.5

The length modifier must be either byte or bit length, not both.
For both byte- and bit-length modifiers, the length value may be written either as a positive
decimal constant or as a positive absolute expression in parentheses.
A nominal value need can be any length (subject to normal truncation and padding rules)
FL.122047,FL.8 6 4 , XL.4 D

DC

generates X 7 FF40D

Incomplete bytes are padded with zero bits:


DC

FL.122047

generates X 7 FF0

Now we can see how to generate the packed unsigned binary integers in Figure 115. Suppose
the four integers A, B, C, and D have values 432, 12, 5001, and 47 respectively. We can define a
word containing these values as shown in Figure 121:
0F,FL.9 U432 , FL.4 U12 , FL.13 U5001 , FL.6 U47

UnsdVals DC

Figure 121. Packing four unsigned bit-length constants in a 32-bit word

Similarly, if the four values could be signed, with values 232, 8, 4001, and 31 respectively,
we could define a word containing their values as shown in Figure 122:
0F,FL.9 -232 , FL.4 -8 , FL.13 -4001 , FL.6 -31

SgndVals DC

Figure 122. Packing four signed bit-length constants in a 32-bit word

Exercises
17.7.1.(1) What differences might you find for these constants?
A
B
C

DC
DC
DC

F -97
FL4 -97
FL.32 -97

17.7.2.(2) + In Figure 121, What constant is generated? What constant would be generated if the
letter U is omitted?
17.7.3.(2) + In Figure 122, What constant is generated?
17.7.4.(3) + Rewrite the constant definitions in Figures 121 and 122 to use the symbolic definitions of the four field lengths named LA, LB, LC, and LD respectively, as shown in Figure
117.
17.7.5.(2) + If you cant write a bit-length constant with a length modifier of the form LA.B
(where A is the byte length and B is the bit length), how can you write it to achieve equivalent
results?

260

Assembler Language Programming for IBM z System Servers

Version 1.00

17.8. Summary
Table 82 summarizes the shift instructions discussed in this section. As mentioned above, the
notation 32+32 means that the shift is in a pair of 32-bit general registers.
Function

Arithmetic shift

SLA
SRA

32 + 32
SLDA
SRDA

Logical shift

SLL
SRL

SLDL
SRDL

Rotating shift

RLL

Operand length (bits)

32

64
SLAG
SRAG
SLLG
SRLG
RLLG

Table 82. Summary of shift instructions discussed in this section

The instruction mnemonics and opcodes are shown in the following table:
Mnemonic
RLL

Opcode
EB1D

Mnemonic
SLDL

Opcode
8D

Mnemonic
SRDA

Opcode
8E

RLLG

EB1C

SLL

89

SRDL

8C

SLA

8B

SLLG

EB0D

SRL

88

SLAG

EB0B

SRA

8A

SRLG

EB0C

SLDA

8F

SRAG

EB0A

The instruction opcodes and mnemonics are shown in the following table:
Opcode
88

Mnemonic
SRL

Opcode
8D

Mnemonic
SLDL

Opcode
EB0C

Mnemonic
SRLG

89

SLL

8E

SRDA

EB0D

SLLG

8A

SRA

8F

SLDA

EB1C

RLLG

8B

SLA

EB0A

SRAG

EB1D

RLL

8C

SRDL

EB0B

SLAG

Terms and Definitions


arithmetic shift
A movement of bits in a general register to the left or right, preserving the arithmetic sign of
the operand.
logical shift
A movement of bits in a general register to the left or right, inserting zero bits into any
vacated bit positions.
rotating shift
A movement of bits in a general register to the left in such a way that bits moved out of the
high-order bit position are inserted into the low-order bit position. (Also called a
circulating shift.)

Programming Problems
Problem 17.1.(2) Write a program that takes a positive word integer from the memory area
named Data and shifts it left until its next-to-highest-order bit (that is, bit number 1) is nonzero.
Store the result in a word area named Norm, and store at the halfword area Count the number of

Chapter V: Basic Instructions

261

shifts required. Print the contents of Data, Norm, and Count. Run the program with several
different values at Data such as 1, 999, 2147483647, and others.
Problem 17.2.(2) A programmer suggested using these instructions to convert the eight bits in a
byte to eight EBCDIC characters representing their value.
ICM 1,B1000,DataByte
LHI 2,8
Loop
SLLG 3,3,8
SR
0,0
SLDL 0,1
A
0,=A(X F0 )
ALR 3,0
SH
2,=H 1
BP
Loop
STG 3,BitChars
- - BitChars DS
D

Put the byte at the left end of GR1


Set the bit count to 8
Make room in GG3 for the character
Clear GR0
Shift a low-order bit into GR0
Add X F0 to make a character
Insert the character into GG3
Count down by 1
Repeat for all 8 bits
Store the 8 characters
8 EBCDIC 0 and 1 characters

Write a program with several data values to test her assertion.


Problem 17.3.(1) Using the instructions in Figure 119 on page 254, write a program to unpack
the four signed integers of Figure 122 on page 260 at the word named SgndVals and display
the unpacked values at First, Second, Third, and Fourth as fullword integers.

262

Assembler Language Programming for IBM z System Servers

Version 1.00

Chapter V: Basic Instructions

263

18. Binary Multiplication and Division

11
111
1111
11
11
11
11
11
11
1111111111
1111111111

8888888888
888888888888
88
88
88
88
88888888
88888888
88
88
88
88
88
88
888888888888
8888888888

When we multiply two numbers, the product can be as long as the sum of their lengths. For
example, multiplying the three-digit decimal number 999 by itself, 999999 gives 998001: six digits
long. Thus, we will need double-length registers if our products of single-length numbers can be
longer than a single register.
The terminology used for the operands is from mathematics:

multiplicand (first operand)


multiplier (second operand)
product

18.1. Overview of Multiplication Instructions


The instructions well examine are summarized in Table 83. The notation 3232 means the
product of two 32-bit integers, and similarly for 3216, 6464, and 6432.
Op
5C

Mnem
M

Type Instruction
R X Multiply (32 + 323232)

4C

MH

RX

71

MS

RX

E351

MSY

RXY

E30C

MSG

RXY

E31C

MSGF

RXY

E396

ML

RXY

E386

MLG

RXY

Multiply Halfword
(323216)
Multiply Single
(323232)
Multiply Single
(323232)
Multiply Single
(646464)
Multiply Single
(646432)
Multiply Logical
(32 + 323232)
Multiply Logical
(64 + 646464)

Op
1C

Mnem
MR

Type Instruction
R R Multiply Register
(32 + 323232)

B252

MSR

R R E Multiply Single Register


(323232)

B90C

MSGR

B91C
B996
B986

R R E Multiply Single Register


(646464)
M S G F R R R E Multiply Single Register
(646432)
MLR
R R E Multiply Logical Register
(32 + 323232)
M L G R R R E Multiply Logical Register
(64 + 646464)

Table 83. Binary integer multiply instructions

264

Assembler Language Programming for IBM z System Servers

Version 1.00

The result of each multiply instruction is a 32-bit, 64-bit, or 128-bit product, as indicated by
32... (for a single 32-bit register), 32+ 32... (for a 64-bit product in a pair of 32-bit registers), 64... (for a single 64-bit register), and 64+ 64... (for a 128-bit product in a pair of
64-bit registers). As we saw for signed and logical addition and subtraction, signed multiplications
sign-extend short operands, and logical multiplications zero-extend short operands.
As Table 83 indicates, there are no instructions giving a 128-bit arithmetic product of two signed
64-bit operands. 110
None of these instructions change the CC setting.
Condition Code
Binary multiplication and division do not change the CC setting.
Signed multiply instructions are the most frequently used, so well discuss them first.

18.2. Arithmetic (Signed) Multiplication Instructions


The two types of arithmetic multiplication instructions give either single-length or double-length
products. Because double-length products are more often used, well start with those.

18.2.1. Double-Length Arithmetic Products


The instructions yielding arithmetic 64-bit double-length products are:
Op
5C

Mnem
M

Type Instruction
R X Multiply (32 + 323232)

Op
1C

Mnem
MR

Type Instruction
R R Multiply Register
(32 + 323232)

Table 84. Double-length arithmetic multiply instructions

M and MR form the 64-bit product of two 32-bit operands. The first operand, the multiplicand,
is in the odd-numbered register of an even-odd register pair. The second operand, the multiplier,
is either in a register or a word in memory, as illustrated in Figure 123. Note that the initial
contents of the even-numbered register, GR R 1, are ignored (unless GR R 1 contains the second
operand).
R1 (even)
R1+1 (odd)

//////////////////////
Multiplicand

32
63 32
63

Multiplier
R2 or D2(X2,B2)
(in register or memory)
Figure 123. General layout of multiplication operands

After the operation completes, the 64-bit product is in the register pair, as shown in Figure 124.

110

At the time of this writing. But new instructions are added regularly to the z System architecture, so check the Principles of Operation. However, you can generate signed products using the unsigned multiply instructions; see Exercises
18.3.2 and 18.3.3.
Chapter V: Basic Instructions

265

R1 (even)
R1+1 (odd)

 Product
Figure 124. Double-length product of multiply operations

For M and MR, no fixed-point overflow is possible. As with the double-length shift instructions,
the even-numbered register is the high-order half of an even-odd register pair, and the next higher
odd-numbered register is the low-order half. The CPU takes the multiplicand from the oddnumbered register and the multiplier from the address or register specified by the second operand.
The product replaces the original contents of the pair of registers, and the high-order bit of the
odd-numbered register is a part of the product, not necessarily a sign bit. The following
instructions produce the indicated results.
*

MR 2,7
Square the number in GR1
MR 0,1
MR 8,8
M
4,XX
M
12,=F932
Square the number in GR4
LR 5,4
MR 4,4

c(GR2,GR3) = c(GR3) * c(GR7)


c(GR0,GR1) =
c(GR8,GR9) =
c(GR4,GR5) =
c(GR12,GR13)

c(GR1) * c(GR1)
c(GR9) * c(GR8)
c(GR5) * c(XX)
= c(GR13) * 932

Move multiplicand to GR5


c(GR4,GR5) = c(GR5) * c(GR4)

The last two instructions show how to square the integer in GR4: the LR instruction copies the
multiplier to the odd-numbered register. The presence of the multiplier in the even-numbered
register does not cause it to be lost when that register is cleared at the beginning of the multiply
sequence; the multiplication takes place after the CPU has saved a copy of the multiplier. After
the LR we could also have used MR 4,5, giving c(GR5)c(GR5).
The product generated by the M and MR instructions is 64 bits long. If we perform these
instructions:
L
1,=A(X10000)
MR
0,1
ST
1,Product
- - Product DS
F

c(GR1) = 65536 = 2**16


Square it to get 2**32
Store low-order half

we would find that the word stored at Product was zero, and that c(GR0) = 1. Similarly, if we
execute these instructions (where 32768 = 2 15):
L
M
ST

1,=A(X10000)
0,=A(X8000)
1,Product

c(GR1) = 65536
Multiply by 32768; result = +2**31
Store +2**31 (??)

we would find that c(GR0)=0, and c(Product) = 231!


There are two situations needing caution. First, the product may be so long that significant bits
occupy more than the low-order register. Second, whether or not the high-order register contains
significant bits, the leftmost bit of the low-order register can be interpreted as a sign bit only if the
product lies in the range
-231 product < +231
Otherwise, the low-order sign bit contains an arithmetically significant digit with positive weight.
As an example using a multiply instruction, suppose we want to evaluate A = B + G * D, a typical
expression in a high-level language. All quantities are word integers, and we assume all results are
small enough so that no overflows occur.

266

Assembler Language Programming for IBM z System Servers

Version 1.00

L
M
A
ST

7,G
6,D
7,B
7,A

c(GR7) = c(G)
c(GR6,GR7) = G * D
c(GR7) = B + (G*D)
Store result at A

We have used the symbols A, B, G, and D to denote both the names of word areas of memory and
the values of the contents of those areas (that is, as variables). This usage is typical of high-level
languages, where little distinction is made among the name associated with an area of memory,
the contents of that area, the value associated with the contents, and the name of the value.111
Suppose we wish to compute the sum of the cubes of the first N integers, where N is stored in the
word at NBR. We assume that N is a small enough positive integer that the sum of the cubes is
representable in a single word. The quantity called K is a counter that runs from 1 to N in
steps of 1.

Repeat

NBR

SR
L
LR
MR
MR
AR
A
C
BNH
ST
- - DC

5,5
4,=F 1
1,4
0,1
0,4
5,1
4,=F 1
4,NBR
Repeat
5,Sum

Sum carried in GR5


Initialize K in GR4
c(GR1) = K
c(GR0,GR1) = K * K
c(GR0,GR1) = K cubed
Accumulate sum
Increment K
Compare to upper limit at NBR
Repeat if K is not bigger
Store sum of first N cubes

F 1 0

Figure 125 shows a slightly different version of this example; it counts from N down to 1:

Repeat

SR
L
LR
MR
MR
AR
S
BP
ST

5,5
4,NBR
1,4
0,4
0,4
5,1
4,=F 1
Repeat
5,SUM

initialize sum to zero


Initialize K from c(NBR) = N
c(GR1) = K
c(GR0,GR1) = K * K
c(GR0,GR1) = K cubed
Add to sum
Decrement K by 1
Repeat if K is still positive
Store sum of first N cubes

Figure 125. Calculate the sum of the first 10 cubed integers

18.2.2. Single-Length Arithmetic Products


The instructions generating single-length arithmetic products are shown in Table 85.
When you know a product will be small enough to fit correctly in a single-length register, or if
you dont care that some high-order bits may be lost, these instructions avoid needing an
even-odd register pair, and may also execute faster than the instructions generating double-length
products.

111

These distinctions are very important in Assembler Language, and can be very confusing to people whose first programming experiences were with high-level languages.
Chapter V: Basic Instructions

267

Op
4C

Mnem
MH

Type Instruction
RS
Multiply Halfword
(323216)

Op

Mnem

Type Instruction

71

MS

RX

B252

MSR

R R E Multiply Single Register


(323232)

E351

MSY

E30C

MSG

Multiply Single
(323232)
RXY Multiply Single
(323232)
RXY Multiply Single
(646464)

B90C

MSGR

R R E Multiply Single Register


(646464)

E31C

MSGF

RXY Multiply Single


(646432)

B91C

M S G F R R R E Multiply Single Register


(646432)

Table 85. Single-length arithmetic multiply instructions

The MH instruction produces a single-length (word) result, the low-order 32 bits of the product of
c(GR R 1) and the halfword second operand. Because only a word result is retained, R1 need not
be even. For example,
MH

5,=H100

Multiply c(GR5) by 100

is a simple way to multiply the contents of GR5 by 100 without affecting the contents of the
lower even-numbered register, GR4. If X and Y are both halfword operands, their product may be
found by writing
LH
MH

8,X
8,Y

Multiplicand in GR8 (even register!)


Multiply by c(Y), product in GR8

and GR9 remains undisturbed. To square the halfword integer at N, we could write
LH
MH

1,N
1,N

c(N) in GR1
N squared in GR1

Because both operands are halfwords with at most 15 significant bits, the product will always fit
in a single register. The only halfword whose magnitude requires 16 bits ( 215) when squared
yields 230, requiring only 31 bits.
As weve seen for MH, all the Multiply Single instructions place the product in a single-length
register. The register may be either even- or odd-numbered; the other register of the pair is not
changed. Other instructions generating a product in a 32-bit register are MS and MSR. For
example:
L
MS

1,=F12345
1,=F12347

c(GR1) = 12345
c(GR1) = 152423715

L
L
MSR

1,=F12345
7,=F12347
1,7

c(GR1) = 12345
c(GR7) = 12347
c(GR1) = 152423715

and the product is small enough to be held correctly in GR1.


MSG and MSGR, and MSGF and MSGFR produce a 64-bit product in a single 64-bit register.
MSG and MSGR are exact analogs of MS and MSR:
LG
MSG

1,=FD12345678
1,=FD23456789

c(GG1) = 12345678
c(GG1) = 289589963907942

LG
1,=FD12345678
LG
7,=FD23456789
MSGR 1,7

c(GG1) = 12345678
c(GG7) = 23456789
c(GG1) = 289589963907942

MSGF and MSGFR generate a 64-bit product of a 64-bit first operand and a 32-bit second
operand by first internally sign-extending the 32-bit second operand to 64 bits:

268

Assembler Language Programming for IBM z System Servers

Version 1.00

LG
1,=FD12345678
MSGF 1,=F23456789

c(GG1) = 12345678
c(GG1) = 289589963907942

LG
1,=FD12345678
L
5,=F23456789
MSGFR 1,5

c(GG1) = 12345678
c(GR5) = 23456789 (32 bits!)
c(GG1) = 289589963907942

Exercises
18.2.1.(1) + What is the value of the largest 64-bit product that can be generated by signed multiplication of 32-bit operands?
18.2.2.(4) Given two unsigned 32-bit integers stored in the words at X and Y, show first how
you can generate their unsigned 64-bit product using the arithmetic multiplication instructions
M and MR. Then, write a sequence of instructions that will store the product in the
doubleword at LogProd.
Let X be the logical (unsigned) representation corresponding to the arithmetic representation x
of some integer, and similarly for Y and y. To form the logical product of the operands X and
Y, we must modify the product xy given by the processor operation of multiplication, which
assumes that the operands are in the arithmetic representation. It will help to remember (from
Section 2.7) that
XY = (232+x)(232+y) = 264 + 232(x+y) + xy (modulo 264)
18.2.3.(2) + What is the value of the largest 48-bit product that can be generated by signed multiplication of 32-bit and 16-bit operands? The largest 96-bit value generated by signed multiplication of 32-bit and 64-bit operands?
18.2.4.(3) + Write a sequence of instructions that forms the product of the positive word integers at A and B, leaves the result in (GR0,GR1), and transfers to Overflow if the result is too
large to be represented in a word.
18.2.5.(4) + Do the same as in Exercise 18.2.4, but make no restrictions on the signs of the
operands.
18.2.6.(4) + Rewrite your solution to Exercise 18.2.5 to branch to OverPos if the result is too
large and positive, and to OverNeg if the result is too large and negative.
18.2.7.(3) Suppose GR11 and GR12 contain the addresses of the first items in two tables of ten
consecutive halfword integers each. Write a code sequence that computes the inner product
of the two tables; that is, compute the product of the first elements from each table, add to it
the product of the second items, etc. Store the final sum as a double-length integer beginning at
the word named DwSum. The addresses in R11 and R12 may be modified. Since there are ten
products, the accumulated sum could overflow the capacity of a single register. Be sure to
handle negative products correctly.
18.2.8.(3) Simplify the coding of Exercise 18.2.2 assuming that the arithmetic representation
corresponding to x is known to be positive at all times.
18.2.9.(2) When we use the M and MR instructions, the first operand specifies an evennumbered register. However, the multiplicand is actually in the next higher odd-numbered register. Can you think of any reasons why the designers of z System did not require that the
actual (odd) multiplicand register be specified?
18.2.10.(2) + Write a simple sequence of instructions that will determine whether the 64-bit
product in (GR0,GR1) is too large to be carried in a single register.
18.2.11.(2) + If all values are positive, what is the value of the largest 48-bit product that can be
generated by multiplication of 32-bit and 16-bit operands? The largest 96-bit value generated by
multiplication of 32-bit and 64-bit operands?

Chapter V: Basic Instructions

269

18.2.12.(3) Given a signed 32-bit operand A and an unsigned 32-bit operand B, write
instructions that will generate their signed 64-bit product.
18.2.13.(2) + A programmer wanted to test whether the product of two positive 32-bit binary
integers was too large to fit in a 32-bit register. Will these instructions do what he wants?

X
Y

L
1,X
M
0,Y
LTR 0,0
BZ
ProdOK
- - DC
F . . .
DC
F . . .

Load first operand


Multiply by second operand
Check high-order 32 bits
If they re zero, product fits
Not OK

18.2.14.(3) + You have created a signed binary product in (GR0,GR1) using instructions like
L
M

1,X
0,Y

and you want to determine whether its value can be stored correctly in the 32-bit field Prod32
or (to be stored correctly) must be stored in the 64-bit field Prod64. Write instructions to make
that determination and store the result.
18.2.15.(2) What would be stored at Z by these instructions?

X
Y
Z

L
3,X
M
2,Y
SR
2,3
ST
2,Z
- - DC
F 9
DC
F -7
DS
F

18.3. Logical (Unsigned) Multiplication Instructions


Table 86 lists the logical multiplication instructions:
Op
E396

Mnem
ML

E386

MLG

Type Instruction
RXY Multiply Logical
(32 + 323232)
RXY Multiply Logical
(64 + 646464)

Op
B996

Mnem
MLR

B986

MLGR

Type Instruction
R R E Multiply Logical Register
(32 + 323232)
R R E Multiply Logical Register
(64 + 646464)

Table 86. Logical multiply instructions

Logical multiply instructions are similar to arithmetic multiply instructions, except that the operands and results are unsigned. All four instructions generate a double-length product in an
even-odd register pair. Logical multiplication is frequently used when high- or multiple-precision
calculations are required112. Although you can use arithmetic multiplication instructions to generate logical products, and logical multiplication instructions to generate arithmetic products, extra
instructions and time are needed.113 Its simplest to use whichever instruction is best suited to the
type of operand.

112
113

270

Some encryption and decryption algorithms use multiple-precision arithmetic extensively.


Try Exercises 18.2.2 and 18.3.2.
Assembler Language Programming for IBM z System Servers

Version 1.00

For example, suppose you multiply the maximum negative 32-bit number by itself using arithmetic and logical multiply instructions:
*

Arithmetic multiplication
L
1,=X80000000
c(GR1) = -2147483648
MR
0,1
c(GR0,GR1) = X40000000 00000000

Logical multiplication
L
1,=X80000000
MLR 0,1

c(GR1) = +2147483648
c(GR0,GR1) = X40000000 00000000

The result is the same in both cases. Arithmetically, the maximum negative number has value
231, and the same bit pattern as an unsigned number has value + 231. Thus, the product in both
cases is + 262. Now, lets try squaring a different operand, 1:
* Arithmetic multiplication: (-1)*(-1) = +1
L
1,=F -1
c(GR1) = X FFFFFFFF
MR
0,1
c(GR0,GR1) = X00000000 00000001
* Logical multiplication: (2**32-1)*(2**32-1) = 18446744065119617025
L
1,=F -1
c(GR1) = X FFFFFFFF
MLR 0,1
c(GR0,GR1) = X FFFFFFFE 00000001
These results are very different! The bit pattern X FFFFFFFF represents 1 arithmetically, but
232 1 logically.
The MLG and MLGR instructions generate 128-bit products in an even-odd pair of 64-bit registers:
LG
MLG

1,=FD74296604373 c(GG1) = 74296604373


0,=FD9876543210 c(GG0,GG1) = 733793623446209457330

LG
1,=FD74296604373 c(GG1) = 74296604373
LG
3,=FD9876543210 c(GG3) = 9876543210
MLGR 0,3
c(GG0,GG1) = 733793623446209457330
These instructions can generate very large products!

Exercises
18.3.1.(1) What is the value of the largest 64-bit product that can be generated by logical multiplication of 32-bit operands?
18.3.2.(3) Given two signed 32-bit integers stored in the words at P and Q, show first how you
can generate their signed 64-bit product using the logical multiplication instructions ML and
MLR. Then, write a sequence of instructions that will store the product in the doubleword at
ArProd.
18.3.3.(4) Do the same as in Exercise 18.3.2, but this time form the 128-bit signed product of
two 64-bit signed operands at DP and DQ using the logical multiplication instructions MLG and
MLGR. Store the result in the pair of doublewords at ArProd2.
18.3.4.(4) As in Exercise 16.6.3 on page 230, form the product of the two 256-bit integers at
A256 and B256 to form a 512-bit product stored at Prod256.

Chapter V: Basic Instructions

271

18.4. How Multiplication Is Done (*)


To illustrate the method used in multiplication, well first use an example in decimal arithmetic.
Suppose we have a processor with registers that hold 3-digit decimal numbers that we assume
are positive, and we multiply 213 and 126. Since we are multiplying two 3-digit numbers, the
product can be 6 digits long. Thus, we assume there is a double-length 6-digit register whose right
and left halves hold a 3-digit number.
When working with pencil and paper, we form the product of the multiplier and each of the multiplicand digits in succession, and generate a series of partial products that must be properly
aligned and then added:
Multiplicand
Multiplier
partial
products
Product

213
126
1278
426
213
26838

Well now see how this manual process can be broken down into steps that are more like the
method used in a computer.
1. We place the multiplicand in the right half of the double-length register, and clear the left half
to zero.
Initial register contents

000 213

2. By examining the rightmost digit of the multiplicand we know how many times to add the
multiplier to the left half of the double-length register. As an aid in counting how many times
to add the multiplier, we decrement the rightmost multiplicand digit by 1 for each addition.
When the rightmost digit has been counted down to zero, the partial product of that digit
and the multiplier has been added to the accumulating result.
Initial register contents
Add multiplier to upper end
that s 1 time
Add multiplier
that s 2 times
Add multiplier
that s 3 times

000
+126
126
+126
252
+126
378

213
212, count down at right
211, count down at right
210, count down at right

3. The entire double-length register is shifted right one digit position, at which time the (now)
zero digit at the right-hand end is lost, and a zero digit is inserted in the vacated position at
the left.
Shift right one place
Add multiplier
that s 1 time

037 821
+126
163 820, count down at right

4. After the second shift, the final multiplicand digit is 2:


Shift right one place
Add multiplier
that s 1 time
Add multiplier
that s 2 times
Shift right one place

016
+126
142
+126
268
026

382
381, count down at right
380, count down at right
838

This process of adding the multiplier and counting down on the multiplicand digit continues until
the proper partial product has been added to the accumulated result. This process is repeated for
as many steps as there are multiplicand digits. When completed, the product is in the doublelength register, and all multiplicand digits have been shifted off the right-hand end.
The main points are:
the multiplicand is initially placed in the right half of the double-length register;

272

Assembler Language Programming for IBM z System Servers

Version 1.00

the left half is initially cleared to zero (after saving the multiplier if it was in the left half);
the multiplier is added to the left end a number of times determined by the multiplicand digit
at the far right; and
the least significant digit of the result is at the right-hand end of the double-length register,
because the number of right shifts was the same as the number of positions in a single-length
register.
When used for multiplying binary numbers, the above scheme is very easy to implement, because
testing the rightmost bit determines whether or not the multiplier is to be added, and no counting
is required. Suppose we have 5-digit binary numbers and registers, and wish to multiply B00110
(=6) by B01001 (=9) to obtain a 10-bit product in a double-length register. The sequence of
steps in Figure 126 shows how this is done.
Initialize

00000 01001 Multiplicand, in right half of


double-length register
00110

Step 1: Rightmost bit = 1,


Add multiplier
Shift right 1 place
Step 2: Rightmost bit = 0,
Shift right 1 place
Step 3: Rightmost bit = 0,
Shift right 1 place
Step 4: Rightmost bit = 1,
Add multiplier
Shift right 1 place
Step 5: rightmost bit = 0,
Shift right 1 place

Multiplier, in separate register

00110 01001
00011 00100 (The 1-bit is lost)
00001 10010
00000 11001
00110 11001
00011 01100 (The 1-bit is lost)
00001 10110 Final product (=54)

Figure 126. Illustration of binary multiplication

It is important to observe that the product really is a double-length number, and not just two
single-length numbers joined end to end. If we consider the contents of the left and right halves of
the double-length register as ordinary single-length twos complement operands, we might believe
the result in the right, or low-order half, was negative! Since a product of two positive numbers
must be positive, a double-length register means that no special significance can be attached to the
sign bit of the low-order half of the result, unless we know in advance that the product is correctly
representable in a single register.114 The leftmost bit of the right-hand register is therefore not a
sign bit; it has positive weight in the double-length result, and the products sign bit is the leftmost bit of the high-order register.
Modern processors gain speed by considering not just the rightmost bit of the multiplicand, but
groups of two, three, or even four bits. In cases where the arithmetic can be considered to be base
4, 8, or 16, the proper multiple is not found by counting down by ones on the multiplicand
bits, but by having internal shifting or table look-up circuits generate the proper factor of the multiplier in many fewer steps. This increases the speed of multiplication, since a separate addition is
not required for each 1 bit in the multiplicand.

114

Because many multiplications involve small numbers not needing a double-length product, the various Multiply
Single instructions were created. They can be faster than instructions generating double-length products.
Chapter V: Basic Instructions

273

18.5. Division Instructions


As with multiplication, the terminology is taken from mathematics:
Quotient
Divisor ) Dividend
- - - Remainder
While multiplying two n-digit numbers usually gives a 2n-digit product, dividing a 2n-digit dividend by an n-digit divisor does not necessarily produce an n-digit quotient. If for example we use
3-digit decimal numbers, 999999=998001; but 998001 100 gives quotient 9980 and remainder 1,
with a 4-digit quotient.
If the divisor is zero, or if the quotient is too large to fit in a single-length register, a Fixed-Point
Divide interruption will occur, with Interruption Code 9. This condition cannot be suppressed (as
can Fixed-Point Overflow). It is important to be careful when preparing for division!
The divide instructions well consider are shown in Table 87.
Op
5D

Mnem
D

E30D

DSG

E31D

DSGF

E397

DL

E387

DLG

Type Instruction
R X Divide
(32,323 2 + 3 2 32)
RXY Divide Single
(64,6464 64)
RXY Divide Single
(64,6464 32)
RXY Divide Logical
(32,323 2 + 3 2 32)
RXY Divide Logical
(64,646 4 + 6 4 64)

Op
1D

Mnem
DR

B90D
B91D
B997
B987

Type Instruction
R R Divide Register
(32,323 2 + 3 2 32)
DSGR
R R E Divide Single Register
(64,6464 64)
D S G F R R R E Divide Single Register
(64,6464 32)
DLR
R R E Divide Logical Register
(32,323 2 + 3 2 32)
D L G R R R E Divide Logical Register
(64,646 4 + 6 4 64)

Table 87. Binary divide instructions

The notation describing the operands and results of these instructions shows the general register
results to the left of the character, and the dividend and divisor to the right. For example,
for the D instruction, (32,3232+32 32) means that the quotient and remainder 32,32 are both
32-bit words; the dividend 32+32 is a pair of 32-bit registers, and the divisor is a 32-bit integer.
Similarly, for DSGF, (64,6464 32) means that the quotient, remainder, and dividend are 64-bit
integers, and the divisor is a 32-bit sign-extended integer.
As Table 87 indicates, there are no instructions (like DG, DGR) for dividing 128-bit arithmetic
operands by a signed 64-bit divisor of the form (64,64128 64), nor instructions (like DS, DSR)
for dividing 32-bit signed operands by 32-bit divisors.115
When any division instruction completes without interruption, the quotient is found in the oddnumbered register of the pair, and the remainder in the even-numbered register, as illustrated in
Figure 127.
R1
R1+1

Remainder

Quotient

Figure 127. General result of divide operation

115

274

At the time of this writing. But new instructions are added regularly to the z System architecture, so check the Principles of Operation.
Assembler Language Programming for IBM z System Servers

Version 1.00

None of the divide instructions changes the CC setting, and an even-odd register pair is always
required, even for the Divide Single instructions.
Register Pairs for Division
All z System binary integer divide instructions require an even-odd register pair.

Exercises
18.5.1.(2) + If you divide an ND-digit dividend (numerator) by a DD-digit divisor (denominator), what are the minimum and maximum numbers of digits QD in the quotient and RD in
the remainder? Assume a valid division, and that zero is a valid result.

18.6. Arithmetic (Signed) Division Instructions


Table 88 summarizes the arithmetic division instructions:
Op
5D

Mnem
D

E30D

DSG

E31D

DSGF

Type Instruction
R X Divide
(32,323 2 + 3 2 32)
RXY Divide Single
(64,6464 64)
RXY Divide Single
(64,6464 32)

Op
1D
B90D
B91D

Mnem
DR

Type Instruction
R R Divide Register
(32,323 2 + 3 2 32)
DSGR
R R E Divide Single Register
(64,6464 64)
D S G F R R R E Divide Single Register
(64,6464 32)

Table 88. Arithmetic divide instructions

The Divide Single instructions (DSG, DSGR, DSGF, and DSGFR) have only a single-length
dividend; well examine them shortly.

18.6.1. Double-Length Division


The most commonly used divide instructions are D and DR. The 64-bit double-length dividend
(the first operand) is placed in an even-odd pair of 32-bit registers, and the second operand (the
divisor) is in another register or a word in memory. This is illustrated in Figure 128.
R1 (even)
R1+1 (odd)

 Dividend

Divisor
R2 or D2(X2,B2)
(in register or memory)
Figure 128. Operands of double-length division

This type of division uses a double-length dividend and a single-length divisor, yielding singlelength quotient and remainder. The sign of the quotient is determined from the usual rules of
algebra; the sign of the remainder is the same as the sign of the original dividend, except that a
zero quotient or remainder always has a zero sign bit.
As with the double-length multiply instructions, the R1 digit is always even, and specifies the register pair containing the double-length dividend. The quotient replaces the low-order half of the
dividend in the odd-numbered register, and the remainder replaces the high-order part of the dividend in the even-numbered register. If a valid quotient cannot be computed, a Fixed-Point
Divide interruption occurs. (An improper division is shown in Figure 133 on page 277.)
Chapter V: Basic Instructions

275

To illustrate, we divide the double-length number in (GR8,GR9) by the number in GR13.


DR

8,13

Divide c(GR8,GR9) by c(GR13)

To divide the same number by 10 we could write


D

8,=F 1 0

Divide c(GR8,GR9) by 10

The most common use of division occurs when dividing a 32-bit word operand by another. For
double-length dividends that must be 64 bits long, you cant just load the dividend operand into
an odd-numbered register and immediately divide, because the even-numbered register is treated
by the CPU as containing the most significant bits of the dividend. We must first extend the sign
bit of the single-length dividend to form its correct double-length representation.
There are two ways to do this:
1. Multiply the 32-bit dividend (in the odd-numbered register) by 1:
L
M

7,NN
6,=F 1

Load 32-bit dividend in GR7


Times 1 gives 64-bit signed dividend

While easy to understand, this method may be slower than the next.
2. The most common method is to load the 32-bit dividend into the even-numbered register,
and then use an SRDA instruction:
L
6,NN
SRDA 6,32

c(GR6) = c(NN)
c(GR6,GR7) = 64-bit signed dividend

Suppose we want to divide the positive or negative word integer at G by three, and store the
quotient at G_Over_3.
L
SRDA
D
ST

8,G
8,32
8,=F 3
9,G_Over_3

Put numerator into even register


Sign-extend to double length
Divide by three
Store quotient

Figure 129. Example of division by 3

Suppose we want to compute the product of the integers in the words named A and B and force
the result to the next larger multiple of 29 if it is not already an exact multiple. (We assume that
the product is small enough that a fixed-point divide interruption will not occur when dividing by
29, and that the final result fits in a single word.)

Mult

L
M
D
LTR
BZ
A
M
ST

3,A
2,B
2,=F 2 9
2,2
Mult
3,=F 1
2,=F 2 9
3,Result

c(GR3) = c(A)
c(GR2,GR3) = c(A) * c(B)
Quotient in GR3
Test remainder in GR2
Branch if c(GR2) is zero
increase quotient by 1
Form correct multiple of 29
Store proper result

This example assumes the final product is correctly represented in the 32 bits of GR3.
Here are two examples of division with rounding.
1. Suppose we want to divide the positive integer at NN by 10, and store the rounded quotient at
QQ. This means that if the remainder is 5 or larger, the quotient must be increased by 1.
L
SR
D
C
BL
A
NoRound ST

7,NN
6,6
6,=F 1 0
6,=F 5
NoRound
7,=F 1
7,QQ

Low-order part of positive dividend in GR7


Set high-order part to zero
Divide by 10
Compare remainder to 5
Branch if smaller than 5
Otherwise round up
Store rounded result

Figure 130. Example of rounded integer division

276

Assembler Language Programming for IBM z System Servers

Version 1.00

2. Now, suppose the integer at NN can be either positive or negative. The above instruction
sequence will not work, for two reasons. First, the initial value of the dividend would not
have a correctly extended sign bit for negative arguments (because we used SR to set the
high-order register to zero). Second, because the sign of the remainder is always the same as
the sign of the original dividend, if c(NN) is negative the compare instruction will always
cause the following branch instruction to transfer control to NoRound, independent of the
magnitude of the remainder.
Heres an example of rounding the quotient of a signed dividend:
L
L
SRDA
BNM
LCR
Divide D
LPR
C
BL
AR
NoRound ST

1,=F 1
6,NN
6,32
Divide
1,1
6,=F 1 0
6,6
6,=F 5
NoRound
7,1
7,QQ

Set up rounding increment


c(GR6) = c(NN)
c(GR6,GR7) = 64-bit signed dividend
Jump if nonnegative dividend
Otherwise set roundoff to -1
Divide by 10
Take magnitude of remainder
Compare to 5
Branch if smaller than 5
Add correctly-signed roundoff
Store rounded quotient

Figure 131. Example of rounded integer division with signed dividend

See Exercise 18.6.13 for a more general technique for calculating a rounded quotient.
A simple check can be made to ensure that a fixed-point divide interruption does not occur: if the
inequality
|dividend| < |divisor| * 231
Figure 132. Ensuring a valid arithmetic division

is satisfied, then the quotient will be computed correctly. If an equality occurs in comparing these
two quantities, we must also check for the possibility that the quotient might be exactly equal to
231 .
To illustrate this relationship, suppose we want to divide the double-length dividend
X0000000100000000 = 232
by two. Comparing dividend and divisor, the dividend might appear to be small enough to
produce a valid quotient:
X0000000100000000 = 232 (dividend)
X00000002
= 2 (divisor; high-order part of dividend is smaller?)
The divisor 2 multiplied by 231 is actually equal to the dividend, so that the inequality in Figure
132 is not satisfied. Since both dividend and divisor are positive, the quotient must also be positive; but the quotient is actually X80000000, which is not representable as a positive number for
signed division.
Thus, a fixed-point divide interruption can be thought of as indicating a quotient overflow. To
show how this might occur in a program, consider the segment below.
L
MR
D

1,=A(X40000)
0,1
0,=F 1 0

c(GR1) = 2**18
Square it, to generate 2**36
Try to divide by 10

Figure 133. Causing a fixed-point divide interruption

Because 236 is not less than 10231, a fixed-point divide interruption will occur.

Chapter V: Basic Instructions

277

18.6.2. Single-Length Division


The arithmetic division instructions using a single-length dividend in a 64-bit register are DSG,
DSGR, DSGF, and DSGFR. Even though the dividend occupies a single 64-bit register (unlike
double-length dividends that require a register pair), a single-length dividend is always placed in
the odd-numbered register. (Its easiest to think of it as being extended internally to double length
before division begins.)
Even though the dividend is in the odd-numbered register, the instruction must specify the evennumbered register as the R1 operand. This is illustrated in Figure 134.
R1 (even)
R1+1 (odd)

////////////////////
Dividend

Divisor
R2 or D2(X2,B2)
(in register or memory)
Figure 134. Operands of single-length division before division

After division, the results appear as in Figure 135.


R1 (even)
R1+1 (odd)

Remainder

Quotient

Figure 135. Operands of single-length division after division

For example, suppose you want to divide 12345678901 by 777:


LG
5,=FD12345678901 c(GG1) = 12345678901
DSG 4,=FD777
Divide by 777 (64-bit divisor)
* c(GG4) = 493 (remainder), c(GG5) = 15888904 (quotient)
LG
5,=FD12345678901 c(GG1) = 12345678901
LG
9,=FD777
c(GG9) = 777 (64 bits)
DSGR 4,9
Divide by 777
The same divisions using DSGF and DSGFR with 32-bit divisors are very similar:
LG
5,=FD12345678901 c(GG1) = 12345678901
DSGF 4,=F777
Divide by 777 (32-bit divisor)
LG
5,=FD12345678901 c(GG1) = 12345678901
L
9,=F777
c(GR9) = 777 (32 bits)
DSGFR 4,9
Divide by 777
and the 32-bit second operands are internally sign-extended to 64 bits.

Exercises
18.6.1.(2) In the inequality in Figure 132 that assures that a division will be correct, explain the
factor of 231. Why isnt it a factor of 232?
18.6.2.(4) Suppose n is the number of some register. Under that circumstances will DR n,n not
cause a program interruption?
18.6.3.(2) + Write a sequence of instructions to simulate a Divide Halfword operation. That
is, given a word dividend at WDividen and a halfword divisor at HDivisor, store the halfword
quotient and remainder at HQuotent and HRemaind respectively.

278

Assembler Language Programming for IBM z System Servers

Version 1.00

18.6.4.(2) + Suppose the dividend in a signed fixed-point division can be correctly represented in
a word. Can division by a nonzero word divisor cause a fixed-point divide interruption?
18.6.5.(2) Under what circumstances can a fixed-point divide interruption occur in Figure 129?
18.6.6.(2) Rewrite the example in Figure 130 to round the result by adding 5 before dividing by
10. Determine carefully whether or not there might be a carry from the addition into the highorder register.
18.6.7.(2) Rewrite the example in Figure 131 to round the dividend before dividing by adding or
subtracting 5. Determine carefully how to handle a possible carry or borrow from the loworder to the high-order register.
18.6.8.(4) Consider the problem of simulating logical division by using arithmetic divide
instructions. Sketch a code sequence that will do this.
18.6.9.(2) Suppose the SRDA instruction is not available, and you want to divide the word
integer in GR1 by another in GR2. Show how you can set up the double-length dividend
without multiplying by 1.
18.6.10.(2) + Figure 131 illustrates a rounded division with positive divisor and signed dividend.
Show what changes are needed if the divisor can also be negative.
18.6.11.(3) + Figure 130 shows a way to compute a rounded quotient. The rounding factor 5 is
half the divisor, 10. Write a sequence of instructions to generalize this by computing
quotient = (dividend / divisor) + 1/2
18.6.12.(1) + A programmer wanted to divide the positive number in GR5 by 2, and wrote
SR
D

4,4
4,=F 2

Clear high-order word


Divide c(GR5) by 2

Find a simpler way to do this.


18.6.13.(3) + Write an instruction sequence showing how to calculate a rounded integer quotient
using 32-bit operands, without knowing the magnitude of the divisor.
18.6.14.(2) + A table of 15 reasonably small halfword grades is stored starting at Grades. Write
instructions to compute their average value and store it at AvgGrade.

18.7. Logical (Unsigned) Division Instructions


The logical division instructions are shown in Table 89:
Op
E397

Mnem
DL

E387

DLG

Type Instruction
RXY Divide Logical
(32,323 2 + 3 2 32)
RXY Divide Logical
(64,646 4 + 6 4 64)

Op
B997

Mnem
DLR

B987

DLGR

Type Instruction
R R E Divide Logical Register
(32,323 2 + 3 2 32)
R R E Divide Logical Register
(64,646 4 + 6 4 64)

Table 89. Binary divide instructions

These four instructions divide a double-length unsigned dividend by a single-length unsigned


divisor, giving a single-length unsigned quotient in the odd-numbered register and the unsigned
single-length remainder in the even-numbered register.
If both dividend and divisor are positive, logical and arithmetic division generate the same results.
For example, dividing X00000000 FFFFFFFF by 3 generates quotient X55555555 and remainder 0
for both types of division.

Chapter V: Basic Instructions

279

As you might expect, negative signed operands can produce very different results when used as
logical operands in unsigned division. For example, an arithmetic division of the maximum negative number (X80000000) by 1 (X FFFFFFFF ) is invalid; but a logical division using the same
operands gives quotient zero and remainder X80000000 (because 231 is smaller than 232 1).
Here is a case that succeeds for arithmetic division but fails for logical division:
L
0,=X80000001
SRDA 0,32
D
0,=F -1

Set GR1 to -2**31+1


Extend to 64 bits in (GR0,GR1)
Arithmetic division

The remainder is 0 and the quotient is + 231 1, as you would expect. For a logical division, the
dividend is (264 231 + 1) and the divisor is 232 1, which leads to a fixed-point divide interruption
because the quotient is greater than 232 1. As another example, consider
L
SR
DL

0,=F -2
1,1
0,=F -1

Set GR0 to X FFFFFFFE


Set GR1 to X00000000
Divide logically by X FFFFFFFF

Figure 136. Example of logical division

and both quotient and remainder are X FFFFFFFE !


As a final example:
L
LR
DL

0,=X FFFFFFF8
1,0
0,=X FFFFFFFF

Initialize GR0
And GR1, with the same bits
Divide by 2**32-1

The quotient is X FFFFFF9 and the remainder is X FFFFFFF1 .

Exercises
18.7.1.(4) Show how you can use logical division instructions to generate the results that would
be obtained by using arithmetic division instructions with the same operands.
18.7.2.(2) By evaluating the expression quotientdivisor + remainder=dividend, show that the
results of the division in Figure 136 are valid.

18.8. How Division Is Done (*)


Division works much like multiplication, only in reverse. Instead of adding onto the high-order
half of the accumulating product, we subtract; instead of counting down in the rightmost digit
position, we count up; instead of shifting right, we shift left. As before, an example using decimal
arithmetic illustrates the process.
Since we start with a dividend and divisor and wish to find a quotient and remainder that satisfy
the equation
dividend = quotient divisor + remainder
The dividend must be a double-length number.
Supposing again that our basic register length is three decimal digits, a requirement on the dividend is clear: because (a) the quotient, to fit in a register, can be at most three digits long (that is,
not exceeding 999) and (b) the remainder must be less than the divisor, we must not have a dividend larger than
999 divisor + (divisor-1) = 103 divisor - 1.
The factor of 10 3 is the base (10) raised to the power of the number of available digits (3). Since
multiplication by 10 3 in this example is equivalent to shifting left three places, the above relation
means that if the division is to produce a valid quotient, the high-order half of the dividend must
be less than the divisor. To illustrate: if the divisor is 456, then any dividend not smaller than
456000 = 10 3 456 would produce a 4-digit quotient; if the dividend is less than or equal to

280

Assembler Language Programming for IBM z System Servers

Version 1.00

455999 = 10 3 456 1, the quotient can be held in three digits. Note that the three highorder digits, 455, are now less than the divisor.
Suppose we want to divide 162843 by 762. In ordinary long division, at each step we determine
how many multiples of the divisor can be subtracted from the leftmost part of the dividend, and
enter that number as the quotient digit. When the subtraction process has been completed, the
remainder, from which no further subtractions can be made, is 537, and the quotient is 213.
+ 213
762)162843
1524
1044
762
2823
2286
537
Just as a check, we find that 762213+537=162843. Using decimal registers, the division works
like this:
162 843
762

High-order part of dividend less than divisor,


division may proceed.

1 628 430
- 762

Shift dividend left; save leftmost digit in an


overflow digit position.
Since dividend divisor,
Subtract, and count up at right end.
Dividend divisor; subtract again, count up
Dividend < divisor, no subtraction
Shift dividend left again
Dividend divisor; subtract and count up
Dividend < divisor; no subtraction
Shift left for the third and last time
Dividend divisor; subtract and count up
Subtract and count up by 1 at right end
Dividend divisor; subtract
and count up by 1
Dividend divisor; subtract and count up
Dividend now < divisor; stop.

0
0
1
0
2
2
1
-

866
762
104
044
762
282
823
762
061
762
299
762
537

431
432
320
321
210
211
212
213

As the successive digits of the quotient were developed, they appeared at the right end of the
double-length register, and were shifted left as the division progressed. Thus at the completion of
the division, the quotient is found in the right half of the register pair, and the remainder, from
which no further subtractions could be made, is in the left half.
As in multiplication, binary division is simplified by the fact that at most one subtraction need be
made for each quotient digit generated. To illustrate, consider an example using a five-bit divisor
and a ten-bit dividend. Let the dividend be B00001 11011 (=59), and let the divisor be B00110
( = 6 ) . (Remember, the two halves of the double-length dividend are not two signed five-bit
numbers joined end to end: the leftmost bit of the right half of the dividend is not a sign bit but
an ordinary arithmetic digit.) If we make allowance for the sign bits of the quotient and
remainder, we actually need an extra shift at the beginning, to align the dividend correctly. This
leads to the following division scheme.
1. Shift the dividend left once. If the high-order (left) part of the dividend is not smaller than the
divisor, an illegal division is being attempted.
2. Shift left one bit position. If the high-order part of the dividend is greater than or equal to the
divisor, subtract the divisor from the dividend, and insert a 1 bit in the rightmost digit position. Otherwise, do nothing.
3. Return to step 2 until a total of 5 shifts has been done, including the shift of step 1.

Chapter V: Basic Instructions

281

We now illustrate the binary division of 59 by 6 in Figure 137, with less detail than in the multiplication example.
00011 10110
(00110)

Shift left once and compare


Dividend < divisor, okay to continue

00111 01100
00001 01101
00010 11010

Shift left once (second shift)


Subtract divisor, insert 1
Shift left once (third shift)
Dividend < divisor; no subtraction
Shift left once (fourth shift)
Dividend < divisor; no subtraction
Shift left once (fifth and last shift)
Subtract divisor, insert 1.

00101 10100
01011 01000
00101 01001

Figure 137. Illustration of binary division

Thus the remainder B00101 (=5) is in the left half, and the quotient B01001 (=9) is in the
right half, as expected.
This example of binary division is meant to illustrate the general process. Many improvements
involving multiple dividend and divisor bits make division faster on modern processors than
testing single bits.
Division in z System involves a double-length register, either a pair of general registers or an
internal double-length register holding the extended single-length dividend. Since the high-order
register of the pair must be even-numbered, the quotient is found in the odd-numbered register,
and the remainder is found in the even-numbered register.

Exercises
18.8.1.(4) The results of a division operation must satisfy the relation
dividend = (quotient * divisor) + remainder.
However, this relation does not uniquely determine the quotient and remainder obtained from a
given divisor and dividend. Even requiring the magnitude of the remainder to be smaller than
the magnitude of the divisor,
|remainder| < |divisor|
does not lead to uniqueness! Consider the following choices:
1. sign(remainder) = sign(dividend)
2. remainder 0

(z System)

(modulo)

3. | divisor/2 | remainder < |divisor/2 |

(rounding)

For cases (2) and (3), show how the z System rules concerning signs and magnitudes would
have to be modified.
18.8.2.(4) + Suppose n is the number of a general register. For each of these instructions, answer
the questions (1) Under what circumstances will this instruction cause an interruption? and (2)
What kind or kinds of interruption?

282

1.

AR

n,n

2.

MR

n,n

3.

DR

n,n

Assembler Language Programming for IBM z System Servers

Version 1.00

18.9. Summary
Table 90 summarizes the multiply instructions weve discussed here.
Product length
(bits)
Operand 1 length
Operand 2 length

Function

16
MH

Arithmetic

32

32 + 32

64

64 + 64

32

32
32

64

64
64

32
MS
MSR

32
MSGF
MSGFR

M
MR

64
MSG
MSGR

ML
MLR

Logical

MLG
MLGR

Table 90. Summary of multiply instructions discussed in this section

The divide instructions discussed in this section are shown in Table 91.

Function

Dividend length (bits)


Divisor length

32 + 32

Quotient & remainder


length

32

Arithmetic

D
DR

Logical

DL
DLR

64

64 + 64
64

64

64

64
32
64

DSG
DSGR
DSGF
DSGFR

DLG
DLGR

Table 91. Summary of divide instructions discussed in this section

Instructions Discussed in this Section


The instruction mnemonics and opcodes are shown in the following table:
Mnemonic
D

Opcode
5D

Mnemonic
DSGFR

Opcode
B91D

Mnemonic
MR

Opcode
1C

DL
DLG

E397

DSGR

B90D

MS

71

E387

5C

MSG

E30C

DLGR

B987

MH

4C

MSGF

E31C

DLR

B997

ML

E396

MSGFR

B91C

DR

1D

MLG

E386

MSGR

B90C

DSG

E30D

MLGR

B986

MSR

B252

DSGF

E31D

MLR

B996

The instruction opcodes and mnemonics are shown in the following table:

Chapter V: Basic Instructions

283

Opcode
1C

Mnemonic
MR

Opcode
B90D

Mnemonic
DSGR

Opcode
E30D

Mnemonic
DSG

1D

DR

B91C

MSGFR

E31C

MSGF

4C

MH

B91D

DSGFR

E31D

DSGF

5C

B986

MLGR

E386

MLG

5D

B987

DLGR

E387

DLG

71

MS

B996

MLR

E396

ML

B252

MSR

B997

DLR

E397

DL

B90C

MSGR

E30C

MSG

Terms and Definitions


multiplicand
In a multiplication, the number that is to be multiplied (the first operand) by another, the
multiplier (the second operand)
multiplier
See multiplicand
arithmetic multiplication
Multiplication of two signed operands, generating a signed product.
logical multiplication
Multiplication of two unsigned operands, generating an unsigned product.
dividend
A number to be divided by a divisor; the first operand; the numerator.
divisor
A number to be divided into the dividend; the second operand; the denominator.
quotient
The primary result of a division operation.
remainder
The residual portion of a division left over when a dividend cannot be evenly divided by a
divisor. Smaller in magnitude than the divisor.
arithmetic division
Division of two signed operands, generating a signed quotient and signed remainder.
logical division
Division of two unsigned operands, generating an unsigned quotient and unsigned remainder.

Programming Problems
Problem 18.1.(2) Write an Assembler Language program that finds the largest integer divisor x
of the integer function
f(n) = n3 - 1,
for values of n running from 2 to 8 in steps of 1, and such that x is less than f(n). Your
program should search for the divisor, and not compute it from the known factors of f(n).
Problem 18.2.(3) Write an Assembler Language program to compute and print the values of Xn
and the quotient and remainder of the fraction
(Xn)**2 + 10727*Xn - 14
2*Xn - 5
where Xn is given by Xn = 2**(3*n), for n = 1, 2, ..., 10.

284

Assembler Language Programming for IBM z System Servers

Version 1.00

Problem 18.3.(4) In the early 17th century, Mersenne conjectured that the number
M(p) = (2**p) - 1
is prime for a particular sequence of prime values of p. Though the conjecture is now known to
be false, several efficient tests for the primality of M(p) have been devised; we will use one (due
to the French mathematician Lucas) for testing a set of such Mersenne Numbers, as follows:
1. Compute M(p), and set S(1) (the initial term of a series) to the value 4. (Note that M(p)
can be calculated very simply by shifting.)
2. Compute the next term S(n+1) of the series as the remainder of the division of
(S(n)*S(n) 2) by M(p).
3. Stop when S(p 1) has been calculated, and print the values of p, M(p), and S(p 1). If
S(p 1) is zero, M(p) is prime.
Write a program that tests M(p) for values of p = 3, 5, 7, 11, 13, 17, 19, 23, 29, and 31.
Problem 18.4.(3) For values of the integer variable X running from 0 to 12 in steps of 1,
compute and print the quotient and remainder of the quantity
(X4 + 7X2 - 11) / (X3 - 21X2 + 131X - 231)
If you find that the denominator is zero for any value of X, print the largest negative magnitude
for both quotient and remainder (that is, the word integer with hex representation X80000000).
Problem 18.5.(2) Write a program to compute a table of factorials. (Remember that we use the
notation N! for the factorial of N; define 0! = 1, and N! = N*(N 1)!.) Print the values of N
and N! until N! will not fit into a word; print a value of 1 for that factorial, and stop.
Problem 18.6.(4) Write a program to calculate the day and month of Easter for the year Y,
using these steps:116
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.

Divide Y by 19; keep remainder A


Divide Y by 100; keep quotient B and remainder C
Divide B by 4; keep quotient D and remainder E
Divide 8B+13 by 25; keep quotient G
Divide 19A+B-D-G+15 by 30; keep the remainder H
Divide A+11H by 319; keep quotient M
Divide C by 4; keep quotient J and remainder K
Divide 2E+2J-K-H+M+32 by 7; keep remainder L
Divide H-M+L+90 by 25; keep quotient N
Divide H-M+L+N+19 by 32; keep remainder P

Then, Easter Sunday is the P-th day of the N-th month of year Y. (Note that this applies to
the Gregorian calendar, for years after 1582.)
Problem 18.7.(2) Write a program to print a hexadecimal addition table, like the one you
created in your solution to Exercise 2.2.4.
Problem 18.8.(2) Write a program to print a hexadecimal multiplication table, like the one you
created in your solution to Exercise 2.2.4.
Problem 18.9.(4) The constant e (2.718...) is the base of natural logarithms. Its value is
defined by
e = Sum (k=0, ) (1/k!)
Evaluating e by calculating the terms of this sequence is very slow (and difficult to do with
fixed-point binary arithmetic, because the third and following terms are less than one). If you
rewrite the value as

116

From Scientific American, March 2001, page 82.


Chapter V: Basic Instructions

285

e-2 = (1/2)*(1+(1/3)*(1+(1/4)*(1+(1/5)*(1+(1/6)*(1+...(1/k))))...)))
theres an easy way to generate successive digits:
1. Multiply the rightmost (k-th) numerator term (initially 1) by 10 and divide by k.
2. Retain the remainder as the numerator for generating the next digit.
3. Multiply the next higher-order numerator by 10, add the quotient from the previous term,
and divide by (k-1).
4. Repeat until k=2. At this point, the final quotient is a digit of e.
5. Repeat from the first step to generate successive digits of e.
As a general rule, the number of digits to be generated is the same as the number of terms you
evaluate.
Write a program to generate the first 50 fraction digits of e, and print the value of the constant.
Problem 18.10.(2) + Write a program that searches for and prints the 25 prime numbers less
than 100.
Problem 18.11.(2) Write a program that creates a base-seven multiplication table like the one
you made for Exercise 2.4.6.

286

Assembler Language Programming for IBM z System Servers

Version 1.00

Chapter V: Basic Instructions

287

19. Logical Operations

11
111
1111
11
11
11
11
11
11
11
1111111111
1111111111

9999999999
999999999999
99
99
99
99
99
99
999999999999
999999999999
99
99
99
99
999999999999
9999999999

In this section well examine instructions that perform logical operations, and give examples of
their use. These operations are very different from logical (unsigned) arithmetic. Here, logical
is used in the sense of the symbolic logic of truth and falsehood; the operations are often called
Boolean operations. 117
The basic capabilities of a computer are derived from interconnections of basic circuits performing
logical functions. Some of the same logical functions are also performed by the CPU on operands in memory and in the general registers using logical instructions. The instructions in this
section are shown in Table 92.
Op
44
E380
46
E381
57
E382

Mnem
N
NG
O
OG
X
XG

Type
RX
RXY
RX
RXY
RX
RXY

Instruction
AND (32)
AND (64)
O R (32)
O R (64)
Exclusive OR (32)
Exclusive OR (64)

Op
14
B980
16
B981
17
B982

Mnem
NR
NGR
OR
OGR
XR
XGR

Type
RR
RRE
RR
RRE
RR
RRE

Instruction
AND Register (32)
AND Register (64)
OR Register (32)
OR Register (64)
Exclusive OR Register (32)
Exclusive OR Register (64)

Table 92. Logical operations involving general registers

There is no difference between operations involving 32- and 64-bit registers, so well describe only
the 32-bit forms. You can easily extend the 32-bit operations to their 64-bit equivalents.

117

288

George Boole (1815-1864) was a British mathematician and philosopher who wrote extensively on logic, especially in
his book An Investigation of the Laws of Thought (1854).
Assembler Language Programming for IBM z System Servers

Version 1.00

19.1. Logical Operations


Unlike logical arithmetic, in which carries and borrows may propagate from a bit position to one
or more of its higher-order neighbors, boolean logical operations always operate on pairs of bits,
with no interactions among neighboring bits.
The three logical operations provided by z System are AND, OR, and Exclusive OR, abbreviated
XOR. These operations between pairs of bits produce a result depending only on the values of
the two bits participating in the operation. The effect of the three operations is given in Figure
138. In each box, the two bits participating in the operation are given in the left column and the
top row; the result bit is at the intersection of the corresponding row and column.

AND 0 1

0 0 0

1 0 1

OR 0 1

0 0 1

1 1 1

XOR 0 1

0 0 1

1 1 0

Figure 138. Logical operations AND, OR, and XOR

In the first case, the result bit is 1 only if the first AND the second operand bits are 1.
In the second case, the result bit is 1 if either the first OR the second operand bit is 1.
In the last case, the result bit is 1 if either the first OR second operand bits is 1, Exclusive of
the case where both are 1 (that is, one but not both bits are 1). 118
The AND operation is often used to set bits to zero; OR is used to set them to one; and XOR is
used to change bits from zero to one and vice versa.
Sometimes the notation for logical operators is shorter, and text descriptions and formulas may
use other symbols: AND is represented by (or or .), OR is represented by (or
+ ), and XOR is represented by . In high-level languages, there are many different representations for each operation. We will use the more readable forms in Figure 138.

Exercises
19.1.1.(1) Taking 1 to represent true and 0 to represent false, rewrite the three diagrams in
Figure 138 as truth tables.

19.2. Register-Based Logical Instructions


In practice, the RR and RX forms of the logical operations are not used frequently. Logical operations are often used to examine and manipulate individual bits in memory, typically using the
SI-type instructions that well see in Section 24.
For the operations in Table 93, the CC is always set. We will discuss each operation in the next
three sections.

118

The distinction between OR and XOR often causes problems in English, where the word or is often interpreted one
way when the other was intended. Question: Are you tired or hungry? Answer: Yes, usually implying both.
Chapter V: Basic Instructions

289

Operation
AND
OR
XOR

CC setting
0:
1:

all result bits are zero


result bits are not all zero

Table 93. CC settings by logical instructions

Unlike logical arithmetic, the result of each of these logical operations is obtained by matching the
corresponding bits of each operand, without interactions between neighboring bits. For example,
suppose c(GR4) = X01234567, and c(GR9) = X EDA96521 . Then if each of the following
instructions is executed, the final contents of GR4 will be as shown.
Operation
Instruction
c(GR4)
c(GR9)
Result

AND
NR
4,9
X01234567
X EDA96521
X01214521

OR
OR

4,9

X01234567
X EDA96521
X EDAB6567

XOR
XR
4,9
X01234567
X EDA96521
X EC8A2046

To see in more detail how these results are obtained, examine the fourth hexadecimal digit (3 and
9) for each case:
AND
3 0011
9 1001
1 0001

OR
3 0011
9 1001
B 1011

XOR
3 0011
9 1001
A 1010

Figure 139. Examples of logical operations

Exercises
19.2.1.(1) The CC settings after the logical operations indicate whether or not the result is or is
not completely zero. Can you think of any reason why a CC setting to indicate a result of all
1-bits was not provided in the design of System/360?

19.3. Logical AND


The most important use of the N and NR instructions is for masking operations where we need
to isolate or extract portions of a word. For example, suppose we want only the third of the four
positive integers packed in the data word illustrated in Figure 115 on page 249. As we saw in
Section 17, we can extract it by shifting in an even-odd register pair:
L
SRL
SRDL
SRL
ST

0,DataWord
0,6
0,13
1,19
1,Third

Get data word with integers


Drop off fourth one
Move third one into GR1
Position for storing
Store

Or, we can use a only single register:


L
SLL
SRL
ST

0,DataWord
0,13
0,19
0,Third

Get data word


Drop off first and second
Drop off fourth, and reposition
Store

If the integers could have negative values, the SRL instructions would be replaced by SRA.
The following instruction sequences use Logical AND, and may be faster. (The bits of the four
integers are represented by a, b, c, and d, respectively.)

290

Assembler Language Programming for IBM z System Servers

Version 1.00

Mask1

L
1,DataWord
B aaaaaaaaabbbbcccccccccccccdddddd
N
1,Mask1
B0000000000000ccccccccccccc000000
SRL 1,6
B0000000000000000000ccccccccccccc
ST
1,Third
Store desired third integer
- - DC
0F,BL41111111111111000000 Mask: 13 1-bits, 6 0-bits

The 0F operand in the DC statement ensures that the bit pattern at Mask1 falls on a word
boundary; type B constants have no implied alignment, and are padded on the left with zero bits.
We can do the same extraction by shifting first and then ANDing:

Mask2

L
1,DataWord
SRL 1,6
N
1,MASK2
ST
1,Third
- - DC
A(X 1 FFF )

B aaaaaaaaabbbbcccccccccccccdddddd
B000000aaaaaaaaabbbbccccccccccccc
B0000000000000000000ccccccccccccc
Store Result
13 1-bits at right end of word

Both masks have 1-bits only in positions corresponding to the bits of the third integer of the data
word (named c). When the N instruction is executed, all of the bit positions where a mask bit
is zero are set to zero, since a 0-bit ANDed to any other bit gives a zero result. In all of the
masks 1-bit positions, the result is the same as the original bit from the data word, because a
1-bit ANDed to any other bit gives a result identical to the other bit, as we saw in Figure 138.

Exercises
19.3.1.(1) + In the second example in Section 15.2 on page 207, shifts were used to set the leftmost 7 bits of GR8 to zero. Show how to do this with a logical AND operation.

19.4. Logical OR
In Figure 115 on page 249, we wanted to insert a new value for the third integer into the proper
part of the data word. We could do this by shifting the various pieces into place:
L
SRDL
L
SRDL
L
SRL
SRDL
ST

0,DataWord
0,6
0,NewThird
0,13
0,DataWord
0,19
0,13
1,DataWord

Get 4 packed integers


Move fourth into GR1
Get new value of third integer
Move it in with fourth
Get integers again
Drop old third and fourth
Move full word into GR1
Store updated result

Using the AND and OR instructions, we can use logical operations:

MaskC

L
0,DataWord
N
0,MaskC
L
1,NewThird
SLL 1,6
OR
0,1
ST
0,DataWord
- - DS
0F
DC
X FFF8003F

Get 4 packed integers


Clear a space for third (C s)
Get new value of third integer
Shift into proper position
OR into place in GR0
Store new dataword
Align
13 0-bits in third-integer position

Figure 140. Inserting a new integer value using A N D and O R

The N instruction zeros all the bit positions into which the third integer will be placed. The OR
instruction then forms the logical OR of all the bits of GR0 and GR1. Since the only bits in
GR1 that might be ones are in the 13 positions corresponding to the space provided in the word
Chapter V: Basic Instructions

291

in GR0, and because the result of ORing a zero bit to any other bit is the value of the other bit,
the effect is to insert the new value of the third integer in its proper position in GR0. This of
course assumes that the contents of NewThird is a positive integer of at most 13 significant bits; if
not, an
N

1,Mask1

instruction should be inserted before the OR instruction to ensure that no extraneous bits are
ORed into GR0.

Exercises
19.4.1.(2) + The word at Data contains information to be shifted circularly: that is, bits shifted
off one end of the register should reappear at the other end. For example, a circular left shift of
the operand X12345678 by 12 bit positions would produce X45678123. Without using a
rotating shift, write a code sequence using logical operations to shift c(Data) circularly to the
left by N places, where N is a nonnegative word integer stored at NShifts. Compare your
solution to the solution you found for Exercise 17.3.17.
19.4.2.(2) + Modify the coding of exercise 19.4.1 so that if N is negative, the shift is a circular
right shift instead. Again, dont use a rotating shift. Compare your solution to the solution
you found for Exercise 17.3.18.
19.4.3.(2) + What will happen if the instructions OR 3,3 and NR 3,3 are executed? what is the
difference between these two and LTR 3,3 ?
19.4.4.(2) Write a code sequence using logical instructions to unpack each of the four integers
illustrated in Figure 115 on page 249.
19.4.5.(2) Now that you have completed Exercise 19.4.4, rewrite your solution to Exercise
17.3.10 to pack the four integers into the word illustrated in Figure 115 on page 249, but now
use logical instructions.

19.5. Logical Exclusive OR


The X and XR instructions are used to invert bits. We saw in Figure 138 on page 289 that the
effect of XORing a 0-bit to any other bit is to leave it undisturbed, and the effect of XORing a
1-bit is to invert it from 1 to 0 or from 0 to 1. Any bit XORed with itself gives a zero bit. This
gives a simple way to set a register to zero.119
XR

1,1

Set GR1 to zero

We can rewrite Figure 140 (in a somewhat roundabout way) to use an X instruction:

Mask3

L
0,DataWord
O
0,Mask3
X
0,Mask3
L
1,NewThird
SLL 1,6
N
1,Mask3
OR
0,1
ST
0,DataWord
- - DS
0F
DC
X0007FFC0

Get integers
Set third-integer space to all 1 s
Now set them to zeros
Etc., as before
Etc.
Make sure there are no extra bits
Etc.
Store updated result

Figure 141. Data masking using Exclusive O R

119

292

This is a very efficient way to zero a general register, because (unlike subtracting the registers contents from itself),
the CPU need not check for a possible overflow.
Assembler Language Programming for IBM z System Servers

Version 1.00

The O instruction first sets all bits in the third integers position to 1-bits, and the X instruction
then resets them all to zero. Well see another use of this technique in Figure 143.
As another example of the use of the Exclusive OR instruction, suppose we want to force the
integer in GR7 to be the next larger multiple of 8 if it is not already a multiple of 8. (We saw a
different way to do this in Figure 109 on page 246.) Consider the two following code segments.
A
N

7,=F 7
7,=F -8

Force carry if any 1s in low 3 bits


Now, set last 3 bits to zero

Figure 142. Rounding to the next multiple of 8

That is a faster method, but space is required for the two constants. We can also use the OR
then XOR technique:
LA
AR
OR
XR

0,7
7,0
7,0
7,0

c(GR0) = 7 = alignment mask


Force carry if any 1 s in low 3 bits
Now force those three bits to 1
And now set them to zero

Figure 143. Rounding to the next multiple of 8

This method is more economical of total instruction length than those illustrated previously.
As a more detailed example, suppose we need to shift the (nonzero) integer contents of GR6 to
the left so that the most significant bit is immediately to the right of the sign bit, and store the
number of positions shifted at Norm. The most significant bit is the leftmost bit that differs from
the sign bit.
Shift

Finish

Norm
Digit

XR
8,8
SLA 6,1
BO
Finish
AH
8,=H 1
B
Shift
SRA 6,1
X
6,Digit
ST
8,Norm
- - DS
F
DC
X40000000

Set shift count in GR8 to zero


Shift left one bit position
Branch if overflowed
Increment shift count
Try again
Reposition
Restore the lost bit
Store shift count
Storage space and alignment
Mask bit for lost bit

We shift left until the overflow condition indicates that a bit different from the sign bit has been
shifted out of bit position 1. The following right shift moves everything back in place, but instead
of restoring the lost bit, extends the sign bit into the second bit position of R6, from which the
most significant bit was just lost. Since the sign is known to be the opposite of the lost bit, the X
operation inverts the second bit to give the correct result.
We can form the ones complement of the number in GR7 by subtracting it from a word of all
1-bits, or by executing
X

7,=F -1

that does the same thing more simply. Thus, we can use the X instruction to form the twos
complement of a double-length integer, as in Figures 90 and 91 on page 227.

Chapter V: Basic Instructions

293

LM
8,9,Arg
X
8,=F -1
X
9,=F -1
AL
9,=F 1
BC
B1100,NoCarry
AL
8,=F 1
NoCarry STM 8,9,ARG
- - Arg
DS
2F

64-bit operand in (GR8,GR9)


Ones complement of high-order part
Ones complement of low-order part
Add low-order 1-bit
Branch if no carry out
Add carry into high-order part
Store complemented result
Double-length word integers

Figure 144. Complementing a double-length integer

This is definitely not the most efficient way to form a complement, but does show one use of
XOR.

Exercises
19.5.1.(2) + Show by examining the possible bit patterns that the sequence of instructions given
below exchanges the contents of GR1 and GR2 without using any other register.
XR
XR
XR

1,2
2,1
1,2

Can the same be done between a register and a word in memory, using three instructions?
19.5.2.(2) What is the result of replacing the XR instructions in Exercise 19.5.1 with SR
instructions?
19.5.3.(4) Suppose you are programming on a processor that has addition and subtraction operations, a logical AND operation, but no OR or Exclusive OR. 120 By examining various bit
combinations (particularly at the left end of a register), show that you can compute the missing
logical functions from
A OR B = (A + B) - (A AND B)
X XOR B = (A OR B) - (A AND B)
19.5.4.(2) + Consider these four logical expressions:
(1)
(2)
(3)
(4)

A
A
(A
(B

XOR
XOR
XOR
XOR

(A
(B
B)
A)

XOR
XOR
XOR
XOR

B)
A)
A
A

What is the result of each operation?


19.5.5.(2) + Figure 141 was rewritten by a student as follows:
L
L
SLL
XR
N
XR
ST

0,DataWord
1,NewThird
1,6
1,0
1,Mask3
0,1
0,DataWord

Get old packed integers in GR0


Get new third integer in GR1
Position new value correctly
XOR with old data in GR0
Mask all but 3rd integer s GR1 bits
XOR those bits back into GR0
Store updated packed result

where Mask3 defines the same bit pattern. By suitable examples, prove that this program
segment either does or does not work.

120

294

This was true of some very early Von Neumann or Institute-type processors like the ILLIAC 1.
Assembler Language Programming for IBM z System Servers

Version 1.00

19.5.6.(2) Rewrite Figure 142 to use a single literal. Are any new problems created in testing
the Condition Code?
19.5.7.(2) Write a DC statement with an A-type constant to specify the mask in Figure 141.
19.5.8.(2) Write code sequences using logical instructions to extract the first, second, and fourth
integers packed in a word at DataWord in the format illustrated in Figure 115 on page 249, and
store the resulting values in the words at First, Second, and Fourth.
19.5.9.(3) The word at Pack contains four positive integers in the format illustrated in
Figure 115 on page 249. Write a code sequence that will retrieve and store at DataItem the
first, second, third, or fourth of the packed binary integers, depending on the value of the
halfword binary integer stored at ItemNbr, which may have value 1, 2, 3, or 4. (It may help to
use tables of masks and shift counts.)

19.6. Interesting Uses of Logical Instructions (*)


The examples of logical instructions in the previous sections show normal uses. You can do
some other interesting things with them; we will illustrate a few.121
1.

Test a nonzero, nonnegative number to see if its a power of 2:


Y = ((2*X)-1) AND X) XOR X
If Y is zero, X is a power of 2. (Note that if X is zero or is the maximum negative number,
Y = 0 . ) To illustrate:
L
LR
SLL
S
NR
XR
JZ

0,=F 5
1,0
1,1
1,=F 1
1,0
1,0
PowerOf2

X in GR0
Copy X to GR1
2*X
(2*X-1)
(2*X-1) AND X
((2*X-1) AND X) XOR X
Branch if a power of 2

X00000005
X00000005
X0000000A
X00000009
X00000001
X00000004

so that 5 is not a power of 2.


2.

Isolate a numbers rightmost 1-bit. If X is a nonzero, nonnegative number:


Y = (((X-1) XOR X)+1)/2
then Y is the rightmost 1-bit of X. To illustrate:
L
LR
S
XR
A
SRL

0,=F 6
1,0
1,=F 1
1,0
1,=F 1
1,1

X in GR0
Copy X to GR1
(X-1)
(X-1) XOR X
((X-1) XOR X)+1
Y=(((X-1) XOR X)+1)/2

X00000006
X00000006
X00000005
X00000003
X00000004
X00000002

which is the rightmost bit of 6 = B00...0110 . If X is zero or the maximum negative


number, Y will be zero.
3.

Turn off the rightmost 1-bit of a positive binary number X:


Y = X AND (X-1)
To illustrate:

121

Some of these examples are based on IBM Thomas J. Watson Research Center Report RC 5809 Functions
Realizable with Word-Parallel Logical and 2s-Complement Addition Instructions by Henry S. Warren, Jr.
Chapter V: Basic Instructions

295

L
LR
S
NR

0,=F 6
1,0
1,=F 1
1,0

X in GR0
Copy X to GR1
(X-1)
(X-1) AND X

X00000006
X00000006
X00000005
X00000004

If this process is repeated, the number of iterations is determined by the power of two
represented by the leftmost 1-bit.
4.

Right-propagate the rightmost 1-bit of a nonzero word:


Y = X OR (X-1)
To illustrate:
L
LR
S
OR

5.

0,=F 1 2
1,0
1,=F 1
1,0

X in GR0
Copy X to GR1
(X-1)
(X-1) OR X

X0000000C
X0000000C
X0000000B
X0000000F

X in GR0
Copy -X to GR1
(X-1) OR X

X0000000C
X FFFFFFF4
X00000004

Isolate the rightmost 1-bit of a word:


Y = X AND (-X)
To illustrate:
L
LCR
NR

6.

0,=F 1 2
1,0
1,0

Turn off the rightmost contiguous string of 1-bits in a word:


Y = [(X OR (X-1)) + 1] AND X
To illustrate:
L
LR
S
OR
A
NR

0,=F 2 3
1,0
1,=F 1
1,0
1,=F 1
1,0

X in GR0
Copy X to GR1
(X-1)
(X-1) OR X
((X-1) OR X)+1
(((X-1) OR X)+1) AND X

X00000017
X00000017
X00000016
X00000017
X00000018
X00000010

and B00..010111 becomes B00..010000.


7.

Left-propagate the bit at position k in a word:


Y = [(X AND (2k+ 1 )) XOR 2k] 2k
A more natural way to program this might be to write:
L
0,X
SLL 0,K
SRA 0,K
but that wouldnt be as interesting.

8.

Test if a number is a power of 2, minus 1:


Y = [(X OR (X+1))]
if Y is zero, X is of the form 2 N 1.
To illustrate:
L
LR
A
XR

0,=F 3 1
1,0
1,=F 1
1,0

X in GR0
Copy X to GR1
(X+1)
(X+1) OR X

so 31 is a power of 2 minus 1.

296

Assembler Language Programming for IBM z System Servers

Version 1.00

X0000001F
X0000001F
X00000020
X00000000

Exercises
19.6.1.(2) + In example 1 of this section, it is stated that if X is 0 or the maximum negative
number, Y=0. Verify this statement.
19.6.2.(3) In example 1 of this section, what result Y is obtained if X is a negative number and
a power of 2?
19.6.3.(3) In example 2 of this section, what result Y is obtained if X is zero? What result is
obtained if X is a negative number?
19.6.4.(2) + In example 3 of this section, what will happen if X is a negative number?
19.6.5.(2) + In example 3 of this section, what will happen if X is zero?
19.6.6.(2) + In example 4 of this section, what will happen if X is zero? If X is negative?
19.6.7.(2) In example 5 of this section, what will happen if X is zero? If X is negative?
19.6.8.(2) + In example 6 of this section, what will happen if X is zero? If X is negative?
19.6.9.(2) Example 7 above shows how to left-propagate a bit in a general register. Suppose
there is an integer K between 1 and 31 stored in the word at KWord. Write a code sequence that
will left-propagate the bit in position K of the word in GR5, using the detailed formula (not the
natural solution).
19.6.10.(2) + Use the techique of example 3 of this section to count the number of 1-bits in the
word in GR0, and leave the result in GR2.
19.6.11.(2) In example 8 of this section, will the technique work if the value of X is unsigned?
19.6.12.(3) + It is claimed that this formula:
(NOT X) AND (X+1)
will create a mask that isolates the rightmost zero bit of X. That is, if X=7, the resulting mask
is X00000008. Write instructions testing a range of negative and positive values of X to validate or invalidate this claim. What will be the result if X=0?
19.6.13.(3) + It is claimed that all three of these formulas:
(NOT X) AND (X-1), NOT(X OR -X), and (X AND -X)-1
will form a mask matching all trailing zero bits. That is, if X=12, the resulting mask is
X00000003. Write instructions testing a range of negative and positive values of X to validate
or invalidate this claim for all three formulas. What will be the result if X=0?
19.6.14.(3) + It is claimed that this formula:
X XOR (X-1)
will form a mask matching the rightmost one bit of X, and all trailing zero bits. That is, if
X=8, the resulting mask is X0000000F . Write instructions testing a range of negative and positive values of X to validate or invalidate this claim. What will be the result if X=0?

Chapter V: Basic Instructions

297

19.7. Summary
Table 94 gives a compact summary122 of the three logical operations:
Operation

One
It remains
unchanged

AND
OR

It is changed to
one

XOR

It is inverted

Anything with
Zero
It is changed to
zero

Itself
It remains
unchanged

It remains
unchanged
It remains
unchanged

It remains
unchanged
It is changed to
zero

Table 94. Summary of the logical operations AND, OR, XOR

The instructions discussed in this section are summarized in Table 95.


Function

Operand length (bits)


A N D (memory)

32

64

NG

A N D (register)

NR

NGR

O R (memory)

OG

O R (register)

OR

OGR

XOR (memory)

XG

O R (register)

XR

XGR

Table 95. Logical-operation instructions discussed in this


section

Instructions Discussed in this Section


The instruction mnemonics and opcodes are shown in the following table:
Mnemonic
N

Opcode
54

Mnemonic
O

Opcode
56

Mnemonic
X

Opcode
57

NG

E380

OG

E381

XG

E382

NGR

B980

OGR

B981

XGR

B982

NR

14

OR

16

XR

17

The instruction opcodes and mnemonics are shown in the following table:

122

298

Opcode
14

Mnemonic
NR

Opcode
56

Mnemonic
O

Opcode
B982

Mnemonic
XGR

16

OR

57

E380

NG

17

XR

B980

NGR

E381

OG

54

B981

OGR

E382

XG

Courtesy of Michael Stack.


Assembler Language Programming for IBM z System Servers

Version 1.00

Exercises
19.7.1.(5) Given the four logical operations AND, OR, XOR, and NOT, where (NOT A) is
equivalent to (1 X O R A): which of each can be expressed in terms of two of the other three?

Terms and Definitions


AND operation
A logical (boolean) operation between two bits, whose result is 1 only if both operand bits
are 1.
OR operation
A logical (boolean) operation between two bits, whose result is 1 if either operand bit is 1.
XOR operation
A logical (boolean) operation between two bits, whose result is 1 if either operand bit is 1
while the other is zero. If the operand bits are identical, the result is zero.

Programming Problems
Problem 19.1.(4) In binary addition, the sum S of two binary digits A and B is
S = A XOR B,
and the carry bit is
c = A AND B.
Thus, to add two numbers composed of a string of binary digits, we must form the sum bit S(i)
of the appropriate digits A(i) and B(i), as well as the carry bit from the next lower-order digit
position, c(i 1). The logical formulas for the sum and carry digits then become
S(i) = A(i) XOR B(i) XOR c(i-1)
and the new carry bit is
c(i) = (A(i) AND B(i)) OR (B(i) AND c(i-1)) OR (A(i) AND c(i-1))
That is, c(i) is 1 if two or more of A(i), B(i), and c(i 1) are 1.
Write a program that computes the logical sum of several pairs of words A and B by performing the above operations 32 times, once on each bit position in the word in succession.
Save or calculate enough information during this process so that when the operation is complete, store a byte at CCL whose value is the same as the CC setting that would result if the AL
or ALR instructions had been used to add the same operands. Your sample values should generate all four possible CC values.
If you can, store at CCA a byte whose value is the same as the CC setting that would result if
the A or AR instructions had been used to add the same operands.
Thus, you should detect the presence or absence of a final carry, and whether the result is zero
or nonzero and positive or negative, by examining the bits as the operation progresses.
Problem 19.2.(3) Write a code sequence that forms the logical sum of two word operands A
and B, using the same logical formulas as in Problem 19.1. In this case, however, the operations should be performed on all 32 bits at once. (Show that there is no interference between
neighboring bit positions.) One method is to generate a word containing
S(1) = A XOR B
and a word
c(1) = A AND B.
The word S(1) contains the sum digits for the first addition, and the word c(1) contains the
carries generated in the first addition step. Shift c(1) left one bit position, and repeat the cycle

Chapter V: Basic Instructions

299

by ANDing and XORing S to c, generating a new sum S(2) and a new set of carries c(2).
Repeat the process until either c(n) is zero for some n, or 32 steps have been done. That is,
S(n+1) = S(n) XOR (2*c(n))
c(n+1) = S(n) AND (2*c(n))
Store the final sum at Sum, and set the word at CCodeL to contain the value of the Condition
Code setting as it would have been produced by the AL or ALR instructions.
Problem 19.3.(2) Modify the logical operation sequences in Problem 19.2 (or in Problem 19.1)
to perform additions or subtractions, as indicated by whether the word at SubFlag is or is not
zero. Test your program on a representative set of values for A and B.
Problem 19.4.(3) There are two parts to this problem. First, a small table of prime numbers is
computed using a method called the Sieve of Eratosthenes, and then the table is condensed
for printing.
To construct the table of primes, lay out in memory a table area of 400 units of any convenient
size; the choice of size is up to you. Consider them to be numbered from 1 to 400. Then,
beginning with table entry number 2, mark in some way each multiple of 2 (other than 2 itself),
up to 400. Then find the next unmarked quantity in the table (which will be 3), and mark each
multiple of that number. Then search for the next unmarked number (which will be 5), and
continue in this fashion.
Only prime numbers will remain unmarked. You need not make passes over the table marking
multiples of any number greater than 19, since the first unmarked number to be marked in this
sieving process will be the square of the number whose multiples are being marked.
From this table, produce a condensed version in a string of 400 bits (80 bytes) such that 1-bits
indicate that the corresponding number is unmarked (and therefore prime). Define the string in
a statement such as
PrimeBts DC

XL50 0 0

Space for 400 bits

so that an appropriate single statement will print the entire string of 100 hexadecimal digits, that
should start with X EA28... , representing 1, 2, 3, 5, 7, 11, 13, ....
If you wish, you may compute the final bit string directly, without having to go through the
intermediate steps of forming a byte table.
Problem 19.5.(3) In Problem 19.4, you produced a string of bits indicating whether the number
that gave its position in the string was a prime number. Half the bits in the table are wasted,
since all even numbers except 2 cannot be prime.
Write a program that will produce a string of 200 bits (25 bytes) indicating which of the odd
numbers less than 400 are prime. That is, if the k-th bit of the string is a 1-bit, the number
2k-1 is prime. Your string of 200 bits should start with X F6D32D... , representing 1, 3, 5, 7, 11,
13, ....
If you had a string of 230 bytes (1GB) available for storing the bits, what is the largest prime
whose primality you could indicate in that bit string?
Problem 19.6.(2) Choose an example from Section 19.6 on page 295 and write a program to
test the given formula for a range of values.

300

Assembler Language Programming for IBM z System Servers

Version 1.00

Chapter VI: Addressing, Immediate Operands, and Loops

VV
VV
VV
VV
VV
VV
VV
VV
VV
VV
VV
VV
VV
VV
VV
VV
VV
VV
VV VV
VVVV
VV

IIIIIIIIII
IIIIIIIIII
II
II
II
II
II
II
II
II
IIIIIIIIII
IIIIIIIIII

The previous chapters have described many different types of instructions. Recent additions to the
original System/360 architecture include extensions to those basic types that can make your programs more efficient, and often much easier to write.
Section 20 describes different types of address generation and the important concept of
addressing modes and the very useful Load Address instruction.
Section 21 introduces instructions with immediate operands that operate on data in the general
registers.
Section 22 examines old and new forms of branch instructions, some of which have immediate
operands. These instructions help manage loops efficiently for iterative processing.

Chapter VI: Addressing, Immediate Operands, and Loops

301

20. Address Generation and Addressing Modes

2222222222
222222222222
22
22
22
22
22
22
22
22
22
222222222222
222222222222

00000000
0000000000
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
0000000000
00000000

20.1. Address Generation


z System provides three forms of Effective Address generation:
1. base-displacement with unsigned 12-bit displacements;
2. base-displacement with signed 20-bit displacements; and
3. relative-immediate.
The next three subsections will describe them.

20.1.1. Address Generation With 12-Bit Displacements


We saw in Sections 5.1 and 5.3 on pages 64 and 65 how Effective Addresses are generated from
instructions using base-displacement addressing: the CPU adds the displacement to the contents
of the base register (and the index register, if any is specified). Figures 19 and 21 illustrate the
process.
In this form, 12-bit displacements are limited to the range
0 displacement + 212 1, or 0 displacement + 4095.

20.1.2. Address Generation With 20-Bit Displacements


In Section 14.7 we saw examples of RXY-type instructions (like LG and STG) that use a 20-bit
signed displacement. Table 96 illustrates the RXY- and RSY-type instruction formats:
opcode

R1

X2

B2

DL 2

DH2

opcode

Table 96. Format of RXY- and RSY-type instructions

For RSY-type instructions the X 2 field is replaced by an R3 field, but that doesnt affect address
generation other than not supporting indexing.

302

Assembler Language Programming for IBM z System Servers

Version 1.00

An Effective Address is generated for these long-displacement instructions in much the same
way it is generated for RX and similar types with an unsigned 12-bit displacement. In this case
the displacement is a signed 20-bit number; the displacement fields are rearranged and combined
as shown in Figure 145.

x b
DL
s DH







 signextended s DH
DL
64bit signed displacement

 Add to

c(base register b)


Effective Address
Instruction

Figure 145. Effective Address generation for long-displacement instructions

In these instructions, the traditional 12-bit unsigned displacement field (named D) is now
named DL, and the high-order 8-bit signed displacement extension is named DH. A 20-bit
signed displacement is formed from DH and DL: DH is concatenated at the left end of DL, and
then sign-extended to 64 bits. This gives a displacement value in the range
219 displacement + 219 1, or 524288 displacement + 524287.
rather than the limited 12-bit displacement range (0,4095). If the DH field is zero, the result is
generated from the familiar 12-bit unsigned displacement.
If the instruction is RXY-type, the address calculation adds both the base and index register contents, if applicable.
The Assembler uses the same resolution rules described in Sections 10.9 (on page 129) and 10.13
(on page 134) with one added step:
5. If no nonnegative displacement can be assigned, choose the register giving a negative displacement with the smallest magnitude.
To illustrate, suppose X has value X2468A0 . With traditional 16-bit addressing halfwords, these
statements would fail:
Using X,3
L
9,X-4

Addressability error

The operand X-4 is not addressable, because the RX-type instruction L provides only an unsigned
12-bit displacement. The LY instruction has an extended 3-byte base-displacement, so that
Using X,3
LY
9,X-4
will resolve the implied address with an extended 3-byte base-displacement X 3 FFC FF , where
the true displacement from the base location in GR3 to the operand location is X FFFFC . That
is, B2 = 3 , D L 2 = X FFC , and D H 2 = X FF .
The instructions
Using X,3
LY
9,X+4
will resolve the implied address with an extended 3-byte base-displacement X300400, where the
traditional 16-bit addressing halfword X3004 is in the first two bytes and DH2 = X 0 0 .

Chapter VI: Addressing, Immediate Operands, and Loops

303

Long displacements provide far greater addressability than the traditional 12-bit displacements,
which are limited to 4KB:
0  Base Register
4KB
Figure 146. Addressability range with 12-bit displacements

You can address very large data areas with a single base register, by setting the base address at (or
near) the middle of the area:


1MB

512K

:
:
:
:
 Base Register

:
:
:
:

+512K1
256 4KB

Figure 147. Addressability range with 20-bit displacements

With 12-bit unsigned displacements, addressing 1MB could require 256 base registers.
Many RX-type and SI-type instructions have equivalent forms with long displacements. They are
shown in the Summary in Section 20.5.

20.1.3. Address Generation With Relative-Immediate Operands


The formats of the two relative-immediate instruction types are shown in Tables 97 and 98:
Opcode

R1

Op

RI 2

Table 97. Format of R-I instructions with 16-bit immediate operands

Opcode

R1

Op

RI 2

Table 98. Format of R-I instructions with 32-bit immediate operands

Unlike the arithmetic and logical immediate operands well see in Sections 21.1 through 21.3,
these RI 2 relative-immediate operands do not involve data in memory or in a general register.
Instead, they are used to form the Effective Address:
1. Sign-extend the immediate operand to 64 bits, and shift it left once, giving 2RI 2.
2. Add the address of the current relative-immediate instruction (not the address in the IA of the
PSW); the result is the Effective Address. Thus, the Effective Address is relative to the
address of the current instruction.
This process is illustrated in Figure 148:

304

Assembler Language Programming for IBM z System Servers

Version 1.00

RI2

Opcode, regs sbbbbbbbbbbbbb

 signextended sbbbbbbbbbbbbb0

 Add to

address of the instruction itself


Effective Address

RItype instruction
Shift left 1 bit

64bit signed offset

(Not the PSW s IA!)

Figure 148. Effective Address formation for relative-immediate instructions

In effect, you have added or subtracted the number of halfwords specified by the RI2 operand to
the address of the instruction.123 The signed RI2 value means that the Effective Address can either
precede or follow the address of the instruction. For 16-bit RI2 fields,
Instructions address 65536 Effective Address Instructions address + 65534,
and for 32-bit RI2 fields,
Instructions address 4294967296 Effective Address Instructions address + 4294967294.
Both these offsets from the instructions address are adequate for most programs.
To resolve the implied addresses of instructions with relative addressing, the Assembler calculates
the difference between the locations of the operand and the instruction and divides the result by 2.
The target operand must
be aligned on a halfword boundary, and
have the same relocation attribute as the instruction. (This rule can be relaxed if the target
operand is an external symbol, as well see in Section 38.)
For example, a Branch Relative on Condition instruction (well discuss it in Section 22.1)
might look like this:

Target

BRC 8,Target
- - L
0,NewValue

Branch if Condition Code 0

and the Assembler will calculate the correct RI2 offset from the BRC instruction to the Target
instruction.

Exercises
20.1.1.(1) The RI-type instruction at address X174629C generates an Effective Address. For
each of the four following RI2 operands, show the generated Effective Address. Assume the
generated address is 32 bits long.
1. 1
2. 6845
3. 65536

123

The RI 2 operand is doubled because the Effective Address usually forms a branch address, which must always refer
to a halfword boundary. For some other processor architectures, the Instruction Address is called the Program
Counter, and Effective Addresses calculated relative to the address of the instruction are then called PC-relative.
Chapter VI: Addressing, Immediate Operands, and Loops

305

4. 2
20.1.2.(1) The RIL-type instruction at address X 7 B1EF0 generates an Effective Address. For
each of the following RI2 operands, show the generated Effective Address. Assume the generated address is 32 bits long.
1.
2.
3.
4.

1
384593
512044
3

20.1.3.(2) Suppose c(GR4)=X FFFFFF7C and c(GR7)=X9610B6C0 . Show the Effective


Address generated by each of these instructions. Assume the generated address is 32 bits long.
1.
2.
3.
4.

L
L
LG
LG

0,0(4,7)
0,3624(4,7)
0,4(4,7)
0,-8194(4,7)

20.1.4.(1) In Figure 148, there is a comment saying (Not the PSW s IA!). Why?
20.1.5.(1) Relative address offsets can be either 2 or 4 bytes long. What is the maximum
allowed distance to an operand from a referencing instruction with (a) a 2-byte offset, (b) a
4-byte offset?
20.1.6.(1) Suppose a relative-immediate instruction is at address X27B9AE . For each of the following four 2-byte immediate operands, what is the Effective Address of the instruction?
(a) X0003
(b) X FFE4
(c) X700F
(d) X8000
20.1.7.(2) How can you generate an odd Effective Address using relative-immediate operands?
20.1.8.(1) Some coders refer to operands like A+8 and *+6 as relative addressing. How
would you describe such operands?

20.2. Addressing Modes


Weve seen how an Effective Address is generated; what happens when we use it? The answer
depends on the CPUs current addressing mode, often abbreviated AMode. All the instructions
weve discussed have ignored AMode considerations; we now consider some basic aspects of this
important topic.
z System supports three addressing modes: 24-bit, 31-bit, and 64-bit. 24-bit addressing was used
in the original System/360, when memory was very expensive: a large processor may have had as
much as 256K bytes of storage, and many had far less.124 24-bit addresses could reference up to
224 (16 million) bytes, which seemed so large that 24-bit Effective Addresses were expected to be
enough for a very long time. Continued application growth was managed by adding virtual
addressing facilities in the early 1970s, but addresses were still limited to 24 bits.125

124

125

306

Some of the most popular System/360 models had only 32K bytes of storage, of which 14K was needed for the
operating system, leaving 18K bytes for applications. Programs were written very carefully, and often in Assembler
Language!
Another memory-saving technique was overlay, which well describe briefly in Section 38.9.
Assembler Language Programming for IBM z System Servers

Version 1.00

In the late 1970s and early 1980s, rapid application growth required more addressability; 31-bit
addressing was introduced, which provided addressability up to 2G bytes. Because existing applications usually needed to continue executing using 24-bit addressing, great care was taken to
ensure that addressing extensions were compatible with older applications.
The growth demands on applications and operating systems continued. Techniques like partitioning 126 allowed some relief, but it was soon clear that more than 31-bit addressing was needed,
at least to manage physical memories much larger than 2G. Thus, in the early 2000s, 64-bit
addressing and 64-bit general registers were introduced with z/Architecture.
When 31-bit addressing was introduced, it was necessary to distinguish areas of memory addressable with 24-bit Effective Addresses that is, addresses between 0 and 224 1 from addresses
requiring 31-bit Effective Addresses. The separation between these areas was called the line, so
that the first 224 bytes were below the line and the rest were above the line. Similarly, when
64-bit Effective Addresses were provided with z System, the separation of areas having addresses
less than 231 and those having larger addresses was called the bar, so that bytes having addresses
between 0 and 231 1 were below the bar and those with greater addresses were above the
bar.
Each of the three addressing modes affects the generation of z/Architecture Effective Addresss:
in 24-bit mode, the leftmost 40 bits of the Effective Address (0-39) are set to zero, leaving the
rightmost 24 bits intact.
0
39 40
63

 00000
....
00000

 ignored  24bit address


in 31-bit mode, the leftmost 33 bits of the Effective Address (0-32) are set to zero, leaving the
rightmost 31 bits intact.
0
33
63

 00000
.....
00000

 ignored  31bit address


in 64-bit mode, all 64 bits form the Effective Address.
0
63

64bit address
Remember:
An Effective Address is not the same as the contents of a register, even
though it may be derived from the contents of one or more registers.
The areas of addressability for the three addressing modes are sketched in Figure 149 on
page 308.

126

Partitioning uses address translation to allow more than one operating system to run in a single physical memory,
each behaving as if its set of real addresses starts at zero.
Chapter VI: Addressing, Immediate Operands, and Loops

307

2**64

:
:

:
:

2**31

:
:

2**24

:
:

Addressable
with AMODE 64

 the bar

Addressable
with AMODE 31

 the line

Addressable with AMODE 24

Figure 149. Areas of memory addressed by three AMODEs

Instructions that place or update addresses in the general registers are called modal instructions,
because the result depends on the addressing mode. Well see some examples in Section 20.3.
Effective Address addressing-mode considerations
In 24-bit or 31-bit addressing modes, 40 or 33 high-order bits of the
64-bit Effective Address (respectively) are set to zero.
If a value in a general register is used for addressing, its high-order bits
are not set to zero (as for generated addresses), but are ignored.
The CPUs current addressing mode is determined by two bits in the Program Status Word,
Basic addressing mode and Extended addressing mode, illustrated in Figure 150.
 128bit PSW

EB

Instruction Address (IA)

0
31 32
63 64
127
Figure 150. z System PSW showing addressing-mode bits

The meanings of the E and B bit settings are:


E
0
0
1
1

B
0
1
0
1

Addressing mode
24-bit mode
31-bit mode
Invalid combination
64-bit mode

Table 99. PSW addressing-mode bits

Almost all instructions that reference operands in memory depend in some way on the current
addressing mode; and instructions that update addresses in registers also depend on the addressing
mode. These are called modal instructions. Other instructions (like AR) are called non-modal
because their results are independent of addressing modes.
In Section 38 we will see instructions used to change addressing modes, and show why attention
to addressing modes can be very important and very useful..

308

Assembler Language Programming for IBM z System Servers

Version 1.00

Exercises
20.2.1.(1) + Suppose c(GG1)=X00000000 82006A04 and c(GG2)=X00000000 FFFF8200 . An
RXY-type instruction at address X629D58 looks like this:
opcode

X 0 4

X A06

opcode

What Effective Address does it generate in 24-bit addressing mode? In 31-bit addressing mode?
In 64-bit addressing mode?
20.2.2.(2) Repeat Exercise 20.1.3, showing how the generated Effective Addresses depend on the
addressing mode.

20.3. Load Address Instructions


The name Load Address is misleading: the instruction loads a register (but not from memory or
another register), and its operand may or may not be an address: the Effective Address of the
second operand is loaded into the R1 register. Thus, it might more properly be named Load
Effective Address.
Although we normally wouldnt consider it a logical instruction, Load Address is often classified
that way. The three instructions are listed in Table 100.
Op
41
C00

Mnem
LA
LARL

Type Instruction
R X Load Address
RIL Load Address Relative Long

Op
Mnem
E371 LAY

Type Instruction
RXY Load Address

Table 100. Load Address instructions

LA and LAY are RX- and RXY-type instructions, and LARL generates the Effective Address
from its address and the 32-bit RI2 operand, as described in Section 20.1.3 on page 304. In each
case, the Effective Address replaces the contents of GR R 1.
The affected parts of GR R 1 depend on the CPUs current addressing mode. As noted in Section
20.2, some of the high-order bits of the Effective Address may be set to zero.
Suppose a LA instruction is at address X543B6D0E , and addressability has been established. Then
if we execute
LAY

0,-1

Put -1 in register 0 (?)

the result depends on the addressing mode:


in 24-bit mode, the Effective Address is X00FFFFFF , and the high-order 32 bits of GG0 are
unchanged.
in 31-bit mode, the Effective Address is X 7 FFFFFFF , and the high-order 32 bits of GG0 are
unchanged.
in 64-bit mode, the Effective Address is X FFFFFFFFFFFFFFFF , and the high-order 32 bits of
GG0 are changed.
Modal Instructions
LA, LAY, and LARL are modal instructions: the resulting Effective
Address depends on the addressing mode.
In any addressing mode, a nonnegative integer n between 0 and 4095 can be placed in a register
by executing
Chapter VI: Addressing, Immediate Operands, and Loops

309

LA

r,n(0,0)

where the displacement contains the constant n. Instead of writing


2,=F 1

requiring 8 bytes (4 for the instruction and 4 for the constant generated by the literal), or
2,=H 1

LH

requiring 6 bytes, we can write either


LA

2,1

or

LA

2,1(0,0)

This requires only 4 bytes and less execution time, because no memory access is required.
Large signed integer values can be placed in a 64-bit register using LAY if the addressing mode is
64-bit:
LAY
LAY

0,500000
1,-500000

c(GR0) = +500000
c(GR1) = -500000 (64-bit mode only!)

Figure 151. Loading integer constants with the LAY instruction

You can also use values assigned to absolute symbols:


HalfMiln Equ
LAY
LAY

500000
2,HalfMiln
2,-HalfMiln

Value = +500000
c(GR2) = +500000
c(GR2) = -500000 (64-bit mode only!)

This can often eliminate the need for constants in memory and the storage references needed to
access them.
For signed arithmetic values, it can be safer to initialize a register with one of the arithmetic
immediate instructions described in Section 21.2 on page 322.
Be Very Careful!
The Effective Address will depend on the addressing mode! LAY 0,-1
generates X00FFFFFF in 24-bit addressing mode, and X 7 FFFFFFF in
31-bit mode.
For example, see Exercise 20.3.8.
Because LA and LAY do not affect the CC, we can clear a register without disturbing a CC
setting that may be required at a later point in the program. For example, suppose we wish to add
c(A) and c(B) and clear the result to zero if it overflows, without changing the CC set by the
addition. These two instruction sequences will work:

ST

L
A
BNO
LA
ST

0,A
0,B
ST
0,0
0,Answer

ST

L
A
BNO
L
ST

0,A
0,B
ST
0,=F 0
0,Answer

Because the LA instruction computes an Effective Address, it also provides a simple way to increment a number in a register (other than register 0) by a small positive amount. We put the increment into the displacement, and use the same register for the R1 and B2 digits. For example,
LA

4,17(0,4)

increases the contents of GR4 by 17, if the original value in GR4 is not corrupted. For example,
in 24-bit addressing mode, C(GR4) must lie between 17 and 224 18. Using LA to increment
register contents is usually limited to cases where the quantity being incremented is an address or
a reasonably small integer.

310

Assembler Language Programming for IBM z System Servers

Version 1.00

Be Careful!
Dont use a Load Address instruction to increment a negative number, or
a number large enough that the result might be affected by the current
addressing mode.
Suppose we want to perform the shifting operation described in Figures 113 and 114 on page 249,
where we wanted to shift the word at N to the right enough places so that its rightmost bit is a
1-bit. Now, however, we also require that the number of positions shifted be stored at the
halfword named Count.

Shift

L
LA
LCR
SRDL
LTR
LA
BNM
SLDL
STH

4,N
3,1
3,3
4,1
5,5
3,1(0,3)
Shift
4,1
3,Count

Get integer to shift


Set GR3 to 1
Initial shift count set to -1
Shift a bit into GR5
Test sign of GR5
Increment GR3 by 1
Branch if GR5 not negative
Move bit back into place
Store shift count

Figure 152. Counting number of shifts to make rightmost bit a 1-bit

By setting the shift count to 1 initially, we guarantee that the correct value will be in GR3 when
we exit from the loop. The first time the LA instruction is executed, the result in GR3 will be
zero. The placement of the LA instruction between the LTR and the ensuing BNM shows that
no change is made to the CC; normally, we would place the LTR just before the BNM because
the relation between the two is then clearer to the programs readers.
A third use of the LA instruction, and possibly the most important, is to generate addresses for
operands in memory. For example, we may require the address of some operand to be in a given
register while executing a segment of code. Suppose we want to add three integers, and branch
after all additions are completed to NoErr if no overflow occurs, and to Err1 if one or more overflows occur. Let the integers to be added be stored in successive words beginning at QQ.

OK1

LA
L
A
BNO
LA
A
BNOR
B

9,NoErr
2,QQ
2,QQ+4
OK1
9,Err1
2,QQ+8
9
Err1

Set branch address for no errors


Get first integer
Add second integer
Branch if no overflow
Set branch address for overflow
Add third integer
Branch if no or one overflow
Branch, some addition overflowed

Figure 153. Using LA to set a branch address

The last unconditional branch instruction could also be written


BO

Err1

without affecting the operation of the code, since that instruction is reached only if the branch
condition for the immediately preceding instruction is not met. By specifying an unconditional
branch it is clear that the branch must always be taken if it is reached.
There is an important assumption in Figure 153 regarding the two LA instructions: the locations
named NoErr and Err1 must be addressable, since the LA instruction simply performs the address
computation specified by the base and displacement assigned by the Assembler. Its sometimes
easy to forget that symbols used in LA instructions must be addressable, since no direct reference
is being made to a memory location: only an Effective Address is being generated, and no checks
are made for the validity of that address.
The addressability limitations of LA can often be overcome using LAY or LARL.

Chapter VI: Addressing, Immediate Operands, and Loops

311

Exercises
20.3.1.(1) The LARL instruction has a signed 32-bit RI2 immediate operand. Why can LARL
not be used to load the R 1 register with a large even integer value?
20.3.2.(1) If the CPU is executing in 24-bit addressing mode, show how the LA instruction can
be used as a masking instruction, producing the same result in a register as
N

reg,=A(X FFFFFF )

20.3.3.(1) + Can the first machine instruction in Figure 153 on page 311 be written
LA

9,A(NoErr) ?

20.3.4.(1) + Can the first machine instruction in Figure 153 on page 311 be written
LA

9,=A(NoErr) ?

20.3.5.(2) + The following two instructions usually have an equivalent effect:


LA
L

9,NoErr
9,=A(NoErr)

c(GR9) = A(NoErr)
c(GR9) = A(NoErr)

Under what circumstances would you use one in preference to the other? Under what circumstances would the two not be equivalent?
20.3.6.(2) + Suppose there is a number between 0 and 7 in GR5, and you want to place into
GR8 a single bit whose position within the low-order byte of that register is given by the
number in GR5. Thus, if GR5 contains X00000006, GR8 should contain X00000002. A
student claimed that the following code sequence does the job; prove or disprove that claim.
LA
SRL

8,X100(0,5)
8,1(8)

20.3.7.(2) Discuss the differences between


and

LA
AH

x,number(0,x)
x,=H number

as techniques for incrementing the contents of register GRx by a small positive integer
number. Under what circumstances would the result be different, and in what ways? Will it
work for all values of GRx? Which values will work, and which values wont? What differences may be required if number is defined by an EQU statement like this?
number

EQU

29

20.3.8.(3) In Figure 151, what will the assembled instructions look like? How will the results
depend on the current addressing mode?
20.3.9.(2) Suppose you execute these two instructions in 24-bit addressing mode:
L
LA

6,=A(X FFFFFF )
6,2(,6)

What value will be in GR6?


What value will be in GR6 if the first instruction had been written
L

6,=A(X FFFFFF00 )

20.3.10.(2) In Figure 152, we might want to initialize GR3 to 1 using


LAY

3,-1

What reasons might be given for not using LAY?


20.3.11.(2) + If x and y are numbers between 1 and 15, what are the differences between

312

Assembler Language Programming for IBM z System Servers

Version 1.00

these two instructions?


LR

x,y

and

LA

x,0(0,y)

20.3.12.(3) + Suppose GR15 contains one of the values 0, 4, 8, or 12. Depending on c(GR15),
you want to branch to A, B, C, or D respectively.127 For a program with a base
register providing addressability to the code, you might write
BList

B
B
B
B
B

BList(15)
A
B
C
D

Branch
Branch
Branch
Branch
Branch

into table
if c(GR15)
if c(GR15)
if c(GR15)
if c(GR15)

of branches
= 0
= 4
= 8
= 12

Suppose your program has no base register to provide addressability for the code.
How can you accomplish this task?
20.3.13.(1) Why cant use use LA or LAY to increment a small nonnegative number in GR0?
20.3.14.(2) + We are given these two definitions of the symbol Number:
1. Number DC

X1234

2. Number DC

X ABCD

Assuming 24-bit addressing mode: what hexadecimal value is left in GR10 by this instruction
sequence?
LH
SLL
LA
SRL

10,Number
10,8
10,0(10,0)
10,8

Now, in 31-bit addressing mode, what hexadecimal value is left in GR10 for each definition of
Number?
20.3.15.(2) + Suppose the contents of general registers 0, 1, and 2 are given by
c ( G R 0 ) = X2112E6D8 , c(GR1)=X 9 B017822 , and c(GR2)=X00FFFF00 . What Effective
Address is generated in 24-bit addressing mode for each of the following addressing halfwords?
1. X00FE
2. X 1 AF9
3. X2109
Now, find the Effective Addresses generated in 31-bit addressing mode.
20.3.16.(2) + Suppose this instruction is at address X543B6D0E :
LAY

0,*

What Effective Address will be generated in (a) 24-bit, (b) 31-bit, and (c) 64-bit addressing
mode?
20.3.17.(3) + A programmer claims that you can test whether adding a length in GR1 to an
existing address in GR2 will cross a known power-of-two boundary with these instructions:
write a test program with various input values to test his assertion.

127

This is a common convention for handling a return code from a called subroutine.
Chapter VI: Addressing, Immediate Operands, and Loops

313

Mask

LAY 1,-1(1,2)
XR
1,2
N
1,Mask
JNZ Crossed
- - DC
A(-8192)

Branch if adding crosses


Negative of power of 2 boundary

20.4. 64-Bit Virtual Addresses


We saw in Figure 22 on page 70 how 31-bit virtual addresses are divided into shorter components for mapping with translation tables into real addresses. The same technique is used for
64-bit virtual addresses, except that an additional 33 high-order bits must be mapped. This is illustrated in Figure 154:
33
11
8
12

region index

segment page
byte

index
index
index

Figure 154. 64bit Virtual Address

Because a 33-bit translation table would be extremely large, the region index is subdivided into
three portions, called region first, region second, and region third indexes, for which the
mapping tables are more manageable. This is sketched in Figure 155.
11
11
11
11
8
12

region 1st
region 2nd region 3rd

segment page
byte

index

index

index

index
index
index

Figure 155. 64-bit Virtual Address with Region Indexes

Fortunately, these details are handled by the operating system so we can focus on our applications.

20.5. Summary
In this section, we discussed addressing modes and the three instructions shown in Table 101.
Function

Instruction

Load
Address
(based)

LA
LAY

Load
Address
(relative)

LARL

AMode = 24
Effective Address in
bits 40-63;
zero in bits 32-39;
bits 0-31 unchanged.

Result in R1 general register


AMode = 31
Effective Address in
bits 33-63;
zero in bit 32;
bits 0-31 unchanged.

AMode = 64

Effective Address in
bits 0-63.

Table 101. Load Address instructions described in this section

Instructions Discussed in this Section


The instruction mnemonics and opcodes are shown in the following table:

314

Assembler Language Programming for IBM z System Servers

Version 1.00

Mnemonic
LA

Opcode
41

Mnemonic
LARL

Opcode
C00

Mnemonic
LAY

Opcode
E371

The instruction opcodes and mnemonics are shown in the following table:
Opcode
41

Mnemonic
LA

Opcode
C00

Mnemonic
LARL

Opcode
E371

Mnemonic
LAY

The long-displacement instructions that have equivalent forms using 16-bit long-displacement
addressing halfwords are summarized in the following table.
12-bit displacement

20-bit displacement

12-bit displacement

20-bit displacement

12-bit displacement

20-bit displacement

AY

LA

LAY

SH

SHY

AH

AHY

LH

LHY

SL

SLY

AL

ALY

LM

LMY

STCM

STCMY

CY

MY

STC

STCY

CH

CHY

MS

MSY

STH

STHY

CL

CLY

MVI

MVIY

STM

STMY

CLI

CLIY

NY

ST

STY

CLM

CLMY

NI

NIY

TM

TMY

IC

IC

OY

XY

ICM

ICMY

OI

OIY

XI

XIY

LY

SY

There are many other instructions with long displacements that are not direct extensions of other
RX-type and SI-type instructions.

Terms and Definitions


addressing mode
One of three modes supported by z System that determines the length of an Effective
Address.
AMode
An abbreviation for addressing mode.
DH
In an instruction supporting 20-bit displacements, the 5th byte of the instruction containing
the signed High-order 8 bits of the displacement.
DL
In an instruction supporting 20-bit displacements, the unsigned Low-order 12 bits of the displacement.
modal instruction
An instruction that places or updates addresses in the general registers, with results that
depend on the addressing mode.
relative address
An Effective Address determined by an offset relative to an instruction containing an RI 2
operand.
Chapter VI: Addressing, Immediate Operands, and Loops

315

316

Assembler Language Programming for IBM z System Servers

Version 1.00

21. Immediate Operands

2222222222
11
222222222222
111
22
22
1111
22
11
22
11
22
11
22
11
22
11
22
11
22
11
222222222222 1111111111
222222222222 1111111111

In Section 4.2 on page 53 we saw the five basic instruction classes introduced with System/360.
The only class with immediate data was the SI-type instructions, where a byte of data in the
instruction operated on, or was stored into, a byte in memory, as sketched in Figure 14 on
page 54. Well learn more about those in Section 23.
Many new instructions include immediate data that is part of the instruction, rather than being
in memory. Thus, it is immediately available. Most immediate operands work with data in the
general registers, rather than memory: Figure 156 shows how immediate operands in RI- and
RIL-type instructions interact with data in registers. 128 You may want to compare it to Figure 14
on page 54.

Registers




RI,
RR

RIL

RX,

Instruction

RS

SI
SS




Memory

Figure 156. Instruction classes, including RI, RIL

In early processors, the relative speeds of memory accesses and instruction execution using
memory operands were nearly the same. As processor speeds have increased, instructions can
often be completed in much less time than it takes to access memory operands. As this speed
difference has grown, the relative cost of memory accesses has also grown, despite many methods

128

Because z/Architecture continues to evolve, you should check the z/Architecture Principles of Operation regularly;
some newer instructions operate on immediate data in the instruction and data in memory.
Chapter VI: Addressing, Immediate Operands, and Loops

317

providing intermediate stages of buffering, using special internal cache memories. Caches can
help reduce, but not eliminate, the speed difference.
Because memory accesses in many applications refer to constant data, instructions containing
these constants provide immediate access to the data without additional memory references. The
resulting improvements in application performance have shown the value of these relativeimmediate instructions.
Two immediate-operand lengths are supported. In RI-type instructions, the I2 immediate
operand occupies a halfword, the last 16 bits of the 32-bit instruction.
opcode

R1

Op

I2

Table 102. RI-type instruction

In RIL-type instructions, the immediate operand I2 occupies a word, the last 32 bits of the 48-bit
instruction.
opcode

R1

Op

I2

Table 103. RIL-type instruction

Several of the instructions well examine use the last two letters of the instruction mnemonic to
indicate a specific portion of the R1 register, with combinations of H and L. The first letter
refers to the High half of a 64-bit register or the Low half of the register. Similarly, the second
letter refers to the High halfword or the Low halfword of the half of the register specified by the
first letter.129 This is illustrated in Figure 157.
 High Half  Low Half
High High
High Low
Low High
Low Low
64bit

HH

HL

LH

LL
operand
register
0
15 16
31 32
47 48
63
Figure 157. Four halfwords in a 64-bit general register

Another way of describing this:


HH
HL
LH
LL

High Halfs High Half (bits 0-15)


High Halfs Low Half (bits 16-31)
Low Halfs High Half (bits 32-47)
Low Halfs Low Half (bits 48-63)

Other instructions with 32-bit immediate operands end in the letters H or L meaning the H
or Low half of the register, followed by F to indicate that the immediate operand is a fullword.
Well now investigate these instructions in three groupings: insert and load, arithmetic, and
logical.

129

318

See the comments at the start of Section 14, on page 180.


Assembler Language Programming for IBM z System Servers

Version 1.00

21.1. Insert and Load Instructions with Immediate Operands


21.1.1. Logical-Immediate Insert Instructions
The insert group of logical-immediate instructions is summarized in Table 104.
Op
C08

Mnem
IIHF

Type Instruction
RIL Insert Logical Immediate
(high) (6432)

Op
C09

Mnem
IILF

Type Instruction
RIL Insert Logical Immediate
(low) (6432)

A50

IIHH

RI

Insert Logical Immediate


(high high) (6416)

A51

IIHL

RI

Insert Logical Immediate


(high low) (6416)

A52

IILH

RI

Insert Logical Immediate


(low high) (6416)

A53

IILL

RI

Insert Logical Immediate


(low low) (6416)

Table 104. Insert-Immediate instructions

The sketch in Figure 158 shows the operation of these six instructions. For example, IIHF inserts
its 32-bit (Fullword) immediate operand into the high half of GG R 1.
 High Half  Low Half
High High
High Low
Low High
Low Low

HH

HL

LH

LL

 


IIHH
IIHF IIHL
IILH
IILF
IILL

Instruction 16 or 32bit Immediate operand

Figure 158. Operation of six Insert Immediate instructions

The insert-immediate operations are similar to the capabilities of the ICM and ICMH instructions
that refer to storage operands. For example, these two instructions have the same result:
ICM 5,B1100,=C LH
IILH 5,C LH

Insert LH into bits 0-15 of GR5


The same with an immediate operand

except that IILH avoids a memory reference. Similarly, these two are equivalent:
ICMH 3,B1111,=F -3
IIHF 3,-3

Insert -3 into bits 0-31 of GG3


The same with an immediate operand

You can think of the IILF instruction as though its a Load Immediate instruction: 130

***

IILF 11,123456789
L
11,=F123456789
LI
11,123456789

has the same result as...


so you could even think of it as L
...but not as LI!

These instructions let you insert 16- or 32-bit operands into any halfword or word portion of a
general register without disturbing other parts of the register.

21.1.2. Arithmetic- and Logical-Immediate Load Instructions


These instructions are listed in Table 105.

130

But you could implement your own LI macro-instruction using the macro-instruction capabilities of the Assembler.
Chapter VI: Addressing, Immediate Operands, and Loops

319

Op
A78

Mnem
LHI

Type Instruction
RI
Load Halfword Immediate
(3216)

Op
A79

Mnem
LGHI

Type Instruction
RI
Load Halfword Immediate
(6416)

C01

LGFI

RIL

Load Immediate (6432)

C0E

LLIHF

RIL

Load Logical Immediate


(high) (6432)

C0F

LLILF

RIL

Load Logical Immediate


(low) (6432)

A5C

LLIHH

RI

Load Logical Immediate


(high high) (6416)
Load Logical Immediate
(low high) (6416)

A5D LLIHL

RI

A5F

RI

Load Logical Immediate


(high low) (6416)
Load Logical Immediate
(low low) (6416)

A5E

LLILH

RI

LLILL

Table 105. Load and insert instructions with immediate operands

The LHI, LGHI, and LGFI instructions are arithmetic load operations, where the I2 immediate
operand is sign-extended from 16 to 32 bits or from 32 to 64 bits, as required by the R1 register
length. They operate just like the corresponding LH, LGH, and LGF instructions, except that
the second operand is found in the I2 field of the instruction rather than in memory. For
example, compare the operation of the LHI instruction in Figure 159 with the operation of LH in
Figure 62 on page 185:

 signextended s
GR R1

0

31

LHI Instruction s
Halfword in LHI instruction

16
31
Figure 159. Operation of L H I instruction

A valuable application of instructions like LHI involves symbolically-defined constants. Suppose


you have a table of data items, and you define a symbol NItems whose value is the number of
items:
Table
Item1

DS
0F
Start of table
DS
CL(ItemLen)
Each item has length ItemLen
- - Space for more similar items
TableEnd DS
0X
End of the table
*
NItems Equ ((TableEnd-Table)/ItemLen) Number of items in table
Then, you can place the count of data items into GR8 using LHI:
LHI

8,NItems

Initialize item counter

Defining symbols like NItems symbolically means that if the table expands or contracts, you need
only to reassemble the program and the value of NItems will be recalculated automatically.
LGHI extends its 16-bit operand to 64 bits in GG R 1, as shown in Figure 160.

 signextended s
GG R1

0

63

LGHI Instruction s

16
31
Figure 160. Operation of L G H I instruction

320

Assembler Language Programming for IBM z System Servers

Version 1.00

Similarly, the LGFI instruction extends its 32-bit operand to 64 bits, as shown for LGF in
Figure 73 on page 197.
Suppose c(GG9)=X12345678 00000000 ; then
LHI

9,X CBA9

Load a halfword-immediate operand

will set the rightmost 32 bits of GR9 to X FFFFCBA9 , leaving the high-order 32 bits of GG9
unchanged. Now suppose c(GG9)=X12345678 9ABCDEF0 ; the other two load-immediate
instructions give the sign-extended results shown in Figure 161:
LGHI 9,X CBA9
LGFI 9,X789ABCDE

c(GG9)=X FFFFFFFF FFFFCBA9 extend 1-bit


c(GG9)=X00000000 789ABCDE extend 0-bit

Figure 161. Examples of load-immediate instructions

The other six logical instructions have an unusual property:


in the proper 16 or 32 bits of the 64-bit general register, and
instructions) the rest of the entire register is set to zero! The
cussed in Section 14.11 on page 197 did zero-extension only
bits to the right of the loaded operand.

the I 2 immediate operand is placed


(unlike the insert-immediate
Load Logical instructions we dison the left, rather than also zeroing

The following figure pictures the operation of these six logical load instructions.
 High Half  Low Half
High High
High Low
Low High
Low Low

HH

HL

LH

LL

 


LLIHH
LLIHF LLIHL
LLILH
LLILF LLILL

Instruction 16 or 32bit Immediate operand

Figure 162. Operation of six logical load instructions

In each case, after the I2 operand has been loaded into the specified part of GG R 1, the rest of
the register is set to zero. For example, if c(GG9)=X FEDCBA9876543210 , executing each of the
following instructions will change GG9 as indicated:
LLIHF
LLILF
LLIHH
LLIHL
LLILH
LLILL

9,X13579BDF
9,X FDB97531
9,X2468
9,X2468
9,X2468
9,X2468

c(GG9)=X13579BDF
c(GG9)=X00000000
c(GG9)=X24680000
c(GG9)=X00002468
c(GG9)=X00000000
c(GG9)=X00000000

00000000
FDB97531
00000000
00000000
24680000
00002468

The Load Logical Immediate instructions are useful whenever you need to place a value into part
of a general register and set the rest of the register to zero, and they help you avoid unnecessary
clearing of the target register. For example, if the LLIHF instruction was not available and you
wanted to load X13579BDF into the high-order 32 bits of GG9 (as in the first instruction above),
you would have to do something like
L
9,=F13579BDF
SLLG 9,9,32

c(GR9)=X13579BDF
c(GG9)=X13579BDF 00000000

requiring both a memory reference and an extra instruction. Similarly, to get the result of the
LLILH instruction above, you would have to do either
SGR 9,9
IILH 9,X2468

Set GG9 to zero


c(GG9)=X00000000 24680000

which uses one of the immediate-operand instructions. Another use could have been
Chapter VI: Addressing, Immediate Operands, and Loops

321

SGR
ICM

9,9
Set GG9 to zero
9,B1100,=X2468 c(GG9)=X00000000 24680000

again requiring an extra instruction and a memory access.

Exercises
21.1.1.(1) What will the Assembler do if you write LHI 0,76543 ? What will be placed in
GR0?
21.1.2.(1) What is the difference between an I2 operand and an RI 2 operand?

21.2. Arithmetic Instructions with Immediate Operands


The arithmetic instructions with immediate operands can be arranged in three groups:
add and subtract instructions
compare instructions
multiply instructions
These instructions can be arranged into very regular patterns, like the related RX-type instructions
we saw in Section 16.

21.2.1. Arithmetic-Immediate Add and Subtract Instructions


The four arithmetic and four logical instructions in this group are shown in Table 106.
Op
A7A

Mnem
AHI

Op
A7B

Mnem
AGHI

AFI

Type Instruction
RI
Add Halfword Immediate
(3216)
RIL Add Immediate (32)

C29

C28

AGFI

C2B

ALFI

RIL

Add Logical Immediate (32)

C2A ALGFI

RIL

C25

SLFI

RIL

Subtract Logical Immediate


(32)

C24

RIL

SLGFI

Type Instruction
RIL Add Halfword Immediate
(6416)
RIL Add Immediate (6432)
Add Logical Immediate
(6432)
Subtract Logical Immediate
(6432)

Table 106. Arithmetic-immediate add and subtract instructions

These instructions are very useful: they can replace most memory references to constants and
literals. Consider the example in Figure 88 on page 224 where we add the first N odd numbers,
but now we use immediate values instead of literals. Three storage references have been replaced
by immediate operands in the statements marked with * in the comment field.

Test

Store

LHI
LR
CH
BE
LR
AR
AHI
AR
AHI
B
ST

4,1
7,4
7,NN
Store
0,7
0,0
0,1
4,0
7,1
Test
4,SUM

* c(GR4) = accumulated sum


c(GR7) = count of additions
Compare count to c(NN)
Branch if equal, N terms added
Compute next odd integer
Counter + counter = 2N
* Add 1, giving next odd term
Add term to sum
* Increment count by 1
Branch back to see if finished
Store result

Almost every previous example using a halfword or word literal can be replaced by an immediate
operand. This saves both execution time and the bytes needed for the storage operand.

322

Assembler Language Programming for IBM z System Servers

Version 1.00

21.2.2. Arithmetic-Immediate Compare Instructions


The four arithmetic and two logical instructions in this group are shown in Table 107.
Op
A7E

Mnem
CHI

Type Instruction
RI
Compare Halfword Immediate (3216)

Op
A7F

Mnem
CGHI

Type Instruction
RI
Compare Halfword Immediate (6416)

C2D

CFI

RIL

Compare Immediate (32)

C2C

CGFI

RIL

Compare Immediate
(6432)

C2F

CLFI

RIL

Compare Logical Immediate


(32)

C2E

CLGFI

RIL

Compare Logical Immediate (6432)

Table 107. Arithmetic-immediate compare instructions

Suppose you must examine a character in storage to see if it is a special character, or a letter or
digit, and retain the character in GR0 for further processing. (Remember that letters and digits in
the EBCDIC representation have values greater than X 8 0 .) You could write the test like this:
LLC
CHI
BNH

0,Char
0,X 8 0
Special

Get character, clear rest of GR0


Test for special character
Special if representation <= X 8 0

The LLC instruction was illustrated in Figure 75 on page 199.


It helps to remember that these compare-immediate instructions always refer to operands in registers, never in memory:
*
NN

CH
2,NN
CHI 2,NN
- - DC
H 4 2

Compare to halfword in memory...


... but this would fail if assembled

21.2.3. Arithmetic-Immediate Multiply Instructions


Table 108 lists the two arithmetic multiply-immediate instructions:
Op
A7C

Mnem
MHI

Type Instruction
RI
Multiply Halfword Immediate (3216)

Op
Mnem
A7D M G H I

Type Instruction
RI
Multiply Halfword Immediate (6416)

Table 108. Arithmetic-immediate multiply instructions

There are no multiply-immediate instructions with 32-bit operands. 131 This is rarely a problem,
because you can use instructions like IILF or LGFI to put a 32-bit operand into a temporary
register. For example, if the product and operands are small enough you can use MHI:
L
1,Operand1
MHI 1,36

Get a number to be multiplied


Multiply by 36, product in GR1

and if the product and operands are larger, you can use IILF:
L
1,Operand2
IILF 15,629036721
MR 0,15

131

Get another number to be multiplied


Put multiplier temporarily in GR15
Form long product in (GR0,GR1)

At the time of this writing. But new instructions are added regularly to the z System architecture, so check the Principles of Operation.
Chapter VI: Addressing, Immediate Operands, and Loops

323

Exercises
21.2.1.(1) Why is there a SLFI instruction, but no SFI instruction?
21.2.2.(2) Do Exercise 18.2.7 on page 269, using immediate-operand instructions and no literals.

21.3. Logical Operations with Immediate Operands


As we have seen, the last two letters of these instruction mnemonics refers to a word or halfword
in part of a 64-bit general register. The three logical operations are AND, OR, and XOR.
The portions of the first operand in GG R 1 not involved in the operation of these instructions is
not affected, and remain unchanged. This was shown in Figure 158 on page 319, where the
Insert Immediate instructions involve either 16 or 32 bits of the register, and the remaining bits
are unchanged. (The Load Immediate instructions do clear the remaining fields of the register!)

21.3.1. Logical-Immediate AND Instructions


The AND group of logical-immediate instructions is summarized in Table 109.
Op
C0A

Mnem
NIHF

A54

NIHH

A56

NILH

Type Instruction
RIL AND Immediate (high)
(6432)
RI
AND Immediate (high high)
(6416)
RI
AND Immediate (low high)
(6416)

Op
C0B

Mnem
NILF

A55

NIHL

A57

NILL

Type Instruction
RIL AND Immediate (low)
(6432)
RI
AND Immediate (high low)
(6416)
RI
AND Immediate (low low)
(6416)

Table 109. AND-immediate instructions

The last example in Section 19.3 uses a bit mask in memory. We can improve it by using an
immediate operand in a NILL instruction:
L
SRL
NILL
ST

1,DataWord
1,6
1,X 1 FFF
1,Third

B aaaaaaaaabbbbcccccccccccccdddddd
B000000aaaaaaaaabbbbccccccccccccc
B0000000000000000000ccccccccccccc
Store Result

Figure 163. Extracting an unsigned integer value using A N D Immediate

The last example in Section 19.4 uses a bit mask in memory. We can also improve it using an
NILL immediate operand:
L
NILF
L
SLL
OR
ST

0,DataWord
0,X FFF8003F
1,NewThird
1,6
0,1
0,DataWord

Get 4 packed integers


Clear a space for third (c s)
Get new value of third integer
Shift into proper position
OR into place in GR0
Store new data word

Figure 164. Inserting a new integer value using A N D Immediate

21.3.2. Logical-Immediate OR Instructions


The OR group of logical-immediate instructions is summarized in Table 110.

324

Assembler Language Programming for IBM z System Servers

Version 1.00

Op
C0C

Mnem
OIHF

Type Instruction
RIL OR Immediate (high)
(6432)

Op
Mnem
C0D OILF

Type Instruction
RIL OR Immediate (low)
(6432)

A58

OIHH

RI

A59

OIHL

RI

A5A

OILH

RI

A5B

OILL

RI

OR Immediate (high high)


(6416)
OR Immediate (low high)
(6416)

OR Immediate (high low)


(6416)
OR Immediate (low low)
(6416)

Table 110. OR-immediate instructions

Suppose you want to set the sign bit of GG8 to a 1-bit. You can use either of these:
OIHH 8,X8000
OIHF 8,X80000000

Set sign bit to 1


Set sign bit to 1

but OIHF is 6 bytes long while OIHH is only 4 bytes long.

21.3.3. Logical-Immediate XOR Instructions


The XOR group of logical-immediate instructions is summarized in Table 111.
Op
C06

Mnem
XIHF

Type Instruction
RIL XOR Immediate (high)
(6432)

Op
C07

Mnem
XILF

Type Instruction
RIL XOR Immediate (low)
(6432)

Table 111. XOR-immediate instructions

You might wonder why there are no XIHH, XIHL, XILH, and XILL instructions, like those for
the 16-bit operands of the logical-immediate AND and OR instructions. (See Exercise 21.3.1.)
The example in Figure 141 on page 292 uses AND, OR, and XOR instructions referring to operands in memory. We can rewrite it to use immediate operands:
L
OILF
XILF
L
SLL
NILF
OR
ST

0,DataWord
0,X0007FFC0
0,X0007FFC0
1,NewThird
1,6
1,X0007FFC0
0,1
0,DataWord

Get integers
* Set third-integer space to all 1 s
* Now set them to zeros
Load new value for third integer
Move to correct position
* Make sure there are no extra bits
Insert the new third value
Store updated result

Figure 165. Data masking using immediate operands

We can improve this example to reduce the possibility of typographic errors, by defining the mask
symbolically:
Int3Mask Equ
L
OILF
XILF
L
SLL
NILF
OR
ST

X0007FFC0
0,DataWord
0,Int3Mask
0,Int3Mask
1,NewThird
1,6
1,Int3Mask
0,1
0,DataWord

Mask for isolating the 3rd integer


Get integers
Set third-integer space to all 1 s
Now set them to zeros
Load new value for third integer
Move to correct position
Make sure there are no extra bits
Insert the new third value
Store updated result

Figure 166. Data masking using a symbolically defined immediate operand

This technique is recommended whenever one value must be used in several instructions. If you
mistype the mask value, it needs correcting in only one place.

Chapter VI: Addressing, Immediate Operands, and Loops

325

Exercises
21.3.1.(2) + Explain why there is actually no need for the four XOR halfword-immediate
instructions XIHH, XIHL, XILH, and XILL.
21.3.2.(2) + Show why the Halfword forms of the AND-immediate logical NIxx instructions
(like NILH, etc.) are unnecessary.
21.3.3.(2) + Show why the Halfword forms of the OR-immediate logical OIxx instructions
(like OIHL, etc.) are unnecessary.
21.3.4.(1) Use instructions with immediate operands to set the high-order byte of GR1 to zero.
21.3.5.(1) Use instructions with immediate operands to invert the sign bit of GG7.
21.3.6.(1) Use instructions with immediate operands to round c(GR2) to the next higher multiple of 16, if it is not already a multiple of 16.
21.3.7.(2) A programmer wanted to test the value of some bits in GR3, and wrote these
instructions:
NILL
BZ
CH
BNL
- - -

3,X00F0
AllZeros
3,=X0070
BitWas1

Isolate the 4 interesting bits


Branch if all 4 bits were zero
Check if leftmost bit is 1
Branch if that bit was 1
Test other values

What value will be in GR3 when control arrives at the instruction named BitWas1?
21.3.8.(2) + A programmer wanted to extract the six low-order bits of GR4, and considered
these three sequences of instructions:
(1)

4,=X0000003F

(2)

SLL
SRL

4,26
4,26

(3)

SRDL 4,26
SR
4,4
SLDL 4,26

Criicize each sequence in terms of its simplicity and/or efficiency, and suggest a single instruction to use in place of each.
21.3.9.(2) + A friend of the programmer in Exercise 21.3.8 suggested using an instruction with
an immediate operand:
NILL 4,X003F
Is his solution acceptable? Explain why or why not.

21.4. Summary
The immediate-operand instructions described in this section can provide savings in three ways:
1. they eliminate the need to access operands from storage,
2. they save the space that those operands needed, and
3. they help eliminate the need for base registers that might have been required to address those
operands.

326

Assembler Language Programming for IBM z System Servers

Version 1.00

The load- and insert-immediate instructions are summarized in Table 112. The insert-immediate
instructions dont affect any part of the R1 register other than the bit positions where the immediate operand has been inserted.
Operand 1
Operand 2
Arithmetic Load

32 bits

Operation

16 bits

64 bits
32 bits

16 bits
LGHI

32 bits
LGFI

Logical Load

LLIHH
LLIHL
LLILH
LLILL

LLIHF
LLILF

Insert

IIHH
IIHL
IILH
IILL

IIHF
IILF

LHI

Table 112. Load and insert instructions with immediate operands

The arithmetic-immediate instructions are summarized in Table 113.


Operand 1
Operand 2
Arithmetic Add/Subtract

32 bits

Operation

16 bits
AHI

AFI

CHI

CFI

CGHI

MHI

32 bits
AGFI
ALGFI
SLGFI

CLFI

Logical Compare
Multiply

16 bits
AGHI

ALFI
SLFI

Logical Add/Subtract
Arithmetic Compare

64 bits
32 bits

CGFI
CLGFI

MGHI

Table 113. Arithmetic instructions with immediate operands

The logical-immediate instructions are summarized in Table 114. The logical-immediate


instructions dont affect any part of the R1 register other than the bit positions where the immediate operand has been ANDed, ORed, or XORed.
Operand 1
Operand 2

Operation

32 bits
16 bits

64 bits
32 bits

AND

OR

16 bits
NIHH
NIHL
NILH
NILL

32 bits
NIHF
NILF

OIHH
OIHL
OILH
OILL

OIHF
OILF

XIHF
XILF

XOR
Table 114. Logical instructions with immediate operands

Instructions Discussed in this Section


The instruction mnemonics and opcodes are shown in the following table:

Chapter VI: Addressing, Immediate Operands, and Loops

327

Mnemonic
AFI

Opcode
C29

Mnemonic
IILF

Opcode
C09

Mnemonic
NIHH

Opcode
A54

AGFI

C28

IILH

A52

NIHL

A55

AGHI

A7B

IILL

A53

NILF

C0B

AHI

A7A

LGFI

C01

NILH

A56

ALFI

C2B

LGHI

A79

NILL

A57

ALGFI

C2A

LHI

A78

OIHF

C0C

CFI

C2D

LLIHF

C0E

OIHH

A58

CGFI

C2C

LLIHH

A5C

OIHL

A59

CGHI

A7F

LLIHL

A5D

OILF

C0D

CHI

A7E

LLILF

C0F

OILH

A5A

CLFI

C2F

LLILH

A5E

OILL

A5B

CLGFI

C2E

LLILL

A5F

SLFI

C25

IIHF

C08

MGHI

A7C

SLGFI

C24

IIHH

A50

MHI

A7D

XIHF

C06

IIHL

A51

NIHF

C0A

XILF

C07

The instruction opcodes and mnemonics are shown in the following table:
Opcode
A50

Mnemonic
IIHH

Opcode
A5F

Mnemonic
LLILL

Opcode
C0B

Mnemonic
NILF

A51

IIHL

A78

LHI

C0C

OIHF

A52

IILH

A79

LGHI

C0D

OILF

A53

IILL

A7A

AHI

C0E

LLIHF

A54

NIHH

A7B

AGHI

C0F

LLILF

A55

NIHL

A7C

MGHI

C24

SLGFI

A56

NILH

A7D

MHI

C25

SLFI

A57

NILL

A7E

CHI

C28

AGFI

A58

OIHH

A7F

CGHI

C29

AFI

A59

OIHL

C01

LGFI

C2A

ALGFI

A5A

OILH

C06

XIHF

C2B

ALFI

A5B

OILL

C07

XILF

C2C

CGFI

A5C

LLIHH

C08

IIHF

C2D

CFI

A5D

LLIHL

C09

IILF

C2E

CLGFI

A5E

LLILH

C0A

NIHF

C2F

CLFI

In general, these immediate-operand instructions dont do anything you cant do with operands in
memory. But on modern CPUs, they will execute much faster and will help reduce the size of
your program.

Terms and Definitions

328

Assembler Language Programming for IBM z System Servers

Version 1.00

immediate operand
An operand contained in a field of the instruction itself.

Programming Problems
Problem 21.1.(2) Rewrite Problem 18.7 to generate a hexadecimal addition table, using immediate operands wherever possible.
Problem 21.2.(2) Rewrite Problem 18.8 to generate a hexadecimal multiplication table, using
immediate operands wherever possible.

Chapter VI: Addressing, Immediate Operands, and Loops

329

22. Branches, Loops, and Indexing

2222222222
222222222222
22
22
22
22
22
22
22
22
22
222222222222
222222222222

2222222222
222222222222
22
22
22
22
22
22
22
22
22
222222222222
222222222222

Programs often process data repetitively or iteratively under the control of a counter or some
other condition. In this section we examine several instructions that simplify coding loops,
sequences of instructions executed repeatedly.
First, well describe a newer form of branch instruction, the relative-immediate branch.

22.1. Branch Relative on Condition Instructions


The conditional relative branch instructions BRC and BRCL calculate their branch address by
adding twice the immediate operand to the address of the branch instruction, as described in
Section 20.1.3 on page 304. They have the formats shown in Tables 115 and 116.
A7

M1

RI 2

Table 115. Format of the BRC instruction

RI-type branch instructions for which the value of the RI 2 operand lies in the range
215 RI2 2151, or
32768 RI2 32767
allow the relative offset to the branch target to lie as far as 65536 and + 65534 bytes away.
C0

M1

RI 2

Table 116. Format of the BRCL instruction

For RIL-type branch instructions the value of the RI 2 operand lies in the range
231 RI2 2311, or
2147483648 RI2 2147483647

330

Assembler Language Programming for IBM z System Servers

Version 1.00

This means the offset of the branch target can be more than 4 billion bytes away from the
RIL-type instruction, in either direction. 132
Relative branch instructions can help you reduce or even eliminate the need for base registers to
address your instructions. We will describe conditional relative branches here, and examine other
forms of relative branch shortly.
In almost every situation where you use an RX-type conditional branch (introduced in Section
15) you can replace it with a branch relative on condition instruction. For example, if you want
to branch to the instruction named Equal if c(GR3)=c(GR12), you might have written a basedbranch instruction like
CR
BC

3,12
8,Equal

Compare c(GR3) to c(GR12)


Branch if they re equal

or, you could use a relative branch by writing


CR
BRC

3,12
8,Equal

Compare c(GR3) to c(GR12)


Branch if they re equal

While this may seem extra effort for no obvious gain, the relative branch has one major advantage: the target of any relative branch can be very distant from the branch instruction, while a
based branch target can be at most + 4094 bytes from the address of the based branch. The only
(and usually minor) disadvantage is that relative branch instructions cant be indexed.
Like the extended mnemonics shown in Table 61 on page 212, the Assembler supports a similar
set of extended mnemonics for branch relative on condition instructions, listed in Table 117.
Because the most-used forms of these extended mnemonics begin with the letter J, they are
often called Jump instructions.
RI Mnemonic
BRC
JC
BRU
J

RIL Mnemonic
BRCL
JLC
BRUL
JLU

BRNO

JNO

BRNOL

JLNO

14

BRNH
BRNP
BRNL

JNH
JNP
JNL

BRNHL
BRNPL
BRNLL

JLNH
JLNP
JLNL

13
13
11

BRNM

JNM

BRNML

JLNM

11

BRE
BRZ
BRNZ
BRNE
BRL

JE
JZ
JNZ
JNE
JL

BREL
BRZL
BRNZL
BRNEL
BRLL

JLE
JLZ
JLNZ
JLNE
JLL

8
8
7
7
4

BRM

JM

BRML

JLM

BRH
BRP

JH
JP

BRHL
BRPL

JLH
JLP

2
2

BRO

JO

BROL

JLO

JLNOP

JNOP

132

Mask
M1
15

Meaning
Conditional Branch
Unconditional Branch
Branch if Not Ones (T)
Branch if No Overflow (A)
Branch if Not High (C)
Branch if Not Plus (A)
Branch if Not Low (C)
Branch if Not Minus (A)
Branch if Not Mixed (T)
Branch if Equal (C)
Branch if Zero(s) (A,T)
Branch if Not Zero (A,T)
Branch if Not Equal (C)
Branch if Low (C)
Branch if Minus (A)
Branch if Mixed (T)
Branch if High (C)
Branch if Plus (A)
Branch if Ones (T)
Branch if Overflow (A)
No Operation

That ought to be enough for most programs. But on second thought, thats what they said at one time about 24-bit
addressing.
Chapter VI: Addressing, Immediate Operands, and Loops

331

Table 117. Extended branch relative on condition mnemonics and their branch mask values

Note:
The letter L in these mnemonics sometimes means Long (as in JLU)
and sometimes Low (as in JL).
The previous example could be rewritten as
CR
JE

3,12
Equal

Compare c(GR3) to c(GR12)


Branch if they re equal

and no base register is needed for the JE instruction.


The Assembler checks that the branch target is within the current control section, so that you
wont accidentally branch to an instruction that isnt part of the program containing the branch.
(Such a branch is allowed if the target is an external symbol; well discuss this case in Section 38.)
Using explicit offsets from the current instruction is generally a poor practice:
CR
JE

3,12
*+10

Compare c(GR3) to c(GR12)


Branch 10 bytes if they re equal

This will cause maintenance problems if another instruction is added or removed between the JE
and whatever instruction is 10 bytes away. The assembler generates X A784 0005 , where the
offset value 10 has been halved at assembly time so that the Effective Address at execution time
will be correct.
An even poorer coding technique is writing the RI2 operand explicitly:
CR
JE

3,12
10

Compare c(GR3) to c(GR12)


Branch 10(?) bytes if they re equal

The Assembler will issue a warning and then generate the instruction with the explicit absolute
operand in the RI 2 field, X A784 000A so that the branch target is actually 20 bytes away!
Branch relative instructions can be very helpful in programs larger than 4K bytes, where using
based branch instructions may require more than one base register to provide addressability.
With relative branches, you can often reduce the number of program base registers (or even
eliminate them entirely), freeing registers for other productive uses.

Exercises
22.1.1.(1) The extended mnemonic for the Long relative branch instructions is formed by
adding the letter L after the initial letter J. But the Long unconditional relative branch mnemonic is JLU, not JL. Why?
22.1.2.(1) Can you think of situations where JNOP and JLNOP will be useful?
22.1.3.(2) + What machine instruction is generated by each of these statements?
(a)
(b)
(c)
(d)

J
J
J
JL

*-10
*+2046
-40
*+2

What will happen if the last of these is executed?

332

Assembler Language Programming for IBM z System Servers

Version 1.00

22.2. A Simple Example of a Loop


We will use variations on a simple example to illustrate some basic principles. Suppose a string
a one-dimensional array of 80 bytes containing character data in the EBCDIC representation
begins at Str and ends at Str+79. The character string could represent data read from an
80-character record.

We want to scan the string and replace all special (non-alphanumeric) characters by blanks. That
is, any character with EBCDIC representation less than C a (X 8 1 ) should be replaced by C
(X 4 0 ).133 Thus, letters and digits will be unchanged.
We begin with the example in Figure 167. It performs the required processing in a straightforward but perhaps clumsy way. This problem will be used for several more examples, so try to
understand the basic idea here.
SR
0,0
Characters are inserted into GR0
LR
1,0
Character count in GR1, initially 0
LA
2,C a
c(GR2) = X00000081
LA
3,C
c(GR3) = X00000040
LA
4,Str
First byte s address in GR4
GetChar IC
0,0(,4)
Get a byte from the string
CR
0,2
Compare to letter a
JNL Okay
Branch if a letter or digit
STC 3,0(,4)
Otherwise replace by a blank
Okay
LA
4,1(,4)
Increment character address by 1
LA
1,1(,1)
Increase character count by 1
C
1,=F 8 0
Compare count to 80 (string length)
JL
GetChar
Loop if less than 80 done so far
- - Str
DC
CL80 String-to,be(Scanned+For*Special=Characters$#
Figure 167. A simple loop to scan and replace characters

The character comparisons are made in the rightmost bytes of registers GR0 and GR2. 134 The
address of the byte being examined is in GR4, and is incremented by 1 at each step, and was
initialized to the address of the first character before entering the loop. The branch instruction at
the end of the loop must branch if the contents of GR1 is less than 80, not if it is less than or
equal to 80: otherwise, the final test would cause the byte at Str+80 to be examined and possibly
changed. The string ends at Str+79.

Exercises
22.2.1.(2) + Show the result at Str after the program segment in Figure 167 completes execution.
22.2.2.(1) Revise the program in Figure 167 to use extended relative branch mnemonics and no
literals.

133

134

Table 13 on page 89 shows that in the EBCDIC character representation, all letters and numeric digits have
encodings greater than X 8 0 .
LA (and not LHI) was used to load GR2 and GR3 with C a and C . LA and LHI are both very fast instructions;
the CPU pays special attention to LA, because address generation is a fundamental operation. Basically, theres no
detectable difference in speed.
Chapter VI: Addressing, Immediate Operands, and Loops

333

22.3. Simple Tables and Array Indexing


The next version of this program uses the indexing capabilities of the IC and STC instructions. 135
Assume that the character string at Str has been defined as in Figure 167.
SR
SR
LA
GetChar IC
C
JNL
STC
Okay
LA
C
JL
- - -

0,0
1,1
3,C
0,Str(1)
0,=A(C a )
Okay
3,Str(1)
1,1(,1)
1,=F 8 0
GetChar

Clear GR0 for character insertion


Initialize index to 0
c(GR3) = blank at right end
Get a character from string
Compare to letter a
Jump if not less than X 8 1
Replace by a blank
Increment index by 1
Compare to length of string
Branch if not done

Figure 168. A simple loop, using indexing

The byte being examined is now addressed using GR1 as an index register. The first time the IC
instruction named GetChar is executed, the contents of GR1 is zero and the Effective Address
generated will be the address of Str. On the last execution of the IC instruction, the contents of
GR1 is 79, and the last byte of the string is inserted into GR0 for examination. Then, after the
LA instruction named Okay is executed, the contents of GR1 is 80, the branching condition for
the final JL instruction is not met, and control will pass to the following instruction.
A minor difference in this version is that the 32-bit word containing the EBCDIC representation
of the letter a is now a word in memory, specified by the literal =A(C a ) , rather than in GR2 as
before.136
Figure 169 illustrates another use of indexing. Three fullword integers stored beginning at QQ are
added with tests for overflow. In this case, however, after the sum is complete, a branch to NoErr
is made if no overflows occurred, to Err1 if exactly one overflow occurred, and to Err2 if two.

A1

A2
BrTbl

SR
L
A
JNO
LA
A
JNO
LA
B
J
J
J

1,1
0,QQ
0,QQ+4
A1
1,4(,1)
0,QQ+8
A2
1,4(,1)
BrTbl(1)
NoErr
Err1
Err2

Set overflow count in GR1 to zero


Load first integer into GR0
Add second integer
Branch if no overflow
Indicate one overflow
Add third integer
Branch if no overflow
Indicate an overflow
Indexed(!) branch into branch table
0-overflow branch
1-overflow branch
2-overflow branch

Figure 169. Indexing into a branch table

When the instruction named A2 is reached, GR1 contains the number of overflows multiplied by
four. This is used as an index in computing the Effective Address of the BC instruction at A2,
which will be BrTbl, BrTbl+4, or BrTbl+8. The appropriate branch instruction will then transfer
control to the desired location. The symbol BrTbl need not be on a fullword boundary: the index
in GR1 is incremented by 4 for each overflow to account for the length of the J instructions.
Branch tables provide a fast and efficient way to route control to different parts of a program.

135
136

334

Review Sections 5.3 and 9.5 for a quick summary of indexing.


While =F 1 2 9 and =A(X 8 1 ) would give identical results, using the fullword integer literal is a poor practice, because
your reader cant tell that the literal is intended for use in a character comparison.
Assembler Language Programming for IBM z System Servers

Version 1.00

Exercises
22.3.1.(2) A list of N halfword integers is stored beginning at DATA and the number N is a
halfword integer at NBR. Write a code sequence that will store at the fullwords POS, NEG, and
NZT respectively the sum of the positive terms, the sum of the negative terms, and the number
of zero terms.
22.3.2.(1) What will happen if the conditional branch instruction named A2 in Figure 169 is
changed to a relative branch instruction?
22.3.3.(2) + Revise Figure 168 to use immediate operands to replace references to operands in
memory.

22.4. Branch on Count Instructions


The branch on count instructions are shown in Table 118. None of them changes the CC setting.
Op
46

Mnem
BCT

Type Instruction
R X Branch on Count (32)

E346

BCTG

RXY Branch on Count (64)

A76

BRCT

RI

Branch Relative on Count


(32)

Op
06

Mnem
BCTR

Type Instruction
R R Branch on Count Register
(32)
B946 B C T G R R R E Branch on Count Register
(64)
A77 B R C T G R I
Branch Relative on Count
(64)

Table 118. Branch on count instructions

Like the conditional relative branches, the Assembler provides extended mnemonics for the two
branch relative on count instructions:
Instruction
BRCT
BRCTG

Extended Mnemonic
JCT
JCTG

Table 119. Extended mnemonics for branch relative on count instructions

The Branch on Count instructions simplify counting and branching operations like those in
Figures 167 and 168 above. As with the BCR and BC instructions, the branch address is
obtained either from R 2 for BCTR and BCTRG (unless the R 2 digit is zero, in which case no
branch is ever taken); or from the Effective Address for BCT and BCTG.
The branch address is computed first. Then, the branching condition is determined by first arithmetically reducing the contents of R1 by one, and branching only if the resulting contents of R1 is
not zero. That is, the branch does not occur only when the result is zero.
The CC is unchanged, and has no effect on the branching condition. An interruption condition is
never recognized, even if an internal fixed-point overflow occurs (that is, if the new contents of R1
wraps around from the largest negative number to the largest positive number).
We can rewrite our original example in Figure 167 to use a JCT instruction, by stepping backwards along the string of characters starting at Str+79 and ending at Str. This lets us use the
same quantity both as an index and a counter.

Chapter VI: Addressing, Immediate Operands, and Loops

335

SR
LA
LA
LA
IC
CR
JNH
STC
JCT

Next

Okay

0,0
1,80
2,C a
3,C
0,Str-1(1)
2,0
Okay
3,Str-1(1)
1,Next

Clear GR0
Set GR1 to number of characters
c(GR2) = letter a
c(GR3) = blank
Get a character
Compare a to character
Branch if a is low or equal
Otherwise blank it out
Count down by 1, jump if not 0

Figure 170. A backward loop to scan and replace characters

We used the implied address Str 1 in the second operand of the IC and STC instructions
because the possible values in GR1 now run from 80 to 1, rather than from 0 to 79 as before.
The range of values is different, but the direction of incrementation makes no difference in this
example. This can be thought of as reflecting a difference in numbering the bytes in the string: if
we number them from 0 to 79 they are addressed by writing the operand as Str(1); but if the
bytes are numbered from 1 to 80, they must be addressed by writing the operand as Str 1(1).
On the final pass through the loop, the contents of GR1 will be 1; when the BCT instruction is
executed, the contents of GR1 is reduced to zero, the branching condition is finally not met, and
control passes to the next sequential instruction. We see an immediate gain in program efficiency
over the example in Figure 168: if we count the instructions inside the loop, we have reduced
them from 7 to 5, and we would expect about the same reduction in processing time.
The Branch on Count instructions are especially useful when a predetermined number of loop
iterations is needed, and no special attention must be paid to indexing quantities. The count of
loop iterations is often set at execution time rather than at assembly time.
To illustrate several uses of these instructions, consider these examples taken from previous
sections.
1. The word at Nbr contains a positive integer N; compute the sum of the cubes of the first N
integers. (See Figure 125 on page 267)
L
SR
LR
MR
MR
AR
JCT
ST

Next

4,Nbr
5,5
1,4
0,1
0,4
5,1
4,Next
5,Sum

c(GR4) = index K , initially N


Initialize sum to zero
c(GR1) = K
K * K
K cubed
Add to sum
Decrease K by 1, and loop
Store sum

2. The halfword at NN contains a positive integer N; store at NSq the sum of the first N odd
integers. (See Figure 82 on page 220)

Loop

SR
LH
LA
BCTR
AR
JCT
ST

0,0
1,NN
2,0(1,1)
2,0
0,2
1,Loop
0,NSq

Clear sum to zero


Get N from memory
(Count + Count) in GR2
(2 * Count) - 1
Add to sum
Reduce count and branch
Store result

Figure 171. Calculate the sum of the first N odd integers

Because N is positive and at most 15 bits long, we can use the LA instruction to compute
(N+N) in one step, since we know the result will fit in the rightmost 24 bits of GR2 for any
addressing mode (so long N is less than 222). The following BCTR instruction does not
branch, because the R 2 digit is zero; its only effect is to reduce the contents of GR2 by one,
as required. (The K-th odd integer is 2K 1.)
3. Find the twos complement of the double-length integer stored in the pair of words at Arg.
(See Figure 91 on page 227)

336

Assembler Language Programming for IBM z System Servers

Version 1.00

LM
LCR
LCR
JZ
BCTR
STM

XXX

6,7,Arg
6,6
7,7
XXX
6,0
6,7,Arg

Double-length number in (GR6,GR7)


Complement high-order part
Complement low-order part
Branch if carry out of GR7
Otherwise reduce c(GR6) by 1
Store complemented result

This is identical to the example in Figure 91 except that the BCTR instruction replaces
SL

6,=F 1

AHI

6,-1

or
so the CC setting may be different when the STM is executed. The BCTR instruction with
R 2=0 may be used this way anywhere in a program; it is shorter than subtracting a constant
1 from memory, but has the possible (minor) disadvantage that the CC is not set. 137
As a further example of the BCT instruction, the program segment in Figure 172 stores the cubes
of the integers from 1 to 10 in a table of ten successive fullwords starting at the word named Cube,
in descending order.
NCubes
Mult

Cube

Equ 10
LA
4,NCubes
LR
3,4
MR
2,3
MR
2,4
LR
1,4
SLL 1,2
ST
3,Cube-4(1)
JCT 4,Mult
- - DS
(NCubes)F

Number of table entries


c(GR4) = number to be cubed
Move it to GR3
Square it
And cube it
Set up index in RX
Multiply by 4 for word length
Store in correct table position
Branch back (NCubes-1) times
Space for NCubes Words

Figure 172. Store the cubes of the first 10 integers

In this case we used the integer argument in GR4 to index the desired word in the table. Since the
table entries are 4-byte words, the index must be multiplied by four for each item, so we use SLL
to multiply. Because the first entry in the table corresponds to 1 cubed, the implied address of
the ST instruction must be Cube-4 so that the address of each entry will be calculated correctly.

Exercises
22.4.1.(2) + In Figure 171, show how you can eliminate one instruction from the body of the
loop.
22.4.2.(1) + In the BCT and BCTR instructions, what initial values of GR R 1 will cause a
fixed-point overflow when the instruction is executed?
22.4.3.(2) A string of N bytes is stored beginning at String, and N is a halfword integer stored
at NN. Store the string at Gnirts in reversed order.
22.4.4.(3) Suppose there is a nonnegative integer K whose value is stored in memory at the
word integer KK. Starting at Str is a string of bytes whose bits are a random assortment of
zeros and ones. Write a code sequence that will find the K-th one-bit in the string, and store its
bit offset in the word at BitOff. For example, if the string starts with X C607... , then if K=1
the bit offset is 0; if K=4 the bit offset is 6; and if K=6, the bit offset is 14.
22.4.5.(2) + If b is the number of a register, what will happen if you execute these instructions?

137

AHI and BCTR are both very fast, and AHI sets the condition code.
Chapter VI: Addressing, Immediate Operands, and Loops

337

BCT

b,0(,b)

or

BCT

b,0(b,0)

22.4.6.(3) + A list of 100 fullword integers is stored beginning at the word named IntList.
Write a code sequence that moves the integers into a list beginning at NewList, but do not
move an item if it is identical to its predecessor. Store the number of items in the new list at
NumNews. For example, if the first six values at IntList are 3, 5, 5, 5, 4, 3, then the list at
NewList would begin with 3, 5, 4, 3.
22.4.7.(2) The following code sequence is supposed to calculate the same sum of N odd integers
as in Figure 171. Why doesnt it? What does it calculate?

XXX

LH
LA
LA
AR
JCT
ST

7,NN
1,1
0,1(7,7)
1,0
7,XXX
1,Nsq

22.4.8.(3) For the program below, determine first the code assembled for each of the instruction
statements. Then when (at execution time) control reaches the SVC instruction, determine
c(GR2). (Dont try to assemble and then execute the program, since the SVC will undoubtedly
do something undesirable.)
Ex22_4_8 START
USING
BASR
LA
LA
SR
Loop
NOPR
AH
LA
BCT
SVC
AA
DC
END

0
*,8
Establish addressability
8,0
Set base register
4,4
Initialize counter
7,AA
Initialize address
2,2
Set sum box to zero
0
Let the CPU catch its breath
2,0(,7)
Add a data item to the sum
7,2(0,7)
Increment address by 2
4,Loop
Branch back if not done
3
Do something unforgettable
H 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9
Table of numbers
Ex22_4_8

22.4.9.(4) Repeat Exercise 22.4.6, but this time the results at NewList may not contain any
duplicate items. For example, if the six initial values at IntList are 2, 3, 2, 4, 2, 3, NewList
would begin with the values 2, 3, 4.
22.4.10.(2) Write a sequence of instructions that will count the number of 1-bits in GG1 and
leave the count in GG0. The original contents of GG1 need not be preserved.
22.4.11.(2) + Repeat Exercise 17.2.6 using a BCT instruction to count the number of shifts.
22.4.12.(3) + These instructions are intended to form the sums C(J)=A(J) + B(J) for values of J
from 1 to 64. Show the generated object code, assuming that the PrintOut instruction generates
exactly 32 bytes on the first available halfword boundary.

338

Assembler Language Programming for IBM z System Servers

Version 1.00

Loc
____
____
____
____
____
____
____
____
____
____
____
____
____
____

Object Code
_____________
_____________
_____________
_____________
_____________
_____________
_____________
_____________
_____________
_____________
_<32 bytes>__
_____________
_____________
_____________

Assembler Language Statements


BASR 12,0
Using *,12
LA
3,64
LA
7,A
Using A,7
Loop
L
0,A
A
0,B
ST
0,C
BCT 3,Loop
Drop 7
PrintOut *
A
DS
64F
B
DS
64F
C
DS
64F

22.4.13.(2) + In Exercise 22.4.12, the instructions dont perform the expected calculation.
Explain what happens, and what needs to be fixed.
22.4.14.(3) + An exercise required writing instructions to count the number of 1-bits in GR1
and leave the count in GR0. A student wrote:
SR
LA
SLL
LTR
BZ
LA
BCT

Loop

Next

0,0
2,32
1,1
1,1
Next
0,1(,0)
2,Loop

Set count to zero


Count 32 bits
Shift a bit into sign position
Test sign bit
Branch if sign bit is zero
Add 1 to count of 1-bits
Repeat for all 32 bits

The instructions didnt work. Find and fix the errors.


22.4.15.(3) + Write instructions to count the number of 1-bits in GR1, leave the count in GR0,
and leave GR1 unchanged without saving and then restoring its contents.
22.4.16.(2) + State the cases in which each of the following five instruction sequences give different results, and explain the differences.
(1) LCR 0,0

(2) X
A

0,=F -1
0,=F 1

(4) BCTR 0,0


X
0,=F -1

(5) S
X

0,=F 1
0,=F -1

(3) X 0,=F -1
AL 0,=F 1

22.4.17.(2) + Consider these three instructions:


LCR 1,1
BCTR 1,0
LCR 1,1
1. What do these instructions do?
2. What instruction(s) do they imitate?
3. How do final Condition Code settings differ between these three instructions and the
instruction(s) they imitate? For at least these initial values in GR1:
(1)
(2)
(3)
(4)
(5)

X00000000
X00000001
X 7 FFFFFFF
X80000000
X FFFFFFFF

determine the resulting c(GR1) and the CC setting from executing the three instructions,
and compare the results to what you get by executing the imitated instruction.
Chapter VI: Addressing, Immediate Operands, and Loops

339

22.5. Looping in General


Most of these programming examples used loops to perform some iterative task, and the termination condition depended on a counting operation. More generally, many applications require
that
some quantity be established as an index
whose value is changed regularly by an increment
and is then compared to some comparand;
a branch may then be made depending on some condition determined by the comparison.
These four terms index, increment, comparand, and condition will appear in several forms
when we look at the branch on index instructions in Section 22.6.
The term index means the variable quantity that controls or determines completion of the loop;
it may or may not be related to a value used as an index in an RX-type instruction (that is, specified by an index register specification digit).
If the increment is negative it might be more appropriate to call it a decrement. Rather than using
special names to distinguish the sign of the increment, we will assume the increment can be either
positive or negative.
Loops have many forms; here are two of the most common. The loops we have seen tested for
loop completion at the end of the loop; this is called a Do-Until loop, because the loop is
executed until the termination condition is reached. This is illustrated in Figure 173.


Initialize index,
loop add increment compare to done
increment, comparand  body to index
comparand

 not done
Figure 173. Sketch of a Do-Until loop

As this figure indicates, a Do-Until loop is always executed once.138


The other form is called a Do-While loop, because the loop is executed only while the termination condition has not been reached. This is illustrated in Figure 174.



Initialize index,
compare to loop add increment
increment, comparand
comparand not body to index

done
done
Figure 174. Sketch of a Do-While loop

For the Branch on Count instructions, the four loop-control items are all implied by the instruction: the index is in register R1, the increment is 1, the comparand is zero, and the condition for
branching is inequality. This rather limited set of possibilities may be sufficient for you to code
your loop effectively.

138

340

For many years, this was the characteristic behavior of loops in the FORTRAN programming language.
Assembler Language Programming for IBM z System Servers

Version 1.00

Note!
The terminology for Do-While and Do-Until loops can be misleading.
Such a loop is not executed until the precise moment when the test condition becomes true, or only while the test condition remains true.
Figure 175 shows another method to calculate a table of the first 10 cubes. The difference from
Figure 172 is that an address, rather than a subscripting index, is used as the varying quantity
controlling execution of the loop.
NCubes

Mult

Cube

Equ 10
Number of table entries
LA
1,Cube+0*4
Address of first table entry
LA
2,Cube+(NCubes-1)*4 Address of last table entry
LA
3,1
c(GR3) = number to be cubed
LR
5,3
Move multiplicand to GR5
MR
4,3
Square
MR
4,3
Cube
ST
5,0(,1)
Store in table
LA
3,1(,3)
Increment number to be cubed
LA
1,4(,1)
Increment table address
CR
1,2
Compare to end address
JNH Mult
Jump back if not past end of table
- - DS
(NCubes)F
Table of resulting values

Figure 175. Store the cubes of the first 10 integers in a different way

In this case an explicit address in the ST instruction is used, rather than an implied address as in
Figure 172. This means that the loop termination condition is determined from address arithmetic, not from tests on any of the quantities being calculated in the loop. Its often convenient to
perform such addressing calculations explicitly, rather than rely on the Assembler to assign all
bases and displacements. The index of the entries in the table can be thought of as running
from 0 to (NCubes 1)*4 = 36 in steps of 4.
We used indexing in Figures 172 and 175 to compute a table of cubes. In Figure 172, the index
of the loop in GR4 is also used in GR1 to index the ST instruction; in Figure 175, the index
of the loop is the address contained in GR1, but no RX-style indexing is done in any of the
RX instructions.
Do-Until and Do-While loops are examples of Structured Programming forms, but other types
of loop structures are often used. For example, you can test for a loop-exit condition in the body
of the loop:


Initialize loop body, exit loop body,

first part test remainder



done

Exercises
22.5.1.(2) A table of N halfword integers is stored beginning at HH, and N is a halfword integer
at NHwds. Store the integers into the table starting at RR in reverse order.
22.5.2.(2) Your solution to Exercise 22.4.9 will probably contain two loops. What are their
types?
22.5.3.(1) What type of loop is illustrated in Figure 175?

Chapter VI: Addressing, Immediate Operands, and Loops

341

22.6. Branch on Index Instructions


Because indexed loops are a key part of many programs, z System provides the Branch on Index
High and Branch on Index Low or Equal instructions shown in Table 120. They can greatly
simplify coding of loops.
Op
86
87

Mnem
BXH
BXLE

Type Instruction
RS
Branch on Index High (32)
RS
Branch on Low or Equal
(32)
RSI Branch Relative on Index
High (32)

84

BRXH

85

BRXLE RSI

Op
Mnem
Type Instruction
EB44 BXHG RSY Branch on Index High (64)
EB45 BXLEG RSY Branch on Index Low or
Equal (64)
EC44 B R X H G RIE Branch Relative on Index
High (64)

Branch Relative on Low or


Equal (32)

EC45 BRXLG RIE

Branch Relative on Index


Low or Equal (64)

Table 120. Branch on index instructions

As there are no essential differences between BXH/BXLE and BXHG/BXLEG other than using
32-bit registers for the former and 64-bit registers for the latter, our examples will use the 32-bit
forms. None of the instructions changes the CC setting.
As with
parison,
RS-type
121 and

Branch on Count, these instructions provide the three functions of incrementation, comand conditional branching, but with much greater flexibility. BXH and BXLE are
instructions requiring two register specification digits R1 and R 3, as indicated in Tables
122.

opcode

R1

R3

B2

D2

Table 121. RS-type BXH and BXLE instructions

BXHG and BXLEG are RSY-type instructions that also require R 1 and R 3 operands:
opcode

R1

R3

B2

DL 2

DH2

opcode

Table 122. RSY-type B X H G and BXLEG instructions

The relative-immediate forms of the branch on index instructions use two different instruction
formats, RSI and RIE:
opcode

R1

R3

RI 2

Table 123. RSI-type BRXH and BRXLE instructions

opcode

R1

R3

RI 2

opcode

Table 124. RIE-type B R X H G and BRXLG instructions

Like the STM and LM instructions, the use of registers other than GR R 3 may be implied. First,
note that all of the loop-control quantities (index, increment, and comparand) are carried in registers. The index is always in GR R 1, and the increment is always in GR R 3. The comparand is
contained either in (GR R 3 + 1) (if R3 is even), or in GR R 3 (if R3 is odd).
Thus, if we write
BXLE

7,4,NEXT

then the index is in GR7, the increment is in GR4, and the comparand is in GR5. On the other
hand, if we write
BXLE

342

7,5,NEXT

Assembler Language Programming for IBM z System Servers

Version 1.00

the index is again in GR7, but both the increment and the comparand are in GR5. Using an
odd-numbered register for both the increment and the comparand will be discussed in Section
22.9.
We use a simple notational device to illustrate the fact that the comparand is always in an oddnumbered register: that is, if the R3 operand is even, the comparand is in GR(R3 + 1), and if the
R 3 operand is odd, the comparand is in GR R 3. We write R3 |1 to mean that the register containing the comparand is determined by ORing a low-order 1 bit into the R3 digit. Thus, GR8 |1
refers to GR9, and GR9 |1 is the same as GR9.139
The operation of Branch on Index instructions, as sketched in Figure 176, is:
1. The sum of the index and increment is computed internally, and any overflow occurring in
forming the sum is ignored.
2. The sum is then compared algebraically to the comparand. Whether or not the branching
condition is met is noted: for Branch on Index High this means that the sum is algebraically greater than the comparand, and for Branch on Index Low or Equal that the sum is
algebraically less than or equal to the comparand.
3. The sum then replaces the index, and the branch is taken if the branching condition is met.

Decode: Compute Compare Is Branch yes
Fetch Compute index + sum to condition
branch Increment Comparand
met?

address

no


Fetch next
Sum replaces
 Br.Addr
 instruction 
index
 to IA 

Figure 176. Operation of BXH and BXLE instructions

The branching condition is not reflected in the CC setting: neither of the Branch on Index
instructions changes the CC.
Because the branch address is computed during the Decode portion of the instruction cycle
before incrementation takes place, the Effective Address may not be as expected if the R1 and B2
digits are the same (unless both are zero, which is very unlikely.)
Its important to note that the comparison takes place before the sum replaces the index; we will
see examples of situations where this is important. (Exercise 22.9.8 is recommended!)
Figure 177 shows another way to visualize the execution of BXH and BXLE.

sum comparand ?
BXLE no

yes

sum =
  sum
index + opcode?
Br.addr to IA to
increment
  index

yes

BXH no

sum > comparand ?

Figure 177. Operation of BXH and BXLE instructions

139

We are using the PL/I-language notation for the logical OR operation, represented by the vertical-bar character
|.
Chapter VI: Addressing, Immediate Operands, and Loops

343

The Branch on Index instructions are powerful and useful, though they sometimes seem difficult.
Normal uses require three general registers, of which two must be an even-odd register pair.
The placement of the comparand in R 3 |1 rather than in R 3+1 (as would seem more useful and
natural) is undoubtedly due to a design requirement for the original models of System/360: it was
simpler to OR than to add a low-order one-bit to the register specification digit. Also, other
double-length instructions such as M, D, and SLDA specify an even-numbered R 1 register, and
the corresponding odd-numbered register may be addressed in the CPU by forcing a low-order
one-bit into the register specification digit R1.
Like the conditional relative branches, the Assembler provides extended mnemonics for the four
branch relative on index instructions:
Instruction
BRXH
BRXHG
BRXLE
BRXLG

Extended Mnemonic
JXH
JXHG
JXLE
JXLEG

Table 125. Extended mnemonics for branch relative on index instructions

Exercises
22.6.1.(3) In the execution of the BXH and BXLE instructions, any overflow in forming the
sum of the index and the increment is ignored. However, the comparison of the sum and the
comparand requires an internal subtraction, in which an overflow might occur.
Make a table that includes all of the eight possible combinations of (1) BXH or BXLE, (2) sign
of result of subtraction is + or , and (3) an internal overflow did or did not occur during the
subtraction. Determine for each of the eight combinations whether or not a branch will occur.

22.7. Examples Using BXLE


To illustrate BXH and BXLE, consider the example given in Figure 167 in Section 22.2, where
we want to replace non-alphanumeric characters by blanks. Well rewrite the code sequence to
use a BXLE instruction.
LM

0,3,=F 0 , 0 , 1 , 7 9

*
*
LM
*
GetChar IC
CR
BNL
STC
Alpha
BXLE
- - -

4,5,=A(C a , C )
0,Str(1)
0,4
Alpha
5,Str(1)
1,2,GetChar

Preset registers GR0-GR3


Chars inserted in GR0, index in GR1,
increment in GR2, comparand in GR3.
Letter a in GR4, blank in GR5.
Get a character from the string
Compare to letter a in GR4
Branch if alphanumeric
Otherwise, store a blank
Increment, test, and branch

Figure 178. Replacing special characters with blanks, using BXLE

The values of the index run from 0 to 79; when control reaches the BXLE instruction, the increment ( + 1) in GR2 is added to c(GR1). Because GR2 is an even-numbered register, the sum is
compared to the comparand in the next higher-numbered register, GR3. If the sum is less than or
equal to 79, the branching condition is met, and control will be transferred to the instruction
named GetChar after the sum is placed back into GR1. When control finally passes to the instruction following the BXLE, c(GR1) will be 80.

344

Assembler Language Programming for IBM z System Servers

Version 1.00

To give an example where BXLE appears in a more normal context, we will rewrite Figures 172
and 175 to compute a table of the cubes of the first 10 integers, stored starting at Cube.
NCubes

Mult

Cube

Equ
LA
SR
LA
LA
LR
MR
MR
ST
AHI
BXLE
- - DS

10
7,1
4,4
2,4
3,4*(NCubes-1)
1,7
0,1
0,7
1,Cube(4)
7,1
4,2,Mult

Number of table entries


Initial integer = 1
Set index to zero
Increment of +4 for indexing
Comparand (=36) in GR3
N in GR1
N * N
N cubed
Store in table
Increase N by 1
Increase index by 4 and loop

(NCubes)F

Space for table of cubes

Figure 179. Creating a table of cubed integers using BXLE

This segment uses fewer instructions inside the loop, at the expense of some extra instructions
outside the loop: this is often a valuable technique, especially for loops executed many times. The
following two code segments do the same calculation, but are set up slightly differently.
NCubes

Mult

Equ
LA
LA
LR
LA
LR
MR
MR
ST
AHI
BXLE

10
7,1
4,4
2,4
5,4*NCubes
1,7
0,1
0,7
1,Cube-4(2)
7,1
2,4,Mult

Number of table entries


Initial value of N = 1
Set increment in GR4 to 4
Initial index in GR2 is 4
Comparand in GR5 = 40
c(GR1) = N
N squared
N cubed
Store in table
Increment N by 1
Count and loop

Figure 180. Creating a table of cubed integers using BXLE

In this example, the index runs from 4 to 40 in steps of 4, rather than from 0 to 36 as in Figure
179. There is no significant difference between the methods illustrated in Figures 179 and 180,
except that the second can be simpler: since the integer N runs from 1 to 10 in steps of 1, the
multiplication by 4 to account for the length of the fullword result makes it natural to have the
index run from 4 to 40 in steps of 4. In Section 23 we will examine cases where such considerations are important, when we access tables of data stored in array form.
Another variation of this example is given in Figure 181, where the index and comparand quantities are addresses.
NCubes

Mult

Equ
LA
LA
LA
LA
LR
MR
MR
ST
AHI
BXLE

10
Number of cubes
4,Cube+0*4
Index set to initial table address
2,4
Increment = 4 for fullwords
3,Cube+(NCubes-1)*4 Comparand = final table address
7,1
Initial value of N = 1
11,7
N
10,11
N * N
10,7
N * N * N
11,0(,4)
Store in table
7,1
Increment N by 1
4,2,Mult
Increment address by 4 and loop

Figure 181. Creating a table of cubed integers with addresses as controls

Chapter VI: Addressing, Immediate Operands, and Loops

345

Exercises
22.7.1.(3) + Examine these two instructions, and determine (1) whether the branch to XX will be
taken, and (2) what will be the contents of GR3 after both instructions have been executed.
LA
3,1
BXLE 3,3,XX
Then, answer the same two questions, assuming that the second instruction is BXH instead.
22.7.2.(3) + Suppose we execute the following two instructions:

Next

LA
3,3
BXLE 3,3,*
- - -

What will be in GR3 when the next instruction is executed? Make the same determination for
BXH.
22.7.3.(3) A positive 64-bit dividend in registers GR6 and GR7 is divided by a positive divisor,
using the D instruction. What will happen if the instruction following the divide is
BXLE 6,7,WhatNext

22.7.4.(2) In Figure 178 on page 344, combine the first two instructions into a single LM that
uses a literal with an A-type constant. Then, initialize registers GR0 through GR5 using immediate operands. Including space required for the constants, which code sequence is shorter?
22.7.5.(4) Suppose registers GRx and GRy (where GRy is an odd-numbered register) contain
nonnegative integers. A student claimed that we can leave in register GRx the sum of their contents modulo (2 31 1) with the following instruction pair:
BXLE x,y,*+8
SL
x,=F2147483647

Form c(GRx)+c(GRy)
(2311)

Verify or disprove his claim.


22.7.6.(2) The following code sequence tries to find the leftmost 1-bit of the positive nonzero
number in GR1, and put its bit number into GR0.

SR
LA
LA
SLA
JM
JXLE
- - -

0,0
2,1
3,32
1,1
Y
0,2,X

Initialize bit position to 0


Initialize BXLE increment
Initialize BXLE comparand
Shift test word left once
Check for minus sign
Count up by 1 and loop
Rest of code

The program segment does not work correctly. Explain why not, and then correct it without
increasing the number of instructions.
22.7.7.(3) + By starting with a negative index value, it is possible to use a single register to hold
the increment and comparand of a BXLE instruction. Rewrite the examples in Figures 179
through 181 to use this technique.
22.7.8.(2) Repeat Exercise 22.7.1, but replace the first instruction with the following:
L

3,=F1073741824

(230)

Now, do the same again, replacing the LA by


L

3,=F -2147483647

(-231+1)

22.7.9.(3) + If you execute this BXLE instruction:


LM
1,3,=F7,17,77
BXLE 1,2,*

346

Assembler Language Programming for IBM z System Servers

Version 1.00

How many times will the BXLE instruction be executed? How many times will it branch?
What will be the sequence of values in GR1?
22.7.10.(2) + Suppose A, B, and C are three positive integers used to initialize the index, increment, and comparand registers of a BXLE instruction that controls the iterations of a loop.
How many times will the body of the loop be executed?

22.8. Examples Using BXH


To illustrate the use of the BXH instruction, Figures 179 and 181 will be rewritten so that the
indexing runs in the opposite direction. First, we calculate the table of cubes using normal
indexing.

Mult

LA
LHI
LA
LHI
SR
LR
MR
MR
ST
AR
BXH

7,10
8,-1
4,40
2,-4
3,3
1,7
0,7
0,7
1,Cube-4(4)
7,8
4,2,Mult

Initial value of N
c(GR8) = -1 for incrementing N
Initial index = 40
Increment = -4
Comparand = 0
N
N * N
N * N * N
Store in table
Add -1 to N
Count and loop

Figure 182. Creating a table of cubed integers using BXH

When the instruction following the BXH is reached, the index in GR4 will be zero.
We can use the value 4 for both the increment and the comparand and carry them in the same
register, as in Figure 183.

Mult

LA
LA
LHI
LR
MR
MR
ST
BCTR
BXH

7,10
4,36
5,-4
1,7
0,7
0,7
1,Cube(4)
7,0
4,5,Mult

Initial value of N is 10
Initial index = 36
Increment and comparand are -4
N
N squared
N cubed
Store in table
Decrease N by 1
Count down and loop

Figure 183. Creating a table of cubed integers, using BXH in a special way

In this case the R3 digit 5 is odd, so R3 |1 is the same as R3; the BXH will increment the index in
GR4 by 4, compare it to 4 (the comparand, also in GR5), and branch until the resulting sum
becomes equal to 4, when control will pass to the following instruction.

Exercises
22.8.1.(3) Suppose we execute the instructions
SRL
BXH

1,1
1,1,*-4

Describe the behavior of this code segment as it depends on the initial contents of GR1. Then
do the same, but with BXLE instead of BXH.

Chapter VI: Addressing, Immediate Operands, and Loops

347

22.9. Specialized Uses of BXH and BXLE (*)


Some specialized uses of BXH and BXLE involve unusual combinations of register specification
digits.
1. Suppose the contents of an odd-numbered register such as GR9 is zero. Then the instruction
XR
9,9
BXLE 4,9,XXX

Set GR9 to zero


Branch to XXX if c(GR4) is <= 0

will branch to XXX only if the contents of GR4 is less than or equal to zero. Similarly,
BXH

4,9,YYY

Branch to YYY if c(GR4) is > 0

would branch to YYY only if the contents of GR4 is greater than zero.
Since BXH and BXLE neither set nor test the condition code, this technique can be used in
situations where a condition code reflecting the state of the contents of GR4 is not available,
the current CC setting must be undisturbed, or if we want to avoid using instructions such as
LTR followed by a conditional branch.
2. Suppose we want to perform the inverse of the BCT instruction: that is, we want to increment the positive contents of a register by + 1, and then branch. If we set c(GR7) to + 1, and
c(GR2) is greater than zero, then
LHI
BXH

7,1
2,7,XXX

Initialize GR7 to +1
Increment c(GR2), branch to XXX

will branch to XXX after incrementing c(GR2) by 1, unless the sum overflows. (There will be
no indication of the overflow in the CC setting!) Similarly, if there is a negative integer in
GR2,
BXLE 2,7,YYY

Branch to YYY if c(GR2) not > +1

will increment c(GR2) and branch to YYY so long as the resulting sum does not exceed + 1.
3. If c(GR4) is + 1, then the instruction
BXH

5,4,ZZZ

will increment c(GR5) by 1 and then branch if the sum does not overflow. The index and
comparand are in the same register: if the comparison was made after the sum was placed in
GR5, equality would always be indicated, and the BXH would never branch.
Such special uses of the Branch on Index instructions are rare; they are used mostly in applications such as table searching and loop control. Try these exercises and the Programming Problems; youll more fully appreciate the power of the branch on index instructions.

Exercises
22.9.1.(3) Suppose c(GR2)=5 and c(GR3)=73. What will be left in GR2 after executing these
two instructions?
BXLE 2,2,*
SRL 2,1
More generally, if GR2 contains a small positive integer and GR3 contains a larger positive
integer, what will be in GR2? Are there limits on the value of c(GR3)?
22.9.2.(3) + What will be left in GR5 after executing these instructions?
LHI 5,1
BXLE 5,5,*

Initialize GR5 to +1
Do something interesting

Now, answer the same question for BXH.


22.9.3.(4) As in Exercise 22.7.6, the following code sequence tries to place in GR0 the number
of the leftmost bit in the positive nonzero number in GR1. Prove that it works correctly.
(Hint: consider the possible values of the two leftmost bits in GR1.)

348

Assembler Language Programming for IBM z System Servers

Version 1.00

Loop
ZBit
Done

LA
LR
SR
BXH
B
BXH
- - -

0,1
2,0
3,3
1,1,ZBit
Done
0,2,Loop

Initialize bit counter


... and bit count increment
Zero comparand
Skip if zero bit
Exit with bit number in GR0
Increment bit count and try again
Bit number now in GR0

22.9.4.(4) What values in GR1 will cause the instruction


BXH

1,1,Yes

to branch to the location named Yes?


22.9.5.(4) Repeat Exercise 22.9.4, but with a BXLE instruction.
22.9.6.(4) What values in GR0 and GR1 will cause the instruction
BXH

0,1,Yes

to branch to the location named Yes?


22.9.7.(4) Repeat Exercise 22.9.6, but with a BXLE instruction.
22.9.8.(2) + The operation of the branch on index instructions has often been described as
follows:
1. The increment is added to the index, and the sum replaces the index.
2. The new index is compared to the comparand to determine the branch condition.
How is this description different from ours, and when and why is this description incorrect?
Give an example showing how it would affect the actual operation of the branch on index
instructions.
22.9.9.(4) + This instruction sequence evaluates X**N (X N ) for 32-bit integer values of X and
N. The base value X is in GR3, and the exponent value N is in GR0. Determine the algorithm
used to evaluate the exponential; assume that no overflows occur.
XR
SRDL
BXH
ZeroBit MR
SRDL
BXLE
OneBit BXLE
LR
Square MR
SRDL
BXLE
MR
TestMore BXH
Finished - - -

1,1
0,1
1,1,OneBit
2,3
0,1
1,1,ZeroBit
0,1,Finished
5,3
4,5
0,1
1,1,TestMore
2,5
0,1,Square

Clear GR1 to zero


Shift low-order exponent bit to GR1
Branch if it was a 1-bit
Was a 0-bit, square work value
Shift another low-order bit for test
Branch if it s zero to square again
Br if remaining exponent bits all 0
More bits to do. Copy work value
Square work value
Move another bit for testing
Branch if it s zero
Otherwise multiply work into answer
Branch if any 1-bits remaining
Result is in GR3

You will find it very instructive to follow this instruction sequence for several values of the
exponent such as 1, 5, 8, 11, and 15.

Chapter VI: Addressing, Immediate Operands, and Loops

349

22.10. Summary
The loop-control instructions discussed in this section are summarized in Table 127.
Relative-Immediate Operand Length
16 bits
32 bits
BCR
BCRL

Operation
Branch on Condition (Relative)

Table 126. Branch relative on condition instructions

Branch on Count (Register)

Register Length
32 bits
64 bits
BCTR
BCTGR

Branch on Count (Indexed)

BCT

BCTG

Branch on Count (Relative)

BRCT

BRCTG

Branch on Index

BXH
BXLE

BXHG
BXLEG

Branch on Index (Relative)

BRXH
BRXLE

BRXHG
BRXLG

Operation

Table 127. Branch instructions for loop control

Instructions Discussed in this Section


The instruction mnemonics and opcodes are shown in the following table:
Mnemonic
BCT

Opcode
46

Mnemonic
BRCT

Opcode
A76

Mnemonic
BXH

Opcode
86

BCTG

E346

BRCTG

A77

BXHG

EB44

BCTGR

B946

BRXH

84

BXLE

87

BCTR

06

BRXHG

EC44

BXLEG

EB45

BRC

A74

BRXLE

85

BRCL

C04

BRXLG

EC45

The instruction opcodes and mnemonics are shown in the following table:
Opcode
06

Mnemonic
BCTR

Opcode
A74

Mnemonic
BRC

Opcode
EB44

Mnemonic
BXHG

46

BCT

A76

BRCT

EB45

BXLEG

84

BRXH

A77

BRCTG

EC44

BRXHG

85

BRXLE

B946

BCTGR

EC45

BRXLG

86

BXH

C04

BRCL

87

BXLE

E346

BCTG

Terms and Definitions

350

Assembler Language Programming for IBM z System Servers

Version 1.00

R3 |1

A notation referring to the general register containing the comparand of a branch on index
instruction. If the R3 operand is even, R3 |1 is the next higher odd-numbered register; and if
the R 3 operand is odd, R 3 |1 is that odd-numbered register.

index
A varying quantity used to control each iteration of a loop.
increment
A (normally) constant value used to update the value of the index for each iteration of a
loop.
comparand
A quantity to which the incremented index is compared to determine whether a loop should
be repeated.

Programming Problems
Problem 22.1. Write a program to print a formatted hexadecimal multiplication table.
Problem 22.2. Each section of this text starts with large block numbers showing the section
number. The blocks are 12 characters wide and 12 characters high.
Write a program that reads a single record containing up to 72 numeric digits, and print up to
10 block number digits at a time across the page, each separated from the preceding by 2
spaces. If more than 10 digits are provided on the input record, print 2 blank lines before each
succeeding group. If a space appears in the input record, leave that 10-character position blank
in the printed output.
Thus, if your input record contained only the three characters 1 2 (with a space between the
two digits), your printed output would look like this:
11
111
1111
11
11
11
11
11
11
11
1111111111
1111111111

2222222222
222222222222
22
22
22
22
22
22
22
22
22
222222222222
222222222222

Some other sections are headed with block letters. You will enjoy extending your program
to handle letters as well as digits.*

Such block-lettered pages were called banner pages, and were often used to separate fan-folded printer outputs for
one job from another.
Chapter VI: Addressing, Immediate Operands, and Loops

351

352

Assembler Language Programming for IBM z System Servers

Version 1.00

Chapter VII: Bit and Character Data

VV
VV
VV
VV
VV
VV
VV
VV
VV
VV
VV
VV
VV
VV
VV
VV
VV
VV
VV VV
VVVV
VV

IIIIIIIIII
IIIIIIIIII
II
II
II
II
II
II
II
II
IIIIIIIIII
IIIIIIIIII

IIIIIIIIII
IIIIIIIIII
II
II
II
II
II
II
II
II
IIIIIIIIII
IIIIIIIIII

In previous chapters we discussed instructions that manipulated data in byte, halfword, word, and
doubleword formats. The four sections of this chapter examine some more basic z System
instructions.
Section 23 shows how we can manipulate data consisting of single bytes and individual bits
within a byte.
Section 24 first introduces important concepts in using SS-type instructions. It then describes
frequently-used instructions used to process data involving large or variable numbers of bytes,
and introduces the powerful Execute instructions.
Section 25 examines instructions that process very long byte strings, and strings containing a
special character.
Section 26 discusses other character representations such as ASCII, Unicode and other
multiple-byte characters, and instructions to handle them.

Chapter VII: Bit and Character Data

353

23. Bit Data and Instructions

2222222222
222222222222
22
22
22
22
22
22
22
22
22
222222222222
222222222222

3333333333
333333333333
33
33
33
33
3333
3333
33
33
33
33
333333333333
3333333333

Instructions having an operand in the instruction itself are called immediate instructions: the
operand is immediately available from the Instruction Register, rather than from another register
or (more slowly) from memory. We saw examples of register-immediate operands in Section 21.
Here, the target operand is in memory, whereas the RI-type and RIL-type instructions in Section
21 refer to target operands in the general registers.

23.1. SI-Type Instructions


SI- and SIY-type instructions let you manipulate byte and bit data. They use an 8-bit immediate
operand contained in the second (I2) byte of the instruction, in the two formats shown in Tables
128 and 129.
opcode

I2

B1

D1

Table 128. SI-type instruction format

opcode

I2

B1

DL

DH

opcode

Table 129. SIY-type instruction format

The actions of the corresponding SI-type and SIY-type instructions are the same, so well describe
only the SI forms. (Remember: the SIY-type instructions support a signed 20-bit displacement,
while the SI-type instructions use an unsigned 12-bit displacement.)
The operand field is written as either
D1(B1),I2

or

S1,I2

showing the explicit and implied forms of address for the first operand.
The first operand of SI-type machine instruction statements typically refers to the name of a byte
in memory. The second operand must be a nonnegative absolute expression of value less than
256, so that it will fit into the I2 byte of the instruction.
Table 130 describes the behavior of the instructions; the first operand is the single byte at the
Effective Address.

354

Assembler Language Programming for IBM z System Servers

Version 1.00

Operation
Move

Mnemonic
MVI, MVIY

Action

CC set?
No

Operand 1  I2

AND

NI, NIY

Operand 1  Operand 1 AND I2

Yes

OR

OI, OIY

Operand 1  Operand 1 OR I2

Yes

XOR

XI, XIY

Operand 1  Operand 1 XOR I2

Yes

CLI, CLIY
TM, TMY

Operand 1 Compared to I 2
Test Selected Bits of Operand 1

Yes
Yes

Compare
Test Under Mask

Table 130. SI-type instruction actions

23.2. MVI Instructions


Table 131 lists the two Move Immediate instructions:
Op
92

Mnem
MVI

Type Instruction
SI
Move Immediate

Op
Mnem
EB52 MVIY

Type Instruction
SIY Move Immediate

Table 131. Move Immediate instructions

MVI stores its I2 operand into the byte at the Effective Address.
MVI
MVI
MVI
MVI

X,0
X,255
X,C Y
X,C

Set the byte


Set the byte
Store EBCDIC
Store EBCDIC

at X to zero
at X to all 1-bits
character Y at X
blank at X

Figure 184. Examples of the MVI instruction

MVI is often used to initialize a byte whose bits will be used as bit flags, or to store a character.
For example:
MVI
MVI

FlagByte,0
CrrgCtrl,C 1

Set all flag bits to zero


Printer carriage control for new page

Exercises
23.2.1.(1) What do you expect will happen if you write these instructions?
MVI
MVI
MVI

0(4),B000000000010101010
0(4),B000000000101010101
0(4),-1

23.3. NI, OI, and XI Instructions


Table 132 summarizes these six Storage-Immediate instructions:
Op
94
96
97

Mnem
NI
OI
XI

Type
SI
SI
SI

Instruction
AND Immediate
O R Immediate
X O R Immediate

Op
EB54
EB56
EB57

Mnem
NIY
OIY
XIY

Type
SIY
SIY
SIY

Instruction
AND Immediate
O R Immediate
X O R Immediate

Table 132. Logical Storage-Immediate instructions

Chapter VII: Bit and Character Data

355

The CC settings after NI, OI, and XI are shown in Table 133:
Operation
AND
OR
XOR

CC setting
0:
1:

all result bits are zero


result bits are not all zero

Table 133. CC settings by SI-type logical instructions

The logical operations of the NI, OI, and XI instructions are between corresponding bits of the
first and second operands, as we saw in Section 19. (You might want to review Figure 138 on
page 289.)
(1)
(2)

NI
NI

X,0
X,253

Same as MVI X,0 except CC set to 0


Sets bit 6 at X to 0 (see below)

Figure 185. Examples of the NI instruction

Sometimes it is better to use other types of self-defining term for the second operand; example (2)
could be written
NI

X,B11111101

which more clearly shows that bit 6 will be zeroed.


(3)
(4)

OI
OI

X,255
X,B00000010

Same as MVI X,255 except CC set to 1


Sets bit 6 at X to 1

(5)
LowerA

OI
DC

LowerA,C
C a

c(LowerA) now is C A
Lower case letter a

Figure 186. Examples of the OI instruction

XI

X,B0000010

Inverts bit 6 at X

Figure 187. Example of the XI instruction

Exercises
23.3.1.(1) Example (5) in Figure 186 claims that the OI instruction changes C a to C A . Is
this true? Why or why not?
23.3.2.(1) Write one instruction that will set the high-order and low-order bits of the byte at
Flags to zero without affecting any of the other six bits.
23.3.3.(1) Write one instruction that will set the high-order and low-order bits of the byte at
Flags to one without affecting any of the other six bits.

23.4. CLI Instructions


Table 134 shows the two Compare Immediate instructions:
Op
95

Mnem
CLI

Type Instruction
SI
Compare Immediate

Op
Mnem
EB55 CLIY

Type Instruction
SIY Compare Immediate

Table 134. Compare Immediate instructions

The CLI instruction logically compares the byte in memory to the eight-bit I2 operand as
unsigned integers. The result is indicated by the CC setting, shown in Table 135.

356

Assembler Language Programming for IBM z System Servers

Version 1.00

CC
0
1
2

Indication
Operand 1 = I 2
Operand 1 < I 2
Operand 1 > I 2

Table 135. CC settings after CLI instruction

Youll remember that the same settings are generated by the CL and CLR instructions, in
Table 74 on page 233.
The following statements would result in the indicated CC settings. We use literals for the first
operand so that both operand values are immediately visible.
CLI
CLI
CLI
CLI
CLI
CLI
CLI

=C A , X C1
=X 0 0 , 0
=C , B01000000
=X 1 , X 2
=C A,250
=C X , C X -1
=X 1 , X 0

CC
CC
CC
CC
CC
CC
CC

=
=
=
=
=
=
=

0:
0:
0:
1:
1:
2:
2:

c(Operand
c(Operand
c(Operand
c(Operand
c(Operand
c(Operand
c(Operand

1)
1)
1)
1)
1)
1)
1)

=
=
=
<
<
>
>

I2
I2
I2
I2
I2
I2
I2

Remember:
The first operand in a CLI comparison is always the byte in memory at
the Effective Address.
We can rewrite the example in Figure 167 on page 333 (and its variations) to blank out the
special characters in the string at Str, now using CLI and MVI instructions. Well start at the
right (high-addressed) end and scan from right to left.
LA
LA
CLI
JNL
MVI
AlfaNum JCT
Next

1,80
2,Str-1(1)
0(2),C a
AlfaNum
0(2),C
1,Next

Initialize loop count to string len


Form character s indexed address
Compare addressed character with a
Skip blanking if not less than a
Blank out if not alphanumeric
Count down and loop

Figure 188. A simpler loop to scan and replace characters

Because SI-type instructions cannot be indexed, the LA instruction named Next generates the
memory address for the character to be tested. The CLI instruction then compares the byte in
memory at that address to the immediate operand C a . If the byte in memory contains a bit
pattern with value greater than or equal to C a , the following JNL instruction will branch around
the MVI instruction. If the branching condition is not met, the MVI stores an EBCDIC blank
character into the character string. These two SI-type instructions have simplified the previous
examples of the same process.

Exercises
23.4.1. + (1) Suppose the length of a string of bytes starting at Data is not known, but we know
that the end of the string is marked with a byte of all 1-bits. Write a code sequence which will
leave the length of the string in GR1.
23.4.2.(1) + In solving Exercise 23.4.1, a student wrote these instructions:
Loop

SR
LA
CLI
BNE

1,1
1,1(,1)
Data-1(1),X FF
Loop

Initialize index
Increment by one
Test the byte
Branch if not all 1-bits

Will this work?

Chapter VII: Bit and Character Data

357

23.4.3.(2) + An 80-byte record starts at Record. Using CLI, find the address of the last nonblank character; store its address at LastChAd and store the length of the initial character
string (from the first character to the last nonblank) at DataLen.
23.4.4.(2) Write an instruction that will set the Condition Code to 1 without changing any data
or referencing any register, and without referencing any constants in storage.
23.4.5.(2) Write an instruction that will set the Condition Code to 2 without changing any data
or referencing any register, and without referencing any constants in storage.
23.4.6.(1) + A programmer tested a byte at Char for the lower case letter f, and wrote
CLI

Char,f

He wasnt satisfied with the result; find two ways to help him.
23.4.7.(2) Write an instruction that will set the Condition Code to 0 without changing any data
or referencing any register, and without referencing any constants in storage.

23.5. Test Under Mask Instructions


Table 136 shows the two Test Under Mask instructions:
Op
91

Mnem
TM

Type Instruction
SI
Test Under Mask

Op
Mnem
EB51 TMY

Type Instruction
SIY Test Under Mask

Table 136. Storage-Immediate instructions

The Test Under Mask instruction is very useful in applications that examine bits. Because the
CPU cannot directly address individual bits, data in bit form must be treated differently from data
in byte or word form.
The I 2 (immediate) operand of a TM instruction is a mask indicating which bits of the addressed
byte are examined: wherever a 1-bit appears in the mask, the corresponding bit position in the
first operand is examined, and wherever a 0-bit appears in the mask, the corresponding bit of the
memory operand is ignored. The result of the examination is indicated in the Condition Code, as
shown in Table 137.
CC
0
1
3

Indication
Bits examined are all zero, or mask is zero
Bits examined are mixed zero and one
Bits examined are all one

Table 137. CC settings after T M instruction

If the I2 mask is zero (meaning that no bits are tested), the CC is set to zero. The following
examples illustrate uses of the TM instruction.
1. Branch to Minus if the fullword integer at Num is negative. (This technique can be used to
avoid loading anything into a register.)
TM
JO

Num,X 8 0
Minus

Test leftmost bit at Num


Branch if a 1-bit

2. Branch to Even if the fullword integer at Num is even.


TM
JZ

Num+L Num-1,1
Even

Test rightmost bit of the word


Branch if bit is zero

3. Branch to Mixed if the bits of the byte at BB are not all zeros or all ones.
TM
JM

358

BB,255
Mixed

Test all eight bits


Branch if mixed zero and one

Assembler Language Programming for IBM z System Servers

Version 1.00

4. Branch to Small if the value of the halfword integer at HNum is between 512 and + 511: that
is, if the leftmost seven bits of the integer are all 0s or all 1s.
TM
BC

HNum,X FE
9,Small

Test leftmost seven bits


Branch if bits all zero or all one

The NI, OI, XI, and TM instructions let you set and test on-off and yes-no indicators in a
program. For example, as in Figure 169 on page 334, suppose we wish to add the three fullword
integers stored beginning at Q, and after all additions are done, branch to NoErr if no overflows
occurred and to Error if one or more overflows occurred.

NextA

Flag
Q

NI
Flag,X FE
L
0,Q
A
0,Q+4
JNO NextA
OI
Flag,1
A
0,Q+8
JO
Error
TM
Flag,1
JZ
NoErr
JO
Error
- - DS
X
DS
3F

Set indicator bit for no overflows


Get first integer
Add second integer
Branch if no overflow
Set overflow bit to 1 ( on )
Add third integer
Branch if overflow
Otherwise examine overflow bit
If bit was zero, no overflows
If one, overflow occurred
Overflow flag byte
Integers to be added

Figure 189. Setting an overflow-indication flag bit

The OI instruction ORs a 1-bit into the rightmost bit position of the byte named Flag, setting it
to a 1. Only the rightmost bit of the byte is modified, so the remaining seven bits could be used
to indicate other conditions in the same program.
As another example of these instructions, suppose we have a list of N halfword integers stored at
List, where the positive nonzero fullword integer N is stored at NN. We must add the elements of
the list, except that alternate elements of the list are added twice. Whether the even-numbered or
the odd-numbered elements are added twice is determined by the setting of the rightmost bit of
the byte named Switch: if the bit is 1, the odd-numbered elements (beginning with the first) are
added twice.

Load

Once

NN
Switch

LA
4,List
L
3,NN
SR
6,6
LH
5,0(,4)
AR
6,5
TM
Switch,1
JZ
Once
AR
6,5
LA
4,2(,4)
XI
Switch,1
JCT 3,Load
- - DS
H
DC
B 0

Initial list address in GR4


Number of elements in GR3
Initialize sum to zero
Get a halfword list element in GR5
Add to sum once
Test switch bit
Branch if zero, add only once
Add a second time
Increment list address by 2
Invert switch bit
Get next list element
Number of halfwords in the list
Byte with the switch bit

Figure 190. Adding alternate list elements twice

Since the XOR of a 1-bit and any other bit inverts its value, the XI instruction alternately sets the
switch bit to one and zero. The TM instruction examines only the rightmost bit of Switch, and
the branching condition is met if the bit is zero.

Chapter VII: Bit and Character Data

359

Exercises
23.5.1.(2) In example 4 following Table 137 on page 358, show that if the leftmost seven bits
of a halfword integer are all zeros or all ones, then the value of the integer lies between 512
and + 511.
23.5.2.(3) + Show that the operation of the TM instruction can be correctly described as
follows:
1. Form internally the logical AND of the first operand and I2. If the result is zero, set the
CC to zero and go to the next instruction.
2. If the result of step 1 is nonzero, form internally the logical XOR of the result byte from
step (1) and I2. If the new result is zero, set the CC to 3 and go to the next instruction.
3. Otherwise set the CC to 1, and go to the next instruction.
23.5.3.(2) Write an instruction that will set the Condition Code to 3 without changing any data,
and without referencing any register.
23.5.4.(2) + A programmer needed to test the sign of a 4-byte binary integer stored at BIN
without using any registers, and then branch to POS if the number was not negative. He wrote:
TUM
BP

BIN,80
POS

Test Under Mask for sign bit


Branch if nonnegative

Why didnt this work? Repair his instructions to work correctly.


23.5.5.(1) Use a TM instruction to set the Condition Code to zero without referencing any registers and without referencing any constants in storage.
23.5.6.(1) + In example 3 of Section 23.5, can the extended mnemonic BNM be used to mean
Branch if Not Mixed? Why?

23.6. Bit Data


The above examples illustrated SI-type instructions used mainly for control purposes. Another
important application is to manipulate data in bit form, data that takes only two values. For
example, suppose that the record of a person carrying automobile insurance requires the following
yes-no information: (1) age less than 25? (2) male? (3) driver-training course completed? (4)
married? (5) any previous claims? (6) assigned risk? Let the yes answers be represented by
1-bits in the byte named Status. Here are ways we could perform the given tasks.
1. The policy-holder has passed his 25th birthday.
Under25 Equ
NI

B10000000
Define the young-person bit
Status,X FF -Under25
He s getting older now

2. The policy-holder has just married.


Married Equ
TM
JO
OI

B00010000
Status,Married
Bigamy
Status,Married

Define the married-person bit


Did he say he was already married?
(You never know!)
Indicate he s married now

3. The policy-holder has submitted a claim. If it is the first, branch to Tsk; otherwise, branch to
TskTsk.
HasClaim Equ
TM
JO
J

360

B00001000
Status,HasClaim
TskTsk
Tsk

Define the made-a-claim bit


Test if he claimed previously
Yes, must be accident-prone
Accidents can happen to anyone

Assembler Language Programming for IBM z System Servers

Version 1.00

4. If the policy-holder is single, male, under age 25, and has not completed a driver-training
course, branch to HighCost. As this example shows, you can test more than one bit with a
single instruction:
Trained Equ
Male
Equ
TM
JNZ
TM
JO
Next
- - -

B00100000
Define the driver-trained bit
B01000000
Define the male-driver bit
Status,Married+Trained Test Married and Trained
Next
Branch if both not zero
Status,Male+Under25
Test age and sex
HighCost
If young untrained male, branch
Rest of program

5. If the policy-holder is an assigned risk, indicate that he has previous claims if he also has no
driver training.
Assigned Equ
TM
JZ
TM
JO
OI
Next
- - -

B00000100
Status,Assigned
Next
Status,Trained
Next
Status,HasClaim

Define the assigned-risk bit


Check assignment status
Branch if not assigned
Check driver training
Branch if completed
Otherwise set claim bit on
Rest of program

6. If the policy-holder is married, or has completed driver training, branch to LowRisk.


TM
JM

Status,Married+Trained Check status


LowRisk
Branch if either but not both

These examples use EQU statements to assign symbolic names to values representing bits. Unfortunately, this is not the same as assigning a name to a bit itself; languages like PL/I have a BIT
data type, but Assembler Language does not.140

Exercises
23.6.1.(2) Write instructions to format the bits in the byte at BitData as eight EBCDIC 0 and 1
characters starting at BitChars.
23.6.2.(1) + In Example 6 of Section 23.6, can the extended mnemonic BNZ be used?
23.6.3.(1) + Suppose we defined a bit with the statement
Over25

EQU

X 8 0

How would you modify the statement in Example 1 of Section 23.6 to use this new definition?

23.7. Bit-Naming Problems (*)


To illustrate a common problem using bit data, suppose we have defined two bytes containing
flag bits, as follows:
Flag1
Bit0
Flag2
Bit1

DS
Equ
DS
Equ

X
X 8 0
X
X 4 0

Define a byte containing flag bits


Name the value of bit 0 (leftmost)
Another flag byte
And a value for bit 1 (next)

Under normal circumstances, we would refer to the bits with a code sequence like

140

You can use macro instructions to implement a bit-defining and bit-handling language that names bits and protects
against referring to them accidentally.
Chapter VII: Bit and Character Data

361

TM
JZ

Flag1,Bit0
SomeCode

Test a bit in flag byte


Go do something if zero

The result of executing this TM instruction could easily be confused with


TM
JZ

Flag1,Bit1
MoreCode

Test bit 1 (in the wrong byte!)


Branch if zero

TM
JZ

Flag2,Bit0
WhatCode

Test bit 0 (in the wrong byte!)


Branch if zero

or

If there is no way to force the definitions of Bit0 and Bit1 to be associated with their
owning bytes, then if we use the wrong byte name we will test or manipulate the wrong bits. If
we execute the instruction
OI

Flag2,Bit0

we will set a bit in the wrong byte. Mistakes like this are not uncommon.
Here is a simple technique that avoids this naming problem: define MyBit and HisBit with the
following statements:
MyBit
HisBit

DS
DS
DS
DS

0XL(X 8 0 )
X
0XL(X 4 0 )
X

Define location and length attribute


Reserve actual storage
Define location, new length attribute
Reserve actual storage

Figure 191. Defining bit names safely

The zero duplication factors mean that no storage will be reserved by the two bit-definition statements. The symbols MyBit and HisBit have the value attributes of the following byte, and their
length attributes can be used to indicate which bit within each byte is desired. We then test the bit
with an instruction sequence like
TM
JZ

MyBit,L MyBit
YourCode

Test desired bit in correct byte


Branch if MyBit is zero

Figure 192. Using safely-defined bit names

and no reference will be made to (now nonexistent) symbols naming the bytes containing the
MyBit and HisBit bits. Referring to MyBit only by its name and length attribute greatly reduces
the chances of incorrectly referencing bit data.
Some IBM macros define bit names by their position in a byte:
Bit0
Bit1
Bit2
Bit3
Bit4
Bit5
Bit6
Bit7

Equ
Equ
Equ
Equ
Equ
Equ
Equ
Equ

B10000000
B01000000
B00100000
B00010000
B00001000
B00000100
B00000010
B00000001

Bit
Bit
Bit
Bit
Bit
Bit
Bit
Bit

0
1
2
3
4
5
6
7

If you use definitions like these to set a specific bit at a known position in a byte, the bit name
indicates the bits position. If, however, the bit is intended to have a meaning like Initialization
Complete or End of Input, it is much better practice give the bit a meaningful name:
InitDone Equ
EndInput Equ

362

B00000001
B00000010

If 1, initialization completed
If 1, no further input exists

Assembler Language Programming for IBM z System Servers

Version 1.00

Exercises
23.7.1.(2) Suppose the definition of MyBit in Figure 191 on page 362 had been written
MyBit

DS
Equ

B
*-1,X 8 0

Would the instructions in Figure 192 on page 362 work correctly? Why or why not?
23.7.2.(2) + Using the bit-naming technique illustrated in Figure 191 on page 362, define two
bits named BitA and BitB in a single unnamed byte. Then, write code sequences to do the
following:
1.
2.
3.
4.

Set BitA and BitB to zero.


Invert the value of BitB.
Branch to Both if BitA and BitB are both one.
Leave in GR0 the value of BitA+BitB (that is, a number which is 0, 1, or 2 depending on
whether neither, either, or both bits are 1).

23.8. A Conversion Example


As a final example using SI-type instructions, suppose there is a fullword integer stored at NN
that we want to convert to a character string of printable decimal digits. The sign of the number
must precede the first digit; if the number is zero, the characters +0 should be placed at the righthand end of the character string. Because a fullword integer can contain a value at most ten digits
long in its decimal representation, we will reserve eleven bytes at CharVal for the result. We use
the conversion method described in 2.3. Converting Integers from One Base to Another (*)
on page 21.
The method shown here works, but is clumsy and complex. We will see when we examine
packed decimal data in Section 30 that other instructions greatly simplify this task.
D

EQU
LA
Blank
LA
MVI
JCT
LA
L
LPR
CnvtLoop SR
D
STC
OI
BCTR
LTR
JP
MVI
TM
JO
MVI
AllDone - - CharVal DS
NN
DS

10
2,D
3,CharVal-1(2)
0(3),C
2,Blank
3,CharVal+D
1,NN
1,1
0,0
0,=F 1 0
0,0(,3)
0(3),X F0
3,0
1,1
CnvtLoop
0(3),C -
NN,X 8 0
AllDone
0(3),C +
CL(D+1)
F

Max number of digits


First, blank out result area
Construct byte address
Store blanks in first D bytes
Branch back (D-1) times
Set up address of rightmost digit
Get number to be converted
Take its magnitude
Clear high-order register
Generate a digit by division
Store the remainder digit
Form correct EBCDIC representation
Move character pointer left by 1
If quotient is zero, finished
If nonzero, generate more digits
Assume value was -, put sign
Check actual sign of argument
Branch if it was indeed Sign is +, store character
Rest of program
Output character string, with sign
Number to be converted

Figure 193. Converting a binary integer to characters

Chapter VII: Bit and Character Data

363

23.9. Instruction Modification (*)


In olden days, it was sometimes thought to be useful (or clever) to change the mask field of a
conditional branch instruction, so that it alternately contained B1111 and B0000, causing an
unconditional branch to alternate with a no-operation. The example in Figure 190 on page 359
might be rewritten as in Figure 194 to use this technique.
L
LA
AR
SR
SR
SR
OI
TM
JZ
NI
Add
AH
Brnch
BC
AH
FlipMask XI
BXLE
ST

1,NN
0,2
1,1
1,0
2,2
3,3
Brnch+1,X F0
Switch,1
Add
Brnch+1,X 0F
3,List(2)
0,FlipMask
3,List(2)
Brnch+1,X F0
2,0,Add
3,Result

Get number of elements to be added


Set up increment of 2 in GR0
2 * N
2 * (N-1) = comparand for BXLE
Initialize index in GR2 to zero
Same for sum, in GR3
Set for single add on first pass
Check to see if setup is correct
Jump if branch setup is correct
Otherwise set up to add twice
Add a term from the list
Mask field alternated by XI inst n
Add again if required
Invert branch mask bits again
Count and loop
Store answer

Figure 194. Adding alternate list elements twice, with program modification

The mask field of the BC instruction is addressed as Brnch+1, because Brnch is the name of the
byte containing the operation code. Then, the instructions that manipulate the mask bits are
written to leave unchanged the index register specification digit of the second byte of the instruction at Brnch, because we do not want to modify the index digit.
Modifying an instruction in memory is now considered a terrible programming practice, for these
reasons:
1. The coding tends to be more difficult to understand, because you wont know with any certainty what is done by a given instruction if it could be modified by other parts of the
program.
2. Debugging the program is more difficult, since it is usually easier to keep track of data (such
as at Switch in Figure 190 on page 359) than parts of instructions. What you see in
memory might not match your program listing. (Its no longer the program you wrote!)
3. If you must rewrite part of a program, it may be difficult to find all the instructions that
modify or are modified by others.
4. If, as many programs are, the program must be re-enterable (a property requiring no selfmodification), such techniques are forbidden.
5. Modern processors assume that any instruction modifying memory is referring to data, so
they prefetch large groups of instructions for faster decoding. If the CPU discovers that you
have stored into the part of the program it prefetched, it must discard its initial analysis and
re-fetch again. This can slow your program considerably.
Important Advice
Avoid self-modifying programs.
Most instruction modification needs are best handled by the Execute instruction, which well see
in Section 24.11.
To show that the example in Figure 194 need not rely on program modification, the code
segment in Figure 195 does the same calculation more rapidly and safely.

364

Assembler Language Programming for IBM z System Servers

Version 1.00

Once
Twice

Next

L
BCTR
ALR
LA
SR
SR
TM
JO
AH
JXH
AH
AH
JXLE
- - -

1,NN
1,0
1,1
0,2
3,3
2,2
Switch,1
Twice
3,LIST(2)
2,0,Next
3,LIST(2)
3,LIST(2)
2,0,Once

Set up JXLE comparand N in GR1


N-1
2 * (N-1) = 2N-2 in GR1
Increment in GR0
Initialize sum to zero
Same for index
Test for first term adding twice
Branch if bit is 1, meaning yes
Add a term once
Increment index, branch if done
Add a term
...twice
Increment index and loop
Continuation of program

Figure 195. Adding alternate list elements twice, without program modification

Study the actions of the JXH and JXLE instructions carefully!

Exercises
23.9.1.(3) The following fragment of code was discovered in a trash can. By examining the
sequence of values contained in R4, determine what the code does.

VA

LA
6,2
LA
4,5
AR
4,6
SLL 6,1
XI
*-4,X 0 1
- - B
VA

Test number

Flip-flop
Some undecipherable material

23.9.2.(2) Show that the SI-type OI, NI, and XI instructions in Figure 194 on page 364 do not
modify the index register specification digit of the instruction named Brnch.
23.9.3.(2) A widely used program (HASP) contained an instruction sequence like the following:

Flag

OI
Flag+1,1
- - TM
Flag+1,0
BNZ FlagSet

Set a flag bit


Test the flag byte
Branch if not zero

Elsewhere in the program, other instructions modified the byte at Flag+1. Why would anyone
write a program this way?

23.10. Summary
The instructions weve discussed in this section are summarized in Table 138.

Chapter VII: Bit and Character Data

365

Move Immediate

Operand 1
12-bit displacement
20-bit displacement
MVI
MVIY

AND Immediate

NI

NIY

I2

O R Immediate

OI

OIY

I2

X O R Immediate

XI

XIY

I2

Compare Immediate

CLI

CLIY

I2

Test Under Mask

TM

TMY

I2

Function

Operand 2
I2

Table 138. Storage-Immediate instructions

Instructions Discussed in this Section


The instruction mnemonics and opcodes are shown in the following table:
Mnemonic
CLI

Opcode
95

Mnemonic
NI

Opcode
94

Mnemonic
TM

Opcode
91

CLIY

EB55

NIY

EB54

TMY

EB51

MVI

92

OI

96

XI

97

MVIY

EB52

OIY

EB56

XIY

EB57

The instruction opcodes and mnemonics are shown in the following table:
Opcode
91

Mnemonic
TM

Opcode
96

Mnemonic
OI

Opcode
EB54

Mnemonic
NIY

92

MVI

97

XI

EB55

CLIY

94

NI

EB51

TMY

EB56

OIY

95

CLI

EB52

MVIY

EB57

XIY

Terms and Definitions


reenterable
A program is reenterable if
Its execution can be suspended, then executed by other processes, and then resumed by
the original process with correct behavior for all processes.
It can be executed simultaneously by multiple processes, with correct behavior for all
processes.
self-modification
A program modifies its instructions or constants. Considered a very poor programming practice with severe execution-time performance penalties, and forbidden if the program must be
reenterable.141

141

366

Technically, a self-modifying program can be reenterable if every execution instance makes exactly the same modifications. This is considered an even poorer practice.
Assembler Language Programming for IBM z System Servers

Version 1.00

24. Character Data and Basic Instructions

2222222222
44
222222222222
444
22
22
4444
22
44 44
22
44 44
22
44 44
22
44444444444
22
444444444444
22
44
22
44
222222222222
44
222222222222
44

The instructions weve seen thus far have involved at most one memory operand; now well investigate basic SS-type instructions that work with two operands in memory having variable lengths.
We will also describe Execute instructions that help you handle varying-length data.

24.1. Basic SS-Type Instructions


Well start with the instructions in Table 139.
Op
D2
C80

D4
D7
DD

Mnem
Type Instruction
MVC
SS
Move [Characters]
MVCOS SS
Move [Characters]
with Optional Specifications
NC
SS
AND [Characters]
XC
SS
X O R [Characters]
TRT
SS
Translate and Test

Op
E8
D5

Mnem
Type Instruction
MVCIN SS
Move [Characters] Inverse
CLC
SS
Compare Logical [Characters]

D6
DC
D0

OC
TR
TRTR

SS
SS
SS

O R [Characters]
Translate
Translate and Test Reverse

Table 139. Basic character-handling instructions

The word Characters is enclosed in square brackets because the z/Architecture Principles of
Operation description of those instructions omits that word from the name of the instruction, even
though its implied by the instruction mnemonics. While often used to manipulate character data,
they simply process strings of bytes, whether or not they represent characters.
Because the lengths of the operands are not implied by the instruction (as we saw for instructions
like L and LH), the number of bytes to be processed must be specified somehow. The
instructions in Table 139 have the format illustrated in Table 140:
opcode

B1

D1

B2

D2

Table 140. Format of single-length SS-type instructions

Chapter VII: Bit and Character Data

367

These instructions are all 6 bytes long, have two Addressing Halfwords, and their second byte
(L) specifies the machine length or Encoded Length142 of the operand or operands; well explain
Encoded Length shortly.
The Assembler Language syntax of these instructions is shown in Figure 196:
mnemonic D1(N,B1),D2(B2)
Figure 196. Assembler Language syntax of basic SS-type instructions

where N, the Length Expression (LE) (also known as the program length) is the number of bytes
the instruction will process. (For some of these instructions, at most N bytes.)
Why do we use L in the object code format, but N in the machine instruction statement format?
They are different: L is one less than N (unless N is zero, in which case L is also zero). This is
important!
There are good reasons for this difference:
programmers want to specify N, the true number of bytes involved;
the CPU must sometimes know the address of the rightmost byte of an operand; that address
is the operands Effective Address (its starting address) plus L;
it makes no sense to operate on zero bytes (thats what NOP instructions are for!).
When you code a value N in a machine instruction statement, the Assembler converts it to the
correct value of L in the generated object code.
Except for TRT, the only reference to or use of the general registers by these nine instructions is
for operand addressing. The result of each operation is found in the first operand location, except
for TRT and CLC, which modify no data in memory.
Important Notation Difference!
The z/Architecture Principles of Operation illustrates SS-type instructions
like MVC this way, where the two uses of L can be very confusing:
CLC D1(L,B1),D2(B2)

[SS]

D5 L
B1
D1
B2
D2

Both the Assembler Language syntax with operands D1(L,B 1),D 2(B 2)
and the format of the assembled instruction use the same letter L to
indicate the operand length! But the two numbers are not the same: the
first L in the Assembler Language statement is the Length Expression
(that we call N, the true number of bytes to process), while the second
L in the assembled instruction is the Encoded Length, one less than the
true length!
When you refer to the z/Architecture Principles of Operation, be very
careful to distinguish the two uses of L.

142

368

The Encoded Length byte is sometimes called the machine length or Length Specification Byte.
Assembler Language Programming for IBM z System Servers

Version 1.00

24.2. Operand Specifications


As illustrated on page 116 in Section 9.9, you could write a typical SS-type instruction as
MVC

Field(5),Area

The operand field specifies three quantities: the implied addresses of the operands named Field
and Area, and the number of bytes to be moved, 5.
Because the symbols Field and Area must be resolved into addressing halfwords, we must derive
five operand-dependent quantities: the Encoded Length L and the base and displacement of the
two addressing halfwords. The base and displacement of each addressing halfword is assigned by
the Assembler from an implied address.
The number L in the Encoded Length byte by the Assembler is derived from the Length
Expression (N) in your machine instruction statement. The LE may also be explicit or implied;
well discuss implied Length Expressions in Section 24.3.
You will remember from Section 8.5 on page 104 that machine instruction statement operands
can take any of these three forms:
expr

expr(expr)

expr(expr,expr)

where the third format can sometimes be written expr(,expr).


For most of the instructions weve seen so far, these formats are used for the first four instruction
types shown in Table 141, where S is our notation for an implied address, an absolute or relocatable expression. In the last row, we see that SS-type instructions introduce new possibilities:
Instruction
Type

Operand Format

expr
expr(expr)
RR
register
invalid
RX
S
S(X)
RS
S
D(B)
SI
S or immediate
D(B)
SS
S
S(N)
Table 141. Instruction types and operand formats

expr(expr,expr)
invalid
D(X,B)
invalid
invalid
D(N,B)

expr(,expr)
invalid
D(,B)
invalid
invalid
D(,B)

In particular, notice that for SS-type instructions, the third operand format does not resolve to
D(X,B)!
Suppose we want to move 23 bytes from the area of memory beginning at AA to the area beginning at BB. We could write
MVC

BB(23),AA

Move 23 bytes from AA to BB

where the addresses of the two operands are implied. For SS-type instructions, the number in
parentheses is not an index register specification, but an explicit Length Expression. Its value, 23,
is the number N of bytes to be moved.
There are several ways to specify the Length Expression, as shown in Table 142. (Remember
that S 1 and S 2 are our notations for the implied addresses of the first and second operands.)
Explicit Length
S1(N),S 2
D 1(N,B 1),S2
S1(N),D 2(B 2)
D 1(N,B 1),D 2(B 2)
Table 142. SS-type instructions with explicit length

Chapter VII: Bit and Character Data

369

An explicit Length Expression is simply an expression you write in your machine instruction
statement. Suppose we again want to move 23 bytes from AA to BB and that if GR9 is used as a
base register, the displacements for AA to BB will be X125 and X47D respectively. Then, Figure
197 shows how we could use any of the following four instructions, corresponding to the four
operand formats in Table 142:
MVC
MVC
MVC
MVC

BB(23),AA
X47D ( 2 3 , 9 ) , AA
BB(23),X125(9)
1149(23,9),293(9)

S1(N),S2
D1(N,B1),S2
S1(N),D2(B2)
D1(N,B1),D2(B2)

Figure 197. Examples of SS-type instruction operands

Equivalent decimal and hexadecimal self-defining terms are used for the displacements D1 and D 2.

Exercises
24.2.1.(1) What is the difference between an implied address and an implicit address?

24.3. Implied Lengths


Implied Length
S1,S2
D 1(,B1),S2
S1,D 2(B 2)
D 1(,B1),D 2(B 2)
Table 143. SS-type instructions with implied length

Note that if the address of the first operand is specified explicitly and the Length Expression is
implied, the comma following the left parenthesis is very important.
As a reminder, the words explicit and implied that we saw in Section 11.4 were used define
constants with explicit and implied lengths:
IMPLIED DC
EXPLICIT DC

F 8
FL5 8

Implied length = 4 bytes


Explicit length = 5 bytes

and the same words describe addresses:


ImplAddr L
ExplAddr L

0,=F 6
0,X D4 ( 0 , 7 )

Implied address, resolved by Assembler


Explicit address, specified by you

In this section, we use the same words to describe Length Expressions: you can provide an explicit
Length Expression, or you can let the Assembler derive the value of an implied Length
Expression.
We usually dont want to have to specify an explicit Length Expression, particularly when the
number of bytes should be apparent from the operands. For example, suppose the symbol BB is
defined in a DC or DS statement like this:

BB

MVC BB,=120C
- - DS
CL23

Set field at BB to blanks


Field of length 23 bytes

Even though the second operand is 120 bytes long, if more than 23 bytes are moved by the MVC
instruction, then the data or instructions following the byte at BB+22 could be overwritten! Thus
the length of the string of bytes to be moved should be determined from the first, or receiving,
operand, rather than the second.

370

Assembler Language Programming for IBM z System Servers

Version 1.00

This is what the Assembler does. If no explicit Length Expression is given, the Length Attribute
of the first operand is used as the value of the Length Expression: it is implied by the operand. In
this example, the length attribute of the symbol BB is 23.
If the first operand is an expression rather than a single term, the length attribute is that of the
leftmost term in the expression. Thus, with BB defined as above, if we write
MVC

BB-4+X 5 -1,=120C

then the length attribute of the first operand is 23, but if we write
MVC

X5+BB-5,=120C

the length attribute of the first operand is 1 because the length attribute of a self-defining term is
always 1 (see Section 7.6).
Now, suppose we want to use an implied length, but with an explicit first operand address. The
value of the LE cannot be immediately associated with a symbol that names an area of the
program using its length attribute. Unlike the examples in Figure 197, knowing the base and
displacement of the symbol BB (9 and X47D ) does not necessarily give the correct Length
Expression when an implied length must be found. If an explicit base and displacement are given,
the value of the LE is the length attribute of the displacement expression. Thus
MVC

X47D ( , 9 ) , AA

specifies an implied length of 1 rather than 23, because X47D is a self-defining term. Using an
explicit address and an implied length is very rare; its much better to use a Length Attribute Reference, which well discuss in Section 24.4.
These rules are summarized in Table 144. The last column shows how the Length Expression is
determined for the four possible forms of the first operand. (L.A. is an abbreviation for
Length Attribute, to be described in the following Section 24.4.)
First operand form
S1
S1(LE)
D 1(,B1)
D 1(LE,B 1)

Address specification
implied
implied
explicit
explicit

Length Expression
implied
explicit
implied
explicit

Length used
L.A. of S1
LE
L.A. of D 1
LE

Table 144. Determining the Length Specification Byte

Advice: Use Implied Lengths


Wherever possible, use implied lengths and let the Assembler derive the
Length Expression for you. If the length of a data field changes, the
Assembler will recalculate the Length Expression; this is safer and much
more convenient than updating explicit Length Expressions manually.

Exercises
24.3.1.(1) How many bytes will be moved by these instructions? What values will you find in
the first operand fields?
(1)
A

MVC
DS

A,=X01020304050
H

(2)
B

MVC
DS

B,=CL6 ABCDEF
BL4

(3)

MVC

C(3),=F 2

24.3.2.(2) + What are the formats of each of these possible operands when used as (a) the first
operand, and (b) the second operand of an MVC instruction?
Chapter VII: Bit and Character Data

371

(1) 7(4) (2) 24(6,12) (3) A(B) (4) 5(,1)


24.3.3.(2) + The paragraph following Table 141 on page 369 says that the comma following the
left parenthesis is very important in some situations. Why?

24.4. Symbol Length Attribute References


You can specify an explicit base and displacement, and still use an implied length. We could have
written
MVC

BB-BB+X47D ( , 9 ) , AA

and the length attribute of the displacement expression is the length attribute of BB, but this is
cumbersome and confusing. We can rewrite this example to use an explicit base and displacement, in the improved form
MVC

X47D ( L BB,9),AA Length Expression = L BB

Figure 198. SS-type instruction using a Length Attribute reference

It is almost always better to use a Symbol Length Attribute Reference, which is one of the terms
we described when examining expressions in Section 8.1.
A Symbol Length Attribute Reference is written as the letter L followed by an apostrophe followed by a symbol, as in L BB. It is an absolute term with value equal to the length attribute of
the symbol. Because symbols can be defined in several ways, the following rules may be helpful:
1. If the symbol was defined in an EQU statement with * or a self-defining term in the operand
field, its length attribute is one. However, as noted in Section 8.4 on page 102, if you specify
a second operand in the EQU statement, that value will be used as the Length Attribute of
the symbol. For example, if you define the symbol XXX in this EQU statement,
XXX

Equ

*,13

then XXX will have the value of the current Location Counter, and length attribute 13.
2. The length attribute of a literal is defined; thus
MVC

BB(L=C RAY ) , = C RAY

(while clumsy) is valid; its better to define a constant named by a symbol, and then use the
length attribute of the symbol:

RAY

MVC BB(L RAY),RAY


- - DC
C RAY

3. The length attribute of a Location Counter Reference (*) is the length of the machine
instruction in which it appears. Thus MVC BB(L *),AA assigns length attribute six, the length
of the MVC instruction.
The length attribute of a symbol naming a macro-instruction depends on the code it generates.

Exercises
24.4.1.(2) Can you find a way to specify an implied Length Expression whose value is zero?
24.4.2.(2) Is it possible to specify the length attribute of an expression using the L notation?

372

Assembler Language Programming for IBM z System Servers

Version 1.00

24.5. The Encoded Length L (*)


Now that we know how to write SS-type instruction statements with any Length Expression we
need, we will review what actually goes into the machine language instruction. As we noted in
Section 24.2, the value of the Encoded Length isnt necessarily the same as the value of the
Length Expression. Heres why.
Because the Length Specification Byte is a single byte, it can have any value between 0 and 255;
these actually specify operand lengths between 1 and 256. This is due to two factors:
Every SS-type instruction always operates on at least one byte.
All the instructions in Table 139 on page 367 except MVCIN and TRTR process data from
left to right in order of increasing addresses.

For left-to-right instructions, the CPU must calculate the address of the last byte of each
operand to check for possible memory-access violations.

Similarly, MVCIN, TRTR, and some other instructions process data from right to left, in
order of decreasing addresses, starting at the rightmost byte.

In both cases, the CPU must compute the addresses of the leftmost and rightmost bytes of the
operand. It is simplest to locate the rightmost byte by adding the Encoded Length L to the
effective address of the operand; if there are N bytes in a string starting at address A, its rightmost byte is at address A+N 1 = A+L.
Thats why the Encoded Length has the value of the Length Expression minus 1.
We usually dont care about this distinction, because we let the Assembler determine the needed
quantities from the operands of the instruction statement. However, at execution time we may
need to calculate the number of bytes to be manipulated, so its important to understand this
relationship between the Encoded Length and the actual number of bytes involved. An illustration (showing a bad way to do this) is given in Example 4 of Section 24.6; the right way to do
this is discussed in Section 24.11.
Thus, the Encoded Length is a number one less than the value of the Length Expression, unless
an explicit length of zero is given, in which case the Encoded Length is also zero.
Encoded Length
The Encoded Length is one less than the Length Expression, unless the
LE is zero.
The instructions in Figure 199 would be assembled as indicated, assuming the same displacements
for the symbols AA and BB relative to the base address in GR9, as in Section 24.2.
*
*

BB
T
H

Instruction

Assembled form

MVC BB(23),AA
MVC BB(1),AA
MVC BB(0),AA
MVC 0(L *,0),29(12)
MVC 15(L BB-4,3),BB
MVC BB,AA
MVC H(L H,H),H
MVC H(H,H),H(H)
MVC H+BB-AA(,9),AA
MVC T,BB-4
MVC BB-AA+4(9),AA
- - DS
CL23
EQU BB
EQU 8

D216
D200
D200
D205
D212
D216
D200
D207
D200
D216
D208

947D
947D
947D
0000
300F
947D
8008
8008
9360
947D
035C

9125
9125
9125
C01D
947D
9125
0008
8008
9125
9479
9125

LE=23
LE=1
LE=0
LE=6 (MVC s length!)
LE=19
LE=23
LE=1
LE=8
LE=1
LE=23
LE=9

Length attribute of T = 23
Self-defining term, Len Attr = 1

Figure 199. Examples of Length Specification Bytes


Chapter VII: Bit and Character Data

373

Possible Confusion?
Sometimes people call the value of the Length Expression simply the
length. This can be confusing if the length is understood to mean the
contents of the Encoded Length, which is sometimes called the machine
length. That is:
You provide implicitly or explicitly a Length Expression (a symbolic
length).
The Assembler generates the Encoded Length (the machine length).

24.6. The MVC and MVCIN Instructions


24.6.1. MVC: Move Characters
MVC moves the specified number of bytes starting at the second operand address, to an area
starting at the first operand address. There are no restrictions on overlapping areas, so you can do
things like propagate a character through an area, or shift the bytes in an area. We need only
remember that almost all SS-type instructions are executed in such a way that each byte is stored
before the next source byte is accessed.
Figure 200 shows how MVC can be emulated by other instructions. Remember that the length
expression LE is not the Length Specification Byte of a real MVC.
*Emulate MVC
LA
LA
LA
LTR
JNZ
LA
MoveByte IC
STC
AHI
AHI
JCT

BB(LE),AA
1,BB
2,AA
0,LE
0,0
MoveByte
0,1
3,0(,2)
3,0(,1)
1,1
2,1
0,MoveByte

Moves LE bytes from AA to BB


Address of first operand
Address of second operand
Length Expression (N)
Check for zero
Nonzero, OK to move
LE=0 means move one byte
Get a second-operand byte
Store at first operand
Increment first operand address
Increment second operand address
Repeat until LE bytes moved

Figure 200. Emulated operation of MVC instruction

Because MVC has no restrictions on operand overlap, the byte at a time emulation in Figure
200 is faithful to the execution of MVC. Of course, the MVC instruction doesnt modify any
registers this way.
Here are some examples using MVC instructions.
1. Set the 120-byte area beginning at Line to blanks.
MVI
MVC

Line,C
Line+1(119),Line

Store EBCDIC blank at Line


Propagate through rest of area

This is sometimes called a ripple move. It requires less storage space than
MVC

Line(120),=120C

because extra space is required for the literal string of 120 blanks.
Another way to set the 120-byte area at Line to blanks:

Blank
Line

374

MVC Line,Line-1
- - DC
C
DS
CL120

Requires carefully-ordered DC s
Single blank
Immediately follows the blank

Assembler Language Programming for IBM z System Servers

Version 1.00

2. Shift the 80-byte character string beginning at Str to the left by two character positions,
leaving blanks in the vacated positions.
MVC
MVC

Str(78),Str+2
Str+78(2),=C

Move left by 2 bytes


Two blanks at end

3. Exchange the contents of the halfword integers at A and B.

Temp
A
B

MVC Temp,A
MVC A,B
MVC B,Temp
- - DS
XL2
DS
H
DS
H

Move A to temporary location


Move B to A
Move old c(A) from Temp to B

4. GR8 and GR9 contain respectively the address and length of a message whose length is less
than 120 characters. Move the message to the area named Line.

MVC

BCTR 9,0
STC 9,MVC+1
MVC Line(0),0(8)

Decrease length by 1
Store in length byte of MVC (??)
Move correct number of bytes

The BCTR reduces the character count in GR9 from its true value to the machine
length value required by the MVC: one less than the actual number of bytes to be moved.
This is a terrible way to do this, because it requires instruction modification (discussed in
Section 23.9). A a better way to do this uses the Execute instruction, which well see in
Section 24.11.

24.6.2. MVCIN: Move Characters Inverse


MVCIN was implemented to support languages written from right to left. It moves characters
the same way as MVC, but in reverse order. That is, the bytes of the second operand are fetched
in right-to-left order and are stored at the first operand in left-to-right order. The second operand
of the machine instruction statement must address the rightmost byte of the string to be moved.
For example:

Chars
CRev

MVCIN CRev,Chars+L Chars-1


Move reversed Chars to CRev
- - DC
C12345
Data to be moved
DS
CL(L Chars)
Moved data = C54321

Figure 201. Example of Move Inverse instruction

As Figure 200 does for MVC, Figure 202 shows an emulation of MVCIN. The emulation uses
GR3 both as an index and as a count of the number of bytes to move.
*Emulate MVCIN
LA
LTR
JNZ
LA
LENotZro LA
LA
Insert IC
STC
AHI
JCT

BB(LE),AA+L AA-1
3,LE
3,3
LENotZro
3,1
1,BB
2,AA-1
0,0(3,2)
0,0(,1)
1,1
3,Insert

Move inverse: LE bytes from AA to BB


Number of characters to move in GR3
Check for LE = 0
Skip if greater than zero
LE = 1 moves one byte
Address of first operand
A(2nd operand s leftmost byte)-1
Insert a byte from right end of AA
Store at left end of BB
Increment first operand address
Reduce byte count by one and loop

Figure 202. Emulated operation of MVCIN instruction

The emulated addressing seems to reference the byte preceding the leftmost byte of the second
operand. However, the indexed IC instruction will start by inserting the rightmost byte and will
end with the byte at AA, because GR3 actually contains the Length Expression, not the Length
Specification Byte.
Chapter VII: Bit and Character Data

375

Unlike MVC, the z/Architecture Principles of Operation does not guarantee byte-by-byte operation for MVCIN, so if the operands overlap by more than one byte, the results may be unpredictable.

24.6.3. MVCOS: Move Characters With Optional Specifications


The MVCOS instruction can simplify character moves. You specify the true length to be moved
in a register, set GR0 to zero, and the instruction will move up to 4096 bytes at a time. Its syntax
is
MVCOS D1(B1),D2(B2),R3
where data is moved from the second operand to the first, and the number of bytes to move is
placed in the R3 operand register. The number of bytes actually moved is the number in the R3
register or 4096, whichever is less. The CC is set to 0 if all bytes have been moved, or to 3 if more
than 4096 bytes were specified.
For example, suppose we want to move 10000 bytes from Here to There:

Mover

LA
LA
LHI
XGR
MVCOS
JZ
AHI
AHI
AHI
J

7,There
4,Here
12,10000
0,0
0(7),0(4),12
Done
7,4096
4,4096
12,-4096
Mover

Target address
Source address
Number of bytes to move
Set GR0 to zero (important!)
Move up to 4096 bytes
Branch if all bytes moved
Update target address
Update source address
Reduce remaining count
Repeat for more bytes

Figure 203. Example of MVCOS instruction

This example illustrates these important points:


The source and target addresses, and the remaining byte count, are not updated by MVCOS:
you must do that.
Setting GR0 to zero is very important: MVCOS is a semi-privileged instruction, and any
nonzero bits in GR0 may cause a program interruption (unless your program is executing in
Supervisor State).
The convenience of MVCOS compared to MVC or MVCL may be outweighed by its slower
performance.

Exercises
24.6.1.(2) Suppose MVCIN used predictable byte-by-byte steps for any degree of operand
overlap. What result would appear in Figure 201 on page 375 if the instruction was
MVCIN Chars,Chars+L Chars-1

24.6.2.(2) The character string at Message has three segments, as defined by these statements:
Message
Prefix
Insert
Suffix

DS
DS
DS
DS

0C
CL43
CL29
CL67

Write instructions that will move the strings at PText, IText, and SText into these fields, but
the string at IText must be moved to Insert in reverse order.
24.6.3.(1) What will be in the character string at Result after executing these instructions?

376

Assembler Language Programming for IBM z System Servers

Version 1.00

Data
Result

MVC Result,Data
- - DC
C Data
DS
CL8

24.6.4.(1) What is in both operands after executing this MVC?


MVC Result2(8),Data2
- - Result2 DS
C ABCD
Data2
DC
C PQRSTUVW
24.6.5.(2) In example 4 of Section 24.6.1, is there any reason (other than very poor style) not to
write the last two instruction statements as
STC
MVC

9,*+5
LINE(0),0(8)

24.6.6.(3) Consider these two examples of an MVCIN instruction with overlapping operands:
(1)
X
Y
(2)
P
Q

MVCIN
- - DS
ORG
DC
MVCIN
- - DC
ORG
DS

X,Y+L Y-1
CL7
*-1
CL7 ABCDEFG
Q,P+L P-1
CL512345
*-1
CL5

In each case, the target and source operands overlap by one byte. After executing the
instructions, what data is at X and Q? Why is this one-byte overlap not a problem?
24.6.7.(2) + Suppose three character strings are defined by the statements
A
B
C

DC
DC
DS

C123456
C PQRSTUVW
CL(L A+L B)

Write instructions to concatenate the strings at A and B into a single string at C.


24.6.8.(2) + Suppose three character strings are defined by
D
E
F

DC
DS
DS

C987654ABCDE
CL4
CL(L D-L E)

Write instructions to split the string at D into two substrings at E and F.


24.6.9.(3) + You are given a string of characters starting at Str and whose length is stored at N,
and are required to extract a substring of characters whose length is at K, starting at a character
whose offset from N is stored at P. The extracted substring should be stored at Sub, and its
length should be stored in the word at L. (N, K, P, and L are words in your program.)
In case the substring is not fully contained in Str, the values at K and L will differ; and if no
valid substring can be extracted (for example, P exceeds N), store zero at L.

Chapter VII: Bit and Character Data

377

24.7. The NC, OC, and XC Instructions


The logical instructions NC, OC, and XC perform the AND, OR, and XOR operations described
in Section 19 on two strings, byte by byte, leaving the result in the first operand string. The CC
is set as in Table 93 on page 290. These examples illustrate the three instructions.
1. Clear the 120-byte area at Line to binary zeros.
XC

Line(120),Line

Set 120 bytes to zero

We could have used the same technique here as in example 1 of Section 24.6 (by moving a
string of 120 zeroed bytes).
2. Branch to Yes if the fullword integer at Lump is zero.
OC
JZ

Lump(4),Lump
Yes

OR 4 bytes to each other


Branch if all bytes are zero

NC
JZ

Lump(4),Lump
Yes

AND 4 bytes to each other


Branch if all bytes are zero

or

The first and second operands are identical, so only only the CC is set; no data is changed.
This technique can sometimes be used when a register is not free.
Dont test a string of bytes for zero this way if the operand is memory-protected, because
both instructions store into the first operand.
3. Suppose there are two words named XX and ZZ that each contain four positive integers,
packed as illustrated Figure 115 on page 249. Replace the second integer in the word at XX
by the corresponding value from the word at ZZ.
MVC Temp,ZZ
NC
Temp,Mask
OC
XX,Mask
XC
XX,Mask
OC
XX,Temp
- - DS
XL4
DC
XL400780000

Temp
Mask

Move new value to temporary location


Eliminate all but second integer
Set bits in 2d integer position to 1
Now set them to zeros
Insert new value into word at XX
Temporary workspace
Mask bits for 2nd integer position

Figure 204. Inserting bits in a word using logical SS-type instructions

4. Exchange the contents of the halfword integers at A and B. (Compare example 3 on page
375.)

A
B

XC
B,A
XC
A,B
XC
B,A
- - DS
H
DS
H

XOR A to B
XOR B to A
XOR A to B

This technique was used to exchange register contents in Exercise 19.5.1.*

Exercises
24.7.1.(2) Revise the instructions in Figure 204 to use two masks, two NC instructions, and
one OC instruction.
24.7.2.(2) A student suggested the following code sequence as a solution to the problem of
replacing data items embedded in a larger field:

378

Which you solved correctly, of course.


Assembler Language Programming for IBM z System Servers

Version 1.00

Old
New
Mask

XC
Old,New
Make a mess of Old field
NC
Old,Mask
Zero space for New item
XC
Old,New
Now clean it all up
- - DC
C DOWNWITH
DC
C PINKNUDITY
DC
2X FF , 4 X 0 , 2 X FF

Verify that his method works, and discover the identity of the student.
24.7.3.(2) The bits in the byte at BitData are to be converted to a string of eight EBCDIC 0
and 1 characters starting at BitChars. A student suggested using these instructions:
LHI 1,8
IC
0,BitData
Repeat STC 0,BitChars-1(1)
SRL 0,1
JCT 1,Repeat
NC
BitChars,=8X 1
OC
BitChars,=8C 0
- - BitData DC
B10010001
BitChars DS
CL8

Count 8 bits in GR0


Get the source byte
Store a byte at BitChars
Shift right by one bit
Iterate for all 8 bits
AND off all but low-order bit
OR makes EBCDIC 0 or 1 characters
Sample source byte
Converted characters

Does this work? What will be found at BitChars? Explain your answer.

24.8. The CLC Instruction


CLC compares the first operand to the second operand one byte at a time, until either an inequality is detected or the required number of bytes has been compared. As with CLI, each step
of the comparison is between unsigned 8-bit logical integers, and the CC settings are as shown in
Table 135 on page 357.
1. If the 120 bytes at Line contain blanks, branch to AllBlank.
CLC
JE

Line(120),=CL120
AllBlank

Compare to 120 blanks


Branch if equal

CLC
JE

=CL120 , Line
AllBlank

Compare to 120 blanks


Branch if equal

or

Because compare instructions modify neither operand, a literal can be used as the first
operand; this second method uses the Length Attribute of the literal as the Length
Expression.
2. Two positive word integers are stored at SS and TT. Branch to TBig if the number at TT is
larger than the number at SS. (The restriction to positive integers means that a logical comparison gives the same result as an algebraic comparison.)
CLC
JH

TT(4),SS
TBig

Compare c(TT) to c(SS)


Branch to TBig if greater

3. Two negative word integers are stored at SS and TT. Branch to TBig if the number at TT is
algebraically larger than the number at SS. (Because both integers are algebraically negative,
a logical comparison is the same as an algebraic comparison; see Exercise 24.8.1.)
CLC
JH

TT(4),SS
TBig

Compare logically, and...


Branch if c(TT) > c(SS)

4. A list of 100 names and occupations, each contained in a block of 60 bytes, is stored beginning at List. Branch to Found if any of the blocks matches the name and occupation in the
block at WhoIsIt.

Chapter VII: Bit and Character Data

379

Test

LA
LA
CLC
JE
LA
JCT
J

1,List
2,100
0(60,1),WhoIsIt
Found
1,60(,1)
2,Test
NotFound

Initialize GR1 to A(first block)


Set GR2 count to number of blocks
Compare blocks
Branch if blocks are equal
Increment address by block length
Count down and branch
No matching block was found

Exercises
24.8.1.(2) Example 3 above claims that a logical comparison of two negative integers gives the
same result as an algebraic comparison. Show that this is or is not true.
24.8.2.(3) + Write instructions using CLC to correctly compare arithmetically two signed word
integers in memory having arbitrary signs. For example, CLC should show that + 10 > 10.
(It can be done!)
24.8.3.(2) Suppose we wish to test the string of 220 bytes at R to see if they all contain zero. It
is claimed that each of the following instructions will set the CC to zero if and only if the string
contains all zero bytes. For which of these instructions is the claim true?
(1)
(2)
(3)
(4)

OC
NC
CLC
CLC

R(220),R
R(220),R
R+1(219),R
R(220),=220X 0

24.8.4.(2) + A programmer described the operation of the CLC instruction with the phrase the
shorter operand is padded with blanks. Give two reasons why this is incorrect.
24.8.5.(2) Write instructions to scan a string of 72 bytes at Chars and branch to AllBlank if
every character is blank, without using a constant string of 72 blank characters.
24.8.6.(2) + In Example 1 above, what would happen if you had written
CLC

=120C , Line

instead?
24.8.7.(1) + What does this instruction do? Is it at all useful? If so, why?
CLC

1(7,4),0(4)

24.9. The TR Instruction


The Translate instruction replaces each byte in a string with any of another 256 possible values.
Like MVC, the TR instruction moves bytes from the second operand location to the first operand
location, but in a very different and possibly disorderly way. It actually performs a sort of
pseudo-indexing:
1. An argument byte is obtained from the first operand address.
2. The value of that byte (as an eight-bit unsigned integer) is added internally to the second
operand address, to access a function byte from the second operand.
3. The accessed function byte replaces the argument byte at the first operand address.143

143

380

In mathematical terminology, the TR operation can be thought of as replacing the argument bytes x1, x2, ..., xn by
the function bytes f(x1), f(x2), ..., f(xn).
Assembler Language Programming for IBM z System Servers

Version 1.00

4. The first operand address is incremented by one, and the process repeats until all first
operand bytes have been translated.
For example, suppose the string of five argument bytes at PP contains X0201040503, and the
character string at GG contains the character constant C ABCDEF . If we execute the instruction
TR

PP(5),GG

then the final contents of the five bytes at PP will be C CBEFD . The first argument byte taken
from the first operand is X 0 2 ; the function byte at GG+X 0 2 is C C , and this replaces the first
byte at PP. Similarly, the fifth and last argument byte at PP is X 0 3 ; the function byte at
GG+X 0 3 is C D , which replaces the final byte in the string at PP.
Unlike the SS-type instructions weve seen thus far, the TR instruction can access bytes as far as
255 bytes away from the second operand address, whereas the other instructions accessed only
those bytes within the area whose length is determined by the Length Specification Byte.
A sequence of RX-type instructions simulating the TR instruction helps clarify its operation. In
Figure 205, the symbols L, B1, D1, B2, and D2 have the values from the TR instruction being
simulated. For this example, assume that B1 and B2 are not 1 or 2, because we will use those
registers in the simulation.
*Emulate TR
LHI
LTR
JNZ
LA
LNotZero SR
SR
GetArg IC
IC
STC
AHI
JCT

D1(L,B1),D2(B2)
0,L
0,0
LNotZero
0,1
1,1
2,2
2,D1(1,B1)
2,D2(2,B2)
2,D1(1,B1)
1,1
0,GetArg

Translate L bytes
Set counter in GR0 to number of bytes
Check for L = 0
Proceed if not zero
L = 0 always translates one byte
Set first operand index to zero
Indexes table at 2nd operand
Get argument byte from 1st operand
Use as index to get function byte
Store in string at 1st operand
Increment first operand index by 1
Loop until L argument bytes done

Figure 205. Emulating the T R instruction

You can appreciate the power of TR if you consider the example in Figure 167 on page 333 and
its variations. We wanted to replace all special characters with blanks. If we create an appropriate
translation or translate table, the entire process can be done with one TR instruction, as in Figure
206.
TR
Str(80),TRTable
- - TRTable DC
(C a ) C
DC
C abcdefghi
DC
7C
DC
C jklmnopqr
DC
CL8
DC
C stuvwxyz
DC
23C
DC
C ABCDEFGHI
DC
7C
DC
C JKLMNOPQR
DC
CL8
DC
C STUVWXYZ
DC
6C
DC
C0123456789
DC
6C

Translate all specials to blanks


Anything less than C a is blanked
Letters are unchanged
Non-printing characters are blanked
Print letters as is
More non-printing characters
Last of the lower-case letters
Blank anything between z and A
Letters are unchanged
Non-printing characters are blanked
Print letters as is
More non-printing characters
Last of the upper-case letters
Blank anything between Z and 0
Digits print okay
Tail-enders are blanked too

Figure 206. TR instruction to change special characters to blanks

Chapter VII: Bit and Character Data

381

As a second example of the TR instruction, suppose we will need to print the contents of the
word at HexWord as eight hexadecimal digits, and we must place the eight EBCDIC characters
representing the hex digits in a string starting at Spred.

Clear

Spred

L
LA
LA
SR
SLDL
STC
LA
JCT
TR
- - DS

1,HexWord
Get fullword to be converted
2,Spred
Address of character being stored
3,8
Digit counter in GR3
0,0
Clear GR0 for shifting
0,4
Shift a hex digit into GR0
0,0(,2)
Store in string at Spred
2,1(,2)
Increment character address by 1
3,Clear
Loop until 8 digits are stored
Spred,=C0123456789ABCDEF Translate to EBCDIC
CL8

Converted result goes here

Figure 207. Translating hex digits to EBCDIC characters (1)

We can also index in the opposite direction, as in Figure 208.

Shift

Spred

L
LA
SRDL
SRL
STC
JCT
TR
- - DS

0,HexWord
Get fullword to be converted
2,8
Counter and index in GR2
0,4
Shift a digit into GR1
1,28
Position for storing
1,Spred-1(2)
Store in character string
2,Shift
Decrease index and shift again
Spred,=C0123456789ABCDEF Translate to EBCDIC
CL8

Converted result goes here

Figure 208. Translating hex digits to EBCDIC characters (2)

This result is sometimes called spread hex; the UNPK instruction (in Section 27) does this
operation much more easily.

Exercises
24.9.1.(1) Assemble the translation table in Figure 206 on page 381 and verify that all nonblank characters are in positions corresponding to their EBCDIC encodings, and that the translate table is 256 bytes long.
24.9.2.(2) + Suppose the bits within each byte of a string of bytes are to be rotated to the right
by one bit position, so that B10110001 becomes B11011000. Write a code sequence,
including a TR instruction and the necessary translate table, to do the rotations.
24.9.3.(2) The translation table in Figure 206 uses hand-counted values for the duplication
factors on DC statements that generate blanks. Rewrite the table to use duplication factors calculated by the Assembler based on the hexadecimal representations of the characters.
24.9.4.(4) A certain program needed to place each of the 80 characters in the string at InputRec
into an array of 80 words at A1Format in such a way that each successive word contains one
character from the string in its leftmost byte, followed by three blanks. Write a program
segment to do this using TR instructions.
24.9.5.(2) + Write a short program segment which will use a TR instruction and an appropriate
table to interchange the positions of the two hex digits in a byte. How long must the table be?
24.9.6.(2) + Rewrite Exercise 22.5.1. to use a TR instruction and an appropriate translate table.
Are there any limitations on the length of the list? Explain your conclusion.

382

Assembler Language Programming for IBM z System Servers

Version 1.00

24.9.7.(2) + Rewrite Exercise 17.4.6 to use a Translate instruction and an appropriate translate
table.
24.9.8.(4) Write a program segment to do the reverse of the action performed by your solution
to Exercise 24.9.4: the high-order bytes of each of the fullwords in the array at A1Format should
be collected into an 80-character string at OutRec.
24.9.9.(3) Assuming that only the valid EBCDIC characters shown in Table 13 on page 89 will
appear in the string, write statements to generate a translation table that will set all other characters to blanks. Verify that your translate table is 256 bytes long.
24.9.10.(4) Write a sequence of instructions including TR that will cause the hex digits in a
string of bytes at Old to be shifted right by one digit position at New. That is, if we start with
X123456 at Old, we should find X012345 at New.
Then do the same for a left shift of one digit position; the result (starting with the same data)
would then be X234560.
24.9.11.(2) Suppose you must translate a very long record to contain all upper-case letters.
Assuming the record starts at Record and its length is found in the word at Reclen, write a
translate table and instructions that will do the translation.
24.9.12.(2) Suppose you must convert the 8 hex digits of c(GR9) to 8 EBCDIC characters
representing those digits, starting at GR9Hex. Will these instructions work? Explain why or why
not, and describe the intended function of the instructions named Q1, Q2, and Q3.

Repeat
Q1
Q2
Q3
Store

GR9Hex

LHI
LA
XR
SLDL
AHI
CHI
JL
AHI
STC
AHI
JCT
- - DS

0,8
1,GR9Hex
8,8
8,4
8,240
8,250
Store
8,-57
8,0(,1)
1,1
0,Repeat
CL8

24.9.13.(2) + The string of characters at Text contains a mixture of lower-case and upper-case
letters, and its length in the halfword at TextLen is less than 256. Write instructions including
TR that will change the lower-case letters to their upper-case equivalents.
24.9.14.(2) Suppose the two bytes stored at Zone contain arbitrary bit patterns, represented as
X wxyz . Write a code sequence with one or more TR instructions which will convert the given
pair of bytes to the form X Fxzy . That is, interchange the two low-order digits, and replace the
high-order digit by X F , no matter what its original value might have been. (This is similar to
the action performed by the UNPK instruction discussed in Section 27.)
24.9.15.(2) + If you execute the following TR instruction, what will you find in the operand
named OddTable when the instruction completes?
TR
OddTable,OddTable Identical first and second operands
- - OddTable DC
X01000302050405
24.9.16.(3) A student suggested the following instructions as a way to convert a string of bytes
at InString to pairs of EBCDIC characters at OutStrng representing the hex values of the
source data. That is, if the first source byte contains X 9F , the first two output characters will
be 9F.

Chapter VII: Bit and Character Data

383

XR
XR
XR
LHI
Convert IC
SRDL
STC
SRL
STC
AHI
AHI
JCT
TR

0,0
Clear a work register
2,2
Input-byte index
3,3
Output string index
4,L InString
Number of bytes to convert
0,InString(2)
Get a source byte
0,4
Shift right 4 bits
0,OutStrng(3)
Store leftmost hex digit
1,28
Move rightmost hex digit to end
1,OutStrng+1(3)
Store rightmost hex digit
2,1
Increment input index
3,2
Increment output index
4,Convert
Repeat for all input bytes
OutStrng,=C0123456789ABCDEF
Translate to EBCDIC

Does this work? What precautions should the students program take?
24.9.17.(5) + In Exercise 17.3.16 you reversed the bits in a 32-bit word, using shift instructions.
Now, write a DC statement to create a translate table that will reverse the bits in each byte of a
string.
24.9.18.(5) Using your solutions to Exercises 24.9.3 and 24.9.17, write a sequence of
instructions using two TR instructions that will reverse both the bytes and the bits of the word
at DataWord and store the result at RevData. For example, if c(DataWord)=X12345678, the
resulting c(RevWord) will be X 1 E6A2C48 . (Well see in Section 26 that there are easier ways
to reverse bytes.)
24.9.19.(3) Suppose you define this translate table:
X1

DC

256AL1(X FF -(*-X))

and the you execute this instruction:


TR

X(256),X

What happens? If you repeat the instruction N times, will you ever get the original table at X?
If so, how many times?
24.9.20.(3) Repeat Exercise 24.9.19 with this translate table:
X2

DC

256AL1(*-X)

What happens? If you repeat the instruction N times, will you ever get the original table at X?
If so, how many times?

24.10. The TRT and TRTR Instructions


Whereas TR converts a sequence of byte values into new values, TRT and TRTR are used to
search a string of bytes for one or more specified values. Both instructions are especially useful in
scanning for punctuation, delimiters, and erroneous characters.
As we saw for MVC and MVCIN, the first operand of TRT refers to the leftmost byte of the first
storage operand, while the first operand of TRTR refers to the rightmost byte of the first storage
operand.
The operation of TRT and TRTR is identical to TR through steps 1 and 2 on page 380, and
quite different thereafter.
3.

The first operand is not modified; the accessed byte from the table addressed by the second
operand (the function byte) does not replace the argument byte from the first operand string.
Instead, the function byte is examined: if it is zero, we continue with step 4 of the
description of TR, incrementing (or decrementing) the first operand address and decrementing the count.
If the function byte is not zero,

384

Assembler Language Programming for IBM z System Servers

Version 1.00

It is placed in the rightmost byte of GR2 or GG2 (the rest of the register is unchanged);
The address of the argument byte which caused a nonzero function byte to be accessed is
placed in GR1 or GG1, depending on the addressing mode:

in 24-bit mode, into the rightmost 24 bits of GR1, and the remaining bits of GR1 are
unchanged
in 31-bit mode, into the rightmost 31 bits of GR1, and the leftmost bit of GR1 is set
to zero
in 64-bit mode, into all the bits of GG1.

The operation terminates, and the CC indicates the result of the operation, as shown in
Table 145.
CC
0
1
2

Meaning
All accessed function bytes were zero.
A nonzero function byte was accessed before the
last argument byte was reached.
The nonzero function byte accessed corresponds to
the last argument byte.

Table 145. Condition Code settings for T R T and T R T R instructions

24.10.1. TRT
To illustrate the basic operation of TRT, suppose we must scan a string of characters to find the
address of the first numeric character. First, we create a translate table with zero function bytes in
all positions except for those corresponding to the EBCDIC representation of decimal digits,
where the function bytes are nonzero.
NumChar DC

(X F0 ) X00,10X 0 1 , 6X 0 0

Then, suppose we test the following strings using TRT:


String1 DC
String2 DC
String3 DC

C abc123def
C *abcdef*
C AB7

Decimal digit before end of string


No decimal digits
Decimal digit in final position

Then, after executing the following instructions, the contents of GR1, GR2, and the CC are as
shown:

TR

Instruction
String1,NumChar

c(GR1)
A(String1+3)

c(GR2)
X xxxxxx01

CC
1

TR

String2,NumChar

unchanged

unchanged

TR

String3,NumChar

A(String3+2)

X xxxxxx01

The xxxxxx characters mean that those portions of GR2 are unchanged when the X 0 1 function
byte is inserted.
As another example, suppose we must scan a string of 80 characters beginning at Record for the
punctuation characters period, comma, and apostrophe. When one of them is found, a branch
should be made to Period, Comma, or Apost respectively, with the address of that punctuation
character in GR1. If none is found, branch to NoPunct. First, we will write an example using
CLI instructions, but not TRT.

Chapter VII: Bit and Character Data

385

LA
LA
TestPunc CLI
BE
CLI
BE
CLI
BE
AHI
JCT
B

1,Record
2,80
0(1),C .
Period
0(1),C ,
Comma
0(1),C
Apost
1,1
2,TestPunc
NoPunct

Initialize character address


Number of characters to examine
Compare to period
Branch if found
Compare to comma
Branch if found
Compare to apostrophe
Branch if found
Otherwise increment address by 1
Count and loop
Branch if none were found

Figure 209. Searching for punctuation characters using CLI

The TRT instruction does the same processing much more rapidly, but at the cost of memory
space for the translate table.
SR
TRT
JZ
B
J
J
J
PuncTbl DC
DC
DC
DC

2,2
Clear GR2, to be used as an index
Record(80),PuncTbl Scan for punctuation
NoPunct
Branch if none found
*(2)
Function byte is index for branch
Period
Period
Comma
Comma
Apost
Apostrophe
(C . ) X 0 0 , X 0 4
Function byte 4 for period
(C , -C . -1)X 0 0 , X 0 8
8 for comma
(C -C , -1)X 0 0 , X 0C
12 for apostrophe
(255-C ) X 0 0
Remainder of table

Figure 210. Searching for punctuation characters using T R T

The three nonzero function bytes are at positions in the table corresponding to the values of the
EBCDIC representations of the characters being sought. The function values are multiples of
four so they can be used to index the branch instruction B *(2). If the conditional branch to
NoPunct had been omitted, GR2 might contain zero and the program could have gone into an
infinite loop at the B instruction.
This translate table was constructed by observing that we need not know the values of the
EBCDIC representations of the period, comma, and apostrophe, only that their representations
are in ascending order. This means that (for example) the number of characters between the
period and the comma is the positive quantity (C , -C . + 1 ) .
Suppose your program has received a string of decimal characters into a field named InputNum.
Before using the data, its a good practice to validate it. (Data validation helps avoid errors and
program interruptions that may occur much later in your program.) Figure 211 shows one way
to do this.
TRT InputNum,ValidDec
JZ
Valid
JNZ ReEnter
- - ValidDec DC
(C 0 ) X 0 1
DC
10X 0 0 , 6X 0 1
InputNum DS
CL12

Test for all numeric data


Branch to process valid data
Something invalid, ask for re-entry
Values < X F0 are invalid
Values > X F9 are invalid
Numeric characters?

Figure 211. Using T R T to validate numeric characters

As another example of the TRT instruction, suppose we are required to scan the quoted character
string starting at Sentence for the occurrence of an embedded character string containing either
apostrophes (as in She said, Never! ), or quotation marks (as in I said, I won t ). As
these examples indicate, the other delimiter may appear freely inside the outer string.

386

Assembler Language Programming for IBM z System Servers

Version 1.00

If such an embedded string exists, we must store its starting address (excluding the preceding
delimiter) at StrAddr and its length in bytes (again excluding the delimiters) at StrLen. (For the
first string, the result would be the 10 characters Shesaid,). If no string exists, branch to None,
and if the apostrophe or quotation mark which would terminate the string is missing, branch to
Unfin. Assume the length of the data string to be scanned is stored at SentLen, and is 256 or less.
The program segment in Figure 212 scans first for the starting delimiter; when it is found, the
proper table is chosen to search for the ending delimiter.
LA
1,Sentence
Starting data address in GR1
L
2,SentLen
Fetch length to scan, and...
BCTR 2,0
Decrement by 1 for length byte,
STC 2,TRT1+1
Store in TRT1 instruction.
LA
3,0(2,1)
C(GR3) = A(last data byte)
SR
2,2
Clear GR2 for function byte
ST
2,StrLen
And set result length to 0
TRT1
TRT 0(*-*,1),T
Scan for first delimiter
JZ
None
Exit if nothing useful found
LA
4,1(,1)
Step over starting delimiter,
ST
4,StrAddr
And store string start address.
LastCh JC
2,Unfin
Exit if that s all there was
LA
1,1(,3)
C(GR1) = A(last data byte)+1
SR
3,4
(length-1) of rest of data
STC 3,TRT2+1
Store in length byte of TRT2
L
3,TAdd-4(2)
Address of correct table in GR3
SR
2,2
Reset GR2 for function byte
TRT2
TRT 0(*-*,4),0(3)
Scan rest of data with new table
SetLen S
1,StrAddr
Subtract start address of string
ST
1,StrLen
And store result string length
LTR 2,2
Test for closing delimiter found,
JZ
Unfin
Branch if not found.
- - StrLen DS
F
Length of final string
StrAddr DS
A
Address of final string
TAdd
DC
A(T2,T3)
Table addresses
T
DC
125X 0 , X040008,128X 0
Initial TRT table
*
Function byte = 4 for apostrophe, 8 for quotation mark
T2
DC
125X 0 , X4,130X 0
Stop on apostrophe
T3
DC
127X 0 , X4,128X 0
Stop on quotation mark
Figure 212. Using T R T to scan for embedded quotations

Several items in Figure 212 deserve comment.


The two STC instructions modify the TRT instructions at TRT1 and TRT2. The Execute
instruction in the next section shows a much better way to do this.
The expression *-* in the instructions named TRT1 and TRT2 is the Location Counter value
subtracted from itself, which is always zero. This notation is often used to indicate that the
contents of the field will be provided by the program at execution time.
By storing zero at StrLen before scanning the string (just preceding TRT1), we have taken care
of the possibility that the initial delimiter may have been the last character in the data string;
this condition is detected by the conditional branch instruction named LastCh.
The function byte in the table named T is used by the Load instruction just preceding the
second TRT as an index to load into GR3 the address at TAdd of the desired secondary table.
By presetting GR1 to the address of the byte immediately following the data string, we can
complete the scan with the second TRT as follows. If a closing delimiter exists, GR1 will
eventually point to it, and the instruction named SetLen will calculate the number of bytes
between the delimiters; GR2 will then contain the nonzero function byte X 0 4 . However, if
no closing delimiter is found, GR1 and GR2 are unchanged, and we can still compute a useful
string length before exiting to Unfin.

Chapter VII: Bit and Character Data

387

As a final example using TRT to scan variable-length data, suppose a string of characters at Names
contains names separated by commas and terminated by a period. We will construct at List a
table of fullword addresses of the first character of each name, followed by a word containing the
number of characters in that name, which is known to be less than 256. When the table is complete, the number of names is stored in the word at NbrNms. To protect against omitted punctuation or other errors, we will branch to LongName if no comma or period is found within 256
characters of the start of a name. No tests are made for repeated names.
MaxNames Equ 50
Assume at most 50 names found
SR
3,3
GR3 contains index for list
SR
2,2
Clear function-byte switch in GR2
LA
1,Names
Initialize scan address
Scan
LR
4,1
Save initial character address
TRT 0(256,1),TRTB
Scan for period or comma
JZ
LongName
Branch if no punctuation found
ST
4,List(3)
Store address of name in list
SR
1,4
Compute name length
ST
1,List+4(3)
Store length of name, too
LA
3,8(,3)
Increment list address
LA
1,1(4,1)
Move GR1 to start of next name
JCT 2,Scan
Branch if comma was encountered
SRL 3,3
If period, compute and store ..
ST
3,NbrNms
...the number of names found
- - TRTB
DC
(C . ) X 0 0 , X 0 1
Function = 1 for period
DC
(C , -C . -1)X 0 0 , X 0 2 Function = 2 for comma
DC
(255-C , ) X 0 0
Zero otherwise
- - Names
DC
C Brown,Green,Wonka,Ofstrand,Jones,Smedley,Doe,
DC
C Apple,Doe,Smithwich,Softnard,Smith,Doelful,
DC
C Lostkind,Jones,Lurp,VonHimmelsBergenSchneider,Doe.
NbrNms DS
F
Number of names found
List
DS
(2*MaxNames)A
Table for addresses and counts
Figure 213. Using T R T to scan a string of names and build an occurrence list

The only unusual feature of Figure 213 is using the function byte as a branching switch: if a
period is encountered, GR2 will contain + 1, and the JCT instruction will not branch.

24.10.2. TRTR
The test in Figure 211 can be done with TRTR and the same translate table:
TRTR InputNum+L InputNum-1,ValidDec Test for numeric data
JZ
Valid
Branch to process valid data
JNZ ReEnter
Something invalid, ask for re-entry
- - Figure 214. Using T R T R to validate numeric characters

Programs often must analyze character strings, finding tokens to be processed individually. But
how do you know when there is no more data in the string, and the rest of the string is blanks? A
common technique is to scan backwards from the end of the string, searching for the last nonblank character in the string. This is sometimes done with a CLI instruction:

388

Assembler Language Programming for IBM z System Servers

Version 1.00

Check

Done

LA
CLI
JNE
BCTR
J
- - -

1,String+L String-1
Address of end of string
0(1),C
Check for a blank
Done
Exit loop if nonblank
1,0
Reduce address by 1 byte
Check
And check again
GR1 points to last nonblank

Figure 215. Scanning a string backward using CLI

This scan can also be done (perhaps more quickly) using a TRTR instruction:
TRTR String+L String-1,BlankTbl Scan backward
JZ
AllBlank
Problem: string is all blanks
- - GR1 points to last nonblank
BlankTbl DC
(C ) X 1 , X0,(256-C -1)X 1
Figure 216. Scanning a string backward using T R T R

While this may appear to use more memory than a CLI loop, translate tables like this are often
used in many different places, so a single table can be referenced by many instructions.

Exercises
24.10.1.(1) Verify that the translate table in Figure 210 on page 386 generates exactly 256
bytes, and that the nonzero entries are at offsets corresponding to the EBCDIC representations
of the punctuation characters.
24.10.2.(2) Show that the ORG instruction can be used to build the Translate and Test table of
Figure 213 on page 388 as follows:
TRTB

DC
ORG
DC
ORG
DC
ORG

XL256 0
TRTB+C .
X 1
TRTB+C ,
X 2
TRTB+256

Define table, length 256


Function byte for period
Function byte for comma
Reset LC to end of table

Use this technique to construct the table in Figure 210 on page 386. Why is this method
superior to the one used in Figures 210 and 213? Can the first DC be replaced by DS?
24.10.3.(2) In Figure 212 on page 387, the length byte in the second TRT is calculated by the
SR 3,4 just preceding it. Is there any reason why the result of the subtraction cannot be
negative? What would happen if it was?
24.10.4.(2) In Figure 212 on page 387, three distinct translate tables were used: one to scan for
an initial apostrophe or quotation mark, and the other two to scan for the matching delimiter
at the end of the quoted string. Rewrite the example to use a single translate table, which is
suitably initialized for each use by instructions such as
XC
MVI

T(256),T
T+C , 4

Set entire table to zero


Set to stop on apostrophe

24.10.5.(4) + In Figure 212 on page 387, there are three translate tables. Show how these tables
can be overlapped in a way that requires only about one-half as much space.
24.10.6.(2) Write instructions to scan the string of 120 characters at CharData and leave in GR1
the address of the first character that is neither alphabetic nor numeric.
24.10.7.(2) In Exercise 23.4.3 you scanned a character string at Record to locate the last nonblank character. Do the same exercise, but this time use MVCIN and TRT instructions instead
of CLI.

Chapter VII: Bit and Character Data

389

24.10.8.(2) In Figure 212 on page 387, why is it necessary to reset GR2 to zero before executing the second TRT?
24.10.9.(2) The translate table in Figure 216 on page 389 is defined with a single DC statement. Verify that it generates the desired data.
24.10.10.(3) Modify the coding in Figure 213 on page 388 to store each name only once, and
add a word to each names entry in the list giving the number of occurrences of that word.
24.10.11.(2) + Show the contents of GR2 and the Condition Code setting after executing the
following instructions:

XX

SR
2,2
TRT XX,=XL520100
- - DC
X0004010203

24.10.12.(3) + Some experiments have shown that trailing blanks can be removed more efficiently than in Figures 215 and 216 by starting at the end of the string and comparing to a
doubleword of blanks until a mismatch occurs, and then using a backward CLI scan. Write an
instruction sequence to implement this technique to truncate the string starting at String
having length L, and store the truncated length of the string in the halfword at TruncLen.
24.10.13.(2) Revise Exercises 24.7.3 and 24.10.7 to use a TRTR instruction.

24.11. The Execute Instructions


While the Execute instructions are not SS-type, they are often used with SS-type instructions to
help process character data.
Op
44

Mnem
EX

Type Instruction
RX
Execute

Op
C60

Mnem
EXRL

Type Instruction
RIL Execute Relative Long

Table 146. Execute instructions

The two Execute instructions in Table 146 are unusual, because they specify the execution of
another instruction at a different address! We will use some concepts of the basic instruction cycle
described in Section 4 and illustrated in Figure 13 on page 52.
These instructions are executed using these steps:
1. The Effective Address is computed, and the R1 digit of the Execute instruction is saved.
2. The instruction at the Effective Address, the target (or subject) instruction, is placed into the
Instruction Register (IR), replacing the EX or EXRL. The Instruction Address in the PSW is
unchanged, and still contains the address of the instruction following the Execute.
3. If the new instruction in the IR is another execute instruction, a program interruption occurs,
and the Interruption Code in the old PSW is set to 3. (There is a good reason for this interruption, as well see shortly.)
4. If the R 1 digit of the Execute instruction was zero, proceed to step 5. Otherwise, the rightmost byte of general register GR R 1 is ORed into the second byte of the IR. Both GR R 1
and the target instruction in memory remain unchanged.
5. The (possibly modified) target instruction in the IR is now decoded and executed as though
it was the original instruction fetched from memory.
If the target instruction in the IR does not change the IA in the PSW (it is not a successful
branch instruction), execution continues with the instruction following the Execute. If the target
instruction does change the IA in the PSW (it is a successful branch), execution will continue
with the instruction at the branch address. The CC is changed only if the target instruction sets
the CC.

390

Assembler Language Programming for IBM z System Servers

Version 1.00

24.11.1. Execute Instruction Without Target-Instruction Modification


To illustrate uses of EX and EXRL, we first consider examples where the R1 digit is zero, so that
no ORing occurs in the IR.
1. Store at CCC the quantity 2*C(A)-C(B), where A and B are the names of words in memory.
SR
LA
LA
Execute EX
JXLE
- - Inst
L
AR
NOPR
S
ST

1,1
2,4
3,12
0,Inst(1)
1,2,Execute

Clear index to zero


Increment = 4, instruction length
Comparand = 12
Execute an instruction
Increment by 4 and loop

0,A
0,0
0
0,B
0,CCC

Load GR0 from A (4-byte instruction)


Double c(GR0) (2-byte instruction)
2 bytes spacing
Subtract c(B) (4-byte instruction)
Store result (4-byte instruction)

Figure 217. Executing a list of instructions

This program segment does four simple instructions the hard way, and merely illustrates a
way to execute instructions which are out-of-line, and not directly in the normal stream of
program execution. The list of instructions at Inst could be executed independently of the
first five instructions by branching to Inst, giving the same result much more rapidly.
2. Suppose we wish to add the three word integers stored beginning at Q. Depending on the
number of overflows: if no overflows occur, multiply the result by 10; if one overflow occurs,
do nothing; and if two overflows occur, set the result to 1.
SR
1,1
L
0,Q
A
0,Q+4
JNO NoOfloA
AHI 1,4
NoOfloA A
0,Q+8
JNO NoOfloB
AHI 1,4
NoOfloB EX
0,FixIt(1)
ST
0,Result
- - FixIt
MH
0,=H 1 0
NOP 0
LA
0,1

Clear overflow counter in GR1


Get first integer
Add second integer
Branch if no overflow
Indicate one overflow
Add third integer
Branch if no overflow
Indicate another overflow
Execute correct operation
And store result
Multiply by 10
Do nothing
Set result to +1

Figure 218. Executing a list of instructions

3. Suppose we must place in GR6 the address of some byte in memory, and that the desired
address is known only to be the Effective Address of some other RX-type instruction. To
make matters more complicated, suppose also that the addressing calculation needed by the
RX instruction could make use of any registers but R14 and R15; that is, the base and index
digits can be anything from 0 to 13. We assume that GR15 is currently being used for a base
register, and that GR14 contains the address of the RX instruction in question.
We will construct a LA instruction in a work area with the same index, base, and displacement fields as the RX instruction, and then execute that LA instruction.

Chapter VII: Bit and Character Data

391

MVC
NI
OI
MVI

MakeLA(4),0(14)
MakeLA+1,X 0F
MakeLA+1,X 6 0
MakeLA,X 4 1

*
EXRL 0,MakeLA
- - DS
2H

MKLA

Move original RX inst n to work area


Clear old R1 digit position
Set new R1 digit to 6
Set LA opcode into instruction
Contents of MakeLA is now 416xbddd
Execute the constructed LA
GR6 now has the desired address
4 bytes on halfword boundary

Figure 219. Constructing an executed instruction

This instruction sequence changes no registers other than GR6, even though R0 could have
been used in the instruction sequence without affecting the operation of the EX, because
GR0 or GG0 could not have been used by the LA as a base or index register. This illustrates
a technique you can use when all other register contents must remain unchanged.

24.11.2. Execute Instruction with Target-Instruction Modification


The Execute instructions are most useful when the R1 digit is not zero, implying modification of
the target instruction in the IR.
1. Suppose we wish to move to Line a message whose address and length are in GR8 and GR9
respectively, as in example 4 on page 375.

Move

BCTR 9,0
EX
9,Move
- - MVC Line(*-*),0(8)

Decrease Length Expression by 1


Execute the MVC instruction
Executed instruction, length = 0

The Length Specification Byte in GR9 is ORed into the proper position in the (target) MVC
instruction in the IR. In the assembled MVC instruction, the length byte was preset to zero
by a zero explicit Length Expression. A major advantage of this method is that the instruction in storage is unmodified, an important consideration in writing re-enterable code.
This is a very typical use of an Execute instruction.
2. Suppose we must branch to Yes if the rightmost byte of GR3 contains B00011111.
EX
3,CLI
BE
Yes
- - CLI
CLI ChkBits,0
ChkBits DC
B00011111

Execute the comparison


Branch if equality is found
Executed instruction
Comparison quantity

The same problem could be solved without using EX, but extra storage accesses would be
required:

Temp

STC 3,Temp
CLI Temp,B00011111
JE
Yes
- - DS
X

Store the byte to be tested


Compare to desired pattern
Branch if equal
Byte from GR3 to be tested

3. Store at RegTotal the sum of the contents of registers GR0 through GR10.
Loop

Adder

LA
12,10
EX
12,Adder
JCT 12,Loop
ST
0,RegTotal
- - AR
0,0

Count in GR12
Execute add instruction, sum in GR0
Decrease counter and register digit
Store sum at RegTotal
R2 digit modified by EX

The R 2 digit of the AR instruction is modified in the IR to contain values from 10 to 1. It is


rare to use Execute instructions to modify register specification or mask digits of executed
instructions.
4. The fullword at Mask contains an integer whose value lies between 0 and 15, to be used as the
mask digit of a BC instruction branching to CondMet.

392

Assembler Language Programming for IBM z System Servers

Version 1.00

NotMet
BCInst

L
1,Mask
SLL 1,4
EX
1,BCInst
- - - - BC
0,CondMet

Get mask value


Position correctly as M1
Execute the BC
Fall through if condition not met
BC with mask of 0

To complete execution of the EX instruction, the mask digit in the rightmost byte of GR1 is
ORed into the BC instruction in the IR. The branch condition is now determined in the
usual way; if it is met, the branch address of CondMet will be placed into the IA in the PSW.
The execution of a successful branch instruction causes control to be taken away from the
EX instruction.
5. Branch to OddVal if the rightmost bit of GR9 is a 1-bit (that is, the number in GR9 is odd).

TMInst
OneBit

EX
9,TMInst
JNZ OddVal
- - TM
OneBit,0
DC
B00000001

Execute a TM instruction
Branch if a 1-bit
Test all 8 bits of next byte
Only rightmost bit = 1

In the IR, the rightmost byte of GR9 becomes the mask byte (the immediate operand, I2) of
the TM instruction. This mask then tests whatever bits of the byte at OneBit correspond to
1-bits in the mask. If the rightmost bit of GR9 is a 1-bit, the tested bits will not be all zero,
and the branch to OddReg will occur. (There are much easier ways to do this test!)
6. As a final (and more practical) example, suppose GR5 contains an integer specifying the
number of bytes to be moved from a string beginning at AA to an area whose address is contained in GR7. The number of bytes may be greater than 256.

Test

LMVC
Last
Finis

LTR
BNP
LA
CHI
JL
MVC
AHI
AHI
AHI
JNZ
J
MVC
BCTR
EX
- - -

5,5
Finis
1,AA
5,256
Last
0(256,7),0(1)
1,256
7,256
5,-256
Test
Finis
0(0,7),0(1)
5,0
5,LMVC

Test number of bytes to be moved


Exit if not greater than zero
GR1 contains from address
See if byte count exceeds 256
If not, do last part of move
Move 256 bytes
Increment from address
Increment to address
Decrease byte count by 256
If not zero, go try again
If count is zero, all done
Move last part of byte string
Decrease byte count by 1 for ex
Move last part of string
Rest of program goes here

Figure 220. Moving a string of bytes of unknown length

In Section 25, we will see how the MVCL and MVCLE instructions can handle such long
moves more simply.
Using an EX instruction to supply the length byte for an SS-type instruction is its most common
application.

24.11.3. Comments on the Execute Instructions (*)


1. The reason that an Execute instruction may not be the target of an Execute instruction (as
stated in step 3 on page 390) is that the CPU could remain in a Fetch-Decode loop (comprising steps 1 through 4 of the Execute-instruction description) if the Execute instruction
tried to execute itself, or if a chain of Execute instructions was circular. That is, consider what
could happen if the instruction
EX

0,*

What are we doing, and why???

Chapter VII: Bit and Character Data

393

is allowed. This loop is very awkward for a CPU to stop, and is avoided simply by not
allowing Executes of Execute instructions.144
2. When possible, place the target of an Execute instruction close to the EX.145
3. Be very careful when executing instructions with 12-bit opcodes, such as AHI. The low-order
digit of the R1 register should be zero, to avoid changing the opcode of the target.
4. Instructions that form Effective Addresses relative to an executed instruction use the address
of the target, not the address of the Execute instruction itself. For example, suppose GR9
contains a branch mask value in the next-to-rightmost hex digit, and we execute a Branch
Relative instruction:
EX
9,GoToXYZ
- - GoToXYZ BRC *-*,XYZ

Execute the relative branch


Branch if CC matches the mask bits

The CPU determines the Effective Address of the BRC instruction relative to its address, not
the address of the EX.
5. The Execute instruction was sometimes described as a special branch instruction! It is said
that EX causes an unconditional branch to the target instruction, followed by an unconditional branch back to the instruction following the EX, unless the target instruction is itself a
successful branch.
This incorrectly describes the contents of the Instruction Address, which remains at the
address of the instruction following the EX, and obscures the modification of the second byte
of the target instruction. This is sometimes described by saying the instruction is modified,
but remains unchanged in memory.
Both descriptions are misleading.
While this discussion of the IR may not be exactly whats done in z System processors, it does
describe the effect of the instruction, and gives a better feel for the way the CPU executes its
instructions. You need not believe in the magic of an instruction being simultaneously modified and remaining unmodified.

24.11.4. Modifiable Parts of Instructions


The highlighted parts of the operands in the instructions listed in Table 147 indicate the modifiable portions of typical instruction types as targets of the Execute instructions.

144

145

This is a fact of computing life that was learned the hard way: on some early processors, the only fix was to turn
off power and restart the machine. I knew a graveyard-shift computer operator on an older machine who discovered
how to create an Execute loop. Then, he would file a Computer Trouble Report for the engineers, and go home
early.
Some programmers use an idiom like this:
LA
BCTR
MVC
EX

1,N
1,0
A(*-*),B
1,*-6

Number of bytes to move


Make an machine length
Move only 1 byte from B to A
Move all N bytes from B to A

This is not generally recommended, because the CPU must process the MVC instruction twice.

394

Assembler Language Programming for IBM z System Servers

Version 1.00

Type
RR
RX, RXY
RS, RSY
SI, SIY
SS
RI

Operands
R1,R2
R1,D 2(X 2,B 2)
R1,R3,D 2(B 2)
R1,M 3,D 2(B 2)
R1,D 2(B 2)
D 1(B 1),I2
D 1(L,B 1),D 2(B 2)
D 1(L1,B 1),D 2(L2,B 2)
D 1(L1,B 1),D 2(B 2),I3
R1,I 2
M 1,I 2

Modifiable
R 1,R 2
R 1,X 2
R 1,R 3
R 1,M 3
R1
I2
L
L 1,L 2
L 1,I 3
R1
M1

Table 147. Modifiable portions of typical EX target instructions

Because the second byte of some instructions contains part of the operation code, there is usually
little reason to execute those instructions with a nonzero R1 digit.

Exercises
24.11.1.(2) What is the relationship between the USING statements in effect when an EX
instruction is assembled, and those in effect when the target instruction is assembled?
24.11.2.(2) + A programmer believed that EX branches to the target instruction, and then
branches back to the instruction following the EX if the target instruction was not a successful
branch. Consider the following code sequence:
Here
BASR1
There

EX
0,BASR1
- - - - BASR 1,0
- - -

What would he claim to be in GR1 after the EX is executed? What will be in GR1?
24.11.3.(2) + Suppose control passes to the following sequence of instructions:

BStar
BASR1

LA
EX
LR
B
BASR
AR
B

1,BStar
0,BASR1
0,0
*
1,0
0,0
BStar

Execute the BASR instruction


Do nothing in particular
Wait here for answer
Do something, maybe
Also do nothing in particular
Branch to waste some cycles

When control arrives at BStar, the address of some instruction should be in GR1. What is it?
What will be the value of the Instruction Length Code immediately after the EX instruction
has completed execution?
24.11.4.(2) + Rewrite Exercise 17.2.9 to use an EX instruction and eight TM instructions to test
the proper bit of the selected byte.
24.11.5.(3) We must move a number of bytes from a string whose starting address is contained
in GR1, to a string whose starting address is contained in GR2. The number of bytes to be
moved (which can be greater than 256) is in GR3. Write a code sequence to perform the
move.
24.11.6.(3) + Suppose you must scan a string of length L (where L 200) bytes starting at
DCData that may contain paired ampersands and apostrophes (as in a C-type character con-

Chapter VII: Bit and Character Data

395

stant). Write instructions to scan the string and move it to DCGen with each paired occurrence
replaced by a single occurrence. Store the length of the resulting string at DCGenL.
24.11.7.(2) In Exercise 24.9.13, the string at Text was assumed to be shorter than 256 characters. Repeat the exercise, now assuming that the strings length may be up to 14000 characters.
24.11.8.(3) + A string of M characters at Data is to be moved to an N-byte area named DataPad
and extended or padded with blanks if N > M. Assume that both M and N are 256, and
have been defined in EQU statements. If N < M, move only N bytes. (Dont use MVCL or
MVCLE!)
24.11.9.(3) In Exercise 24.8.4. you explained why CLC does not pad the shorter operand with
blanks. Write an instruction sequence that simulates the operation of a CLC instruction that
does pad the shorter operand with blanks. Your instructions must set the Condition Code correctly.
24.11.10.(3) Parentheses are used in many programming languages to enclose expressions,
denote groupings, and so forth. These parentheses must be balanced: that is, they must
match up so that (1) each left parenthesis has a matching right parenthesis that follows it
somewhere, (2) the leftmost parenthesis must be a left parenthesis, and (3) it must be matched
by the rightmost parenthesis. More formally, if L(n) and R(n) are the number of left and right
parentheses encountered after scanning n characters, and if there are N characters in the string,
then a balanced string must have L(n) R(n) for 0 < n < N, and L(N)=R(N).
Using appropriate TRT and EX instructions, write a program segment which will test a string
of characters for balanced parentheses. Assume initially that GR7 contains the address of the
string, and its length in bytes is a 32-bit binary integer in GR8. Branch to Balanced and
Unbalncd for successful and unsuccessful scans, respectively.
24.11.11.(2) + Modify the illustration of the fetch-decode-execute cycle in Figure 16 on page 58
to show how the Execute instruction and its target instruction are fetched and decoded. Indicate
explicitly where the test for an Execute exception is made.
24.11.12.(2) Suppose the bits within the byte stored at Rotator are to be rotated to the right N
bit positions, where N is defined by the three low-order bits in GR1. Write a code sequence,
including the necessary translate table or tables, to do the shift.
Can you devise a table which will accomplish the shift by executing only a single TR instruction?
24.11.13.(2) + In example 5 on page 393 in Section 24.11.2, we want to test for the presence of
a 1-bit in GR9. What will happen if the branch instruction is JO instead of JNZ?
24.11.14.(2) How can the code sequence in example 5 of Section 24.11.2 be modified to test if
the contents of some register is a multiple of a given power N of 2? What are the limitations on
this technique?
24.11.15.(2) + A programmer used an EX instruction to load the constant 137 into a general
register whose number was determined at execution time. He knew that the number of the
target register would be in the rightmost 4 bits of GR1, and wrote

LHIOp

EX 1,LHIOp
- - LHI 0,137

Load the constant into a GPR


Executed: load into the target GPR

This wont do what he wants. Explain why not, and show what he should have written.
24.11.16.(2) Write a code fragment using an Execute instruction that will convert the byte at
Byte to 8 EBCDIC characters starting at Char that represent the value of its 8 bits.
24.11.17.(2) Modify the coding in Figure 212 on page 387 to use EX instructions where appropriate.

396

Assembler Language Programming for IBM z System Servers

Version 1.00

24.11.18.(3) + Suppose your CPU has no MVCIN instruction, and you want to move the string
of L characters starting at Source to the string of L characters starting at Target in reverse
order. Assuming that 0 < L < 256 is a number in GR0, create an appropriate translate table
and instructions that will move the characters as required.
24.11.19.(2) + If c(GR1) = X FEDCBA98 , and you then execute this instruction:

Sub

EX
1,Sub
- - SR
5,2

what SR instruction will the CPU actually execute?


24.11.20.(2) How can an EX instruction choose one of multiple possible target instructions in a
single execution?

24.12. Summary
Remember:
The length you code in an SS-type assembler instruction statement (N)
specifies how many bytes are involved (unless you code zero, in which
case one byte always participates in the operation). The length you
specify as the R1 operand of an EX instruction (L) is one less than the
number of bytes involved.
For most instructions, operand overlap is not a problem.
If neither operand is changed (for example, by CLC and TRT), operand overlap doesnt
matter.
Most instructions operate as though the bytes of the source operand are fetched one at a time,
and the result byte is stored at the target operand before the next source byte is fetched.146
For other instructions, operand overlap can lead to unpredictable results.
Well note special cases as they arise.
Table 148 summarizes Tables 142 and 143 about explicit and implied length specification in
single-length SS-type instructions:
Explicit Length
S1(LE),S 2
D 1(LE,B 1),S2
S1(LE),D 2(B 2)
D 1(LE,B 1),D 2(B 2)

Implied Length
S1,S2
D 1(,B1),S2
S1,D 2(B 2)
D 1(,B1),D 2(B 2)

Table 148. Operands of single-length SS-type instructions

The instructions discussed in this section are shown in Table 149.

146

Modern processors may fetch, process, and store groups of several bytes, but the result still appears to be byte-at-atime operation.
Chapter VII: Bit and Character Data

397

Function
Move
AND
OR
XOR
Compare
Translate
Translate and Test
Translate and Test
Reverse
Execute

Instruction
MVC
MVCIN

Data is Processed
Left to right
Right to left

NC
OC
OC
CLC
TR
TRT
TRTR

Left
Left
Left
Left
Left
Left

No

right
right
right
right
right
right

Yes
Yes
Yes
Yes
No
Yes

Right to left

Yes

Depends on target

EX
EXRL

to
to
to
to
to
to

CC Set?

Table 149. Basic instructions for data in storage

Instructions Discussed in this Section


The instruction mnemonics and opcodes are shown in the following table:
Mnemonic
CLC

Opcode
D5

Mnemonic
MVCIN

Opcode
E8

Mnemonic
TR

Opcode
DC

EX

44

MVCOS

C80

TRT

DD

EXRL

C60

NC

D4

XC

D75E

MVC

D2

OC

D6

The instruction opcodes and mnemonics are shown in the following table:
Opcode
44

Mnemonic
EX

Opcode
D4

Mnemonic
NC

Opcode
DC

Mnemonic
TR

C60

EXRL

D5

CLC

DD

TRT

C80

MVCOS

D6

OC

E8

MVCIN

D2

MVC

D7

XC

Terms and Definitions


IR
Instruction Register; an internal register holding a target instruction so its second byte may
be modified by an Execute instruction prior to decoding.
target instruction
An instruction addressed by an Execute instruction.
Length Specification Byte
The second byte (L) of an SS-type instruction, one less than the length of its operand or
operands.
Length Expression
A value (N) coded implicitly or explicitly in a machine instruction statement for an SS-type
instruction, from which the Assembler derives the Length Specification Byte L.

398

Assembler Language Programming for IBM z System Servers

Version 1.00

Programming Problems
Problem 24.1.(2) Using the definitions in Exercise 24.11.10, write a program which will read
character strings from records and test for balanced parentheses. Print each string and a message
which indicates whether or not it is balanced. Assume that the first blank character ends the
character string.
Problem 24.2.(3) A perfect shuffle of a deck of 52 playing cards interleaves each card of the
top 26 cards with each card of the bottom 26, in exactly the same way for each shuffle.147 Thus,
after a single shuffle the order of the cards is 1, 27, 2, 28, ... 25, 51, 26, 52.
It is claimed that after a small number (less than 10) of perfect shuffles, the original order of the
cards is restored. Test this claim by writing a program using a TR instruction to perfectly
shuffle the numbers from 1 to 52. The results may be displayed in hexadecimal.
Just for fun, try your program for different (even!) numbers of cards to see how many shuffles are needed to recover the original order.
Problem 24.3.(3) Write a program to read 80-character records that should contain only
EBDCIC decimal digits or blanks. If any invalid character is found, display the record and the
column number where the invalid character was found.
Problem 24.4.(4) In storing data containing large numbers of characters, it is often useful to find
some way to compress the data. For example, if the data consists of 80-byte records that
rarely contain 80 nonblank characters, space might be saved if we discard the trailing blanks
(following the last nonblank character on the record, and place a control byte at the beginning
that gives the length of the remaining string. Thus, a record containing only an asterisk in
column 1 would be stored as the two bytes X015C , a saving of 78 bytes.
Many such compression schemes exist, and they can be simple or elaborate depending on the
needs of a particular situation. One packing method applicable to strings containing many
repeated characters is the following:148
1. Copy the first character of the record in its exact form.
2. Replace each subsequent character by the binary value (or difference) that when added to
the preceding characters value (ignoring carries) will produce the desired character.
3. When the difference is zero, indicating a redundant (repeated) character, that zero difference
is used as a flag, and the next character contains a count of the number of remaining repetitions.
4. Preceding each string of compressed text is a record length byte containing the number of
bytes in the string, including itself.
5. A record length byte containing zero indicates the end of the compressed text for that
record.
These examples may help:
Input String

Compressed Line Record

AAAAAAAAAA
AAAAABBBBB
BBAA
ABCDDDDDEFFGH

04
07
06
0D

C1
C1
C2
C1

00
00
00
01

08
03 01 00 03
00 FF 00 (no extra 00!)
01 01 00 03 01 01 00 00 01 01

(This compression scheme will require more space than the original text if the longest string of
repeated characters is of length 2, as in the third example.)

147
148

This is also known as an out-shuffle.


Due to J. E. Hunter, IBM Technical Disclosure Bulletin, Volume 15, Number 6, November 1972.
Chapter VII: Bit and Character Data

399

Write a program that will read 80-byte records and produce a block of compressed text records
in memory. For example, if there were only a single compressed text record (a single line of
text), as in the fourth example above, then the block in memory would contain 14 bytes:
0D C1 01 01 01 00 03 01 01 00 00 01 01 00
Then, de-compress the block of text, and print it. If you can, write your compressed text
onto records and give them to someone else to expand. Compare the expanded results to the
original records.
Problem 24.5.(4) + A common requirement in scanning character strings is that some character
positions must match a pattern exactly, while other positions may match any character. For
example, suppose a pattern is defined by C AB%CD , meaning that when scanning a test string,
AB must match the first two characters of the test string, the % means that any character in the
third position of the test string is acceptable, and CD must match the fourth and fifth characters of the test string. For example, this pattern would match the test string C AB?CD . but not
the test string C ABCDEF .
Write a program that will accept a pattern string (perhaps on a record with initial characters
Pattern ) followed by records containing test strings. Print the pattern, the test string, and an
indication of whether the pattern matches the test string or not.
Problem 24.6.(5) + This problem is an extension of Problem 24.5. In addition to a pattern character like % that will match an arbitrary character in a test string, it is often useful to match
some characters while some number of others need not be matched. For example, if a pattern
uses the character * to mean match any number of characters, including none, then the
pattern C A*B would match test strings like C AB and C A123B . Similarly, a pattern like C A*
would match test strings like C A and C ABCDEFG .
As in Problem 24.5, write a program that will accept various patterns followed by test strings,
and print the pattern, the test string, and an indication of whether the pattern matches the test
string or not.
Problem 24.7.(5) + Combine the two pattern types of Problems 24.5 and 24.6, so that a pattern
might look like C A%B*C , which would match test strings like C A.BC and C AJBRSTUVWC .
Problem 24.8.(2) A programmer claimed that he can convert the hex digits of a word stored at
Word to eight EBCDIC characters stored at HexWord representing the hex digits with these
instructions:
L
2,Word
L
4,=4X 0F
LR
3,2
SRL 3,4
NR
3,4
NR
4,2
STM 3,4,Temp
TR
Temp,=C0123456789ABCDEF
MVC HexWord,=X0004010502060307
TR
HexWord,Temp
- - Temp
DS
D
HexWord DS
CL8
Word
DC
X 1 F2E3D4C
(For example)
Write a program to test his claim with a variety of values at Word.
Problem 24.9.(2) Write a program to simulate the execution of the TR instruction.
Problem 24.10.(3) Write a program to simulate the execution of the TRT instruction, without
considering final Condition Code settings
Problem 24.11.(4) Write a program to simulate the execution of the TRT instruction, with
correct settings of the Condition Code when execution completes.

400

Assembler Language Programming for IBM z System Servers

Version 1.00

Problem 24.12.(3) + Write a program to display on three lines the 80-byte records of any short
program you wrote: on the first line, the original record (with double-spacing carriage control;
and on the second and third lines, each byte of the original line is shown in vertical hex,
where the first hex digit of the EBCDIC character is shown on the upper line, and the second
hex digit on the lower line. For example, the characters This is a TEST (or
X E38889A24088A2408140E3A5E2E3 ) would be arranged on 3 output records like this:
0This is a TEST
E88A48A484EAEE
38920820103523
The key to the solution is the translate table.
This technique can be very useful for displaying the contents of records (like object modules)
that contain a mixture of EBCDIC and binary values.
Problem 24.13.(3) Write a program to read the records shown below. The first record is a title
line, the next is blank, and the remaining records contain the name of a student and four exam
grades in columns 31-40, 41-50, 51-60, and 61-70.
Write a program to read the data and produce a report with the average grade for each student
in columns 71-80, and after the last students grades and average, skip a line and print the
average grade for each exam. For example, the output might be formatted like this:
Name

Exam 1

Exam 2

Exam 3

Exam 4

Average

Student 1
- - Student n

nn

nn

nn

nn

nn

nn

nn

nn

nn

nn

Exam Averages

nn

nn

nn

nn

nn

Exam 1

Exam 2

Exam 3

Final

79
44
97
61
90
79

83
91
89
71
90
83

88
67
80
85
88
88

93
89
73
97
92
47

This is some sample data:


Name
Doaks, Joe
Queue, Susie
Shakes IV, Pete
Burley, Hurley
Throckmorton, Chauncey
Doaks, Jonathan

Problem 24.14.(3) Write a program to read the records shown below, that contain the text of
Lincolns Gettysburg Address as a string of characters in fixed-format 80-byte records. You
will need a work area of about 2000 bytes.
Count and print the number of words.
These are the records for you to read:

Chapter VII: Bit and Character Data

401

Four score and seven years ago our fathers brought forth on this continent a ne
w nation, conceived in liberty, and dedicated to the proposition that all men a
re created equal. Now we are engaged in a great civil war, testing whether that
nation, or any nation, so conceived and so dedicated, can long endure. We are
met on a great battle-field of that war. We have come to dedicate a portion of
that field, as a final resting place for those who here gave their lives that t
hat nation might live. It is altogether fitting and proper that we should do th
is.
But, in a larger sense, we can not dedicate, we can not consecrate, we can not
hallow this ground. The brave men, living and dead, who struggled here, have co
nsecrated it, far above our poor power to add or detract. The world will little
note, nor long remember what we say here, but it can never forget what they di
d here. It is for us the living, rather, to be dedicated here to the unfinished
work which they who fought here have thus far so nobly advanced. It is rather
for us to be here dedicated to the great task remaining before us -- that from
these honored dead we take increased devotion to that cause for which they gave
the last full measure of devotion -- that we here highly resolve that these de
ad shall not have died in vain -- that this nation, under God, shall have a new
birth of freedom -- and that government of the people, by the people, for the
people, shall not perish from the earth.

Problem 24.15.(4) Write a program to read the same records as in Problem 24.14. Now, create a
table of distinct words, ignoring differences between lower and upper case forms of the same
word. Sort the words into alphabetical order, and print the words and the number of occurrences of each.
Problem 24.16. Write a program to read the same records in Problem 24.14.
Your program should then create a readable version of the text on lines of 60 characters, with
words correctly joined where they were split across the original records. No characters may go
past the end of the 60-character output line. For example, if two input records contain something like this:
 80 characters 
word1 word2 word3 word4 word5 word6 word7 word8 word9 wordiness wordA wordB word
C wordD wordE ...

then your formatted line would contain something like this:


 60 characters 
word1 word2 word3 word4 word5 word6 word7 word8 word9
wordiness wordA wordB wordC wordD wordE ...

If you encounter a completely blank line in the input, leave a blank line in the formatted
output.
You might enjoy making the width of the output line depend only on a symbol defined by an
EQU statement; try values such as 60, 80, and 100.
Problem 24.17.(4) Write a program to read the data in Problem 24.14. Create an output area of
the same size as your input area. Now, you will encrypt the records from the input to the
output areas. Create a key by defining a suitably random binary fullword from a 9-digit
decimal value. Then, encrypt the input message as follows:
1. XOR your key with the first word of the input message, and store the result in the output
buffer.
2. XOR that result with the second word of the input message, and store the result in the
second word of the output buffer.
3. Continue in this way until the entire message has been encrypted.

402

Assembler Language Programming for IBM z System Servers

Version 1.00

Then, create a third buffer of the same length as the input buffer. Using your key, decrypt the
message in the output into this third buffer, using the same technique. Then, compare your
decrypted result with the original. (They should be identical!)
Problem 24.18.(3) Write a program to read records with blank-terminated strings of octal (base
8) digits. Assuming the octal digits represent a right-adjusted binary number, convert the digits
to binary represented as a string of hexadecimal digits. Then, display the original octal digit
string followed by the converted hex string.
Remember that the rightmost octal digit contains the three low-order bits of the binary
number, so that octal 76543 (O76543? Whats its value in decimal?) is the same as X 7 D63 .

Chapter VII: Bit and Character Data

403

25. Character Data and Extended Instructions

2222222222
222222222222
22
22
22
22
22
22
22
22
22
222222222222
222222222222

55555555555
555555555555
55
55
555555555
5555555555
555
55
55
555
55555555555
555555555

All the instructions discussed thus far complete their task before the next instruction is processed.
In this section, well look at some instructions that may take much longer to complete. This
means that if the CPU is interrupted by a high-priority request, something must be done about
the current instruction. The CPU handles this in one of two ways:
Method A: Save enough information in the general registers about the intermediate state of the
instruction, reset the Instruction Address back to the address of the interrupted instruction,
and then process the interrupt. When execution of your program resumes, the interrupted
instruction continues from its intermediate state as though it had not been interrupted.
Method B: Process a portion of the operands, update registers appropriately, and set the Condition Code to 3 to indicate that the operation was only partially completed. Any pending
interruptions can then occur. The Instruction Address is not reset, so the following instruction
should test for CC=3 and branch back to the interrupted instruction so it can complete the
operation.
Well see each method in the instructions in this section.
The processed portion of the operands can vary greatly from instruction to instruction, and for
repeated executions of the same instruction.

25.1. Move Long and Compare Logical Long


These instructions also use a special padding character, or an end (or stop, test, search,
special, terminating) character.149 All the instructions in Table 150 use a padding character.
Op
0E
0F

Mnem
MVCL
CLCL

Type Instruction
RR
Move Long
RR
Compare Logical Long

Op
A8
A9

Mnem
Type Instruction
MVCLE RS
Move Long Extended
CLCLE RS
Compare Logical Long
Extended

Table 150. Character-handling instructions using padding characters

149

404

The appropriate name for the end character depends on how its used; some names are more descriptive than
others for a given instruction.
Assembler Language Programming for IBM z System Servers

Version 1.00

We begin by examining the Move Long (MVCL) and Compare Logical Long (CLCL)
instructions in a general way. Both are RR-type instructions with the usual format, and they
both use four general registers! The instruction formats are
MVCL R1,R2
CLCL R1,R2
where both R 1 and R 2 designate an even-odd pair of registers. (A specification exception occurs if
either R 1 or R 2 is odd.) The even-numbered registers contain the operand addresses, and the nexthigher odd-numbered registers contain the operand lengths; each length is treated as a 24-bit
unsigned number. The high-order byte of R 2 + 1 contains the padding byte, as sketched in Figure
221. (Register lengths and addressing modes are ignored for a moment.)

Operand 1 address

////////////////////////////////////////
Operand 1 Length

Operand 2 address

///////////////////////////////pad byte
Operand 2 length

0
31 32
40 41
63

GPR R1
GPR R1 +1
GPR R2
GPR R2 +1

Figure 221. Register use by CLCL and MVCL

MVCL and CLCL simplify moving and comparing long strings of bytes, which would otherwise
require lengthy loops.
These instructions are unlike MVC and CLC in several respects.
Two lengths are specified; the operands may have different lengths, and the instructions depend
on both lengths.
Much longer strings of bytes may be compared or moved in a single instruction. Instead of a
limit of 256 bytes, MVCL and CLCL can specify up to 224 1 bytes.150
All four registers may be changed by the instructions. The addresses in the even-numbered
registers depend on the addressing mode.
The lengths are true lengths rather than machine lengths (the true length minus 1). Only the
24 low-order bits of R1 + 1 and R 2 + 1 (containing the operand lengths) are updated, and the
remaining bits are unchanged.
The high-order byte of R2 + 1 holds a pad byte used to extend certain operands, if necessary.
The MVCL instruction sets the Condition Code, and no data movement takes place if there is
any possibility of destructive overlap of the operands.
Either R 1 or R 2 may be zero, so that GR0 may contain an operand address!
Both instructions are interruptible: if an interrupt occurs before the operation is complete,
Method A is used: the registers are updated appropriately, and the Instruction Address in
the the PSW is backed up by 2 bytes from the address of the following instruction to the
address of the CLCL or MVCL instruction. When control is returned to the interrupted
program, execution of the instruction resumes with the remnants of the operands.

150

At the time MVCL and CLCL were implemented, The operand length of 2 24 1 bytes seemed sufficient for many
years. But memory sizes grew rapidly, so MVCLE and CLCLE were added to handle longer compare and move
operations. Well see them in Section 25.2.
Chapter VII: Bit and Character Data

405

25.1.1. MVCL
In the absence of special conditions, MVCL operates by moving bytes from the second (source)
operand field to the first (target) operand field. As noted in our discussion of implied lengths in
Section 24.3, the number of bytes moved is controlled by the first (receiving) operand length.
Thus, if the first operand length is zero, no bytes are moved.
Unlike MVC, MVCL tests for the possibility of destructive overlap, which occurs when any part
of the first operand field is used for a source after data has been moved into it. If destructive
overlap could occur, the CPU sets the Condition Code to 3, and moves no data.
Execution of MVCL proceeds (conceptually) as follows:
1. Bytes are moved one by one from the second to the first operand field; the counts are decremented by 1 and the addresses are incremented by 1 for each byte moved.
2. If both operand counts reach zero at the same time, the CC is set to 0.
3. If the first operand count reaches zero before the second operand count, the CC is set to 1.
That is, the target length in R1 + 1 less than the source length in R2 + 1.
4. If the second operand count reaches zero first, the pad character is used as a source byte until
the first operand count reaches zero; the CC is then set to 2. That is, the target length in
R 1 + 1 greater than the source length in R2 + 1.
5. On termination, the operand 1 length is zero, and the operand 1 address has been updated by
the corresponding length. The operand 2 address has been incremented by the number of
bytes moved from the second operand field whether or not padding has occurred, and the
second operand count has been decreased by the same amount.
6. On termination (even for destructive overlap),
in 24-bit addressing mode, the leftmost byte of GR R 1 and GR R 2 are zeroed, and the
high-order half of GG R 1 and GG R 2 are unchanged;
in 31-bit addressing mode, the leftmost bit of GR R 1 and GR R 2 is zeroed, and the highorder half of GG R 1 and GG R 2 are unchanged;
in 64-bit addressing mode, both GG R 1 and GG R 2 are updated.
MVCL sets the Condition Code as shown in Table 151.
CC
0
1
2
3

Meaning
Operand 1 length = Operand 2 length
Operand 1 length < Operand 2 length; part of operand 2 not moved
Operand 1 length > Operand 2 length; operand 1 was padded
Destructive Overlap, no data movement

Table 151. CC settings after MVCL

Figure 222 may help you to to visualize the operation of MVCL, assuming there is no destructive
overlap. The figure uses these notations:
A1
c(A1)
L1
A2
c(A2)
L2
Pad

406

Address of a first-operand byte, c(R1)


The first-operand byte at address A1
Remaining length of the first operand, c(R1 + 1)
Address of a second-operand byte, c(R2)
The second-operand byte at address A2, c(R2 + 1)
Remaining length of the second operand
Padding byte

Assembler Language Programming for IBM z System Servers

Version 1.00

START L1=0? L2=0? c(A1)Pad




No
No
Yes


Yes

A1=A1+1

c(A1)c(A2)
L1=L11




A1=A1+1
L1=0?


A2=A2+1
Yes 

L1=L11
No

Done; if
L2=L21

Done;
L2=0 CC0 Yes


Set
else CC1 L1=0?

CC1,2

No

Interrupt
PSW IA = IA2
 Pending? Process interrupt
No
Yes
Figure 222. Execution of the MVCL instruction

To illustrate some uses of MVCL, suppose we want to set the area at Line to blanks (as in
example 1 of Section 24.6).
LineLen Equ
SR
ICM
LA
L
MVCL

120
1,1
1,8,=C
2,Line
3,=A(LineLen)
2,0

Number of blanks to move


Operand 2 length = 0
Pad character is blank
Set address of first operand in GR2
And first operand length in GR3
Move pad characters to Line

Figure 223. Using MVCL to set a field to blanks

Because the second operand length in GR1 is zero, we need not initialize GR0 with an address.
This method is a lot more work than the example in Section 24.6, because we must set up four
registers and a pad byte. However, MVCL is superior to MVC when the number of bytes to be
moved grows large: by omitting the ICM (which inserts the padding character into R1), we could
just as easily have set the area to zero, as in example 1 of Section 24.7. MVCL is often used this
way to zero large blocks of memory without having to use XC instructions, and to initialize areas
without using MVC instructions with overlapping operands.
Suppose GR8 and GR9 contain the address and length of a message which is to be moved to the
120-byte area at PrintMsg. We will pad the message with blanks, and branch to WontFit if all of
the message wont fit in the 120-byte area.
LA
LA
ICM
MVCL
JH
JO

2,PrintMsg
3,L PrintMsg
9,8,=C
2,8
WontFit
NotMoved

First operand address


First operand length
Set padding character to blank
Move the string, pad if necessary
Branch if something left over (CC1)
Error, destructive overlap (CC3)

Figure 224. Moving a message with padding and length checking

No Execute instruction (or STC, to store a length byte into an MVC) was needed to supply the
Length Specification Byte for the move.

Chapter VII: Bit and Character Data

407

25.1.2. CLCL
The two operand byte strings are compared byte by byte as unsigned binary numbers (just as for
CLC), starting at the low-addressed end and proceeding toward higher addresses. The comparison stops when an inequality is detected, or when the end of the longer operand is reached (not
the shorter!). Unlike MVCL, where only the first operand might be padded, CLCL can pad either
operand! The CC is set in the usual way to indicate the result of the comparison. If both operand
lengths are zero, or if R1 and R 2 designate the same register, the CPU simply sets the CC to zero,
indicating equality.
The comparison can be considered as proceeding in the following way:
1. Bytes are compared one by one; the operand addresses are incremented by 1 and the operand
lengths are decremented by 1 for each step.
2. If an inequality is detected before either length becomes zero, the CC is set, registers R1 and
R 2 contain the addresses of the unequal bytes, and the counts in the rightmost 24 bits of the
respective odd-numbered registers tell how many bytes remain to be compared. The CC
setting indicates the larger or smaller operand.
3. If one of the lengths becomes zero, the comparison continues with the padding character
being compared to bytes from the longer operand. For the shorter operand, the even register
contains the address of the first byte past the end of the operand string, and the odd register
contains zero.
4. If an inequality is detected between the padding character and a byte from the longer
operand, the address and count for that operand are set as in step 2 (the address and count
for the shorter operand were set in step 3).
5. If no inequality is detected before the longer count becomes zero, the even-numbered register
points to the first byte past the end of the longer operand string.
6. The register contents on termination are the same as shown for MVCL in step 6.
If the two operands are completely equal (including the padding character, if needed), both counts
will be zero, and the corresponding addresses will have been incremented by the original count
values.
CLCL sets the Condition Code as shown in Table 152.
CC
0
1
2

Meaning
Operand 1 = Operand 2, or both 0 length
First operand low
First operand high

Table 152. CC settings after CLCL

Figure 225 may help clarify this description. The figure uses notations similar to those preceding
Figure 222 on page 407:
A1
c(A1)
L1
A2
c(A2)
L2
Pad
x:y

408

Address of a first-operand byte, c(R1)


The first-operand byte at address A1
Remaining length of the first operand, c(R1 + 1)
Address of a second-operand byte, c(R2)
The second-operand byte at address A2
Remaining length of the second operand, c(R2 + 1)
Padding byte
x is compared to y

Assembler Language Programming for IBM z System Servers

Version 1.00

START L1=0? L2=0? c(A1):Pad


Yes
No
No
Yes
=/
=




 Pad:c(A2)  L2=0?
c(A1):c(A2) 

/=
=
Yes
=
/=







A2=A2+1

A1=A1+1

A1=A1+1
Done; L2=L21
Done;
A2=A2+1
Done;
L1=L11
Set

Set
L1=L11
Set

CC1,2

CC0
L2=L21
CC1,2




START  Interrupt pending? PSW IA = IA2


No
Yes Process interrupt

Figure 225. Execution of the CLCL instruction

The greater power of CLCL compared to CLC is seen in the changes to the four registers at the
end of the operation. Not only do you know exactly how many bytes were compared, but the
precise position of the inequality is known, which is impossible with CLC unless the bytes are
compared one at a time. 151 By testing the lengths for zero, you can tell whether an inequality
occurred between bytes in memory, or between the padding character and a byte in memory.
To illustrate CLCL, suppose we want to see if all 120 bytes at Line contain blanks, and branch to
AllBlank if so.
LA
LA
SR
ICM
CLCL
JE
- - -

2,Line
3,120
1,1
1,8,=C
2,0
AllBlank

First operand address in GR2


First operand length in GR3
Second operand length = 0
Pad character is blank
Compare first operand to blank
Branch if all blanks at Line
GR2 points to first nonblank char

Figure 226. Using CLCL to test for blanks

Because the length of the second operand in GR1 is zero, no address is needed in GR0.
Suppose we have read two records into memory, and want to determine if they are equal; let the
addresses and lengths of the records be stored in fullwords at Addr1, Len1, Addr2, and Len2
respectively.
If the records are unequal up to the length of the shorter record, we will branch to UnEqual.
We branch to Equal if their lengths and contents are identical.
We branch to Equal1 or Equal2 respectively if the operands are equal up to the shorter length,
but operand 1 or operand 2 is longer.
Neither operand may be padded.

151

For long strings of bytes, this could be painfully slow.


Chapter VII: Bit and Character Data

409

L
L
L
L
LA
CLR
JE
JH
LA
LR
J
Op1Long LA
LR
Compare CLCL
JNE
BR

2,Addr1
3,Len1
6,Addr2
7,Len2
1,Equal
3,7
Compare
Op1Long
1,Equal2
7,3
Compare
1,Equal1
3,7
2,6
UnEqual
1

Set first operand address


And length of first record
Set second operand length
And length of second operand
Assume lengths are equal
Compare lengths
Go compare if equal lengths
Branch if operand 1 longer
Operand 2 longer, set equality exit
2nd operand length = shorter value
And compare
Operand 1 longer, set equality exit
1st operand length = shorter value
Compare operands with equal lengths
Branch if inequality detected
Branch to desired equality routine

Figure 227. Comparing two records without padding

The preliminary effort in this example ensures that GR3 and GR7 will both contain the shorter
operand length when the CLCL is executed. This illustrates precautions we must take if we dont
want the shorter operand to be extended with a padding character.

Exercises
25.1.1.(1) Why does using GR0 for an operand address not violate the rules given in Section 10,
where GR0 cant be used to generate an Effective Address?
25.1.2.(2) + What do you think will happen if MVCL is the target of an EX instruction, and an
interruption occurs before the MVCL operation is completed?
25.1.3.(1) Using MVCL, is there any possibility of destructive overlap if the length of the
second operand is 1?
25.1.4.(1) Suppose the operand 1 length of an MVCL instruction is zero. What will be the CC
setting?
25.1.5.(2) + A 3500-byte area at Field contains a value in its first byte that is to be propagated
through the rest of the area (all 3500 bytes are to contain that value). Write a code sequence
using MVCL to perform the task.
25.1.6.(3) + It is claimed that destructive overlap will not occur with MVCL if
operand 1 address operand 2 address, or
operand 1 address > operand 2 address + MINLEN 1
where MINLEN is the smaller of the two operand lengths. Is this true? Why?
25.1.7.(2) + Suppose we execute this instruction sequence:
LA
LA
LA
LA
ICM
CLCL

0,STR1
1,L STR1
2,STR2
3,L STR2
3,8,PAD
0,2

Address of first operand string


Length of first operand string
Address of second string
Length of second string
Padding character in GR3
Compare STR1 to STR2

For each of the following sets of definitions of the symbols STR1, STR2, and PAD, show what
will be in GR0 through GR3 and the CC setting after the CLCL is executed. (Assume that the
address of the symbol STR1 is X74212D0 in each case.)

410

Assembler Language Programming for IBM z System Servers

Version 1.00

(a)

STR1 DC
STR2 DC
PAD DC

F 1
F 2
X 0

(b)

STR1 DC
STR2 DC
PAD EQU

CL120
110C
STR2

(c)

STR1 DC
STR2 DC
PAD DC

CL20 **
C **
H 4 0

(d)

STR1 DC
STR2 DC
PAD DC

0XL5
C ABCD
X FF

25.1.8.(2) Sketching MVCL operands and their lengths sometimes helps you understand when
destructive overlap may occur. For example, in this sketch,
Source operand

Target operand

No destructive overlap

no destructive overlap occurs because no target operand byte is used as a source operand byte if
data is moved one byte at a time. Sketch other possibilities to determine when destructive
overlap will and will not occur.
25.1.9.(3) As in Exercise 24.11.15, use one or more MVC instructions to move a string of bytes
whose address is in GR1 to an area whose address is in GR2; the number of bytes in GR3 is
greater than zero and less than X FFFFFF . Perform these additional tests:
1. If the strings overlap destructively branch to Destroy with no data having been moved.
2. If the data strings overlap, but no data is destroyed, perform the move and then branch to
Overlap.
25.1.10.(3) What factors must be considered if you write instructions to emulate the behavior of
CLCL?
25.1.11.(2) Rewrite the example in Figure 226, reversing the operands: that is, make the first
operand have zero length.
25.1.12.(1) Revise Exercise 24.8.5 to use a CLCL instruction.
25.1.13.(1) Can you do a ripple move with MVCL, as you can with MVC?
25.1.14.(1) + Revise Figure Figure 223 on page 407 to initialize to zero the 8192 bytes starting
at New.
25.1.15.(4) Suppose you are using a CPU that does not support the MVCL instruction. Write
instructions (not using MVCL!) to simulate MVCL, including correct Condition Code settings.

25.2. Move Long and Compare Logical Long Extended


These two instructions are only slightly more complicated than MVCL and CLCL. Both
instructions use Method B to allow the CPU to process interruption conditions. Table 153
gives their format:
opcode

R1

R3

B2

DL 2

DH2

opcode

Chapter VII: Bit and Character Data

411

Table 153. Format of MVCLE and CLCLE instructions

There are three operands: the operands in the even-numbered registers R1 and R 3 are analogous
to the R 1 and R 2 operands of MVCL and CLCL. The second operand is not used as an address;
instead, the low-order 8 bits of its Effective Address are used as the padding byte.

/////////////
///////// pad Second operand s Effective Address

For example, to specify a blank padding character, you could write
MVCLE 2,8,C ( 0 )
CLCLE 4,14,X40(0)
Another difference is that the odd-numbered registers hold the 32-bit (or 64-bit) operand lengths,
which can be from 0 to 232 1 (or from 0 to 264 1 for 64-bit addressing mode).

Operand 1 address

Operand 1 length

Operand 3 address

Operand 3 length

GPR R1
GPR R1 +1
GPR R3
GPR R3 +1

Figure 228. Register use by MVCLE and CLCLE

If these instructions are executed in 24- or 31-bit addressing modes, the rightmost 24 or 31 bits of
the even-numbered registers contain the operand addresses. On termination, the high-order (nonaddress) bits of the R1 and R 3 registers may or may not be set to zero.152

25.2.1. MVCLE
Unlike MVCL, no overlap test is done for MVCLE; the results of overlapping operands are
unpredictable. Its execution is sketched in Figure 229, using similar notations as in Figure 222,
except that the source operand address is A3 and the source operand length is L3.

152

412

This is not just a whim on the part of the CPU; its meant to give the CPU designers more freedom to decide how
best to implement the instructions. (Maybe its a whim on the part of the CPU designers?.)
Assembler Language Programming for IBM z System Servers

Version 1.00

START L1=0? L3=0? c(A1)Pad




No
No
Yes


Yes

A1=A1+1

c(A1)c(A3)
L1=L11




A1=A1+1
L1=0?


A3=A3+1
Yes 

L1=L11
No

Done; if
L3=L31

Done;
L3=0 CC0 Yes


Set
else CC1 L1=0?

CC1,2

No

Enough

 for now? Done; Set CC3


No
Yes
Figure 229. Execution of the MVCLE instruction

On termination, the register contents are:


1. If the first operand has been completed, the CC is set to 0 if the two operand lengths are
equal.
2. If the first operand has been completed, the CC is set to 1 if the first operand is shorter than
the second.
3. If the first operand has been completed, the CC is set to 2 if the first operand is longer than
the second (meaning that the first operand was padded).
4. If the CPU has moved enough bytes and wants to pause for any pending interruptions, the
CC is set to 3. You would then branch back to the MVCLE instruction to resume the move.
5. Whatever the reason for termination, the registers are updated to account for the amount of
data that has been moved.
6. Some special padding byte values can be used to improve the performance of MVCLE; see
the z/Architecture Principles of Operation for details.
To summarize, MVCLE sets the Condition Code as shown in Table 154.
CC
0
1
2
3

Meaning
All bytes moved, operand lengths are equal
All bytes moved, operand 1 shorter; part of operand 2 was not moved
All bytes moved, operand 1 longer; operand 1 was padded
Some bytes moved; end of operand 1 not reached

Table 154. CC settings after MVCLE

We can use MVCLE for the same task as in Figure 223 on page 407, where we again assume
that GR8 and GR9 have been initialized already:

Move

LA
LA
LA
MVCLE
JO

2,PrintMsg
3,L PrintMsg
0,C
2,8,0
Move

First operand address


First operand length
Set padding character to blank
Move the string, pad if necessary
Repeat if not finished

Figure 230. Using MVCLE to set a field to blanks

As another example, suppose we use MVCLE to initialize a large area of storage starting at Work
to zeros:

Chapter VII: Bit and Character Data

413

Clear

XR
XR
LA
L
MVCLE
JO

BlockLen Equ
NBlocks Equ
WorkSize DC

0,0
1,1
2,Work
3,WorkSize
2,0,X 0 0
Clear

Source address will be ignored,


...because source length is zero
Start of area to initialize
Length of work area
Initialize with X00 padding
Repeat if necessary

32000
20000
A(BlockLen*NBlocks)

Large area

Figure 231. Using MVCLE to initialize an area to zero

Its unlikely that youd ever need to initialize such a large an area of storage; because the value at
WorkSize is larger than 224, we cant use MVCL.
It may or may not be important to your application that MVCLE does not check for overlap.

25.2.2. CLCLE
CLCLE operates in much the same way as CLCL, as sketched in Figure 232, using the same
notations as in Figure 225, except that the source operand address is A3 and the source operand
length is L3.
START L1=0? L3=0? c(A1):Pad
Yes
No
No
Yes
=/
=




 Pad:c(A3)  L3=0?
c(A1):c(A3) 

/=
=
Yes
=
=/







A3=A3+1

A1=A1+1

A1=A1+1
Done; L3=L31
Done;
A3=A3+1
Done;
L1=L11
Set

Set
L1=L11
Set

CC1,2

CC0
L3=L31
CC1,2




START  Enough for now? Done; Set CC3


No
Yes
Figure 232. Execution of the CLCLE instruction

On termination, the registers are set as follows:


1. If an inequality is found, the CC is set as shown in Table 157.
2. If the operands are equal (including the padding byte, if used), the addresses and lengths are
updated to account for the number of bytes compared.
3. If the CPU has compared enough bytes without an inequality and wants to pause for any
pending interruptions, the CC is set to 3. You would then branch back to the MVCLE
instruction to resume comparing.
In summary, CLCLE sets the Condition Code as shown in Table 155.
CC
0
1
2
3

Meaning
All bytes compared, operands equal, or both zero length
First operand low
First operand high
Some bytes compared without finding an inequality

Table 155. CC settings after CLCLE

414

Assembler Language Programming for IBM z System Servers

Version 1.00

To illustrate, well rewrite Figure 221 on page 405 to use CLCLE:


LA
LA
XR
XR
Compare CLCLE
JE
JO
- - -

2,Line
3,120
0,0
1,1
2,0,C
AllBlank
Compare

First operand address in GR2


First operand length in GR3
Second operand address is ignored,
...because its length is zero
Compare first operand to blanks
Branch if all blanks at Line
Repeat if comparison is incomplete
GR2 points to first nonblank char

Figure 233. Using CLCLE to test for all blanks

The similarities of CLCL and CLCLE are close; only the operand lengths and the source of the
padding byte are different. But, the differences between CLC and CLCL/CLCLE are more significant:
CLC requires only one or two base registers to address the operands; CLCL/CLCLE both
require four registers.
CLC is limited to 256-byte operands; CLCL/CLCLE operands can be much longer.
CLC simply indicates an inequality; CLCL/CLCLE also set R1 and R 2 to the addresses of the
unequal bytes.
CLC does no padding; CLCL/CLCLE support a padding character.

Exercises
25.2.1.(2) What do you think will happen if the B2 register of a CLCLE or MVCLE instruction
is the same as R1 or R 3 or R 1 + 1 or R 3 + 1?
25.2.2.(1) + Can both operands of CLCL or CLCLE be padded?
25.2.3.(2) In 24-bit addressing mode, the maximum valid address is X00FFFFFF , or 224 1.
However, MVCLE allows you to specify operand lengths up to X FFFFFFFF , or 232 1. What
do you think will happen if you execute MVCLE with a length longer than X FFFFFF ?
25.2.4.(1) In Figure 231 on page 414, what is the hex value of the word at WorkSize?
25.2.5.(2) Let NB2M be the number of bytes to be moved to Tgt from the second operand
field at Src by MVCL. Make a table which gives the initial and final register contents, and the
value of NB2M, for each of the possible resulting CC values when all bytes have been moved.
Then, do the same for MVCLE.

25.3. Special String-Handling Instructions


The four instructions in Table 156 arose from the need to process character strings used by the C
and C+ + programming languages, where character strings are terminated by a zero byte (X 0 0 )
called a null byte.153 The instructions have many general uses, whatever the origins of the data,
and whether or not it contains a null terminating byte.
We will use a bold italic letter n to represent a null byte, as in n. For example,
DC

153

C A C-string. , X 0

Generates A C-string.n

The earliest implementations of C were done on machines with instructions that could move bytes and simultaneously
test their values, so very few instructions were needed to move null-terminated character strings.
Chapter VII: Bit and Character Data

415

The length of a C-string* does not include the terminating null character, so that the single byte
X 0 0 represents a C-string of length zero (a null string).
Op
B255
B25E

Mnem
MVST
SRST

Type Instruction
R R E Move String
R R E Search String

Op
Mnem
B25D CLST
B2A5 T R E

Type Instruction
R R E Compare Logical String
R R E Translate Extended

Table 156. Character-handling instructions for terminated strings

These instructions all have RRE format, as shown in Table 157:


opcode

R1

R2

Table 157. Format of RRE-type instructions

Each instruction uses a special (end, test, or terminating) character in the rightmost byte of GR0.
All but TRE require that the remaining bits of GR0 be zero.
The operation of the MVCL, MVCLE, CLCL, and CLCLE instructions is controlled by a length
in a register; the four instructions in Table 156 are controlled by the presence of the special character in one or both operands. Only TRE uses both a length and a terminating character.

Exercises
25.3.1.(1) + Write DC statements defining C-strings of length zero, one, and ten.

25.4. Search String Instruction


The SRST instruction is the simplest of these four instructions. It scans the second operand
string addressed by register R2, looking for a byte matching the specified test character in GR0.
If a matching byte is found, the R1 register is set to its address. Because the second operand
string can be very long, the CPU uses Method B to process part of the string before checking
for interruptions.
For finding a single character, SRST is simpler and faster than a Translate and Test instruction
like TRT, or a CLI loop. Unlike TRT, however, it searches for only a single character.
To use SRST, set the test character in GR0, set the R 2 register to the address of the leftmost byte
of the string to be scanned, and the R1 register to the address of the first byte after the end of the
string. The CPU uses the address in the R1 register to know when to stop the scan; otherwise, it
could keep scanning bytes in memory until it found a match somewhere, or caused an unexpected
interruption. This is summarized in Figure 234.
R2
R1

string to be searched

Figure 234. Registers bounding the SRST search string

Table 158 gives the Condition Code settings after SRST:

416

I know of no programming language named G


Assembler Language Programming for IBM z System Servers

Version 1.00

CC
1
2
3

Meaning
Test character found; R1 points to it
Test character not found before the byte addressed by R1
Partial search with no match; R1 unchanged, R 2 points to next
byte to process

Table 158. CC settings for SRST instruction

On completion, either or both of the R 1 and R 2 registers may be updated:


If the CC is 1, the R1 register is updated and the R2 register is unchanged.
If the CC is 2, both the R1 and R 2 registers are unchanged.
If the CC is 3, R1 is unchanged and R2 is updated to the address of the next byte to be tested.
You can then branch back to the SRST instruction to continue the search.
When a register is updated, any high-order bits not used for addressing are set to zero. Figure 235
sketches the operation of the SRST instruction. The notation used in the figure is:
A1
A2
Test

Address of the first byte after the end of the string being searched
Address of a byte being checked during the search
Test character in GR0
Yes
START Save R1,R2 A1A2? Done: Reset

No
R1,R2;

Set CC2


Yes
c(A2)=Test? Done: R1
A2;

No
Reset R2;


Set CC1

A2=A2+1

No

Yes
 Enough Done: Set CC3
for now?

Figure 235. Execution of the SRST instruction

For example, suppose you want to scan the string at MyData to find the first occurrence of a blank
character:

Repeat

LA
LA
LA
SRST
JO
JH
- - -

0,C
1,MyData
5,MyData+L MyData
5,1
Repeat
NotFound

Search character is a blank


Set GR1 to start of the string
Set GR5 to byte past end of string
Scan the string for a blank
Scan was incomplete, try again
CC2, no blank was found
GR5 points to the blank

If the Condition Code is 3, we simply branch back to the SRST to continue the search.

Exercises
25.4.1.(2) Write a sequence of instructions to find the last nonblank character in a C-string of
fewer than 256 characters stored at CData. If no nonblank characters are found, branch to
AllBlank.

Chapter VII: Bit and Character Data

417

25.4.2.(2) + The C/C++ programming languages define the strlen function to return the length
of a C-string argument. Suppose a C-string of unknown length is stored at WorkArea. Store its
length in the word at WorkLen.
25.4.3.(3) The C/C++ programming language function memchr searches the first N bytes of a
C-string argument to find the first occurrence of a given byte. Suppose a C-string of unknown
length is stored at WorkArea, and you want to find an occurrence in the string of the byte stored
at FindByte, and the maximum number of bytes to search is stored in the word at N. If the
desired character is found, put its address in GR1; if not found, set GR1 to zero.
25.4.4.(2) A single byte is stored at OddByte. Write instructions to search for its first occurrence
in the C-string stored at Clutter. If found, set GR9 to the address of the first occurrence; if
not found, set GR9 to zero.
25.4.5.(3) Suppose your program processes words and sentences, and you must alternately
search for the blank ending a word and a nonblank starting the next word. Write a sequence of
instructions that show how to scan a string at TextLine and build arrays containing (a) the
length of each word, and (b) its starting address.
25.4.6.(4) Repeat Exercise 25.4.5 but assume that the words might be followed by punctuation
characters that should not be stored as part of the word.

25.5. Move String Instruction


The MVST instruction moves bytes from the second operand to the first, testing each source byte
for the ending character. If the entire operand (including the ending character) has been moved,
the CPU sets Condition Code 1, and sets the R 1 register to the address of the ending character. If
some bytes remain to be moved, the addresses in R1 and R 2 are updated to point to the next
bytes to be processed, unused high-order addressing bits are set to zero, and the Condition Code
is set to 3.
CC
1
3

Meaning
Entire second operand moved; R 1 points to end of first operand
Incomplete move; R 1 and R 2 point to next bytes to process

Table 159. CC settings for MVST instruction

Figure 236 sketches the operation of the MVST instruction.

START c(A1) c(A2) c(A2) = End Char? Done; Set CC1



No
Yes

A1=A1+1

A2=A2+1

No

Yes
 Enough Done; Set CC3
for now?

Figure 236. Execution of the MVST instruction

The following example moves a null-terminated string from Old to New.

418

Assembler Language Programming for IBM z System Servers

Version 1.00

Move

Old
New

XR
LA
LA
MVST
JO
- - DC
DS

0,0
1,Old
2,New
2,1
Move

Ending character is a null byte


Address of source string
Address of target string
Move from Old to New
Repeat if CC=3

C This is a null-terminated string , X 0


CL(L Old+1)
Reserve space for New string

Figure 237. Moving a null-terminated string

Its important to ensure that the target field is long enough to hold both the characters and the
null terminating byte.
Many programs must scan character strings containing tokens separated by commas. Using
MVST, you can move the tokens one at a time to a work area for analysis.
LHI
LA
NextTok LA
LR
Move
MVST
JO
SR
STH
- - LA
J
- - Source DC
WorkArea DS
TokenLen DS

0,C ,
1,Source
2,WorkArea
3,1
2,1
Move
1,3
1,TokenLen
1,1(1,3)
NextTok

Ending character is a comma


Address of source string
Address of work area for a token
Save starting address of token
Move from Source to WorkArea
Repeat if CC=3
Subtract token s starting address
Save its length
Process the token (preserve GR1,GR3)
Point GR1 past the comma
And go scan for the next token

C LIST,OBJECT,XREF,ADATA,
String of tokens
CL20
Reserve space for longest token
H
Length of current token

Figure 238. Using MVST to isolate comma-separated tokens

This example is incomplete because we would expect more tokens to follow the last one (ADATA),
and because the length of the entire string should be checked to see if the last token was not
followed by a comma.

Exercises
25.5.1.(2) + What would happen in Figure 237 if you used an MVC instruction to move the
string from Old to New? (Assume the string is less than 250 bytes long.)
25.5.2.(2) In Figure 238, how would you know that you had correctly processed the last token
in the source string?
25.5.3.(2) In Figure 238, is the length stored at TokenLen the length of the token, or the length
of the token and its terminating comma?
25.5.4.(3) Suppose a C-string is stored at From and you want to move it to Target but with the
additional limitation that at most N bytes are moved, where N is stored at NBytes. If the null
character terminating the string at From is moved, set GR1 to the address of the byte following
the null character; if the null character is not moved, set GR1 to zero.
25.5.5.(2) + Write instructions to concatenate the C-string stored at Suffix at the end of the
C-string stored at Prefix. Make sure that the resulting C-string is terminated correctly.
Assume that the string at Suffix is at most 8000 bytes long.

Chapter VII: Bit and Character Data

419

25.5.6.(3) Repeat Exercise 25.5.5, but assume that the amount of space available for the concatenated string is only 150 bytes. If the result will not fit in the space available, branch to
TooLong.
25.5.7.(2) + Write instructions to copy a C-string from Here to There.
25.5.8.(3) Modify the instructions in Figure 238 to scan and process all the tokens in the character string, given that the total length of the token string is in a word at StrLen and that the
string might contain only a single token without a trailing comma.

25.6. Compare Logical String Instruction


As we saw for CLCL and CLCLE, the two operands being compared can have different lengths,
and either operand may be padded. CLST, however, requires that the operands have the same
terminating character; and neither is padded during comparison.
The operands are compared byte by byte from left to right, until unequal bytes are found or the
end of an operand is reached. Unlike SRST, there is no stop address or operand length for either
operand, so be sure the strings are properly terminated.
If the end character is found in either operand before being found in the other, the shorter
operand is low; if they are found at the same time, the operands are equal.
The Condition Code settings after CLST are the same as those for other compare instructions,
except that CC3 indicates an incomplete operation. As with SRST and MVST, if the Condition
Code is 3, you can just branch back to repeat the CLST.
CC
0
1
2
3

Meaning
Entire operands are equal; R1 and R 2 unchanged
First operand low; R 1 and R 2 point to last bytes processed
First operand high; R 1 and R 2 point to last bytes processed
Operands equal so far; R1 and R 2 point to next bytes to process

Table 160. CC settings for CLST instruction

Figure 239 on page 421 sketches the operation of the CLST instruction. The notation used in the
figure is:
A1
c(A1)
A2
c(A2)
End
x:y

420

Address of a first-operand byte, c(R1)


The first-operand byte at address A1
Address of a second-operand byte, c(R2)
The second-operand byte at address A2
End character in GR0
x is compared to y

Assembler Language Programming for IBM z System Servers

Version 1.00

Yes
Yes
START Save R1,R2 c(A1)=End? c(A2)=End? Done: Reset

No
No
R1,R2;


Set CC0

Set CC1


Yes

c(A2)=End? Set CC2

No

c(A1):c(A2) c(A1)<c(A2)? Set CC2

=
/=
Yes
No

A1=A1+1


A2=A2+1
Set CC1 Done

No

Yes
 Enough Done: Set CC3
for now?

Figure 239. Execution of the CLST instruction

At termination, the contents of the registers are:


1. If the comparison ends at the End character for both operands, they are equal: the CC is set
to 0 and GR R 1 and GR R 2 point to the End characters.
2. If the comparison ends at unequal bytes, the CC is set to 1 or 2 depending on whether the
first operand byte is less than or greater than the second operand byte. GR R 1 and GR R 2
contain the addresses of the unequal bytes.
3. If the comparison reaches the End character of one operand before the other, that operand is
considered the smaller and the CC is set accordingly. GR R 1 and GR R 2 point to the bytes
where the comparison stopped. (Note that no padding occurs!).
4. If the comparison is not complete when the CPU needs to allow for possible interrupts, the
CC is set to 3 and GR R 1 and GR R 2 have the addresses of the next bytes to be compared.
You can then branch back to the CLST instruction to continue comparing.
To illustrate, suppose you want to compare the two C-strings at A and B.

Comp

XR
LA
LA
CLST
JO
JE
JH
J

0,0
7,A
5,B
7,5
Comp
Equal
A_High
A_Low

Set null ending byte in GR0


Set GR7 to start of first operand
Set GR5 to start of second operand
Compare the two strings
Incomplete comparison, repeat
Strings are equal
String A compares higher than string B
String A compares lower than string B

When an inequality is found, the ending characters of the operands are not part of the comparison. However, when R 1 and R 2 are updated when the Condition Code is 3, they could contain
the addresses of either or both ending characters.

Exercises
25.6.1.(2) Write an instruction sequence that will compare the C-string stored at StringA to the
C-string stored at StringB. Set GR0 to + 1 if StringA is greater than StringB, to zero if they
are equal, and to 1 if c(StringA) is less than c(StringB).
25.6.2.(3) Write an instruction sequence that will compare the first N bytes of the C-strings
stored at StringA and StringB respectively, where the number of bytes N is stored in the word
at NBytes. Set GR0 to + 1 if StringA is greater than StringB, to zero if they are equal, and to
Chapter VII: Bit and Character Data

421

1 if StringA is less than StringB. Be sure to handle cases where either or both strings are
shorter than N bytes.
25.6.3.(2) + Suppose these instructions are used to compare two C-strings:
XR
LA
LA
CLST

0,0
1,X
2,Y
1,2

Ending character is a null byte


First operand is at X
Second operand is at Y
Compare first and second operands

For each of the following, assume that the string named X is at address X26F943 . Give the
Condition Code setting and the addresses in GR1 and GR2 after comparing each pair of
strings.
(1)

X
Y

DC
DC

C ABCD , X 0
C ABJE , X 0

(2)

X
Y

DC
DC

X 0
X 0

(3)

X
Y

DC
DC

C ABCD , X 0
C ABCDEFGH , X 0

(4)

X
X

DC
DC

C BCDEFGH , X 0
C ABCD , X 0

25.6.4.(4) Two strings of bytes begin at A and B and their lengths are stored in the halfwords at
LA and LB respectively. Compare the two strings up to the length of the shorter; however, if a
mismatch occurs and one of the unmatched bytes is X FF , continue comparing. (Thus X FF is
a dont care character which can match any other character.) Branch to AB_Equal, A_High, or
B_High accordingly.

25.7. Translate Extended Instruction


The TRE instruction is similar in function to TR. In both cases, the first operand is the string of
bytes to be translated, scanning from left to right, and the second operand is the translate table.
There are several differences:
Addresses: specified in base-displacement form for TR, but in R1 and R 2 for TRE.
Lengths: for TR, encoded in the instructions Length Specification Byte, but in R1 + 1 for
TRE.
Stop condition: for TR, all first operand bytes are translated; for TRE, either all first operand
bytes are translated, or a first operand byte matches the stop character in GR0.
Condition Code: unchanged by TR, but updated by TRE.
Operand overlap: TR operates byte-by-byte so that operand overlap has no effect; for TRE
the results are unpredictable.
One important result of having a stop character is that it cant be translated, unless you add extra
instructions to do your own translation after TRE completes.
Table 161 gives the Condition Code settings following execution of a TRE instruction:
CC
0
1
3

Meaning
All bytes translated; R1 incremented by length, R1 + 1 set to 0
R 1 points to the byte matching the stop character; R1 + 1 decremented by the
number of bytes processed before the match
R 1 incremented and R 1 + 1 decremented by the number of bytes processed

Table 161. CC settings for T R E instruction

422

Assembler Language Programming for IBM z System Servers

Version 1.00

To illustrate, suppose a sentence of text starting at Sentence is known to be at most 800 bytes
long. We want to translate all alphabetic characters to upper case, and stop on the first period.
LA
LHI
LHI
LA
UpChars TRE
JO
JZ
*
- - -

1,UpperTbl
0,C .
3,800
2,Sentence
2,1
UpChars
NoPeriod

Address of translate table


Stop character in GR0
Maximum length
String to be translated
Translate characters to upper case
Repeat if not finished
All characters translated, but ...
... no stop character was found.
GR2 has address of the stop character

Figure 240. Translating characters to upper case with T R E

If we need to translate additional text, we can simply increment GR2, reset the length in GR3,
and continue.
The translate table referenced in Figure 240 could be defined with statements like these:
UpperTbl DC
Org
DC
Org
DC
Org
DC
Org

256AL1(*-UpperTbl)
UpperTbl+C a
C ABCDEFGHI
UpperTbl+C j
C JKLMNOPQR
UpperTbl+C s
C STUVWXYZ
,

Initialize table to identities


Position at C a
Upper-case equivalents
Position at C j
Upper-case equivalents
Position at C s
Upper-case equivalents
Reposition Location Counter

Exercises
25.7.1.(2) What do you think will happen to a TRE instruction if R 1= 0 o r R 2=0? If R 1= R 2?
25.7.2.(2) + Suppose you execute these instructions:
LA
LHI
LA
LA
TRE

0,C ?
3,N
2,X
9,Table
2,9

Assuming an appropriate translate table has been defined at Table, show the contents of GR2,
GR3, and the Condition Code for each of the following values of N and byte strings starting at
X which is at address X 7 F290C .
(1)

N
X

Equ
DC

7
C Who? What?

(2)

N
X

Equ
DC

7
C Unknown?

(3)

N
X

Equ
DC

50
10C Possibly?

Chapter VII: Bit and Character Data

423

25.8. Compare Until Substring Equal Instruction (*)


CUSE is a very complex instruction. 154 It is unusual in another way: it is both interruptible
(Method A) and stops and sets Condition Code 3 to allow interruption processing (Method
B). 155 Though not widely used, it may be applicable in certain applications.
Op
B257

Mnem
CUSE

Type Instruction
R R E Compare Until Substring Equal

Table 162. Compare Until Substring Equal instruction

In general, there are two types of matching substring, depending on whether the equal substrings
are at the same or different offsets:
In XBCY and ABCD , the equal substrings B and BC (with lengths 1 and 2 respectively) are
at offset 1.
In XYBC and ABCD , the equal substrings B and BC are at different offsets.
The CUSE instruction searches only for equal substrings at the same offset, and having the length
specified in GR0. It requires six general registers, two of which are fixed: GR0 and GR1. The
rightmost byte of GR0 contains the length of the desired matching substrings, and the rightmost
byte of GR1 contains a padding byte. The remaining bits of both registers are ignored.
The addresses of the two operands are specified by the even-numbered registers R1 and R 2, and
their lengths are in R1 + 1 and R 2 + 1, respectively. And unlike instructions like MVCL and
CLCLE, the lengths are signed, and a negative length is treated as zero.156
Its important to remember that the substrings must occur at the same offset in both operands.
Thus, in the two strings
ABCDEFG

and

QRSDEFT

the substring DEF occurs at offset 3, so CUSE can identify matching substrings for lengths 1, 2,
and 3. However, in the two strings
ABCDEFG

and

BCDEFGH

the string BCDEFG appears at different offsets, so they will not be considered as equal substrings by
CUSE.
The padding character in GR1 is used to extend the shorter string if necessary. For example, if the
padding byte is C * and the two operand strings are
ABC

and

BCD**

with lengths 3 and 5 respectively, and the substring length is 2, then the matching substring will
be the characters **.
The Condition Code and registers are set as indicated in Table 163.

154
155
156

424

Other complex instructions include EDIT and EDMK; well see them when we describe packed decimal arithmetic.
At the time of this writing, I know of no other instruction that supports both types of interruption management.
A signed length seems strange, as its hard to think of uses for strings with negative lengths. Other instructions like
MVCL and MVCLE use unsigned lengths. (See Exercise 25.8.7.)
Assembler Language Programming for IBM z System Servers

Version 1.00

CC
0
1
2
3

Meaning
Equal substrings found; R1, R 2, and lengths updated; or,
the substring length is 0, and R 1, R 2 are unchanged
Ended at longer operand, last bytes were equal
(allows continuing search for further matches if required)
Ended at longer operand, last bytes were unequal; or,
both operand lengths = 0 and the substring length is > 0
Search operation incomplete, last compared bytes unequal;
R 1 and R 2 and lengths are updated

Table 163. Condition Code settings by CUSE

Here are some examples of CUSE: suppose we execute the code sequence in Figure 241 for
various values of String1 and String2 and their lengths, with different pad characters, searching
for matching 3-byte substrings in each case:
LA
LA
LM
CUSE

0,Substr_Len
Desired substring length in R0
1,Pad_Char
Pad Character in R1
2,5,=A(String1,L String1,String2,L String2)
2,4

Figure 241. Examples using the CUSE instruction

The results are shown in Table 164; matching substrings are underlined.

String1

L1

CABCEFDEFEAB 12
ABCDEF
6
ABCBACAC
9
ABC
3
ABC
3
ABCBA
5

String2

L2

Substr
Len

Pad
Char

CC

ACBABBCEFEAB
BCDEFA
BCBABCAC
CABAAA
CABCAB
BCBAA

12
6
9
6
6
5

3
3
3
3
3
3

C
C
C
C A
C A
C A

0
2
0
0
2
1

L1
after

L2
after

5
0
3
0
0
1

5
0
3
3
0
1

Result
Match
No match
Match at end
Match with pad
No match
No match, last bytes equal

Table 164. Results of examples using the CUSE instruction

Searching for matching substrings can be a complex and tedious process, especially if different
offsets are allowed. (See Exercise 25.8.1 and Programming Problem 25.1.)

Exercises
25.8.1.(4) Write a sequence of instructions using CLCLE instructions to emulate the function
of CUSE.
25.8.2.(2) + What is the length of the longest matching substring that can be found using
CUSE?
25.8.3.(2) Suppose a CUSE instruction detects an inequality following several equal bytes, but
the number of equal bytes is less than the required substring length. Should the instruction
restart its comparison at the second equal bytes, or at the bytes following the inequality?
25.8.4.(2) + Suppose your CUSE instruction specifies a substring length 2 with padding character A. If the strings ABCA and DEFA are compared, will it find a matching substring AA?
25.8.5.(2) If the substring length is 1, how is CUSE similar to and different from CLCLE?
25.8.6.(4) Create a flow diagram for CUSE, similar to those in Figures 236 and 239.
25.8.7.(5) Suppose the CUSE instruction supports negative operand lengths, and performs a
backward search. For example, if StringA is ABCD and has length + 4, while StringB is WCBZ and
Chapter VII: Bit and Character Data

425

has length 4. If the search starts at the rightmost byte of an operand with negative length, it
would find a matching substring BC in this case.
Write instructions to emulate a CUSE instruction that supports negative operand lengths.

25.9. Summary
Null-terminated C-strings must be handled carefully. If the terminating null byte is omitted, programs scanning or moving such strings may process far more data than intended, possibly overwriting other data or parts of the program.
The instructions discussed in this section are listed in Table 165; all set the Condition Code.
Function
Move
Compare

Length control
MVCL
MVCLE

End-char control
MVST

CLCL
CLCLE
CUSE

CLST

SRST

Search
Translate

TRE

Table 165. Extended instructions for character data

Instructions Discussed in this Section


The instruction mnemonics and opcodes are shown in the following table:
Mnemonic
CLCL

Opcode
0F

Mnemonic
CUSE

Opcode
B257

Mnemonic
MVST

Opcode
B255

CLCLE

A9

MVCL

0E

SRST

B25E

CLST

B25D

MVCLE

A8

TRE

B2A5

The instruction opcodes and mnemonics are shown in the following table:
Opcode
0E

Mnemonic
MVCL

Opcode
A9

Mnemonic
CLCLE

Opcode
B25D

Mnemonic
CLST

0F

CLCL

B255

MVST

B25E

SRST

A8

MVCLE

B257

CUSE

B2A5

TRE

Exercises
25.9.1.(3) + The C/C++ function strncpy copies at most N characters from a C-string at From to
a C-string at To and pads it with null bytes if the From string has fewer than N characters.
Assuming that the number N is stored in a word at NBytes, write an instruction sequence to
perform this function.
25.9.2.(2) + The C/C++ function strcat concatenates characters from the C-string at Second to
the end of the C-string at First. Write an instruction sequence to perform this function, being
sure that the result has only a single null character.

426

Assembler Language Programming for IBM z System Servers

Version 1.00

25.9.3.(3) The C/C++ function strncat concatenates at most N characters from a C-string at
Second to the end of the C-string at First and terminates the result with a null byte. Assuming
that the number N is stored in a word at NBytes, write an instruction sequence to perform this
function.
25.9.4.(3) The C/C++ function strncmp compares at most N characters from the C-string at A to
the C-string at B. Assuming that the number N is stored in a word at NBytes, write an instruction sequence to perform this function, setting GR0 to + 1 if A>B, to 0 if A=B, and to 1 if A<B.
25.9.5.(2) The C/C++ function strchr searches a C-string for the first occurrence of a character.
Write instructions to perform this function, assuming that the C-string is stored at CString and
the character to be sought is stored at FindChar. If the character is found, set GR3 to its
address; otherwise, set GR3 to zero.
25.9.6.(3) + The C/C++ function strrchr searches a C-string for the last occurrence of a character. Write instructions to perform this function, assuming that the C-string is stored at
CString and the character to be sought is stored at FindChar. If the character is found, set GR3
to its address; otherwise, set GR3 to zero.
25.9.7.(3) The C/C++ function strspn searches a C-string for any of the characters in a second
C-string, and returns the length of the initial portion of the first string containing characters
belonging to the second. Assuming that the C-strings are stored at First and Second, write
instructions that will place in GR1 the length of the first part of the first string containing only
characters from the second.
25.9.8.(3) The C/C++ function strcspn searches a C-string for any of the characters not in a
second C-string, and returns the length of the initial portion of the first string containing no
characters belonging to the second. Assuming that the C-strings are stored at First and Second,
write instructions that will place in GR1 the length of the first part of the first string containing
none of the characters from the second.
25.9.9.(3) The C/C++ function strpbrk searches a C-string for the first occurrence of any character in a second C-string, and returns the address of the character if present, or a null (zero)
pointer if none is found. Assuming that the C-strings are stored at First and Second, write
instructions that will place in GR1 the address of the first occurrence in the first string of any
character from the second, or zero if none is found.
25.9.10.(3) The C/C++ function strstr searches a C-string for the first occurrence of a second
C-string, and returns the address of the first character of that matching string if present, or a
null (zero) pointer if none is found. Assuming that the C-strings are stored at First and
Second, write instructions that will place in GR1 the address of the first occurrence in the first
string of the second string, or zero if none is found. If the second string is null, return the
address of the first.
25.9.11.(2) The C/C++ function memchr searches N bytes in memory for the first occurrence of a
character, and returns a pointer to the character if present or a null (zero) pointer if none is
present. Write instructions to perform this function, assuming that the data to be searched is
stored at MemData, the character to be sought is stored at FindChar, and the number N is stored
in a word at NBytes. If the character is found, set GR3 to its address; otherwise, set GR3 to
zero.
25.9.12.(2) The C/C++ function memset stores a character into the first N bytes of a C-string.
Write instructions to perform this function, assuming that the C-string is stored at CString, the
character to be stored is at FillChar, and the number N is stored in a word at NBytes.
What will happen if the null bytes at the end of the C-string is overwritten, or if no null byte is
placed after the N-th byte?
25.9.13.(4) + A string of EBCDIC characters starting at Str+2 contains substrings of blanks and
nonblanks. The total length of the string is a halfword binary integer in the two bytes at Str.
Write instructions to replace multiple blanks in the string with a single blank, and update the
string length accordingly. (Such a result is sometimes called blank-compressed.)

Chapter VII: Bit and Character Data

427

Terms and Definitions


destructive overlap
Destructive overlap occurs when any part of a target operand field is used for a source after
data has been moved into it.
interruptible
An instruction is interruptible if the CPU suspends its operation, updates the registers
involved in the operation and subtracts the instructions length from the Instruction Address
in the PSW, so that when the program resumes execution, the instruction will start from the
point where it was interrupted.
null byte
A zero or X 0 0 byte, indicated by the character n.
C-string
A string of zero or more bytes ending with a zero or null byte.

Programming Problems
Problem 25.1.(3) Write a program that reads two character strings from two 80-byte records,
and searches for the first and longest matching substring at any offset within the two strings.
Use a blank for the padding character. Print the original strings, the matching substring and its
length, and its offset within each string. Repeat for several pairs of input strings.
For example, if the two strings are XYA12345 and $12345678 , the longest matching substring
is 12345 with length 5, at offsets 3 and 1 respectively. The requirement that you find the
longest matching substring means that you shouldnt report a one-byte substring like 1 .
Problem 25.2.(3) + Programs must sometimes isolate a string of characters preceded and followed by strings of blanks. For example, if the original string is ABCD (where means a
blank character), the desired result is the string ABCD .
Write a program that reads 80-character records and removes leading and trailing blanks. Print
the original record, and the blank-trimmed result and its length. Repeat for several input
records.
Some sample input records might include
DC
DC
DC
DC
DC

CL80
AB CD
80C *
CL80 AB
CL78 , C YZ
CL80

As in the example above


No blanks
No leading blanks
No trailing blanks
All blanks

You should create other records to exercise your program.

428

Assembler Language Programming for IBM z System Servers

Version 1.00

26. Other Types of Character Data (*)

2222222222
222222222222
22
22
22
22
22
22
22
22
22
222222222222
222222222222

6666666666
666666666666
66
66
66
66
66666666666
666666666666
66
66
66
66
66
66
666666666666
6666666666

This section digresses somewhat from the main threads of the previous and following sections.
For many programs, you need not be concerned with the details of the character representation
used for your programs. There are times, however, when programs need to recognize the
encodings used for data they read or create. This section introduces some of the other character
encodings you may meet, and instructions to help process them.

26.1. Character Representations


Data is stored as strings of bits; we interpret the meanings of the bits differently for different data
types. Every computer system must solve the problem of representing characters as bit patterns.
Many character encodings exist, and many others have been forgotten. As the number of
encodings for a given character grew it became much more difficult to exchange data among
systems. This led to efforts to standardize on a smaller set of codes; among them are single-byte
EBCDIC, ASCII, double-byte EBCDIC, and Unicode. Well investigate each in turn.

26.1.1. BCD characters


The EBCDIC code used in z System is a descendant of the older BCD (Binary Coded
Decimal) encodings used on early IBM processors. Each character was 6 bits wide, and was
represented as two octal digits.157
Table 166 gives the BCD encodings. There are no lower-case characters, and fewer special characters than are supported by EBCDIC. (See Exercise 26.1.3.)

157

We mentioned base-8 (octal) encoding in Section 2.2.


Chapter VII: Bit and Character Data

429

Octal
00
01
02
03
04
05
06
07
10
11
13
14

Char
0
1
2
3
4
5
6
7
8
9
=

Octal
20
21
22
23
24
25
26
27
30
31
33
34

Char
+
A
B
C
D
E
F
G
H
I
.
)

Octal
40
41
42
43
44
45
46
47
50
51
53
54

Char
J
K
L
M
N
O
P
Q
R
$
*

Octal
60
61
62
63
64
65
66
67
70
71
73
74

Char
blank
/
S
T
U
V
W
X
Y
Z
,
(

Table 166. Old BCD character representation

Exercises
26.1.1.(1) Suppose a string of 60 bytes contains characters encoded in BCD; each byte has two
high-order zero bits. Write a sequence of instructions that will convert the BCD characters to
EBCDIC.
26.1.2.(2) + Suppose a string of 72 bytes contains 96 BCD six-bit characters packed together
with no padding bits. That is, each group of three bytes contains four BCD characters. Write a
sequence of instructions that will unpack the BCD characters from the string starting at
BCDChars into a string of 96 EBCDIC characters starting at EBCDChar.
26.1.3.(1) If the card image in Table 12 on page 80 uses the BCD coding in Table 166, what
40 octal digits will encode the characters in the first 20 columns?

26.2. EBCDIC Representations and Code Pages


In System/360 processors, the 8-bit byte required a new 8-bit character encoding, EBCDIC. Initially, the character set included mainly the characters used in the United States.
However, these early processors were soon used in many countries where the EBCDIC characters
shown in Table 13 did not provide national characters. For example, father in French
(pre) requires e-grave, and young woman in German (Fralein) requires u-umlaut.
Thus, additional EBCDIC encodings were created; these are grouped in code pages giving the
characters assigned to each of 256 possible bit patterns. It was difficult to exchange data and
programs because the same character encoding was often different among code pages. For
example, Table 167 shows some of the varying hexadecimal encodings used in current EBCDIC
tables, for these language groupings:
Code Page
037
500
1047
1140
1141
1142
1143

430

Description
Original EBCDIC: this ancestral EBCDIC code page is the code page used for
Assembler Language programs
Modern EBCDIC; a few special characters have different encodings than in code
page 037
International-1
United States, Canada, Netherlands, Australia, New Zealand, Portugal, Brazil
Austria, Germany
Denmark, Norway
Finland, Sweden

Assembler Language Programming for IBM z System Servers

Version 1.00

1144
1145
1146
1147
1148
1149
1153

Italy
Spain, Latin American Spanish
United Kingdom
France
International-1, supporting most Western languages
Iceland
Eastern Europe

All the above code pages support the euro character .


Table 167 shows why you cant assume that a given encoding represents an expected character.
As your program is moved from region to region (and code page to code page), many of the
encodings for the characters are different.
Char

037

500

1047

1140

1141

1142

1143

1144

1145

1146

1147

1148

1149

1153

5B

5B

5B

5B

5B

67

67

5B

5B

4A

5B

5B

5B

5B

7C

7C

7C

7C

B5

80

EC

B5

7C

7C

44

7C

AC

7C

7B

7B

7B

7B

7B

4A

63

B1

69

7B

B1

7B

7B

7B

4F

BB

4F

4F

BB

BB

BB

BB

4F

4F

BB

BB

BB

6A

5F

BA

B0

5F

BA

BA

BA

BA

5F

5F

BA

BA

BA

BA

4A

AD

BA

63

9E

B5

90

4A

B1

90

4A

AE

4A

BB

5A

BD

BB

FC

9F

9F

51

5A

BB

B5

5A

9E

5A

C0

C0

C0

C0

43

9C

43

44

C0

C0

51

C0

8E

C0

D0

D0

D0

D0

DC

47

47

54

D0

D0

54

D0

9C

D0

9F

9F

5A

5A

9F

9F

9F

9F

9F

9F

9F

Table 167. Sample EBCDIC characters with varying code points among code pages

If you write programs or create data that might be sent to other countries, it helps to remember
that many EBCDIC characters have the same encoding across almost all modern EBCDIC code
pages. These invariant characters are called the Syntactic Character Set:

blank/space
decimal digits
upper-case and lower-case Latin-alphabet letters
these special characters:
+ < = > % & *

( ) , _ - . / : ; ?

Using just these 82 characters will also help you avoid the possibility that your program could be
difficult to read when printed, or when displayed on a different terminal or workstation. Note
that the three national characters allowed in Assembler Language symbols (the dollar sign $, the
at sign @, and the sharp, hash, or (US) pound sign #) are not invariant across EBCDIC code
pages!

Exercises
26.2.1.(3) Suppose your program contains character data written using code page 037, and you
must translate the character data to the code page used in Sweden, 1143. Write statements to
generate a 256-byte table for translating characters in code page 037 to characters in code page
1143. Assume that all the varying characters are those shown in Table 167. (For extra credit:
try to find if there are any other variant characters between those two code pages.)
26.2.2.(1) What does your Assembler generate if you code this statement?
DC

C @#$|{[]}

Chapter VII: Bit and Character Data

431

26.3. ASCII
A widely used single-byte character representation is the American Standard Code for Information Interchange, or ASCII for short. It started as a 7-bit code and was later extended to 8 bits.
The hexadecimal character encodings for 7-bit ASCII are shown in Table 168. 158
Char
blank
!

#
$
%
&

(
)
*
+
,
.
/
0
1
2
3
4
5
6
7

Code
20
21
22
23
24
25
26
27
28
29
2A
2B
2C
2D
2E
2F
30
31
32
33
34
35
36
37

Char
8
9
:
;
<
=
>
?
@
A
B
C
D
E
F
G
H
I
J
K
L
M
N
O

Code
38
39
3A
3B
3C
3D
3E
3F
40
41
42
43
44
45
46
47
48
49
4A
4B
4C
4D
4E
4F

Char
P
Q
R
S
T
U
V
W
X
Y
Z
[
]
^
_
`
a
b
c
d
4
f
g

Code
50
51
52
53
54
55
56
57
58
59
5A
5B
5C
5D
5E
5F
60
61
62
63
64
65
66
67

Char
h
i
j
k
l
m
n
o
p
q
r
s
t
u
v
w
x
y
z
{
|
}

(none)

Code
68
69
6A
6B
6C
6D
6E
6F
70
71
72
73
74
75
76
77
78
79
7A
7B
7C
7D
7E
7F

Table 168. 7-bit ASCII character representation

All these characters use only the rightmost 7 bits; the high-order bit is zero. When the high-order
bit is 1, more characters are available; many are accented or special. For example, the e-grave
character in pre has ASCII representation X D8 , and the u-umlaut character in Fralein has
ASCII representation X FC .
The Assembler generates ASCII character constants if you specify subtype A on a C-type constant. For example:
ASCIICon DC

CA ASCII Characters

will generate

158

432

Different ASCII character encodings are used on other hardware and software systems. This encoding and its 8-bit
superset (known as ASCII Standard 8859-1) is the representation used for z System applications.
Assembler Language Programming for IBM z System Servers

Version 1.00

X41534349492043686172616374657273
A S C I I C h a r a c t e r s

The Assembler treats the nominal value of the constant as EBCDIC characters, and translates
each byte (after pairing) to ASCII.
You can also generate ASCII constants by specifying the TRANSLATE(AS) option; this causes
all C-type constants (with no subtype) to be translated from EBCDIC to ASCII. Note that character self-defining terms are not translated to ASCII, unless you also specify the
COMPAT(TRANSDT) option. It is worth remembering that the ASCII code for a blank space
is X 2 0 .

Exercises
26.3.1.(1) + If you saw a hexadecimal display of a string of alphanumeric characters (letters and
digits), what would help you decide whether they were represented in ASCII or EBCDIC?
26.3.2.(2) What machine language data is generated by these statements?
Con1
Con2
Con3
Con4

DC
DC
DC
DC

CA 5 *(2.236/Denom)+Pi
CA Invalid Expression?
CA Hello, World!
CA BitMask&&Byte|| Chars

26.4. Double-Byte EBCDIC Data (*)


The EBCDIC characters representable by a single 8-bit byte have too few values to handle ideographic languages like Japanese. To solve this problem, the EBCDIC encodings were extended to
encodings with pairs of bytes, and two special byte codes allow switching between double-byte
characters and our familiar single-byte characters.
Single-byte character sets are sometimes abbreviated SBCS, and a collection of double-byte
characters is a Double Byte Character Set, or DBCS for short.
DBCS data is a stream of single bytes, grouped in pairs. Groups of DBCS pairs are always delimited by Shift-Out (SO) and Shift-In (SI) byte codes:
Shift-Out (X 0E ) shifts out of single-byte mode to double-byte mode;
Shift-In (X 0F ) shifts in to single-byte mode from double-byte mode.
Data between the SO and SI byte codes is always treated as byte pairs. The byte codes for ampersand and apostrophe are not treated specially in DBCS data.
A string of bytes mixing single- and double-byte characters is illustrated in Figure 242, where sb
represents a single-byte EBCDIC character, db represents one of the two bytes of a double-byte
EBCDIC character, and SO and SI represent the Shift-Out and Shift-In byte codes.




 shift codes

sbsbSOdbdbdbdbdbdbSIsbsbSOdbdbdbdbSIsbsb

3 DB characters
2 DB chars
Figure 242. Mixed single- and double-byte EBCDIC characters

These 20 bytes represent 6 single-byte characters and 5 double-byte characters.

Chapter VII: Bit and Character Data

433

Because the byte codes used for SO and SI arent displayable, we use a special notation for DBCS
data.
Its customary to represent SO pictorially by <, and SI by >. (Remember that the actual characters < and > are not in the data!) Sometimes the characters  and are used instead.
We represent double-byte characters by Dx. Thus, <Dz> represents a Shift-Out, a double-byte
character, and a Shift-In. Its hexadecimal value is represented by 0EDDzz0F. (A confusing notation: the DD characters represent the hex value of the high-order byte of the DBCS pair, and zz
represents hexadecimal value of the low-order byte.)
Latin-alphabet EBCDIC characters in DBCS format are represented by .X, so that the DBCS
letter A could be shown as .A. These are sometimes called wide Latin-alphabet characters, because DBCS-sensitive devices display them that way. For example, the DBCS A
could be written <.A>.
Single-byte SBCS EBCDIC characters are represented by e (or themselves). Thus, the characters in Figure 242 might be described as ee<DbDbDb>ee<DbDb>ee.
Except for DBCS blanks, which have representation X4040, both DBCS bytes have values in
the range [X 4 1 , X FE ]. This is illustrated in Table 170.
Here are some examples of DBCS data:
<.A>
<..&>
<Da>
<&>
a<.A>b

X 0 E42C10F
X 0 E427D42500F
X 0 E....0F
X 0 E7D500F
X810E42C10F82

(pure DBCS)
(pure DBCS; & and not paired )
(whatever Da represents; e.g. X 0 EDDaa0F )
(in the user-defined character range)
(mixed SBCS and DBCS data)

Figure 243. Examples of DBCS data

Some DBCS EBCDIC code point assignments for Japanese are given in Table 169. The first
byte of a DCBS character selects a ward, a group of DBCS code points having identical first
bytes. Each ward can represent up to 192 DBCS characters.
First (ward)
byte
X 4 1
X 4 2
X 4 3
X 4 4

Second byte

Contents

X41-FE
X41-FE
X41-FE
X41-FE

X45-55
X56-68
X69-7F
X80-FE

X41-FE
X41-FE
X41-FE
X41-FE

Greek, Cyrillic, Roman numerals


Latin alphabets and alphanumerics
Katakana: phonetic, foreign loan words
Hiragana: grammatical endings and Japanese
indigenous words
Kanji basic set
Kanji extension set
User definable
Reserved

Table 169. Japanese DBCS assignments

Thus, the . in DBCS representations of Latin-alphabet SBCS characters represents the X 4 2


ward byte. Table 170 shows the overall structure of DBCS character representations; valid DBCS
codings are in the shaded areas.

434

Assembler Language Programming for IBM z System Servers

Version 1.00

0
0

4
0

4
1

F
F

00

40
41

FF
Table 170. DBCS encoding

It helps considerably that the standard EBCDIC characters shown in Table 13 on page 89 are
represented in DBCS with X 4 2 as the first two digits. That is, if a nonblank characters
EBCDIC representation is X xy , its DBCS representation is X42xy .

26.4.1. The DBCS Option (*)


The Assemblers DBCS option controls recognition of DBCS data. It also allows G-type constants and self-defining terms. The byte codes for SO and SI are recognized as shifts only if the
DBCS option is active, and ampersand and apostrophe byte codes are not tested for pairing in
either byte of a double-byte character.
If the NODBCS option is active (the Assemblers default), normal rules apply:
Shifts (SO and SI) are just data bytes.
Nothing is recognized as DBCS data.
Ampersands and apostrophes between SO/SI are recognized for pairing.
G-type constants and self-defining terms are not allowed.

26.4.2. G-Type DBCS Constants and Self-Defining Terms (*)


Like any other form of character data, DBCS data must be enclosed in apostrophes. It is allowed
wherever EBCDIC character data is allowed.
You can specify both pure and mixed DBCS data in statement operands. Pure DBCS data is
DBCS only, as in C<Da..Dz> . Mixed DBCS data may contain both single-byte EBCDIC and
DBCS data, as in C ee<Da..Dz>ee .
Both G-type constants and self-defining terms are written G dbcs_data , and support only pure
DBCS data. The shifts are removed from the generated object code. For example:
DC
DC

G<DwDxDy>
G < . A.&.B>

Generates X DDwwDDxxDDyy
X42C1425042C2

(6 bytes)
(6 bytes)

In addition, redundant SI/SO pairs such as >< are removed, since they have no useful effect in
pure DBCS data. For example:
DC
DC

G<Dx><Dy>
G < . A><.B>

Generates X DDxxDDyy
X42C142C2

(4 bytes)
(4 bytes)
Chapter VII: Bit and Character Data

435

Because each DBCS character is two bytes, G-type self-defining terms contain either one or two
DBCS characters.
DBCSAC
DBCSB
GNull

Equ
Equ
Equ

G<DxDy>
G < . B>
G<>

Has value X DDxxDDyy


Has value X000042C2
Causes an error

Constants and terms are padded on the right with DBCS blanks:
DC

GL4 < . B>

Generates X42C24040

Explicit lengths must be a multiple of 2 bytes, and truncation is done at the right end of the
constant.
C-type constants and self-defining terms may contain either pure DBCS or mixed DBCS data.
Unlike G-type constants and self-defining terms, the shift bytes are generated. For example:
DC
DC
DC

C1<DxDy>2
C < . A.&.B>
C1<Dx>2<Dy>3

Generates

X F10EDDxxDDyy0FF2
X 0 E42C1425042C20F
X F10EDDxx0FF20EDDyy0FF3

Also, redundant SI/SO pairs (><) are not removed. For example:
DC
DC

C<Dx><Dy>
C < . A><.B>

Generates

X 0 EDDxx0F0EDDyy0F
X 0 E42C10F0E42C20F

C-type self-defining terms may contain only one DBCS character, because the shift bytes are
included:
DBCSJ
CNull

Equ
Equ

C < . J>
C<>

Has absolute value X 0 E42D10F


Value X00000E0F ( not truly DBCS!)

Both G-type and C-type constants are padded on the right with EBCDIC blanks:
DC

CL5 < . B>

Generates

X 0 E42C20F40

and truncation is also on the right. However, truncation into DBCS data not allowed if the
DBCS option is specified. For example,
DC

CL3 < . B>

Generates an error message

truncates into the DBCS data.


Thus, identical nominal values are treated differently in G-type and C-type constants. For
example:
GTerm
CTerm

Equ
Equ

G < . A>
C < . A>

Has value
Has value

X000042C1 ( no shifts)
X 0 E42C10F ( with shifts)

26.4.3. Continuation Rules for DBCS Data (*)


When the DBCS option is active, the SO and SI are not considered continuation indicators! If an
SI appears before the continuation-indicator column at the end of a continued line, and is followed by an SO in the continue column of the next line, they are considered redundant, and are
removed in the generated constant.
Because G-type DBCS constants might be displayed on devices sensitive to DBCS characters,
DBCS characters should not be split at points of continuation. The Assembler provides a special
extended continuation rule when the DBCS option is active, a flexible end column on a line-byline basis. If the continuation indicator is nonblank, then the end column is the first column to
the left of the continuation indicator that differs from the continuation indicator. Assuming
default end and continuation columns, Figure 244 shows how extended continuation works:

436

Assembler Language Programming for IBM z System Servers

Version 1.00

DBCSA

*
DBCSB

col.16
col.72
DC
G<DaDbDcDdDeDfDgDhDiDjDkDlDmDnDoDpDqDrDsDt>*************
<DuDvDwDx>///////////////////////////////////////////////
<DyDzD1D2D3D4D5>
No SO/SIs in generated constant
DC

C123456789A123456789B123456789C123456789D123456789E=====
<D1D2D3D4>
SO/SI are generated

Figure 244. Extended continuation for DBCS data

For DBCSA the continuation character * at the end of the first line is extended to the left, so the
end column becomes the SI code following Dt. And because the continuation line starts with an
SO code, both are eliminated. Similarly, the SI following Dx and the SO on the third line are
redundant, so the generated constant will be
DaDbDcDdDeDfDgDhDiDjDkDlDmDnDoDpDqDrDsDtDuDvDwDxDyDzD1D2D3D4D5
However, the constant named DBCSB is a C-type constant, so the shift bytes are included, and the
generated value also includes four equal sign (X 7E ) characters:
X F1F2F3F4F5F6F7F8 F9C1F1F2F3F4F5F6 F7F8F9C2F1F2F3F4 F5F6F7F8F9C3F1F2
F3F4F5F6F7F8F9C4 F1F2F3F4F5F6F7F8 F9C57E7E7E7E0Exx F1xxF2xxF3xxF40F
where the xx characters among the last nine bytes are the hexadecimal representation of the highorder byte of the four DBCS characters D1D2D3D4.

Exercises
26.4.1.(1) Assuming the DBCS option is specified, what data will be generated by these statements?
A
B
C
D

DC
DC
DC
DC

G < . A.B.C>
GL4 < . A.B.C>
CL4 < . A.B.C>
C < . A.B.C>

26.5. Unicode
Unicode is a much broader topic than this brief summary can properly describe. Well first introduce some background, then the character representation, and how to use the Assembler to create
Unicode character constants. Section 26.6 will introduce instructions used to process Unicode
data.

26.5.1. The Unicode Representation


The growing number of (human) languages using character data led to an international effort to
standardize on a single encoding. The resulting Unicode 159 standard has greatly simplified character data exchange among nations and languages. It is identical to the International Standards
Organization (ISO) ISO/IEC 10646 standard, and provides for 8-bit (UTF-8), 16-bit (UTF-16),
and 32-bit (UTF-32) encodings. 160 All three encodings represent the same repertoire of all characters and (essentially) all languages of the modern world.
Unicode assigns every UTF-16 character a 16-bit numeric scalar value, denoted U+nnnn, where
each n represents a hexadecimal digit. (It is the same as X nnnn .) The 7-bit ASCII character

159

160

Unicode is a trademark of Unicode , Inc. Unicode is officially known as the Unicode Standard, and was created
by a cooperative effort of the Unicode Consortium and the International Standards Organization (ISO).
UTF is an abbreviation for Unicode Transformation Format.
Chapter VII: Bit and Character Data

437

code shown in Table 168 on page 432 is a basic element of the Unicode standard: all 8-bit ASCII
codes are used as the 256 lowest UTF-16 values, U+0000 through U+00FF. This is known as the
Basic Multilingual Plane, or BMP, and is the same as ASCII Standard 8859-1.
Unicode character assignments encompass a truly enormous variety of characters; some subsets
are shown (for your amazement) in Table 171.161
Range
U+0000-U+007F

Block Name
Basic Latin (BMP)

Range
U+0080-U+00FF

U+0100-U+017F
U+0250-U+02AF
U+0370-U+03FF
U+0590-U+05FF
U+0900-U+097F
U+13A0-U+13FF
U+2070-U+209F
U+3040-U+309F
U+4E00-U+9FFF

Latin Extended-A
Phonetics
Greek and Coptic
Hebrew
Devanagari
Cherokee
Superscripts and subscripts
Hiragana
China/Japan/Korea
Unified Ideographics

U+0180-U+01FF
U+0300-U+0365
U+0400-U+04FF
U+0600-U+06FF
U+0980-U+09FF
U+1400-U+167F
U+20A0-U+20CF
U+30A0-U+30FF
U+E000-U+F8FF

Block Name
Latin-1 Supplement
(BMP)
Latin Extended-B
Combining Diacritics
Cyrillic
Arabic
Bengali
Canadian Aboriginal
Currency Symbols
Katakana
Private Use

Table 171. Sample Unicode assignments

As sometimes happens with international standards, compromises were needed to satisfy the needs
of all participants. Originally, Unicode was intended to be a purely 16-bit encoding, but as its
popularity grew, more codes were needed to support new characters. This led to a provision for
surrogate characters: the first 16-bit Unicode character (the high surrogate) indicates that the
next 16 bits (the low surrogate) are an extension of the the first; together, they are called surrogate pairs. This allowed including over 1 million new characters without disrupting the basic
encoding scheme. (Well see surrogate pairs again when we describe the format-conversion
instructions in Section 26.6.5.) Surrogate pairs are rarely used in Assembler Language programs.
For the next part of this discussion, well stay with the UTF-16 encoding, and describe the oftenused variant encoding, UTF-8, in Section 26.6.5.

26.5.2. Glyphs and Characters


A character is the basic unit of encoding, and UTF-16 is the most commonly used encoding
format. It is important to distinguish between glyphsand characters. A glyph is what you see
when a character is printed or displayed. For example, displayed forms might include a, a, a, a,
and A, A, A, A, A . All of these are representations of the two characters a and A, four in
lower case and five in upper case forms (normal, italic, bold, bold italic, and small caps).
Some characters can require more than one 16-bit Unicode character code value. For example,
has Unicode coding U+00C4 (the same as X00C4 ). Because the base character A has been combined or composed with an accent, it is called a precomposed character. However, may also be
represented by two separate Unicode characters: the A (with coding U+0041) and a combining
mark (a diaresis or umlaut, with coding U+0308). This combination is called a decomposed form.
Similarly, (U+00F1) = n (U+006E) + (U+0303) represent composed and decomposed forms.
Fortunately, Assembler programs rarely need to handle decomposed characters.

161

438

Additional encodings have also been standardized for highly specialized uses such as ancient Phoenecian and
Sumero-Akkadian Cuneiform. The Unicode Standard contains the encodings and some interesting history.
Assembler Language Programming for IBM z System Servers

Version 1.00

26.5.3. Unicode Character Constants


The Assembler generates Unicode constants if you specify constant type CU: that is, type C with
type extension U. The nominal value is a string of 8-bit EBCDIC code points.
Because the same character can have different EBCDIC encodings while Unicode provides unique
representations for all characters, the Assemblers CODEPAGE option lets you specify the character
representation used for the nominal values in your CU-type constants.
To show why the CODEPAGE option may be important, suppose you live in England. When
preparing your program, you enter a byte for the Pound Sterling character. It has code point
X 5B on code page 1146, the usual code page for the United Kingdom. However, if the
CODEPAGE(1146) option is omitted, the Assembler will convert the character to U+0024, the
Unicode representation of the $ dollar sign! This is because the Assembler assumes a default code
page on which $ has code point X 5B . When the CODEPAGE(1146) option is specified, the
Assembler converts the correctly to U+00A3.
These constants are scanned using the usual rules for C-type constants (apostrophe and ampersand pairing). Each byte of the result is then mapped from the EBCDIC encoding specified by
the CODEPAGE option to the equivalent 2-byte UTF-16 encoding.
The Length attribute of a CU-type constant is always measured in bytes (not characters); an
explicit length (if specified) must be even. If the explicit length is longer than the implied length,
the byte string is padded with EBCDIC blanks, and if shorter, the byte string is truncated on the
right. Then, it is translated to UTF-16. Implied lengths are the number of bytes generated:
2(number of EBCDIC characters after pairing).
SampleCU DC

CU Unicode Characters

Figure 245. CU-type constant generating Unicode characters

The statement in Figure 245 generates these 36 bytes from the 18 nominal-value characters:
0055006E00690063 006F006400650020 0043006800610072 0061006300740065 00720073
Because the characters in the nominal value of the CU-type constant in Figure 245 are members
of the invariant EBCDIC character set described on page 431, any of the CODEPAGE option
values described on page 430 may be specified to generate the above result.
Notice that each Unicode character starts with nine zero bits (B0000 0000 0 ), meaning that it is
representable in the 7-bit portion (U+0000 to U+007F) of the UCS-16 Unicode encoding. 162 The
symbol SampleCU has Length Attribute 36.
Its important to remember that the Assemblers CODEPAGE option applies only when translating EBCDIC characters to Unicode in CU-type constants. The remaining characters in your
program are understood by the Assembler to be represented in the 037 code page.

Exercises
26.5.1.(2) + In Figure 245, what changes to the generated object code would occur if your
program had been created using code page 1146?
26.5.2.(4) Search the web to find the character encodings used for upper-case letters and decimal
digits on old machines like the Control Data Corporation (CDC) 1604, the CDC 6600, the
Burroughs 5500, the IBM 7030 Stretch computer, and others. Show the differences, and
explain why Unicode is an improvement.
26.5.3.(1) What object code is generated by these constants?

162

The Assembler actually used the 1148 EBCDIC code page for the EBCDIC-to-Unicode translation.
Chapter VII: Bit and Character Data

439

C1
C2
C3
C4

DC
DC
DC
DC

CU ABC
CUL12 ABC
CUL2 ABC
CUL8 A&&B C

26.6. Unicode Instructions


We will describe three groups of instructions:
String search, compare, and move instructions
Translation instructions
Format conversion instructions

26.6.1. String Search, Compare, and Move


The three instructions in Table 172 search, compare, and move, Unicode strings. While each has
Unicode in its name, they actually just search for, compare, and move arbitrary two-byte
values; there is no need for the operands to be Unicode characters! They are very similar to their
single-byte counterparts: CLCLE, MVCLE, and SRST.
Op
B2BE
EB8E

Mnem
Type Instruction
SRSTU R R E Search String Unicode
MVCLU RSY Move Long Unicode

Op
Mnem
Type Instruction
EB8F CLCLU RSY Compare Logical Long Unicode

Table 172. Unicode string instructions

Though each instruction manipulates two-byte operands, there is no requirement that they be
halfword aligned.
Search String Unicode: SRSTU scans the second operand string addressed by register R2,

looking for a pair of bytes matching the rightmost two bytes of GR0 (the test character; the rest
of GR0 must be zero). If a match is found, the R1 register is set to its address. Because the
second operand string can be very long, the CPU uses Method B to process part of the string
before checking for interruptions.

To use SRSTU, put the test character in GR0, set the R 2 register to the address of the leftmost
byte of the string to be scanned, and the R1 register to the address of the first byte after the end of
the string. The CPU uses this address to know when to stop the scan; otherwise, it could keep
scanning byte pairs in memory until it found a match somewhere, or caused an unexpected interruption.
Table 173 gives the Condition Code settings after SRSTU:
CC
1
2
3

Meaning
Test character found; R1 points to it
Test character not found before the byte addressed by R1
Partial search with no match; R1 unchanged, R 2 points to next
byte to process

Table 173. CC settings for SRSTU instruction

On completion, either or both of the R 1 and R 2 registers may be updated:


If the CC is 1, the R1 register is updated and the R2 register is unchanged.
If the CC is 2, both the R1 and R 2 registers are unchanged.
If the CC is 3, R1 is unchanged and R2 is updated to the address of the next byte to be tested.
You can then branch back to the SRST instruction to continue the search.

440

Assembler Language Programming for IBM z System Servers

Version 1.00

The operation of the SRSTU instruction is very similar to that of SRST, as sketched in
Figure 235 on page 417, except that the second operand address is incremented by 2.
For example, suppose you want to scan the string at MyData to find the first occurrence of a
Unicode A character:
UnicodeA Equ
LAY
LA
LA
Repeat SRSTU
JO
JH
- - -

X0041
0,UnicodeA
1,MyData
5,MyData+L MyData
5,1
Repeat
NotFound

Unicode capital letter A


Put test character in GR0
Set GR1 (R2) to string start
GR5 (R1) = byte past end
Scan the string
Scan was incomplete, try again
CC2, no match was found
CC1, GR5 now points to the A

If the Condition Code is 3, we simply branch back to the SRST to continue the search.
Move Long Unicode: Like MVCLE, the results of overlapping operands are unpredictable. The

execution of MVCLU is the same as in Figure 229 on page 413, except that addresses are incremented by 2 and lengths are reduced by 2, and that two bytes are moved at each step. Also, the
low-order 16 bits of the Effective Address are used as the pad character.
Normally both operand lengths are even, but MVCLU allows either operand to have odd length.
The two-byte padding character is then described as the high-order padding byte followed by
the low-order padding byte.
If the operand lengths are equal but odd, MVCLU does the same as MVCLE.
If the first (target) operand length is odd and is shorter than the third (source) operand, an odd
number of bytes is moved.
If the first operand is longer:

If its length is even, padding starts with the even padding byte.
If its length is odd, padding starts with the odd padding byte. This means that any additional padding is done with proper even-odd pairs of padding bytes.

MVCLU sets the Condition Code as shown in Table 174.


CC
0
1
2
3

Meaning
All bytes moved, operand lengths are equal
All bytes moved, operand 1 shorter; part of operand 2 was not moved
All bytes moved, operand 1 longer; operand 1 was padded
Some bytes moved; end of operand 1 not reached

Table 174. CC settings after MVCLU

For example, suppose we use MVCLU to initialize a large area of storage starting at Work to
Unicode space characters:
XR
XR
LA
L
Move
MVCLU
JO
- - WorkSize DC
BlockLen Equ
NBlocks Equ

0,0
1,1
2,Work
3,WorkSize
2,0,X020
Move

Source address will be ignored,


...because source length is zero
Start of area to initialize
Length of work area
Initialize with Unicode spaces
Repeat until done

A(BlockLen*NBlocks)
Length of work area
32000
...containing 32000 blocks,
20000
...each 20000 bytes long

Figure 246. Using MVCLU to initialize an area to Unicode spaces

Chapter VII: Bit and Character Data

441

Compare Logical Long Unicode: CLCLU operates in much the same way as CLCLE.

However, operand lengths must be even, operand addresses are incremented by 2 and lengths are
decremented by 2, and the 16-bit padding character is contained in the low-order two bytes of
the Effective Address formed from the second operand.
CLCLU sets the Condition Code as shown in Table 175.
CC
0
1
2
3

Meaning
All bytes compared, operands equal, or both zero length
First operand low
First operand high
Some bytes compared without finding an inequality

Table 175. CC settings after CLCLU

To illustrate, well rewrite Figure 246 to use CLCLU to test if the same field contains all Unicode
spaces:
XR
XR
LA
L
Compare CLCLU
JO

0,0
1,1
2,Work
3,WorkSize
2,0,X020
Compare

Source address will be ignored,


...because source length is zero
Start of area to initialize
Length of work area
Compare entirely to pad bytes
Repeat until done

Figure 247. Using CLCLU to test for Unicode spaces

Warning!
Comparing and sorting character data in EBCDIC and Unicode can give
very different results, because the character encodings are quite different.

26.6.3. Optional Operands


The Unicode-related instructions introduce optional operands, which have not been used in most
of the instructions weve seen previously.
Unused fields in instructions are filled with zero bits by the Assembler. But as z System has
evolved, the CPU architects have sometimes needed to extend the function of an existing instruction. Rather than create a new instruction, some of these previously unused fields were assigned
special bit-mask values.
It was important to avoid the problem that programs containing existing instructions now supporting new fields could need to be rewritten to handle the new operand specifications. To solve
this, the new operand was made (a) optional and (b) the last operand of the assembler instruction
statement. If the optional operand is omitted, the Assembler sets the optional field to zero, as
usual. Thus, programs needing the enhanced function can specify the new operand, and existing
programs not specifying the new operand continue to work without modification.
For example, an RRE-type instruction has this format:
opcode

R1

R2

Table 176. RRE-type instruction

The extension of RRE-type instructions to support the new operand required a new instruction
type: RRF, shown in Table 177.
opcode

M3

R1

R2

Table 177. RRF-format instruction with an optional operand

442

Assembler Language Programming for IBM z System Servers

Version 1.00

where M 3 is the optional operand; the notation used in the z/Architecture Principles of Operation
describing the Assembler Language format of such instructions is illustrated in Figure 248, where
the square brackets [ ] indicate that the operand is optional.
mnemonic R1,R2[,M3]
Figure 248. Assembler instruction statement for RRF-type instructions with an optional operand

If the optional operand is omitted, the Assembler fills the M3 field of the instruction with zero
bits, so that writing
mnemonic R1,R2
is the same as writing
mnemonic R1,R2,0
We will see examples of optional operands in some of the following Unicode instructions.

26.6.4. Translation
The four instructions for Unicode translation are listed in Table 178. Each has an optional
operand in the form shown in Table 177 and Figure 248.
Op
B993
B991

Mnem
TROO
TRTO

Type Instruction
R R F Translate One to One
R R F Translate Two to One

Op
Mnem
B992 T R O T
B990 T R T T

Type Instruction
R R F Translate One to Two
R R F Translate Two to Two

Table 178. Unicode translate instructions

These instructions are generalizations of TRE, which was described in 25.7. Translate Extended
Instruction on page 422, but there are interesting and significant differences:
TRE tests a source-operand character, but these instructions test the function character from
the translate table.
TRE tests the character in GR0 after the result byte has been stored, but these four
instructions test the function character against the character in GR0 before completing a character translation.
If the optional operand is 1, the instruction suppresses the test for a source character matching
the test character in GR0, and the translation is controlled only by the length of the first
operand.
The address of the translation table for TRE is specified in R2, but is in GR1 for these four
instructions. Unlike other translate instructions, you can specify different source and target
operands, so the translation can be non-destructive.
The source, target, and test characters can be either one or two bytes long. This means that
the translation tables may be (much) larger:

TROO: Translate One to One (256-byte table)


TROT: Translate One to Two (512-byte table)
TRTO: Translate Two to One (64K-byte table)
TRTT: Translate Two to Two (128K-byte table)

If you are translating characters of the same length (one to one, or two to two), the source and
target operands have the same length. Otherwise:

If you translate One to Two, the target operand is twice as long as the source operand.
If you translate Two to One, the target operand is half as long as the source operand.

Unlike TR, TRT, and TRE, the translate tables must be aligned on a doubleword
boundary. 163

163

Originally, the translate tables for TRTO and TRTT had to be on a 4K-byte boundary, but this was quite inconvenient for most programs so the restriction was removed.
Chapter VII: Bit and Character Data

443

If the target operand contains two-byte characters (for TROT and TRTT), the source character is shifted left internally by one bit before being added to the table address from GR1, to
correctly address the two-byte translate table entries.
Some of these factors are summarized in Table 179.
Instruction
TROO
TROT
TRTO
TRTT

Source
1 byte
1 byte
2 bytes
2 bytes

Test Character
1 byte
1 byte
2 bytes
2 bytes

Table Entry
1 byte
2 bytes
1 byte
2 bytes

Table Size
256
512
65,536
131,072

Table 179. Arguments and translate tables for TRxx instructions

Table 180 summarizes how the registers are used by these four translate instructions:
Register
GR0
GR1
R1
R1 + 1
R2

Contents
Test character, unless the optional operand is 1, in which case GR0 can be used
for any other purpose.
Address of the translation table.
Address of the target operand where translated characters will be stored.
Length in bytes of the second (source) operand; must be an even number for
TRTO, TRTT.
Address of the source operand to be translated.

Table 180. Registers used by TRxx instructions

All overlaps produce unpredictable results, whether of storage operands or of register assignments.
Table 181 describes the Condition Code settings after executing these instructions:
CC
0

Meaning
All characters translated; if the optional operand was 0 (test character comparison
was performed), no function character matching the test character was found. R1
points to the byte after the last target character, R1 + 1 is zero, and R2 points to the
byte after the last source character,
If the optional operand was 0 (test character comparison was performed), a function character matching the test character was found. R 1 + 1 is decreased by the
number of bytes processed before the character whose function character matched
the test character; R2 is incremented by the same number, and R1 is increased by
the number of bytes placed in the first operand.
Partial translation; branch back to the instruction to continue. Registers R1,
R 1 + 1, and R 2 have been adjusted so that translation will continue, eventually
ending with CC 0 or 1.

Table 181. Condition Code settings for TRxx instructions

Remember: if the optional M 3 operand is 1, the test character is ignored.


To illustrate, suppose TRTT is used to translate a string of DBCS characters to Unicode:

444

Assembler Language Programming for IBM z System Servers

Version 1.00

LA
LA
LA
LA
TrDBCS TRTT
JO
- - DBCSCon DC
UString DS
DS
MapTbl DC

1,MapTbl
2,UString
3,L DBCSCon
4,DBCSCon
2,4,1
TrDBCS

Point GR1 to the translation table


Point GR2 to the Unicode result string
Set GR3 to the second operand length
Point GR4 to the DBCS source operand
Translate without a test character
Repeat until all translations done

G < . A.B ... .Y.Z>


CL(L DBCSCon)
0D
X . . .

DBCS character string


Unicode result has same length
Doubleword alignment for table
Mapping from DBCS to Unicode

Figure 249. Using T RT T to translate from DBCS to Unicode

Because the translate table at MapTbl could be up to 131,072 bytes long, we could take advantage
of the fact that DBCS characters have representations between X4040 and X 7 FFE to define a
smaller table.
While these may seem very complex, the TROO instruction can be used in many places where
TR would be inconvenient, because it lets you specify separate source and target operands.
To illustrate, suppose you must translate a long string of characters at OldText to another string
at NewText while leaving the original string unchanged. Assume the string length is stored in the
word at TextLen and that the required translation table starts at TextTbl. Then, Figure 250
shows instructions using MVC and TR compared to instructions using TROO.
* With MVC and
L
LA
LA
LA
Repeat CHI
JNH
EX
EX
AHI
AHI
AHI
J
LastPart JNP
BCTR
EX
EX
Done
- - - - MoveText MVC
TRText TR

TR
3,TextLen
2,NewText
4,OldText
1,255
3,256
LastPart
1,MoveText
1,TRText
2,256
4,256
3,-256
Repeat
Done
3,0
3,MoveText
3,TRText

0(*-*,2),0(4)
0(*-*,2),TextTbl

|* With TROO
|
L
|
LA
|
LA
|
LA
|Repeat
TROO
|
JO
|Done
- - |
|
|
|
|
|
|
|
|
|
|
|
|

3,TextLen
2,NewText
4,OldText
1,TextTbl
2,4,1
Repeat

Figure 250. Translating a long string with T R and MVC, and with TROO

With TROO, the CPU adjusts the operand registers automatically, while with MVC and TR you
must write instructions to do the updates.

26.6.5. Conversion Among Transformation Formats


As mentioned in Section 26.5, the Unicode standard defines 8-, 16-, and 32-bit encoding formats;
each is useful in different contexts. One problem in transmitting Unicode data across networks is
that some of the byte codes used for the 16-bit or 32-bit Unicode characters also have meaning as
network control codes. It may be necessary to transform a UTF-16 or UTF-32 encoding to
UTF-8 for transmission over a network, and the receiver can transform the byte stream back to
UTF-16 or UTF-32 (or even work directly with the received UTF-8 byte stream).
The bits of a UTF-16 character are sometimes represented as shown in Figure 251 on page 446:
Chapter VII: Bit and Character Data

445

0 1 2 3 4 5 6 7
8 9 10 11 12 13 14 15

a b c d e f g h i j k l m n o p

Figure 251. Bits of a UTF-16 Unicode character

To see why UTF-8 is needed, consider the Cyrillic character P with representation U+0420. If
this was transmitted as single byte data, the single X 0 4 byte could be interpreted as an End of
Transmission (EOT) flag! Thus, the UTF-8 encoding transforms a UTF-16 character to one,
two, three, or four bytes as follows:
If the UTF-16 character has the form B00000000 0jklmnop (it lies between U+0000 and
U+007F), it is transformed into a single byte B 0 jklmnop .
If the UTF-16 character has the form B00000fgh ijklmnop (it lies between U+0080 and
U+07FF), it is transformed into the two bytes B110fghij 10klmnop .
If a UTF-16 character lies between U+0800 and U+D7FF, or lies between U+DC00 and U+FFFF, it is
transformed into the three bytes B1110abcd 10efghij 10klmnop .
Because the 16 UTF-16 bits were not sufficient to encode all required characters, forms with
scalar values greater than or equal to U+10000 were added; they are represented by surrogate
pairs, as illustrated in Figure 252. The four bytes of surrogate pairs have these bit patterns:

1 1 0 1 1 0 a b

1 1 0 1 1 1 k l

c d e f g h i j High surrogate

m n o p q r s t Low surrogate

Figure 252. Bits of a UTF-16 Unicode surrogate pair

Given a high surrogate that lies between U+D800 and U+DBFF and a low surrogate that lies
between U+DC00 and U+DFFF, the pair is transformed into the four UTF-8 bytes
B11110uvw 10xyefgh 10ijklmn 10opqrst , where uvwxy = abcd+1.
While this transformation is complicated, it guarantees that no UTF-16 character will be mistaken
for a control code, and that the receiver can immediately find where a character encoded in
UTF-8 form begins. The initial bits of the first UTF-8 byte indicates how many bytes follow it in
a multi-byte sequence.
The Unicode and ISO standards also define a UTF-32 standard that uses 32 bits for each character, and does not need surrogates. The UTF-32 representation of a normal UTF-16 character
(as shown in Figure 251) with encodings from U+0000 to U+DBFF and from DC00 to U+FFFF, simply
append two high-order bytes of zeros to the UTF-16 character.
For UTF-16 surrogate pairs, the mapping is more complex: the four bytes shown in Figure 252
are mapped into the form shown in Figure 253, where the bits named uvwxy have value abcd+1.

0 0 0 0 0 0 0 0

e f g h i j k l

0 0 0 u v w x y First 16 UTF-32 bits

m n o p q r s t Second 16 UTF-32 bits

Figure 253. Bits of a UTF-32 Unicode character from a UTF-16 surrogate pair

The z System instructions that convert among the three UTF encodings are shown in Table 182.
Two of the instructions have two names, because CUUTF and CUTFU were implemented
before the other four; the original two were then renamed so that all six instruction names are
consistent. The old names are retained for compatibility.164

164

446

Originally, only the two instructions CUUTF and CUTFU were defined, meaning Convert Unicode to UTF and
Convert UTF to Unicode, respectively. At that time, UTF meant UTF-8, and Unicode meant UTF-16.
Assembler Language Programming for IBM z System Servers

Version 1.00

Op
B2A7

Mnem
Type Instruction
CU12,
R R F Convert UTF-8 to
CUTFU
UTF-16

Op
Mnem
B9B0 CU14

Type Instruction
R R F Convert UTF-8 to UTF-32

B2A6

CU21,
R R F Convert UTF-16 to
CUUTF
UTF-8
CU41
R R F Convert UTF-32 to
UTF-8

B9B1 CU24

R R F Convert UTF-16 to UTF-32

B9B3 CU42

R R F Convert UTF-32 to UTF-16

B9B2

Table 182. Unicode format conversion instructions

The R 1 and R 2 registers must be even, and contain the addresses of the first and second operands;
the next higher-numbered registers R1 + 1 and R 2 + 1 contain the operand lengths.
The CU41 and CU42 instructions have the form shown in Table Table 176 on page 442, and the
CU12, CU14, CU21, and CU24 instructions have the form shown in Table 177.
When these instructions were first implemented, the Unicode Standard did not forbid invalid
forms. Further revisions of the Standard made those forms invalid, so an optional operand was
added to CU12, CU14, CU21, and CU24 to let you choose whether or not well-formedness
should be enforced. If the optional operand is one, checking is done for well-formedness.165
Further details may be found in the z/Architecture Principles of Operation.
Table 183 shows the Condition Code settings after executing these instructions:
CC
0
1
2
3

Meaning
Entire second operand was processed.
End of the first operand was reached.
An invalid UTF-8 character was found; or an invalid low surrogate was found; or
an invalid UTF-32 character was found.
Operation incomplete; branch back to it to complete the operation.

Table 183. CC settings after Unicode format conversion instructions

Exercises
26.6.1.(2) What do you think will happen if the B2 register of a CLCLU or MVCLU instruction is the same as R1 or R 3 or R 1 + 1 or R 3 + 1?
26.6.2.(1) Can both operands of CLCLU be padded?
26.6.3.(2) + Write a sequence of instructions to find the last nonblank UTF-16 Unicode character in a string of UTF-16 Unicode characters stored at UData. If no nonblank characters are
found, branch to AllBlank.
26.6.4.(1) + Write instructions to copy a string of Unicode characters from UHere to UThere.
26.6.5.(1) What UTF-16 Unicode characters can be used for padding if you use a CLCLU or
MVCLU instruction with B 2= 0 ?
26.6.6.(3) In Figure 249 on page 445, what changes to the first LA instruction would be
needed if the translate table at MapTbl starts with the DBCS character corresponding to the
DBCS character with representation X4040?
26.6.7.(2) + Suppose one of the four TRxx instructions is used with the optional operand set to
1. Can GR0 be used for the R 2 operand?

165

A well-formed multi-byte UTF-8 character requires that each byte after the first start with B 1 0 .
Chapter VII: Bit and Character Data

447

26.6.8.(2) Can TRTT be used to simulate TROO?


26.6.9.(2) It was stated that the first byte of the UTF-8 representation of a Unicode character
indicates how many bytes follow it. Show that this is true by analyzing the bit patterns in the
first byte.
26.6.10.(3) It is claimed that a binary sort of UTF-8 character strings gives the same ordering as
a binary sort of UTF-16 scalar values, so long as there are no surrogates. Create examples to
show that this is or is not true.
26.6.11.(2) GR5 contains a halfword value that is to be sought in a table of halfwords starting
at HWList. Write a sequence of instructions using SRSTU to locate the entry in the table that
matches the halfword in GR5.
26.6.12.(4) Create a translation table for mapping EBCDIC code page 037 to UTF-16.
26.6.13.(5) Many programs convert strings of bytes to pairs of EBCDIC characters representing
the hexadecimal digits of each byte. (Exercise 15.6.5 is a typical example.) Using a single DC
statement, create a translate table to be used by a TROT instruction like

Repeat

LA
LA
LA
LA
TROT
JO

1,PH
2,Target
3,L Source
4,Source
2,4,1
Repeat

Address of 2-to-2 translation table


Address of target string
Length of source string
Address of source string
Translate each byte to two
Repeat if incomplete

that converts source bytes to their representative pairs of EBCDIC characters. For Example,
the table should start with the characters C00010203 (that is, X F0F0F0F1F0F2F0F3 ), and end
with the characters C FCFDFEFF (that is, X C6C3C6C4C6C5C6C6 ).
26.6.14.(2) Suppose the CU24 and CU42 instructions did not exist. How could you translate
between UTF-16 and UTF-32?
26.6.15.(1) Show how the bit patterns of the first UTF-8 byte can be used to determine how
many following bytes are part of the same Unicode character.

26.7. Byte Reversal and Workstation Data


All our previous examples using binary data have assumed that the most significant bits are found
in the byte with the lowest address, with significance decreasing at higher addresses. Some other
processor architectures store numeric data in the opposite direction: the byte with the least significant bits are at the lowest address, and significance increases in the bytes at higher addresses.
The significance of bits within a byte is the same in either case: the high-order bit has the greatest
significance.166
The choice of byte order for binary data is sometimes called the Endian question.167 Because
z System stores the most significant bits at the lowest address, it is called a Big-Endian
processor (i.e., big end first). Many early microprocessors could handle only 4 bits or a single
byte at a time, and because bits are added starting with the least significant, it was more econom-

166

167

448

But be careful: data on some processors sometimes numbers bits from right to left, rather than the z System convention from left to right. Right-to-left numbering has the advantage that a bits number is the same as the power of 2 it
represents.
The term Endian was taken from Jonathan Swifts Gullivers Travels, where the kingdoms of Lilliput and Blefuscu
were permanently at war over the correct way to eat a boiled egg. The Lilliputian Little-Endians insisted on
opening the egg at the sharp end, and the Blefuscudian Big-Endians insisted on the rounded end.
Assembler Language Programming for IBM z System Servers

Version 1.00

ical to address the (numerically) lowest-order byte (i.e., little end first). Many personal computers and workstations are Little-Endian.
For example, if a word containing X87654321 is stored in a Big-Endian processor memory
starting at address A, we would see the bytes in storage as in Figure 254:
A
A+1 A+2 A+3

87 65 43 21

 Addresses

Figure 254. Big-Endian storage representation of X 87654321

However, on a processor storing data with the least significant bits at the lowest address (a
Little-Endian processor) we would see the bytes in storage as in Figure 255:
A
A+1 A+2 A+3

21 43 65 87

 Addresses

Figure 255. Little-Endian storage representation of X 87654321

When your program manipulates multi-byte data, youll want to know where it originated.

26.7.1. Byte-Reversing Instructions


The byte-reversing instructions are listed in Table 184. They are provided because z System
processors must often exchange data with workstations and personal computers that store some
types of data in byte-reversed order.
Op
E31E
E30F
E31F
E33E

Mnem
LRV
LRVG
LRVH
STRV

Type
RXY
RXY
RXY
RXY

Instruction
Load Reversed (32)
Load Reversed (64)
Load Halfword Reversed (16)
Store Reversed (32)

Op
B91F
B90F
E33F
E32F

Mnem
LRVR
LRVGR
STRVH
STRVG

Type
RRE
RRE
RXY
RXY

Instruction
Load Register Reversed (32)
Load Register Reversed (64)
Store Halfword Reversed (16)
Store Reversed (64)

Table 184. Byte-reversing load and store instructions

They behave like normal Load and Store instructions, except that the left-to-right order of the
bytes is reversed. This is illustrated in Figure 256.

byte 0 byte 1 byte 2 byte 3 R1











byte 3 byte 2 byte 1 byte 0 Word in memory or R2

Figure 256. Byte reversal by LRV, LRVR, and STRV instructions

These instructions convert two, four, or eight bytes between Big-Endian and Little-Endian
format quickly and efficiently for processing. For example, suppose the word in Figure 254 is
stored at A. Then, executing
LRV

0,A

c(GR0) = X21436587

Chapter VII: Bit and Character Data

449

will load GR0 with the pattern shown in Figure 255. Byte reversal can also be done when
storing the contents of a general register into memory:
L
0,=X12345678
STRV 0,Rev

c(GR0) = X12345678
c(Rev) = X78563412

The LRVR instruction is similar to LRV, except that the second operand comes from GR R 2
rather than from memory.
The LRVH and STRVH instructions are similar to LRV and STRV, except that only the two
rightmost bytes of GR R 1 are involved. This is illustrated in Figure 257.

byte 0 byte 1 byte 2 byte 3 R1

 unchanged






byte 3 byte 2 Halfword in memory

Figure 257. Byte reversal by LRVH and STRVH instructions

For example:
LRVH 1,=X1234

c(GR1) = X xxxx3412

where xxxx is the original data in the two high-order bytes of GR1.
LRVH is unusual in this respect: unlike the other Load Halfword instructions, it does not propagate the sign bit of the leftmost bit of the (reversed) halfword just loaded. Thus, it might better be
thought of as the Insert Halfword Reverse instruction, because the rest of the R1 register is
unchanged.
The 64-bit instructions LRVG, LRVGR, and STRVG are the 64-bit equivalents respectively to
LRV, LRVR, and STRV: the operands are 8 bytes long rather than 4. Otherwise, their operation
is the same.
Processing halfword, word, and doubleword data with these instructions is straightforward.
If the fields in a data item do not align neatly on byte boundaries, processing Endian data can
be much more difficult. Suppose a word in memory containing four different binary integers has
the format shown (in Big-Endian format) in Figure 115 on page 249. As before, the bits are
lettered, but now we must number the individual bits of the integers A, B, C, and D, as in Figure
258. The 9 bits of A are numbered A0-A8; the 4 bits of B are numbered B0-B3; the 13 bits of C
are numbered C0-Cc; and the 6 bits of D are numbered D0-D5.
9 bits
4 bits
13 bits
6 bits

A A A A A A A A A B B B B C C C C C C C C C C C C C D D D D D D
0 1 2 3 4 5 6 7 8 0 1 2 3 0 1 2 3 4 5 6 7 8 9 a b c 0 1 2 3 4 5

 first byte  second byte  third byte  fourth byte


Figure 258. Four integers packed in a Big-Endian 32-bit word

Thus, the first byte contains bits A0-A7; the second byte contains bits A8, B0-B3, and C0-C2; the
third byte contains bits C3-Ca; and the fourth byte contains bits Cb-Cc and D0-D5.
Suppose these four bytes are reversed and sent to a Little-Endian processor; the data would then
look like this:

450

Assembler Language Programming for IBM z System Servers

Version 1.00


C C D D D D D D C C C C C C C C A B B B B C C C A A A A A A A A
b c 0 1 2 3 4 5 3 4 5 6 7 8 9 a 8 0 1 2 3 0 1 2 0 1 2 3 4 5 6 7

first byte
second byte
third byte
fourth byte
Figure 259. The same four integers packed in a Little-Endian 32-bit word

You can imagine the difficulties a program on a Little-Endian processor might have in extracting
the four integer values. Conversely, if your program receives a Little-Endian word in which overlapping bit fields are specified as in Figure 258, your z System program would see the word in
Figure 259.
Something to Check
Before processing data, be sure you know its Endianness, as well as its
character representation.

Exercises
26.7.1.(2) Suppose the two rightmost bytes of GR2 contain a 2-byte Little-Endian integer.
What will these two instructions do?
LRVR 2,2
SRA 2,16
What will happen if the SRA instruction is replaced by SRL?
26.7.2.(3) Suppose the data shown in Figure 258 is actually in Little-Endian format, so you find
it on your z System processor in the word at OddData in the form shown in Figure 259. Write
a sequence of instructions to extract the four (unsigned) integers, and store them in halfwords
named A, B, C, and D.
26.7.3.(1) Put the 4 bytes of the word at DPG into GR1 in reverse order. (See Exercise 17.2.5.)

26.8. Summary
The extended instructions for Unicode are summarized in Table 185.
Function
Move

Instruction
MVCLU

Compare

CLSTU

Search

SRSTU

Stop Conditions
End of first operand
End of longer operand,
or unequal comparison
End of second operand,
or stop character found

Table 185. Extended instructions for Unicode data

The Unicode-based translation instructions are summarized in Table 186.


Operand 1
Operand 2
Translate

Function

1 byte
1 byte
TROO

2 bytes
TRTO

2 bytes
1 byte
TROT

2 bytes
TRTT

Table 186. Unicode-based translate instructions

The Unicode format conversion instructions are summarized in Table 187.

Chapter VII: Bit and Character Data

451

Function

Operand 1
Operand 2

1 byte
2 bytes
4 bytes
CU21
CU41
CUUTF

Convert Format

2 bytes
1 byte
4 bytes
CU12
CU42
CUTFU

4 bytes
1 byte
2 bytes
CU14
CU24

Table 187. Unicode format conversion instructions

The byte-reversing instructions are summarized in Table 188.


Function

Operand1
Operand2

Load (from memory)

4 bytes
2 bytes
LRVH

4 bytes
LRV

8 bytes
8 bytes
LRVG

STRVH

LRVR
STRV

LRVGR
STRVG

Load (from register)


Store

Table 188. Summary of byte-reversing instructions

452

Assembler Language Programming for IBM z System Servers

Version 1.00

Chapter VIII: Zoned and Packed Decimal Data and Operations

VV
VV
VV
VV
VV
VV
VV
VV
VV
VV
VV
VV
VV
VV
VV
VV
VV
VV
VV VV
VVVV
VV

IIIIIIIIII
IIIIIIIIII
II
II
II
II
II
II
II
II
IIIIIIIIII
IIIIIIIIII

IIIIIIIIII
IIIIIIIIII
II
II
II
II
II
II
II
II
IIIIIIIIII
IIIIIIIIII

IIIIIIIIII
IIIIIIIIII
II
II
II
II
II
II
II
II
IIIIIIIIII
IIIIIIIIII

The four sections of this chapter discuss the zoned and packed decimal number representations
and typical operations on each.
Section 27 discusses the zoned and packed decimal representations and instructions that
convert between them.
Section 28 gives an overview of the principles of packed decimal arithmetic, to help you understand the operation of the instructions in Sections 29 and 30.
Section 29 describes the instructions that perform packed decimal arithmetic operations.
Section 30 describes instructions used to convert data between packed decimal and binary, and
between packed decimal and character strings.
The other z System decimal data format, decimal floating-point, will be discussed in the next
chapter.

Chapter VIII: Zoned and Packed Decimal Data and Operations

453

27. Zoned and Packed Decimal Representations

2222222222 777777777777
222222222222 777777777777
22
22 77
77
22
77
22
77
22
77
22
77
22
77
22
77
22
77
222222222222
77
222222222222
77

In this section we examine the zoned decimal and packed decimal representations of data, which
are useful in applications requiring decimal arithmetic, compactness, selectable precision, and simplicity. (Packed decimal is different from decimal floating-point, which is discussed in the next
chapter.) Well start with the instructions in Table 189.
Op
D1
F2
E9
E1

Mnem
MVN
PACK
PKA
PKU

Type
SS
SS
SS
SS

Instruction
Move Numerics
Pack
Pack ASCII
Pack Unicode

Op
D3
F3
EA
E2

Mnem
MVZ
UNPK
UNPKA
UNPKU

Type
SS
SS
SS
SS

Instruction
Move Zones
Unpack
Unpack ASCII
Unpack Unicode

Table 189. Basic packed and zoned decimal instructions

The zoned and packed decimal data representations of z System provide simple and economical
ways to store decimal data that will not take on a large range of values. There are no instructions
that perform arithmetic with zoned decimal data; its main use is as an intermediate step between
the internal packed decimal representation (with which arithmetic is possible), and an external
representation such as character data.

27.1. Zoned Decimal Representation


First, two definitions. The two hexadecimal digits of a byte are known as the zone (high-order)
digit and the numeric (low-order) digit, represented by Z and n in Figure 260.

Z n Z n Z n Z n Z n

Figure 260. Zone and numeric digits of a byte

The MVN and MVZ instructions are almost identical to MVC: rather than moving entire bytes,
they move only the numeric digits or the zone digits, respectively. To illustrate, suppose we define
a string of bytes at the constant named RandomF and move the numeric and zone digits to byte
strings named Numerics and Zones respectively.

454

Assembler Language Programming for IBM z System Servers

Version 1.00

MVN Numerics,RandomF Move numeric digits


MVZ Zones,RandomF
Move zone digits
- - RandomF DC
XL8 FEDCBA987654321F
Source operand
Numerics DC
XL8 0
Numerics
Zones
DC
XL8 0
Zones
Figure 261. Example of MVN and MVZ instructions

Then, the contents of the two byte strings will be


c(Numerics) = X 0 E0C0A080604020F
c(Zones)
= X F0D0B09070503010
The two following examples illustrate some simple uses.
1. Convert the non-negative halfword integer at N to a string of five EBCDIC characters beginning at NDec, which give the decimal representation of the contents of the halfword at N.

XXX

NDec
N

LH
1,N
Number to be converted in odd reg
LA
2,L NDEC
Use GR2 to count number of digits
SR
0,0
Clear high-order (even) register
D
0,=F 1 0
Generate a digit
STC 0,NDEC-1(2)
Store digit in output string
BCT 2,XXX
Count and branch until done
MVZ NDEC,=(L NDEC)X FF
Attach zones for EBCDIC
- - DS
CL5
Converted result
DC
H12345
Number to convert

We could have used literals such as =5C 0 or =5C 9 in the MVZ instruction, with the same
results.
2. Convert the five-digit decimal number in EBCDIC form at NDec to a fullword binary integer,
and store it at MM.
RW
RNum
RC
RDP

Mult

Temp

EQU 0
EQU 1
EQU 2
EQU 3
MVN TEMP,NDEC
LA
RDP,Temp
LA
RC,L NDEC
SR
RW,RW
SR
RNum,RNUM
MH
RNum,=H 1 0
IC
RW,0(,RDP)
AR
RNum,RW
LA
RDP,1(,RDP)
BCT RC,Mult
ST
RNUM,MM
- - DC
XL(L NDEC) 0

Work register for inserting digits


Value accumulated in GR1
Count digits in GR2
Digit pointer
Move numeric portions of digits
Address of current digit in RDP
Number of digits to be processed
Clear RW for digits
And RNum for number being generated
Multiply accumulated part by 10
Insert digit from input, unzoned
Add to partial sum
Increment digit address
Count and loop
Store result
Zones pre-zeroed, digits moved in

As we will see, the CVD and CVB instructions considerably simplify the conversion of
numbers between binary and decimal formats.
These instructions are sometimes used in processing packed decimal data.
Calling the left and right hex digits of a byte the zone and numeric digits might seem to limit
the use of MVZ and MVN to packed and zoned decimal data. However, they simply move the
left or right digits of a string of bytes, no matter what data type they represent.
The zoned decimal representation actually differs little from the familiar EBCDIC representation
for characters. For example, the EBCDIC representation of the decimal characters 12345 is
Chapter VIII: Zoned and Packed Decimal Data and Operations

455


F 1 F 2 F 3 F 4 F 5

The only difference between the zoned decimal and EBCDIC representations of the digits 12345 is
in the treatment of the zone digit of the rightmost byte. In the EBCDIC representation, the zone
digit is X F , as illustrated above. In the zoned decimal representation, however, this digit may be
any of the six hexadecimal digits A, B, C, D, E, or F; they are treated as the sign of the zoned
number, as indicated in Figure 262.

Sign Digit Sign

A
+

C
+

E
+

F
+

Figure 262. Zoned decimal sign conventions

Of the six possible sign digits, the preferred values are X C for + and X D for . Thus,
the zoned decimal representation of + 12345 is

F 1 F 2 F 3 F 4 C 5

Table 190 contains some some examples of zoned decimal constants: As these examples illustrate, leading zeros may appear in a zoned decimal number without affecting its value.
Value
+12345

Representation
X F1F2F3F4C5

-12345

X F1F2F3F4D5

+003
-0999

X F0F0C3
X F0F9F9D9

Table 190. Examples of zoned decimal data

If these byte strings are printed, the last character in each will be a letter!
Figure 263 gives a pictorial representation of a zoned decimal number, where Z represents a
zone digit, S represents a sign digit, and d represents a numeric (decimal) digit.

Z d Z d Z d Z d S d

Figure 263. A zoned decimal number

All of the decimal characters we saw in previous sections used X F for their zone digits Z.
Other zone digits are used for ASCII and Unicode numeric character data.

456

Assembler Language Programming for IBM z System Servers

Version 1.00

27.1.1. Why Zoned Decimal Is The Way It Is (*)


The reason for the choice of preferred zones comes from the days of punched cards. To save
space in the card column containing the last character of a numeric field, by convention a hole
corresponding to the desired digit and another zone punch appeared in one of the two top rows of
the same card column.
For example, a punched card containing two 10-character fields containing the right-adjusted
numbers + 12345 and 67890 would appear as shown in Table 191:


0000000000000000000000000000000000000000000000000000000000000000000000000000000
1111111111111111111111111111111111111111111111111111111111111111111111111111111
2222222222222222222222222222222222222222222222222222222222222222222222222222222
3333333333333333333333333333333333333333333333333333333333333333333333333333333
4444444444444444444444444444444444444444444444444444444444444444444444444444444
5555555555555555555555555555555555555555555555555555555555555555555555555555555
6666666666666666666666666666666666666666666666666666666666666666666666666666666
7777777777777777777777777777777777777777777777777777777777777777777777777777777
8888888888888888888888888888888888888888888888888888888888888888888888888888888
999999999999999999999999999999999999999999999999999999999999999999999999IBM5081
Table 191. Punched-card image of two numbers, + 12345 and 67890

The technique of using the top two unnumberedrows of the card indicated both the end of a
field of digits, and the sign of the number: if the number was positive, the 12-row (top row) of the
card column containing the numeric digit punch was also was punched, and if the number was
negative the 11-row (the next to top row) was punched. This meant that + 5 appeared as the
letter E (with hex representation X C5 ), and 9 appeared as the letter R (with hex representation X D9 ). When numbers in this representation are read into memory as EBCDIC
characters, the presence of a sign punch over the last digit automatically gives the zoned decimal
representation of the number. (If a sign is prefixed to the digits, a + sign is a single punch in the
12-row, and a sign is a single punch in the 11-row.)

Exercises
27.1.1.(2) + In Figure 261 on page 455, why are Numerics and Zones defined with explicit
length 8? Show the results if they had been defined instead by
Numerics DC
Zones
DC

8X 0
8X 0

27.1.2.(1) + What will be the result of executing these two instructions?


MVN
MVZ

Target,Source
Target,Source

27.1.3.(3) Write an instruction sequence using TRT to test the validity of the digit and sign in
the rightmost byte of the zoned decimal number at ZTest. If the digit portion is invalid, branch
to BadDigit; if the sign portion is invalid, branch to BadSign; and if both are invalid, branch to
BadByte. If you can also determine the sign of a valid byte, branch to ZPlus for a plus sign and
to ZMinus for a minus sign.
27.1.4.(2) + Write an instruction sequence using TRT to test the validity of all but the rightmost
byte of the zoned decimal number at ZTest. If any byte is invalid, branch to BadZDig with
GR1 containing the address of the invalid byte.
27.1.5.(1) In Table 190, what will be printed for the rightmost byte of each item?
Chapter VIII: Zoned and Packed Decimal Data and Operations

457

27.1.6.(2) Find the EBCDIC punched card code for the + and characters. Now, do the same
for the BCD punched card codes.
27.1.7.(1) + After example 1 of using the MVZ instruction (on page 455), it was stated that the
literals =5C 0 and =5C 9 could have been used also. Explain why this is so.
27.1.8.(2) Consider the MVZ instruction in the same example as in Exercise 27.1.7. Could the
statement have been written in any of the following forms? Explain why or why not.
MVZ
MVZ
MVZ
MVZ

NDec,=XL5 FF
NDec,=(NDec)X FF
NDec,=XL(L NDec)X FF
NDec,=(L NDec)X FF

27.2. Zoned Decimal Constants


Zoned decimal constants are defined with a DC statement with type Z. Each digit in the constant is translated into a single byte in storage and the Assembler assigns the preferred sign code
to the rightmost byte. For example, the constants in Table 190 on page 456 could be defined
with either of these statements:
ZoneA
ZoneB

DC
DC

Z12345,Z -12345 , Z+003,Z -0999


Z12345,-12345,+003,-0999

Figure 264. Zoned decimal constants with implied lengths

When the length of the constant is implied (as in Figure 264), the length of the constant is the
same as the number of digits in the nominal value. As usual, the length attribute of the namefield symbol is that of the first constant in the first operand.
A decimal point may be placed anywhere in a zoned decimal constant. Its presence is ignored,
and it does not appear in the generated constant. 168 Thus, both
DC
DC

Z12345.
Z.12345

and

generate X F1F2F3F4C5 .
To specify an explicit length, use a length modifier. If the value of the length modifier is less than
the number of digits, the constant will be truncated at the left end to the required length:
DC

ZL312345

Truncated constant = X F3F4C5

If the value of the length modifier is greater than the number of digits, the Assembler will pad
with high-order (zoned, EBCDIC) zeros, with representation X F0 :
DC

ZL5123

Padded constant = X F0F0F1F2C3

The maximum length of a zoned decimal constant is 16 bytes.


The constants in Table 190 on page 456 could also be defined with explicit lengths:
ZoneC

DC

ZL512345,ZL5 -12345 , ZL3 3 , ZL4 -999

Figure 265. Zoned decimal constants with explicit lengths

Scale and exponent modifiers, and decimal exponents, are not supported for Z-type constants.

168

458

The position of the decimal point is reflected in the integer and scale attributes of the symbol, which are useful mainly
in macro instructions. They are rarely if ever used with zoned constants.
Assembler Language Programming for IBM z System Servers

Version 1.00

Exercises
27.2.1.(1) + What data would be generated if we wrote the constants in Figure 264 as
ZoneD

DC

ZL512345,-12345,+3,-999

Is anything different? If so, what and why?


27.2.2.(1) Show the generated data for these zoned decimal constants:
(1) Z -1

(2) Z+0

(3) Z -042

(4) ZL2 5

27.2.3.(1) What decimal value is represented by the following zoned decimal constants?
(1) X F0B9

(2) X F2

(3) X F0F0A7 (4) X B0

27.2.4.(1) Show the generated data for these zoned decimal constants:
(1) ZL16123456.789
(3) ZL5.654321

(2) Z123456789012345678
(4) ZL20 2 . 2 0

27.2.5.(2) + How many valid zoned decimal values can be represented in a single byte?
27.2.6.(2) + What data would be generated if we wrote the constants in Figure 264 as
ZoneD

DC

CL512345,-12345,+3,-999

What is different? Why?


27.2.7.(1) + What are the length attributes of the symbols in Figure 264?

27.3. Packed Decimal Representation


The packed decimal representation is often used when computing speed is less important than
economy of storage space, and we want speed and simplicity of conversion to and from character
form. Also, because humans calculate in decimal, operations like rounding are more intuitive
than if the same calculation is done using binary data, and can be more accurate than the same
computations in binary.
As its name implies, data is more closely packed than in the zoned decimal representation. The
basic data element is the binary coded decimal (BCD) digit169 represented by four bits; these BCD
digits can be packed two to a byte. The six bit combinations corresponding to the hex digits A
through F are invalid data digits in the packed decimal representation. If an invalid data digit
appears in an arithmetic operation, the CPU will generate an interruption for invalid Decimal
Data.
The rightmost digit position of a packed decimal number is reserved for its sign, which obeys the
conventions shown in Figure 262 on page 456. As with zoned decimal data, the preferred values
for the sign digit are X C for +, and X D for .
of Figure 263 on page 456, a packed decimal number will appear in storage as shown in Figure
266. Note that there are no zone digits in a packed decimal number.

169

This representation, where a decimal digit is encoded in four bits, is often called binary coded decimal. To avoid
confusion with the 6-bit character code that was also called Binary Coded Decimal (see Section 26.1.1 on page 429
and Table 166 on page 430), we will use the terms packed decimal digit or decimal digit instead.
Chapter VIII: Zoned and Packed Decimal Data and Operations

459


d d d d d d d d d d d S

Figure 266. Representation of a packed decimal number

Packed decimal numbers look more like numbers we are familiar with, and the sign being at the
right end is a small adjustment for us to make. Some examples are shown in Table 192.
Value
+12345
-0012345
+3
-09990
39

Representation
X12345C
X0012345D
X 3C
X09990D
X039C

Table 192. Examples of packed decimal


data

Any extra digits at the left end will be set to zero. Because the sign always occupies one digit
position, a packed decimal number in memory always has an odd number of digits. Packed
decimal data may be up to 16 bytes long, so it is possible to have 31-digit numbers; however,
some operations on decimal data require shorter operands.
The packed decimal representation has an unusual feature: it is possible to have a negative sign
digit and all zero data digits. Thus, packed decimal is an example of a sign-magnitude representation,. In most cases, a zero result of an operation is given a positive sign digit, but it is also
possible to generate negative zeros in special cases. Thus it is not possible (as is possible in the
twos complement binary representation) to determine that a number is strictly negative by examining its sign digit.
There is also an unsigned packed decimal representation used in conjunction with decimal floating
point; well investigate it in Section 35.

Exercises
27.3.1.(2) + A packed decimal number contains N digits; give a formula for the number of bytes
required to hold it in memory.
27.3.2.(2) How many valid packed decimal values can be represented in a single byte?
27.3.3.(4) Test the packed decimal number at Pack for validity with a single TRT instruction
and a suitable translate table. If the number is valid and nonzero branch to PPlus or PMinus
depending on its sign. Otherwise,
if the sign is invalid branch to BadSign
if a byte contains an invalid digit branch to BadDigit
if a byte contains both an invalid sign and digit branch to BadByte
with the address of the byte containing the invalid data in GR1.
27.3.4.(2) + Suppose you must force the sign of the packed decimal number at SomeVal to be
positive. Show you you can do this with one instruction.
27.3.5.(3) A packed decimal operand is known to have a bad numeric digit. Create a translate
table that can be used with a TRT instruction to identify both the byte with the bad digit, and
whether the first or second digit is invalid.
27.3.6.(3) Suppose you must force the sign of the packed decimal number at SomeVal to be
negative. Can you do this with one instruction? (Compare to your answer for Exercise 27.3.4.)

460

Assembler Language Programming for IBM z System Servers

Version 1.00

27.4. Packed Decimal Constants


Packed decimal constants are defined using a DC statement with type P. For example, we
could define the constants in Table 192 with these statements:
PackA
PackB

DC
DC

P12345,P -0012345 , P + 3 , P -9990 , P 3 9


P12345,-012345,3,-09990,39

Figure 267. Packed decimal constants with implied lengths

When the lengths are implied, the Assembler generates exactly the number of bytes needed to
contain the constant, and no more. Remember that the number of packed decimal digits is
always odd, so that a value with an even number of digits will have an extra high-order zero digit
supplied by the Assembler. As with Z-type constants, the maximum length of a packed decimal
constant is 16 bytes, or 31 decimal digits.
Explicit lengths are assigned to packed decimal constants in the usual way, with padding and truncation being performed at the left end of the constant. The constants in Figure 267 could be
specified with explicit lengths, as shown in Figure 268.
PackC

DC

PL312345,PL4 -12345 , PL1 3 , PL3 -9990 , PL2 3 9

Figure 268. Packed decimal constants with explicit lengths

As with zoned decimal constants, scale and exponent modifiers are not allowed. An optional
decimal point may be placed within a constant, but its presence is ignored in forming the constant. This means that we can write constants such as
YourPay DC
MyPay
DC

P947.24
P13.07

Stored value = 94724C


Stored value = 01307C

and the decimal point can help you to understand an intended use of the data.
Because the position of the decimal point doesnt affect the generated constant, we can write constants like these, all of which generate the same data:

MyPay

DC
DC
DC
DC
DC

P1307.
P130.7
P13.07
P1.307
P.1307

Stored
Stored
Stored
Stored
Stored

value
value
value
value
value

=
=
=
=
=

01307C
01307C
01307C
01307C
01307C

Unfortunately, this means that you must remember where the decimal point lies. Programming
financial applications involving fractional quantities like currency and interest rates in packed
decimal can be quite difficult if you must know the position of the decimal point for the operands
of each arithmetic operation.
Similarly, the same value can have multiple representations:
DC
DC
DC
DC

P1307.
PL41307
PL51307
PL61307

Stored
Stored
Stored
Stored

value
value
value
value

=
=
=
=

01307C
0001307C
000001307C
00000001307C

We will see in Section 35 on page 667 that decimal floating-point arithmetic is much simpler.

27.4.1. Scale Attributes and Packed Decimal Constants (*)


Although a generated packed decimal constant ignores any decimal point in the nominal value,
the Assembler assigns a Scale Attribute to any symbol naming the constant. The value of the
scale attribute is the number of decimal digits to the right of the decimal point. For example:

Chapter VIII: Zoned and Packed Decimal Data and Operations

461

MyPay
MyPayA
MyPayB
MyPayC
MyPayD

DC
DC
DC
DC
DC

P13.07
P130.7
P.0013
P1.200
P1307

Scale
Scale
Scale
Scale
Scale

Attribute
Attribute
Attribute
Attribute
Attribute

=
=
=
=
=

2
1
4
3
0

You can retrieve the scale attribute of a symbol using the S operator, just as the L operator
retrieves its length attribute.
Scale attributes can be very helpful in complex calculations involving numbers with fractional
values, but the necessary techniques usually require some practice.

Exercises
27.4.1.(2) + For each of the following zoned and packed decimal constants, state which ones are
invalid, and why. For the valid constants, show (in hex) the generated bytes.
Z1
Z2
P3
P4
Z5
P6
P7
Z8

DC
DC
DC
DC
DC
DC
DC
DC

Z2147483648
ZL92147483647
PL6 -99999999999
P+123,456,789
ZL20 5 0 0 , PL20500
P3.1415926535
PL1 4 0 , ZL1 4 0
Z1,20,400,80000,1600000000

27.4.2.(1) + For each of the DC statements in Exercise 27.4.1, determine the length attribute of
each symbol that names a valid constant.
27.4.3.(1) + What sort of constant is generated by the DC operand PL2 1000? (Try it with the
Assembler.)
27.4.4.(2) Both of these constants will be truncated, since more digits are specified than the
explicit length allows.
DC
DC

PL20000437
ZL3 -000904

However, the truncated digits are all zeros; should this condition be considered an error by the
Assembler?
27.4.5.(2) The nominal values in Figure 267 on page 461 are different, but they generate the
same machine language data. How is this possible?
27.4.6.(3) The packed decimal number at P is from 1 to 4 bytes long. Write instructions to
load the number into GR6 to form a valid 4-byte packed decimal number. For example, if
c ( P ) = X 123C , the result in GR6 should be X 0000123C .
27.4.7.(3) Repeat Exercise 27.4.6, now assuming the packed operand at P can be from 1 to 8
bytes long, and that it should be loaded into GG6.
27.4.8.(2) A four-byte area of memory contains the bit pattern X 4040405C . What is represented by that pattern?
27.4.9.(5) Write (and test!) a single DC statement that generates all 1000 two-byte packed
decimal constants from X 000C through X 999C , representing 000 + through 999 + .
27.4.10.(5) Write (and test!) a single DC statement that generates all 1000 three-byte zoned
decimal constants from X F0F0C0 through X F9F9C9 .
27.4.11.(1) Determine the scale attributes of each of these constants:

462

Assembler Language Programming for IBM z System Servers

Version 1.00

A
B
C
D
E

DC
DC
DC
DC
DC

P1.4142135
P002471.360
P16777216.5
P186.3541
P2236067977

27.4.12.(3) The Assembler assigns an Integer Attribute to symbols naming packed decimal data.
Its value is the number of decimal digits to the left of the decimal point, and the value can be
retrieved with the I operator.
Given the L (Length) and S (Scale) attribute values of a symbol X naming a packed decimal
constant, derive a formula for the value of its Integer Attribute.
27.4.13.(2) Using your results from Exercise 27.4.12, determine the Length, Integer, and Scale
Attributes of the symbols in Exercise 27.4.11.
27.4.14.(2) Using the definitions in Exercise 27.4.12, given the L and S attribute values of a
symbol X naming a zoned decimal constant, derive a formula for the value of its Integer Attribute.

27.5. Converting Between Packed and Zoned


Because packed decimal data is often used in applications needing conversion between external
(character) and internal forms, z System provides two instructions that simplify this process.
The PACK instruction converts data from zoned to packed decimal, and the UNPK instruction
converts packed decimal data to zoned. (There are two other powerful instructions for converting
from packed decimal to character form, ED and EDMK; well discuss them in Section 30.) Both
PACK and UNPK are SS-type instructions, as illustrated in Table 9 on page 55.
The Assembler Language syntax for these two instructions is shown in Figure 269:
mnemonic D1(N1,B1),D2(N2,B2)
Figure 269. Format of typical two-length SS-type instructions

Compared to Figure 196 on page 368, which has only one length field, these have two, N1 and
N 2; and, unlike the SS-type instructions described in Section 25 (compare Table 150 on
page 404), the length specification byte requires two four-bit length fields, as in Table 193.
opcode

L1

L2

B1

D1

B2

D2

Table 193. Format of two-length SS-type instructions

The length digits L1 and L 2 take values between 0 and 15, specifying operand lengths N1 and N 2
of 1 to 16 bytes. (Section 24.1. Basic SS-Type Instructions on page 367 explains the reasons
for the differences between N, N1, N 2, and L, L1, L2: the L values the CPU sees are one less
than the N values you specify.)
Because there are six operand-dependent components in these instructions, the operand field of
the machine instruction statements may take a great variety of forms. Each operand may have
the same form as the first operand of the one-length SS-type instructions discussed in Section 25;
that is, both length and address may be implied or explicit for each operand.
The possible forms of either operand are summarized in Table 194. Though the quantities B1, D 1,
and N 1 refer to the first operands, the possible forms of the second operand are identical.

Implied Address
Explicit Address

Implied Length
S1
D 1(,B1)

Explicit Length
S1(N 1)
D 1(N 1,B 1)

Chapter VIII: Zoned and Packed Decimal Data and Operations

463

Table 194. Operands of two-length SS-type instructions

These examples illustrate the four forms of a first operand:


PACK
PACK
PACK
PACK

A,B
A(7),B
24(,9),B
24(7,9),B

Implied address and length


Implied address, explicit length
Explicit address, implied length
Explicit address and length

The form of the first operand in the third example is rarely used, because the implied length of the
first operand will usually be 1, the length attribute of the term used for the displacement D1.
If the length of an operand is implied, the value assigned to the Length Expressions N1 and N 2 is
the length attribute of the leftmost term in the expressions S1, S2, D 1 or D 2, as appropriate.
As we saw in Section 24 for the one-length SS-type instructions, the number the Assembler places
into the Encoded Length digits L1 and L 2 is actually one less than the value of the corresponding
Length Expressions N 1 and N 2, whether implied or explicit. As with other SS-type instructions,
an explicit Length Expression N of value zero is assembled as a zero length digit.
To illustrate, suppose the symbols AA and BB have length attributes 2 and 11, respectively. Then
the following statements would be assembled as shown. Only the length digits L1 and L 2 are
important for this example; ignore the bddd base and displacement fields. (The operation codes
X F2 and X F3 are for PACK and UNPK respectively, as shown in Table 189 on page 454.)
*
*

AA
BB

Instruction

Assembled Form

PACK
UNPK
PACK
PACK
UNPK
PACK
- - DS
DS

F244
F3A1
F2F0
F200
F3A1
F212

AA(5),BB(5)
BB,AA
0(16,9),65(,2)
AA(0),BB(0)
BB-AA(,9),BB(L AA)
AA,BB+11(3)

bddd
bddd
bddd
bddd
bddd
bddd

bddd
bddd
bddd
bddd
bddd
bddd

N1=5,N2=5
N1=11,N2=2
N1=16,N2=0
N1=0,N2=0
N1=11,N2=2
N1=2,N2=3

L1=4,L2=4
L1=10,L2=1
L1=15,L2=0
L1=0,L2=0
L1=10,L2=1
L1=1,L2=2

PL2
ZL11

Figure 270. Examples of assembled PACK and U N P K instructions

In each case the L value is one less than the N value, but if the N value is zero, the L value is
also zero.
This illustrates another reason why the Encoded Length byte L (in one-length SS-type
instructions), and the Encoded Length digits L1 and L 2 (in two-length SS-type instructions), are
one less than the values given for the Length Expressions in machine instruction statements. To
obtain the addresses of the starting bytes of the operands of a PACK or UNPK instruction, the
CPU simply adds the length specification digits to the Effective Addresses derived from the
addressing halfwords.
Even though were describing PACK and UNPK in the context of zoned and packed decimal
data, the instructions are not sensitive to data types: they simply move data in prescribed ways,
whatever their type.
The PACK and UNPK instructions, unlike many of the SS-type instructions we have discussed,
process data from right to left. Neither sets the Condition Code.

Exercises
27.5.1.(1) + In Figure 270, determine the bddd values for every explicit address.

464

Assembler Language Programming for IBM z System Servers

Version 1.00

27.6. The PACK Instruction


The PACK instruction (and the UNPK instruction to be described in Section 28.7) have the
machine instruction format shown in Table 193, and the operands of its assembler instruction
statements take any of the forms shown in Table 194.
PACK converts data from zoned to packed form. Its operation is easily visualized by writing a
number in both representations. Well use +12345 again, which has these zoned and packed
forms:

F 1 F 2 F 3 F 4 C 5

1 2 3 4 5 C

Figure 271. Zoned and packed forms of + 1 2 3 4 5

If we interchange the digits of the rightmost byte of the zoned form, we obtain the rightmost byte
of the packed form. The remaining digits are extracted in right-to-left order from the numeric
portion of each zoned byte, and placed into the proper positions in the packed operand. This is
illustrated in Figure 272.

Z d Z d Z d Z d S d Zoned operand




  


     

d d d d d S Packed operand

Figure 272. PACK instruction operation

If the zoned and packed operands were named ZonOp and PackOp respectively, we could perform
the operation pictured in Figure 272 with this instruction:

ZonOp
PackOp

PACK PackOp,ZonOp
- - DC
Z12345
DS
PL3

From zoned to packed


Zoned operand, length = 5 bytes
Packed operand, length = 3 bytes

Figure 273. Converting from zoned to packed decimal using PACK

No checking is done for invalid data digits in the packed operand; the instruction just moves data
as illustrated. But, you should ensure that valid packed operands are generated if they are to be
used for arithmetic.
In the operation illustrated in Figure 272, the operands were chosen to contain exactly the right
number of digits. However, either operand of a PACK instruction might be too long for the
other. The rules for such cases are:
1. If the first (packed) operand is completed before the zoned operand is exhausted, the rest of
the zoned operand is ignored.
2. If the second (zoned) operand is exhausted before the packed operand is completed, the
remaining high-order digits of the packed operand are filled with zeros. (If this was not done,
the high-order digit positions of the packed operand might contain unknown values.)
The PACK operation is therefore controlled by the length of the first operand; the result always
has the specified length. The second (zoned) operand is unmodified (assuming no overlap).
Chapter VIII: Zoned and Packed Decimal Data and Operations

465

To illustrate, suppose we execute some PACK instructions with operands of various lengths, as in
Figure 274. The result of each operation is shown in the comment field of the statement defining
the first operand.
PACK
PACK
PACK
PACK
- - DC
DS
DS
DS
DS

Zone
P1
P2
P3
P5

P1,Zone(4)
P2,Zone
P3,Zone(2)
P5,Zone

Lengths
Lengths
Lengths
Lengths

1,
2,
3,
5,

4
5
2
5

Z12345
PL1
PL2
PL3
PL5

Zoned operand = X F1F2F3F4C5


Result = X 4F
Result = X345C
Result = X00012F
Result = X000012345C

Figure 274. Examples of the PACK instruction

Note especially the result at P1: because the length of the second operand in the first PACK
instruction was explicitly specified as 4 (rather than the correct implied length of 5, as in the
second PACK instruction), the rightmost byte of the second operand is X F4 You must be
careful to specify correct lengths for the operands of PACK instructions because significant data
digits can easily be lost, or undesired or unexpected values may be generated.
The first and second operands of a PACK instruction could overlap. While such uses are almost
always accidental, this programming trick might be useful in special cases.
If overlap occurs with PACK operands, the CPU will store the completed first operand
(packed) byte after fetching the next two second operand (zoned) bytes (or the next one byte,
if that will exhaust the second operand).
We saw in Figure 272 that the two hex digits of the rightmost byte are interchanged. We can use
this property of PACK to swap the digits of any byte:
PACK A,A
- - DC
X 1 2

Swap digits of A
Result = X 2 1

Figure 275. Digit swap using PACK

Exercises
27.6.1.(1) + Suppose a zoned decimal operand containing NZ bytes is to be converted to packed
decimal form. Give a formula for NP, the minimum number of bytes required for the packed
decimal operand.
27.6.2.(2) Suppose you execute this PACK instruction:

PData

PACK PData,XXX
- - DS
PL6

Show the contents of the field at PData if the data at XXX is defined as follows:
1. XXX
2. XXX
3. XXX

DC
DC
DC

F -9
C Hello, World!
CA Hello, World!

27.6.3.(4) Write a program segment which will simulate the action of the PACK instruction.
Assume that the packed and zoned operands are stored at POP and ZOP respectively, and that
the length attributes of those symbols are the correct operand lengths. That is, the code should
produce the same result as:
PACK POP,ZOP

466

From zoned to packed

Assembler Language Programming for IBM z System Servers

Version 1.00

Without using a PACK instruction, of course!


27.6.4.(3) Suppose a PACK instruction specifies operands that overlap. Where must the rightmost byte of the first (target) operand be placed relative to the first byte of the second (source)
operand, so that the correct result will be obtained in all cases?
27.6.5.(2) + For the zoned decimal constant named ZData, show the result of executing each of
the following PACK instructions.
ZData

DC
- - PACK
PACK
PACK
PACK
PACK

Z2468,Z1357
P1(2),ZData
P2(3),ZData
P3(1),ZData+1(2)
P4(6),ZData+2(6)
P5(5),ZData(L ZData+3)

27.6.6.(3) + Suppose a zoned decimal operand is packed onto itself. That is, the first and
second operands of a PACK instruction are identical. What is the maximum length of the
operand such that the result will be correct? The minimum length?
27.6.7.(3) Give the contents of the storage area named DATA after executing the following
PACK instruction.

DATA

PACK DATA,DATA
- - DC
X123456789ABCDEF

27.6.8.(2) + A common programming convention is that an all-blank field on a data record


should be interpreted as a zero value. What will be the result of PACKing a string of blank
characters? Need anything be done to the result? If so, what?
27.6.9.(2) Suppose we start with a zoned decimal operand at Zone having length N bytes, and
execute the instruction
PACK PackOp,Zone(K)
where the length K is always less than or equal to N. Consider possible lengths for the first
operand PackOp: under what conditions will a valid packed result be obtained?
27.6.10.(2) Suppose you need to pack some zoned data at ZData by EXecuting this PACK
instruction:
PACK PackData(*-*),ZData
The length of the packed decimal field at PackData is contained in GR2, and does not exceed
16. Write a sequence of instructions to do this.
27.6.11.(1) + Suppose you execute this PACK instruction:

PACK P,P
- - DC
X ABCDEF

Pack a field onto itself

What result will be at P?


27.6.12.(2) Suppose you execute this PACK instruction:

Q
P

PACK
- - DS
ORG
DC

Q,P

Pack a field onto itself

XL3
Q+1
X ABCDEF

Result field
Source field starts at Q+1
Source field

What result will be at Q?

Chapter VIII: Zoned and Packed Decimal Data and Operations

467

27.6.13.(2) Suppose you execute this PACK instruction:

Q
P

PACK
- - DS
ORG
DC

Q,P

Pack a field onto itself

XL3
Q-1
X ABCDEF

Result field
Source field starts at Q-1
Source field

What result will be at Q?


27.6.14.(1) + When you PACK a zoned decimal field, what will be different in the result if the
numeric digits are preceded by blanks or by leading zeros?

27.7. The UNPK Instruction


The UNPK instruction performs the inverse of PACK: it transforms a packed decimal operand
into zoned decimal form. Like PACK, the UNPK instruction
does not set the Condition Code,
does not check for valid data or sign digits in the packed operand, and
is controlled by the length of the first (zoned) operand.
The digits of the low-order byte of the second (packed) operand are switched, and the result
becomes the rightmost byte of the first (zoned) operand. Successive digits are then taken in rightto-left order from the packed operand and placed into the numeric-digit positions of successive
bytes in the zoned operand, with X F placed in each zone digit.

d d d d d S Packed operand

     






  

Z d Z d Z d Z d S d Zoned operand

Figure 276. Operation of the U N P K instruction

Figure 277 shows how to convert the packed value +12345 to zoned form.

ZonOp
PackOp

UNPK ZonOp,PackOp
- - DS
ZL5
DC
P12345

From packed to zoned


Zoned operand, length = 5 bytes
Packed operand, length = 3 bytes

Figure 277. Example of an U N P K instruction

In the PACK operation, the zone digits of the zoned operand were discarded. For the UNPK
operation, the zone digits are supplied by the CPU. 170

170

468

On System/360 CPUs, the zone digits were determined by the setting of the A bit in the PSW, which is no longer
used. If the A bit was zero, the CPU assumed that EBCDIC characters are desired, and automatically supplied a
zone digit X F where needed; if the A bit was 1, the CPU assumed that characters in the USASCII representation
are desired, and supplied X 5 for the zone digits. (This is different from the current definition of ASCII, where the
zone digits are X 3 .)
Assembler Language Programming for IBM z System Servers

Version 1.00

When the lengths of the two operands do not correspond exactly, rules like those for PACK
apply to UNPK:
1. If the first (zoned) operand is completed before the packed operand is exhausted, the rest of
the packed operand is ignored.
2. If the second (packed) operand is exhausted before the zoned operand is completed, the
remaining high-order bytes of the zoned operand are completed with zoned zeros.
To illustrate the operation of the UNPK instruction, the result of unpacking a packed decimal
number is shown in the comment field of each statement.

Pack
Z5
Z7
ZB
ZA
Z4

UNPK
UNPK
UNPK
UNPK
UNPK
- - DC
DS
DS
DS
DS
DS

Z5,Pack
Z7,Pack
ZB,Pack
ZA,Pack(2)
Z4,Pack(1)

Data
Data
Data
Data
Data

lengths
lengths
lengths
lengths
lengths

P12345
ZL5
ZL7
ZL3
ZL3
ZL4

3-byte
Result
Result
Result
Result
Result

5,
7,
3,
3,
4,

3
3
3
2
1

packed operand, X12345C


= X F1F2F3F4C5
= X F0F0F1F2F3F4C5
= X F3F4F5
= X F1F243
= X F0F0F021

Figure 278. Examples of U N P K instructions

If you study the results at ZA and Z4 you will understand the need for care in specifying the
lengths of the operands, since possibly invalid zoned decimal results can be generated; we saw
similar incorrect results in Figure 274.
As was done with the PACK instruction in Figure 275, we can use UNPK to swap the hex digits
of a byte:
UNPK A,A
- - DC
X 1 2

Swap digits of A
Result = X 2 1

Figure 279. Digit swap using U N P K

The first and second operands of an UNPK instruction could overlap. While such uses are
almost always accidental, this behavior might be useful in special cases.
If overlap occurs with UNPK operands, the CPU processes the operands by storing two result
bytes immediately after the necessary source operand byte has been fetched for the next step.
In Section 30.3 on page 526 well see how the powerful ED and EDMK instructions make it easy
to format packed decimal data for printing and display.

Exercises
27.7.1.(1) + In Figure 273 on page 465, what will be the contents of the memory area named
PackOp after executing the PACK instruction? In Figure 277 on page 468, what will be at ZonOp
after executing the UNPK instruction?
27.7.2.(2) Suppose the CPU executes this UNPK instruction:

ZData

UNPK ZData,YYY
- - DS
ZL9

Show the contents of the field at ZData if the data at YYY is defined as follows:
1. YYY
2. YYY

DC
DC

F -9
C Hello, World!
Chapter VIII: Zoned and Packed Decimal Data and Operations

469

3. YYY

DC

CA Hello, World!

27.7.3.(3) Determine the result of executing an UNPK instruction instead of the PACK instruction in Exercise 27.6.7.
27.7.4.(4) Write a program segment like that in Exercise 27.6.3, except that the instruction
UNPK ZOP,POP

From packed to zoned

should be simulated.
27.7.5.(4) Suppose the operands of an UNPK instruction overlap, and assume that the address
of the last byte of the packed decimal operand is greater than or equal to the address of the last
byte of the zoned operand. What rule or rules can you state that will guarantee the same results
as if there were no operand overlap? For example, in this sketch the address of the last byte of
the packed operand is greater than the address of the last byte of the zoned operand.

packed operand

zoned operand

27.7.6.(2) + For the given packed decimal constant below, show the result of executing each of
the following UNPK instructions.
PData

DC
- - UNPK
UNPK
UNPK
UNPK
UNPK
UNPK

P123456
Z1(6),PData
Z2(7),PData
Z3(2),PData
Z4(6),PData+2(2)
Z5(4),PData(3)
Z6(2),PData+3

27.7.7.(3) Do the same as in Exercise 27.6.6, but now consider unpacking a packed decimal
operand onto itself using an UNPK instruction with identical operands.
27.7.8.(2) Suppose a packed decimal operand NP bytes long is to be converted to zoned
decimal form. Give a formula for NZ, the minimum number of bytes required for the zoned
operand. Is your formula the same (aside from algebraic rearrangement) as the result you
obtained in Exercise 27.6.1? If not, why not?
27.7.9.(3) In the PACK and UNPK instructions, the operation is controlled by the length specification digit for the first operand, namely L1. Why not use L 2? What would happen if the
longer length were chosen? The shorter?
27.7.10.(5) In Exercise 27.7.5 you considered the situation where the operands of an UNPK
instruction overlap, and the address of the rightmost byte of the second (packed) operand was
not less than the address of the first (zoned) operand. Now, suppose the operands overlap, but
the address of the rightmost byte of the packed operand is less than the address of the rightmost
byte of the zoned operand: what rule or rules can you state for the relations between operand
lengths and addresses that will guarantee the same results as if there were no operand overlap?
For example, in this sketch the address of the last byte of the packed operand is less than the
address of the last byte of the zoned operand.

packed operand

zoned operand

470

Assembler Language Programming for IBM z System Servers

Version 1.00

27.7.11.(4) Repeat Exercise 27.7.3, but now assume you execute the UNPK instruction twice in
succession. What will be in the field named Data when the second instruction completes execution?
27.7.12.(2) Figure 274 on page 466 and Figure 278 on page 469 illustrate how invalid results
can be generated when the length supplied for the second operand of the PACK and UNPK
instructions is not the same as the length of the datum. Give a general guideline which will
generate a valid result in such cases.
27.7.13.(3) Write program segments to perform the functions described in Exercises 27.7.10 and
27.7.11 using shifts, loops, and no translate instructions.
27.7.14.(2) Suppose you execute this UNPK instruction:

U
P

UNPK
- - DC
Org
DC

U,P

Unpack P operand to U

XL6 0
U+2
X123456

U initialized to 6 zero bytes


Position P at third byte of U
Three bytes of second operand P

What result will appear at U?


27.7.15.(3) Suppose you execute this UNPK instruction:

U
P

UNPK
- - DC
Org
DC

U,P

Unpack P operand to U

XL6 0
U+3
X123456

U initialized to 6 zero bytes


Position P at fourth byte of U
Three bytes of second operand P

What result will appear at U?


27.7.16.(3) Suppose you execute this UNPK instruction:

U
P

UNPK
- - DC
Org
DC

U,P

Unpack P operand to U

XL6 0
U+4
X123456

U initialized to 6 zero bytes


Position P at fifth byte of U
Three bytes of second operand P

What result will appear at U?


27.7.17.(2) + If you execute this UNPK instruction, what will be the result at Answer?

Answer
Start

UNPK Answer,Start
- - DS
ZL7
DC
P76543

27.8. Packing and Unpacking ASCII and Unicode Data (*)


Unlike the PACK and UNPK instructions, the packed decimal operand of the last four
instructions in Table 189 on page 454 is always 16 bytes long, and the Length Expression of the
instruction gives the length of the zoned operand. However, ASCII and Unicode numeric characters are not zoned in the same sense as zoned decimal data; there is no special sign code in
the rightmost byte.
Overlapping operands always generate unpredictable results.
As with PACK and UNPK, the ASCII pack and unpack instructions are not sensitive to data
types; they simply move data fields in a prescribed way. Both process data from right to left.

Chapter VIII: Zoned and Packed Decimal Data and Operations

471

27.8.1. Packing ASCII and Unicode Data


The PKA and PKU instructions convert numeric characters to packed decimal format. PKA is
simpler: like PACK, it extracts the numeric digits from the second operand and packs them into
the first operand. Both PKA and PKU have the format shown in Table 195; note that the
Encoded Length L refers to the second operand. Because there is no zone sign on the loworder character, the CPU automatically inserts a X C plus sign. Its up to you to know whether
the value should actually have a minus sign.
This format is the same as many of the SS-type instructions weve seen. However, the assembler
instruction statement format is different: the Length Expression N is specified in the second
operand:
mnemonic D1(B1),D2(N,B2)
Neither PKA nor PKU changes the Condition Code.
opcode

B1

D1

B2

D2

Table 195. Format of P K A and P K U instructions

Figure 280 shows an example of packing the ASCII characters at AChars into 16 bytes starting at
PDecA.
PKA PDecA,AChars
- - PDecA
DS
PL16
Packed decimal result (16 bytes)
AChars DC
CA1234567890123 ASCII numeric characters (13 bytes)
* Result at PDecA = X00000000000000000001234567890123C
Figure 280. Packing ASCII characters

If the zoned operand has too few digits to fill all 31 digit positions of the packed operand, the
remaining high-order digits are set to zero, as in Figure 280 where the ASCII operand contains
only 13 digits.
PKU operates in much the same way. Since Unicode means UTF-16 here, the zoned
operand is pairs of bytes. Each numeric digit is extracted from the rightmost four bits and placed
into the packed operand. For example, if the Unicode operand is the two UTF-16 characters 47,
or X 00340037 , the packed decimal result would contain X 00...0047C . Figure 281 shows how
you could pack Unicode characters:
PKU PDecU,UChars
Pack Unicode characters
- - PDecU
DS
PL16
Packed decimal result (16 bytes)
UChars DC
CU1234567890123 Unicode numeric characters (26 bytes)
* Result at PDecU = X00000000000000000001234567890123C
Figure 281. Packing Unicode characters

To avoid the possibility that the zoned operand could be too long, its length is limited:
For PKA, the zoned operand length N may be at most 32 bytes (0 L 31)
For PKU, the zoned operand length N may be at most 64 bytes (0 L 63)
It may seem strange to allow the zoned operand to contain one more character than will fit into
the 31-digit packed operand, but if the maximum length is specified the CPU simply ignores the
leftmost zoned character.

472

Assembler Language Programming for IBM z System Servers

Version 1.00

27.8.2. Unpacking ASCII and Unicode Data


The UNPKA and UNPKU instructions convert packed decimal data to ASCII and Unicode
characters, respectively. Like PKA and PKU, the packed operand is always 16 bytes long; and
unlike them, these unpack instructions set the Condition Code but in a rather strange way, as
well see.
The Assembler Language syntax of these two instructions is
mnemonic D1(N,B1),D2(B2)
where the Length Expression N is part of the first operand.
The length field of UNPKA and UNPKU holds L, the Encoded Length of the first operand, as
shown in Table 196:
opcode

B1

D1

B2

D2

Table 196. Format of U N P K A and U N P K U instructions

As with PKA and PKU, the length of the first operand is limited:
For UNPKA, the zoned operand length N may be at most 32 bytes (so 0 N 32 and
0 L 31).
For UNPKU, the zoned operand length N may be at most 64 bytes (so 0 N 64 and
0 L 63).
Because there is no zoned sign for ASCII and Unicode characters, the sign digit of the packed
operand is used only to set the Condition Code. Instead of the EBCDIC X F zones inserted by
UNPK, the CPU inserts X 3 digits for UNPKA, and inserts X 003 digits for UNPKU.
The unpacking operation proceeds from right to left, and is controlled by the length of the first
operand, so portions of the packed second operand may be ignored. For example:

PDec
AChars
UChars

UNPKA
UNPKU
- - DC
DS
DS

AChars,PDec
UChars,PDec

Convert to ASCII characters


Convert to Unicode characters

PL1698765432
CL12
CL24

31 packed decimal digits


Space for 12 ASCII characters
Space for 12 Unicode characters

Figure 282. Unpacking to ASCII and Unicode characters

In this case, the results at AChars and UChars will be


X30 30 30 30 39 38 37 36 35 34 33 32
and
X0030 0030 0030 0030 0039 0038 0037 0036 0035 0034 0033 0032
where spaces were inserted for readability.
However, if the first operand field is not long enough to contain all significant digits, no indication
is given.

PDec
AChar2
UChar2

UNPKA
UNPKU
- - DC
DS
DS

AChar2,PDec
UChar2,PDec

Convert to ASCII characters


Convert to Unicode characters

PL1698765432
CL7
CL14

31 packed decimal digits


Space for 7 ASCII characters
Space for 14 Unicode characters

In this case, the results at AChar2 and UChar2 will be

Chapter VIII: Zoned and Packed Decimal Data and Operations

473

X38 37 36 35 34 33 32
and
X0038 0037 0036 0035 0034 0033 0032
The Condition Code settings after UNPKA and UNPKU are given in Table 197.
CC
0
1
3

Meaning
Packed operand sign is + (X A, C, E, F )
Packed operand sign is (X B, D )
Packed operand sign is invalid.

Table 197. CC settings after UNPKA, U N P K U instructions

Warning
Every other instruction that tests a numeric result sets the Condition
Code to zero for a zero result. These two instructions set Condition Code
zero for a positive operand. If your program depends on the CC setting
after these instructions, be very careful.

Exercises
27.8.1.(2) Show the generated packed decimal data at APack after you execute this PKA instruction:

AChars
APack

PKA APAck,AChars
- - DC
CA1234567890ABCDEFGHIJKLM
DS
PL16
Packed operand

(See the ASCII encodings in Table 168 on page 432.)


27.8.2.(2) What will be the result at PA of this PKA instruction?

A
PA

PKA PA,A(30)
- - DC
10X ABCDEF
DS
PL16

Zoned operand
Packed operand

27.8.3.(2) What will be the result at PU of this PKU instruction?

U
PU

PKU PU,U(60)
- - DC
20X ABCDEF
DS
PL16

Zoned operand
Packed operand

27.8.4.(2) In Figure 280 on page 472, what will happen if PDec is shorter than 16 bytes?
27.8.5.(2) + How should the Condition Code settings after UNPKA and UNPKU have been
set?
27.8.6.(2) In Figure 282 on page 473, show the representation of the packed decimal operand
at PDec.
27.8.7.(2) + In Figure 282 on page 473, what will be the Condition Code setting after the
UNPKA and UNPKU instructions?

474

Assembler Language Programming for IBM z System Servers

Version 1.00

27.9. Printing Hexadecimal Values


Beside its uses in converting from packed to zoned decimal, the UNPK instruction can also help
convert a string of hexadecimal digits to spread hex, the EBCDIC characters which represent
them. (See Figures 207 and 208 on page 382.) Suppose the 8 hex digits in the 4 bytes in memory
at Data are to be converted to the 8-byte character string at Chars. Now, we cannot immediately
write something like this:

Chars
Data

UNPK Chars(8),Data(4)
- - DS
CL8
DC
X1234ABCD

Spread hex, first (incorrect) attempt


Space for character result
Initial data

Figure 283. Unpacking hex digits (incorrectly)

because Chars would contain


X F0F1F2F3F4FAFBDC
The two digits in the rightmost byte of the second operand (at Data+3) were simply switched and
placed in the byte at Chars+7; the remaining six digits were given zones, and the high-order character contains X F0 . But X FAFBDC does not correctly represent the hex digits ABCD in
character form.
To solve these problems, we supply an extra byte after each operand.

Chars
Data

UNPK
- - DS
DC
DS

Chars(9),Data(5)

Spread hex, second (correct) attempt

CL8,C
X1234ABCD
X

Space for result and 1 extra byte


Data to be unpacked
The extra source byte, X xy

Figure 284. Unpacking hex digits (correctly)

Now, Chars will contain


X F1F2F3F4FAFBFCFD , X yx
where the rightmost (extra) byte contains uninteresting data of some sort, as indicated by X yx .
These two digits are the switched digits from the byte at Data+4, following the right end of the
bytes at Data.
The result shown is not yet in EBCDIC form, because the characters generated for the hex digits
A through F have incorrect zones and numerics. For example, the hex digit A produces X FA
instead of X C1 . To complete the conversion, these bytes can be converted using a TR instruction (described in Section 24.9 on page 380). We dont need a 256-byte translate table because all
the result bytes have X F zones. We need only a 16-byte table, as shown in Figure 285.

Char
Data
TRTab

UNPK
TR
- - DS
DC
DC

Char(9),Data(5)
Char(8),TRTab-X F0

Convert to partial EBCDIC


Translate to true EBCDIC

CL8,CL1
F -5026
C0123456789ABCDEF

Space for result and a junk byte


Data to be spread
Translate table

Figure 285. Converting hex data to printable characters

This technique is used in many situations when diagnostic information is printed in hexadecimal.

Exercises
27.9.1.(2) + In Figure 285, why is the second operand of the TR instruction written
TRTab-X F0 ?

Chapter VIII: Zoned and Packed Decimal Data and Operations

475

27.9.2.(2) + In Figure 285, what will appear in the extra byte at Char+8 after the instructions
are executed?
27.9.3.(3) + Using the technique illustrated in Figure 285 on page 475, convert the 16 hex digits
in the doubleword at DW to a string of 16 EBCDIC characters representing the original value.
27.9.4.(2) Explain the appearance of the quantity X F0 in the leftmost byte of the result
shown following Figure 283 on page 475.
27.9.5.(3) In Figure 285 on page 475, we assumed that the expression TRTab-X F0 in the
second (TR) instruction is addressable. What should be done if it is not?
27.9.6.(5) Suppose you want to print the contents of a byte as eight EBCDIC zero and one
characters representing the bits. (This could be called spread binary.) For example, a byte
containing X 5B would be converted to the eight characters 01011011. The technique used in
Section 28.8 for printing hexadecimal values can be extended, so that instead of a single UNPK
and TR, you can use three UNPK instructions and two TR instructions. Use a translate table
whose last 16 bytes contain
X00010405101114154041444550515455
First, work through an example to show that your method works for all byte values. Then,
write a instruction sequence a to convert the byte at Byte to eight spread binary characters
starting at BinaryCh.
27.9.7.(5) Suppose you want to convert strings of eight EBCDIC ones and zeros to a bit
pattern in a single byte, as represented by the characters. For example, the characters 01011001
would be converted to X 5B . Write a instruction sequence using three PACK and two TR
instructions which will convert the eight characters at BinaryCh to a single byte at Byte. The
translate table needed is 86 bytes long, and not all of it contains necessary data.

27.10. Summary
The move instructions weve discussed in this section are summarized in table 198.
Function
Move

Numeric digits
MVN

Zone digits
MVZ

Table 198. Instructions for moving numeric and zone digits

The packing and unpacking instructions weve discussed in this section are summarized in Table
199.
Function
Pack
Unpack

Zoned EBCDIC
PACK
UNPK

Zoned ASCII
PKA
UNPKA

Table 199. Instructions for packing and unpacking data

476

Assembler Language Programming for IBM z System Servers

Version 1.00

Zoned Unicode
PKU
UNPKU

28. Packed Decimal Arithmetic

2222222222
222222222222
22
22
22
22
22
22
22
22
22
222222222222
222222222222

8888888888
888888888888
88
88
88
88
88
88
88888888
88888888
88
88
88
88
88
88
888888888888
8888888888

In this section we will examine the methods used by the CPU to perform packed decimal arithmetic.
Because we are all familiar with decimal arithmetic, it may seem strange to investigate the way it
is done by the CPU. While the broader features of decimal arithmetic are simple, its implementation on a binary machine leads to some unexpected subtleties.
In this and the following sections, we will use a simple notation for numbers in the packed
decimal representation. Instead of 123 we will write 123 , because this form is closer to the
internal decimal representation of 123, namely X 123D . Thus, if a number is written with a
trailing sign, its representation in memory can be visualized by substituting the hex digits C and D
for the + and signs, respectively.
For convenience, we will refer to the packed decimal representation simply as decimal whenever
packed decimal is clearly meant.
Writing zoned and packed decimal values
Because the sign of zoned and packed decimal numbers is always in the
rightmost byte, it is convenient write such values with the sign on the
right, as in 12345+ or 09990 .

28.1. General Rules


Before examining decimal arithmetic, we will state some general rules applying to decimal operations and operands.
1. The result of a decimal arithmetic operation (other than comparison) always replaces the first
operand, so it has the same length as the first operand. Neither the second operand in
memory (assuming no overlap) nor the contents of the General Registers are modified.
2. For z System processors, the preferred EBCDIC signs (X C and X D ) are always attached
to results.171

171

In System/360, the USASCII sign digits (X A and X B ) were used if the A bit in the PSW was 1.
Chapter VIII: Zoned and Packed Decimal Data and Operations

477

3. Because decimal operands have finite length, results might overflow the allotted space: a
decimal overflow exception will occur, and the Condition Code is set to 3.
By setting a bit in the Program Mask (described in Section 16.2.1 on page 235), you can
direct the CPU to ignore the exception condition for a decimal overflow. If the interruption
does occur, the Interruption Code is set to 10 (X 000A ).
4. Because each decimal digit is represented by four bits, the CPU must guard against the possibility that a decimal digit position might contain one of the six invalid bit configurations.
Similarly, a numeric digit may not occur as the lowest order hex digit (the sign digit) of an
operand. If either error condition is detected, a Data Exception interruption occurs, and the
Interruption Code is set to 7.
This interruption might seem to be an unnecessary nuisance, but it is actually very helpful.
Almost all other arithmetic operations dont (or cant) check for invalid operands, and can
generate meaningless results from invalid data. Because packed decimal operands are validated, your program is more likely to produce valid results, and can take corrective action
when its needed.

28.1.1. Precision and Accuracy


Packed decimal values are precise, because all values are integers. Their accuracy depends on the
validity of the data used for each operation, and the care taken to preserve the inherent accuracy
of the data. Inadequate precision can degrade accuracy, so be sure to specify enough digits so
that significant digits wont be lost.

Exercises
28.1.1.(1) If you execute these instructions, would you say that the result at PWord is a valid
packed decimal number?

PWord

XR
1,1
AHI 1,12
ST
1,PWord
- - DS
F

Set GR1 to zero


Add 12
Store the result

28.2. Decimal Addition and Subtraction


Because the CPU works from right to left in adding or subtracting decimal operands, excess digits
are lost at the left, or high order, end of the operand.
The rules for adding and subtracting numbers in the packed decimal representation are the usual
and familiar rules of arithmetic. There are three minor matters to be considered:
1. If the second operand is shorter than the first, then during its internal arithmetic the CPU
will extend the second operand with enough high-order zeros so that its length matches that
of the first operand. These extra zero digits are generated internally during the operation; the
second operand in memory is never modified.
2. A decimal overflow condition occurs after an addition or subtraction if the first operand field
is too short to hold all significant digits of the result. This can be due to one of two causes:
If one operand is longer than the other, high-order zeros are supplied internally to extend
the shorter operand. For example, 3+ added to 999+ becomes 003+ + 999+, and the sum
1002+ overflows either operand used to hold the sum.
If the resulting sum or difference causes a nonzero digit or a carry to be lost because the
first operand field is too short, an overflow has occurred. For example, 6+ added to 7+
yields 13+ which overflows either operand used to hold the sum.

478

Assembler Language Programming for IBM z System Servers

Version 1.00

3. The CPU always attaches a + sign to a valid non-overflowed zero result of addition or subtraction.
The resulting sign might be in case of overflow! If the rightmost portion of an overflowed result has a negative sign and enough low-order zero digits to fill the first operand
field, the CPU will generate a negative zero result. For example, adding two one-byte
operands such as (5 ) + (5 ) will yield 0 , and a decimal overflow exception is indicated.
The Condition Code is set to reflect the status of the result, as shown in Table 200.
CC
0
1
2
3

Indication
Result is zero
Result is less than 0
Result is greater than 0
Decimal overflow

Table 200. CC settings for decimal addition and subtraction

To illustrate these rules, suppose we add the following two operands:


00006+
+ 23497+

(1st operand)
(2nd operand)

The result, 23503+, replaces the first operand. If the two operands were
+

23497+
6+

(1st operand)
(2nd operand)

and the result would be the same. But if the two operands had been defined as
006+
+ 23497+

(1st operand)
(2nd operand)

then the result at the first operand location would be 503+, and an overflow exception would indicate the loss of significant digits due to truncation. Unlike adding binary integers in the general
registers, decimal addition or subtraction overflow can depend on the order of the operands.
Be Careful!
The results of packed decimal addition may depend on the order of the
operands.
Addition of two operands of unlike sign follows the same rules. For example, suppose we add
04006+ and 01005 , the result would be 03001+ as expected. (We will see shortly that this result,
while expected, is not as easy to obtain). Suppose now that we wish to add these quantities:
006+
+ 01005-

(1st operand)
(2nd operand)

The result, 999 , replaces the first operand. Even though there are nonzero digits in the second
operand corresponding to the internal extension digit positions in the first operand, no overflow
occurs because the result has become short enough to fit into the first operand field.
The rule for subtraction of decimal operands is simple: invert the sign of the second operand, and
then add. The change of sign is done internally by the CPU during the subtraction; the second
operand is never modified in memory.172 Thus, the subtraction operation
04006+
- 01005+
05011+

(1st operand)
(2nd operand, subtracted)

is internally identical to the addition operation

172

If the operands overlap, either could be modified.


Chapter VIII: Zoned and Packed Decimal Data and Operations

479

04006+
+ 0100505011+

(1st operand)
(2nd operand, negated and added)

As noted in Section 16.2.1, we can use the SPM instruction to mask off a decimal overflow interruption. The result will be the same whether or not an interruption occurs, and the CC will be set
to 3.

Exercises
28.2.1.(1) + In Section 2.10, we saw that no overflow was possible in adding fixed-point binary
operands if their signs differed. Why is it possible to cause a decimal overflow exception when
adding decimal operands of unlike sign?
28.2.2.(2) + For each of the following pairs of numbers, the first operand is given first. Determine (1) the resulting sum or difference, (2) the resulting CC setting, and (3) whether or not an
overflow condition will occur.
(a) (2147483647 + ) + (2147483648 + )
(b) (99999 + ) + (00002 + )
(c) (99999 ) + (00002 + )
(d) (7 ) (97 + )
(e) (45 + ) (66 )
(f) (4 ) (4 )
(g) (745 ) + (255 )
(h) (2 + ) (99999 + )
28.2.3.(3) + Each of the following pairs of numbers is taken from the same operand in memory;
that is, the low-order bytes of both operands coincide. Determine in each case (1) the resulting
sum or difference, (2) the CC setting, and (3) whether or not an overflow condition will occur.
(a) (12345 + ) + (345 + )
(b) (345 + ) (12345 + )
(c) (000 ) + (0 )
(d) (729 + ) + (729 + )
(e) (476692543 ) (6692543 )
(f) (12345 + ) (12345 + )

28.3. Decimal Comparison


Comparing two decimal operands is simply an internal subtraction; the setting of the Condition
Code indicates the result, as shown in Table 201. As in addition and subtraction, all digits and
signs are checked for validity.
CC
0
1
2

Meaning
Operand 1 = Operand 2
Operand 1 < Operand 2
Operand 1 > Operand 2

Table 201. CC setting after decimal comparison

The sign of a zero operand doesnt matter: 0 is considered equal to 0 + .


Comparison is actually somewhat simpler than subtraction, because all arithmetic is internal. As
many high-order zeros are supplied for the operands as necessary, and no overflow condition is
recognized. Thus, comparing 99999+ and 2 leads to an internal subtraction
-

480

99999+
2-

(1st operand)
(2nd operand)

Assembler Language Programming for IBM z System Servers

Version 1.00

which becomes, after adding extra digit positions and making the necessary sign changes, an addition operation:
0099999+
+ 0000002+

(1st operand)
(2nd operand)

Because the internal result is positive, the CC will be set to 2 to indicate that operand 1 is greater
than operand 2. This result would not have been obtained by directly subtracting the two operands (see Exercise 28.3.1).

Exercises
28.3.1.(1) Give two reasons why the result of comparing 99999+ and 2- would not have been
obtained by performing a subtraction instead (aside from the fact that one operand would be
modified).
28.3.2.(1) Suppose you compare these two packed decimal operands using a CLC instruction:

PDP
PDM

CLC PDP,PDM
- - DC
P+0
DC
P -0

Compare operands

What will be the resulting CC setting?


28.3.3.(2) + Suppose the operations of addition and subtraction in Exercise 28.2.2 are replaced
by comparison operations. Determine the CC setting in each case.
28.3.4.(2) + Suppose the data in Exercise 28.2.3 is used in a comparison operation. Determine
the CC setting in each case.
28.3.5.(2) + By considering possible operand lengths and addresses for decimal addition, subtraction, and comparison, give a rigorous rule for the conditions under which the two operands
may safely overlap.

28.4. Decimal Multiplication


The rules for multiplication of decimal operands obey the usual rules of algebra concerning signs.
The product of the first operand (the multiplicand) and the second operand (the multiplier)
replaces the first operand, which must be long enough to contain the digits of the result.
Remember that the product of a number N1 digits long and another number N2 digits long is at
most N1 + N2 digits long.
The following rules apply to decimal multiplication:
1. All digits and signs are verified; any invalid digits will cause a data interruption, and the Interruption Code will be set to 7.
2. To ensure that the product will fit into the first operand field without overflow, there must be
as many leading zero bytes in the first operand as the number of bytes in the second operand.
Violating this requirement causes a data exception.
The length of the first (multiplicand) operand must be greater than the length of the
second (multiplier) operand.
3. The z System architecture imposes an additional condition: the length of the second operand
must not exceed 8 bytes. If this or the previous condition is not met, a specification exception
will occur, and the IC will be set to 6.
Rules 2 and 3 avoid a potential multiplication overflow that could corrupt the product (multiplicand) field if the overflow was detected late in the multiplication process. We can usually
choose the order of the two operands so that the rules are satisfied, because multiplication is
commutative (independent of operand order).
Chapter VIII: Zoned and Packed Decimal Data and Operations

481

4. The sign of the result is determined from the rules of algebra, even if one or both operands is
zero. Thus, (2 + )(0 ) will generate a minus zero.
Because the CPU takes great care to check the validity of both operands, no multiplication overflow can occur. This saves time and avoids data damage, because the multiplication need not be
partially executed only to discover that the result is invalid. As with other z System multiply
instructions, the CC setting is unaffected.
To illustrate a decimal multiplication, suppose we wish to multiply 126+ and 213+ (the operands we used in describing binary multiplication in Section 18.4):

0000213+
126+
0026838+

(operand 1) (multiplicand, with 2 high-order zero bytes)


(operand 2) (multiplier)
(product)

In this example, the operand lengths were chosen to have the minimum number of bytes needed
to contain the given quantities, and still satisfy the above rules. However, the product still contains an excess high-order byte of zeros; this is a typical result in decimal multiplication. Multiplying 005+ and 5+ generates the result 025+, and shows that at least one leading zero digit is
always found in the product. (See Exercise 28.4.2.)
Be Careful!
The results of packed decimal multiplication may depend on the order of
the operands.

Exercises
28.4.1.(2) In decimal multiplication rule 2 on page 481, why require the number of leading zero
bytes in the first operand to be at least as many bytes as in the second operand?
28.4.2.(3) Show that the requirement that the number of leading zero bytes in a decimal multiplicand be no less than the number of bytes in the multiplier leads to at least one leading zero
digit in the product.
28.4.3.(1) Give a reason why the z System architecture requires the second operand of a
decimal multiplication to be no more than 8 bytes long.
28.4.4.(1) What is the largest packed decimal number that can be generated by a single multiplication?
28.4.5.(3) + Determine the products of each of the following pairs of decimal numbers,
assuming that the first number is the multiplier. Then do the same, assuming that the second
number is the multiplier. Add enough leading zeros to each multiplicand so that the product
will be valid.
(a)
(b)
(c)
(d)
(e)
(f)

(9+) (9 )
(72 ) ( 7 + )
(44+) (44+)
(15 ) (55+)
(107+) (107+)
(28+) (3 )

28.4.6.(2) + What result will be generated if you multiply (007 + ) and (009 )?

482

Assembler Language Programming for IBM z System Servers

Version 1.00

28.5. Decimal Division


Dividing two decimal numbers is more complicated than multiplying, since the result field must
contain both the quotient and the remainder. The dividend (the first operand) is divided by the
divisor (the second operand); the quotient and remainder then replace the dividend.
The method used is essentially the same as our familiar process of long division: the divisor is
subtracted from the leftmost portion of the dividend, and the number of successful subtractions
becomes the first quotient digit. The divisor is then shifted one digit position to the right, and the
subtractions continue. This process ends when the rightmost digit of the divisor is aligned with
the rightmost digit of the dividend, and no further subtractions can be performed. It is therefore
natural that the remainder appears at the right end of the dividend (first operand) field, and the
remainder has the same length as the divisor. The quotient is placed in the leftmost portion of
the dividend field.173
Suppose 027+ (the dividend) is divided by 4+ (the divisor); the result that replaces the first
operand is 6 + 3 + . That is, the quotient is 6 + and the remainder is 3 + . Note that both operands
are signed; this means that there must be enough space in the first operand field for the quotient
and remainder digits, and two sign digits.
Now, suppose 00787 is divided by 094 + . We see that the result will be 8 035 ; the quotient is
8 and the remainder is 035 . If we invert the signs of the dividend and the divisor and divide
00787 + by 094 , the result is 8 035 + .
The rules for decimal division may be summarized as follows:
1. The sign of the quotient is determined from the usual rules of algebra, and the remainder sign
always agrees with the dividend sign. (These rules apply even when the quotient or remainder
is zero.)
2. The operands in a successful division always satisfy the relation
dividend = (quotient divisor) + remainder,
and the magnitude of the remainder is less than the magnitude of the divisor.
3. The length of the divisor is the length of the remainder, which is found at the right end of the
first operand field.
4. The length of the divisor must be less than the length of the dividend so that there will be
enough room for both quotient and remainder. Also, the z System architecture requires that
the length of the divisor be 8 bytes or less. If either of these conditions is not met, a specification exception occurs.
5. If the divisor is zero, or if the quotient is too large to fit into the available space, the operation is suppressed: the dividend in memory remains unchanged, and a decimal divide interruption always occurs. The Interruption Code is set to 11.
6. Decimal overflow cannot occur, and the CC remains unchanged.
Here is a simple test to determine whether a divide exception will occur: align the divisor and
dividend so that the leftmost divisor digit is under the next-to-leftmost dividend digit. If the
newly-positioned divisor is now less than or equal to the dividend, the division is improper and a
decimal divide interruption will occur. For example, in dividing 00787+ by 094+, if we align the
two operands as shown,
00787+
094+

(dividend)
(divisor)

we see by comparing leading digits that 09 is greater than 007, so the division is proper. Conversely, if we divide 123456789+ by 987+, the alignment

173

This is different from the process described for binary division in Section 18.8, where we visualized the process as
shifting the dividend across the divisor; here, the divisor is shifted under the dividend.
Chapter VIII: Zoned and Packed Decimal Data and Operations

483

123456789+
987+

(dividend)
(divisor)

shows that the division is improper, since 9 is less than 12. Thus, the dividend must contain at
least one leading zero digit.
The next two topics will concern some fairly technical aspects of packed decimal addition and
subtraction on a binary processor. You may safely skip them if you are satisfied that the
processor gets its results somehow, but the methods dont interest you.

Exercises
28.5.1.(2) + Give examples which show how to generate a negative zero (1) as a sum, (2) as a
product, (3) as a quotient, and (4) as a remainder.
28.5.2.(3) Determine the quotient and remainder for each of the following dividend-divisor
pairs, and state any error conditions that might arise.
(a)
(b)
(c)
(d)
(e)

(0009999+) (088+)
(09999+) (099+)
(0271828182845+) (4 )
(0192519200513+) (370+)
(012345678+) (321 )

28.5.3.(2) + Explain why the result of dividing 00787 by 094+ cannot be 08 35 , rather than
8 035 .

28.6. True Decimal Addition (*)


The term true addition means the addition of two operands of like sign; we will discuss complement addition, the addition of two operands of unlike sign, in Section 28.7. True addition is
simpler because the sign of the result is known in advance.
We will omit sign digits in the following examples, and assume that the sign digit of the first
operand is left in memory as the sign of the final result.
Suppose we add two decimal digits using the four-bit binary representation for each decimal digit.
A sum such as
2
+ 5
7

0010
+ 0101
0111

gives the desired result both in decimal and in hexadecimal. However, if we add two digits whose
sum exceeds 9, the decimal sum is correct, but the binary sum B 1100 = X C is not a valid
packed decimal digit:
5
+ 7
12

0101
+ 0111
1100

Because we are using four bits to represent a decimal digit, the six bit combinations X A -X F
must remain unused. A simple solution to this difficulty is to add 6 to the binary sum whenever
it exceeds 9. In the above example, this correction process would be done as follows:
0101
+ 0111
1100
+ 0110
1 0010

484

hex
hex
hex
hex
hex

5
7
C
6
12

= 12 decimal, > 9
Correction

Assembler Language Programming for IBM z System Servers

Version 1.00

The two BCD digits in the result X 12 are the correct packed decimal representation of the sum,
12.
There is an obvious problem: how do we know when to add 6? In the first example, it would have
been wrong to add 6, because the sum of 2 and 5 did not exceed 9. Furthermore, it will be difficult for the CPU to compare each sum digit to 9 (to see if a correction is needed), since a comparison implies a subtraction. Instead of correcting after adding, we do the following:
1. Add the digits of the two operands, and a corrector digit 6, at each digit position.
2. Note which digit positions generate a carry; the carry should be propagated.
3. In the digit positions from which no carry occurred, correct the sum by subtracting 6 (that is,
by adding 10=B 1010 , the twos complement of 6=B 0110 ) without propagating carries.
Here are some examples of this method. Let us add 2 and 5 again, including an extra high-order
digit.
02
05
+ 66
6D
+ AA
07

0000
0000
+ 0110
0110
+ 1010
0000

0010
0101
0110
1101
1010
0111

first operand
second operand
corrector digits
intermediate sum, no carries occurred
re-correction, add without carrying
final sum

In this example, there were no carries out of either digit position in forming the intermediate sum,
so that 6 had to be subtracted from both digit positions to arrive at the final sum.
Adding 95 and 87 (=182) would be done as follows:
095
087
+ 666
782

0000 1001 0101


0000 1000 0111
+ 0110 0110 0110
0111 1000 0010
c
c

first operand
second operand
add corrector digits
intermediate sum, two carries

At this point, carries have occurred out of both of the low-order hex digit positions but not from
the high-order digit; the final correction therefore involves a subtraction in only the leftmost digit:
782
+ A00
182

0111 1000 0010


+ 1010 0000 0000
0001 1000 0010

intermediate sum
add complement of 6
final sum

Remember that carries are not propagated during the final re-correction step; otherwise, the sum
would have been 1182 instead of 182.

Exercises
28.6.1.(3) Show by appropriate examples that true decimal addition can be performed as
follows:
1. Perform a true binary addition, propagating carries.
2. In those digit positions from which no carry occurred, add 6, propagating carries.
3. In those digit positions from which no carry occurred in the second addition, subtract 6.
28.6.2.(2) Using the rules for true decimal addition given in this Section, perform the following
sums, showing all the intermediate steps:
(a) (007) +
(b) (007) +
(c) (00987)
(d) (00885)

(007)
(009)
+ (00789)
+ (00595)

Chapter VIII: Zoned and Packed Decimal Data and Operations

485

Signs were omitted because true addition involves like signs.

28.7. Complement Decimal Addition (*)


Complement addition of two decimal operands is more complicated than true addition, since the
result may be of either sign. We will review the rules for complement addition first, and then give
some examples.
1. The sign of the first operand is saved as the tentative sign of the result. The shorter operand
is extended internally with high-order zeros to the length of the longer operand.
2. The numeric digit portion of the second operand (that is, everything but the sign digit) is
complemented: this is the usual twos complement, obtained by inverting each bit, and
adding a 1-bit in the low-order position.
3. The two operands are added. Carries are propagated from each 4-bit digit to the next, and
whether or not a carry occurred is noted for each digit position.
4. To correct the result of the addition in step 3, subtract 6 (that is, add 10=B 1010 , the twos
complement of 6=B 1010 ) in each digit position where no carry occurred in step 3. Carries
out of a 4-bit group are not propagated to the next digit position during this decimal correction process.
5. If there was a carry out of the high-order digit position in step 3, the result is now complete.
(We say that the result is in true form.)
6. If there was no carry out of the high-order digit position in step 3, the result is said to be in
complement form. To obtain a correct result, invert the sign of the first operand (it was saved
at step 1).
7. Form the twos complement of the result by inverting each bit and adding a 1-bit in the loworder digit position. In propagating the carries from this added 1-bit, note which 4-bit groups
produce a carry and which do not.
8. This result is decimally corrected by subtracting 6 (adding binary 1010) to those digit positions from which no carry occurred during step 7. Carries generated in this correction process
are not propagated.
We will now look at some examples of complement addition in which the result after step 5 is in
true form; cases requiring recomplementation will be examined shortly. First, suppose we add 5 +
and 2 . After saving the plus sign for the result, we proceed as follows:
5
+ E
c 3

0101
+ 1110
c 0011

first operand
2 s complement of second operand
sum, with carry indicated by c

Since a carry occurred out of each digit position, no decimal correction is required; and since a
carry occurred out of the high-order digit position, the result is in true form. Thus the final result
is 3+, as expected.
To give an example in which a decimal correction (but no recomplementation) is needed, suppose
we add 043 + and 019 . Saving the + sign for the result, we first form the twos complement of
the second operand:
+

1111 1110 0110


1
1111 1110 0111

invert all bits of second operand (019)


add 1 in low-order position
two s complement of second operand

Now, we add this to the first operand:


043
+ FE7
02A

486

0000 0100 0011


+ 1111 1110 0111
0000 0010 1010
c
c

first operand
2 s complement of second operand
uncorrected sum, high-order carry
carries

Assembler Language Programming for IBM z System Servers

Version 1.00

Since no carry occurred out of the rightmost hex digit position, we must decimally correct by
subtracting 6 (adding binary 1010), without carrying:
02A
+ 00A
024

0000 0010 1010


+ 0000 0000 1010
0000 0010 0100

uncorrected sum
add correction, no propagation
final true sum

The final sum is 024 + , as expected.


To illustrate complement decimal additions in which a final recomplementation is required, we
use the same two examples, but reverse the order of the operands. Thus, suppose we start by
adding 2 and 5 + . The tentative sign of the result is , the sign of the first operand. We then
proceed as before:
2
0010
+ B + 1011
D
1101

first operand
2 s complement of second operand
uncorrected sum, no carry

Because no carry occurred out of any digit position, we must add a decimal correction:
D
1101
+ A + 1010
7
0111

uncorrected sum
decimal correction
sum, in complement form

The carry generated during the correction process is ignored. The result is known to be in complement form because there was no carry from the high-order (and only) digit position during the
first addition. Thus, we invert the minus sign being saved for the result, and set it to a plus sign.
To perform the final recomplementation, we first form the twos complement of the above result:
+

1000
1
1001

invert each bit of result


add 1 in low-order position
uncorrected 2 s complement of result

Now, to obtain the final result, we observe that there was no carry out of the digit during the
complementation process; we therefore add 6 to obtain the final sum:
9
1001
+ A + 1010
3
0011

uncorrected recomplemented result


decimal correction
final corrected result

As noted, the carry generated during the final decimal correction is ignored, so the result is 3 + , as
expected.
As our final example, we add 019 and 043 + . After saving the minus sign for the result, we take
the twos complement of the second operand:
+

1111 1011 1100


1
1111 1011 1101

invert all bits


add a low-order 1-bit
2 s complement of second operand

Now, we can do the first addition:


019
+ FBD
FD6

0000 0001 1001


+ 1111 1011 1101
1111 1101 0110

first operand
2 s complement of second operand
initial sum

Since there was no carry from the high-order digit position, we know the result is in complement
form, and we invert the sign of the result to a plus sign. A carry occurred only out of the rightmost digit position, so we must add a decimal correction to the two leftmost digit positions:
FD6
+ AA0
976

1111 1101 0110


+ 1010 1010 0000
1001 0111 0110

uncorrected initial sum


decimal correction digits
sum in complement form

This is the result in complement form. To obtain the final result, we take the twos complement,
and correct it by adding 6 in any position where no carry occurred during complementation:

Chapter VIII: Zoned and Packed Decimal Data and Operations

487

0110 1000 1001


1
0110 1000 1010
+ 1010 1010 1010
0000 0010 0100

+
68A
+ AAA
024

bit-wise complement of 976


add low order 1-bit
complemented uncorrected result: no carries
decimal correction digits
final result

As expected, the final result is 024 + .

Exercises
28.7.1.(2) The three signs in an add or subtract operation are (1) the operation (+) or ( ),
(2) the first operand sign, and (3) the second operand sign. Make a table of the eight possible
combinations of signs and verify that an even number of minus signs indicates a true addition,
and an odd number of minus signs indicates a complement addition.
28.7.2.(5) Decimal numbers are sometimes represented in binary machines in the excess-3
representation, whereby each decimal digit is represented by a hex digit whose value is larger by
3. For example, the number 280+ would be represented by 5B3+. Give rules like those in
Sections 28.6 and 28.7 for true and complement addition in the excess-3 representation.
28.7.3.(3) Using the rules for complement decimal addition given above, perform each of the
following operations.
(a) (004 + ) + (004 )
(b) (004 ) + (004 + )
(c) (0391 ) + (1715 + )
(d) (4837 + ) (5537 + )
28.7.4.(2) Assuming that recomplementation takes extra time, how could a list of decimal
numbers of mixed signs be ordered to reduce the number of recomplementations and the time
needed to compute their sum?
28.7.5.(3) In decimal complement addition, a result in complement form must be recomplemented and decimally corrected. During recomplementation, carries may or may not occur out
of a 4-bit group. Show that in the low-order positions, a carry may occur only out of zero
digits.
28.7.6.(2) Give examples of the possible combinations of digits to show that the addition
scheme described above gives a correct decimal sum.
28.7.7.(3) Show by appropriate examples that the final correction of the sum (by subtracting 6
in certain digit positions) cannot cause a borrow from the next high-order digit.
28.7.8.(3) Examine the rules for true and complement decimal addition, and determine a general
rule for the conditions under which carries are and are not propagated during the various intermediate addition steps.
28.7.9.(3) Determine the maximum number of additions required to add two one-byte decimal
operands of any sign.

488

Assembler Language Programming for IBM z System Servers

Version 1.00

29. Packed Decimal Instructions

2222222222
222222222222
22
22
22
22
22
22
22
22
22
222222222222
222222222222

9999999999
999999999999
99
99
99
99
99
99
999999999999
999999999999
99
99
99
99
999999999999
9999999999

Table 202 lists the decimal arithmetic instructions in this section. MVO has rather specialized
uses, and is not used often since SRP was introduced. Except for TP, each instruction has the
format of a two-length SS-type instruction, as shown in Table 193 on page 463.
Op
FA
FC
F9
F0

Mnem
AP
MP
CP
SRP

Type
SS
SS
SS
SS

EBC0

TP

RSL

Instruction
Add Decimal
Multiply Decimal
Compare Decimal
Shift and Round
Decimal
Test Decimal

Op
FB
FD
F8
F1

Mnem
SP
DP
ZAP
MVO

Type
SS
SS
SS
SS

Instruction
Subtract Decimal
Divide Decimal
Zero and Add Decimal
Move with Offset

Table 202. Packed decimal arithmetic instructions

The previous section sketched how the CPU does packed decimal addition, subtraction, multiplication, division, and comparison. Now, well examine the corresponding instructions.
All decimal operations process their operands from right to left. The operands should not
overlap, or (in some cases) their rightmost bytes should coincide. If the operands overlap in any
way, the CPU will store the result byte from one step of an operation before fetching the operand
bytes to be used in the next step.
Note!
All packed decimal arithmetic is integer arithmetic. Section 29.10 shows
how you can do packed decimal arithmetic with mixed integer-fraction
data (like 123.4564.07).

Chapter VIII: Zoned and Packed Decimal Data and Operations

489

29.1. TP Instruction
The TP instruction checks its packed decimal operand for validity. The Assembler Language
syntax of a TP instruction is shown in Figure 286:
TP

D1(N,B1)

Figure 286. Syntax of the TP instruction

where the Length Expression N is the length of the packed decimal operand. The format of the
assembled machine instruction is illustrated in Table 203:
EB

B1

D1

C0

Table 203. Format of the TP instruction

You will remember from Sections 24.2 and 27.5 that the Encoded Length L is one less than the
Length Expression N. The valid forms of the Assembler Language statement operand are shown
in Table 204:

Explicit Address
Implied Address

Explicit Length
D 1(N,B 1)
S(N)

Implied Length
D 1(,B1)
S

Table 204. Operand formats for TP instruction

TP sets the Condition Code as shown in Table 205.


CC
0
1
2
3

Meaning
All digit codes and the sign code are valid.
The sign code is invalid.
At least one digit is invalid.
The sign code and at least one digit are invalid.

Table 205. CC settings for the TP instruction

Some of the examples and exercises in previous sections showed other ways to test the validity of
a packed decimal operand. The TP instruction is generally much simpler; its only shortcoming is
that it doesnt indicate which digit(s) or byte(s) may be invalid.
For example, we can test several operands:

T0
T1
T2
T3

TP
T0
TP
T1
TP
T2
TP
T3
- - DC
X123456789D
DC
X1234567890
DC
X12345C789C
DC
X12345C7890

Test
Test
Test
Test

operand
operand
operand
operand

T0;
T1;
T2;
T3;

CC=0
CC=1
CC=2
CC=3

Valid operand
Invalid sign code
Invalid digit
Invalid sign and digit

Exercises
29.1.1.(2) + For each of these operands, what will be the CC setting after testing it with a TP
instruction?

490

Assembler Language Programming for IBM z System Servers

Version 1.00

(a)
(b)
(c)
(d)
(e)
(f)

Z330
P -1945
X567890
H255
P31415926535897914142135326607977277059
C abcd?

29.1.2.(2) Is there a way to use TP to detect the first of several possible invalid digit codes in a
packed decimal operand?
29.1.3.(2) Suppose you know that a packed decimal operand has an invalid digit in the byte at
BadByte. Write a short instruction sequence to test whether the left or right digit was bad, and
branch to BadLeft or BadRight accordingly.

29.2. ZAP Instruction


The ZAP instruction 174 moves decimal data from the second operand to the first operand field.
Its Assembler Language and machine instruction formats are the same as for PACK and UNPK,
described in Section 27.
As the name implies, ZAP can be considered as equivalent to (1) setting the first operand field to
0+, and (2) adding the second operand to the newly-zeroed first operand. 175 That is, only the
second operand must be a valid packed decimal number.176 The first operand field may actually
contain anything, and is not checked for validity.
If the second (source) operand is exhausted before the first operand field has been filled, the
CPU supplies extra high-order zeros until the first operand is complete.
If significant (nonzero) high-order digits are lost because the first operand field is too short, a
decimal overflow exception is recognized.
If you use ZAP to initialize a field, sign codes of the second operand are converted in the first
operand to the preferred signs, X C and X D .
The sign of a zero result is + , unless there is an overflow; in that case, the zero result has the
sign of the second operand.
ZAP isnt fussy about operand overlap, so long as the rightmost byte of the first (target) operand
is not at a lower address than the rightmost byte of the second (source) operand.
ZAP sets the Condition Code as shown in Table 206.
CC
0
1
2
3

Indication
Result is zero.
Result is less than zero.
Result is greater than zero.
Decimal overflow.

Table 206. CC settings by the ZAP, AP, and SP instructions

174

175

176

The Principles of Operation calls it just Zero and Add, rather than Zero and Add Decimal. The P in the
mnemonic helps to classify ZAP with other packed decimal instructions.
The name Zero and Add is slightly confusing, because the instruction does not actually zero the first operand and
then add the second to it. Initially subtracting the first operand from itself might fail if its not a valid packed decimal
number!
Anything else will cause a data exception interruption.
Chapter VIII: Zoned and Packed Decimal Data and Operations

491

Remember that a potential interruption for a decimal overflow condition can be masked off using
the SPM instruction described in Section 16.9 on page 235.
The following statements show the effect of executing several ZAP instructions, where we use
literals for the second (source) operands.

ZAP X,=PL1 1
ZAP X,=P -9
ZAP X,=P1234
ZAP X,=P0234
ZAP X,=P 0
ZAP X,=X1234
ZAP X,=X ABCD
- - DS
PL2

2nd Operand
X 1C
X 9D
X01234C
X00234C
X 0C
X1234
X ABCD

Result
c(X) = 001+, CC = 2
c(X) = 009-, CC = 1
c(X) = 234+, CC = 3 (overflow!)
c(X) = 234+, CC = 2
c(X) = 000+, CC = 0
Data Exception (invalid sign, 4 )
Data Exception (invalid digit, C )
First operand, two bytes long

Figure 287. Examples of the ZAP instruction

The third ZAP instruction illustrates a decimal overflow due to the loss of significant highorder digits. The digits lost in the fourth statement are both zero, so no overflow occurs.
The sixth ZAP instruction fails because the final digit 4 is not a valid sign, one of A-F.
The last ZAP instruction fails because the first three digits are not numeric, one of 0-9;
because data is accessed from right to left, the invalid digit X C in the first byte (X CD ) causes
the decimal data exception.
If the first and second operand fields have the same length, it may be simpler to use an MVC
instruction, assuming the second operand is valid.
To give some examples of the use of ZAP, suppose we must initialize a table of 50 three-byte
packed decimal numbers starting at Dec. Each number in the table is three bytes long, and we
must set them to zero. Well use the Branch on Count (BCT) instruction (described in Section
22.4 on page 335) to control the loop:
NDec

Loop

Dec

Equ 50
LA
1,NDec
LA
2,Dec
ZAP 0(3,2),=P 0
AHI 2,L Dec
BCT 1,Loop
- - DS
(NDec)PL3

Number of elements
Initialize loop counter
Point to first element
Zero a 3-byte element
Step pointer to next element
Perform ZAP NDec times in all
Table of 3-byte elements

Figure 288. Using ZAP to initialize a table of packed decimal operands

where the ZAP instruction first operand has D1=0, N=3 (so L=2), and B 1= 2 .
In this example, every number in the table has the same length and the entire table is only 150
bytes long, so we could also use an MVC instruction instead of executing a loop:
NDec

Dec

Equ 50
Number of table elements
ZAP Dec,=P 0
Initialize the first element
MVC Dec+L Dec((NDec-1)*L Dec),Dec
Propagate the zero
- - DS
(NDec)PL3

Figure 289. Initializing a table of decimal numbers using MVC

where the ZAP instruction uses an implied length, the length attribute of Dec. If the length of the
elements starting at Dec changes, we wont need to update the MVC instruction. Note also that
N=(NDec 1)*L Dec is the number of bytes at Dec after the first element.

492

Assembler Language Programming for IBM z System Servers

Version 1.00

This technique may be limited by the size of the table, and cant be used if the elements have
different lengths.
ZAP is often used to move a shorter operand into a longer field; for example, ZAP is typically
used to set up the first operand (the multiplicand) for decimal multiplications.

Exercises
29.2.1.(1) + In Figure 287 on page 492, show the contents of the second byte of each ZAP
instruction.
29.2.2.(1) + Under what circumstances would it be useful to execute this instruction statement?
ZAP

A,A

29.2.3.(2) + Suppose X is the name of a packed decimal operand two bytes long. Determine the
effect of executing the instruction
ZAP

X,Y

if Y is the name of each of the following DC operands:


(1)
(2)
(3)
(4)
(5)
(6)

PL5 -123
CL2 *
H13
P0000753
X F00000123C
X000123

29.2.4.(2) Write one or more instructions to invert the sign of the packed decimal value at
PackVal.
29.2.5.(1) As suggested following Figure 287 on page 492, you could use MVC instead of ZAP
to initialize a packed decimal operand. Can you think of any reasons to avoid this technique?
29.2.6.(2) In Figure 289 on page 492, what is the maximum value of NDec for which the
program segment will work correctly?
29.2.7.(2) + Write instructions to replace the packed decimal number at SomeVal by its absolute
value (that is, force the sign to be + ), ensuring that the sign is the preferred sign, X C .
29.2.8.(3) + Draw a detailed flowchart that describes the digit-by-digit action of ZAP. Take care
to check the validity of sign and digits, set the CC and final sign, detect length incompatibilities,
possible overflows, and operand overlap. (You will appreciate the complexities of implementing
the instruction!)

29.3. AP and SP Instructions


Adding and subtracting decimal numbers is straightforward. The sum or difference replaces the
first operand, and the usual CC setting (shown in Table 206 on page 491) reflects the status of
the result.
AP and SP have the same machine instruction formats as ZAP, PACK, and UNPK, shown in
Table 193, and the assembler instruction statement operand formats shown Table in 194, both on
page 463.
Unlike binary addition in the general registers, the results of decimal addition may depend on the
order of the operands if the first operand field is too small. For example, adding 9 + to 123 + gives
132 + , but adding 123 + to 9 + creates a decimal overflow:

Chapter VIII: Zoned and Packed Decimal Data and Operations

493

PD123
PD9

AP
PD123,PD9
AP
PD9,=P+123
- - DC
P+123
DC
P+9

Result = 132+
Result = 2+, with decimal overflow
Packed decimal 123+
Packed decimal 9+

The same consideration applies to subtraction, particularly for operands with opposite signs.
To illustrate the AP and SP instructions, Figure 290 assumes that the initial contents of the first
operand field at XX is 143 + for each instruction (the instructions are not executed in sequence!).
The result of executing each instruction is shown in its comment field.

XX

AP
XX,XX
SP
XX,XX
SP
XX,XX+1(1)
AP
XX,=P -555
SP
XX,=P -555
AP
XX,=P1136
SP
XX,=P1136
- - DC
PL2143

2nd Operand
X143C
X143C
X 3C
X555D
X555D
X01136C
X01136C

Result
c(XX) =
c(XX) =
c(XX) =
c(XX) =
c(XX) =
c(XX) =
c(XX) =

286+,
000+,
140+,
412-,
698+,
279+,
993-,

CC=2
CC=0
CC=2
CC=1
CC=2
CC=3 (overflow)
CC=1

Initial contents for all cases

Figure 290. Examples of the AP and SP instructions

In the third example, the second operand is one byte long, and starts at the second byte of XX.
The operands of SP and AP may overlap only if their rightmost bytes coincide, as in the first,
second, and third instructions above. SP is rarely used to clear a field to 0 + as in the second
instruction above, because ZAP (or MVC) are simpler and usually faster.
Suppose the table of decimal numbers at Dec that we zeroed in Figure 288 on page 492 now
contains 50 data values, and that we wish to add them and place the sum at SumDec.
NDec

Equ 50
ZAP SumDec,=P 0
LA
0,NDec
LA
1,Dec
Loop AP
SumDec,0(3,1)
LA
1,L Dec(,1)
JCT 0,Loop
- - SumDec DS
PL4
Dec
DS
(NDec)PL3

Number of table elements


Initialize sum to zero
Counter for number of summations
Pointer to first table element
Add 3-byte element to sum
Step pointer to next element
Branch until loop is complete
Accumulated sum
Table of 3-byte numbers

Figure 291. Adding a table of 50 packed decimal numbers

where the second operand of the AP instruction has D2= 0 , N 2=3 (so L 2=2), and B 2= 1 .
Because each table entry is at most 5 digits long, the space allocated for the sum at SumDec does
not have to be more than 7 digits (4 bytes) long. If the sum area is more than 4 bytes long, extra
time might be needed each time the AP instruction was executed. Unlike addition and subtraction in the general registers, the time required for decimal addition and subtraction depends on
the length of the operands.
Be Careful!
The results of packed decimal addition and subtraction may depend on
the order of the operands if there is any possibility of decimal overflow.

494

Assembler Language Programming for IBM z System Servers

Version 1.00

Exercises
29.3.1.(2) A devious programmer thought he could ensure his continued employment by
writing obscure code, such as this:

UNPK
A
B
C

PACK
PACK
AP
UNPK
- - DS
DS
DS

A,*(1)
B,UNPK(1)
A,B
C,A(3)

Do a packing task
Do another, too
Add some things
Unpack the things

CL2
B
XL4

First, what do these instructions place in the fields named A, B, and C? Then rewrite his
instructions without any obscurities, to show that you could easily take over his job.
29.3.2.(3) + Suppose the two-byte field at XX initially contains 364+, and that the instruction
AP

XX,XX+1(1)

is executed repeatedly until a decimal overflow occurs. How many times will the AP be executed?
29.3.3.(1) Compare the use of SP and XC (with identical first and second operands) for setting
a decimal field to zero.
29.3.4.(3) Repeat Exercise 29.3.2 assuming that the field at XX initially contains 365+.
29.3.5.(1) Can a decimal overflow be caused by subtracting one operand from another, if both
have the same sign?
29.3.6.(3) In Figure 290 on page 494, the third instruction uses an SP instruction with overlapping fields to zero a part of a packed decimal number. Devise other ways to do this, making no
restrictive assumptions about the length of the operand or the amount of overlap.
29.3.7.(2) + For the operands at A and B, show the result of executing these two AP
instructions, assuming the same initial values of the operands.

A
B

AP
A,B
AP
B,A
- - DC
P 0
DC
X075F

Case 1
Case 2

29.3.8.(2) + An instructor claimed177 that this information came from a program interruption.
Explain why the claim is false.
Interruption Code = X000A , Instruction Length Code = 1
29.3.9.(2) + In Figure 291, is the length of the SumDec field sufficient to hold the sum without
overflow?

177

On an examination, of course!
Chapter VIII: Zoned and Packed Decimal Data and Operations

495

29.4. CP Instruction
The Compare Decimal instruction CP has the same Assembler Language and machine instruction
formats as AP and SP.
Comparing two decimal operands only sets the CC, as shown in Table 207. Overflow cannot
occur.
CC
0
1
2

Indication
Operands are equal.
First operand is low.
First operand is high.

Table 207. CC setting by the CP instruction

The CP instruction is illustrated in the following examples; the result of the comparison is shown
in the comment field of each statement.

XX
YY

CP
XX,XX
CP
XX+1(1),XX
CP
XX,YY
CP
YY,XX
CP
XX+1(1),YY+2(1)
CP
XX(1),YY(1)
- - DC
P+123 (=X123C )
DC
P -70493

CC = 0
123+ = 123+
CC = 1
3+ < 123+
CC = 2
123+ > 70493CC = 1 70493- < 123+
CC = 2
3+ > 3Interruption, invalid data

In the last CP instruction, only the first byte of each operand is accessed, and an interruption will
occur because neither byte contains a valid sign in its rightmost digit position.
To illustrate the CP instruction, suppose we must add the items in the same table of 50 decimal
numbers as in Figure 291. Now, assume that the positive and negative terms must be added separately, and the sums of their magnitudes are to be stored at SumPos and SumNeg respectively.
NDec

Loop

Plus
Next

SumPos
SumNeg
Dec

Equ 50
ZAP SumPos,=P 0
ZAP SumNeg,=P 0
LA
0,NDec
LA
1,Dec
CP
0(L Dec,1),=P 0
JH
Plus
JE
Next
SP
SumNeg,0(L Dec,1)
J
Next
AP
SumPos,0(L Dec,1)
LA
1,L Dec(,1)
JCT 0,Loop
- - DS
PL4
DS
PL4
DS
(NDec)PL3

Number of table elements


Clear positive sum box
And negative sum box
Initialize term counter
Point to start of table
Check sign of an entry
Branch to add + term
Skip if it s zero
It s -, accumulate negative sum
And go count to next item
Accumulate positive sum
Step item pointer to next
Repeat for the next item
Positive sum
Magnitude of negative sum
Table of elements

Figure 292. Adding positive and negative items separately

This program segment is straightforward; the JE instruction might save a small amount of time if
zero elements are likely to appear in the table. The SP accumulates the magnitudes of the negative
terms by subtracting them from SumNeg.
As another example, suppose we want to scan the table to find which element is algebraically
largest, and leave its address at BigItemA.

496

Assembler Language Programming for IBM z System Servers

Version 1.00

LA
0,NDec
LA
1,Dec
Compare CP
Max,0(L Dec,1)
JH
Next
ZAP Max,0(L Dec,1)
ST
1,BigItemA
Next
LA
1,L Dec(,1)
JCT 0,Compare
- - BigItemA DS
A
Max
DC
PL3 -99999
Dec
DS
(NDec)PL3

Initialize count
And table pointer
Compare current max to element
Branch if max is bigger
Save element as new max value
And save address of that element
Step pointer to next element
Count and loop
Address of largest element
Initial maximum is a minimum
Table of elements

Figure 293. Finding the largest item in a table

Using JH in the fourth instruction rather than JNL may cause extra work to be done, but it
guards against the remote possibility that all the table elements are equal to 99999 .

Exercises
29.4.1.(1) + Give two reasons why it might be useful to compare a decimal number to itself.
29.4.2.(2) Suppose the table in Figure 293 contains more than one occurrence of the maximum
value. Which one will the program find?
29.4.3.(2) + Suppose you compare these two packed decimal operands using a CP instruction:

PDP
PDM

CP
PDP,PDM
- - DC
P+0
DC
P -0

Compare operands

What will be the resulting CC setting? Now, compare the same operands using a CLC instruction: what will be the resulting CC setting? How do the results depend on the sign codes of the
operands?
29.4.4.(3) + Rewrite the instructions in Figure 293 to eliminate all uses of a field (like the one
named Max) in which the current maximum value is stored. Instead, set GR2 to the address of
the largest element.
29.4.5.(2)+ What will be the Condition Code after executing these two instructions?
CP
CLC

=P+10,=P -20
=P+10,=P -20

Explain your results.

29.5. MP Instruction
Two length digits are provided in the MP instruction. The first digit specifies the length of the
first (multiplicand) operand and of the product; the second digit specifies the length of the second
(multiplier) operand. The two Encoded (machine) Length digits must satisfy the relations
1 L 1 15,

0 L 2 7,

L1 > L 2

and their Length Expressions must statisfy


2 N 1 16,

1 N 2 8,

N1 > N 2

Chapter VIII: Zoned and Packed Decimal Data and Operations

497

(Section 24.1 describing basic SS-type instructions on page 367 explains the reasons for the differences between N, N1, N 2, and L, L1, L2: the L values the CPU sees are one less than the N
values you specify.)
It is important to remember that the number of bytes of high-order zeros in the first operand
must not be less than the length of the second operand, even though the second operand may
already contain enough high-order zeros.
Unlike binary multiplication in the general registers, these length restrictions mean that the results
of decimal multiplication depend on the order of the operands. For example, multiplying
0000123 + by 456 + gives 0056088 + , while multiplying 456 + by 0000123 + creates a specification
exception, because the product field is too short to contain the result.

DP123
DP456

MP
DP123,DP456
MP
DP456,DP123
- - DC
PL4+123
DC
PL2+456

Result = 0056088+
Specification exception
4-byte packed decimal operand
2-byte packed decimal operand

The first (multiplicand) operand field for a Multiply Decimal instruction is usually initialized with
a ZAP instruction. This automatically sets the high-order digits of the first operand to zero.
Thus, we could multiply 213+ by 126+ (as in Sections 18.4 and 28.4) as follows:

Prod

ZAP Prod,=P213
MP
Prod,=P126
- - DS
PL4

Set up multiplicand
Form product
Space for product

Figure 294. Example of decimal multiplication

The CC is unchanged by the MP instruction; in this example it will have been set to 2 by the
preceding ZAP instruction to indicate the sign of the multiplicand.
To give a more elaborate example, suppose we wish to compute the square of each element of the
table of fifty 5-digit numbers at Dec and store them in the table starting at DecSq. Each element
of the table of products must be 6 bytes long, because there must be as many bytes of high-order
zeros in the multiplicand as there are bytes (3) in the multiplier.
NDec
LD

Set

Dec
DecSq

Equ 50
Equ 3
LA
0,NDec
LA
1,Dec
LA
2,DecSq
ZAP 0(2*LD,2),0(LD,1)
MP
0(2*LD,2),0(LD,1)
LA
1,LD(,1)
LA
2,2*LD(,2)
JCT 0,Set
- - DS
(NDec)PL(LD)
DS
(NDec)PL(2*LD)

Number of table elements


Length of input table elements
Initialize counter
Point to input table
Point to output table
Set up multiplier
Form (2*LD)-byte product
Step Dec table pointer
Step DecSq table pointer
Count down and loop
Table of input data
Squares of input elements

Figure 295. Using M P to square a table of decimal numbers

In this example, the number of table elements and the length of each element may be varied by
modifying the EQU statements.
The MP instruction is easy to use, but there are times when some of its restrictions are annoying.
For example, suppose we want to multiply the 4-byte operand 0001234 + by the 2-byte multiplier
101 + ; the result (0124634 + ) will fit quite comfortably in the four bytes provided by the original
operand. However, because there are not as many bytes of high-order zeros as there are bytes in
the multiplier, we must resort to schemes like this:

498

Assembler Language Programming for IBM z System Servers

Version 1.00

MPCand
R

ZAP
MP
- DC
DS

R,MPCand
R,=P101

Move multiplicand
Multiply by 101

PL40001234
PL5

4-byte multiplicand
Result must be 1 byte longer

Figure 296. Using ZAP to set correct decimal multiplicand length

The result at R will be 000124634 + , but the extra byte of high-order zeros might not be needed
for whatever operations are performed next.
Suppose as before that we want to multiply 0001234 + by 101 + , but this time we reverse the order
of the operands.

R
MPlier

ZAP R,=P101
MP
R,MPlier
- - DS
PL6
DC
PL41234

Lengthen the multiplicand


Now multiply by 0001234+
Result at least 6 bytes long
4-byte multiplier

Figure 297. Using ZAP to set correct decimal multiplicand length

Because the multiplier is four bytes long, there must be four bytes of high-order zeros at R after
the multiplicand 101+ has been placed there. Thus the result field must now be six bytes long,
instead of the five required in Figure 296. Situations may arise where the order of the operands in
a decimal multiplication is important!178 Forgetting to allocate the necessary extra bytes for the
product will result in a data exception: a program interruption will occur, and the IC will be set to
7.
A final (but rarely troublesome) feature of decimal multiplication is that a negative zero result can
be generated as the product of positive and negative zero operands. This is unlikely to occur in
practice, because decimal addition and subtraction place a + sign on zero results (so long as no
overflows occur). The generation of a negative zero is illustrated in Figure 298.

X
Y

MP
X,Y
- - DC
PL2 0
DC
P -0

Generate a negative zero product


Positive zero
Negative zero

Figure 298. Generating 0 using M P

The product is X 000D , or 000 .


Be Careful!
Successful decimal multiplication often depends on the order of the operands.

Exercises
29.5.1.(1) + Determine the inequalities that must be satisfied by the two Length Expressions in
an MP machine instruction statement.
29.5.2.(1) What is the maximum value that may be assigned to the symbol LD in Figure 295 on
page 498?
29.5.3.(2) + Show why we cannot directly multiply 0001234+ by 100+ using an MP instruction, even though the product would contain a high-order zero digit.

178

Mathematically, this means that the MP instruction might not always be commutative.
Chapter VIII: Zoned and Packed Decimal Data and Operations

499

29.5.4.(2) What will happen if we write MP

X,X ?

29.5.5.(4) Suppose the CPU performed decimal multiplication by fetching one operand byte at
a time, and storing a result byte as soon as it is generated. (It doesnt operate that way!) Under
what circumstances could the first and second operands of an MP instruction overlap?
29.5.6.(2) + What result will appear at A after executing the MP instruction?

MP
A,A+1(1)
- - DC
PL2 7

29.5.7.(2) + What result will appear at B after executing the MP instruction?

MP
B,B+3(1)
- - DC
PL4567

29.5.8.(3) What result will appear at C after executing the MP instruction?

MP
C,C+3(3)
- - DC
PL684567

29.6. DP Instruction
As noted in Section 28.5, the results of a decimal division are found in the first operand field.
Unlike binary division in the general registers, however, the quotient of a decimal divide is found
in the left, or high-order, portion of the result, and the remainder is found in the right, or loworder portion. Take care in specifying the lengths of the operands: the remainder has the same
length as the divisor, so the length of the quotient is the difference between the dividend and
divisor lengths.
(quotient length) = (dividend length) - (remainder length)
= (dividend length) - (divisor length)
To avoid a specification error, the Encoded Length digits in the second byte of the instruction
must satisfy the same inequalities as for MP:
1 L 1 15,

0 L 2 7,

L1 > L 2

and similarly for the corresponding Length Expressions.


To illustrate, suppose we want to divide 162843 + by 762 + (as in Section 18.8) using packed
decimal division, as shown in Figure 299.

Dvnd

ZAP Dvnd,=P162843
DP
Dvnd,=P762
- - DS
PL4

Initialize dividend
Divide by 762+
Space for quotient and remainder

Figure 299. Decimal division using D P

After the ZAP instruction is executed, the area named Dvnd will be initialized to 0162843 + .
Because the divisor is 762 + , the alignment test described in Section 28.5 will be satisfied, and a
valid quotient and remainder can be computed. After the DP instruction is executed, the four
bytes at Dvnd will contain 213+ 537+ , so the quotient is 213+ and the remainder is 537+ .
Its often easier to let the Assembler determine operand lengths by using Symbol Length Attribute
References, as shown in Figure 300.

500

Assembler Language Programming for IBM z System Servers

Version 1.00

Dvnd
Dvsr
Quot
Rem

ZAP Dvnd,=P162843
Initialize dividend
DP
Dvnd,Dvsr
Divide by divisor
ZAP Quot,Dvnd(L Dvnd-L Dvsr)
Move quotient...
ZAP Rem,Dvnd+L Dvnd-L Dvsr(L Dvsr) ...and remainder
- - DS
PL4
Can be up to 16 bytes long
DC
P762
Divisor
DS
PL5
Space for quotient 000000213C
DS
PL4
Space for remainder 0000537C

Figure 300. Decimal division using Length Attribute References for operands

In this example, the areas named Quot and Rem were purposely chosen to be longer than required,
to show that extra length makes no difference in the values that will be stored. So long as none
of the restrictions on operand lengths are violated, this instruction sequence will give correct
results.
As a final example, suppose we must calculate the average of the entries in a table of nonzero
9-digit packed decimal numbers stored beginning at Tbl, and that we dont know the length of the
table, only that the last entry is followed by a zero element.
ELen

Test
AddUp

Divide

Finish
Sum
Nbr
Avg
Tbl

Equ 5
Length of a table entry (9 digits)
LA
1,Tbl
Point to origin of table
ZAP Sum,=P 0
Initialize sum box
ZAP Nbr,=P 0
Initialize element counter
ZAP Avg,=P 0
And set average to zero
CP
0(ELen,1),=P 0
Check for table end
JE
Divide
Found end, go compute average
AP
Sum,0(ELen,1)
Accumulate sum
AP
Nbr,=P 1
And increment counter
LA
1,ELen(,1)
Step pointer to next entry
J
Test
And loop
CP
Nbr,=P 0
Check for no data at all
JE
Finish
Give up if no entries
DP
Sum,Nbr
Perform division
ZAP Avg,Sum(L Sum-L Nbr)
Move result
- - - - DS
PL15
Accumulated total of entries
DS
PL4
Count of entries being summed
DS
PL(ELen)
Average value
DS
5000PL(ELen)
Lots of room for data

Figure 301. Computing the average of a table of decimal numbers

Useful Rule of Thumb


The field into which you ZAP a dividend prior to a packed decimal division should be at least as long as the length of the dividend plus the
length of the divisor. (The symbolic forms in Figure 300 are helpful for
valid divisions.)

Exercises
29.6.1.(2) + Revise Figure 301 on the assumption that the end of the table is signaled by a zero
element with a negative sign. Positive zeros are permitted among the table entries.
29.6.2.(1) + Determine the inequalities that must be satisfied by the Length expressions in a DP
instruction statement.
29.6.3.(2) + What will happen if we write DP

X,X ?

Chapter VIII: Zoned and Packed Decimal Data and Operations

501

29.6.4.(1) Give at least two methods for testing whether a packed decimal number is even or
odd.
29.6.5.(2) In Exercise 29.6.1, why can we not test for the terminating negative zero element with
this statement?
Test

ZAP
JM

0(ELen,1),0(ELen,1)
NegZero

Test for -0 element


Jump if -0

29.6.6.(2) It is possible to write DP and MP instruction statements that will specify L1 digits,
where L1 has value zero. If this is done, what will happen when the instructions are executed?
29.6.7.(4) Suppose the CPU performs decimal division by fetching one operand byte at a time,
and storing a result byte as soon as it is generated. (It doesnt operate that way!) Under what
circumstances could the first and second operands of a DP instruction overlap?
29.6.8.(2) + What result will appear at A after executing this DP instruction?

DP
A,A+3(1)
- - DC
PL4 6 7

29.6.9.(2) + What result will appear at B after executing this DP instruction?

DP
B,B+3(2)
- - DC
PL5567

29.6.10.(3) What result will appear at C after executing this DP instruction?

DP
C,C+3(2)
- - DC
PL59567

29.6.11.(1) Can you think of a reason why the designers of z System required the length of the
second operand of a decimal division to be 8 or fewer bytes?
29.6.12.(2) + Explain why there must be at least one leading high-order zero digit in the dividend of a decimal division.
29.6.13.(3) In a division process, the remainder may be chosen in (at least) three ways: (1) the
remainder has the same sign as the dividend, (2) the remainder has the same sign as the quotient, and (3) the remainder is always nonnegative. In all cases, the magnitude of the remainder
is less than the magnitude of the divisor.
In z System, the first alternative is used. What modifications would have to be made to the
rules for decimal division if the second or third alternatives had been chosen instead?

29.7. SRP Instruction


The SRP instruction shifts its operand to multiply or divide a packed decimal number by a power
of 10, and to round the quotient of such a power of 10 division.
Before SRP was available, shifting a computed number of digit positions was complicated: different coding techniques had to be used for shifting left or right by an even or odd number of
digit positions.179 It was also difficult to use the EX instruction to specify the number of digits to
be shifted. The CPU architects rectified this unhappy situation by creating the SRP instruction,
which shifts in either direction with optional rounding for right shifts.

179

502

If youre interested, well see examples in Section 29.9.


Assembler Language Programming for IBM z System Servers

Version 1.00

The Assembler Language statement format for an SRP instruction statement is shown in Figure
302, where the first operand address is given by D1(B 1), the Effective Address of the second
operand D 2(B 2) specifies the number of digits to be shifted, and I3 is the rounding digit.
SRP

D1(N1,B1),D2(B2),I3

Figure 302. Assembler Language format of SRP machine instruction statement

Table 208 shows the assembled machine instruction. format of the SRP instruction:
F0

L1

I3

B1

D1

B2

D2

Table 208. Format of the SRP instruction

The SRP instruction format has several unusual features.


1. There is a single 4-bit length field, L1.
2. The immediate I 3 is used for rounding only when shifting to the right. It must be a valid
decimal digit; if not, a decimal data exception occurs, and the IC is set to 7. (The value of
the I 3 digit is not specified by nor inferred from the length of the second operand.)
3. The decimal number to be shifted is in memory at the Effective Address computed from the
first addressing halfword.
4. The Effective Address computed from the second addressing halfword determines both the
direction and the amount of the shift. It is not a memory address.
The L 1 digit and the first addressing halfword provide the usual method for referring to a packed
decimal operand. The effective address computed from the second addressing halfword is evaluated by the CPU, and its rightmost six bits are treated as a signed twos complement integer. The
number of digits to be shifted therefore lies in the range
B100000 = 32 shift count + 3 1 = B011111
The shift is to the left if the shift count is positive, and to the right if the shift count is negative.
You can think of the shift count as the power of ten P by which the decimal operand will be
multiplied. A zero shift count may be specified, but it only causes the decimal operand to be
checked for validity, which is done at the start of every SRP operation.
If the shift is to the left, the CPU checks for nonzero high-order digits, and indicates a decimal
overflow condition if any are lost. If the shift is to the right, the I3 digit is added decimally to the
last digit shifted out of the first operand, and any carry is propagated into the remaining part of
the first operand. The I3 digit is considered to have the same sign as the decimal number being
shifted. For both left and right shifts, vacated digit positions are set to zero. The CC settings after
SRP are the familiar values shown in Table 206 on page 491.
You can specify the second-operand shift amount using the rules for the twos complement representation: because the shift count is a number P between 32 and +31, its 6-bit twos complement representation is simply 2 6 + P, or 64 + P. Thus, a right shift of two places with no rounding
is specified by this instruction statement:
SRP

A,64-2,0

Shift right 2, no rounding

Similarly, a left shift of two places is specified by


SRP

A,64+2,0

Shift left 2 digit positions

When shifting left, the value of the I3 digit is ignored (but it still must be a valid decimal digit!).
The extra factor of 64 in the shift count will be ignored when the rightmost 6 bits of the effective
second operand address are used; including the factor of 64 ensures that we wont forget it if its
needed for right shifts.
Suppose we want to shift the operand 12345 + to the left three places, as in Figure 303.

Chapter VIII: Zoned and Packed Decimal Data and Operations

503

SRP A,3,0
- - DC
P12345

Left shift causes an overflow


Final contents = 45000+

Figure 303. Shifting a decimal operand left 3 places using SRP

The CC will be set to 3 to indicate the decimal overflow condition.


To shift the same operand to the right without rounding, we can use SRP as in Figure 304.

SRP A,64-2,0
- - DC
P12345

Shift right 2 digits, no rounding


Final value = 00123+

Figure 304. Shifting a decimal operand right 2 places using SRP

To illustrate rounding, lets shift 12345 + to the right one digit position with I3 rounding digit 9
(so that rounding will occur if the last digit shifted has any nonzero value). We set the
rounding digit to 9 to show that it may be any value, not just the value 5 normally used for
rounding.

SRP A,64-1,9
- - DC
P12345

Shift right, rounding digit = 9


Final value = 01235+

Figure 305. Shifting a decimal operand right 1 place with rounding using SRP

An important property of SRP is that the rounding digit can be provided at execution time by an
EX instruction. For example, suppose the rounding digit is contained in the one-byte packed
decimal number at RndDigit and the shift amount is stored as a halfword binary integer at
ShiftAmt. We can then shift the operand as shown in Figure 306, where the shift amount is contained in GR1, and the rounding digit in GR2 is ORed into the second byte of the SRP instruction in the Instruction Register as the target of EX.
LH
1,ShiftAmt
XR
2,2
IC
2,RndDigit
SRL 2,4
EX
2,SRP
- - SRP
SRP A,0(1),*-*
A
DC
PL1659365
RndDigit DC
PL1 9
ShiftAmt DC
H -2

Get shift amount


Clear GR2 for rounding digit
Get rounding digit and its sign
Drop off sign code
Execute the SRP instruction
Executed instruction
Operand to be shifted
Rounding digit, packed decimal form
Shift amount

Figure 306. Shifting a decimal operand with an EXecuted SRP

In Section 29.9 we will see examples showing why SRP is such a useful decimal instruction.

29.7.1. Biased and Unbiased Rounding with SRP


The rounding provided by SRP is slightly biased. To see why, suppose a bank pays daily interest
in cents, and the calculated amounts for four days are 1.5, 2.5, 3.5, and 4.5 cents. If these are
rounded to single cents using SRP with rounding digit 5 and a single right shift, the amounts
added to the account are 2, 3, 4, and 5 cents, or a total of 14 cents. But the true total of the
unrounded amounts is 12 cents, so the bank would be overpaying the customer. 180
We may need to provide unbiased rounding for packed decimal results. Consider this example
with a single rounding digit, as in 337785+ , where the 5 is the digit to be rounded. Using a

180

504

Banks dont like to overpay their customers. (Of course, a bank could truncate the fraction part and keep the accumulated breakage.)
Assembler Language Programming for IBM z System Servers

Version 1.00

single right shift and a SRP rounding digit 5, the biased result would be 33779+ . The rule for
unbiased rounding is:
If the value to be rounded lies exactly halfway between two possible rounded values, choose the
rounded value with an even low-order digit.
Thus, in this example, the unbiased rounded value is 33778+ . The unbiased rounded daily interest
values would be 2, 2, 4, and 4 cents (a total of 12 cents), and the bank would not be overpaying
its customer.
These instructions show one way to do unbiased rounding of a packed decimal number with a
single rounding digit:
MVZ RDigit(1),PDVal+L PDVal-1
Save rounding digit
CLI RDigit,X 5 0
Is the rounding digit exactly 5?
JNE RoundUp
No, do a normal round up
TM
PDVal+L PDVal-2,1 Is the to-be-rounded digit odd?
JO
RoundUp
If yes, round up to an even value
SRP PDVal(L PDVal),64-1,0 No: round down to even
J
Done
Rounding completed
RoundUp SRL PDVal(L PDVal),64-1,5 Round up to even
Done
- - Rdigit DC
X 0 0
Single rounding digit tested here
PDVal
DC
P337785
Decimal value, single rounding digit
See Exercises 29.7.14 and 29.7.15 for general forms of unbiased rounding.
Well see in Chapter IX that decimal floating-point provides many more forms of decimal
rounding, and requires many fewer instructions.

Exercises
29.7.1.(1) + A programmer who wanted an SRP instruction to shift an operand two digits to
the right wrote the statement
SRP

A,-2,0

and received a diagnostic message from the Assembler. Attempting to correct the statement, he
wrote
SRP

A,0-2,0

and received the same diagnostic. Why did he receive these diagnostic messages? What is wrong
with these statements? What should be done to fix them?
29.7.2.(2) + Prove that no overflow exception can occur when executing an SRP instruction
when the shift is to the right.
29.7.3.(2) + In an SRP instruction performing a right shift, why is the I3 digit added decimally
to the last digit shifted out, rather than just added?
29.7.4.(2) What will happen if you execute this SRP instruction on each of the given operands?

A
A

SRP A,64-1,5
- - DC
X123456
DC
X ABCDEF

First sample operand


Second sample operand

29.7.5.(2) What will be the result at X1, X2, and X3 after executing these SRP instructions?

Chapter VIII: Zoned and Packed Decimal Data and Operations

505

X1

SRP
DC

X1,0,5
P998

X2

SRP
DC

X2,1,5
P 9 5

X3

SRP
DC

X3,64-1,5
P 9 5

29.7.6.(1) What shift amount is specified by these instructions, and what resulting data will
appear at A?
LHI 2,-2
SRP A,1(2),3
- - DC
PL3 -4567

c(GR2) = -2
Shift the data somehow
Test data

29.7.7.(2) After executing this SRP instruction, what result will appear at XX?

XX

SRP XX,63,+5
- - DC
PL3 -4567

Shift data at XX
Sample data

29.7.8.(2) In Figure 306 on page 504, what result will appear at A and what will be in the
rightmost 6 bits of GR1? Why is the shift amount in GR1 not reduced by 1, as is done for
EXecuted instructions like MVC?
29.7.9.(5) A program contains
1. a packed decimal operand at A whose length is given by its length attribute L A,
2. a positive one-byte decimal number at RND satisfying 0 c(RND) 9, and
3. a halfword binary integer at SHFT satisfying 32 c(SHFT) + 30.
Write a program segment (not using SRP) to simulate the action of SRP on the operand at A,
as illustrated in Figure 306 on page 504.
29.7.10.(2) SRP and the general-register shift instructions discussed in Section 17 all use the
low-order six bits of an Effective Address for the shift amount. Why do you think SRP treats
this amount as a signed number, while the binary shifts treat it as an unsigned number?
29.7.11.(1) If you thought SRP meant Shift Right Packed but found that was incorrect,
would you have any reasons to prefer that it be named SLRP, meaning Shift Left or Right
and Round Decimal? Why might this actually be a better choice?
29.7.12.(2) A careful programmer wanted to be certain that his SRP instruction would correctly
round a negative packed decimal operand, so he wrote
SRP NegData,64-1,-5
- - NegData DC
PL4 -72945

Round a negative operand correctly


Negative operand to be rounded

What will this instruction do?


29.7.13.(2) + What is the result at E of executing this SRP instruction?

SRP E,2,5
- - DC
X075F

29.7.14.(5) When 5 is used as the rounding digit in an SRP instruction, the rounded result is
slightly biased, because values exactly halfway between two possible rounded results are always
forced to the larger magnitude.

506

Assembler Language Programming for IBM z System Servers

Version 1.00

Write instructions that will round packed decimal numbers D digits long to R digits (where
R < D ; that is, the number of digits to be discarded after rounding is D R), in such a way
that initial values lying exactly half way between two possible rounded R-digit results always
give a result with an even low-order digit.
For example, if D=5 and R=3, two right shifts are required; if the source operand is 12550 +
then the rounded result will be 00126 + , but 12450 + will be rounded to 00124 + , not to 00125 +
as SRP would do.
29.7.15.(5) Suppose the packed decimal number at PDVal is B bytes long, and has R rounding
digits, where R < 2 B 1. (There will be 2 B 1 R digits left after rounding.) Write
instructions that will leave an unbiased rounded result at PDVal. For example, if there are R=3
rounding digits, and the number is 33778529 + , then the rounded result should be 00033779 +;
but if the number is 33778500 + , the rounded result should be 00033778 + .
29.7.16.(2) It is claimed that a rounded quotient can be formed this way:
1. Shift the dividend left one digit.
2. Divide.
3. Shift the quotient right one place, with rounding digit 5.
Prove or disprove this claim.
29.7.17.(2) Show at least four ways to generate a packed decimal negative zero.

29.8. MVO Instruction


MVO simply moves data from the second operand field to the first, with no validity checking and
no effect on the CC. MVO moves hex digits from the second operand field to the first operand
field in a way similar to ZAP, with one very important difference: the sign digit of the first
operand is left in place, and all the digits (including the sign) of the second operand are placed to
the left of the first operand sign. Zeros are supplied in the high-order positions of the first operand
if the second operand is exhausted.
This process is illustrated in Figure 307, where the digits of the second operand are named a,
b, etc., and the sign digits of the first and second operands are named s1 and s2.

a
b c
d e
s2

 Before

x
x x
x x
s1

a
b c
d e
s2 Operand 2

 After

b
c d
e s2
s1 Operand 1

Figure 307. Operation of the MVO instruction

For most applications, the first and second operands will not overlap. We can visualize the
sequence of operations performed by the CPU in executing an MVO instruction this way:
1. Move the second operand to an internal work area, and shift it left (offset it) by one hex
digit.
2. Attach the sign digit of the first operand to the right end of this internal digit string, and place
as many high-order zero digits at the left end as may be needed to fill all bytes of the first
operand.
3. Move the resulting digit string to the first operand area, starting at the right-hand end. Excess
high-order digits are lost.
Figure 308 illustrates using MVO with nonoverlapping operands.

Chapter VIII: Zoned and Packed Decimal Data and Operations

507

MVO A,B
MVO C,D
- - DC
P678
DC
PL4 -5

B
A
*

- - DC
P987654321
DC
PL3555

D
C
*

Move a shorter to a longer, and...


Move a longer to a shorter.
Two-byte operand
Initial contents = X0000005D ,
Final contents = X000678CD
Five-byte operand
Initial contents = X00555C ,
Final contents = X4321CC

Figure 308. Two Examples of MVO results

Figure 308 shows that the result of an MVO instruction can be an invalid decimal operand,
because the rightmost byte may contain two sign codes instead of one.
This example does not indicate the contexts in which an MVO instruction might normally
appear. The next section contains examples of its most common early application, decimal
shifting. You can of course perform a decimal shift by multiplying or dividing by an appropriate power of ten, just as a binary shift multiplies or divides by a power of two. However, SRP
is faster than the corresponding multiplication and division instructions.
While MVO is rarely used with overlapping operands, the result is as though bytes are processed
one at a time with each result byte being stored immediately after fetching the source bytes.
Some examples showing how MVO can be used for shifting are described in Section 29.9.

Exercises
29.8.1.(4) Given that N1 and N 2 are the true lengths of the first and second operands, write
instruction sequences to simulate an MVO instruction assuming
1. N 1 = N 2,
2. N 1 < N 2, and
3. N 1 > N 2.
29.8.2.(1) + What will be the result (in hexadecimal) at New of executing this instruction, for
each of the source operands?
MVO New,Old
- - DC
C12345*

New
1.
2.
3.
4.

Old
Old
Old
Old

DC
DC
DC
DC

X123456
C ABCD
F123456
X123456789ABC

29.8.3.(2) + What can you say aout the number of numeric digits moved by an MVO instruction?
29.8.4.(2) + If an MVO instruction results in truncated second-operand digits, what can you say
about the number of truncated digits?
29.8.5.(3) + Draw a detailed flowchart that describes the digit-by-digit action of MVO. Be sure
you correctly handle operands of unequal lengths, and the possibility of operand overlap. (Can
you use the similarities between MVO and ZAP to combine this flowchart with the one you
drew for ZAP in Exercise 29.2.8?)
29.8.6.(2) + You have now encountered several instructions which can be used to move individual hex digits from byte to byte. Let the left and right hex digits of Byte1 be labeled 1L and
1R, respectively, and similarly for digits 2L and 2R of Byte2. Now, make a table which shows all

508

Assembler Language Programming for IBM z System Servers

Version 1.00

of the possible ways to move one or both digits from Byte1 to Byte2, and an instruction that
will perform the specified movement.
29.8.7.(3) + A programmer suggested this technique for converting the bits of a byte to eight
printable 0 and 1 EBCDIC characters:

Byte
Mask
Work
Out

MVC
MVC
NC
MVO
MVC
TR
DC
DC
DC
DC

Out(1),Byte
Out+1(7),Out
Out,Mask
Work,Out(4)
Out(4),Work
Out,=C011111111
B11010110
X8040201008040201
XL57777777777
XL8 aaaaaaaaaaaaaaaa

First, explain how it works. Then, explain why the literal is nine characters long.

29.9. Decimal Shifting Using MVO (*)


When we need to multiply or divide packed decimal numbers by a power of ten, its easiest to use
the SRP instruction. Unfortunately, the original architecture of System/360 provided no basic
instruction to shift decimal operands; you had to write an explicit instruction sequence for each
shift. Well examine some techniques that can be used to shift packed decimal operands the
hard way.
You will appreciate the power of the SRP instruction by comparing it to what had to be done
when it was not available.

29.9.1. Shift Right an Odd Number of Digits


To perform a decimal right shift of an odd number of digit positions, only the MVO instruction
need be used. For example, to shift 12345 + to the right by three digit positions, we could write
instructions as in Figure 309.

MVO A,A(1)
- - DC
P12345

Shift right 3 decimal digits


Initial contents = 12345+

Figure 309. Shifting a decimal operand right an odd number of digits

Because the contents of the byte at A(1) is X 1 2 , the final contents of the 3-byte memory area
named A would be 00012 + , as desired.
To illustrate this technique in greater generality, suppose an operand at A of length L bytes is to
be shifted right N decimal digit positions, and we know N is odd and that N < 2L 1. The
required MVO instruction can be written as in Figure 310:
MVO

A(L),A(L-N/2+1)

Shift right N decimal digits

Figure 310. Shifting a decimal operand right an odd number of digits

Although the first and second operands overlap, its easy to see how this instruction works, since
the data is being shifted to the right: this is the natural direction for MVO.

Chapter VIII: Zoned and Packed Decimal Data and Operations

509

29.9.2. Shift Left an Odd Number of Digits


To perform a decimal left shift of an odd number of decimal places, we need more than one
instruction. If we want only to introduce an odd number of zeros at the right end of the number
without dropping off any digits at the left, this simple technique can be used. First, we move the
sign to the right N+1 digit positions, and then we move the digits themselves to the right one
digit position. This effectively introduces N vacant digits, which can then be set to zeros. To
illustrate, suppose the packed decimal operand 12345 + at A is to be shifted left 3 decimal digit
positions and placed at AShifted.
MVN A+4(1),A+2
MVO A(4),A(3)
NC
A+3(2),=X000F
- - AShifted DS
0PL5
A
DC
P12345
DS
PL2

Move sign 4 digits to right


Shift digits right once
Remove unwanted digits
Result = 012345000+
Initial operand = 12345+
Space for 3 inserted zeros and sign

Figure 311. Shifting a decimal operand left an odd number of digits

The symbol AShifted is defined in such a way that we can refer to the shifted (and extended)
operand with the correct address and its new length attribute. (See Exercise 29.9.2.)
If the shifted operand must have the same length as the original operand, the code required is
slightly more complicated, unless only a single digit shift is required. This case can be done
simply, as illustrated in Figure 312. Suppose the initial operand is again 12345 + .

MVO A,A
NI
A+L A-1,X 0F
- - DC
P12345

Shift left one decimal digit


Set duplicated sign to zero
Final contents = 23450+

Figure 312. Shifting a decimal operand left by one digit

In this case the operands overlap completely. The rule used by the CPU to handle possible
memory conflicts is that any second operand bytes needed for any step of the operation are
fetched from memory just before storing the result byte of that step.
If the first and second operands must have the same length for odd left shifts of 3 or more digits,
then it is best to use a separate area for the first operand. To illustrate, suppose the packed
decimal operand 12345 + must be shifted left 3 places, and the result is stored at B. As in
Figure 303 on page 504, well shift the operand 12345 + to the left three places, as shown in
Figure 313.

A
B

MVN B+2(1),A+2
MVO B(2),A
NC
B+1(2),=X000F
- - DC
P12345
DS
PL3

First, move sign digit


Move sign and two digits (45+x)
Set sign and extra digits to zeros
Initial contents = 12345+
Final contents = 45000+

Figure 313. Shifting a decimal operand left by three or more digits

This technique can of course be used for single left shifts, but the method of Figure 312 is
simpler. (See Exercise 29.9.3.)

29.9.3. Shifting an Even Number of Digits


Shifting a decimal number an even number of digit positions is usually simpler than for the odd
shifts, because the digits retain their relative positions within each byte. Thus, we usually do even
shifts with the ordinary move and logical instructions. For example, to multiply 0001234 + by
100 (not by the packed decimal operand 100 + ), we need only shift the digits left by two positions,
or one byte:

510

Assembler Language Programming for IBM z System Servers

Version 1.00

0001234+ 100

becomes

0123400+.

This result cant be obtained by using an MP instruction, because there are not enough highorder zeros in the operand to be shifted.

29.9.4. Shifting Left an Even Number of Digits


To shift left using move and logical instructions, we can use the technique shown in Figure 314.

MVC A(3),A+1
NI
A+3,X 0F
NI
A+2,X F0
- - DC
PL41234

c(A) = 01234+4+
c(A) = 01234+0+
c(A) = 0123400+, now 100 greater
Initial data = 0001234+

Figure 314. Shifting a decimal operand left an even number of digits

In this example, the length of the operand is the same before and after the operation. If you need
a longer result, you can use the technique shown in Figure 315: instead of shifting the data to the
left, we shift the sign to the right.

B
A

MVN B+4(1),A+3
NI
B+4,X 0F
NI
B+3,X F0
- - DS
0PL5
DC
PL41234
DS
P

Move sign digit only


Zero out the excess digit
And the old sign position
5-byte result = 000123400+
Initial value of number to shift
Reserve one extra byte

Figure 315. Shifting a decimal operand left an even number of digits

As these two examples show, extra effort is needed to zero out the positions vacated by the
shift. It may be simpler in some cases to use an SS-type instruction to set the necessary digit
positions to zero, as in Figure 316.

A
Mask

MVC A(3),A+1
NC
A+2(2),Mask
- - DC
PL41234
DC
X F00F

Move first three bytes left


Set vacated digits to zero
Initial operand
Mask for zeroing vacated digits

Figure 316. Shifting a decimal operand left an even number of digits

This NC instruction does the same zeroing as the two NI instructions in Figure 315.

29.9.5. Shifting Right an Even Number of Digits


To shift right an even number of places, two techniques are used, depending on whether or not
the result must have the same length as the original operand. If the result may have a different
length, it is simplest to move the sign digit to the left, and leave the leftover data in place. For
example, suppose 12345 + is to be shifted right two digit positions, so 123 + is the desired result.

B
A

MVN A+1(1),A+2
- - DS
0PL2
DC
PL312345

Move sign 2 digits to left


For referring to shifted result
Final contents = 123+5+

Figure 317. Shifting a decimal operand right an even number of digits

We must now refer to the result at B with its new name and length attribute, since the original
three-byte operand now contains an invalid digit. (See Exercise 29.9.4.)

Chapter VIII: Zoned and Packed Decimal Data and Operations

511

When the length of the original operand must be preserved (so that the desired number of highorder zeros actually appears in the leftmost bytes), it is difficult to use the move instructions,
because they process data from left to right, rather than from right to left.
Surprisingly, it is easiest to shift right an even number of digit positions by doing two odd shifts!
To illustrate, we can shift 12345 + to the right by two digit positions using two MVO instructions,
as in Figure 318.
MVO A(3),A(2)
MVO A(3),A(2)
- - DC
P12345

Shift once, result = 01234+


Shift again, result = 00123+
Original 3-byte operand = 12345+

Figure 318. Shifting a decimal operand right an even number of digits

As these examples show, SRP may be much simpler; it also provides protection against invalid
data and unexpected decimal overflow.

Exercises
29.9.1.(1) + At the end of Section 29.9.3, the text states that we cant use the MP instruction to
multiply 0001234 + by 100 + . Explain why not.
29.9.2.(3) Generalize the instructions in Figure 311 on page 510 to handle an odd left shift of
N digit positions of the L-byte operand at A. State any restrictions that must be imposed on
the values of L and N.
29.9.3.(3) Generalize the instructions in Figure 313 on page 510 to an odd left shift of N digit
positions of the L-byte operand at A, leaving the shifted result at B. State any restrictions
imposed on the values of L and N.
29.9.4.(3) Generalize the technique illustrated in Figure 317 on page 511 to an L-byte operand
shifted right an even number N of digit positions. State any restrictions on N and L.
29.9.5.(2) In the discussion preceding Figure 310 on page 509 about using MVO to shift an
L-byte operand to the right by an odd number of digit positions N, we said that we required
N < 2 L 1. Why cant this requirement be written N 2L 1 ?
29.9.6.(2) Write a sequence of instructions using the technique illustrated in Figure 312 on
page 510 to perform a single left shift of the L-byte packed decimal operand at A. If the shift
causes a decimal overflow, branch to Over after the shift is completed.
29.9.7.(3) The decimal operand at A has length L bytes, and is to be shifted left N digit positions, where N is an even number. Generalize the instruction sequence shown in Figure 316 on
page 511 to do the shift. State any restrictions that must be placed on N and L.
29.9.8.(3) Do the same as in Exercise 29.9.7, but branch to Over if significant high-order digits
are lost.
29.9.9.(3) Using the same conditions as in Exercise 29.9.7, generalize the instruction sequence of
Figure 315 on page 511, and state any necessary restrictions on N and L.
29.9.10.(3) Suppose we wish to multiply the decimal number at A by an even power of ten,
where the power of ten is defined in an EQU statement such as
N

Equ

Multiply by 10**6

Write a sequence of instructions using the techniques illustrated in Figures 314 through 316 to
perform the desired multiplication. What restrictions must be placed on the value of N, and
how will it depend on the length of the number at A?

512

Assembler Language Programming for IBM z System Servers

Version 1.00

29.9.11.(5) Write instruction sequences not using SRP that will shift a decimal number to the
right N digit positions, and round the result properly. (Rounding should be done by adding 5 to
the most significant digit shifted out of the operand.)
29.9.12.(3) Generalize the technique in Figure 318 on page 512 to shift an L-byte operand to
the right by an even number N of digit positions. State any restrictions on L and N.

29.10. Scaled Packed Decimal Computations: General Rules


All previous examples of packed decimal arithmetic have assumed integer operand values. But
decimal arithmetic must often deal with numbers containing fractional parts, such as currency
values, percentages, and the like. Packed decimal arithmetic with such values requires some extra
considerations.
For example, adding two currency values like $123.45 and $234.56 is simple; we can treat them as
integers, and remember to insert the decimal point in the right place when the result is formatted
for printing or display.
$123.45
+ $234.56
$358.01
Similarly, multiplying a currency value by an integer can be done in much the same way:
$123.45
x
12
$1481.40
But if our data is more complex, we need to know more.

29.10.1. Precision and Scale


There are two senses of the word precision.
In Assembler Language terms, precision refers to the number of digits a field or register can
hold. A 4-byte object can hold 32-bit integers, or 7 packed decimal digits, or 4 zoned decimal
digits. This is sometimes called field precision. We dont need to know the values stored in
those objects.
In computational terms, precision refers to the number of significant digits in a number. A
value like 3.14159265368979 has 15 significant digits, so its precision is 15 digits. The number
3.12345678901234 is also precise to 15 digits.181
Because we may not know the precision of a value stored in a field at any given time, we must
work with the known maximum precision of the value: the precision of the field.
Overflows can also cause inaccuracy in precise values: the sum of two 32-bit integers that causes a
fixed-point overflow is still precise to 32 bits, but a very inaccurate representation of the true sum.
We must often do arithmetic with numbers having different numbers of digits before and after the
decimal point. For example, suppose we use an AP instruction to directly add two 3-digit packed
decimal numbers:
A
B

DC
DC

P 1 2 3 .
P . 4 5 6

X123C
X456C

Because packed decimal arithmetic is integer arithmetic, we find that the sum P579 has no
correct digits. For a correct sum, we must first define a field to hold 6 or more digits:

181

The first value is an approximation to pi that is also accurate to 15 decimal digits. However, the second value is
accurate to only two digits. Theres a big difference between precision and accuracy!
Chapter VIII: Zoned and Packed Decimal Data and Operations

513

Sum

DS

PL4

Space for 7 digits

To account for the differences in decimal point positions, we must (1) align the operands and (2)
remember the position of the decimal point in the sum:
ZAP Sum,A
SRP Sum,64+3,0
AP
Sum,B
- - DC
P 1 2 3 .
DC
P . 4 5 6
DS
PL4

A
B
Sum

c(Sum) = X0000123C = 123.


c(Sum) = X0123000C = 123.000
c(Sum) = X0123456C = 123.456

Space for 7 digits

Figure 319. Ensuring decimal point alignment for packed decimal addition

It is up to you to write instructions that keep track of the position of the decimal in all mixed
integer-fraction calculations.182
We will use I.F as our notation for a number containing both integer and fraction values,
where I is the number of integer digits and F is the number of fraction digits.

29.10.2. General Rules: Addition and Subtraction


Consider adding these two numbers:
123.45
+ 994.7264
1118.1764
Because the sum may cause a carry from the high-order digit of the larger operand, the I value of
the result is one larger than the I value of the larger operand. (For subtraction, the result could
have fewer digits.)
If we call 123.45 the first operand, its I and F values are I1=3 and F 1=2; for the second operand,
I2=3 and F 2=4. We see that the results I and F values are F=4 and I= 4 .
We can infer a general rule for addition and subtraction:
I = Max(I1,I2) + 1
F = Max(F1,F2)
That is, a sum or difference may have one more integer digit than the larger number of integer
digits of the operands, and it may have the larger number of fraction digits of the two operands.

29.10.3. General Rules: Multiplication


Well use another example to illustrate a general rule. Suppose we multiply these two numbers:
x

432.45
6.0743
2626.831035

and we see that the products number of integer and fraction digits is given by
I = I1 + I2
F = F1 + F2
These values are of course the largest possible; if we multiply 1.252.2=2.750 we see that I for
the product can be less than the maximum; and if we omit trailing zeros, F can also be less than
the maximum.

182

514

The Integer (I ) and Scale (S ) attributes of packed decimal operands can help; see the example in Section 29.11.4.
Assembler Language Programming for IBM z System Servers

Version 1.00

29.10.4. General Rules: Division (*)


Division rules are more complicated than those for addition, subtraction, and multiplication. To
start, consider the simple division 4/3:
4./3. = 1.3333333333333333333333333333333333333333333333...
We see that the number of integer digits is limited, but the unending fraction is a problem. So we
need a rule to give useful values of I and F. First, well consider I:
4./.3 = 13.3333333333333333333333333333333333333333333333...
4./.03 = 133.33333333333333333333333333333333333333333333...
4./.003 = 1333.333333333333333333333333333333333333333333...
4./.0003 = 13333.3333333333333333333333333333333333333333...
so we see that the value of I is
I = I1 + F2
Depending on how many fraction digits we want to keep in the result, the length of the packed
decimal quotient field might need to be much larger than I to accommodate the quotients fraction digits.
As another example, suppose we divide 457.9 by 1.23. Since multiplying both terms by the same
number doesnt change the quotient, we can multiply both by 100 to eliminate the fraction parts,
so that the divisor (1.23) is now 123 and the dividend is now 45670:
45790/123 = 372.27642276422764227642276422764227642276...
The unending quotient is again a problem: how many fraction digits should we keep? Usually we
will round the result to a reasonable number of digits, being careful to keep correct numbers of
integer and fraction digits. But, what is the correct number of digits?
You can consider two ways to handle this question:
1. If the fraction digits arent important, you can use the shortest valid lengths for divisor and
dividend. For example, in evaluating 4/3 we could write:

Num
Den

ZAP Num,=P 4
DP
Num,Den
- - DS
PL2
DC
P 3

Set up dividend
Divide by divisor
Minimum possible length!

and the result at Num will be X 1 C1C , with quotient 1 and remainder 1.
2. If, however, you want to retain (say, 5) digits of the fraction, you will first need to allocate a
longer area for Num and then multiply the dividend by 10 5:

Num
Den

ZAP Num,=P 4
SRP Num,64+5,0
DP
Num,Den
- - DS
PL5
DC
P 3

Set up dividend
Scale up by 5 digits (* 10000)
Divide by divisor
Space for quotient and remainder

and the result at Num will be X0133333C1C , with quotient 133333 and remainder 1. When
you format the result for printing or display, you will have to unscale the result by placing
the decimal point correctly. For example, you can use the ED (Edit) instruction (to be
described in Section 30):

EDM
W

MVC W(L EdM),EdM


Copy edit pattern
ED
W,Num
Edit the result
- - DC
X4020214B2020202020 bds.ddddd
7 quotient digits
DS
CL9

and the result at W is C 1.33333 (where represents a space).

Chapter VIII: Zoned and Packed Decimal Data and Operations

515

As another example, suppose we want to print the quotient of 479.6/1.23, rounded to 2


decimal places. Now,
479.6/1.23 = 389.9186991869918699186991869918699...
so our final rounded result should be 389.92. First, we must multiply by 100 to change both
operands to integers, so the division becomes 47960/123, which has the same result. The
quotient and divisor both have 3 digits (which fit in 2-byte packed decimal numbers), so we
might try this:

Num
Den

ZAP Num,=P47960
DP
Num,Den
- - DS
PL4
DC
P123

Set up dividend
Divide by divisor
Space for quotient and remainder

which gives a result at Num of X389C113C , a quotient of 389 and remainder 113. But this
doesnt have enough digits for both the fraction and the remainder parts (we want 2 rounded
fraction digits), so we need at least one additional digit for rounding. So, we first multiply
the numerator by 1000, remembering that we must increase the length of the Num field by 2
additional bytes:

Num
Den

ZAP Num,=P47960
SRP Num,64+3,0
DP
Num,Den
- - DS
PL6
DC
P123

Set up dividend
Scale up by 3 digits
Divide by divisor
Space for quotient and remainder

which gives a result at Num of X0389918C086C . The quotient, X389918C , is ready for
rounding using an SRP instruction:

Num
Den

ZAP Num,=P47960
SRP Num,64+3,0
DP
Num,Den
SRP Num(4),64-1,5
- - DS
PL6
DC
P123

Set up dividend
Scale up by 3 digits
Divide by divisor
Shift right one digit and round
Space for quotient and remainder

and the rounded result at Num is X0038992C086C , ready for printing to 5 significant digits.
So, the answer to our question what is the correct number of digits? depends on how many
fraction digits are required for a particular application. So, if we say that the total number of
integer and fraction digits needed is N=I+F, and we already know the value of
I = I1 + F2,
so for division the number of fraction digits F is simply
F = N - I

29.10.5. COBOL and PL/I Notations (*)


High-level languages like COBOL and PL/I keep track of these details for you. Each numeric
quantity is explicitly or implicitly declared with a number of integer and fraction digits, and the
compiler and its run-time library use that information to produce valid results whenever possible.
They use different terminology than the I.F described above:
COBOL calls the number of integer digits integers and the number of fraction digits decimals.
Thus,
01 Number Pic S9(4)V9(2) Packed-decimal Value +1234.56
declares Number to have 4 integers and 2 decimals.
PL/I assigns a precision p and a scale q to fixed-point values: p is the total number of digits the
field can hold, and q is the number of fraction digits. Thus,

516

Assembler Language Programming for IBM z System Servers

Version 1.00

Declare Number Decimal (6,2) Init (1234.56);


assigns p=6 and q=2 to Number. Thus for PL/I, I.F = (p q).q.

Exercises
29.10.1.(2) Express the I and F values of the three symbols in Figure 319 on page 514 in PL/I
notation.

29.11. Example of a Packed Decimal Business Computation


To illustrate a real packed decimal application, suppose a wholesaler and a retailer complete an
order:
1. The retailer orders from the wholesaler 60 high-tech widgets at $74.65 each.
(60$74.65 = $4479.00)
2. For this large order, the wholesaler discounts the price by 4.7%.
($4479.000.047 = $210.513, so the discounted price is $4479.00 $210.51 = $4268.49)
3. The wholesaler adds 9.75% local sales tax, and a $4.00 per-item shipping charge.
(4268.491.0975 = 4684.67; the shipping charge is 60$4.00 = $240.00, so the total is
$4684.67 + $240.00 = $4924.67.)
4. The retailers pre-payment of $1000.00 is deducted. The result is the wholesalers bill to the
retailer.
($4294.67 $1000.00 = $3294.67)
Then, the retailer calculates his necessary markup and the sale price:
5. The retailer calculates his base cost for each item.
($4294.67/60 = $82.07785 or $82.08)
6. He then applies his retail markup (about 37%), adjusted to a sale cost just below one dollar.
(The markup is $82.081.37 = $112.4496 or $112.45, and the adjustment is
$0.54 + $112.45 = $112.99)
7. Each item a customer buys must include 9.25% sales tax and a $7.50 recycling fee.
(The sales tax is $112.991.0925 = $123.44; adding the recycling fee gives the final customer
cost: $123.44 + $7.50 = $130.94)
8. The result is the final cost per item to the customer.
9. The retailers gross profit per item is (sale cost) (base cost).
($112.99 $82.08 = $30.91. The percent gross profit is $30.91/$82.08 = 0.376 or 38%)
We will now see how each step is calculated in packed decimal arithmetic.

29.11.1. The Wholesalers Calculation


First, he creates data and work areas, choosing field lengths to hold values and results. The
parenthesized values are (I.F): the number of integer digits and the number of fraction digits.
Thus, the width of the field is I+F digits. (Remember that the number of bytes is (I+F)/2+1.).

Chapter VIII: Zoned and Packed Decimal Data and Operations

517

UnitCost
WItems
Discount
WhlseTax
ShipChrg
Prepaid
WhlseNet
WWorkVal
ShipWork
WDisc
WSTax

DC
DC
DC
DC
DC
DC
DS
DS
DS
DS
DS

PL374.65
PL2 6 0
PL2 . 0 4 7
PL3.0975
PL2 4 . 0 0
PL51000.00
PL500000.00
PL8
PL4
PL8
PL8

Base cost per item


Number of wholesale items ordered
Discount percentage for large order
Sales tax at wholesaler location
Shipping charge per item
Retailer s prepayment
Net cost to retailer
Work area for wholesaler calculations
Work area for shipping charge
Work area for bulk-order discount
Work area for wholesale sales tax

(3.2)
(3.0)
(0.3)
(1.4)
(1.2)
(7.2)
(7.2)

Figure 320. A business calculation in packed decimal, part 1

Next, the wholesaler uses this data and the work areas to calculate the retailers bill:
ZAP
*
MP

WWorkVal,UnitCost Set up unit cost


(nnnnnnnnnnnnn.nn)
WWorkval,WItems
Multiply by no.items ordered

X000000000007465C (13.2)
X000000000447900C (13.2)

Because the number of items is an integer, there is no change in the number of fraction
digits in the product.
ZAP
MP
SRP
SP

WDisc,WWorkVal
WDisc,Discount
WDisc,64-3,5
WWorkVal,WDisc

Copy base cost for bulk discount


Discounted cost
X000000021051300C (13.5)
Rounded bulk discount
X000000000021051C (13.2)
Calculate discounted cost
X000000000426849C (13.2)

The discount has 3 fraction digits, so the number of fraction digits in the product increases
to 5, so we shift right 3 places and round to get the correct discount.
ZAP
MP

WSTax,WWorkVal
WSTax,WhlseTax

SRP
AP

WSTax,64-4,5
WWorkval,WStax

Copy for calculating sales tax


Wholesaler s sales tax
(nnnnnnnnn.nnnnnn)
Calculate rounded sales tax
Add wholesaler s sales tax

X000000416177775C (11.6)
X000000000041618C (13.2)
X000000000468467C (13.2)

The sales tax has 4 fraction digits, so the number of fraction digits in the product increases
to 6, so we shift right 4 places and round to get the correct tax amount.
ZAP
MP
AP
SP
ZAP

ShipWork,ShipChrg
ShipWork,WItems
WWorkVal,ShipWork
WWorkVal,PrePaid
WhlseNet,WWorkVal

Set shipping charge


Times number of items
Add shipping charge
Subtract retailer s prepayment
Now have net cost to retailer

X0024000C
X000000000492467C
X000000000392467C
X000392467C

(5.2)
(13.2)
(13.2)
(7.2)

Figure 321. A business calculation in packed decimal, part 2

Thus, the wholesalers bill to the retailer is X000392467C , or $3924.67. Note that the
instructions must keep track of the decimal point at each step.

29.11.2. The Retailers Calculation


Now that the retailer has received the widgets and the bill from the wholesaler he must determine
what to charge as a retail price, and what his margin of profit will be for each widget he sells.
First, he creates data and work areas, choosing field lengths to hold values and results:

518

Assembler Language Programming for IBM z System Servers

Version 1.00

WhlseChg
NItems
BaseCost
RMarkup
RFudge
Retail
GrossPrf
CustCost
RWorkVal
RetailTx
Recycle
ItemCost

DC
DC
DS
DC
DC
DS
DS
DS
DS
DC
DC
DS

PL44924.67
PL2 6 0
PL4 0
PL3 1 . 3 7
PL2 0 . 5 4
PL4
PL3 0
PL4
PL8
PL3.0925
PL3 7 . 5 0
PL4

Charge for the full order


Number of items ordered
Base cost per item work area
Basic retail markup margin
Bump up retail price a little
Retail advertised price per item
Gross profit per item sold
Final charge per item to customer
Work area for retail calculations
Sales tax at retailer location
Recycling charge per item
Total customer cost per item

(5.2)
(3.0)
(5.2)
(1.2)

(1.4)
(3,2)

Figure 322. A business calculation in packed decimal, part 3

As in the wholesalers calculation, the (precision,scale) of each item are shown.


The retailer can now calculate the retail cost per widget and his expected rate of profit per item.
ZAP
DP

RWorkVal,WhlseChg Prepare to calculate base cost X000000000447967C (13.2)


RWorkVal,NItems
Calculate base cost per item
X00000008207C047C (9.2)

The retailer wants to round the base cost, but SRP wont work: only if twice the remainder is
greater than or equal to the number of items (the divisor) should the quotient be rounded.
AP
CP
JL
AP
NoRnd ZAP
ZAP
MP
SRP
AP

RWorkVal+6(2),RWorkVal+6(2) Check remainder


RWorkVal+6(2),NItems
2*Remainder < NItems?
NoRnd
Branch if yes, no roundup
RWorkVal(6),=P 1 Round up base cost
RWorkVal,RWorkVal(L RWorkVal-2) Drop remainder
BaseCost,RWorkVal Save the base cost per item
RWorkVal,RMarkup Find approximate retail price
RWorkVal,64-2,5
Round off the two extra digits
RWorkVal,RFudge

X00000008207C094C ( 1 . 2 )
X00000008208C

(9.2)

X0008208C
X000000001124496C
X000000000011245C
X000000000011299C

(5.2)
(11,4)
(13.2)
(13.2)

He wants the sales price to seem more sale-like, so he adds a value to force the sales price
upward to end in .99.
ZAP
MP
SRP

Retail,RWorkVal
Save advertised retail price
X0011299C
(5.2)
RWorkVal,RetailTx Calculate retailer s sales tax X000000010451575C ( 9 . 6 )
RWorkVal,64-4,5
Round off to dollars/cents
X000000000001045C (13.2)

Just as the wholesaler did, the retailer compensates for the four fraction digits in the sales tax
by rounding the tax to have two decimal digits.
AP
AP
ZAP
ZAP
SP
SRP
DP

RWorkVal,Retail
RWorkVal,Recycle
CustCost,RWorkVal
RWorkVal,Retail
RWorkVal,BaseCost
RWorkVal,3,0
RWorkVal,BaseCost

Add the retail cost


X000000000012344C (13.2)
Add widget recycle charge
X000000000013094C (13.2)
Save customer cost/item
X0013094C
(5.2)
Calculate gross profit per item
Subtract base from retail
X000000000003091C (13.2)
Position for % calculation
X000000003091000C (10.5)
Percentage gross profit
X0000376C0004792C ( 7 . 1 )

Figure 323. A business calculation in packed decimal, part 4

The third and fourth instructions help calculate a rounded quotient; like binary division, packed
decimal quotients are unrounded. If 2(remainder) divisor, we add 1 to round the quotient.
Finally: the advertised retail cost per widget is $112.99, and with sales tax and recycling charge,
total cost per widget to the customer is X0013094C = $130.94.
The retailers gross profit per item is X0003091C = $30.91, and his profit margin is
X0000376C = 37.6%.

Chapter VIII: Zoned and Packed Decimal Data and Operations

519

29.11.3. Comments
As these examples illustrate, doing realistic calculations with packed decimal arithmetic can be
complicated; you must plan carefully to ensure that field lengths are correct and that edit patterns
(described in Section 30) produce correctly formatted results. This business calculation can be
done much more easily in Assembler Language using decimal floating-point, as well see in
Section 35.13; but (for packed decimal arithmetic) many programmers prefer letting a high level
language like PL/I or COBOL worry about the details.
Preview of Coming Attractions
Having completed this section, you can understand the difficulties of
typical packed decimal arithmetic calculations. Chapter IX will describe
Decimal Floating Point arithmetic and data, which greatly simplifies the
problems inherent in packed decimal.

29.11.4. Using Integer and Scale Attributes (*)


The assembler can help with packed decimal data containing integer and/or fraction digits, using
the Integer Attribute (I ) and the Scale Attribute (S ) of a symbol. Consider the symbols in
Figure 319 on page 514:
c(Sum) = X0000123C = 123.
c(Sum) = X0123000C = 123.000
c(Sum) = X0123456C = 123.456

ZAP Sum,A
SRP Sum,64+3,0
AP
Sum,B
- - DC
P 1 2 3 .
DC
P . 4 5 6
DS
PL4

A
B
Sum

Space for 7 digits

The values of the symbol attributes are shown in Figure 324, where we see that I A=3, S A=0,
I B=0, S B=3, I Sum=7 and S Sum=0.
000000 123C
000002 456C
000004

1 A
2 B
3 Sum

DC
DC
DS

P 1 2 3 .
P . 4 5 6
PL4

000008 0300
00000A 0003
00000C 0700

5
6
7

DC
DC
DC

AL1(I A,S A)
AL1(I B,S B)
AL1(I Sum,S Sum)

Figure 324. Integer and Scale Attributes

We could use these values in the SRP instruction to determine the amount of the shift:
ZAP
SRP
AP

Sum,A
Sum,64+(S B-S A)
Sum,B

c(Sum) = X0000123C
c(Sum) = X0123000C
c(Sum) = X0123456C

(7.0)
(4.3)
(4.3)

Figure 325. Using Scale Attributes in a SRP instruction

In practice, Integer and Scale attributes are used rather rarely, and then mainly in macro
instructions.
29.11.1.(2) Show the Integer and Scale Attributes of the following packed decimal data items:
1.
2.
3.
4.

520

P1024.2048
P -0.98765
P+2235058.4
P72.3456

Assembler Language Programming for IBM z System Servers

Version 1.00

29.12. Summary
Some properties of the instructions discussed in this section are summarized in Table 209.
Mnemonic

Generate preferred signs?

AP
CP
DP
MP
MVO
SP
SRP
TP
ZAP

Y
N
Y
Y
N
Y
Y
N
Y

Possible interruptions
Decimal overflow, decimal data
Decimal overflow, decimal data
Zero divide, decimal data, specification
Decimal data, specification

Decimal overflow, decimal data


Decimal overflow, decimal data

Decimal overflow, decimal data

Table 209. Summary of decimal instruction behavior

Chapter VIII: Zoned and Packed Decimal Data and Operations

521

30. Converting and Formatting Packed Decimal Data

3333333333
333333333333
33
33
33
33
3333
3333
33
33
33
33
333333333333
3333333333

00000000
0000000000
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
0000000000
00000000

The instructions in Table 210 perform useful operations on packed decimal numbers. Along with
PACK and UNPK, they are used to convert data among binary, packed decimal, and character
formats.
Op
4F
EB06
E30E
DE

Mnem
CVB
CVBY
CVBG
ED

Type
RX
RXY
RXY
SS

Instruction
Convert to Binary (32)
Convert to Binary (32)
Convert to Binary (64)
Edit

Op
4E
E326
E32E
DF

Mnem
CVD
CVDY
CVDG
EDMK

Type
RX
RXY
RXY
SS

Instruction
Convert to Decimal (32)
Convert to Decimal (32)
Convert to Decimal (64)
Edit and Mark

Table 210. Instructions used for converting and formatting packed decimal

The only difference between CVB and CVBY, and between CVD and CVDY, is that the
instructions ending with Y have signed 20-bit displacements, while the other two have unsigned
12-bit displacements.

30.1. CVD, CVDY, and CVDG Instructions


The CVD and CVDY instructions convert a twos complement binary number in the rightmost
32 bits of general register R1 to packed decimal format and store it at the 8-byte183 second operand
in memory. To illustrate, suppose c(GR7)=X 00000087 , or + 135 in decimal. If we execute
either of the CVD or CVDY instructions
CVD 7,WorkArea
CVDY 7,WorkArea
- - WorkArea DS
D

Convert to packed decimal at WorkArea


Convert to packed decimal at WorkArea
Result = X000000000000135C

then the packed decimal result at WorkArea will have the value shown.

183

522

On System/360 CPUs, the second operand was required to be aligned on a doubleword boundary; if it wasnt, a
specification exception caused a program interruption. Like many other operand alignment requirements, it was
removed in System/370, but doubleword alignment is still a good practice.
Assembler Language Programming for IBM z System Servers

Version 1.00

Because the second operand field can hold 15 decimal digits, there will always be at least five
high-order zeros in the result. The largest magnitude of the first operand is 2147483648, which
has ten significant digits. When converted to packed decimal, the result is X 000002147483648D .
Similarly, CVDG converts the 64-bit binary integer first operand in GG R 1 to a 16-byte packed
decimal second operand. Thus, if GG8 contains X 4000000000000000 (262),
CVDG 8,WrkArea2
- - WrkArea2 DS
2D

Convert to 16-byte packed decimal


Result=X00000000 00004611 68601842 7387904C

Figure 326. Converting a 64-bit binary integer to packed decimal

then the packed decimal result at WrkArea2 has the value shown.
These three instructions may be thought of as store instructions, because the data moves
from the first operand (a register) to the second (in memory).
Suppose we use CVD to help produce printable decimal values, as in a program that prints a
multi-page listing with a page number on each page. Suppose the halfword integer at PgNum contains the current page number, and we want to put that number (preceded by the characters
Page) into an area named PageNo.
NDigits Equ
LH
CVD
UNPK
OI
- - WorkArea DS
PgNum
DC
PageNo DS
DC
ZonePgN DS

5
Max number of digits in page number
0,PgNum
Get binary value of page number
0,WorkArea
Convert to decimal
ZonePgN,WorkArea Unpack to zoned format
ZonePgN+L ZonePgN-1,C 0 Set zone X F for last digit
XL8
H345
0CL(5+NDigits)
C Page
ZL(NDigits)

Conversion work area


Simulated page number
Length for Page nnnnn
Character form of page number

Figure 327. Using CVD to format page numbers

UNPK transfers the original sign of the packed operand to the zoned operand, which would be
X C in this example. Thus, the OI instruction sets the zone digit in the low-order character of
the field, for its correct EBCDIC representation.
This instruction sequence has a minor defect, however: if the number to be printed has fewer
significant digits than the size of the field, the result will contain leading zeros. A simple loop can
be written to change leading zeros to blanks, but the ED and EDMK instructions provide a more
elegant and powerful solution to this problem. (See Exercises 30.1.4 and 30.1.5.)

Exercises
30.1.1.(1) + In Figure 326, the result at WrkArea2 has many leading zero digits. What is the
minimum number of zero hex digits in the result from a CVDG instruction?
30.1.2.(1) Why can the 8-byte second operand of a CVD instruction hold 15 digits?
30.1.3.(1) Suppose GR1 contains the maximum negative number X 80000000 , and the
instruction
CVD

1,X

is executed. Show the contents of 8-byte area named X.


30.1.4.(2) + Suppose the OI instruction had been omitted in Figure 327. Explain what would
happen when the result at PageNo was printed, given that the page number at PgNum was first
29, then 30, and then 31.
Chapter VIII: Zoned and Packed Decimal Data and Operations

523

30.1.5.(2) + Add a short loop to the instruction sequence in Figure 327 to blank the leading
zeros in the page number.
30.1.6.(2) + For each of these values at Arg,
1.
2.
3.
4.

Arg
Arg
Arg
Arg

DC
DC
DC
DC

F -1
F2147483321
X77777783
C
*

show the packed decimal result at DecVal after executing these instructions:

DecVal

L
1,Arg
CVD 1,DecVal
- - DS
0D,XL8

30.1.7.(3) + For each of these values at Arg2,


1.
2.
3.
4.

Arg2
Arg2
Arg2
Arg2

DC
DC
DC
DC

FD -1
FD9223372036854775807
X B7777783A60D93CA2
CL8 Ghastly!

show the packed decimal result at DecVal2 after executing these instructions:
LG
1,Arg2
CVDG 1,DecVal2
- - DecVal2 DS
0D,XL16
30.1.8.(4) Write a sequence of instructions to simulate the operation of CVD.

30.2. CVB, CVBY, and CVBG Instructions


The CVB and CVBY instructions perform the inverse operation to CVD and CVDY; similarly,
CVBG does the inverse of CVDG. That is, the packed decimal number at the second operand
address is converted to twos complement binary form and the result is placed in general register
R 1. Thus, they can be thought of as load instructions that move data from the second
operand (in memory) to the first (in a register).
To illustrate, suppose we execute this CVB instruction:
CVB 6,PackNum
- - PackNum DC
PL8 -135

Result in GR6 = X FFFFFF79


X000000000000135D

The result in GR6 is X F F F F F F 7 9 , with value 135.


Similarly, if we execute this CVBG instruction
CVBG 9,PackNum2
Convert to 64 bits in GG9
- - PackNum2 DC
PL16 -123456789012345
The result in GG9 is X FFFF8FB779F22087 .
All three instructions are subject to two possible program interruption conditions.
If the second operand field does not contain valid decimal data, a decimal data exception
occurs and the Interruption Code is set to 7.
If the value of the decimal operand is too large to fit in the first operand register, a fixed-point
divide exception occurs and the IC is set to 9.

524

Assembler Language Programming for IBM z System Servers

Version 1.00

This situation is handled differently for CVB/CVBY and CVBG.

For CVB and CVBY, the low-order 32 bits of the twos complement binary result are
placed into register R1.

For CVBG, the operation is suppressed, and register R1 is unchanged.

Suppose an 80-byte record contains numeric data, and we must convert a number on the record
from character form to binary and place the result in GR5. Assume the characters are rightjustified in an 8-byte field of the record at offset DOff.
DLen
DOff

DWork
Record

Equ
Equ
PACK
CVB
- - DS
DC

8
Length of data field
72
Offset of start of field
DWork,Record+DOff(DLen) Pack data to decimal
5,DWork
Convert to binary value in GR5
XL8
CL75 , C45678

Conversion area
80-byte input data record

Figure 328. Converting decimal characters to binary

This technique is adequate for unsigned numbers, or for zoned decimal data in which the sign is
over-punched in the last digit column of the input field. Greater care is needed when the digits
may be preceded by a sign. (See Exercise 30.2.6.)

Exercises
30.2.1.(1) + What will happen if a CVB instruction specifies a second operand containing
X 000002147483648C ?
30.2.2.(2) + Suppose we execute the following two instructions. What will happen, and what
results will be found at DWork and in GR0?

DWork
Data

PACK
CVB
- - DS
DC

DWork,Data
0,DWork
D
C123

30.2.3.(2) + What will happen in the instruction sequence of Exercise 30.2.2 if Data is defined
by
Data

DC

CL20123 ?

30.2.4.(2) + What will happen in the instruction sequence of Exercise 30.2.2 if Data contains
four blanks, such as
Data

DC

CL4 ?

30.2.5.(4) If the binary result of a CVB instruction is too large, an interruption occurs after the
low-order 32 bits of the result are put into the first operand register. This means that a certain
amount of internal arithmetic apparently had to be performed to a precision of more than 32
bits; what is the minimum number of internal bits required?
30.2.6.(3) + Suppose the datum in the 8-column field in Figure 328 might be preceded by an
optional sign character, C + or C . Modify the instruction sequence to place the correctly
signed binary result into GR5. (Assume that the number is well-formed: it contains no extra
signs, no embedded or trailing blanks, no invalid characters, etc.)
30.2.7.(1) Why do you think the designers of the CVB instruction chose to place the low-order
32 bits of the result into general register R1 even when the fixed-point divide exception indicates
that the result is not correct?

Chapter VIII: Zoned and Packed Decimal Data and Operations

525

30.2.8.(2) Show the resulting value in GR0 for each of these data values at PackData after executing this instruction:
CVB
1.
2.
3.
4.

PackData
PackData
PackData
PackData

0,PackData
DC
DC
DC
DC

XL8 FFFFFFFC
XL8743915506D
XL8 AFFFFFFFFFFFFFFFD
XL8999C

30.2.9.(3) Write a sequence of instructions to simulate the operation of CVB.


30.2.10.(3) Repeat Exercise 30.2.6, but make no assumptions about correctly formed input data.
If an invalid character is found, branch to BadChar with its address in GR1.

30.3. Editing Overview


The ED and EDMK instructions are complex. They are related to UNPK: they convert the
packed decimal second operand to character form in the first operand. However, that is about all
that is similar between UNPK and the editing instructions! Editing can also suppress leading
zeros, insert special characters, and do other things that produce readable results.
Both editing instructions are single-length SS-type instructions, as shown in Table 211.
opcode

B1

D1

B2

D2

Table 211. Format of the E D and E D M K instructions

The length field of these instructions refers only to the length of the first, or pattern, operand
(unlike other single-length SS-type instructions in which the lengths of the two operands are considered to be the same). The number of bytes taken from the second operand depends on the
contents of both operands.
Editing converts the packed decimal second operand to character (zoned) form under the control
of a pattern provided by the first operand, as sketched in Figure 329. The bytes of the pattern
provide a picture showing what the edited result should look like: each byte in the pattern represents one character of the result.

d d d d d d d s Packed decimal operand

Edit operation


Pattern, replaced by
Ch Ch Ch Ch Ch Ch Ch numeric and other
characters
Figure 329. Sketch of an editing operation

This picture is created from four types of information that tell the instruction how to convert the
packed decimal second operand into zoned characters. Each byte in a pattern contains one of
these five types of information:
1. a Digit Selector (DS) character X 20 ;
2. a Digit Selector and Significance Start (SS) character X 21 ;
3. a Field Separator (FS) character X 22 ;
4. a Message Character (MC), which may have any value other than X 20 , X 21 , or X 22 .

526

Assembler Language Programming for IBM z System Servers

Version 1.00

5. a Fill Character (FC), which may have any value.


Each byte in a pattern is called a Pattern Character (PC). 184
The editing process scans the pattern once from left to right, and takes action depending on
which of the five kinds of pattern byte is encountered, and
what has happened previously.
To remember what happened previously, the CPU uses a single internal bit called the Significance Indicator (SI).185
The Significance Indicator is not a part of any register or of the PSW, and its value is not accessible to the program except as it influences the progress of an editing operation. It is set OFF at
the start of an editing operation, and then it is turned on and off by events that occur during the
edit. Its final setting may influence the Condition Code setting when the edit operation completes.
Visualizing patterns is difficult because the three non-message characters (with values X 20 ,
X 21 , and X 22 ) have no printable representation. If we choose a printable character to represent each of them, then we might confuse them with ordinary message characters, because any
printable character in a pattern is normally a message character!
We will use this convention: the lower-case letters d, s, and f represent the Digit Selector (DS),
Digit Selector and Significance Start (SS), and Field Separator (FS) characters respectively. As
before, well use to represent a blank space.
Thus, we might represent the pattern
X402020202120C3D922202120

by

C dddsdCRfdsd

Figure 330. Representation of an editing pattern

The first byte in a pattern is the Fill Character (FC). The CPU saves a copy of this first pattern
character for the duration of the editing operation. It is used in various situations to replace other
pattern characters. A common choice for a fill character is a blank, as in Figure 330.
To summarize the features described thus far:
1. The first operand is a pattern containing the Fill Character, and one or more Digit Selector,
Digit Selector and Significance Start, Field Separator, and Message Characters.
2. The second operand is one or more packed decimal numbers to be converted to zoned
format in a manner controlled by (and pictured by) the pattern.
3. The result replaces (overwrites) the pattern with Message Characters, Fill Characters, and
zoned decimal digits. Thus the pattern is usually copied first to an editing area.

Exercises
30.3.1.(2) + For each of the following patterns, identify (1) the Fill Character, (2) Digit Selectors, (3) Significance Start and Digit Selectors, (4) Field Separators, and (5) Message Characters.
1.
2.
3.
4.

X40202020202120
X 5 C20202021204B2020
X 5 C4020202021202240E396A381937E20202021204B2020
C Hello, World!

30.3.2.(2) An early programming convention represented the DS, SS, and FS characters by , (,
and ) respectively. Rewrite the pattern of Figure 330 using this convention, and assess its readability.

184
185

z System has had a PC since 1966.


In some older books and manuals, it was called the S-Trigger.
Chapter VIII: Zoned and Packed Decimal Data and Operations

527

30.4. Simple Examples of Editing


We begin by illustrating the simplest forms of the editing process with a plausible example, and
then give some more general rules. While the overall operation of ED and EDMK will turn out
to be fairly straightforward, it may be difficult initially to understand why and how things are
happening.
Suppose we are printing a report having titles and page numbers on each page, and we know
there will be at most 900 pages in a report. This means that the two-byte packed decimal number
at PgNo can hold the page number without overflow. We could use UNPK to produce a printable
character string of the form Page nnn with these instructions.

PgNo
TtlP
TtlPgN

UNPK
OI
- - DC
DC
DS

TtlPgN(3),PgNo(2) Convert to zoned format


TtlPgN+2,C 0
Set correct zone on last digit
PL2 7
C Page
ZL3

3-digit page number 007+


Start of page-number string
Zoned page number

Figure 331. Convert a packed decimal integer to characters using U N P K

This has a defect: small page numbers will have leading zeros, as in Page 007. We can use the
ED instruction to both unpack the digits and suppress the leading zeros, as shown in Figure 332:

PgNo
TtlP
TtlPgN
PgNPat

MVC TtlPgN(4),PgNPat
ED
TtlPgN(4),PgNo
- - DC
PL2 7
DC
C Page
DS
CL4
DC
C , 3 X 2 0

Move a copy of pattern


Convert to zoned format
Page number 007+
Start of page-number string
Edited result = C 7
Pattern = C ddd

Figure 332. Convert a packed decimal integer to characters using E D

Because we will want to print the page number more than once, we must use the MVC instruction to copy the unmodified pattern from PgNPat each time, where it will be replaced by the
edited result.
The ED instruction converts the packed operand at PgNo as follows:
1. The first character of the pattern (a blank) is saved as the Fill Character, and the Significance
Indicator is set OFF.
2. When the first Digit Selector character is encountered, the first digit of the second operand is
examined: if it is zero (as in this case) and the Significance Indicator is OFF, the Fill Character replaces the pattern character.
3. The next pattern character and the next source digit are examined; because no significant
(nonzero) digits have been encountered, the Fill Character again replaces the pattern character.
4. Finally, the last pattern character and second operand digit are examined. Because the latter is
nonzero, it is converted to zoned format (X F7 ), and the zoned result replaces the pattern
character. The Significance Indicator is set ON to show that a significant digit has been
found.
The result C 7 contains three blanks: the first is the original Fill Character, and the other two
are the suppressed leading zeros.
Now, suppose the page number at PgNo is 700+ instead of 007+. When the ED instruction is
executed, the first digit examined is nonzero. The Significance Indicator will be set ON, and

528

Assembler Language Programming for IBM z System Servers

Version 1.00

X F7 will replace the first Digit Selector character. When the second and third pattern characters
are examined, the status of the Significance Indicator shows that the zero digits from the second
operand are now significant. They are therefore zoned, and replace the pattern characters. The
result will be Page 700 as desired.
From this simple example, we infer some simple rules about how editing works:
1. If the pattern character is a Digit Selector, the next decimal digit is taken from the second
operand.
2. If the Significance Indicator is ON, go to step 5.
3. If the SI is OFF, examine the decimal digit. If it is not zero, set the SI ON and go to step 5.
4. If the SI is OFF and the decimal digit is zero, replace the pattern character (DS) by the Fill
Character, and go to step 6.
5. Attach a zone to the decimal digit, and replace the (DS) pattern character with the result.
6. Step to the next pattern character and decimal digit, and repeat until the pattern is exhausted.
This description omits some important considerations, but it shows the basic features of the
editing process. The number of decimal digits examined from the second operand is exactly the
number of selector characters (DS and SS) in the pattern.
Suppose you now want to print any nonnegative 3-digit decimal number using the technique
shown in Figure 332. Everything works unless you try to print 000+: in the figure we assumed
that page numbers start at 1, not at zero, so we didnt have to worry about this case. From the
above description it is clear that using the pattern X 40202020 to edit 000+ gives an all-blank
result! If we actually wanted to blank out a zero field, fine: we just discovered how to do it (by
accident).
You will normally want to print at least one zero character in such cases. The Digit Selector and
Significance Start (SS) character is used to force digit significance to begin.
The SS character works exactly like the DS character, except that it also turns the Significance
Indicator ON if it was not already on. However, the Significance Indicator is set ON after the
source digit has been examined, so significant digits will start (if they havent already) in the next
digit position! Thus, the SS character actually indicates not the start of significance, but more
correctly the end of insignificance, the rightmost limit of zero suppression.
Step 4 of the preceding simple rules can be revised as follows:
4.

If the SI is OFF and the decimal digit is zero, replace the pattern character (DS or SS) by
the Fill Character. Set the SI ON if the pattern character was SS, and go to step 6.

Suppose you need to print the value of the nonnegative binary integer fullword at Num. If the
value is zero, a single 0 digit should be printed. Since a fullword integer can be at most 10 decimal
digits long, we might plan to use an edit pattern with 10 digit selectors. With a fill character, the
pattern would be 11 bytes long.
However, after converting the binary value to packed decimal, we find that the 8-byte decimal
field always contains a minimum of 5 high-order zero digits that we want to ignore. We can
adjust the second operand address to skip four of the leading zeros, but because the digits taken
by the editing instruction always start with the leftmost digit of the second operand, the pattern
must contain 11 digit selectors to account for the remaining leading zero.

Chapter VIII: Zoned and Packed Decimal Data and Operations

529

L
0,Num
Get nonnegative number
CVD 0,WorkArea
Convert to packed decimal
MVC LineX,Pat
Move pattern to print line
ED
LineX,WorkArea+2 Start edit with high-order digits
- - Num
DC
F1234567890
Number to be printed
WorkArea DS
D
8-byte work area for CVD
Pat
DC
C , 9 X 2 0 , X2120
Pattern = C dddddddddsd
Line
DC
C Num=
Start of printable text
LineX
DS
CL12
Edited result here
Figure 333. Converting a 32-bit binary integer to characters

The pattern at Pat contains 11 digit selector bytes; the next-to-last also starts significance, so the
result will have at least one significant digit. The implied length (12) of the symbol LineX supplies
the length byte in the MVC and ED instructions.

Exercises
30.4.1.(2) + In Figure 333, what result will appear at LineX if the pattern at Pat contains only
10 digit selectors?
30.4.2.(2) Suppose a pattern is L bytes long. What is the maximum number of bytes that might
be taken from the second operand? The minimum?
30.4.3.(2) + Suppose we execute these instructions for each of the three indicated values of the
pattern. What results will be generated?

Work8
Output

MVC Output,Pattern
ED
Output,Work8+2
- - DC
X000000000729413C
DS
CL12

The patterns are defined by


1. Pattern DC
2. Pattern DC
3. Pattern DC

C , 1 1X 2 0
C * , X21,10X 2 0
C * , 3 X 2 0 , X 2 1 , 7X 2 0

30.4.4.(2) In Exercise 30.4.3, what would have been generated if the second operand of the ED
instruction was Work8+1 instead?
30.4.5.(1) What will result in Figure 333 if c(Num) = 0?
30.4.6.(2) + Which DS characters in the pattern in Figure 333 will always be replaced by the
Fill Character?
30.4.7.(2) + What will happen if the length byte of an ED instruction contains 0 (the pattern is
1 byte long), and the pattern byte is not a DS or SS character, and the operand 2 address is
invalid? What will happen if the pattern is longer than one byte but still contains no digit selectors?

530

Assembler Language Programming for IBM z System Servers

Version 1.00

30.5. Single-Field Editing


Now that we have a general idea of how editing works, we can give a more detailed description.
Well investigate the function of the Field Separator (FS) pattern character in Section 30.7.
Each step of an edit operation always gives one of three possible results:
1. a source digit from the second operand is zoned and stored into the pattern in place of a DS
or SS character; or,
2. the Fill Character replaces the pattern character; or,
3. the pattern character is left unchanged.
Which of these three results occurs depends on the state of the Significance Indicator and the type
of pattern character. If the pattern character is a Digit Selector of either type, the result also
depends on whether the source digit is zero.
Message Characters in the pattern are either left unchanged (if the SI is ON) or replaced by the
Fill Character (if the SI is OFF). They can be thought of as being significant or not
significant Message Characters.
Suppose we want to print the nonnegative fullword integer at Num as in Figure 333 on page 530,
and we want commas to separate every group of three digits (counting from the right). Thus, the
binary integer 1234567890 should be edited to form the characters 1,234,567,890. This is done
just as before, except that the pattern is now C dd,ddd,ddd,dsd . (Remember from Section 1
on page 15 that we use the character to represent a blank.)
L
0,Num
Get number to be printed
CVD 0,WorkArea
Convert to packed decimal
MVC LineX,Pat
Move pattern to print line
ED
LineX,WorkArea+2 Edit 11 decimal digits
- - Num
DC
F1234567890
Number to be printed
WorkArea DS
XL8
Work area for CVD
Pat
DC
C , 3 X20206B20 , X2120
X 6B is a comma
Line
DC
C Num=
Start of printable text
LineX
DS
CL(Line-Pat)
Edited result here
Figure 334. Editing a binary integer with separating commas

The Message Character comma was written in its hexadecimal form, X 6B .


Until a nonzero source digit (or the SS pattern character) is encountered, the SI will be OFF, and
all pattern characters including the commas will be replaced by the Fill Character, a blank. Thus,
if the value at Num is 4095, the first two commas in the pattern will be suppressed, leaving 4,095
as the nonblank part of the result.

30.5.1. Editing Negative Values


We have deferred considering the sign of the second operand, assuming that it was always nonnegative. When the sign code at the end of the packed decimal operand is encountered, the Significance Indicator is set OFF if the sign code is + . This can be used to fill characters following
the last digit.
For example, suppose you must print the balance in a charge-card account. If the balance is
negative, indicating that the customer has a credit balance, you should print the word CREDIT
following the amount. Let the packed decimal number at Balance represent the account balance
in cents, so a decimal point must precede the last two digits of the edited result.

Chapter VIII: Zoned and Packed Decimal Data and Operations

531

MVC LinB,Pat2
Move pattern to print line
ED
LinB,Balance
Edit to printable form
- - Balance DC
P -0012345
Credit balance of $123.45
Pat2
DC
C , X20206B2020214B2020 , C CREDIT Pattern
* Note: PAT2 = C dd,dds.ddCREDIT
PatX
Equ *
Used for defining length of Pat2
Line
DC
C Your account balance is
LinB
DS
CL(PatX-Pat2)
Space for edited result
Figure 335. Editing a signed number

When the sign code at the end of the second operand is encountered, the SI will be ON because
nonzero digits were found in the second operand. Thus, the Message Characters following the last
DS in the pattern are significant, and they will not be replaced by the Fill Character. Using to
represent a blank, the result would be
YourAccountBalanceis123.45CREDIT
Now, suppose the customers balance is 0032109 + , where the + sign code indicates he owes that
amount: the word CREDIT should not be printed. In this case, the same instructions would
produce
YourAccountBalanceis321.09
Finally, suppose the customers balance is 0000002 , indicating he has a credit of two cents. The
SS character in the pattern immediately preceding the decimal point (X 4B ) sets the SI ON, so
the decimal point and the two following digits remain in the edited line. The printed result would
then be
YourAccountBalanceis.02CREDIT

30.5.2. Protecting High-Order Fields


When printing negotiable items like paychecks, it is important to protect the high-order portion
of the field. If we changed the contents of Line to read Your pay is, an enterprising programmer could run his paycheck through his own printer and insert some extra significant digits
to the left of the decimal point, perhaps to make it look like
Yourpayis$4,960.02CREDIT
This is usually prevented by using a nonblank Fill Character such as * to protect the edited result.

PayAmt
PayPay
Line
LPat

MVC LPat,PayPat
Move pattern to line
ED
LPat,PayAmt
Edit to protected print form
- - DC
P0098765
Amount to print = 987.65
DC
C * , X20206B2020214B2020
C *dd,dds.dd
DC
C Dollars
Start of Amount area
DS
CL(Line-PayPat)
Result = C ****987.65

Figure 336. Using field protection with E D

and the printed result will be Dollars****987.65.

Exercises
30.5.1.(1) + Which Message Characters set the Significance Indicator ON? Which ones set it
OFF?
30.5.2.(1) + In Figure 335, how would you modify the pattern to ensure that at least one digit
appears before the decimal point?

532

Assembler Language Programming for IBM z System Servers

Version 1.00

30.5.3.(2) If a packed decimal number is P bytes long, how many Digit Selector and/or Significance Start characters should be in the edit pattern used to format it?
30.5.4.(4) Suppose a packed decimal operand is P bytes long, but you only want to edit N
digits. Determine
1. the number of d and s selectors that must be in the pattern, and
2. the offset D from the start of the packed decimal operand that should be specified in the
second operand of the ED instruction.
30.5.5.(2) What will result in Figure 334 on page 531 if c(Num) = 0? If c(Num) = 512, will
there be a leading comma in the result? Explain.

30.6. The EDMK Instruction


It is often useful to know where the most significant digit of an edited result occurs. For example,
a minus sign customarily precedes negative results in integer arithmetic, and a currency symbol ($)
might be placed immediately before the first significant digit of a dollar amount. The EDMK
instruction may put the address of the first significant digit into general register 1, and then only if
the SI is OFF when the first significant digit is stored into the pattern. If the first significant digit
is stored after the first SS character in the patternthat is, if significance is forced register 1 will
remain unchanged. (The flow diagram in Figure 342 on page 537 may help.)
The example in Figure 337 shows one way to insert a currency symbol, but it is incomplete:

PayAmt
PayPat
Line
LPat

MVC
EDMK
AHI
MVI
- - DC
DC
DC
DS

LPat,PayPat
LPat,PayAmt
1,-1
0(1),C $

Move pattern to Line


Edit and Mark result
Decrement GR1 (move left one byte)
Put $ sign before first digit

P0098765
Amount to print = $987.65
C , X20206B2020214B2020
C dd,dds.dd
C Pay Exactly
Precedes the Amount: area
CL(Line-PayPat)
Result = C $987.65

Figure 337. Edited result with a floating currency symbol

This example will not work the way we want if the packed decimal number at PayAmt is 99 or
less, because the pattern contains a Significance Start character just before the decimal point
which will force significance of the last three pattern characters. Because GR1 would then be
unchanged by the EDMK, we must preset its contents to the address of the byte following the
Significance Start pattern character, which will be the first significant result character if significance
is forced.

PayAmt
PayPat
Line
LPat

MVC
LA
EDMK
AHI
MVI
- - DC
DC
DC
DS

LPat,PayPat
1,LPat+7
LPat,PayAmt
1,-1
0(1),C $

Move pattern to print area


Point to 1st significant pat n char
Edit and mark result
Move to left of 1st significant char
Put the $ in the result

P0000002
Two cents pay for all this work?
C , X20206B2020214B2020
Same pattern
C Pay Exactly
Start of print line
CL(Line-PayPat)
Result = C $.02

Figure 338. Edited result with a properly placed floating currency symbol

If we want to print edited integer results with leading signs, we must know which of the + and
characters to place before the first significant digit. This can be determined by testing the
Condition Code at the end of the edit:

Chapter VIII: Zoned and Packed Decimal Data and Operations

533

CC
0
1
2

Meaning
All source digits 0, or no digit selectors in pattern
Nonzero source digits, and SI is ON (result < 0)
Nonzero source digits, and SI is OFF (result > 0)

Table 212. CC settings after ED, E D M K

The CC can be relied on to give a valid sign indication only if the last source byte taken from the
second operand contained a sign code in its right digit.
Suppose we now revise Figure 334 on page 531 to allow values of either sign, with the added
requirement that zero values are to be printed with no sign character. (The PrintLin macro is
described in Appendix B: Simple I/O Macros on page 1001.)
L
1,Num
Get number to be printed
CVD 1,WorkArea
Convert to packed decimal
MVC LineX,Pattern
Move pattern to print line
LA
1,LineX+L LineX-1 Point to possibly forced digit
EDMK LineX,WorkArea+2 Edit and mark up to 11 digits
JZ
Print
If zero, print immediately
BCTR 1,0
Adjust to preceding byte
MVI 0(1),C +
Assume result was +
JP
Print
Branch if the guess was right
MVI 0(1),C -
Negative result, set - sign
Print
PrintLin Line,(L Line+L LineX) Print result
- - Num
DC
F -1234567890
Number to be printed
WorkArea DS
D
Doubleword work area for cvd
Pattern DC
C , 3 X20206B20 , X2120
Pattern
Line
DC
C Num =
Start of printed output
LineX
DS
CL(Line-Pattern) Result = C -1,234,567,890
Figure 339. Integer value with optional sign and separating commas

We use BCTR 1,0 here instead of AHI 1, 1 to decrement the address in GR R 1 because AHI
changes the Condition Code.

Exercises
30.6.1.(3) Packed decimal numbers can represent minus zero, but the CC setting after an
EDMK instruction only indicates that all source digits are zero. Write an instruction sequence
using EDMK to display a correctly signed 4-byte packed decimal number at PackVal even if its
value is zero.
30.6.2.(2) +
What CC setting will result from editing the packed decimal operand 000 with the pattern
X C1212020 ?

30.7. Editing Multiple Fields (*)


More than one edited result can be produced by a single execution of an ED or EDMK instruction. The fields of the result are separated in the pattern by the Field Separator (FS) character,
X 22 . The FS character (a) resets the zero-digits test that will be used to determine the final CC
setting (essentially, it resets the CC to 0), (b) sets the SI OFF, and (c) is replaced by the Fill
Character. Thus, each field of the pattern can be considered separately from the others; however,
only the last field can be marked by an EDMK instruction, since the address in general register
1 will refer to the last significant digit stored while the SI was OFF.

534

Assembler Language Programming for IBM z System Servers

Version 1.00

To illustrate, suppose there are three packed decimal numbers in successive fields named Hours,
Rate, and PayAmt to be edited into a single print line.

Hours
Rate
PayAmt
Pat

Line
LPat

MVC LPat,Pat
Move pattern to line
ED
LPat,Hours
Edit all 3 fields at once
- - DC
PL2 3 5 . 5
Hours worked, in tenths
DC
PL3 7 . 5 0
Pay rate in dollars/hour
DC
PL426625
Pay amount = $266.25
DC
C , X20204B20
C dd.d
DC
X 2 2 , X2020214B2020
C fdds.dd
DC
X 2 2 , X20202020214B2020 C fdddds.dd
DC
C Hours Rate
Pay
title line
DS
CL(Line-Pat)
Space for edited pattern

Figure 340. Editing multiple values

And the two lines would then contain


Hours Rate
35.5 7.50

Pay
266.75

While we would like to use EDMK here to insert a $ character before the first significant digit
of the Pay field of the result, this may not work. Suppose the amount to be paid is 99 cents or
less. Then the address in general register 1 would remain at the address of the first significant digit
of the last field in which significance was not forced, which would be the 3 in the Rate field
of the result!
Even if we had preset register 1 to the address of the decimal point in the last field of the pattern,
we could still find ourselves placing the $ sign in the wrong field. Thus, it is rare to use EDMK in
editing multiple fields with floating currency symbols unless you can guarantee that no such problems can arise.

Exercises
30.7.1.(2) + Suppose a pattern contains N digit selectors. What are the maximum and
minimum number of bytes that might be taken from the second operand?
30.7.2.(3) Suppose a Field Separator character is encountered in an edit pattern when the next
second operand digit to be examined is in the right half of a source byte. Will the next digit
selector in the pattern after the FS cause that source digit to be examined, or will the FS
pattern character cause the next source digit to come from the left half of the following second
operand byte? (You may want to consult the z/Architecture Principles of Operation!)
30.7.3.(2) + Suppose you use EDMK to edit a multiple-field pattern. Under what conditions
can you assume that GR1 refers to a character in the last field only?

30.8. Summary Comments on Editing (*)


Before we give a complete summary of the actions of the ED and EDMK instructions, there are
two minor items to consider:
1. In the source bytes brought from the second operand, only valid decimal digits from 0 to 9
may appear in the left digit of a source byte. If a sign code appears in the left half of a source
byte, a program interruption will occur, and the Interruption Code will be set to 7. The contents of the result field (and the contents of general register 1 if the instruction is EDMK) is
unpredictable.
2. There is no point in trying to overlap the first and second operand fields in an editing operation, because the results are quite unpredictable.

Chapter VIII: Zoned and Packed Decimal Data and Operations

535

We will summarize the action of the editing instructions in three different ways:
1. Table 213 shows what happens for each of the four different types of pattern characters.
2. In a set of logical relations in Figure 341.
3. In a flow diagram in Figure 342.
The abbreviations used are the same as previously introduced, now including ZD (Zoned Digit)
and PC (Pattern Character).
The actions caused by each of the four types of pattern character is described in Table 213, where
SI=0 means OFF and SI=1 means ON.
Get
Source
Digit?

SI

Source
Digit

Result

Set
SI

Sign code in right


digit?

X 20 (DS)

Yes

1
0
0

Any
Nonzero
Zero

ZD
ZD
Fill Char

1
1
0

If + , set SI OFF;
otherwise, leave it
unchanged

X 21 (SS)

Yes

1
0
0

Any
Nonzero
Zero

ZD
ZD
Fill Char

1
1
1

If + , set SI OFF;
otherwise, leave it
unchanged

X 22 (FS)

No

Fill Char

No source byte is
examined

Other (MC)

No

0
1

Fill Char
MC

0
1

No source byte is
examined

Fill Character
(FC)

No

N/A

Fill Char

N/A

Pattern Character (PC)

Table 213. ED and E D M K treatment of pattern characters

Using the following logical symbols to represent logical operators:


& AND,

NOT

OR,

we can write a simple set of logical equations that describe the action of the editing process in
this compact form:
SI & MC MC
FS | (( SI) & MC) FC
(DS | SS) & SD=0 & SI FC (insignificant zero)
((DS | SS) & SI) | SD=/0 ZD (significant digit)
Figure 341. Logical-operation description of the editing process

This compact notation does not describe the setting and resetting of the Significance Indicator,
but those actions were discussed in detail earlier.
A flow diagram of the editing process is given in Figure 342, where SD refers to a source digit
from the second operand.

536

Assembler Language Programming for IBM z System Servers

Version 1.00

Set SI OFF, Get new 


1st PC FC
patt. char

on DS,SS MC
on

SD?SI?PC? SI?

09

AF
off
FS
off




SI OFF FC PC





Prog.

Int.,SD? PC? SI ON

IC=7. AF 0 SS


19
DS

SI ON
FC PC

yes

EDMK? A(PC) R1

no





no
ZD PC Sign code in Done?

source byte?  no

yes
+






SI OFF skip it Set CC

Figure 342. ED and E D M K operation

Chapter VIII: Zoned and Packed Decimal Data and Operations

537

538

Assembler Language Programming for IBM z System Servers

Version 1.00

Chapter IX: Floating-Point Data and Operations

IIIIIIIIII
IIIIIIIIII
II
II
II
II
II
II
II
II
IIIIIIIIII
IIIIIIIIII

XX
XX
XX
XX
XX
XX
XX
XX
XX XX
XXXX
XXXX
XX XX
XX
XX
XX
XX
XX
XX
XX
XX

The sections of this chapter discuss floating-point number representations and their uses.
Section 31 introduces the basic concepts of scaled fixed-point and floating-point data, including
the hexadecimal, binary, and decimal floating-point data types supported by z System. Then,
it describes the floating-point registers and some basic instructions for moving floating-point
operands.
Section 32 describes some general principles of floating-point arithmetic.
Section 33 examines the hexadecimal floating-point representation of numbers, and describes
hexadecimal arithmetic and instructions.
Section 34 discusses the binary floating-point representation and instructions for doing binary
floating-point arithmetic.
Section 35 discusses the decimal floating-point representation and instructions for doing
decimal floating-point arithmetic.
Section 36 summarizes the three z System floating-point representations, and describes some
important differences between mathematical real arithmetic and floating-point arithmetic.

Chapter IX: Floating-Point Data and Operations

539

31. Floating-Point Number Representation

3333333333
11
333333333333
111
33
33
1111
33
11
33
11
3333
11
3333
11
33
11
33
11
33
33
11
333333333333 1111111111
3333333333 1111111111

Why was floating-point arithmetic invented? How did programmers handle data with both integer
and fraction parts when only fixed-point binary arithmetic was available? Before we investigate
floating-point numbers and arithmetic, a bit of background may help.

31.1. Scaled Fixed-Point Arithmetic


Up to now, most of our examples involving arithmetic have used only integer values, as illustrated
in Figure 343.
 data size

integer value
.


radix point
Figure 343. A data item containing an integer value

As we saw in Section 29.10 on page 513, packed decimal arithmetic may frequently need to
manipulate values with both integer and fraction parts, as illustrated in Figure 344, where the
decimal point is implied (not actually present).
 field size

integer part . fraction part


radix point
Figure 344. A packed decimal field containing integer and fraction parts

With fixed-point binary instructions, you can use numbers with fractional parts by assuming that
a number is part integer and part fraction, with the position of the implicit radix point defined to
be somewhere inside the number, as in Figure 345.

540

Assembler Language Programming for IBM z System Servers

Version 1.00

 word size

integer part . fraction part


radix point
Figure 345. A binary word containing integer and fraction parts

We call these quantities fixed-point data. You can write instructions that take account of this
scaling (the position of the radix point) when doing arithmetic with such quantities. For example,
when we process financial data, amounts are often stated in dollars and cents, Euros and cents,
and the like: the assumed decimal point lies to the left of the two rightmost decimal digits.
Weve seen how to convert integers between representations in different bases and to printable
values; before examining arithmetic with integer-fraction values, well see how to convert fractions
between representations.

31.2. Converting Fractions


In 2.3. Converting Integers from One Base to Another (*) on page 21 we converted integers
from one base to another by successive divisions, generating digits in the new base from least to
most significant. For fractions, we do the reverse, using successive multiplications to generate digits
from most to least significant.
Let the string of digits
0 . d1 d2 d3 ... dn
be the representation in some base D of the fraction X: that is,
X = SUM(k=1 to n) (dk D k)
= d1D 1 + d2D 2 + ... + dnD n.
For example, the decimal fraction 0.1234 is
0 . 110 1 + 210 2 + 310 3 + 410 4
Now, suppose we want to convert X from its known representation in base D to its representation in a new base B: that is,
X = SUM(k=1 to m) (bk B k)
= b1B 1 + b2B 2 + ... + bm B m.
We know the old and new bases D and B, and the digits d k of the old representation. To find the
digits b k in the new representation, we do the following:
1. Multiply X by the new base B. Save the fraction part of the result, and the integer part is b 1.
This can be seen by writing the product as
B X = b1 + [ b2B 1 + b3B 2 + ... + bm B( m + 1 ) ]
2. Multiply the saved fraction part (the term in square brackets) by X again, and save the new
fraction part. The generated integer part will be the second digit b 2.
3. Repeat the process until you have generated as many digits as you need, or until the saved
fraction part is zero. Note that the digits are produced in order of decreasing significance.
There is no automatic terminating condition for fractions as for integers, because there are finitelength fractions in one base which do not have finite representations in another; the decimal representation of the fraction 1/3 is a well-known example. But if the saved fraction part becomes
zero, the conversion terminates and the representation in the new base has a finite number of
digits. Here are some examples.
1. Give the base two representation of the decimal fraction 0.375.

Chapter IX: Floating-Point Data and Operations

541

.375
2
0.750
b1=0

.75
2
1.50
b2=1

.5
2
1.0
b3=1

Since the fraction part after three multiplications is zero, the binary representation of 0.375
terminates, and we know that 0.375 (base 10) = 0.011 (base 2).
2. Give the base 16 representation of the decimal fraction 0.1.
0.1
16
1.6
b1=1

0.6
16
9.6
b2=9

0.6
16
9.6
b3=9

In this case, repeated multiplication will continue to generate 9 digits, and the base 16 representation will not terminate. We can therefore write
0.1 (base 10) = 0.19999... (base 16) = 0.19 (base 16) = X0.19 ,
where the underscore indicates that the underscored digit (or group of digits) should be
repeated indefinitely.186 Thus, 2/3 (base 10) = 0.6 (base 10), 0.1 (base 3) = 0.3 (base 10),
and 0.1 (base 10) = 0.00011 (base 2).
When we represent such numbers in a computer we must settle on enough digits to represent
the number. This means it is very likely there will be some necessary inaccuracy in the result.
3. Give the decimal representation of X 0 . FA . First, we note that
X 0 . FA = 15/16+10/256 = 250/256 = 0.9765625
Now, we do the conversion arithmetic in base 16; if we do it in decimal we must convert the
fraction to base 10 first, which is the object of the conversion!
0.FA
A
A
9.C4
b1=9
b7=5

0.C4
A
A
7.A8
b2=7

0.A8
A
A
6.90
b3=6

0.9
A

0.A

0.4

0.8

5.A
b4=5

6.4
b5=6

2.8
b6=2

5.0

so that 0.FA (base 16) = 0.9765625 (base 10), as expected. Converting between decimal
and hexadecimal fractions like these can sometimes be done using the tables in the Appendix
at Conversion Tables for Hexadecimal Fractions on page 997

Exercises
31.2.1.(3) + Perform the indicated conversions. For number bases greater than 10, use the
hexadecimal digits A, B, C... corresponding to 10, 11, 12....
1.
2.
3.
4.

Convert
Convert
Convert
Convert

0.1 (base 10) to bases 2 and 16.


0.3142 (base 10) to bases 3 and 14.
0.BBBBB... (base 16) to bases 10 and 15.
3.6 (base 8) to bases 10 and 16.

31.2.2.(2) + Convert the following fractions from base 16 to base 10, giving the result to at most
7 decimal digits:
1. X 0 . DEFACE
2. X 0 . 5

186

542

The more common mathematical notation for repeated groups of digits is an over-bar (called a vinculum), but the
software formatting these notes insists on unnatural acts to print over-bars.
Assembler Language Programming for IBM z System Servers

Version 1.00

3. X 0 . C2854
4. X0.333333
5. X 0 . BEEF
31.2.3.(2) Convert these decimal fractions to hexadecimal, giving at most six significant digits:
1.
2.
3.
4.

0.063725
0.0001
0.987603
0.000005

31.2.4.(1) What is the binary representation of the fraction 1/3?


31.2.5.(2) + Convert the decimal fractions 0.1 through 0.9 in increments of 0.1 to base-8 (octal)
format.

31.3. Mixed Integer-Fraction Representation


Early computers provided only integer representations and arithmetic, so values with integer and
fraction parts were approximated by scaled fixed-point numbers. Programmers had to keep track
of the radix point for each variable, and programmed shifts or other corrections for re-scaling after
each operation.
For example, Suppose an importer has received a shipment valued at $11749.49, and import tax
must be paid at a rate of 5.147 percent. Your job is to calculate the amount of tax to be paid.
(Remember, government auditors will be verifying your work!)
First, you calculate the product of the two numbers:
$11749.49 5.147% = $604.7462503
But the actual calculation using fixed binary or packed decimal arithmetic would be
1174949 5147 = 6047462503
Knowing that there are two fraction digits in $11749.49 and five fraction digits in 0.05147 (the
percent rate), you know that there will be seven fraction digits in the product:
$604.7462503
You would then round this to the nearest cent:
$604.7462503
+
5
$604.75
This is fairly easy to program on a processor with instructions that do decimal arithmetic. For
example, you can multiply, shift, and round with just a few packed decimal instructions, as in
Figure 346.

PDAmt
PDTax
PDProd

ZAP PDProd,PDAmt
MP
PDProd,PDTax
SRP PDProd,64-5,5
- - DC
P11749.49
DC
P.05147
DS
PL8

Copy amount to work area


Multiply by tax rate
Convert to cents and round
Amount to be taxed
Tax rate
Resulting product

Figure 346. Calculating a tax amount in scaled fixed decimal arithmetic

The result can then be formatted for printing. (See Programming Problem 31.1.)
But what will you do if your CPU supports only fixed binary arithmetic? This difficulty faced
many early programmers.
Chapter IX: Floating-Point Data and Operations

543

Our little tax example is relatively easy to solve with fixed-point binary arithmetic. We treat all
quantities as integers (noting that the product is more than 31 bits long), and remember how
many powers of 10 to divide by to give a quotient that is fewer than 32 bits long. Thus, we could
use binary arithmetic as in Figure 347.
L
1,Amount
M
0,Percent
AL
1,Round
JC
12,NoCarry
AHI 0,1
NoCarry D
0,Correct
- - Amount DC
F . . .
PerCent DC
F . . .
Round
DC
F . . .
Correct DC
F . . .

Put amount in cents in GR1


Multiply by integer-ized percent
Add a rounding factor
Skip if no carry occurred
Propagate the carry bit
Divide by some power of 10
Cost of shipment
Percentage to multiply by
Rounding factor
Correction for scaling

Figure 347. Calculating a tax amount in scaled fixed binary arithmetic

The quotient in GR1 can then be converted to decimal and formatted.


The actual values of the four constants are for you to determine: first, solve Exercise 31.3.1 and
then do Programming Problem 31.2.

31.3.1. Scaled Fixed-Point Binary Arithmetic (*)


Obscure topic
Scaled fixed-point binary arithmetic is rarely used today; it has occasional
application to calculating time differences using the CPU clock.
The import-tax example above is fairly straightforward. A common problem with mixed integerfraction data is choosing the scaling to maximize precision while retaining the maximum range of
represented values. When we must do arithmetic with scaled numbers of the form Int.Frac (with
FD fraction digits), we need to know two things:
1. the largest magnitude of Int, and
2. the number of bits needed to represent Frac to FD significant decimal digits.
The number of bits needed to represent Int is
log2(Int)+1
and the number of bits needed for Frac is
log2(FD)+1
where the logarithm values have been truncated to an integer, which accounts for the + 1 in each
case. Reserving a single bit for the sign, the word length used to represent a signed value like
Int.Frac must satisfy
word length log2(Int)+log2(FD)+2
This inequality sometimes limits the range or precision of values that can be used in fixed-point
arithmetic.
Now, consider a more difficult problem: suppose you must calculate the square root of 2
(1.414213562...) using fixed binary or packed decimal arithmetic, to 8 significant decimal digits (1
integer and 7 fraction digits). This can be done using a Newton-Raphson iteration. Let A be
the number whose square root x is desired; if the initial estimate for x is reasonable, the value of
x will converge rapidly to the square root of A:
x = x + (A/x x)/2
We can use 1 as our initial estimate.

544

Assembler Language Programming for IBM z System Servers

Version 1.00

Because there is only a single digit to the left of the decimal point, we can use a binary representation with just a few bits to the left of the binary point, leaving the remaining bits to represent
the fraction. For example, if the leftmost four bits of a word are the integer part, the remaining 28
bits will hold the fraction. The number 2 in this representation will be X20000000, and the
initial estimate 1 will be X10000000.
A problem like finding the square root of a small number like 2 is relatively straightforward,
because all quantities have the same scaling. More often, the operands have different scale factors,
so it takes more effortas we saw for packed decimal arithmeticto manage the operands while
preserving enough precision in the intermediate and final results.
The need to manage problems like this led to the development of floating-point data and arithmetic, which maximizes precision and manages scaling automatically.

31.3.2. Scaled Fixed-Point Binary Constants (*)


The Assembler can do some scaling for you. For example, the values of A and x in the NewtonRaphson iteration can be written as scaled fixed-point constants:
A
X

DC
DC

FS(28) 2
FS(28) 1

2, scaled by 2**28
1, scaled by 2**28

X20000000
X10000000

Figure 348. Two binary constants scaled by 2**28

where the letter S following the constant type asks the Assembler to scale the result by shifting the
nominal value to the left 28 bits. Other values used in the calculation are then scaled accordingly.
In effect, we are defining two constants of this form:
4  28

Int .
Frac


radix point
Suppose we want to do scaled binary arithmetic with numbers having integer parts between 0 and
1000, which will need about 10 bits. And because we might add two numbers near 1000, well
allocate 11 bits for the integer value and one bit for a sign. This leaves 20 bits for the fraction
part.
How should the constant + 123.4567 be represented?
1. The integer part of the constant is 123, or X07B , so we know that the first three bytes of the
constant will be X07B . (The sign bit is 0 for + .)
2. Following the steps in Section 31.2 for converting fractions, we find that
0.456710 = X74EA4A8C... . Because only 20 bits are allocated to the fraction, we must
round this to five hex digits, giving X74EA5
3. Combining the integer and fraction parts, we find that the constant is X07B74EA5 .
The main problem is keeping track of the scaling of intermediate quantities during the iterations,
and formatting the decimal digits of the results fraction part. (See Programming Problem 31.3.)
In addition to scaled fixed-point binary constants like those in Figure 348, you can also define
scaled constants where the radix point lies outside the constant! For example, suppose you want
to represent 1012 in a 32-bit word. But 1012 is greater than 231, so it might seem impossible. But
because there are 12 low-order zero bits in 1012, we can ask the Assembler to create a constant
without those 12 zero bits; we must then remember to compensate for them when doing arithmetic with the constant:
TenTo12 DC

FS(-12) 1 E12

10**12 scaled by -12 bits

Figure 349. Defining a scaled binary constant 10**12

Chapter IX: Floating-Point Data and Operations

545

where the negative scale factor 12 means that the Assembler will shift the binary constant to the
right by 12 bits before generating the machine language constant. Effectively, you will generate a
constant of this form:
 32  12

Integer


radix point
If we want to multiply the scaled constant 2 in Figure 348 by the scaled constant 1012 in Figure
349, we can use instruction like these:
L
M
SRDA
- - TenTo12 DC

1,A
0,TenTo12
0,16

c(GR1) = 22**28
Multiply by 10**122**(-12)
Compensate for both scale factors

FS(-12) 1 E12

10**12 scaled by 12 bits

Figure 350. Multiplying two scaled binary numbers

and the 64-bit result in c(GR0,GR1) will be 210**12, or X000001D1 A94A2000 . If this value will
be used in later arithmetic, it will once again need to be scaled by 2**( 12) so that it will fit in a
single register: X 1 D1A94A2 .
Programming on processors with only fixed-point arithmetic isnt easy!

Exercises
31.3.1.(2) Write DC statements to define the values named Amount, Percent, Round, and
Correct in Figure 347 on page 544.
31.3.2.(2) What machine language constant will be generated by the DC statement in
Figure 349 on page 545?
31.3.3.(1) What machine language constants will be generated for the two packed decimal constants in Figure 346 on page 543, and how long must the work area named PDProd be?
31.3.4.(3) Convert these decimal values to hexadecimal, giving at most six significant fraction
digits:
1. 6.3725
2. 987.603
3. 314.1592654
31.3.5.(1) With signed 32-bit words, how many different integer-fraction representations can be
created? With unsigned 32-bit words?
31.3.6.(2) Referring to the import-tax example in 31.3. Mixed Integer-Fraction
Representation on page 543, what is the minimum number of bits needed to represent the
integer portion of the signed quantity + 604.7462503?
31.3.7.(2) Given =3.14159265359, what is its hexadecimal representation as a 32-bit scaled
fixed-point binary number with 28 fraction bits?
31.3.8.(4) The binary representation of each power of 10 has as many trailing zero bits as the
power. For example, 10 2 = X 6 4 = B1100100.
Determine the largest scaled power of 10 that can be held in a 32-bit and a 64-bit signed twos
complement constant. Then, determine the largest unsigned values for both lengths.

546

Assembler Language Programming for IBM z System Servers

Version 1.00

31.3.9.(2) + What would happen if you had written the constant TenTo12 in350 this way?
TenTo12 DC

FS(-12)10E12

10**12 scaled by 12 bits

31.3.10.(3) + Given a scaled binary constant at Value representing the decimal value 98.234567,
convert its value to EBCDIC characters with 5 digits after the decimal point, and with the last
digit rounded.

31.4. Why Use Floating-Point Numbers?


Floating-point arithmetic sometimes seems unusual (or even frightening) compared to fixed-point
arithmetic. It is also sometimes thought to be prone to errors; but it is no different in that respect
from fixed-point arithmeticand sometimes, better. The examples of computing import tax in
Figures 346 and 347 on page 544 actually introduced errors, because the results had to be rounded
and presented to less than full precision.
But you will want to be careful. Most floating-point computations are reliable, simple, fast, and
accurate, while others can give misleading (or even wrong!) answers.
Because actual data can take many magnitudes, the floating-point number representation helps us
manage data of widely varying values. Figure 351 has examples of various constants:
6022 00000 00000 00000 00000.
9 46000 00000 00000.
2997 76000.
33136.
745.7
440.
16.3872
3.14159
kilometers/mile
1.60935
ln 2
.69314
Coulombs/electron
.00000
Planck s const (Joule-sec) .00000

Avogadro s Number
meters/light-year
meters/sec (light)
cm/sec (sound)
Watts/horsepower
hertz (Concert A)
cc/cubic inch
26535 8979

71805 59945
00000 00000 00016
00000 00000 00000 00000 00000 00066 26

Figure 351. Examples of data with widely ranging values

Managing these widely varying magnitudes with fixed point binary arithmetic is rather difficult.
Like most results in fixed-point arithmetic, we are mainly concerned with the most significant
digits, and we use a power of some base such as 2, 10, or 16 by which those digits should be
multiplied.
Thus, floating-point data and arithmetic have many advantages:
Because the most significant digits are retained, values have more uniform precision. Scaled
fixed-point representations may need to use less precision for the fraction part of a number so
they can correctly represent the largest values of their integer part.
Our scaled fixed-point examples used 32-bit fullwords, but they were very limited in the range
of values they could represent. Floating-point variables give up some bits of precision in order
to support a much greater range.
Precision losses involve the least significant digits, which is how we normally do arithmetic
with numbers with many digits.
Floating-point manages scaling automatically; the CPU keeps track of the radix point for you.
For many problems, floating-point arithmetic is by far the simplest approach.

31.4.1. Precision and Accuracy

Chapter IX: Floating-Point Data and Operations

547

Suggestion
You may want to review the discussion of precision and accuracy for
fixed-point data in Section 29.10.1 on page 513.
Unlike the precision of packed decimal and binary integer values, floating-point values can be
imprecise if the number of significant digits exceeds what the representation can provide. Because
of the much greater range of floating-point values, they can sometimes retain greater accuracy.

Exercises
31.4.1.(1) In Figure 351, represent Avogadros Number and Plancks constant as numbers with
one integer digit and several fraction digits, multiplied by a power of 10.
31.4.2.(2) Suppose you must represent both Avogadros Number and Plancks constant in a
fixed-point integer-fraction representation. Estimate the number of bits required.

31.5. Floating-Point Representations


A typical floating-point number representation has four elements: a sign, an exponent, its significant digits, and the base or radix used for the significant digits. Figure 352 shows a typical
arrangement:
one bit for the sign of the number (0 = + , 1 = )
some bits representing the exponent
the remaining bits for the significant digits of the number, usually known as the significand.187

sign exponent
significant

s
e

digits

Figure 352. A typical floating-point representation

These fields need not be arranged in the order shown in Figure 352, but all z System floatingpoint representations use this basic format.
Designers of floating-point representations must then make several choices:
1. What base or radix should be used for the significant digits?
2. How should the significant digits be represented? Should they be digits of the radix (like the
digits 0-9 for radix 10) or should they be encoded in some way?
3. Should a number like 12.34 be stored as the fraction 0.1234 with an exponent + 2, or as the
integer 1234 with an exponent 2, or with a single integer digit as in 1.234 with an exponent
+ 1, or as 12.34 with a zero exponent?
4. Must all of the significant digits be present in the significant digits field, or can some of
them be assumed, or combined with other fields?
5. If different data lengths are supported (such as 32 and 64 bits), should the same or different
exponent widths be assigned to each?
6. How large a field should be allotted to the exponent? (A larger exponent field means less
room for the significant digits.)

187

548

The significand was sometimes called the mantissa, but that word had long been used for logarithms, where the
meaning is quite different.
Assembler Language Programming for IBM z System Servers

Version 1.00

7. Should the exponents value be represented in binary or some other radix? (The answer
seems always to have been binary.)
8. How should the sign of the exponent be represented?
z System supports three sets of answers to these questions: hexadecimal, binary, and decimal,188
which well investigate in Sections 33, 34, and 35.
To illustrate some possible choices, consider a floating-point representation of a number X, using
4 significant decimal digits. (Well ignore what to do about the exponent for a moment.)
First, suppose the significant digits are stored as integers, with the radix point understood to
follow the rightmost digit. In Figure 353, X is the value represented, and k is the exponent, a
power of 10.

0 1 2 3.

k = 0
X = 123

2 3 4 0.

k = -1
X = 234

0 0 7 3.

k = 0
X = 73

0 0 7 3.

k = 2
X = 7300

0 0 7 3.

k = -3
X = 0.073

Figure 353. An example of a floating-point representation using 4 decimal digits

Other digit strings and exponents can be used to represent the same value for X; for example,
X=123 could be represented by the digits 1230 and exponent 1.
Now, suppose the significant digits are stored as fractions, with the radix point understood to
precede the leftmost digit. In Figure 354, X is again the value represented and k is the exponent
as a power of 10.

.1 2 3 0

k = 3
X = 123

.0 1 2 3

k = 4
X = 123

.7 3 0 0

k = 2
X = 73

.0 7 3 0

k = 3
X = 73

.0 0 7 3

k = 4
X = 73

Figure 354. Another example of a floating-point representation using 4 decimal digits

The three representations of the number 73 show how the same number can have different representations.
Many floating-point representations viewing the significant digits as fractions expect the leftmost
fraction digit to be nonzero: this means that as many significant digits as possible are kept with
the number. This is called normalization: the leftmost significand digit of a nonzero number is
nonzero. Thus, some values in Figure 354 are normalized and some are not:
Normalized

.1 2 3 0

k = 3
X = 123

Unnormalized

.0 1 2 3

k = 4
X = 123

Normalized

.7 3 0 0

k = 2
X = 73

Unnormalized

.0 7 3 0

k = 3
X = 73

Unnormalized

.0 0 7 3

k = 4
X = 73

Figure 355. A floating-point representation showing normalized and unnormalized values

Figure 355 shows that unnormalization allows redundant representations. Well see that z System
hexadecimal and decimal floating-point allow redundant representations, but binary floating-point
does not.

188

Processor manufacturers previously created many different solutions (well see some in Section 36) but in recent years
this wide variety of floating-point formats has converged on a small set of possibilities.
Chapter IX: Floating-Point Data and Operations

549

31.5.1. Some Additional Details (*)


Interesting observations
This section will be interesting mainly to mathematically inclined readers.
Mathematically, floating-point numbers are a subset of the rational numbers: that is, they are a
subset of all possible fractions (including fractions like 123/1). A value X is represented by
Mr k, where
M

is an integer satisfying 0 M < r p, an unsigned p-digit integer

is the radix (or base) of the significant digits of the representation

is the precision of M (the number of base-r digits)

is the exponent, the power of r by which M is multiplied, typically positive and negative
values of approximately equal ranges.

We sometimes say that the set of all such values is known as a floating-point system FP(r,p).
We can also use a fraction for the significant digits, so that f = M r p, and the fraction satisfies
0 f < 1.0. This puts the radix point at the left end of the digits; X is then represented by
fre, and the exponent e = k + p (k was the exponent we used for the integer-format representation above). The normalization condition then becomes r 1 f < 1.0, so the most significant digit of f is nonzero.
z System uses both floating-point representations: hexadecimal and binary represent the significant digits as fractions, and decimal uses integers. To clarify which is being discussed, well use
FPF(r,p) to mean a fraction representation, and FPI(r,p) to mean an integer representation. Thus,
Figure 353 uses the FPI(10,4) representation, and Figure 354 uses the FPF(10,4) representation.
For example, suppose our FPF(10,4) representation allows a single decimal digit for the decimal
exponent. The signed numbers + 123 and + .0123 would be represented as in Figure 356:

++3.1 2 3 0

and

+-1.1 2 3 0

Figure 356. Floating-point numbers with signed exponent

Another issue is rounding. If a number is not exactly representable in a given system, it should
be approximated by one of the two nearest 189 representable values, preferably the value closest to
the exact value. Figure 357 shows some familiar approximations in FPI(10,4):
Rounded Down

3 3 3 3.

k = -4
X = 1/3

Rounded Down

6 6 6 6.

k = -4
X = 2/3

Rounded Up

6 6 6 7.

k = -4
X = 2/3

Figure 357. Examples of approximate floating-point representations

where we chose an approximation from one of the two nearest 4-digit neighbors of the exact
value.
We saw in 31.2. Converting Fractions on page 541 that decimal values like 0.1 cannot be converted exactly to binary or hexadecimal. So we must choose the best approximation of 0.1 in
binary or hexadecimal floating-point. For example, if we use a hexadecimal floating-point repre-

189

550

Some numbers are very difficult to convert accurately between bases. Modern conversions are almost always able to
choose one of the two nearest neighbors of the exact value. This was not true for many years, and was the source of
occasional unhappiness and confusion.
Assembler Language Programming for IBM z System Servers

Version 1.00

sentation with 6 significant digits, and a binary floating-point representation with 24 significant
bits, the best resulting fraction values will be close, but not exact:
In FPF(16,6):
In FPF(2,24):

1677722/16 6
13421773/2 27

= 1677722/16777216
= 13421773/134217728

= 0.100 000 023 84


= 0.100 000 001 49

Most decimal fractions arent representable precisely in base 2 or 16.

Exercises
31.5.1.(1) Using the FPF(10,4) representation in Figure 356 on page 550 with a single signed
decimal digit for the exponent, how many redundant representations of zero are possible?
31.5.2.(1) In the floating-point systems FPF(10,4) and FPI(10,4), how many representations are
there of 4.7?

31.6. z System Floating-Point Representations


z System supports three different representations for floating-point numbers: hexadecimal,
binary, and decimal, with bases 16, 2, and 10.190 For each representation, three data lengths are
defined: 4 bytes, or short, 8 bytes, or long, and 16 bytes, or extended. Each has a sign bit, an
exponent field, and a significand field for all of the significant digits (hexadecimal) or all but one
of the significant digits (binary and decimal floating-point).

4 bytes
Short

8 bytes
Long

16 bytes
Extended

Figure 358. Three floating-point data lengths

The three z System floating-point number representations have different properties and ways of
representing the data. Well explore them in Sections 33, 34, and 35.

31.7. z System Floating-Point Registers


z System uses a separate set of registers for floating-point operands and arithmetic. For many
years, the original System/360 and its successors supported only the four floating-point registers
shown in Figure 359.

190

Historically, base 16 was supported first, then base 2, and then base 10.
Chapter IX: Floating-Point Data and Operations

551

FPR 0
FPR 2
FPR 4
FPR 6

 8 bytes
 4 bytes

Figure 359. Four floating-point registers

This figure raises several questions:


1. Why were there only four floating-point registers while there are 16 general registers?
2. Why were the floating-point registers numbered 0, 2, 4, and 6 rather than 0, 1, 2, and 3?
3. Why are separate floating-point registers used for floating-point operations, rather than using
the general registers?
4. The floating-point registers are 64 bits long; how can we access the rightmost 32 bits?
Here are some possible answers:
1. In System/360 days, registers were expensive. Because businesses were the primary market,
packed decimal data and operations were expected to satisfy most business needs. The
Floating-Point Feature could be ordered if floating-point data and arithmetic was needed.
2. Because the floating-point registers are 64 bits long, their similarity to 32-bit general register
pairs made it natural to number them the same way.
3. The general registers are needed for base registers and for address and integer arithmetic, so it
seemed best to provide separate registers for floating-point operations.
4. Hexadecimal was the only floating-point representation supported for many years; short
hexadecimal operands used just the leftmost 32 bits, while long operands used all 64 bits.
There was rarely any need to access only the rightmost 32 bits of the floating-point register.
Later, IBM added the remaining 12 floating-point registers; all modern CPUs have 16.
Unlike the general registers, the floating-point registers are addressed only by their leftmost
portions. The low-order portion of the register is not separately addressable.
In Figure 358, extended-precision operands are shown as being 16 bytes long; because the
floating-point registers are only 8 bytes long, a pair of registers is used.191 The eight valid register
pairs are (0,2), (1,3), (4,6), (5,7), (8,10), (9,11), (12,14), and (13,15), as illustrated by the
bracketing in Figure 360.
Remember!
Each 64-bit floating-point register is not a pair of 32-bit registers.

191

552

Weve already seen general register pairing for double-length integer products and dividends.
Assembler Language Programming for IBM z System Servers

Version 1.00

FPR 0
FPR 1
FPR 2
FPR 3
FPR 4
FPR 5
FPR 6
FPR 7
FPR 8
FPR 9
FPR10
FPR11
FPR12
FPR13
FPR14
FPR15

Figure 360. All sixteen floating-point registers, showing register pairings

The high-order half of an extended operand is in the lower-numbered register, and the low-order
half is in the register number two higher.
Remember!
floating-point register pairs are Rn and R n + 2, not R n and R n + 1, as with
general register pairs.
It may help to visualize floating-point register pairing this way:

Chapter IX: Floating-Point Data and Operations

553


FPR 0

FPR 1

FPR 4

FPR 5

...
...

FPR13

FPR 2

FPR 3

FPR 6

FPR 7

FPR15

You may want to be careful when referencing floating-point registers on a very old CPU that has
only the four original registers. A specification exception would be generated by any instruction
which tries to refer to any but FPR0, FPR2, FPR4, and FPR6. 192

Exercises
31.7.1.(1) Why do you think the floating-point registers are not paired in the same way as the
general registers? For example, (0,1), (2,3), etc.
31.7.2.(2) Suppose the CPU has the number of a floating-point register to be used in an
extended precision operation. What is an easy way to derive the number of the paired floatingpoint register?

31.8. Floating-Point Constants


The Assemblers DC statement lets you define floating-point constants of the three standard
lengths, with these default alignments:
Type
E
D
L

Length
4 bytes, fullword aligned
8 bytes, doubleword aligned
16 bytes, doubleword aligned

and all three representations, hexadecimal, binary, and decimal, specified by these subtypes:
Subtype
H or none
B
D

Data Representation
Hexadecimal floating-point
Binary floating-point
Decimal floating-point

These are described in the sections discussing each type of representation and arithmetic.

192

554

The Assembler can help by checking register references at assembly time. By default, all 16 registers are valid, but if
you want to be sure your program references only those four, see the AFPR topic in the Assemblers Language
Reference manual.
Assembler Language Programming for IBM z System Servers

Version 1.00

Exercises
31.8.1.(1) What DC constant type (and subtype, if any) would you specify for floating-point
constants of these types?

Long decimal
Short binary
Extended hexadecimal
Extended decimal

31.9. Representation-Independent Floating-Point Instructions


While many of the floating-point instructions depend on the representation of the data they
manipulate, some work for all three.193 That is, you can put any string of bits in a floating-point
register; just be careful not to do arithmetic with them!
Worth remembering
These instructions do not depend on the representation of the data in the
floating-point registers.

31.9.1. Register-Storage Instructions


The instructions in Table 214 move data between memory and the floating-point registers for data
in all three z System floating-point representations. They do the same operations for floatingpoint register data as do the related instructions (like L, ST) for general register data. The CC is
unchanged.
Op
78
68
70
60

Mnem
LE
LD
STE
STD

Type
RX
RX
RX
RX

Instruction
Load (Short)
Load (Long)
Store (Short)
Store (Long)

Op
ED64
ED65
ED66
ED67

Mnem
LEY
LDY
STEY
STDY

Type
RXY
RXY
RXY
RXY

Instruction
Load (Short)
Load (Long)
Store (Short)
Store (Long)

Table 214. Basic floating-point instructions

There are no register-memory instructions to load or store an extended operand into or from a
floating-point register pair, and no instructions that load or store multiple floating-point registers.

31.9.2. Register-Register Instructions


Table 215 lists the instructions for moving floating-point operands among the floating-point registers:

193

The z/Architecture Principles of Operation refers to them as radix-independent or Floating-Point Support


instructions.
Chapter IX: Floating-Point Data and Operations

555

Op
38

Mnem
LER

Type Instruction
RR
Load FPR from FPR
(Short)

B365

LXR

R R E Load FPR from FPR


(Extended)

B373
B370

L C D F R R R E Load Complement (Long)


L P D F R R R E Load Positive (Long)

Op
28

Mnem
LDR

Type Instruction
RR
Load FPR from FPR
(Long)

B371 L N D F R R R E Load Negative (Long)

Table 215. Instructions copying data between FPRs

You may have noticed that Load and Test doesnt appear among these representationindependent instructions; well see why such instructions depend on the format of the operands.
LER and LDR are similar to LR and LGR: both LR and LER move only 4 bytes, and LGR
and LDR move 8 bytes. LXR moves all 16 bytes, and requires both operands to refer to the
lower-numbered register of a floating-point register pair.194
There are two important differences between LR and LER:
1. While LR copies the low-order 4 bytes of one general register to another, LER copies the
high-order 4 bytes of one floating-point register to another. For example:
LG
LG
LR

0,=X0123456789ABCDEF
2,=X FEDCBA9876543210
0,2

Load GG0
Load GG2
c(GG0)=X0123456776543210

LD
LD
LER

0,=X0123456789ABCDEF
2,=X FEDCBA9876543210
0,2

Load FPR0
Load FPR2
c(FPR0)=X FEDCBA9889ABCDEF

The rightmost 4 bytes of GG0 are changed, but the leftmost 4 bytes of FPR0 are changed.
2. There is no way to reference the 4 low-order bytes of a floating-point register separately from
its high-order 4 bytes.
The LCDFR, LNDFR, and LPDFR instructions in Table 215 are different from many similar
instructions (such as LCR, LNR, and LPR for binary integers, and LCER, LNER, and LPER
for hexadecimal floating-point), because they dont set the Condition Code. There are other
representation-dependent instructions like these that do set the CC.

31.9.3. Load-Zero Instructions


Before these instructions were introduced, setting a floating-point register to zero was awkward:
either a zero had to be loaded from memory (which is relatively slow), or the registers content
had to be subtracted from itself, which could also be slow (and sometimes cause other undesired
side-effects). The three instructions in Table 216 simply set the designated operand register(s) to
zero, and do not change the Condition Code.
Op
B374
B376

Mnem
LZER
LZXR

Type Instruction
R R E Load Zero (Short)
R R E Load Zero (Extended)

Op
Mnem
B375 L Z D R

Type Instruction
R R E Load Zero (Long)

Table 216. Floating-point Load Zero instructions

The LZER instruction probably isnt needed, because LZDR will clear the full 8 bytes of the
floating-point register; and because you cant refer separately to the low-order 4 bytes of the register, there seems to be little gain in clearing only the high-order 4 bytes.

194

556

Previously, two LDR instructions were needed to copy an extended-precision operand from one floating-point register pair to another.
Assembler Language Programming for IBM z System Servers

Version 1.00

31.9.4. GPR-FPR Copying Instructions


Transferring data between general registers and floating-point registers on System/360 required
using an intermediate storage area in memory. As CPUs have become much faster relative to
memory speeds, those two memory accesses can cause program delays.
The two instructions in Table 217 transfer data directly between general and floating-point registers.
Op
B3C1

Mnem
LDGR

Type
RXY

Instruction
Load FPR from GPR
(Long)

Op
Mnem
B3CD L G D R

Type
RXY

Instruction
Load GPR from FPR
(Long)

Table 217. Instructions moving data between FPRs and GPRs

As the instruction names indicate, these two instructions move 64-bit operands. For example:
LDGR 4,13
LGDR 1,6

Copy c(GG13) to c(FPR4)


Copy c(FPR6) to c(GG1)

31.9.5. Sign-Copying Instruction


The Copy Sign instruction is unusual: the second operand is copied to the first operand (as for
LDR), but with the sign bit of the third operand!
Op
B372

Mnem
CPSDR

Type
RRF

Instruction
Copy Sign (Long)

Table 218. Copy Sign instruction

The instruction format is


CPSDR R1,R3,R2
The second operand (in R 2) is copied to the first operand (in R1) with the sign of the third
operand (in R 3). Only the long format is supported; but you can use CPSDR for short operands,
and for extended operands if you remember to copy the low-order half from the second operands
higher-numbered register to the higher-numbered register of the first operand.
Thus, you could write
CPSDR 1,5,8

Copy FPR8 to FPR1 with FPR5 s sign

to avoid having to write an LDR instruction followed by other Load and Test and Load Complement instructions to set the correct sign.

Exercises
31.9.1.(1) Write three different short instruction sequences to swap the contents of FPR0 and
FPR4.
31.9.2.(1) In Exercise 19.5.1, you showed how the contents of two general registers could be
exchanged using logical operations. Show another way to do this without referencing memory
or by using logical operations.
31.9.3.(1) If you designed register-memory instructions to load and store extended floating-point
operands, or to load and store multiple floating-point registers, what mnemonics might you
assign to those four instructions? What possible exception conditions might they recognize?

Chapter IX: Floating-Point Data and Operations

557

31.10. Summary
This section has described scaled fixed-point arithmetic, and shown why its difficulties led to the
introduction of floating-point.
The representation-independent instructions useful in programs handling floating-point operands
are listed in Table 219.
Operation
Load
(memory)

Operands
8 bytes

4 bytes
LE
LEY

LD
LDY

LER

LDR
LCDFR
LNDFR
LPDFR
LZDR

Load
(register)
Zero
(register)
Copy Sign
(register)
Store
(memory)

LZER

16 bytes

LXR

LZXR

CPSDR
STE
STEY

STD
STDY

Table 219. Basic Load/Store instructions for floating-point operands

The two instructions in Table 220 transfer data between floating-point registers and general registers.
Instruction
LGDR
LDGR

Operand 1
8-byte G P R
8-byte F P R

Operand 2
8-byte F P R
8-byte G P R

Table 220. Instructions moving operands between GPRs and FPRs

Instructions Discussed in this Section


The instruction mnemonics and opcodes are shown in the following table:
Mnemonic
CPSDR

Opcode
B372

Mnemonic
LER

Opcode
38

Mnemonic

Opcode

LZDR

B375

LCDFR

B373

LEY

ED64

LZXR

B376

LD

68

LGDR

B3CD

STD

60

LDGR

B3C1

LNDFR

B371

STDY

ED67

LDR

28

LPDFR

B370

STE

70

LDY

ED65

LXR

B365

STEY

ED66

LE

78

LZER

B375

The instruction opcodes and mnemonics are shown in the following table:

558

Assembler Language Programming for IBM z System Servers

Version 1.00

Opcode
28

Mnemonic
LDR

Opcode

Mnemonic

Opcode

Mnemonic

B370

LPDFR

B3C1

LDGR

38

LER

B371

LNDFR

B3CD

LGDR

60

STD

B372

CPSDR

ED64

LEY

68

LD

B373

LCDFR

ED65

LDY

70

STE

B374

LZER

ED66

STEY

78

LE

B375

LZDR

ED67

STDY

B365

LXR

B376

LZDR

Terms and Definitions


floating-point
A data representation with a sign, an exponent, and a set of significant digits.
significand
The numerically significant digits of a floating-point number, whether explicitly or implicitly
represented.
radix
The base in which the significant digits of a floating-point number are represented.
exponent
The power of the radix by which the significand of a floating-point number must be multiplied to determine its value.
mantissa
An old term for the significant digits of a floating-point number.195
floating-point system FP(r,p)
A floating-point data representation with a specified radix and number of significant digits,
denoted FPF(r,p) or FPI(r,p).
floating-point system FPF(r,p)
A floating-point system with radix r and p digits of precision, in which the significant digits
are represented as fractions.
floating-point system FPI(r,p)
A floating-point system with radix r and p digits of precision, in which the significant digits
are represented as integers.

Programming Problems
Problem 31.1.(1) Write a program using packed decimal arithmetic to solve the import-tax calculation described in Section 31.3, and print the formatted result.
Problem 31.2.(2) Write a program using fixed binary arithmetic to solve the import-tax calculation described in Section 31.3, and print the formatted result.
Problem 31.3.(4) Write a program using fixed binary arithmetic to evaluate the square root of 2
using the Newton-Raphson iteration described in Section 30.1, with initial estimate 1. (The
hardest part of this problem will probably be formatting the fraction part of the result.)

195

This term should be avoided because it can be confused with the mantissa of a logarithm, which is quite different.
Chapter IX: Floating-Point Data and Operations

559

32. Basic Concepts of Floating-Point Arithmetic

3333333333
333333333333
33
33
33
33
3333
3333
33
33
33
33
333333333333
3333333333

2222222222
222222222222
22
22
22
22
22
22
22
22
22
222222222222
222222222222

In this section we examine the basic behavior of floating-point arithmetic, and some factors that
you (and CPU designers) must consider. Well start with floating-point multiplication.

32.1. Floating-Point Multiplication


Suppose we want to multiply two floating-point numbers A and B, where A = a10Ea and
B = b 10Eb . Their product is
AB = (ab)10(Ea + Eb)
That is, we multiply the significant digits and add the exponents.
For example, suppose A is 3300 (33102) and B is 0.029 (2910 3). Multiplying, we find that
AB = (3329)10(2 + ( 3)) = 95710 1 = 95.7
If we represent A and B in FPF(10,4) as four-digit base-10 floating-point values with normalized
fractions, A = 0.3300104 and B = 0.290010 1. Multiplying gives
AB = (0.33000.2900)10(4 + ( 1)) = 0.095710 + 3 = 95.7
The result is numerically correct, but the product fraction 0.0957 is not normalized. To generate a
normalized result, the fraction must be shifted left one digit position to form 0.9570; and because
this increases the fraction by 10, we must reduce the exponent by 1 to compensate. The normalized result is then 0.9570102.
This final multiplication correction is called post-normalization, and may be needed if the leading
digit of the product fraction is zero. For example, if we multiply the decimal fractions 0.2 and
0.3, the product fraction 0.06 must be shifted left once to obtain a normalized result. If the postnormalizing shift is performed, the exponent is reduced by 1 to account for the shift having multiplied the fraction by 10.
This example shows that multiplication using FPF(r,p) may require a post-normalization shift.
The same product using integer values in FPI(10,4) would give
AB = (0032.102)(0029.10 3) = 0957.102 + ( 3) =
0957.10 1 = 95.7
and no post-normalizing shift is needed.

560

Assembler Language Programming for IBM z System Servers

Version 1.00

The products in these examples have had few enough digits that we havent had to worry about
excess low-order (or high-order) digits. Well investigate what can be done about them in Section
32.3.

Exercises
32.1.1.(2) In FPF(10,4) using 4-digit internal arithmetic, what are the normalized values of
these products?
1. (0.76541012)(0.123510 8)
2. (0.7655102)(0.7655102)
3. (0.0333102)(0.0321101)

32.2. Pre-Normalization of Fraction Operands


Our examples assumed that the operands of a product in an FPF(10,4) representation were normalized, so that at most a single post-normalizing shift is needed. But what if the operands are not
normalized? If the numbers A and B had been represented by the unnormalized values
A = 0.0033106 and B = 0.0029101, the product will be
AB = (0.00330.0029)106 + 1 = 0.00000957107
If we had retained only the first 4 digits of this product, all significance would have been lost.
This product fraction has five leading zeros, so something must be done to preserve the accuracy
of the result. This is called pre-normalization: before the operands are multiplied the CPU internally normalizes them and adjusts their exponents; the product fraction is then 0.0957, which
needs only a single post-normalizing shift.
Because most floating-point operands are already normalized, the cost of pre-normalization is
very low relative to the other steps needed to complete the instruction. Also, if the operand fractions are pre-normalized, we know that at most one post-normalization shift may be needed.

Exercises
32.2.1.(2) + In FPF(r,p), what is the largest number of pre-normalizing shifts required for a
nonzero operand?
32.2.2.(2) Show the normalized results in FPF(10,4) of each product, with and without prenormalized operands.
1. (0.0147102)(0.0070103)
2. (0.0073104)(0.0071101)

32.3. Floating-Point Rounding


We learned to round decimal results by adding 5 to the first digit to be lost, propagating any
carries. This is sometimes called arithmetic rounding or round half-up (among other names).
It is one of many ways to round a more precise value to a less.
Arithmetic rounding is biased in the sense the sums may be slightly too large. For example,
suppose you are calculating the sum of the exact values .11115, .11125, .11135, .11145, and
.11155, and each exact value must be rounded to four significant digits before final summation.
With arithmetic rounding, the intermediate values are .1112, .1113, .1114, .1115, and .1116 and
their sum is .5570. But the sum of the 5-digit intermediate values is .55675, which we would
round to 4 significant digits as .5568.

Chapter IX: Floating-Point Data and Operations

561

In hexadecimal floating-point, arithmetic results are truncated (rounded toward zero). Our five
intermediate values would be .1111, .1112, .1113, .1114, and .1115, and their sum would be .5565.
An important rounding that reduces bias is round half-even (sometimes called bankers
rounding). If the value to be rounded lies exactly half way between two closest neighboring
numbers in the less-precise representation, we choose the value whose low-order digit is even.
With half-even rounding, our five intermediate values would be .1112, .1112, .1114, .1114, and
.1116, and their sum is .5568; and this is also the rounded (half-even or arithmetic rounding) value
of the exact sum.
Starting with the exact value, we can summarize our examples of these three types of rounding:

.55675 = exact
.5565 = truncated (rounded toward zero)
.5570 = arithmetic (half-up) rounding
.5568 = half-even rounding

This shows how arithmetic results can depend on the type of rounding used. z System supports
some other types of rounding, especially for binary and decimal floating-point arithmetic. We
noted above that hexadecimal floating-point arithmetic truncates: its sum would be .5565.
The guard and rounding digits are used only internally, and are not a part of any accessible register. This means that these two digits are not available on completion of an operation, and their
values are not carried over from one instruction to the next. You can think of them as being set
to zero at the beginning of the operation.

Exercises
32.3.1.(2) + Given the two FPF(10,4) numbers X=.1000101 (=1.000) and Y=.5555100
(=.5555), show the results of four iterations of the calculation
X = (X+Y)-X
using (a) round to zero, (b) round half-up, and (c) round half-even arithmetic for each iteration.

32.4. Guard and Rounding Digits (*)


Lets try other examples of multiplication in FPF(10,4) with normalized operands. First, consider
11 = (.1000101)(.1000101). The intermediate product is .0100102, which after normalization becomes .1000101.
Now, consider 11.234 = (.1000101)(.1234101). Since our products are 4 digits long, the
intermediate product is .0123102, or .1230101 after normalization. But this is unacceptable: we
want to believe that 1A for any A always yields A.
The solution to this unfortunate situation 196 is to use a guard digit, a single extra digit used internally for intermediate results. With a guard digit, the intermediate product is .0123[4], where the
guard digit is shown in square brackets [ ]. The post-normalizing shift shifts the intermediate
product including the guard digit left by 1 digit position, and the final product is .1234101 as
required.
Another example can reinforce the importance of a guard digit. If we have two positive numbers
A and B with A < B, then multiplying both by A should mean (according to the rules of
algebra) that A 2 < AB. Now, suppose A = .9999100 and B = .1000101, so A < B.
Without a guard digit, the products are A 2 = .9998100, and AB = .9990100, which means

196

562

It happened to IBM in 1966, because the very first System/360 processors omitted the guard digit for long
hexadecimal arithmetic. The oversight was quickly corrected, along with some other hexadecimal floating-point
inconsistencies.
Assembler Language Programming for IBM z System Servers

Version 1.00

that A 2 > AB instead! With a guard digit, the products are A 2 = .9998100 and
AB = .9999100, preserving the required inequality.
A guard digit is needed not only to improve the precision of a result. It might seem that the difference between the results with and without a guard digit is small (and especially so with fractions
having many digits), and is therefore negligible. The important observation is not that the answer
is slightly incorrect, but that an expected ordering relationship between the operands might be
destroyed. Its quite difficult to write reliable programs if you cant assume that inequalities
between operands behave normally.
Suppose we multiply 509151; the product is 76859. In FPF(10,4), (.5090103)(.1510103)
gives an intermediate product .0768[5]9106, and post-normalization gives the result
.7685105 = 76850. But a much better approximation in FPF(10,4) is .7686105 = 76860. To
produce this more accurate result, a second internal digit is needed, a rounding digit.
To round, we first post-normalize the intermediate result and then add 5 to the digit (if any) after
the last significant digit (propagating carries, of course). The rounded intermediate product fraction .0768[5]9 becomes
.76859 (normalized)
+
5
.76864
The rounding digit is then discarded, giving .7686105, as desired.
If no post-normalizing shift is needed, the guard digit is used as the rounding digit.
In z System processors, hexadecimal floating-point arithmetic provides a guard digit but no
rounding digit. Special instructions can round longer results (extended and long) to shorter (long
and short), but very few hexadecimal floating-point instructions round their results.
However, z System binary and decimal floating-point arithmetic let you specify several rounding
modes, both generally and for individual instructions. Well explore the instructions and rounding
modes when we discuss binary and decimal floating-point.

Exercises
32.4.1.(2) Without a guard digit, what types of operand A in FPF(10,4) will cause 1A to be
unequal to A?
32.4.2.(2) For these pairs of FPF(10,4) operands, show their products (a) with no guard or
rounding digit, (b) with a guard digit but no rounding digit, and (c) with both guard and
rounding digits.
1.
2.
3.
4.

155165
452469
211117
127137

(=25575)
(=111105)
(=23457)
(=17399)

32.4.3.(3) For these pairs of FPF(10,4) operands, show their products (a) with no guard or
rounding digit, (b) with a guard digit but no rounding digit, and (c) with both guard and
rounding digits.
1.
2.
3.
4.

509101
509555
509150
407515

(=51409)
(=282495)
(=279950)
(=209605)

32.4.4.(2) Repeat Exercise 31.1.1, assuming the operands are pre-normalized. Show the results
(a) with a guard digit, and (b) with guard and rounding digits.

Chapter IX: Floating-Point Data and Operations

563

32.4.5.(3) Construct three examples of products using FPF(10,4) operands that show differences
between rounding before post-normalization and rounding after post-normalization.

32.5. Integer-Based Representations (*)


Integer-based floating-point representations raise a different set of questions. Using the FPI(10,4)
notation of Figure 353 on page 549, we can consider several representations of the number 73:

7 3 0 0.

k = -2
X = 73

0 7 3 0.

k = -1
X = 73

0 0 7 3.

k = 0
X = 73

Figure 361. Integer-based representation of 73 in FPI(10,4)

All three representations have the same value, but only the third looks like the integer 73,
because its exponent is zero (so the lowest-order digit is multiplied by 10 0).
Now, suppose we multiply 73 by 730, both represented as integers with exponent zero. then
(0073.100)(0730.100) is 53290.100. But there are five digits in the product, so to preserve precision we must shift the result one digit to the right, giving 5329.101. The result no longer has
the original integer representation, because the lowest-order digit has effectively been multiplied by
101. Because the discarded digit was zero, we didnt worry about rounding. Thus, the product is

5 3 2 9 0.

k = +1
X = 53290
and the decimal point lies beyond the precision of the representation.
Now, consider the product 127137 = 17399. If we start with integer values with exponent
zero, the product again has too many digits and must be shifted right once to fit in the 4-digit
significand field. Because the digit to be discarded is nonzero, the remaining digits should be
rounded, so the result will be 1740.101.
Integer-based floating-point representations are not normalized either by requiring the highestorder digit to be nonzero (as in fraction-based representations), nor by requiring the lowest-order
digit to be nonzero. Integer-based floating-point is used in z System only for decimal floatingpoint, which well explore in Section 35.

Exercises
32.5.1.(2) In FPI(r,p), what advantage might there be if you pre-normalize the nonzero operands of a multiplication to the right so that the lowest-order digit is nonzero?

32.6. Floating-Point Division


If we calculate the quotient Q of two floating-point operands S and T, Q = S T, where
S = s 10Es and T = t 10Et , the quotient S T will be
S T = (s t)10(Es Et)

564

Assembler Language Programming for IBM z System Servers

Version 1.00

To illustrate, suppose we use the same FPF(10,4) representation for S and T as for A and B
above: four fractional base-10 digits and an exponent, and let S = 3300 (0.3300104) and
T = 6 (0.6000101), so the quotient will be 550. Then
S T = (0.3300 0.6000)10(4 1) = 0.5500103 = 550
In this case, the quotient fraction is properly normalized.
Now, suppose we divide 0.5 by 0.2, ignoring exponents. The result fraction is 2.5, which is
greater than 1, so the result requires a corrective right shift.197 Because shifting the fraction right by
one digit position is the same as dividing it by 10, the exponent of the result is increased by 1 to
compensate for the shift. This is illustrated in Figure 362:

.5 0 0 0 .2 0 0 0

k = 0
k = 0

= 2.5 0 0 0  .2 5 0 0

k = 0
k = 1

Figure 362. Illustrating floating-point division corrective right shift

Division operand fractions are pre-normalized, as for multiplication. If they werent, we might
divide 0.95 by 0.0005, giving 1900. for the (very unnormalized) quotient! This could cause extra
work to produce a correctly normalized result; possibly, the CPU designers would avoid designing
the extra circuits and simply indicate an error.
If the divisor T is zero, the division is improper and the CPU generates a floating-point divide
exception. If the dividend S is zero, the result can be set to zero immediately.

Exercises
32.6.1.(2) Ignoring exponents, which of the following division operations will require a corrective right shift for the 4-digit quotient? Show the rounded 4-digit quotient fraction.
1.
2.
3.
4.
5.

.1428
.6667
.1277
.3456
.9999

.7142
.6666
.3456
.1275
.9999

32.7. Floating-Point Addition and Subtraction


Adding and subtracting floating-point numbers is more complicated than multiplying and
dividing. We dont need to consider subtraction separately: to subtract, the CPU needs only to
invert the sign bit of the second operand and then add. Thus, we consider adding operands with
like signs or unlike signs.198
One major difference between division and multiplication on the one hand, and addition on the
other, is that in addition neither operand needs to be pre-normalized. This is because
there is no guarantee (as was the case for multiplication and division) that at most one corrective shift will be needed when the addition is completed, and
some calculations are simplified by not pre-normalizing; some of these will be illustrated when
we discuss hexadecimal floating-point in Section 33.

197

198

This corrective right shift is not a post-normalizing shift in same sense as for multiplication, because normalization
is usually understood to imply a left shift of the fraction to eliminate leading zero digits.
Adding operands with unlike signs is just another name for subtraction.
Chapter IX: Floating-Point Data and Operations

565

To illustrate floating-point addition, well again use decimal operands to add 124 and 3. In
FPF(10,4), these are represented as 0.1240103 and 0.3000101 respectively. Now we cant
simply add the fractions directly, since the true positions of the decimal points dont correspond
to the same leading digit positions: that is, adding
0.1240 + 0.3000 =(?) 0.4240
is clearly not correct. To add the fractions correctly, we must compare the exponents of the operands: if they are equal, the fractions can be added immediately. If the exponents are not equal, the
fraction part of the number with the smaller exponent is shifted right by a number of digit positions equal to the difference between the exponents. Because each right shift means that the
smaller exponent is increased by 1, it will eventually be equal to the larger.
Thus, the CPU must unnormalize the fraction of the operand with the smaller exponent until the
exponents of the two operands are equal. The fraction parts can then be added directly; in our
example we would find after shifting the fraction 0.3 to the right by 3 1 = 2 places and adding,
that the result fraction is
Before
.1240 103
+ .3000 101
????? 10?

After
.1240 103
+ .0030 103
.1270 103

The result exponent is 3, the exponent of the larger operand, and the value to which both exponents were adjusted.
As another decimal example of adding operands with like signs, suppose we want to add 62 and
77, which would be represented as .6200102 and .7700102. The exponents are equal, so the
fraction parts may be added directly, giving 1.3900102.
.6200 102
+ .7700 102
1.3900 102, or +.1390 103.
This fraction is not less than one in magnitude, so a single corrective right shift is needed; the
exponent is increased by one to account for the right shift. Thus, the result is + .1390103, as
desired.
When adding two normalized numbers of like signs, the only post-addition correction that may be
needed is a possible right shift of the fraction by one digit position, with an accompanying
increase of the exponent or characteristic by one.
What happens if the operands have exponents with a larger difference? Suppose we add .1234 and
.00008, which in FPF(10,4) have representations .1234100 and .800010 4. Because the exponent difference is 4, we must shift the smaller operand right 4 places:
.1234 100
+ .00008 100
.12348 100
As with multiplication, discarding the extra rightmost digit would give a less accurate result; some
types of floating-point arithmetic use the extra digit position to round the result to .1235100.
If the exponent difference is large enough, the smaller operand would be shifted so far to the right
that its digits cant contribute to the sum. Thus, the CPU can compare exponents to quickly
determine that it can deliver the larger operand as the result without doing any arithmetic.
Adding numbers with unlike signs proceeds the same way: the fraction part of the operand with
the smaller exponent is right-shifted a number of digit positions equal to the difference of the
exponents. The subtraction (negative addition) of the two fractions is then performed, and the
sign of the result is noted.
Since the result fraction can be smaller in magnitude than the larger of the two original operands,
we may find some leading zero digits in the result. If a normalized result is desired, the fraction
digits are shifted left (post-normalized) and the exponent is decremented by the number of left

566

Assembler Language Programming for IBM z System Servers

Version 1.00

shifts performed. (Sometimes its useful to retain the unnormalized result; well see examples
when we discuss hexadecimal floating-point.)
For example, suppose we add + 72 ( + .7200102) and 67 ( .6700102). Because the exponents
are equal, no operand shift is needed. Then, the steps of the addition are these:
+ .7200 102
- .6700 102
+ .0500 102
This example shows that adding numbers of unlike signs can generate an unnormalized result. If
a normalized result is required, the result would be + .5000101, as expected. Similarly, we can
subtract 99 (.9900102) from 102 (.1020103). After shifting the operand with the smaller exponent to the right by one digit position, the steps are shown in this example:
+ .1020 103
- .0990 103
+ .0030 103, or .3000 101.
and two shifts are needed to normalize the result.

Exercises
32.7.1.(2) For each of these differences in FPF(10,4) arithmetic, show the result (a) without
guard and rounding digits, (b) with a guard digit but no rounding digit, and (c) with both
rounding and guard digits.
1.
2.
3.
4.

(.7435103) (.9621101)
(.7435101) (.6994101)
(.1043105) (.9527104)
(.1000100) (.999210 2)

32.7.2.(1) In describing addition with unlike signs, the text above states ... the result fraction
can be smaller in magnitude than the larger of the two original operands.... Why does it not
state ... the result fraction is smaller in magnitude...?
32.7.3.(2) + In FPF(10,4), show the intermediate steps and the results in calculating the following quantities. (1) 9*9, (2) 9 9, (3) 643 552, (4) 2/3, (5) 28 32.

32.8. Floating-Point Precision


You may have learned in a mathematics class about what mathematicians call real numbers
that have unlimited precision199 and magnitude. But in our realistic world, we must deal with
numbers having finite precisionlimited numbers of digits. This is familiar to us; the import-tax
example in Section 31.3 on page 543 is typical of everyday calculations.
Floating-point arithmetic is necessarily realistic because data items have finite numbers of digits.
When we want to know the precision of a floating-point number, we need to know the precision
p of its representation.
Well use values in FPF(10,4) to illustrate. Ignoring exponents for the moment, consider the fraction .1000: we might say it has a precision of 4 decimal digits. The next larger value is .1001; the
relative difference between the two is .0001 .1000, or 10 3. Somehow, our four digits of precision has become three!

199

If you ever had to follow a mathematics proof using deltas and epsilons, youll remember that they can be
arbitrarily tiny.
Chapter IX: Floating-Point Data and Operations

567

The relative size of a one-digit change in the rightmost digit of a floating-point number is sometimes called a Unit in the Last Place, or an ulp for short. An ulp is defined by
ulp(x) = successor(x) - x
where the successor of a floating-point number is the next larger value.200 This is the spacing
between neighboring values.
Because the size of an ulp depends on the size of the number, it may be more useful to know its
relative size. The relative size of an ulp is
ulp(x) x
This is the relative weight of the low-order digit of the number x.
In FPF(10,4), ulp(.1000106) is 102, and ulp(.100010 6) is 10 10; but the relative size of both
ulps is about 10 3.
But now consider the fraction .9998: its successor (the next larger value) is .9999, so their relative
difference is .0001 .9998, or almost 10 4. So, the relative size of an ulp can vary by as much a
factor of 10, the radix of the representation.
This behavior applies to any floating-point representation using radix r: the relative size of an ulp
can vary between r p and r (p 1), so its size can vary by as much as r.201 Thus the relative precision of a floating-point representation is best described as r (p 1), and the precision of a p-digit
decimal fraction is not 10 p, but 10 (p 1).
As we saw for values in FPF(10,4), the precision of a floating-point number is sometimes estimated (incorrectly) as the relative value of its lowest-order digit. For example, in FPF(16,6) a
short hexadecimal floating-point number has six hexadecimal digits, so the relative value of its
rightmost digit is
16 6 = 0.000000059604644775390625 5.9610 8
This has sometimes led people to say that a short hexadecimal floating-point number can accurately represent seven decimal digits. But because the precision of the low-order digit may be
smaller:
16 5 = 0.00000095367431640625 9.5410 7
Its much safer to say that only six decimal digits can be accurately represented.
The question How many decimal digits does this floating-point number represent? also involves
issues of converting between decimal and the floating-point radix; well discuss this topic more
fully in Section 36.

Exercises
32.8.1.(2) Estimate the largest relative size of an ulp in each floating-point representation:
1. FPF(16,14)
2. FPF(2,24)
3. FPF(10,34)

200

Its more usual, and somewhat more correct, to define


ulp(x) = min[ successor(x)-x , x-predecessor(x) ]

201

568

where the predecessor is the number with the next smaller value.
This effect is sometimes called wobbling precision.
Assembler Language Programming for IBM z System Servers

Version 1.00

32.9. Floating-Point Range


We will use positive numbers in the FPF(10,4) representation to illustrate limits on the size of
floating-point data. It may help to refer occasionally to Figure 363, where the results of the following examples are indicated by keys like this: 1
We will also use [exponentfraction] to represent a floating-point value, where the exponent is a
signed decimal digit. Well call the maximum allowed exponent Emax, and the minimum
allowed exponent Emin. In these examples, Emax= + 9 and Emin= 9. This means that the
largest normalized value is [ + 9+ .9999] (called Max or MaxReal 6), and the smallest normalized value is [ 9+ .1000] (called Min or MinReal 7).
Floating-point numbers with too-large exponents cant be represented. These exponent range violations are called exponent overflow (the exponent is positive, and its value is greater than Emax)
and exponent underflow (the exponent is negative, and its value is less than Emin).
1. The very large number [ + 9+ .5000] multiplied by itself gives [ + 18+ .2500], which generates
an exponent overflow 1 because the exponent + 18 is greater than Emax.
2. Similarly, the very small number [ 9 .5000] multiplied by itself gives [ 18+ .2500], which
generates an exponent underflow because the exponent is less than Emin. 2
These two examples show that products and quotients of normal numbers can generate
results with double the allowed exponent range.
3. Adding the very large number [ + 9+ .9000] to itself generates [ + 10+ .1800]. The result has
an exponent one larger than Emax, which shows that the exponents of sums of normal
numbers can overflow Emax by 1. 3
4. Subtracting the very small number [ 9+ .1000] from its next larger value [ 9+ .1001] generates [ 12+ .1000]. Because our precision p is 4, this example shows that differences of
normal numbers can generate exponents as small as Emin (p 1). 4
5. Although this normalized result has caused exponent underflow, some floating-point systems
support operations that generate unnormalized results for some arithmetic operations. If
[ 12+ .1000] is denormalized by shifting the fraction right three places and adding 3 to the
exponent, the resulting value is [ 9+ .0001]. 5
This is the smallest nonzero value in our FP(10,4) representation. This denormalized
minimum value is sometimes called DMin.
Multiplying [ 5+ .5000] by itself generates [ 10+ .2500]. The normalized result has created
an exponent underflow, but denormalizing the fraction by one digit creates the representable
value [ 9+ .0250].
The two values [ 9+ .0001] and [ 9+ .0250] have valid exponents but unnormalized fractions; they are sometimes called denormal or subnormal numbers.
Exponent overflow and underflow are serious conditions, and its important to handle them carefully. Operations on overflowed values are difficult to manage. Sometimes the exponent of the
result has been adjusted to lie between Emin and Emax, so you must be careful not to continue
calculations with the adjusted value.
Sometimes overflowed results may be set to values like MaxReal, MinReal, a bit pattern representing infinity, or zero, and underflows may be set to zero.
MaxReal is sometimes mistakenly called infinity, but MaxReal is very different from the mathematical concept of :
/ 2 = , but MaxReal/2 is finite
0 is meaningless, but MaxReal0 = 0

Chapter IX: Floating-Point Data and Operations

569

 Representable Values

 Exponent Values

Unrepresentably Large Values




2Emax


Products, Quotients

Overflow Range 1

Emax+1  Sums 3


Emax
Overflow Threshold


MaxReal 6

0
Normal Range


MinReal 7
Emin
Underflow Threshold

 Subnormal Range 5


Emin-p+1 Differences 4

Underflow Range 2


Products, Quotients
2Emin


Unrepresentably Small Values

Figure 363. Exponent range of representable and computable values

Exercises
32.9.1.(2) Using our FPF(10,4) representation with a single signed decimal digit for exponent,
create three pairs of numbers such that dividing the first number by the second generates
1. an overflowed result with exponent 2EMax,
2. an underflowed result with exponent 2Emin, and
3. an underflowed result that can be denormalized to have exponent Emin.
32.9.2.(3) Show the results of these operations in FPF(10,4), and indicate whether the result is
normal, overflowed, underflowed, or can be denormalized to have exponent EMin. Assume
that both guard and rounding digits are used.
1. [ + 8+ .4946] + [ + 8+ .5429]
2. [ + 8+ .4946] [ + 8+ .5429]

570

Assembler Language Programming for IBM z System Servers

Version 1.00

32.10. Exponents and Characteristics


The examples above used exponents with a sign and a single decimal digit having values from 9
to + 9. If the sign and digit were represented in binary on a real computer, we would need one
bit for the sign and 4 bits for the digit. But with the same 5 bits, we can represent signed binary
numbers from 16 to + 15. This greater range of exponent values shows why floating-point data
representations use binary exponents.
All z System floating-point systems use a form of exponent representation called a characteristic.
Because exponents can take both positive and negative values, internal arithmetic involving the
exponent is simplified by adding a bias that makes the characteristic an unsigned number.
This eliminates the problems of dealing with two different signed values in a single number (the
significands + and the exponents ) and makes it easier to handle and detect both normal and
abnormal conditions. When we multiply two numbers, one bias value is subtracted and then the
characteristics are added; if a carry is detected after the characteristic addition, we know that an
exponent overflow has occurred, and if the result would be negative we know that an exponent
underflow has occurred.
Similarly, in division we add one bias value and subtract the characteristic of the divisor; and for
addition and subtraction, the difference in characteristics determines the number of places the
smaller operand must be shifted.
To illustrate, suppose we decide to restrict our decimal exponent to a single unsigned digit. If we
choose E m a x = + 4 and E m i n = 5, we need to add a + 5 bias for unsigned characteristic
values between 0 and 9. The number 100 previously represented as [ + 3+ .1000] in this new
FPFa(10,4) representation would be [ + 8+ .1000]. Similarly, the true MaxReal [ + 9+ .9999]
would be represented as [ + 4+ .9999] and the true MinReal [0+ .1000] would be represented as
[ 5+ .1000].
If we multiply this proposed MaxReal by itself, the characteristic of the intermediate result would
be + 18 5, or + 13, corresponding to an exponent + 8. Because Emax = + 4, an exponent overflow condition would be recognized. Similarly, if we add this MaxReal to itself, the intermediate
result would be [ + 10+ .1000] because the rounded fraction was shifted right one position and the
characteristic was incremented by one. The characteristic + 10 corresponds to an exponent + 5,
which exceeds Emax by 1.
The choice of a bias value not only determines the range of representable values, but influences
arithmetic using those values. For example, suppose we divide 1 by this proposed MinReal: if we
use true exponents for a moment, we find
[+1+ .1000] [-5+ .1000] = [+7+ .1000]
But this number is about 100 times larger than MaxReal!
The solution to this range asymmetry is to choose the bias to be 4 instead of 5. Now, in this
updated FPFb(10,4) representation, + MaxReal would be [ + 5+ .9999] and + MinReal would be
[ 4+ .1000]. Now, if we divide 1 by the new MinReal, the result (again using true exponents) is
[+1+ .1000] [-4+ .1000] = [+6+ .1000]
and this result is just a tiny bit larger than MaxReal.
These examples show how the choice of bias can influence the range of computable results. The
bias is usually chosen to try to minimize range asymmetries.

Exercises
32.10.1.(2) Short hexadecimal floating-point is a FPF(16,6) representation with EMax= + 63
a n d E M i n = 64, with characteristic bias + 64. Show the hexadecimal values of Max and Min.

Chapter IX: Floating-Point Data and Operations

571

32.10.2.(2) Using the same representation as in Exercise 32.9.1, estimate its range asymmetry.
32.10.3.(3) Review Exercise 32.9.1. Then, estimate the range asymmetry if the same exponent
range is used with characteristic bias + 65. Also, estimate the values of MaxReal and MinReal.

32.11. Summary
This has been a brief overview of floating-point arithmetic. The examples weve seen represent
the behavior of the three floating-point representations used in z System, although each has its
variations on the themes described in this section.

Terms and Definitions


bias
A fixed value added to an exponent so that the exponent field always contains a nonnegative
value, the characteristic.
characteristic
The true exponent plus the bias.
MaxReal
The largest representable floating-point magnitude, also called Max.
MinReal
The smallest representable floating-point magnitude. If normalized, it is also called Min; if
denormalized, it is also called DMin.
exponent overflow
A condition arising when the exponent of a calculated result is too large to be contained in
its floating-point representation.
exponent underflow
A condition arising when the exponent of a calculated result is too small to be contained in
its floating-point representation.
normalization
A process of ensuring that the most significant digit in a fraction-based floating-point representation is nonzero.
pre-normalization
A process of normalizing the operand or operands before operating on it or them.
post-normalization
A process of normalizing the result operand after operating on it.
denormalization
A process of shifting the result fraction of a floating-point number to the right by enough
digit positions so the exponent will lie in a representable range.
guard digit
An extra internal digit used to increase the accuracy of a calculated floating-point result.
rounding digit
An extra internal digit used to help correctly round a calculated floating-point result.
ulp
An abbreviation for unit in the last place, a measure of the relative precision of a floatingpoint number.

572

Assembler Language Programming for IBM z System Servers

Version 1.00

33. Hexadecimal Floating-Point Data and Operations

3333333333
333333333333
33
33
33
33
3333
3333
33
33
33
33
333333333333
3333333333

3333333333
333333333333
33
33
33
33
3333
3333
33
33
33
33
333333333333
3333333333

This section examines the hexadecimal floating-point (HFP) representation and the instructions
for hexadecimal floating-point arithmetic. Hexadecimal floating-point was introduced with the original System/360, and is the oldest of the three z System floating-point representations.

33.1. Hexadecimal Floating-Point Data


The hexadecimal floating-point representation uses hexadecimal fraction digits and a binary exponent representing a power of 16. All significant digits are present; none are implied. A number X
in hexadecimal floating-point form is
X = f 16e
where f is a fraction with value less than one, and e is a positive or negative binary integer
exponent with value between 64 and + 63, so that
64 e +63
For example, the number 1 can be represented in decimal as 10010 2, 1.00100, and 0.0001104,
and in hexadecimal as X10016 2, X 1 160, and X0.0001164. The normalized short
floating-point form is X.100000161.
Figure 364 shows the three hexadecimal floating-point formats. The sign bit S is 0 for positive
numbers and 1 for negative numbers. The exponent is represented as an unsigned characteristic in
twos complement form, obtained by adding a bias 64 to the exponent:
characteristic = exponent + 64 = exponent + X 4 0
Thus, the characteristic satisfies
0 characteristic 127
The sign and seven-bit characteristic occupy the first byte of the number, and the magnitude of
the fraction is carried in the remaining bytes, as shown in Figure 364.

Chapter IX: Floating-Point Data and Operations

573


S char 6 digit fraction
Short: 4 bytes
FPF(16,6)
0
8
31

S char 14 digit fraction


Long: 8 bytes
FPF(16,14)
0
8
63

S char first 14 fraction digits...


Extended:
16 bytes
/////// ...remaining 14 fraction digits
FPF(16,28)

0
8
63
Figure 364. Hexadecimal floating-point number representations

The short-format fraction has 6 hexadecimal digits, the long-format fraction has 14, and the
extended-format fraction has 28. The high-order byte of the second portion of the extended
format is ignored.202
To illustrate a short hexadecimal floating-point representation, consider the value + 123.4567 that
we converted to scaled fixed-point binary in Section 31.3.
1. The integer value 123 = X 7B , giving the first two digits of the hexadecimal fraction.
Because the significand is a fraction, 123 must be represented as X . 7 B 16 + 2. Thus, we know
that the exponent is + 2 and the characteristic is 66 = X 4 2 .
2. The fraction value .4567 = X . 7 4 EA48A... , which rounds to X . 7 4 EA .
3. We now combine the parts:
The sign is + , so the first bit is zero.
The characteristic is X 4 2
The hexadecimal fraction is X . 7 B74EA
The converted representation is X427B74EA
Table 221 summarizes the properties of hexadecimal floating-point numbers. The column headed
Precision gives the number of hexadecimal digits in the fraction.
Byte
length
4
8
16

Char.
(bits)
7
7
7

Min
exp.
64
64
64

Max
exp.
+ 63
+ 63
+ 63

Char.
Bias
+ 64
+ 64
+ 64

Precision
6
14
28

Max Norm.
(Max)
7.210 + 75
7.210 + 75
7.210 + 75

Min Norm.
(Min)
5.410 79
5.410 79
5.410 79

Min Denorm.
(DMin)
5.110 85
1.210 94
1.710 111

Table 221. Hexadecimal floating-point data representations

These rules determine a unique representation for a normalized number X:


1. If f = 0, and e = 64, then X is a true zero; that is, everything except possibly the sign bit
S is zero.
2. If f = 0 and e > 64, then X is a pseudo-zero (the characteristic is nonzero).
3. If 1.0 > f 1/16, then X is said to be normalized (the most significant fraction digit is
nonzero).

202

574

The unused bits of the extended format were used to greatly extend the exponent range in a special form called the
Extended Exponent Range Representation, or XEXP. It was implemented only in software.
Assembler Language Programming for IBM z System Servers

Version 1.00

However, the representation of X could be unnormalized:


4. If 1/16 > f > 0, then X is unnormalized (there is at least one leading zero digit in the fraction).
A number X has a unique normalized representation, and may have several unnormalized representations with the same value. For example, we can represent the number 1.0 in several ways;
only the first is normalized:
41100000

42010000

43001000

44000100

45000010

46000001

If the value is not an integer, the unnormalized forms may not have the same value as the normalized form. For example, if we chose to represent the decimal fraction 0.1 as an unnormalized
short floating-point number, it might appear to have the following equivalent representations:
4019999A

4101999A

4200199A

4300019A

4400001A

45000002

The values represented become less accurate as the amount of unnormalization increases.
4019999A
.100000023

4101999A
.100000381

4200199A
.100006104

4300019A
.100097656

4400001A
.101562500

45000002
.125000000

In the last case, the value of the number is not 0.1 (base 10) but 0.125, which would be unacceptably different for most applications. Thus, normalized floating-point numbers offer the greatest
precision: they contain more digits with reliable values. This is not the same as saying that normalized results are more accurate, because there may be other errors in a calculation which cause
the results to be incorrect even though all six digits are always retained in the answer.
Table 222 shows some unnormalized numbers in short hexadecimal floating-point format, and
their corresponding normalized forms:
Unnormalized
40030000

Normalized
3F300000

41003000

3F300000

620AB128

61AB1280

4300009E

3F9E0000

CB00FACE

C9FACE00

03000123

00123000

Table 222. Unnormalized and normalized short hexadecimal floating-point


numbers

Table 223 shows some examples of short hexadecimal floating-point numbers: Their representations are fairly simple because all the quantities are multiples of powers of two.
Value
1
1
256
7/8
5/4
1/1024
1000/1024

Fraction-exponent
representation
+ 1161
+ .0001164
+ .000001168
+ E160
.14161
+ .416 2
+ .FA160

Short floating-point
representation
41100000
44000100
48000001
40E00000
C1140000
3E400000
40FA0000

Table 223. Short hexadecimal floating-point numbers

Consider the representation of + 1000/1024:


First, 1000.10 = X 3 E8. = B0011 1110 1000.
Dividing by 1024 shifts this value right 10 bits, giving X . FA = B.1111 1010 0000
Chapter IX: Floating-Point Data and Operations

575

The result has exponent 0 and characteristic X 4 0 , giving X40FA0000 as the hexadecimal
floating-point representation.
Long floating-point numbers are 8 bytes long; Table 224 shows some typical examples.
Value
1
0.1
256
1000
7/8

Fraction-exponent
representation
+ 1161
+ .110 1
1163
+ 1000.0103
+ E160

Long floating-point
representation
41100000 00000000
40199999 9999999A
C3100000 00000000
433E8000 00000000
40E00000 00000000

5/4
1/1024
1000/1024

.14161
+ .416 2
+ .FA160

C1140000 00000000
3E400000 00000000
40FA0000 00000000

Table 224. Long hexadecimal floating-point numbers

An extended-precision number is 16 bytes long, and is represented by a pair of long-precision


numbers, the high-order and low-order halves. The high-order half contains the sign, the characteristic, and the most significant 14 hex digits of the fraction of the extended number. The sign
and characteristic of the low-order half are ignored, and the fraction part of the low-order half
contains the least significant 14 digits of the fraction.203 (By convention, the characteristic of the
low-order half is set to 14 less than the characteristic of the high-order half.) Thus, an extended
number has a precision of 28 hexadecimal digits, equivalent to about 32 decimal digits.
Table 225 shows some examples of extended hexadecimal floating-point numbers.
Value
0.1

e
.000000000001

Fraction-exponent
representation
0.1100
.314159...10 + 1
.271828...10 + 1
.110 11

Extended floating-point representation


40199999
413243F6
412B7E15
37119799

99999999
A8885A30
1628AED2
812DEA11

32999999
338D3131
33A6ABF7
29197F27

9999999A
98A2E037
158809CF
F0F6E886

Table 225. Extended hexadecimal floating-point numbers

Exercises
33.1.1.(2) A four-byte area of memory contains the bit pattern X4040405C . What is represented by that pattern? (You should now be able to describe five different possibilities.)
33.1.2.(2) How many redundant values are there for these short HFP numbers? (a) 25, (b) 1,
(c) 0.25, (d) 0. How many redundant values for long numbers?
33.1.3.(1) + 25.5. Determine if each of the following short HFP numbers is a pseudo-zero, a
true zero, is normalized, or is unnormalized.
1.
2.
3.
4.
5.

203

576

X45678900
X FFFFFFFF
X00000001
X80000000
X00FF00FF

The two halves of an extended-precision hexadecimal floating-point number are not treated as independent values, as
is done on some other systems supporting double-double precision.
Assembler Language Programming for IBM z System Servers

Version 1.00

6. X40000000
7. X C400C1D4
33.1.4.(3) The XEXP representation mentioned in the footnote on page 574 stated that the
unused bits of the low-order characteristic were used to extend the exponent range of extendedprecision numbers. Assuming that the sign bit was reserved and the remaining 7 bits were used
to extend the high-order characteristic, what would be the resulting exponent range?
33.1.5.(2) + Given the quantities Z, A, B, C, D, E, and D as in Exercise 2.8.5, give their representations in short hexadecimal floating-point form.
33.1.6.(2) Given a short precision hexadecimal floating-point number S, write fixed-point
instructions to calculate short floating-point numbers with (a) the largest power of 16 S, and
(2) the smallest power of 16 S. Store the results at S1 and S2. Ignore the possibility of exponent underflow or overflow.
For example, if S=X42280000= 4 0 10, then the result at S1 is X42100000= 1 6 1 and the result
at S2 is X43100000= 1 6 2.
33.1.7.(2) Can you extend the instructions you wrote in solving Exercise 33.1.6 for long and
extended precision operands? Why or why not?

33.2. Writing Hexadecimal Floating-Point Constants


As mentioned in Section 31.8, the basic lengths of all floating-point constants are determined by
types E (short), D (long), and L (extended). The default length and alignment are word,
doubleword, and doubleword. The default alignment in memory of an extended-precision
number is only to a doubleword boundary, not to a 16-byte double-doubleword or
quadword boundary.
The syntax of DC assembler instruction statements for HFP constants is
DC

[dup_factor]type[modifiers] value[dec_exponent]

Like many other numeric constants, you can provide several value[dec_exponent] values separated by commas.
where

the duplication factor [dup_factor] is optional,


the type is required,
the [modifiers] are optional,
a value is required, and
the decimal exponent [dec_exponent] is optional.

This constant has all five items:


DC

2EL4S1E-27.73E8

The duplication factor is 2, the type is E, the three modifiers are L4, S1, and E 2;, the
value is 7.73, and the decimal exponent is E8.
Table 226 gives some examples of simple floating-point constants. For extended-precision constants, the Assembler gives the same signs to the high-order and low-order halves, and the characteristic of the low-order half is 14 less than the characteristic of the high-order half. The CPU
does the same for the results of extended-precision arithmetic operations.

Chapter IX: Floating-Point Data and Operations

577

DC Operand
E1000

Assembled Constant
433E8000

E22.75

4216C000

D3.142

413245A1 CAC08312

E100.04

42640A3D

D.0000923

3D60C897 B3E64BFA

D729

432D9000 00000000

E -55

C3370000

D -7088.263

C41BB043 53F7CED9

L 1 . 0

41100000 00000000
33000000 00000000

L 0 . 1 E-70

0611AB20 E472914A
786BEAF3 890FCB47

Table 226. Assembled hexadecimal floating-point constants

Consider the second constant: 22 = X 1 6 , and .75 = 12/16 = X . C . Putting these two parts
together we get 22.75 = X 1 6 .C or X . 1 6C 16 + 2. (Remember, the significand is represented as
a hexadecimal fraction!) So the characteristic is + 2 + 6 4 = X 4 2 , and the entire 8-digit constant is
therefore X4216C0000 .
The Assemblers decimal to hexadecimal floating-point conversion is rounded, but hexadecimal
floating-point arithmetic performed by the CPU is almost always unrounded.

33.2.1. Decimal Exponents


If a constant has many leading or trailing zeros, it is inconvenient to have to write out all the
digits; the operand E10000000000000 is an awkward way to define the constant 1013 . To simplify writing such constants, two different methods may be used, both of which specify a power of
ten by which the value must be multiplied: one is to use a decimal exponent with the nominal
value, and the other is to use an exponent modifier.
As we saw for F and H-type binary constants in 12.1. F-Type and H-Type Constants on page
148, a decimal exponent is written as the letter E followed by a positive or negative integer
which specifies the power of ten by which the constant is to be multiplied. It is written immediately following the value of the constant. For instance, we could write a DC statement operand
to define four constants of value 1013 like this:
DC

E 1 E13 , E 1 . 0 E13 , E100E11 , E 1 0 . E+12

Table 227 shows some examples of constants with decimal exponents.


DC Operand
D . 1 E+4

Assembled Constant
433E8000 00000000

D . 1 E+3

42640000 00000000

D . 1 E-1

3F28F5C2 8F5C28F6

D . 1 E-2

3E418937 4BC6A7F0

D . 1 E-3

3D68DB8B AC710CB3

D . 1 E-4

3CA7C5AC 471B4784

Table 227. Hex floating-point constants with decimal exponents

The previous rules for using literals also apply to hexadecimal floating-point literals.

578

Assembler Language Programming for IBM z System Servers

Version 1.00

Exercises
33.2.1.(1) Some HFP constants have one or more trailing zero digits. Does the generated constant for
DC

E 1 E13

contain all the significant bits of the value 1013? How could you tell whether it does or does
not?
33.2.2.(2) Write a single DC statement that generates a table of 11 short HFP constants containing the powers of 10 from 0 to 10.
33.2.3.(2) What is the largest power of 10 that can be stored precisely as (1) a short, (2) a long,
(3) an extended HFP number?
33.2.4.(1) + Write statements to generate the nine hexadecimal floating-point constants for the
decimal fractions from 0.1 to 0.9 in steps of 0.1.

33.3. Modifiers
Hexadecimal floating-point constants allow three types of modifiers: Length, Scale, and Exponent.
If any are present, they must appear in that order.

33.3.1. Length Modifiers


As with other constants, you can use the L modifier to define explicit lengths; the generated constants are not aligned. Truncation or padding takes place on the right. Thus, the DC operand
EL2 1 generates the constant X4110, and DL3 0 . 1 generates X40199A . The Assembler rounds
the fraction to the specified length.
Length modifiers are rarely used with floating-point constants, and then mainly to cause unaligned
data in a tightly-packed data structure. Generating a shorter constant loses precision, as Table
228 shows:
DC Operand
EL42.71965

Generated Constant
X412B83B0

EL32.71965

X412B84

EL22.71965

X412C

EL12.71965

X 4 1

(Error!)

Table 228. Length-modified hexadecimal floating-point constants

Note that as each fraction grows shorter, the lowest-order digit is rounded to compensate for the
truncated portion that was removed. The Assembler issues an error message for the last case to
indicate that all precision has been lost.

33.3.2. Scale Modifiers (*)


Obscure topic
Because scale modifiers are used very rarely for floating-point constants,
feel free to skip this subsection.
Like the scale modifiers described in Section 31.3.2 for binary constants, a scale modifier is used
to generate an unnormalized HFP constant. It is written as the letter S followed by either a
decimal self-defining term or a nonnegative absolute expression enclosed in parentheses; the
Chapter IX: Floating-Point Data and Operations

579

decimal value or the parenthesized expression may be preceded by a + sign if desired. The
value of the scale modifier determines the number of leading zero digits in the fraction: the
number of hex digit positions the fraction is to be shifted to the right.
Scale modifiers larger than 5 for short, 13 for long, and 27 for extended operands will cause all
significant digits to be lost, so the Assembler considers this an error.204 The characteristic of the
generated number is adjusted upward by the number of hex digits shifted, so that the value of the
constant remains the same, subject to the possible loss of accuracy caused by the right shift. For
example:
DC
DC
DC
DC
DC
DC
DC

ES0 1 . 0
ES1 1 . 0
ES2 1 . 0
ES3 1 . 0
ES4 1 . 0
ES5 1 . 0
ES515.999

Generates
Generates
Generates
Generates
Generates
Generates
Generates

X41100000
X42010000
X43001000
X44000100
X45000010
X46000001
X47000001 (rounded!)

The Assembler rounds the remaining portion of the fraction to account for the part that was
shifted off; if after rounding there is a carry into a zeroed digit position, the fraction is shifted right
once more, and the characteristic is adjusted accordingly.

33.3.3. Exponent Modifiers


Unlike a decimal exponent, an exponent modifier appears before the nominal value of the constant or constants. It is written as the letter E followed by either a decimal self-defining term or
an absolute expression enclosed in parentheses. A sign may precede the decimal value or the
parenthesized expression.
We can write the constant 1013 as EE13 1 , EE6100E5 , EE-2 1 . 0 E15 , EE-(3-1) 1 . E+15 or
EE17 1 E-4 , where the exponent modifier is indicated by a bold-face E and the decimal exponent
by an underscored E. The modifying power of ten applied to each constant is the sum of the
decimal exponent and the exponent modifier.
Either method is accepted for a given constant, so you might ask why both methods are used.
One possibility is that you might want to specify multiple constants in a single operand, as in
DC

EE21,20,3E3,4E22

Four short HFP constants

where the exponent modifier 2 applies to all the constants generated, while each decimal exponent
affects only the value to which it is appended. The values of the third and fourth operands are
affected by both an exponent modifier and a decimal exponent.
The allowed range for exponents is such that the sum of the decimal exponent and the exponent
modifier must lie between 85 and + 75.
The constants in Table 229 will be assembled as shown, where we assume the absolute expression
(B A) has value + 4.
As noted following Table 228, the characteristic is adjusted to compensate for shifts due to
scaling.

204

580

If the scale modifier is equal to the fraction length, the assembler notes that precision is lost; if the modifier exceeds
the fraction length, it is considered invalid.
Assembler Language Programming for IBM z System Servers

Version 1.00

DC Operand
EL5E1 1 0

Assembled Constant
4264000000

EL3S1E1 1 0

430640

DS13 . 5

4E000000 00000008

ES1E1 1

420A0000

E.999999

40FFFFEF

EE-((8+4)/6) 1 E15

4B9184E7

EL(B-A)S(B-A)E(B-A) 4

4800009C

ES5 3 1

47000002

2EL4S1E-27.73E8

47075F3547075F35

Table 229. Hexadecimal floating-point constants with modifiers

Exercises
33.3.1.(2) What would you expect the Assembler to generate for these hexadecimal floatingpoint constants?
A
B
C
D
E

DC
DC
DC
DC
DC

EL1 2 5
EL2 . 1
DL2999
DL1 1
EL21000

33.3.2.(1) What decimal values are represented by these constants?


W
X
Y
Z

DC
DC
DC
DC

DE5 3 . 7 E-2
EE-25 1 . 0 E80
LE2 8 . 8 E-2
EE9 4 E9

33.4. Subtypes Q and H (*)


Hexadecimal floating-point constants allow two subtypes, Q and H.

33.4.1. LQ-Type Constants


The Q subtype is used only with type L, and its only effect is to align the generated constant on a
quadword (16-byte) boundary. For example:
DC
L 0 . 1
DC
LQ 0 . 1
- - DS
0LQ
DC
CL32 Characters!

Doubleword aligned
Quadword aligned
Align to quadword boundary
Quadword-aligned character string

Figure 365. Quadword aligned constants and data

To be sure your constants and data are correctly aligned on quadword boundaries when your
program is loaded into memory for execution,

Chapter IX: Floating-Point Data and Operations

581

1. use the Assemblers SECTALGN(16) option to request that all control sections 205 begin in
quadword boundaries, and
2. verify that the linker and loader of your operating system support quadword alignment.

33.4.2. Subtype H
Specifying subtype H for hexadecimal floating-point constants lets you specify
more precise rounding
value suffixes to choose a rounding mode
symbolic operands (Max), (Min), and (DMin) with optional signs
Without the H subtype, the Assembler rounds HFP constants by adding 1 to the first lost bit
position, just as we do decimal rounding by adding 5 to the first lost decimal digit. When you
specify subtype H, five rounding modes can be specified by adding Rn at the end of the
nominal value, where the number n selects a rounding mode shown in Table 230.
Mode
R1
R4

R5
R6
R7

Rounding
Add 1 to the first lost bit (this is the default mode).
Round the exact value to the nearest representable machine value.
If the exact value is exactly half-way between two machine
numbers, choose the one with a zero low-order bit.
Round toward zero: truncate by discarding any extra bits.
Round toward the maximum positive value (toward + )
Round toward the maximum negative value (toward )

Table 230. Hexadecimal floating-point rounding modes with subtype H

The rounding-mode suffix must follow the value of the constant, including any decimal exponent.
Figure 366 gives some examples of HFP constants using rounding-mode suffixes:
DC
DC
DC
DC
DC
DC
DC
DC
DC

EH 0 . 1 R1
generates
EH 0 . 1 R4
EH 0 . 1 R5
EH 0 . 1 R6
EH 0 . 1 R7
EH1048576.5R1
EH1048576.5R4
EH1048577.5R1
EH1048577.5R4

X4019999A
X4019999A
X40199999
X4019999A
X40199999
X46100001
X46100000
X46100002
X46100002

rounded
rounded
rounded
rounded

up
down to even
up
up to even

Figure 366. Hexadecimal floating-point constants with rounding suffixes

The value 1048576.5 has hexadecimal representation X100000.8, exactly halfway between
X100000 and X100001. Standard rounding (R1) rounds the lost bit up, while Round to
Even (R4) rounds to the nearest number with a low-order zero bit, X100000. Similarly, the
representation of 1048577.5 is X100001.8; in this case, Round to Even rounds up to
X100002.
The difference between these two rounding modes is sometimes important when you create data
for floating-point arithmetic.
Table 231 shows The symbolic operands and their generated constants:

205

582

More about control sections in Section 38.


Assembler Language Programming for IBM z System Servers

Version 1.00

Constant Type

DC
Operand

Generated Constant

Maximum Magnitude

EH ( Max)
DH ( Max)
LH ( Max)

X 7 FFFFFFF
X 7 FFFFFFF FFFFFFFF
X 7 FFFFFFF FFFFFFFF 71FFFFFF FFFFFFFF

Minimum Normalized
Magnitude

EH ( Min)
DH ( Min)
LH ( Min)

X00100000
X00100000 00000000
X00100000 00000000 72000000 00000000

Minimum Denormalized Magnitude

EH ( DMin)
DH ( DMin)
LH ( DMin)

X00000001
X00000000 00000001
X00000000 00000000 72000000 00000001

Table 231. Symbolic hexadecimal floating-point constants

33.4.3. Difficult Numbers (*)


Obscure topic
This section will be interesting mainly to mathematically inclined readers.
In addition to symbolic operands and rounding modes, H subtypes are converted using greater
internal precision, so certain difficult numbers may be slightly more accurate.
Difficult numbers are those whose exact values lie very close to half way between two representable numbers, so extra precision is needed to determine how they should be rounded. Not
only are they difficult to convert accurately, its difficult to find them! Here are some examples:
DC Operand
D.30332554866797714604E-10

Without H Subtype
X382159DA E5B7B6BD

With H Subtype
X382159DA E5B7B6BE

D.185240322463448422373E-23

X 2 D23D4A8 0F402692

X 2 D23D4A8 0F402693

E.1053771313464019060319004056804E-41

X 1 E177FF8

X 1 E177FF9

L.8031692147E-10

X38584F34 1F25338E
2A9D527E 34864A16

X38584F34 1F25338E
2A9D527E 34864A17

Table 232. Difficult hexadecimal floating-point conversion values

Exercises
33.4.1.(5) Find another difficult number.
33.4.2.(2) Write and assemble the third (E-type) difficult number as an L-type constant. What
property does the generated constant have that makes it difficult?
33.4.3.(2) The hexadecimal floating-point value of 10 3 to many digits is
3E418937 4BC6A7EF 9DB22D0E 56041893 74BC6A7E F9DB22D0 E5604189 ...
If this is rounded to long format using rounding-mode suffixes R1, R4, and R5, what will be
the generated result?

Chapter IX: Floating-Point Data and Operations

583

33.5. Basic Hexadecimal Floating-Point Instructions


We will be concerned mainly with instructions for multiplying, dividing, adding, and subtracting
hexadecimal floating-point operands. Well describe some details of their operation, but you
dont need to fully understand these details to use them.
For these instructions, the CPU
uses a single hexadecimal guard digit, and
truncates all results without rounding.
Later in this section well see some instructions that round their results.
In most operations on extended-precision numbers, the CPU gives the same signs to the highorder and low-order halves, and the characteristic of the low-order half will be 14 less than the
characteristic of the high-order half.

33.6. Hexadecimal Floating-Point RR-Type Data-Movement Instructions


Some instructions used for all types of floating-point operands were described in Section 31.9;
these instructions are specifically for hexadecimal operands.
Op
32
31

Mnem
LTER
LNER

Type Instruction
R R Load and Test (Short)
R R Load Negative (Short)

Op
33
30

Mnem
LCER
LPER

Type Instruction
R R Load Complement (Short)
R R Load Positive (Short)

22
21

LTDR
LNDR

RR
RR

23
20

LCDR
LPDR

RR
RR

B362
B361

LTXR
LNXR

R R E Load and Test (Extended)


R R E Load Negative (Extended)

Load and Test (Long)


Load Negative (Long)

B363 LCXR
B360 L P X R

Load Complement (Long)


Load Positive (Long)

R R E Load Complement (Extended)


R R E Load Positive (Extended)

Table 233. Data-moving hexadecimal floating-point instructions

The register-to-register Load and Test, Load Positive, Load Negative, and Load
Complement instructions are similar to the corresponding general register instructions:

Load
Load
Load
Load

and Test sets the Condition Code to indicate the sign of a value
Positive sets the sign to +
Negative sets the sign to for nonzero values
Complement inverts the sign for nonzero values.

For hexadecimal floating-point, there are a few differences:


1. Negation only needs to invert the sign bit, and not complement all the other bits. Thus, no
overflow is possible when complementing an operand, and the characteristic and fraction are
unmodified.
2. In instructions that set the Condition Code, an operand is treated as zero if its fraction part is
zero. A pseudo-zero is treated as a zero even though its characteristic is nonzero.
3. If short operands are specified, only the left half of the register is involved. This means that in
testing the contents of the result register R1 in order to set the Condition Code, the low-order
half of the register is ignored. For example, if
c(FPR2) = X42000000 12345678
the instructions LTER

2,2 and LTDR

2,2 yield CC settings of 0 and 2 respectively.

4. Because only the sign bit is manipulated, it is possible to generate a minus zero, a number
with all zero bits except for sign. It still behaves like a true zero.
5. Operands are not normalized.

584

Assembler Language Programming for IBM z System Servers

Version 1.00

The CC settings after floating-point arithmetic are the same as for the GPR instructions: 0 for a
zero fraction, 1 for a negative result, and 2 for a positive result. These instructions do not set
Condition Code 3.
For example:
LD
LTDR
LCDR
LPDR

0,=DH ( Max)
0,0
6,0
6,6

Initialize FPR0
CC = 2
CC = 1
CC = 2

*
LE
4,=X46000000
LTER 4,4
LCER 2,4

Pseudo-zero in FPR4
CC = 0, c(FPR4)=X46000000
CC = 0, c(FPR2)=X C6000000

Figure 367. Examples of hexadecimal floating-point instructions

These extended-precision instructions have an additional behavior: for nonzero fractions, the
high-order and low-order signs are made equal, and the low-order characteristic is set to the highorder characteristic minus 14, modulo 128.
LD
4,=X 4 A123456789ABCDE Initialize FPR4
LD
6,=X00EDCBA987654321 ..and FPR6
LTXR 0,4
c(FPR0,2)=X 4 A123456789ABCDE..
..3CEDCBA987654321 , CC=2

Figure 368. Example of LTXR instruction

If the source operand is a pseudo-zero, the result characteristic and fraction are set to zero, and
the sign bits of the high-order and low-order halves are made identical.
LZXR 4
Set c(FPR4,6) to zero
LD
4,=X CE00000000000000
Negative pseudo-zero in FPR4
LTXR 0,4
c(FPR0,2)=X8000000000000000..
..8000000000000000 , CC=0
LCXR 0,4
c(FPR0,2)=X0000000000000000..
..0000000000000000 , CC=0

*
*

Figure 369. Examples of extended-precision hexadecimal R R instructions

Exercises
33.6.1.(1) If you execute these instructions:
LD
4,=X50123456789ABCDE
LD
6,=X FEDCBA9876543210
LTXR 0,4
What will be in the register pair (FPR0,FPR2), and what will be the CC setting?
33.6.2.(2) Suppose c(FPR0)=X 0 A123456789ABCDE and c(FPR2)=X42857196DBB93310 . Show
the CC setting and the contents of the result register or registers after executing each of the
following instructions:
(1)
(2)
(3)
(4)

LPER
LTDR
LCXR
LCDR

4,2
2,2
4,0
4,2

Chapter IX: Floating-Point Data and Operations

585

33.7. Hexadecimal Floating-Point Multiplication


Table 234 lists the hexadecimal floating-point multiplication instructions. None of them affect the
Condition Code.
Op
ED37

Mnem
MEE

7C
6C

ME,
MDE
MD

67

MXD

Type Instruction
R X E Multiply (ShortShort to
Short)
R X Multiply (ShortShort to
Long)
R X Multiply (LongLong to
Long)
RX

Op
Mnem
B337 M E E R
3C

Multiply (LongLong to
Extended)

Type Instruction
R R E Multiply (ShortShort to
Short)
R R Multiply (ShortShort to
Long)
R R Multiply (LongLong to
Long)

2C

MER,
MDER
MDR

27

MXDR RR

26

MXR

RR

Multiply (LongLong to
Extended)
Multiply (Ext.Ext. to Ext.)

Table 234. Hexadecimal floating-point Multiply instructions

Multiplication is the simplest HFP operation. Suppose we need to find the product z of two
numbers w and y. From the usual rules of algebra, we know that if w = F w 16Ew and
y = F y 16Ey then
z = (Fw Fy) 16(Ew + Ey)
so that F z = F w F y and Ez = Ew + Ey.
The CPU sets the result to a true zero immediately if either fraction is zero. Otherwise, the characteristic C z of the result is computed from
Cz = Cw + Cy 64 = Cw + Cy X 4 0
where X 4 0 is subtracted so that C z is biased only once. (See Exercise 33.7.7.)
The two fractions are pre-normalized, and the result characteristic is adjusted internally to account
for both shifts. The CPU then multiplies the two fractions to obtain the result fraction F z. Since
F x and F y were pre-normalized and both are nonzero, we must have a value for F z in the range
1.0 > Fz 16 2
so it may be necessary to shift F z left one digit to post-normalize the result fraction.
The sign of the result is determined from the rules of algebra, which means that an XOR is performed between the sign bits of the original operands. The result is placed in the floating-point
register specified by the first operand of the instruction.
Suppose we multiply w = 5 and y = 7. Then, C w = X 4 1 , C y = X 4 1 , F w = X.500000,
and F y = X.700000. The result characteristic C z is
Cz = X41 + X41 X40 = X 4 2
and the result fraction is X.230000, which requires no post-normalization. Thus, in short
floating-point form, we find that z = X42230000. The instructions in Figure 370 do this:
LE
2,W
MEE 2,Y
STE 2,Product
- - W
DC
E 5
Y
DC
E 7
Product DS
E

Put W in FPR2
Multiply by Y
Store the result
X41500000
X41700000
Result = X42230000

Figure 370. Short hexadecimal floating-point multiplication

Figure 371 shows the contents of the two floating-point registers:

586

Assembler Language Programming for IBM z System Servers

Version 1.00

FPR2 Before

//////// ////////

41500000 ////////

Operation
LE

2,W

MEE

2,Y

FPR2 After

41500000 ////////

42230000 ////////

Figure 371. Floating-point registers used for hexadecimal floating-point multiplication

To illustrate a typical use of hexadecimal floating-point multiplication, suppose we must calculate


Z(i)=X(i)X(i)Y(i) for values of i from 1 to 10, where X(i), Y(i), and Z(i) are short floatingpoint numbers in tables at XX, YY, and ZZ respectively.

Loop

XX
Count
YY
ZZ

XR
LH
LE
MEER
MEE
STE
LA
JCT
- - DC
DC
DC
DS

5,5
2,Count
0,XX(5)
0,0
0,YY(5)
0,ZZ(5)
5,L XX(,5)
2,Loop

GR5 contains index


Counter in GR2
Load X(i) in FPR0 (short)
X(i)*X(i) in FPR0
Multiply by Y(i)
Store short result Z(i)
Increment index by operand length
Count down and loop

E 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 1 0 Values of X(i)
Y((*-XX)/L XX)
Count of X(i) entries
5E3.14159,2.71828 2 YY(i) values, copied 5 times
10E
Results Z(i)

Figure 372. Calculating a table of short hexadecimal floating-point products

Note that in defining the symbol Count we use the length attribute of the symbol XX twice. If new
entries are added to the X(i) table, or if the X(i) entries are updated to long precision, the value at
Count will be updated automatically when you reassemble the program.
The general registers provide addressing and indexing; all floating-point arithmetic uses FPR0. If
the same calculation is done with long operands, the program segment would appear as in Figure
373.

Loop

XX
Count
YY
ZZ

XR
5,5
LH
2,Count
LD
0,XX(5)
MDR 0,0
MD
0,YY(5)
STD 0,ZZ(5)
LA
5,L XX(,5)
JCT 2,Loop
- - DC
10D 2 7
DC
Y((*-XX)/L XX)
DC
10D -263E-17
DS
10D

Initialize index to zero


Number of elements (10)
Load X(i) in FPR0 (long)
X(i)*X(i) in FPR0
Multiply by Y(i)
Store long result Z(i)
Increment index by operand length
Count down and branch
Some values for X(i)
Count of X(i) entries
And for Y(i)
Space for results

Figure 373. Calculating a table of long hexadecimal floating-point products

Here, the length attribute of the symbol XX is 8; in both figures, the number of elements at Count
is determined automatically by the Assembler.
The hexadecimal floating-point multiply instructions in Table 234 generate products of different
lengths, as summarized in Table 235. None of them set the Condition Code.

Chapter IX: Floating-Point Data and Operations

587

Operand 1

Operand 2

Product

Instructions

Short

Short

Short

Long
Extended

Long
Extended

Long
Extended

MD, MDR
MXR

Result
Truncated to
right half of
unchanged
Truncated to
Truncated to

Short
Long

Short
Long

Long
Extended

MDE (ME), MDER (MER)


MXD, MXDR

Exact product
Exact product

MEE, MEER

6 digits;
FPR R 1
14 digits
28 digits

Table 235. Summary of hexadecimal floating-point multiplication results

MEE and MEER generate the same short product as the high-order four bytes of the product
generated by MDE and MDER. You can think of ME and MER as the HFP equivalents of M
and MR, because both generate double-length products of single-length operands. Similarly,
MEE and MEER are equivalent to MS and MSR, because both generate single-length products
of single-length operands.206
To show how ME differs from MEE, suppose we revise Figure 371 as shown in Figure 374:
FPR2 Before

//////// ////////

41500000 ////////

Operation
LE

2,W

ME

2,Y

FPR2 After

41500000 ////////

42230000 00000000

Figure 374. Floating-point registers used for hexadecimal floating-point multiplication

In this case, the product is a long hexadecimal floating-point value.


There are no hexadecimal floating-point multiply instructions that use one short and one long
operand.
When you use MXD and MXDR, remember these considerations:
Because the first operands register pair will contain the extended product, R1 must be the lownumbered register of a floating-point register pair.
The fraction part of the low-order half of an extended result is not necessarily normalized
(because the 28-digit fraction is normalized in the high-order half). Its characteristic is 14 less
than the characteristic of the high-order half, except that 128 is added if the low-order characteristic becomes negative. No exponent underflow is indicated if the low-order characteristic
becomes negative.
To form the long product of the long operand in FPR0 by itself, we write
MDR

0,0

To form the extended product of the same long operand by itself, we would write
MXDR 0,0
and the original contents of FPR2 is replaced by the low-order half of the extended result. To
illustrate the use of MXD, suppose we wish to store at XPrd the extended product of the two long
operands stored at DA and DB.
LD
MXD
STD
STD

206

588

0,DA
0,DB
0,XPrd
2,XPrd+8

Load first operand into FPR0


Form extended product in FPR(0,2)
Store high-order half of product
Store low-order half of product

The ME and MER mnemonics were defined for System/360 and are still valid. MDE and MDER are recommended
because they more clearly indicate that multiplying two short operands yields a long product.
Assembler Language Programming for IBM z System Servers

Version 1.00

33.7.1. Exponent Overflow and Underflow.


Two error conditions can arise if the result characteristic lies outside the range
0 Cz 127.
If the left inequality is not satisfied (the result characteristic is negative), an exponent underflow
occurs; if the right inequality is not satisfied (the result characteristic exceeds 127), an exponent
overflow occurs. These two conditions are sometimes known as exponent or characteristic spill.
In both cases an interruption condition is recognized, and the quantity left in the result register
has the correct sign and fraction, but the characteristic field contains the rightmost seven bits of
the true characteristic. This treatment of the characteristic is called characteristic wraparound, in
the sense that 0 follows 127 for overflows, and 127 follows 0 for underflows.
To illustrate, if we multiply X70800000 by itself, the product fraction is X400000. The result
characteristic is
X70 + X70 X40 = X A0 (= X80 + X 2 0 ) ,
which is the same as X 2 0 when the rightmost seven bits are retained. The result is then
X20400000, with an overflow interruption.
Similarly, if we multiply X10800000 by itself, the result is X60400000. The result characteristic
is found from
X10 + X10 X40 = X20 = X80 + X 6 0 .
By retaining a result which is incorrect only by a fixed power of 16 (16128), you can take steps to
continue a calculation and still get a correct final result despite intermediate exponent spills.
Uninterrupted calculation of some results can depend on the order of the operations. Suppose
you must multiply the three numbers 16 50, 1640, and 16 60 . The product of the first two
numbers creates an overflow, and multiplying that product by the third number creates an underflow. But, multiplying the first and third numbers and then multiplying by the second generates
no interruptions. It helps to know the magnitudes of your operands!
Because exponent underflow means the result has become small enough to be considered negligible in certain circumstances, you can set the HFP Exponent Underflow bit (shown in Table 76
on page 236) in the Program Mask to zero to request that if an exponent underflow occurs, the
result should be set to a true zero and no interruption should occur. If the bit is 1, an interruption
due to exponent underflow does occur, and the Interruption Code is set to 13 (X D ). An interruption for exponent overflow cannot be suppressed; the Interruption Code is set to 12 (X C ).

Exercises
33.7.1.(3) Using short operands, modify Figure 372 on page 587 to show how to benefit from
a 12-digit product of the operands at XX to generate long results at ZZ.
33.7.2.(1) What two things can you say that are true for all products generated by ME and
MER?
33.7.3.(2) If the ME and MEE instructions rounded their results, could the four high-order
bytes be different if they multiply the same operands?
33.7.4.(2) Write a program segment that will compute a table of the cubes of the first 100 integers, and store them as short hexadecimal floating-point numbers starting at Cubes.
33.7.5.(2) What result will be in FPR0 after executing these instructions?
LD
0,=X4111111199999999
MEER 0,0
33.7.6.(3) Consider the product of any floating-point number with fraction part X . uvwxyz and
1.0, which has representation X41100000. Show that without a guard digit, the product fracChapter IX: Floating-Point Data and Operations

589

tion would be X . 0 uvwxy , which after post-normalization becomes X . uvwxy0 . What does this
mean for multiplication by 1?
33.7.7.(1) Show an easy way for the CPU to subtract X 4 0 from the sum of two characteristics.

33.8. Hexadecimal Floating-Point Division


Table 236 lists the five hexadecimal floating-point divide instructions. The sign of the quotient is
set to the XOR of the operand signs. The CC is not changed by a divide instruction.
Op
7D
6D

Mnem
DE
DD

Type Instruction
R X Divide (Short)
R X Divide (Long)

Op
3D
2D
B22D

Mnem
DER
DDR
DXR

Type
RR
RR
RRE

Instruction
Divide (Short)
Divide (Long)
Divide (Extended)

Table 236. Hexadecimal floating-point Divide instructions

Suppose we want to calculate z = w/y. If the divisor fraction F y is zero, the division is
improper and a HFP divide exception is initiated; the resulting program interruption sets the
Interruption Code to 15 (X F ), and the dividend operand in the first-operand register is
unchanged. If the dividend fraction F w is zero, the result is set to zero immediately. Otherwise,
both fractions are pre-normalized, and the result characteristic
Cz = Cw Cy + X40 = Cw Cy + 64
is adjusted to account for the normalizing shifts. The result fraction F z = F w / F y is then computed. Since we must have a value for F z that satisfies the inequalities
16 > Fz 1/16,
a single corrective right shift may be needed for a proper fractional result; the characteristic is
increased by 1 to account for the shift if it is performed, as we saw in Section 32.6.
Unlike fixed-point binary division where the remainder is in the even register and the quotient is
in the next higher-numbered odd register, no floating-point remainder is provided by the CPU.
Well see how to calculate a hexadecimal floating-point remainder in Section 33.15.
To give another example of hexadecimal floating-point division, suppose we divide x=3 by y=5.
Then,
Fw = X . 3 , Fy = X . 5 ,
Cx = Cy = X 4 1
Cz = X 4 1 X41+X40 = X 4 0 .
We know that the result fraction in decimal is 0.6; to convert this to hexadecimal we use the
method described in Section 31.2. on page 541:
0.6
16
9.6
so the first hexadecimal fraction digit is 9. But the next decimal digit is 6 again, so that
0.610 = X.9999999... and Fz = X.999999.
In short floating-point form, the quotient z is X40999999. This result is not rounded; the
rounded result would have been X4099999A . Thus,
LE
DE

0,=E 3
0,=E 5

Load FPR0 with 3 (X41300000)


Divide by 5
(X41500000)

leaves the unrounded quotient X40999999 in FPR0.


The hexadecimal floating-point divide instructions DE, DER, DD, and DDR are similar to the
four multiply instructions, except that the divisor, dividend, and quotient fractions are all 6 digits

590

Assembler Language Programming for IBM z System Servers

Version 1.00

long for short operand division, 14 digits for long operand division, and 28 digits long for
extended division.
No attempt is made to provide an inverse to the short multiply instructions by dividing a short
divisor into a long dividend. The low-order part of the register is ignored in short HFP division,
and is not replaced by a remainder.
If youre not dividing by zero, the quotient is computed; if a corrective right shift of the result
fraction is needed, the extra digit at the right end is lost and the quotient then replaces the dividend. Characteristic wraparound also applies to division: if we divide X60200000 by X10400000
the quotient is X10800000 with an exponent overflow indicated, and if we divide X16600000 by
X79200000, the result is X 5 D300000 with a (maskable) exponent underflow condition indicated.
Figure 375 illustrates floating-point divide instructions. Suppose we again have two arrays at XX
and YY of ten short hexadecimal floating-point operands X(i) and Y(i), and wish to store
Z ( i ) = |X(i) |/Y(i) 2 in the array at ZZ.

Loop

XR
LA
LE
LPER
LE
MER
DER
STE
LA
JCT

7,7
2,10
2,XX(7)
4,2
6,YY(7)
6,6
4,6
4,ZZ(7)
7,4(,7)
2,Loop

Set index in GR7 to zero


Initialize counter in FR2 to 10
Load X(i) in FPR2
Place absolute value in FPR4
Get Y(i)
Square it in FPR6
Form quotient in FPR4
Store Z(i)
Increment index
Count and loop

Figure 375. Example of hexadecimal floating-point divide instructions

It was unnecessary to use FPR4 as an intermediate register. Figure 376 shows another way to do
the same calculation. (It might run slightly slower because more divide instructions are used and
more memory accesses are required for the operands.)

Loop

XR
LA
LE
LPER
DE
DE
STE
LA
JCT

1,1
2,10
0,XX(1)
0,0
0,YY(1)
0,YY(1)
0,ZZ(1)
1,4(,1)
2,Loop

Initialize index
And counter
X(i) in FPR0
Abs(X(i)) in FPR0
Abs(X(i))/Y(i)
Abs(X(i))/Y(i)/Y(i)
Store Z(i)
Increment index
Count down and branch

Figure 376. Example of hexadecimal floating-point divide instructions

33.8.1. The Halve Instructions (*)


The two instructions in Table 237 divide an operand by 2 by doing a single binary shift, saving
the cost of a more expensive multiplication or division instruction. The first operand is replaced
by a number whose value is one-half that of the second operand. The Condition Code is
unchanged.
Op
34

Mnem
HER

Type Instruction
R R Halve (Short)

Op
24

Mnem
HDR

Type Instruction
R R Halve (Long)

Table 237. Hexadecimal floating-point Halve instructions

The fraction part of the second operand is shifted right by one bit position. The bit shifted off the
right end moves into the guard digit, which was initialized to zero. If the fraction is still normalized, the instruction is complete; otherwise a normalizing (hexadecimal) left shift is done, and the
characteristic is decreased by 1 for each shift. The result is not rounded.

Chapter IX: Floating-Point Data and Operations

591

For example:
LE
HER

0,=E 1 0
0,0

c(FPR0) = X41A00000
Result = X41500000 (no shift)

LE
HER

0,=E 1 . 0
0,0

c(FPR0) = X41100000
Result = X40800000 (normallized)

Figure 377. Example of a hexadecimal floating-point halve instruction

The only possible exception is an exponent underflow, as illustrated in Figure 378.


LE
HER

0,=EH ( Min)
0,0

c(FPR0) = X00100000
Result = X 7 F800000 with underflow

Figure 378. Hexadecimal halve instruction causing underflow

For short operands (using the HER instruction), the low-order part of the register is unchanged,
and does not contain the lost bit when no post-normalization is performed. If the fraction part of
the second operand is zero, a true zero replaces the first operand.

Exercises
33.8.1.(1) In calculating the quotient 3/5, the result is given as X40999999, and not the
rounded value X4099999A . How do we know what the rounded answer is?
33.8.2.(2) + What is the result of executing
HER

0,0

if FPR0 contains each of these operands:


1. X4013579B
2. X40013579
33.8.3.(2) + What is the result of executing
HDR

0,0

if FPR0 contains each of these operands:


1. X42FB2690 5A66B73D
2. X C5774302 D4FB018F
33.8.4.(2) What result will be in FPR4 after executing these instructions?
LE
HER

0,=X04000002
4,0

33.8.5.(1) What instructions involving the general registers might be thought of as the fixedpoint analogs of the floating-point Halve instructions HER and HDR?
33.8.6.(3) Write instructions to implement a rounded hexadecimal floating-point halve operation.

33.9. Hexadecimal Floating-Point Addition and Subtraction


There are two major groups of hexadecimal floating-point add and subtract instructions: those
that normalize their results, and those that do not. Both groups are listed in Table 238.

592

Assembler Language Programming for IBM z System Servers

Version 1.00

Op
7A
7B
6A
6B
36

Mnem
AE
SE
AD
SD
AXR

Type
RX
RX
RX
RX
RR

Instruction
Add (Short)
Subtract (Short)
Add (Long)
Subtract (Long)
Add (Extended)

Op
3A
3B
2A
2B
37

Mnem
AER
SER
ADR
SDR
SXR

Type
RR
RR
RR
RR
RR

Instruction
Add (Short)
Subtract (Short)
Add (Long)
Subtract (Long)
Subtract (Extended)

7E
7F

AU
SU

RX
RX

3E
3F

AUR
SUR

RR
RR

6E

AW

RX

Add (Short) Unnormalized


Subtract (Short) Unnormalized
Add (Long) Unnormalized

2E

AWR

RR

Add (Short) Unnormalized


Subtract (Short) Unnormalized
Add (Long) Unnormalized

6F

SW

RX

Subtract (Long) Unnormalized

2F

SWR

RR

Subtract (Long) Unnormalized

Table 238. Hexadecimal floating-point Add/Subtract instructions

Four distinctive properties of the hexadecimal floating-point add and subtract instructions are:
1. No initial tests are made for zero operands.
2. Neither fraction is pre-normalized.
3. The Condition Code is always set.
4. The operation code specifies whether or not the final result will be normalized.
The first step is to compare the characteristics of the operands. If the difference is such that the
fraction part of the operand with the smaller characteristic would have to be shifted to the right
by too many places so that no significant digits would be left, the result is the operand with the
larger characteristic. That is, the smaller operand is ignored in short arithmetic if the magnitude of
the characteristic difference is greater than 6, in long arithmetic if it exceeds 14, and in extended
arithmetic if it exceeds 28, because there could be no useful digit to add. In such cases, no shifted
digit could appear in the guard digit position.
For example, suppose we add the normalized short operands X58123456 and X52987654. The
characteristic difference X 5 8 X 5 2 = 6 means that the second fraction must be shifted right by
six digit positions, giving a fraction with six leading zero digits. Since the intermediate arithmetic
is performed with a precision of only seven digits, the second operand cannot possibly contribute
to the final result, so it is ignored. (Remember that the guard digit is initialized to zero!) To
visualize this process:
58123456(0)
+52987654

First operand, guard digit 0


Second operand before shifts

58123456(0)
+58000000(9)
58123456

First operand, guard digit 0


Second operand after shifts
Sum

Figure 379. Example of hexadecimal floating-point addition

Because the sum need not be normalized, the guard digit is lost.
Subtraction can be different; consider the same two operands:
58123456(0)
-52987654

First operand, guard digit 0


Second operand before shifts

58123456(0)
-58000000(9)
58123455

First operand, guard digit 0


Second operand after shifts
Difference

In this case, the digit shifted into the guard digit position causes a borrow from the low-order
digit of the first operand. Thus, if the operation is a subtraction, an exponent difference equal to
Chapter IX: Floating-Point Data and Operations

593

the number of digits in the significand does not necessarily mean that the result will be the larger
operand.
For addition, if the characteristic difference is equal to 6, 14, or 28, and if the operand with the
larger characteristic is unnormalized, a digit from the operand with the smaller characteristic may
appear in the result. (See Exercise 33.9.14.)
If the registers were longer, the second operand could contribute to the sum, so short and long
arithmetic might yield different results from the same data. (See Exercise 33.9.1.)
Adding (or subtracting) two numbers that lead to a zero fraction produces different results,
depending on the setting of the Program Mask. If the intermediate result fraction including the
guard digit is zero, a HFP significance exception may be recognized, meaning there are no significant digits in the result, only the correct sign and characteristic.
As with exponent underflow, you can zero the HFP Significance bit in the Program Mask (shown
in Table 76 on page 236) to request that the CPU ignore the exception condition and set the
result to a true zero.207 If the interruption does occur, the result register will contain a pseudo-zero
with the correct characteristic, and the Interruption Code will be set to 14 (X E ).
For example:
LE
AE

2,=X456789AB
2,=X C56789AB

If the Program Mask bit is zero, c(FPR2)=X00000000; but if the Program Mask bit is one,
c ( F P R 2 ) = X45000000 when the program interruption occurs.
The difference between a true zero is and a pseudo-zero is rarely important, so most applications
set the HFP-significance mask bit to zero so they dont have to worry about interruptions for
calculated zero results.
Suppose we must evaluate the expression
Z = T * (A + B) + 2C / (A + B)
where all operands are long and are found at memory locations with the same names.
LD
AD
HDR
MD
LD
DDR
ADR
STD

6,A
6,B
4,6
6,T
2,C
2,6
2,6
2,Z

Form sum first


(A+B) in FPR6
Save (A+B)/2 in FPR4
Multiply sum by T, giving T*(A+B)
Load C in FPR2
Divide by c(FPR4) giving 2C/(A+B)
Form Z in FPR2
Store the long result at Z

Figure 380. Evaluating a hexadecimal floating-point expression

Suppose we must form the inner product of two linear arrays of twenty short-precision elements each, by evaluating the sum
Z = X(1)*Y(1) + X(2)*Y(2) + ... + X(19)*Y(19) + X(20)*Y(20),
where the arrays of the X(i) and Y(i) values are stored starting at XX and YY respectively. The
value of Z will be accumulated in long precision, and stored in short precision.

207

594

In practice, the Significance exception is rarely enabled because it would occur even when a calculated result should
be zero. The Program Mask bit is almost always set to zero. (You can change the bits in the Program Mask with the
SPM instruction, as described in Section 16.2.)
Assembler Language Programming for IBM z System Servers

Version 1.00

TLen

Loop

EQU
LZDR
XR
LA
LA
LE
ME
ADR
JXLE
STE

20
2
7,7
2,4
3,4*(TLen-1)
0,XX(7)
0,YY(7)
2,0
7,2,Loop
2,Z

Table length is 20
Initialize sum in FPR2 to zero
Initialize index to zero
Increment = 4
Comparand = 76
C(FPR0) = X(i)
C(FPR0) = X(i)*Y(i) (long result)
Add long product to retain accuracy
Increment index and branch
Store short floating-point result

Figure 381. Evaluating a hexadecimal floating-point inner product

As a second example, suppose we want to evaluate the polynomial


Z = A(10)*Y10 + A(9)*Y9 + A(8)*Y8 + ... + A(1)*Y1 + A(0),
where the coefficients A(k) are stored in an array starting at AA in the order A(0), A(1), ..., A(10).
We will do the evaluation by writing the polynomial in nested form (sometimes known as
Horners Rule):
Z = ((...((A(10) * Y) + A(9)) * Y + ... + A(1)) * Y + A(0))
Figure 382 shows an example using this method.
LE

Next

EQU
LHI
LA
LE
LE
MER
AE
JXH
STE

10
3,-4
2,4*(LE-1)
6,AA+4*LE
4,Y
6,4
6,AA(2)
2,3,Next
6,Z

Highest coefficient number


JXH increment and comparand in GR3
Initial index points to A(9)
Initial polynomial term is A(10)
Hold Y in FPR4, less memory access
Multiply current sum by Y
Add next coefficient
Decrease index by 4 and loop
Store short result

Figure 382. Evaluating a polynomial with hexadecimal floating-point arithmetic

For short polynomials it is simpler and faster to do the calculation without looping. If we want
only the quadratic portion (up to the second power in Y) of the same polynomial, we could use
the instructions in Figure 383:
LE
ME
AE
ME
AE
STE

0,AA+8
0,Y
0,AA+4
0,Y
0,AA
0,Z

Get A(2)
*Y
+A(1)
*Y
+A(0)
Store at Z

Figure 383. Evaluating a quadratic polynomial

and no loop-control housekeeping instructions are needed.

33.9.1. Unnormalized Addition and Subtraction


Unnormalized addition and subtraction follow the same rules as the normalizing operations,
except that the result is not post-normalized. This leads to these conditions:
The guard digit is ignored (it participates only if a post-normalization shift is needed to deliver
a normalized result).
If the sum creates a carry out of the high-order digit, a corrective right shift is needed, so an
exponent overflow is possible. For example:
LE
AU

0,=X 7 FFE7654
0,=X 7 EFEDCBA

Large number in FPR0


Add another almost as large

generates an exponent overflow interruption, and the result in FPR0 is X0010E641 .


Chapter IX: Floating-Point Data and Operations

595

If there is no overflow, the characteristic of the result is that of the operand with the larger
characteristic (the fraction of the operand with the smaller characteristic will have been shifted
right).
Because there is no normalizing left shift, no exponent underflow is possible.
If the result fraction is zero, a HFP lost-significance exception is possible; if suppressed, the
result is set to + 0. For example:
LE
SUR

0,=X76543210
0,0

Initialize FPR0
Unnormalized subtraction

generates a significance-exception interruption, and the result in FPR0 is X76000000. If the


Program Mask bit is zero there is no interruption, and c(FPR0)=X00000000.
The test for a zero intermediate fraction includes the guard digit for normalized addition and subtraction, and excludes the guard digit for unnormalized addition and subtraction, because the
guard digit cannot appear in the final result. (See Exercise 33.9.9.)

33.9.2. Older Uses of Unnormalized Addition (*)


Some history
This section describes instructions that see relatively little use on modern
CPUs.
Before the instructions described in Section 33.14 on page 606 were available, unnormalized addition was needed to convert numbers between binary integers and HFP values. If we had to
convert 12345 from binary to hexadecimal floating-point we might have used the instructions in
Figure 384.

Const

L
1,=F12345
ST
1,Const+4
LD
0,=D 0
AD
0,Const
- - DC
0D,X 4E , 7 X 0

Binary integer to be floated


Store in right half of a constant
Clear FPR0
Add the constant
Unnormalized constant

Figure 384. Converting a binary integer to hexadecimal floating-point

After the ST instruction, c(Const)=X 4 E00000000003039 . Because its exponent is 14, the radix
point is at the right end of the constant; after executing the AD instruction to normalize the
result, c(FPR0)=X4430390000000000.
Converting in the other direction used a similar technique shown in Figure 385, this time with an
unnormalized addition:
LD
AW
STD
L

0,=D12345
Value to be converted to binary
0,=X 4 E00000000000000 Force unnormalization
0,DTemp
Store the result
1,DTemp+4
Binary integer now in GR1

Figure 385. Converting a hexadecimal floating-point number to a binary integer

After the AW instruction is executed, c(FPR0)=X4400000000003039. The L instruction finally


loads X00003039=12345 into GR1.
Newer instructions provide improved ways of converting between HFP and binary, as well see in
Section 33.14.

Exercises

596

Assembler Language Programming for IBM z System Servers

Version 1.00

33.9.1.(2) In Figure 379 on page 593, we considered adding the short operands X58123456
and X52987654. If these were the long operands X5812345600000000 and
X5298765400000000, what would be their sum?
33.9.2.(1) Suppose you execute these instructions:
LD
LD
AXR

2,=D 1 . 0
6,=D 2 . 5
2,6

What will be in FPR2?


33.9.3.(0) There is an engineers pun among the mnemonics in Table 238 on page 593. Can
you find it?
33.9.4.(2) + Given the following short hexadecimal floating-point operands:
A
B
C
D
E

=
=
=
=
=

X41200000
X C0138762
X420A0000
X 6 B200000
X45000000

Show (in hexadecimal) the appropriate contents of FPR0 and the setting of the Condition
Code after executing each of the following instruction sequences.
1. LE
SE

0,E
0,B

2. LE 0,D
MER 0,0

3. LE 6,E
LTER 0,6

4. LE
DE

0,C
0,D

33.9.5.(3) + Given the following hexadecimal floating-point quantities:


A
B
C
D
E

=
=
=
=
=

X C1200000
X4310000F
X03780000
X C400E000
X408279ED

Show (in hexadecimal) the contents of FPR0 and the Condition Code setting after executing
each of the following instruction sequences:
1. LE 0,A
AE 0,B

2. LE 0,E
AER 0,0

5. LE 0,C
MER 0,0

6. LE 0,A
AE 0,E

3. LE 4,B
HER 0,4

4. LE 0,B
DE 0,C

33.9.6.(3) + Using the same quantities as in Exercise 33.9.5, and these additional hexadecimal
floating-point quantities:
W = X04100000
X = X 0 B012335
Y = X4600ABCD
show (in hexadecimal) the contents of FPR0 and the Condition Code setting after executing
each of the following instruction sequences:
1. LE 0,A
AU 0,C

2. LE
AU

0,D
0,B

5. LE 0,W
AU 0,X

6. LE 0,Y
AUR 0,0

3. SER 0,0

4. LE 0,X
SU 0,X

33.9.7.(2) + Sometimes programs use data having the wrong type, as in this example. What
result will be in FPR0 after executing these instructions?
LE
AER

0,=F -3
0,0

Binary integer?
Added to itself as floating-point??
Chapter IX: Floating-Point Data and Operations

597

33.9.8.(1) Show that if an exponent overflow occurs in executing an unnormalized add or subtract instruction, the characteristic of the result must be zero.
33.9.9.(2) + Suppose X40FFFFFF is subtracted from X41100000 using (1) SE and (2) SU
instructions. What will be the result in each case?
33.9.10.(1) In Figure 382 on page 595, what conflicts might arise between the uses of LE as a
symbol and as a mnemonic?
33.9.11.(2) An array of short hexadecimal floating-point numbers is stored starting at Data, and
the number of elements in the array is in the fullword integer at NItems. Write instructions to
compute the average of the numbers and store the result at Average.
33.9.12.(2) Suppose you want to add 1000000 and 0.000001 using hexadecimal floating-point
arithmetic. What limitations should be imposed on the registers and operands if the result is to
be computed correctly?
33.9.13.(2) + Suppose you add X58023456 to X52987654. The difference in the characteristics
is 6; what is the result of the addition?
33.9.14.(2) Show the result in FPR0 after executing each of the following five pairs of
instructions:
(a)

LE
AE

0,=X41100005
0,=X40100005

(b)

LE
SE

0,=X41100005
0,=X40800005

(c)

LE
SE

0,=X41100000
0,=X38100000

(d)

LE
SE

0,=X41100000
0,=X 3 A100000

(E)

LE
AE

0,=X40123456
0,=X40100000
A Suggestion

The next two subsections (33.10 and 33.11) explore some details of
implementing floating-point addition and subtraction. If youre not interested, they can be skipped with no loss in continuity.

33.10. Adding Operands of Like Sign (*)


Adding operands of like sign (or true addition) is straightforward; the sign of the result is known.
If the original operands are normalized, the result fraction cannot need any post-normalizing left
shifts because no leading zero digits can be generated, and at most one corrective right shift (with
an accompanying increment of the characteristic) can be needed. Thus, true addition is the only
case in floating-point addition where exponent overflow can occur. The guard digit is significant
in like-sign addition only if unnormalized operands are used, and if the instruction also requires
that the result be normalized. A few examples of adding short operands will illustrate these points.
Example 1:

X40111111 + X40222222

Because the exponents are equal, the fractions are added directly, with result X40333333.
The CC is set to 2 to indicate a positive result.

598

Assembler Language Programming for IBM z System Servers

Version 1.00

Example 2:

X40123456 + X42456789

After shifting the fraction part of the smaller first operand right by two places, the intermediate result is X424579BD(5) , where the guard digit is parenthesized. The CC is again set to
2.
Example 3:

X42FEDCBA + X41456789

After shifting the second fraction to the right by one place, the intermediate sum is
X1.033332(9) with a carry bit (so seven digits plus a guard digit are shown). After a corrective right shift, the result is X43103333; both the guard digit and the low-order digit of the
intermediate sum are lost, and no rounding is done. The CC is set to 2.
Example 4:

X FF801020 + X FF934567

This case illustrates an exponent overflow: the result fraction is X1.145587(0), which after
right-shifting leads to characteristic X 8 0 and fraction X.114558(7). The guard digit is lost,
and because of characteristic wraparound the result becomes X80114558, and an exponent
overflow interruption is initiated. The CC is set to 1 indicating a negative result.
Exponent overflow during addition should be an infrequent occurrence, because the operands
involved must be quite large.
Example 5:

X43000123 + X416789AB

In this case the intermediate sum fraction X.0068AC(A) is unnormalized; if the result is normalized, we obtain X4168ACA0 , and the guard digit is retained.
Example 6:

X02000012 + X00023456

After right-shifting the second fraction by two places, the intermediate sum is
X02000246(5). On normalization, this gives X 7 F246500 , with an accompanying exponent
underflow exception condition.
If the Exponent Underflow mask bit is zero, no interruption occurs and the CC and the
result are set to zero. Otherwise, the result register is unchanged, the CC is set to 2 (the
result is positive), and an interruption occurs.
Exponent underflow can occur when adding numbers of like sign only if both operands are
unnormalized.

33.11. Adding Operands of Unlike Sign (*)


Adding operands of unlike sign (or complement addition) is more complicated.
1. No exponent overflow can be generated, because the difference of two operands is never
greater in magnitude than the larger of the original two.
2. Leading zeros can be generated in the fraction part of the intermediate result so that exponent
underflows can occur even with normalized operands.
Suppose we add 5 (X C1500000 ) and + 121 (where 121 = X 7 9 = X . 7 9 162 (X42790000).
After shifting the first fraction to the right by one digit position and subtracting it from the second
fraction, the intermediate result is X42740000(0). Since the result is now normalized and no
characteristic spill was generated, the result is X42740000 and the CC is set to 2 indicating a
positive result. If we use the same operands with inverted signs, the same process generates
X C2740000 , with CC 1 indicating a negative result.

33.11.1. Hexadecimal Floating-Point Complement Addition (*)


Its easy in some cases to see what the result should be, by inspecting the operands: we observe
which is the larger, subtract the smaller, and use the sign of the operand with the larger magnitude.
But the CPU cannot compare the operands to see which has the larger magnitude without doing
a subtraction! It would have to duplicate much of its effort if a comparison indicated that the
subtraction should actually have been done in the opposite order. Thus, a technique similar to

Chapter IX: Floating-Point Data and Operations

599

that for fixed-point arithmetic is used, where subtraction was performed by adding the twos complement of the second operand to the first.
We cant do the same with the fraction parts of the floating-point operands, because the sign bit is
not an extension of the fraction: that is, the fractions are represented in a sign-magnitude representation.
Though z System may not do complement addition exactly this way, we will describe a method,
using the short-arithmetic addition of 5 and + 121.
1. Given operands X C1500000 and X42790000, determine whether one of them has a characteristic larger than the other; call it the first operand. If the characteristics are equal, simply
choose one of the operands as the first. (Thus, X42790000 is the first operand.)
2. As in true addition, if the characteristic difference exceeds 6 for short, 14 for long, or 28 for
extended operands, the intermediate result is the first operand.
3. As in true addition, shift the fraction part of the second operand to the right by a number of
places equal to the magnitude of the characteristic difference. In our example, the second
operand fraction is shifted once to produce X.050000(0), with the seventh digit being the
guard digit.
4. The sign of the intermediate result is assumed to be the same as the sign of the first operand
( + in this example).
5. The twos complement of the second fraction is added to the first fraction, with carries off the
left being ignored. Thus, we add X.790000(0) + X . FB0000(0) , giving X(1).740000(0).
The carry bit is explicitly indicated, even though it doesnt appear in the result.
6. Depending on the presence or absence of a carry, one of the following is performed:
a. if there is a carry, it is ignored and the intermediate result consists of the first operand
sign, the first operand characteristic, and the intermediate fraction to whatever precision
it was calculated.
b. if there is no carry, the intermediate result fraction is said to be in complement form. It is
then recomplemented, and the sign bit is inverted.
At this point the zero-fraction test for a Significance exception is made; the guard digit does not
participate if an unnormalized result is to be generated. The intermediate result may be normalized if required by the instruction.
Here are some further examples of adding operands, now with unlike signs.
Example 7:

X C2777444 + X40121314

The first operand is X C2777444 ; after shifting and then complementing the second operand
fraction, we do the following addition (where we show the parts of the intermediate result as
sign, characteristic, and fraction):
Sign Char
42
-

42

Fraction
.7774440 first operand with guard digit
.FFEDECF complemented 2nd operand fraction
(1).776230F carry occurs

Thus the result is in true form, and we have the intermediate result X C2776230(F) . The
lowest-order digit of the second operand was lost in the shifting operation.
Example 8:

X C2000444 + X40121314

As before, we arrive at
-

42

42

.0004440 first operand


.FFEDECF complemented 2nd operand fraction
.FFF230F no carry occurs

The result is in complement form, as indicated by the absence of a carry. After


recomplementation and sign inversion, we have
+

600

42

.000DCF1

Assembler Language Programming for IBM z System Servers

Version 1.00

giving the intermediate result X42000DCF(1) . The guard digit will become significant if the
final result is normalized, when the result would be X 3 FDCF100 .
Example 9:

X42111111 + X C1111111

The intermediate calculation would yield


+

42

42

.1111110
.FEEEEEF
(1).0FFFFFF

with a carry; thus we have the intermediate result X420FFFFF(F) .


X40123456 + X C0123457

Example 10:

The intermediate result would be found from


+

40

40

.1234560
.EDCBA90
.FFFFFF0

with no carry; after recomplementation and sign inversion the intermediate result would be
X C0000001(0) , as we would have guessed from inspecting the operands.
These last two examples illustrate an important consideration: if the original operands are normalized, a single guard digit provides adequate protection against unexpected loss of precision.
This is because the difference of two normalized fractions with unequal characteristics can introduce at most one leading zero digit in the intermediate result fraction (except in cases of severe
cancellation). Example 8 above illustrates that a single guard digit may be insufficient if unnormalized operands are allowed. If the operands have the same characteristic (as in Example 10), the
possible loss of accuracy can be predicted but not prevented, so in this situation you are entitled
only to the digits left in the intermediate result and no more.

33.11.2. Implementing Hexadecimal Floating-Point Complement Addition (*)


Complement addition can be simplified by forming the ones complement of the second fraction,
rather than the twos complement. Then, if a carry occurs after the fractions are added, it is
carried around to the low-order end of the intermediate sum and added there. This gives the
effect of having added the twos complement of the second operand initially. If there is no carry,
the recomplementation is also a ones complement, which retrieves the low-order one-bit that
would have been added if the twos complement had been formed originally; that is, we have
effectively subtracted and then added back the low-order bit.
A reason for using this technique is that the formation of the twos complement of a number is
an arithmetic operation requiring an addition (and therefore, time and hardware for the propagation of carries), while ones complementation requires only the simple and inexpensive logical
operation of inverting all the bits of an operand. (You might review the similar discussion at
How Additions and Subtractions are Actually Performed on page 36.)
Using this revision to the above addition scheme, Examples 9 and 10 above would appear as
shown in Examples 11 and 12 below.
X42111111 + X C1111111

Example 11:

The intermediate calculation gives


+

42

42

Example 12:

.1111110
.FEEEEEE
(1).0FFFFFE
+
1
.0FFFFFF

first operand
ones complement of 2nd fraction
carry occurs, so...
add back at low-order end
intermediate result

X40123456 + X C0123457

Remember that a guard digit is part of the second operand fraction, even though it is initially
zero; the intermediate calculation is

Chapter IX: Floating-Point Data and Operations

601

40

40

.1234560 first operand


.EDCBA8F ones complement of 2nd fraction
.FFFFFEF

The intermediate result fraction is in complement form; recomplementation (now using the
ones complement) and sign inversion give X C0000001(0) as before.

Exercises
33.11.1.(3) In Example 8 above, what result would be generated if the X C2000444 operand was
normalized?
33.11.2.(3) + Given the hexadecimal floating-point quantities you defined in Exercise 33.1.5,
compute in decimal and in then in short hexadecimal floating-point forms the following values:
(a) D+C

(b) A+E

(c) B+E

(d) E F

(e) DB

(f) CC

(g) D/B

33.12. Hexadecimal Floating-Point Comparison


Table 239 lists the hexadecimal floating-point comparison instructions:
Op
79
69

Mnem
CE
CD

Type Instruction
R X Compare (Short)
R X Compare (Long)

Op
39
29
B369

Mnem
CER
CDR
CXR

Type
RR
RR
RRE

Instruction
Compare (Short)
Compare (Long)
Compare (Extended)

Table 239. Hexadecimal floating-point Compare instructions

Comparing two floating-point operands requires an internal subtraction which follows all the
above rules. As with other compare instructions, no interruption conditions are recognized and
the intermediate result (including the guard digit) is examined to determine the CC setting. The
operands are considered to be equal if the intermediate difference (including the guard digit) is
zero.
The Condition Code settings are shown in this table:
CC
0
1
2

Meaning
Operands are equal
First operand is low
First operand is high

Table 240. CC settings for hexadecimal floating-point comparison

Be careful: if you compare unnormalized operands, two unequal operands may compare equal.
For example, if we compare the short HFP number X40000001 to any number of the form
X 3 B10wxyz , the CC setting is zero (indicating equality) for any values of the digits wxyz. (See
Exercise 33.12.1.)

Exercises
33.12.1.(2) + Perform the intermediate steps of comparing the two short operands X40000001
and X 3 B1vwxyz:, where vwxyz are arbitrary hex digits, and prove that they will be found equal.
33.12.2.(2) Given the quantities A, B, C, D, and E shown in Exercise 33.9.5, show the CC
setting after executing each of these instruction sequences:

602

Assembler Language Programming for IBM z System Servers

Version 1.00

1. LE
CE

0,D
0,A

2. LE
CE

0,C
0,D

3. LE
CE

6,E
6,E

4. LE
CE

0,B
0,E

33.12.3.(3) Given three arrays of 10 short hexadecimal floating-point values stored beginning at
SideA, SideB, and SideC respectively, write an instruction sequence to set the byte at offset K in
the ten-byte string starting at Triangle to one if the values of the K-th floating-point numbers
could form the sides of a plane triangle, and to zero if not. (Remember that a triangle has the
property that the sum of any two sides is greater than the third.)
33.12.4.(3) Given two arrays of twenty short HFP numbers X(i) and Y(i) stored at XX and YY
respectively, write an instruction sequence that will store in the array starting at Ratio the
quantity (X(i) / Y(i)) if |X(i)/Y(i) |< 1 0 40 , or 1040 otherwise.
Your program should be written so that no exponent overflows or underflows can be generated.

33.13. Rounding and Lengthening Instructions


Two sets of length-changing hexadecimal floating-point instructions let you
round a longer operand to a shorter, and
extend a shorter operand to a longer.

33.13.1. Rounding Instructions


Though hexadecimal floating-point arithmetic is not rounded, the instructions in Table 241 round
a longer operand to a shorter.
Op
35
B366

Mnem
LRER,
LEDR
LEXR

Type Instruction
R R Load Rounded (Long to
Short)
R R E Load Rounded (Extended to
Short)

Op

Mnem

Type Instruction

25

LRDR,
LDXR

RR

Load Rounded (Extended to


Long)

Table 241. Hexadecimal floating-point Round instructions

The LRDR and LXDR instructions round an extended operand to long, and LRER and LEDR
round a long operand to short, as follows.
1. Examine the fraction bit of the next longer floating-point format that immediately follows the
low-order fraction bit of the shorter operand. For LRER, LEDR, or LEXR this will be bit
32 of FPR(R 2); and for LRDR or LDXR, it will be bit 8 of FPR(R 2 + 2).
2. If the examined bit is zero, the high-order part of the second operand is placed in the first
operand register.
3. If the examined bit is one, a low-order 1-bit is added internally to the low-order bit of the
first-operand length of the second operand, and the resulting floating-point sum is placed in
the first operand register.
4. If, in adding the low-order 1-bit, a carry occurs out of the high-order digit of the fraction, the
fraction is shifted right one hex digit, and the characteristic is increased by 1. If this process
causes the characteristic to exceed 127, an exponent overflow interruption occurs, and the IC
is set to 12 (X C ).
5. No post-normalization is done, except for a possible right shift of one digit if there is a carry
out of the high-order digit position, and the characteristic is incremented.
6. The Condition Code is not changed by these instructions.
For example, to round a long operand in FPR2 to short and store it at Rounded we can use the
instructions in Figure 386.

Chapter IX: Floating-Point Data and Operations

603

LRER 0,2
STE 0,Rounded

Long operand in FPR2, short in FPR0


Store short rounded result

Figure 386. Rounding a long hexadecimal floating-point number to short

To form the extended product of two long operands at DA and DB and then round the result to
long format, you can use an instruction sequence like this:
LD
0,DA
MXD 0,DB
LRDR 0,0

Load first operand into FPR0


Form extended product in FPR(0,2)
Round extended to long in FPR0

Suppose we must store at ZZ the rounded inner product of two linear arrays of twenty longprecision elements that start at XX and YY. (Compare Figure 381 on page 595.)
TL

Equ
LZXR
LA
LA
SR
LD
MXD
AXR
JXLE
LRDR
STD
- - DS
DS
DS

Loop

XX
YY
ZZ

20
4
0,L XX
1,L XX*(TL-1)
2,2
0,XX(2)
0,YY(2)
4,0
2,0,Loop
2,4
2,ZZ

Length of arrays
Accumulate extended sum in FPR(4,6)
JXLE Increment in GR0
JXLE Comparand in GR1
JXLE Index in GR2
Fetch operand XX(i)
Form extended product XX(i)*YY(i)
Accumulate extended sum
Increment index and loop
Round the result sum into FPR2
Store final result

(TL)D
(TL)D
D

Space for first array


Space for second array
Rounded inner product stored here

Figure 387. Rounded inner product of long H F P numbers

To retain precision, products of the long elements are generated and accumulated as an extendedprecision sum that is rounded to the final long result. Because there are no instructions to test
individual bits in the floating-point registers, you could do rounding manually in other ways
that illustrate the rounding method used by the CPU.
Suppose the LRER instruction did not exist. We could write instruction sequences to round the
long floating-point number in FPR2 in several ways:
1. A direct method stores the long operand and tests the bit. If it is one, form an unnormalized
quantity of the same sign and characteristic with only a low-order 1-bit in the fraction, and
add it to do the rounding. Suppose the result is to be stored at Round1.

Done
Temp
One
Round1

STD 2,Temp
TM
Temp+4,X 8 0
JZ
Done
MVC One(1),Temp
AE
2,One
STE 2,Round1
- - DS
D
DC
F 1
DS
E

Store long operand


Test high-order bit of right half
If zero, no rounding
Move sign and characteristic
Add roundoff bit
Store rounded result
Workspace
Low-order 1-bit for rounding
Rounded result

Figure 388. Manually rounding long to short (1)

Suppose FPR2 initially contains X ccdd dddr xeee eeee , where cc is the characteristic, r is
the digit that might be rounded, and the high-order bit of x is tested by the TM instruction.
If the bit is zero, nothing else need be done. If it is 1, the characteristic is moved to the
high-order byte of the constant named One (poor programming technique!), forming
cc00 0001, which is then added as a short hexadecimal floating-point value to FPR2,
rounding the long value to short.

604

Assembler Language Programming for IBM z System Servers

Version 1.00

2. Another instruction sequence uses the fact that if the high-order bit of the lower half of the
long operand is a 1-bit, then adding that bit to itself will produce a carry into the low-order
bit position of the short half of the register.

T
Round2

STD 2,T
XC
T+1(3),T+1
AD
2,T
STE 2,Round2
- - DS
D
DS
E

Store long operand


Set 1st 3 fraction bytes to 0
Add back to round off
Store rounded short operand

Figure 389. Manually rounding long to short (2)

3. This instruction sequence uses only the floating-point registers, and no intermediate storage:

Round3
Round1

LDR
LZDR
LER
SWR
ADR
STE
- - DS
DS

6,2
4
4,2
6,4
2,6
2,Round3

Move long argument to FPR6


Clear all of FPR4
Move short half of argument to FPR4
Subtract left part of fraction
Add low-order half to round
Store rounded result

E
E

Rounded result

Figure 390. Manually rounding long to short (3)

These examples only show how rounding works; its far simpler to use the CPUs rounding
instructions, not these.

33.13.2. Lengthening Instructions


These instructions do a simple operation: the second operand is copied to the first operand register and extended with zeros. The Condition Code is unchanged.
Op
ED24

Mnem
LDE

ED26

LXE

ED25

LXD

Type Instruction
R X E Load Lengthened (Short to
Long)
R X E Load Lengthened (Short to
Extended)
R X E Load Lengthened (Long to
Extended)

Op
Mnem
B324 L D E R
B326 LXER
B325 L X D R

Type Instruction
R R E Load Lengthened (Short to
Long)
R R E Load Lengthened (Short to
Extended)
R R E Load Lengthened (Long to
Extended)

Table 242. Hexadecimal floating-point Load Lengthened instructions

For example, to lengthen a short operand to long, you could write:


LE
0,=X12345678
LDER 4,0

Short hexadecimal floating-point value


c(FPR4)=X1234567800000000

For extended targets (of LX-type instructions), the signs of the first operands high- and low-order
halves are the same, and the low-order characteristic is 14 less than the high-order characteristic
(modulo 128).
LD
0,=X123456789ABCDEF0 Source operand
LXDR 4,0
Extend in (FPR4,6)
will set FPR4 to the same value that is in FPR0, and FPR6 will be set to X0400000000000000.
If the source fraction for an extended target is negative zero, the result is all zero digits except for
the two matching sign bits. For example:

Chapter IX: Floating-Point Data and Operations

605

LD
0,=X8000000000000000 Minus zero
LXDR 4,0
Extend in (FPR4,6)
will set both FPR4 and FPR6 to X8000000000000000.
Bonus effect
LXE and LXD provide an easy way to load a short or long operand into
a floating-point register while also setting its paired register to zero.

Exercises
33.13.1.(2) + Suppose an LRER or LRDR instruction causes an exponent overflow. What are
the possible values of the rounded result?
33.13.2.(2) + Show the result in FPR0 of executing
LRER 0,0
with each of these register contents:
1. c ( F P R 0 ) = X 7 FFFFFFF87654321
2. c ( F P R 0 ) = X4000000087654321
3. c ( F P R 0 ) = X4000000012345678
33.13.3.(2) Write and execute instructions to verify that the sequence shown in Figure 390 on
page 605 works as described.
33.13.4.(1) Suppose you execute these instructions:
LE
4,Variable
LDER 2,4
LEDR 0,2
What differences will there be between c(FPR0) and c(FPR4)?
33.13.5.(2) Show the contents of the registers at each step in Figure 390 on page 605.

33.14. Converting Between Binary Integers and HFP


Before these instructions were added to the z System instruction set, converting between
hexadecimal floating-point and binary integers was somewhat roundabout. The instructions in
Table 243 greatly simplify the process.
Op
B3B4

Mnem
CEFR

B3B5

CDFR

B3B6

CXFR

B3C4

CEGR

B3C5

CDGR

B3C6

CXGR

Type Instruction
R R E Convert from
Short)
R R E Convert from
Long)
R R E Convert from
Extended)
R R E Convert from
Short)
R R E Convert from
Long)
R R E Convert from
Extended)

Fixed (32 to

Op
B3B8

Mnem
CFER

Fixed (32 to

B3B9

CFDR

Fixed (32 to

B3BA

CFXR

Fixed (64 to

B3C8

CGER

Fixed (64 to

B3C9

CGDR

Fixed (64 to

B3CA

CGXR

Table 243. Hexadecimal floating-point F P R / G P R conversion instructions

606

Assembler Language Programming for IBM z System Servers

Version 1.00

Type Instruction
R R F Convert to Fixed
32)
R R F Convert to Fixed
32)
R R F Convert to Fixed
to 32)
R R F Convert to Fixed
64)
R R F Convert to Fixed
64)
R R F Convert to Fixed
to 32)

(Short to
(Long to
(Extended
(Short to
(Long to
(Extended

33.14.1. Converting Binary Integers to Hexadecimal Floating-Point


The six instructions in the left-hand columns of Table 243 convert a binary integer from a general
register to a hexadecimal floating-point value in a floating-point register. For example, we can
convert the integer in GR5 to short hexadecimal floating-point in FPR4:
L
5,=F54321
CEFR 4,5

c(FPR4)=X44D43100

Figure 391. Converting a 32-bit integer to short hexadecimal floating-point

The rules for these six instructions are simple:


1. Zero integer values are converted to + 0 floating-point values.
2. The HFP result is truncated, not rounded.
3. The Condition Code is unchanged.
4. The CXFR and CXGR instructions require that the R 1 operand refer to the lower-numbered
register of a Floating-Point Register pair.
Converting 64-bit integers to hexadecimal floating-point is just as easy, but you can see in Figure
392 that large integer values may lose some low-order bits when converted to short or long
hexadecimal floating-point formats:
LG
CEGR
CDGR
CXGR

5,=FD123456789012345678
(X01B69B4BA630F34E )
4,5
c(FPR4)=X 4 F1B69B4
(truncated)
4,5
c(FPR4)=X 4 F1B69B4BA630F34 (truncated)
4,5
c(FPR4)=X 4 F1B69B4BA630F34 41E0000000000000 ( OK)

Figure 392. Converting a 64-bit integer to three hexadecimal floating-point values

To help you appreciate the simplicity of these instructions, consider this sequence of instructions
used by an early System/360 FORTRAN compiler 208 to convert the fullword integer stored at
FWInt to hexadecimal floating-point, and store the result at DFInt.

Neg

Store
DFInt
DCon

LD
0,=D 0
L
1,FWInt
LTR 1,1
BM
Neg
ST
1,DCon+4
AD
0,DCon
B
Store
LPR 1,1
ST
1,DCon+4
SD
0,DCon
STD 0,DFInt
- - DS
D
DC
X 4E , 7 X 0

Clear all of FPR0


Load integer from FWInt into GPR1
Test sign
Branch if negative
Store magnitude
Normalized result in FPR0
Branch to store
Take magnitude of integer
Store it
Form negative normalized value
Store long floating value
Doubleword result
Pseudo-zero, exponent = 14

Figure 393. Early conversion of integer to hexadecimal floating-point

More efficient and elegant techniques were developed as high-level languages evolved; some of
them are illustrated in (the recommended!) Exercises 33.14.4 through 33.14.6.
When converting a fullword integer to short hexadecimal floating-point, there may be as many as
32 significant bits in the integer, but a short HFP number has only a 24-bit fraction. Thus, there
may be a loss of accuracy in converting fullword integers to short hexadecimal floating-point.
Since floating-point arithmetic is concerned primarily with maintaining as many high-order digits
as possible, this truncation is tolerated by the new instructions also.

208

A very early compiler. Subsequent compilers quickly used improved techniques.


Chapter IX: Floating-Point Data and Operations

607

33.14.2. Converting Hexadecimal Floating-Point to Binary Integers


The six instructions in the right-hand columns of Table 243 convert a hexadecimal floating-point
value in a floating-point register to a binary integer in a general register. Any fractional value is
lost, except that rounding the lost fraction might affect the low-order digit of the integer result. In
addition to the expected R1 and R 2 operands, they also specify a rounding modifier M3 as another
operand. The instruction format is:
opcode

M3

R1

R2

Table 244. Format of H F P to fixed binary instructions

Calling it the third operand may be confusing, because it is actually specified as the second
operand of a machine instruction statement:
CFER R1,M3,R2
Figure 394. Format of machine instruction statement for converting H F P to binary

The R 1 (target) operand specifies a general register and the R2 (source) operand specifies a
floating-point register. The M3 operand determines what rounding should be done, as shown in
Table 245. (These instructions are easy to use; just be sure to specify a rounding mode (M3)
operand, as there is no default.)
M3
B0000
B0001
B0100
B0101
B0110
B0111

Meaning
Truncate the fraction part (round toward zero)
Round to nearest; if the source value is halfway between two integer
values, choose the one with the larger magnitude
Round to nearest; if the source value is halfway between two integer
values, choose the even one with a zero low-order bit
Truncate the fraction part (round toward zero)
Round toward +
Round toward

Table 245. Rounding modifiers for HFP-to-binary conversion

Other modifier values are invalid, and cause a specification exception.


These instructions set the Condition Code, with CC=3 as an interesting and unusual case.
CC
0
1
2
3

Meaning
Result is = 0
Result is < 0
Result is > 0
The rounded result exceeds the range of the target representation, and has
been replaced by the largest representable correctly signed magnitude.

Table 246. CC settings for HFP-to-binary conversion

As you would expect, the CFXR and CXFGR instructions require that the R 2 operand reference
the low-order half of a floating-point register pair.
For example, these instructions generate the indicated results:
LE
CFER
LD
CGER
LE
CFER

608

4,=E123.456
2,B0110,4
4,=E -73.946
2,B0111,4
4,=E1234567890
2,B0100,4

c(GR2) = X0000007C (=124)


c(GG2) = X FFFFFFFFFFFFFFB6 (=-74)
c(GR2) = X49960300 (=1234567936)

Assembler Language Programming for IBM z System Servers

Version 1.00

The last example shows that some low-order bits could not be represented in the short second
operand.
Unexpected results can also be generated if floating-point values known to have integer values
are converted to binary. For example if a HFP result is expected to be 8 but actually is calculated
as 7.999999, the lack of a rounding conversion to binary generates the integer value 7.
Table 247 summarizes the actions of some instructions that move and/or convert data between
and among the general registers and floating-point registers:
To
From

Fixed Bin
(32 bits)

Fixed Bin
(64 bits)

Hex Float
(32 bits)

Hex Float
(64 bits)

Hex Float
(128 bits)

Fixed Bin
(32 bits)
Fixed Bin
(64 bits)

LR

LGFR

CEFR

CDFR

CXFR

LR

LGR

CEGR

CDGR

CXGR

Hex
(32
Hex
(64

Float
bits)
Float
bits)

CFER

CGER

LER

LDER

LXER

CFDR

CGDR

LRER
LEDR

LDR

LXER

Hex Float
(128 bits)

CFXR

CGXR

LEXR

LRDR
LDXR

LXR

Table 247. Instructions moving/converting binary and hexadecimal floating-point operands

Exercises
33.14.1.(2) An array of fullword integers is stored starting at IntData and the number of elements in the array is stored as a fullword integer at NItems. Write instructions to compute and
store at IntAvg the floating-point average of the list of integers, taking into account the possibility that the integer sum may overflow a general register.
33.14.2.(2) What is the largest binary integer that can be converted to hexadecimal floatingpoint long format without loss of precision? Explain.
33.14.3.(1) Can the instructions for converting a binary integer to hexadecimal floating-point
generate an exponent spill?
33.14.4.(3) + A compiler used these instructions to convert the fullword binary integer in GR0
to long hexadecimal floating-point form in FPR0.

DCon
Float

X
0,Float+4
Invert sign bit
ST
0,DCon+4
Store result in long number
LD
0,DCon
Load the unnormalized value
SD
0,Float
Subtract and normalize
- - DS
0D
Align on doubleword boundary
DC
X 4 E00000000000000
Pseudo-zero, exponent = 14
DC
X 4 E00000080000000
2**31, unnormalized

Analyze this method, and show (a) how it works, and (b) that it will work correctly for any
integer value.
33.14.5.(3) Another compiler used this instruction sequence to convert a fullword binary integer
in GR0 to long hexadecimal floating-point form in FPR0. Analyze its action for positive, zero,
negative, and maximum negative integer values. Describe the differences between this instruction sequence and that in Exercise 33.14.4.

Chapter IX: Floating-Point Data and Operations

609

DCon
Float

X
0,DCon+4
Invert sign bit
ST
0,Float+4
Store result in long number
LD
0,Float
Load the unnormalized value
AD
0,DCon
Add and normalize
- - DS
0D
Align on doubleword boundary
DC
X CE00000080000000
-2**31 unnormalized
DC
X 4 E00000000000000
pseudo-zero, exponent = 14

33.14.6.(3) + The following instruction sequence was used by a compiler to convert a short
hexadecimal floating-point value at X to a fullword integer in GR0. Analyze its operation for
positive, zero, and negative hexadecimal floating-point values, and describe its behavior for
hexadecimal floating-point values exceeding 231 .

FTemp
DCon

LD
0,DCon
Clear low-order half of FPR0
LE
0,X
Get floating-point operand
AD
0,DCon
Add and normalize
STD 0,FTemp
Store the result
L
0,FTemp+4
Put the integer result in GR0
- - DS
D
Doubleword temporary
DC
X 4 F08000000000000
Conversion constant

Explain the form of the constant at DCon.


33.14.7.(3) What modifications would be required to the instructions in Exercise 33.14.6 to
handle conversion of a long precision hexadecimal floating-point value to fullword integer form?
To 64-bit integer form?
33.14.8.(2) + Write the constants named DCon in Exercises 33.14.4 through 33.14.6 as
hexadecimal floating-point constants in DC statements.
33.14.9.(2) + What integer values satisfying
230 value < 231
can be converted without loss of precision to short hexadecimal floating-point form?
33.14.10.(3) Without using the instructions described in Section 33.14, write instructions to
convert the long hexadecimal floating-point value at YY to a fullword binary integer stored at
NN. If the integer result is too large to be correctly represented, branch after storing the result to
the instruction at location TooBig.
33.14.11.(3) Without using the instructions described in Section 33.14, write instructions to
convert the short hexadecimal floating-point number at XX to a correctly rounded fullword
integer value stored at MM.
33.14.12.(2) Write the constant named Float in Exercise 33.14.4 in a DC statement as a scaled
D-type constant.
33.14.13.(3) + Write an instruction sequence that will convert the nonnegative fullword integer
at IntVal to a rounded short hexadecimal floating-point format stored at Result, using round
half-up (arithmetic) rounding.
33.14.14.(3) Repeat Exercise 33.13.13, but use half-even rounding.
33.14.15.(2) The following short HFP numbers are converted to binary integers using these two
instructions:

610

Assembler Language Programming for IBM z System Servers

Version 1.00

(a)

LE
0,HFP_Number
CFER 3,0,0

(b)

LE
0,HFP_Number
CGER 3,0,0

for these HFP_Number values:


(1)
(2)
(3)
(4)
(5)

X46000000
X C7654321
X 7 FEDCB49
X ABCDEF74
X4974662B

Show the Condition code and the contents of GR3 and GG3 for each HFP number.
33.14.16.(2) + If you convert the HFP constant E65537 to a halfword binary integer, what is
the result?
33.14.17.(2) Suppose you use these instructions to convert a long HFP operand at DFloat to a
fullword binary integer stored at NF. What value will be stored?

DTemp
DCon
DFloat
NF

LD
0,DFloat
AW
0,DCon
STD 0,DTemp
L
1,DTemp+4
BNM *+6
LCR 1,1
ST
1,NF
- - DS
D
DC
X 4E , 7 X 0
DC
D16777219
DS
F

Get long operand


Add long pseudo-zero, exponent 14
Store temporarily
Pick up fullword integer
Branch if nonnegative
Complement integer value
Store fullword result

Pseudo-zero, exponent=14
Long HFP source data
Integer result

33.15. Hexadecimal Floating-Point Integers and Remainders (*)


We must sometimes compute the remainder of a floating-point division, even though its not
provided by the CPU as a result of any divide instruction. Given two operands A and B, we may
need to calculate a quotient Q and a remainder R so that
A = Q*B + R
The quotient Q is produced by the divide instructions; for floating-point arithmetic, R must be
calculated separately. This can be done using
R = A - Int(A/B)*B
Thus, we evaluate A/B, convert it to its floating-point integer form, multiply that by B, and subtract the product from A to give the desired result.
For example, suppose we use three-digit decimal floating-point and divide 5.55 by 2.47; the true
quotient is 2.246963562753.... The integer part of the quotient is 2, so we must evaluate
5.55 (22.47) to find the remainder, 0.61.
The key step is finding the integer part of the quotient, using the instructions in Table 248.

Chapter IX: Floating-Point Data and Operations

611

Op
B377
B367

Mnem
FIER
FIXR

Type Instruction
R R E Load FP Integer (Short)
R R E Load FP Integer
(Extended)

Op
B37F

Mnem
FIDR

Type Instruction
R R E Load FP Integer (Long)

Table 248. Hexadecimal floating-point instructions generating floating-point integers

Its important to remember that the result is a hexadecimal floating-point integer in the same
format, not a fixed binary integer!
The results of these instructions are normalized.
The Condition Code is unchanged.
FIXR requires that both operands refer to the lower-numbered register of a floating-point register register pair.
If the exponent of the second operand is large enough, the result in the first operand will be
the same value (normalized).
Using the values A=5.55 and B=2.47, Figure 395 shows how we would calculate the HFP
remainder:
LE
DE
FIER
ME
LCER
AE

0,=E 5 . 5 5
0,=E 2 . 4 7
0,0
0,=E 2 . 4 7
0,0
0,=E 5 . 5 5

A = 5.55
B = 2.47
Int(A/B) = 2
Multiply by B
Invert sign of the product
Remainder = A - Int(A/B)*B

Figure 395. Calculating a H F P remainder

The result in FPR0 is X409C28F0 , or approximately 0.60999966 in decimal.


To give another example:
LE
0,=X42345678
FIER 2,0

Hex 33.5678
c(FPR2) = X4234000

removes the fraction X42005678, leaving the integer part.


Suppose there are short hexadecimal floating-point operands at A and B and the remainder is to
be stored in short form at AModB.

AModB
A
B

LE
DE
FIER
ME
LCER
AE
STE
- - DS
DC
DC

0,A
0,B
0,0
0,B
0,0
0,A
0,AModB

Load A into FPR0


Divide by B
Drop off the fraction part
Form product with integer part
Form -B*IntPart(A/B)
Add A to form remainder
Store result

E
E 2 0
E 1 6

Remainder
A value for A
And for B

Figure 396. Evaluating a hexadecimal floating-point remainder

This technique should be used with care. If the relative magnitudes of A and B are close, the
result is acceptable; but if the ratio |A/B | approaches the precision of the operands, the result can
be inaccurate, and special programming techniques may be needed to calculate an accurate result.

612

Assembler Language Programming for IBM z System Servers

Version 1.00

Exercises
33.15.1.(2) + In Figure 396, what will be in FPR0 after the DE instruction? After the FIER
instruction? After the ME instruction? After the AE instruction?
33.15.2.(2) + Show that the FIER instruction in Figure 396 can be replaced by
AU

0,=X46000000

33.15.3.(3) What will happen in Figure 396 if the FIER instruction is replaced by
AE

0,=X46000000

For what values of A/B will there be no difference between using AE and AU instructions?
33.15.4.(1) Rewrite the instructions in Figure 396 to use long operands.
33.15.5.(2) What is the result in FPR0 of each of these instruction sequences?
(1)

LE
0,=X44001234
FIER 0,0

(2)

LD
0,=X C7FEDCA987654321
FIDR 0,0

(3)

LXD 0,=X1234567890ABCDEF
FIXR 0,0

(4)

LE
0,=X77654321
FIER 0,0

(5)

LD
0,=X C7FEDCA987654321
FIER 0,0

33.15.6.(2) + Rewrite the instructions in Figure 396 to handle long HFP operands.

33.16. Square Root Instructions (*)


The instructions in Table 249 extract the square root of a hexadecimal floating-point operand.
None of them change the Condition Code.
Op
ED34
ED35

Mnem
SQE
SQD

Type Instruction
R X E Square Root (Short)
R X E Square Root (Long)

Op
B245
B244
B336

Mnem
SQER
SQDR
SQXR

Type
RRE
RRE
RRE

Instruction
Square Root (Short)
Square Root (Long)
Square Root (Extended)

Table 249. Hexadecimal floating-point Square Root instructions

The SQXR instruction requires both the R 1 and R 2 operands to refer to the lower-numbered
register of a Floating-Point Register pair.
The second operand is first tested to see if it is negative and nonzero. If so, a HFP Square Root
interruption occurs, and the IC is set to 29 (X 1D ). Otherwise, the operand is normalized internally and its square root is evaluated; the result is normalized, rounded, and its sign is always + .
Because the exponent of a square root is about one-half the exponent of its argument, the result
cannot cause an exponent spill.
Figure 397 gives some examples of these instructions:
Chapter IX: Floating-Point Data and Operations

613

LE
SQER
LD
SQDR
LE
SQER

2,=E1024.576
0,2
2,=X41FFFFFFFFFFFFFF
0,2
2,=X80000000
0,2

c(FPR2)=X43400937
c(FPR0)=X4220024E = 32.00900...
= 15.999999999997...
c(FPR0)=X4140000000000000 = 4.0
Minus zero
c(FPR0)=X00000000

Figure 397. Examples of H F P square root instructions

These instructions have two interesting properties (see Exercises 33.16.1 and 33.16.2):
1. Rounding cannot produce a carry out of the high-order digit of the result.
2. A square root cannot lie exactly half way between two representable values, so that traditional half-up rounding can be used.

Exercises
33.16.1.(1) + Estimate the value of the square root of HFP (Max), (Min), and (DMin) values.
33.16.2.(3) It is stated above that rounding the result of a square root instruction cannot create
a carry out of the high-order digit of the fraction. Why not?
33.16.3.(4) It is stated above that the result of a square root instruction cannot lie exactly half
way between two representable values. Why not?

33.17. Multiply and Add/Subtract Instructions (*)


The instructions in Table 250 combine two operations into one: a multiplication followed by an
addition or subtraction; they are sometimes called fused multiply-add or FMA instructions.
None of them change the Condition Code.
Op
ED2E
ED3E
ED2F

Mnem
MAE
MAD
MSE

ED3F

MSD

Type
RXF
RXF
RXF

Instruction
Multiply and
Multiply and
Multiply and
(Short)
R X F Multiply and
(Long)

Add (Short)
Add (Long)
Subtract

Op
B32E
B33E
B32F

Mnem
MAER
MADR
MSER

Subtract

B33F M S D R

Type
RRF
RRF
RRF

Instruction
Multiply and Add (Short)
Multiply and Add (Long)
Multiply and Subtract (Short)

R R F Multiply and Subtract (Long)

Table 250. Hexadecimal floating-point Multiply and add/subtract instructions

These instructions have three operands; their RRF format (shown in Table 251) is similar to that
in Table 244 on page 608, except that the instruction operands are in different fields.
opcode

R1

R3

R2

Table 251. Format of RRF-type H F P multiply and add/subtract


instructions

The RXF-type instruction format is shown in Table 252:


opcode

R3

X2

B2

D2

R1

Table 252. Format of RXF-type multiply and add/subtract instructions

The assembler instruction statement format for these instructions is simpler:

614

Assembler Language Programming for IBM z System Servers

Version 1.00

opcode

MAE R1,R3,D2(X2,B2)
MAE R1,R3,S2
MAER R1,R3,R2

Explicit address
Implied address

The effect of these instructions is to evaluate


operand_1 = (operand_3 operand_2) operand_1
or
c(R1) = (c(R3) operand_2) c(R1)
Initially, the product of operand_2 and operand_3 is evaluated internally to double precision: that
is, to 14 digits for short operands, and to 28 digits for long operands. Possible exponent spills are
ignored at this stage. Then, operand_1 is added or subtracted, the result is normalized and truncated, and replaces operand_1. Exponent overflow or underflow may occur at this stage.
A single guard digit is used for the addition or subtraction, and the final result is truncated, not
rounded.
None of the operands is normalized at the start of the instructions.
For example:
LE
LE
MAE

4,=E 2 5
2,=E123
2,4,=E 4

Operand_3 in FPR4
Operand_1 in FPR2
Operand_2 = 4.0

multiplies 25 and 4, and adds 123, giving X42DF0000 , or 223 as expected.


The big advantage of these instructions is that they avoid the possibility of double rounding, or
the need for using higher-precision arithmetic. If you wanted to achieve the same result without
the MAE instruction, you would have to write something like this:
LE
LDER
LE
LDER
MDR
LE
LDER
ADR

4,=E 2 5
4,4
2,=E 4
2,2
4,2
2,=E123
2,2
2,4

Operand_3
Extend to long precision
Operand_2
Extend to long precision
Form long product
Operand_1
Extend to long precision
Accumulate final result

This not only takes more instructions (and probably executes more slowly), but it is open to the
possibility that the MDR instruction could cause an exponent spill that would otherwise have
been compensated by the ADR instruction. For example:
LE
LE
MAE

4,=X60987654
2,=X FFFFFFFF
2,4,=X60234567

Operand_3
Operand_1
Operand_2 in memory

produces a result X 7 F50182C in FPR2 with no overflow, but


LE
ME
AE

4,=X60987654
4,=X60234567
4,=X FFFFFFFF

Operand_3
Operand_2 in memory
Operand_1

produces an exponent overflow when the ME instruction is executed with


c ( F P R 4 ) = X00150182B83FCC00 ; the following AE instruction ignores the (now) tiny result of the
ME instruction, giving X FFFFFFFF as the final result!

Exercises
33.17.1.(2) + Rewrite the example in Figure 381 on page 595 to use multiply-add instructions.
33.17.2.(2) Rewrite the example in Figure 382 on page 595 to use multiply-add instructions.

Chapter IX: Floating-Point Data and Operations

615

33.18. Some Hexadecimal Floating-Point History (*)


In the early System/360 CPUs, processor and memory speeds were close (and in some cases a
memory access was faster than the time needed to execute an instruction). Some programming
techniques that performed acceptably then are no longer used.

33.18.1. Zeroing Floating-Point Registers


Sometimes you need to clear a floating-point register to zero, or set the low-order half of a
floating-point register to zero prior to loading a short operand. Without the lengthening
instructions in Section 33.13.2 on page 605, or the Load Zero instructions in Section 31.9.3. on
page 556, you might have used instructions like these:
LD

0,=D 0 . 0

Load a zero from memory

SWR

0,0

Subtract the register from itself

or
with the cost of a constant and a memory access for the LD instruction, and a possible HFP
lost-significance exception for the SWR instruction.

33.18.2. Hexadecimal Floating-Point to Binary Conversion Comments (*)


There are some possible problems.
1. Suppose we try to convert the HFP constant E50000 to a halfword integer. If we use a
typical instruction sequence, the intermediate HFP result would be X4600C350 . If we load
the rightmost four digits of this result into a general register using a LH instruction, the contents of that register would be X FFFFC350 , an integer value of 15536! This could be quite
a surprise, because the original operand was positive. Such conversions gave no indication
that the result was corrupted.
While this example might seem relatively harmless (the negative result indicates that an overflow has occurred), it is easy to create examples where the loss of accuracy is not as obvious.
2. The lack of a CC setting meant that the binary result would have to be tested using a LTR
instruction to determine its sign; the new instructions like those in Section 33.14.2 on page
608 solve that problem
3. When converting an integer to short hexadecimal floating-point, it is possible that the integer
has enough low-order zero bits so that its magnitude may exceed 224 and still no significant
bits will be lost in the conversion, but we have no way to know this is so. While this may
not seem very important, there are situations where you may obtain unsuspected results.

33.18.3. Initial System/360 Oversights


When the very first System/360 CPUs were delivered, customers found that some floating-point
implementation oversights made program portability more difficult among different models:
1. There was no guard digit for long hexadecimal floating-point arithmetic. (For example, the
multiplicative identity 1a=a failed in long arithmetic due to the lack of a guard digit.)
2. No post-normalization or zero-fraction test was performed after the Halve instructions, so
that unnormalized results could be generated from normalized operands.
3. No characteristic wraparound or correct fraction was guaranteed in case of overflow and
underflow, and the result left in the register depended on the model.
4. A condition code of 3 was generated when exponent overflow occurred during add operations.
5. No extended precision operations were available.
These oversights were corrected very promptly: IBM announced in February 1967 that engineering changes would be made to all machines (if desired by the owner or renter) in order to
rectify the first four of the above conditions. Extended precision was delivered several years later.

616

Assembler Language Programming for IBM z System Servers

Version 1.00

33.19. Summary
Weve covered a lot of material in this section; a few summary comments may help.
Operands are pre-normalized for multiplication and division, but not for addition or subtraction.
There are no reserved or special values, as for binary and decimal floating-point.
Arithmetic results are not rounded.
Arithmetic truncates (usually, but not always, toward zero!) For example:
X42100000 X40FFFFFF = X41F00001 (instead of X41F00000 ); this result is truncated
away from zero, with error = 15/16 ulp.
Zero arithmetic results are delivered as + 0 (true zero).
There are no instructions operating on two hexadecimal floating-point operands of different
lengths, such as adding a short and a long operand. Such arithmetic is sometimes called mixedlength or mixed-precision arithmetic. The only practical way to mix short and long operands is
to clear the low-order half of a long register (or area of memory), place the short operand in the
high-order half, and then do the required operation in long arithmetic.
The hexadecimal floating-point instructions for moving and testing data in the floating-point registers are summarized in Table 253.
Function
Load and Test
Load Complement
Load Negative
Load Positive

Operand Length
4 bytes
8 bytes
16 bytes
LTER
LTDR
LTXR
LCER
LCDR
LCXR
LNER
LNDR
LNXR
LPER
LPDR
LPXR

Table 253. Hexadecimal floating-point Move/Test instructions

The hexadecimal floating-point multiplication instructions are summarized in Table 254.


Function

Source Length
Product Length

4 bytes
4 bytes
8 bytes
MEER
MER
MDER
MEE
ME
MDE

Multiply (registers)
Multiply (storage)

8 bytes
8 bytes
16 bytes
MDR
MXDR
MD

16 bytes
16 bytes
MXR

MXD

Table 254. Hexadecimal floating-point Multiply instructions

The hexadecimal floating-point divide instructions are summarized in Table 255.


Function
Divide
(register)
Divide
(storage)
Halve
(register)

4 bytes
DER

Operand Length
8 bytes
16 bytes
DDR
DXR

DE

DD

HER

HDR

Table 255. Hexadecimal floating-point Divide instructions

Chapter IX: Floating-Point Data and Operations

617

The hexadecimal floating-point instructions for normalized and unnormalized addition and subtraction and for comparison are summarized in Table 256.
Function
Add/Subtract Normalized
(register)
Add/Subtract Unnormalized
(register)

4 bytes
AER
SER
AUR
SUR

Add/Subtract Normalized
(storage)
Add/Subtract Unnormalized
(storage)
Compare (register)
Compare (storage)

AE
SE
AU
SU
CER
CE

Operand Length
8 bytes
16 bytes
ADR
AXR
SDR
SXR
AWR
SWR
AD
SD
AW
SW
CDR
CD

CXR

Table 256. Hexadecimal floating-point Add, Subtract, and Compare instructions

The hexadecimal floating-point rounding instructions are summarized in Table 257.


Function

Source Length
Result Length

8 bytes
4 bytes
LRER
LEDR

Round

16 bytes
4 bytes
LEXR

16 bytes
8 bytes
LRDR
LDXR

Table 257. Hexadecimal floating-point Round instructions

The hexadecimal floating-point operand-lengthening instructions are summarized in Table 258.


Source Length
Result Length
Lengthen (register)
Lengthen (storage)

Function

8 bytes
LDER
LDE

4 bytes
16 bytes
LXER
LXE

8 bytes
16 bytes
LXDR
LXD

Table 258. Hexadecimal floating-point Lengthening instructions

The instructions for converting hexadecimal floating-point operands to binary integers are summarized in Table 259.
Source Length
Target Length
Convert float to binary

Function

4 bytes
32 bits
64 bits
CFER
CGER

8 bytes
32 bits
64 bits
CFDR
CGDR

16 bytes
32 bits
64 bits
CFXR
CGXR

Table 259. Convert hexadecimal floating-point to binary instructions

The instructions for converting binary integer operands to hexadecimal floating-point are summarized in Table 260.
Function

Source Length
Target Length

Convert binary to float

32 bits
4 bytes

8 bytes

CEFR

CDFR

64 bits
16
bytes
CXFR

4 bytes

8 bytes

CEGR

CDGR

16
bytes
CXGR

Table 260. Convert binary to hexadecimal floating-point instructions

The instructions for removing the fraction part of hexadecimal floating-point operands (that is,
extracting the integer portion) are summarized in Table 261.

618

Assembler Language Programming for IBM z System Servers

Version 1.00

Function
Operand Length
Form floating-point integer

4 bytes
FIER

8 bytes
FIDR

16 bytes
FIXR

Table 261. Form hexadecimal floating-point integer instructions

The instructions for evaluating the square root of hexadecimal floating-point operands are summarized in Table 262.
Function
Square root (register)
Square root (register)

4 bytes
SQER
SQE

Operand Length
8 bytes
16 bytes
SQDR
SQXR
SQD

Table 262. Hexadecimal floating-point Square Root instructions

The instructions for performing multiply-and-add and multiply-and-subtract operations on


hexadecimal floating-point operands are summarized in Table 263.
Function
Multiply-add (register)
Multiply-add (storage)
Multiply-subtract (register)
Multiply-add (storage)

Operand Length
4 bytes
8 bytes
MAER
MADR
MAE
MAD
MSER
MSDR
MSE
MSD

Table 263. Hexadecimal floating-point Multiply-Add/Subtract instructions

Instructions Discussed in this Section

Chapter IX: Floating-Point Data and Operations

619

The instruction mnemonics and opcodes are shown in the following table:

620

Mnemonic
AD

Opcode
6A

Mnemonic
FIDR

Opcode
B37F

Mnemonic
MAER

Opcode
B32E

ADR

2A

FIER

B377

MD

6C

AE

7A

FIXR

B367

MDE

7C

AER

3A

HDR

24

MDER

3C

AU

7E

HER

34

MDR

2C

AUR

3E

LCDR

23

ME

7C

AW

6E

LCER

33

MEE

ED37

AWR

2E

LCXR

B363

MEER

B337

AXR

36

LDE

ED24

MER

3C

CD

69

LDER

B324

MSD

ED3F

CDFR

B3B5

LDXR

25

MSDR

B33F

CDGR

B3C5

LEDR

35

MSE

ED2F

CDR

29

LEXR

B366

MSER

B32F

CE

79

LNDR

21

MXD

67

CEFR

B3B4

LNER

31

MXDR

27

CEGR

B3C4

LNXR

B361

MXR

26

CFDR

B3B9

LPDR

20

SD

6B

CFXR

B3BA

LPER

30

SDR

2B

CGDR

B3C9

LPXR

B360

SE

7B

CGER

B3C8

LRDR

25

SER

3B

CGXR

B3CA

LRER

35

SQD

ED35

CXFR

B3B6

LTDR

22

SQDR

B244

CXGR

B3C6

LTER

32

SQE

ED34

CER

39

LTXR

B362

SQER

B245

CFER

B3B8

LXD

ED25

SQXR

B336

CXR

B369

LXDR

B325

SU

7F

DD

6D

LXE

ED26

SUR

3F

DDR

2D

LXER

B326

SW

6F

DE

7D

MAD

ED3E

SWR

2F

DER

3D

MADR

B33E

SXR

37

DXR

B22D

MAE

ED2E

Assembler Language Programming for IBM z System Servers

Version 1.00

The instruction opcodes and mnemonics are shown in the following table:
Opcode
20

Mnemonic
LPDR

Opcode
3E

Mnemonic
AUR

Opcode
B361

Mnemonic
LNXR

21

LNDR

3F

SUR

B362

LTXR

22

LTDR

67

MXD

B363

LCXR

23

LCDR

69

CD

B366

LEXR

24

HDR

6A

AD

B367

FIXR

25

LDXR

6B

SD

B369

CXR

25

LRDR

6C

MD

B377

FIER

26

MXR

6D

DD

B37F

FIDR

27

MXDR

6E

AW

B3B4

CEFR

29

CDR

6F

SW

B3B5

CDFR

2A

ADR

79

CE

B3B6

CXFR

2B

SDR

7A

AE

B3B8

CFER

2C

MDR

7B

SE

B3B9

CFDR

2D

DDR

7C

MDE

B3BA

CFXR

2E

AWR

7C

ME

B3C4

CEGR

2F

SWR

7D

DE

B3C5

CDGR

30

LPER

7E

AU

B3C6

CXGR

31

LNER

7F

SU

B3C8

CGER

32

LTER

B22D

DXR

B3C9

CGDR

33

LCER

B244

SQDR

B3CA

CGXR

34

HER

B245

SQER

ED24

LDE

35

LEDR

B324

LDER

ED25

LXD

35

LRER

B325

LXDR

ED26

LXE

36

AXR

B326

LXER

ED2E

MAE

37

SXR

B32E

MAER

ED2F

MSE

39

CER

B32F

MSER

ED34

SQE

3A

AER

B336

SQXR

ED35

SQD

3B

SER

B337

MEER

ED37

MEE

3C

MDER

B33E

MADR

ED3E

MAD

3C

MER

B33F

MSER

ED3F

MSD

3D

DER

B360

LPXR

Chapter IX: Floating-Point Data and Operations

621

Exercises
33.19.1.(2) + Suppose you evaluate X42100000 X40FFFFFF using SE and SU instructions.
Estimate the size of the error for each result, and explain their difference.
33.19.2.(4) Suppose the designers of System/360 had chosen an octal (base 8) representation for
floating-point arithmetic. Consider two choices for the width of a binary characteristic: 7 bits
(with 8 fraction digits), or 4 bits (with 9 fraction digits); the remaining bit is for the sign.
Determine the exponent ranges and fraction accuracy for each.
The following six exercises use the definition of ulp(x) described in Section 32.8 on page 567.
33.19.3.(2) + Suppose a short hexadecimal floating-point number is stored at X. Write
instructions to calculate ulp(X) and store the result at ULPX. Assume that the value at X is large
enough that no exponent underflow occurs in calculating the result.
33.19.4.(3) What is the minimum value of the hexadecimal floating-point number at X that will
not underflow when you calculate ulp(X)?
33.19.5.(2) + Repeat Exercise 33.19.3 assuming that the value at X is a long precision
hexadecimal floating-point number.
33.19.6.(3) Repeat Exercise 32.19.4 assuming that the value at X is a long precision hexadecimal
floating-point number.
33.19.7.(3) + Repeat Exercise 33.19.3 assuming that the value at X is an extended precision
hexadecimal floating-point number.
33.19.8.(3) Repeat Exercise 33.19.4 assuming that the value at X is an extended precision
hexadecimal floating-point number.

Terms and Definitions


unnormalized add/subtract
Hexadecimal floating-point addition and subtraction in which the result is not normalized.
multiply and add/subtract
An instruction in which a double-length product is created internally to which a third
operand is added or subtracted before truncating or rounding the result to the length of the
original operands.
rounding-mode suffix
The letter R and a number appended to the numeric value of a constant to request the
Assembler to perform a specific form of rounding.
significance exception
In hexadecimal floating-point, the result of an addition or subtraction yields a significand of
all zero digits. This exception can either cause a program interruption with IC=14, or can be
masked to produce a true zero.

Programming Problems
Problem 33.1.(2) Write a program to compute and print the hexadecimal floating-point values
of the expression
f(x) = 1/(x3 3x 2)
for integral values of x from 5 to + 5. Print the largest possible hexadecimal floating-point
value if the denominator is zero for any value of x in the range.

622

Assembler Language Programming for IBM z System Servers

Version 1.00

Problem 33.2.(2) Write a program to compute a table of factorials from 0 to 55, and determine
which values will be stored exactly (with no truncation error) for both short and long precision.
Problem 33.3.(4) Write a program to convert short hexadecimal floating-point numbers to a
printable decimal format such as -.123456E+21. Test your program by reading records with
eight hexadecimal characters: convert them to a word representing the short floating-point
number; convert those values, and print a line showing the original hexadecimal string and the
converted result.
Some sample input values are
80000000
451E240C
40100000
00000001
7FFFFFFF
and the output from the last of these could look like this:
X 7 FFFFFFF = +.723701E+76
Problem 33.4.(3) For values of X running from + 2.0 to 2.0 in steps of 0.1, write an instruction sequence to compute and print (in short hexadecimal floating-point) the value of the
expression
7X4 3X3 + 4x2 + 5x 2.
Evaluate the expression using only four multiplications by factoring it into nested form.
Problem 33.5.(3) Write a program using short, long, and extended precision hexadecimal
floating-point arithmetic that shows that the expression (1.0/N)N=1.0 is true for values of N
between 1 and 100 only when N is a power of 2.
Problem 33.6.(3) Using the iterative technique described in Section 31.3.1 on page 544, write a
program to evaluate the square root of 2 to 10 significant digits using long hexadecimal floatingpoint arithmetic, and without using hexadecimal square-root instructions. Format and print the
result as a fixed-point value.
Problem 33.7.(2) + To explore the relationship between significance and accuracy described in
Section 25.10, write a program to assemble the 50 decimal values
0.062499991
0.062499992
- - 0.062499999
0.062500000
0.062500001
- - 0.062500040
in short and long precision, and observe the behavior of the assembled constants. See if you can
find other sequences of decimal values that exhibit similar behavior.

Chapter IX: Floating-Point Data and Operations

623

624

Assembler Language Programming for IBM z System Servers

Version 1.00

34. Binary Floating-Point Data and Operations

3333333333
44
333333333333
444
33
33
4444
33
44 44
33
44 44
3333
44 44
3333
44444444444
33 444444444444
33
44
33
33
44
333333333333
44
3333333333
44

This section describes binary floating-point data and arithmetic, often known as IEEE Binary
Floating-Point 209 Its design is based on many years of experience with irregular floating-point
architectures that caused great problems in creating stable and reliable software. Binary floatingpoint was carefully designed210, has been widely adopted, and is now used on almost all
processors. Its benefits include:
Greater precision and exponent range than hexadecimal floating-point (except for short precision, which has greater exponent range), making exponent spills less likely.
Rounding for all arithmetic operations.
Gradual underflow.
Special values (such as infinity and Not a Number or NaN).
Ways to control and test for exception conditions.
First, well examine the binary floating-point data representations

34.1. Binary Floating-Point Data


Table 264 summarizes the three binary floating-point data formats supported by z System:
Length
(bytes)
4
8
16

Char.
(bits)
8
11
15

Min
exp.
126
1022
16382

Max
exp.
+ 127
+ 1023
+ 16383

Char.
Bias
+ 127
+ 1023
+ 16383

Precision
24
53
113

Max Norm.
(Max)
3.410 + 38
1.810 + 308
1.210 + 4932

Min Norm.
(Min)
1.210 38
2.210 308
3.410 4932

Min Denorm.
(DMin)
1.410 45
4.910 324
6.510 4966

Table 264. Binary floating-point data representations

209

210

IEEE stands for the Institute for Electric and Electronic Engineers, which publishes standards used in many industries.
The standards committee paid ...meticulous attention to details that hardly matter to most people but matter, when
they do matter, very much. (W. Kahan)
Chapter IX: Floating-Point Data and Operations

625

Unlike hexadecimal floating-point, the characteristic field width is different for each data length,
and certain characteristic bit patterns represent the special values infinity and Not a Number.
Another key difference is that almost all finite values are normalized. This means:
there are no redundant representations of finite values, and
the leading significant fraction digit of a normalized number must be 1, so it can be omitted
and its presence can be assumed.
Fraction and Significand
Unlike hexadecimal floating-point where all the significant bits of a
number (its significand) are present in the fraction field, the fraction of a
normal binary floating-point number does not contain all its significant
bits.

34.1.1. Data Representations


Figure 398 illustrates the three data formats. The three components of each format are
The sign bit (0 = + , 1 = )

s
char

The characteristic (biased exponent), with values from C min = 0 to C max = all 1-bits.
fraction
The remaining bits of the significand. Because there is an extra implied high-order 1-bit for
normal values, significands actually have 24-bit, 53-bit, and 113-bit precisions respectively.
1
8
23
Single, short
s char
fraction
(32bit)
Format
1
11
52
Double, long
s char
fraction
(64bit)
Format
1
15
112
/...//.../ Extended
s char

fraction
(128bit)
/...//.../ Format
Figure 398. Three binary floating-point data representations

There are six classes of binary floating-point data; all are signed:
1.
2.
3.
4.
5.
6.

Zero
Normal numbers
Denormalized numbers
Infinity
Quiet NaN
Signaling NaN

The Not a Number (or Not any Number) was introduced with the binary floating-point
standard. 211 It is used to indicate the result of an operation that cant deliver a valid result, such as
a division by zero. NaNs are very useful: they let you detect unusable results in your computations when they occur, and with proper error handling you can avoid doing lengthy calculations
only to produce useless results.

211

626

Some earlier processors supported reserved values such as indeterminate.


Assembler Language Programming for IBM z System Servers

Version 1.00

All but the normal numbers are considered special values, even though we normally think of only
NaNs and infinity as being special. Valid results can be (but might not be) generated from data
of all classes except NaNs.
Unlike hexadecimal and decimal floating-point, binary floating-point has no redundant representations.

34.1.2. Normal Numbers


The exponent of a normal number is determined from its unsigned characteristic:
Characteristic = Exponent + Bias
Two characteristic values, Cmin (0) and Cmax (all 1-bits), are reserved for special values. This
means that the characteristics range is (Cmin B i a s ) + 1 = E min to (C max Bias) 1 = E max , so the
exponent range is Emin to E max , as shown in Table 264.
Because the significand is actually 1.fraction (the leading 1-bit is implied), the fraction is necessarily always normalized, and the significand satisfies 1 significand < 2. Thus, the value of a
normal number is:
Single precision (short) value: (1.fraction) 2char 127
Double precision (long) value: (1.fraction) 2char 1023
Extended precision (16 bytes) value: (1.fraction) 2char 16383
Table 265 shows examples of short precision normal values.
Value
+ 1.0

S
0

Char.
01111111

Fraction
000........000

Representation
X 3 F800000

+ 15.0

10000010

1110000....000

X41700000

+ 0.1

01111011

10011001...011

X 3 DCCCCCD

+ Max

11111110

111........111

X 7 F7FFFFF

Min

00000001

000........000

X80800000

0.0

00000000

000........000

X80000000

Table 265. Examples of short-precision binary floating-point normal values

The first number has characteristic value 127 and zero fraction, so its value is
(1.0)2127 127 = 1.0.

34.1.3. Special Values


Special values are indicated by the reserved characteristic values Cmin (zero), and Cmax (all 1-bits).
1. If the characteristic is zero, there are two possible representations:
If the fraction is zero, the value is 0.
If the fraction is not zero, the value is a denormalized number.
In this case, there is no implied 1-bit before the fraction, so the value is
(0.fraction) 2 Emin . (E min values are shown in Table 264 on page 625.)
Table 266 shows examples of short precision denormalized values.
Value
110 40

S
0

Char.
00000000

Fraction
00...011000010

Representation
X000116C2

Largest Denorm

00000000

111........111

X007FFFFF

Smallest Denorm

00000000

000........001

X00000001

Table 266. Examples of short-precision binary floating-point denormalized values

Chapter IX: Floating-Point Data and Operations

627

2. If the characteristic is all 1-bits, two special values are represented:


If the fraction is zero, the value is infinity. Well see that the sign of an infinity is sometimes important.
If the fraction is nonzero, the value is a NaN. There are two types of NaN:

If the leftmost bit of the fraction is 1, the NaN is called a Quiet NaN.

If the leftmost bit of the fraction is 0, the NaN is called a Signaling NaN. Signaling
NaNs can cause exceptions.

The sign of a NaN is ignored.


Table 267 shows examples of short precision special values:
Value
Infinity

S
1

Char.
11111111

Fraction
0000....0000

Representation
X FF800000

a Quiet NaN

11111111

1100....0000

X 7 FE00000

a Signaling NaN

11111111

0100....0000

X 7 FA00000

Table 267. Examples of short-precision binary floating-point special values

34.1.4. Range of the Representation


The full range of representable binary floating-point data is sketched in Figure 399:

Special
Values

Normal
Values

Special
Values

Characteristic
Fraction
=/ 0: NaN
Cmaxs 111...111
 = 0: Infinity

s 111...110


s 111...101


: :
:
:
: :
:
: Zero fraction
: :
:
: implies value
: :
:
: is an integral
: :
:
: power of 2.
: :
:
:

s 000...010


s 000...001


Cmins 000...000
 = 0: Zero
=/ 0: Denormalized

Figure 399. Range of the binary floating-point representation

The special values with characteristic Cmax are infinity and NaNs; those with characteristic Cmin
are denormalized numbers and zero.
Another view of the binary floating-point representation for computationally valid values is
shown in Figure 400:

628

Assembler Language Programming for IBM z System Servers

Version 1.00

DeDeNormal numbers
norms -0 +0 norms
Normal numbers
 

+
Figure 400. A view of the binary floating-point representation

NaNs are the only representable forms that cant be used in arithmetic operations.

Exercises
34.1.1.(2) + Write numeric expressions for the values of the three short binary floating-point
values
Min (minimum normal number),
DMax (maximum denormalized number), and
DMin (minimum denormalized number).
34.1.2.(2) + In the short precision binary floating-point representation, how many denormalized
numbers can be represented?
34.1.3.(2) Show the hexadecimal representation of + infinity in short, long, and extended precision binary floating-point formats.
34.1.4.(2) Repeat Exercise 34.1.2 for long binary floating-point values.

34.2. Writing Binary Floating-Point Constants


Binary floating-point constants have the same types (E, D, and L) as other floating-point constants, and the type extension must be B.
EB

Short format binary floating-point

DB

Long format binary floating-point

LB

Extended format binary floating-point

You can create short binary floating-point constants like these:


SBFP1
SBTenth
BPi
B10Mil
B10Milth
Familiar

DC
DC
DC
DC
DC
DC

EB 1 . 0
EB 0 . 1
EB3.14159265
EB10000000
EB.0000001
EB123.4567

X 3 F800000
X 3 DCCCCCD
X40490FDB
X 4 B189680
X33D6BF95
X42F6E9D5

Binary floating-point 1
Binary floating-point 1/10
Pi
10**7
10**(-7)
A familiar value

Figure 401. Examples of short binary floating-point constants

Converting decimal values to binary floating-point is a bit complicated; if youre interested, heres
how its done for the last constant, + 123.4567:
1. The integer part of the constant is 123 = X 7B .
2. The fraction part, 0.4567, must be converted to binary. Using the method described in
Section 31.2 on page 541, the result (written in hexadecimal for compactness) is
X0.74EA4A8C1... .
3. The two parts combined (again, in hexadecimal) give 123.456710 = X 7 B.74EA4A8C1... .
4. Now, we rewrite this in binary: B111 1011. 0111 0100 1110 1010 1010 1000... .

Chapter IX: Floating-Point Data and Operations

629

5. We multiply the value by 2 6, so it can be rewritten as


B1.11 1011 0111 0100 1110 1010 1010 1000...26. The single 1-bit preceding the decimal
point is because normal binary floating-point values have an implicit high-order 1-bit.
6. We now know the exponent 6; adding the bias ( + 127, from Table 264 on page 625), the
characteristic is 133 = X 8 5 = B10000101.
7. From Table 264 the characteristic width is 8 bits; using a zero bit for the sign, we know that
the first 9 bits of the constant are 0 1000 0101, or 0100 0010 1.
8. Finally, we attach the fraction bits (omitting the implicit 1-bit):
B0100 0010 1111 0110 1110 1001 1101 0101, or X42F6E9D5 .
9. The first omitted bit (underscored in step 4 above) is zero, so the result wasnt rounded.
Its easy to see why we leave conversions to the Assembler!
Similarly, you can create long and extended format binary floating-point constants:
LBFP1
LBTenth
LB10Mil
XBMTenth

DC
DC
DC
DC

DB 1 . 0
LB 0 . 1
DB1000000
LB -.1

BFP
BFP
BFP
BFP

1, long format
1/10, extended format
10**7, long format
-0.1, extended format

Figure 402. Examples of long and extended binary floating-point constants

Rounding is important in binary floating-point arithmetic. You can choose how your constants
should be rounded by following the nominal value of a numeric constant with the letter R and a
decimal number. The supported rounding indicators are:
R1

Add 1 in the first lost bit position (biased round)

R4

Unbiased round to nearest, ties to even (default)

R5

Round toward zero (truncate, chop)

R6

Round toward maximum positive value ( + infinity)

R7

Round toward minimum positive value ( infinity)

If no rounding indicator is specified, the Assembler uses R4, unbiased round to nearest. The
examples in Figure 403 show how these rounding indicators are used; the first two constants use
default rounding.
DC
DC
DC
DC
DC
DC
DC
DC
DC
DC
DC
DC

EB+0.1
EB -0.1
EB+0.1R1
EB -0.1R1
EB+0.1R4
EB -0.1R4
EB+0.1R5
EB -0.1R5
EB+0.1R6
EB -0.1R6
EB+0.1R7
EB -0.1R7

X 3 DCCCCCD
X BDCCCCCD
X 3 DCCCCCD
X BDCCCCCD
X 3 DCCCCCD
X BDCCCCCD
X 3 DCCCCCC
X BDCCCCCC
X 3 DCCCCCD
X BDCCCCCC
X 3 DCCCCCC
X BDCCCCCD

Unbiased round half-even


Unbiased round half-even
Biased round
Biased round
Unbiased round half-even
Unbiased round half-even
Truncate
Truncate
Round toward +infinity
Round toward +infinity
Round toward -infinity
Round toward -infinity

Figure 403. Rounding indicators for binary floating-point constants

The Assembler also supports nominal-value operands for special values, as shown in Table 268.

630

Assembler Language Programming for IBM z System Servers

Version 1.00

Operand
(Inf)
(Max)
(Min)
(DMin)
(SNaN)
(QNaN)
(NaN)

Generated value
Infinity
Largest magnitude
Smallest normalized magnitude
Smallest denormalized magnitude
A Signaling NaN, with B 0 1 in the high-order fraction bits and zeros elsewhere
A Quiet NaN, with B 1 1 in the high-order fraction bits and zeros elsewhere
A Quiet NaN, with B 1 0 in the high-order fraction bits and zeros elsewhere

Table 268. Nominal-value operands for binary floating-point special values

These assembled constants are shown for each format in Table 269:
Value
(Inf)

Short
7F800000

Long
7FF0000000000000

Extended
7FFF000000000000 0000000000000000

(Max)

7F7FFFFF

7FEFFFFFFFFFFFFF

7FFEFFFFFFFFFFFF FFFFFFFFFFFFFFFF

(Min)

00800000

0010000000000000

0001000000000000 0000000000000000

(DMin)

00000001

0000000000000001

0000000000000000 0000000000000001

(SNaN)

7FA00000

7FF4000000000000

7FFF400000000000 0000000000000000

(QNaN)

7FE00000

7FFC000000000000

7FFFC00000000000 0000000000000000

(NaN)

7FC00000

7FF8000000000000

7FFF800000000000 0000000000000000

Table 269. Assembled binary floating-point special-value constants

Special values may be signed:


DC
DC
DC

EB -(Inf)
DB -(Min)
LB -(NaN)

X FF800000
X8010000000000000
X FFFF800000000000 0000000000000000

Sometimes it is useful to add information to the unused fraction bits of a NaN, such as its address
or the number of the statement in which it was defined. This payload can be used for diagnostic
information when a numeric result doesnt behave as you might expect.
QN
QNParm
SN
SNParm

DC
Org
DC
DC
Org
DC

EB ( QNaN)
*-2
H1324
DB ( SNaN)
*-4
A(SN)

Short QNaN
Back up location counter by 2
Statement 1324, short NaN payload
Long SNaN
Back up location counter by 4
Address of the long SNaN

Figure 404. Examples of parameterized binary floating-point NaNs

If you decide to parameterize your NaNs by adding payloads, follow these guidelines:
Dont use the two high-order fraction bits; they are needed to distinguish NaN types.
If possible, use at most the 21 high-order bits for NaN payload values, in case your NaN
might be used in an arithmetic operation that yields a short-format result.
Thus, in Figure 404 the SNParm payload might be truncated if the NaN named SN is shortened, and the address information would be incorrect.

34.2.1. Decimal Exponents and Exponent Modifiers


As with other numeric floating-point constants, you can specify a decimal exponent with the
nominal value, and an exponent modifier to apply to all values in the constant. For example,
some of the constants in Figures 401 and 402 could be written as in Figure 405.

Chapter IX: Floating-Point Data and Operations

631

B10Mil DC
B10Milth DC

EB 1 E7
EB 1 E-7

X 4 B189680
X33D6BF95

Exponent
Exponent

B10Mil DC
B10Milth DC

EBE7 1
EBE-7 1

X 4 B189680
X33D6BF95

Modifier
Modifier

LBFP1

DBE-12 1 E12

X 3 FF0000000000000 Both

DC

Figure 405. Binary floating-point constants with decimal exponents and modifiers

As the constant LBFP1 shows, the power of ten multiplying the numeric part of the constant is the
sum of the exponent modifier ( 12) and the decimal exponent ( + 12), so the generated constant is
simply 1.0 in long precision.

34.2.2. Length Modifiers (*)


Length modifiers are rarely used for binary floating-point data. To avoid excessive truncation, the
Assembler requires the minimum bit lengths shown in Table 270.
Data Type

Short

Long

Extended

Normal values
Special values

9
11

11
14

16
18

Table 270. Minimum bit lengths for binary floating-point constants

While it may seem strange to allow normal binary floating-point constants to include only the
sign and exponent, there is always an implied 1-bit preceding the radix point. Thus, you could
write
DC

LBL2 1

X 3 FFF

and generate a valid (if not especially useful) constant!


The minimum lengths for special values are two larger than for normal values, to make sure
theres enough room for the bits distinguishing NaN types.
Advice
Dont use length modifiers with binary floating-point constants.
Binary floating-point constants do not support a Scale modifier.

Exercises
34.2.1.(2) What is the hexadecimal representation of the decimal value 0.1 with lengths 2, 3, and
4 bytes in each of the three formats?
34.2.2.(2) + A four-byte area of memory contains the bit pattern X4040405C . What is represented by that pattern? (You should now be able to describe six different possibilities.)
34.2.3. Determine if each of these short binary floating-point numbers is zero, normal,
denormal, infinity, a QNaN, or a SNaN:
1.
2.
3.
4.
5.
6.

X 7 FFFFFFF
X007FFFFF
X80000000
X00FFFFFF
X FF8000AB
X FF800000

34.2.4.(3) Suppose you define these constants:

632

Assembler Language Programming for IBM z System Servers

Version 1.00

Short
DC
ShortOne DC

DBL4 0 . 1
DBL4 1

Long
DC
LongOne DC

EBL8 0 . 1
EBL8 1

What values would actually appear when the first pair is used as short operands, and the second
pair is used as long operands?

34.3. Binary Floating-Point Arithmetic in General


The IEEE standard 212 specifies a powerful rule:
Each of the computational operations that return a numeric result ... shall be performed
as if it first produced an intermediate result to infinite precision and with unbounded
range, and then rounded that intermediate result, if necessary, to fit the destinations
format.
This rule means that you can know the calculated result in all situations.

34.3.1. Rounding Modes


The standard specifies that the result cannot suffer more than one rounding error. There are
four global rounding modes that can be set to apply to subsequent operations; you can change
them during your programs execution.
0

Unbiased round to nearest (ties exact values lying exactly half way between two representations in the target formatoperand in FPR0 isnt in long formatits just the high-order
round to the neighbor of the exact value with low-order bit zero)

Round toward zero (truncate)

Round toward +

Round toward

Most applications use rounding mode 0 and dont change it during execution.
Some specialized instructions provide an explicit local rounding-method mask field for the
operation of only that one instruction:
0

Round according to the current global rounding mode in the Floating-Point Control Register (described in Section 34.4.1)

Biased round to nearest (ties round away from zero; effectively, the same as adding 1 to the
first lost bit)

Unbiased round to nearest

Round toward zero (truncate)

Round toward +

Round toward

Most of the conversion instructions between binary floating-point and binary integers provide a
local rounding mask.

212

The full name is IEEE Std 754 -2008.


Chapter IX: Floating-Point Data and Operations

633

34.3.2. Denormalized Numbers


Denormalized numbers allow gradual underflow if the exponent of a normalized result might
fall below Emin . This means that binary floating-point arithmetic needs no unnormalizing arithmetic operations.
To illustrate the importance of denormalization, well use the notation for FPF(10,4) numbers
introduced in Section 32.9 on page 569, where Emin is 9. Suppose we have two numbers
X = (.123410 9) or [ 9+ .1234], and Y = (.120010 9), or [ 9+ .1200]. Then X Y is
-9+ .1234
- -9+ .1200
= -9+ .0034
= -11+ .3400

X
-Y
intermediate denormalized result
normalized (underflowed) result

Because the exponent of the normalized result is 11, the result is often set to zero.
Suppose we add Y to (X Y): we would expect to get X.
-9+ .1200
+ 0+ .0000
= -9+ .1200

Y
underflowed difference (X-Y)
normalized result = Y

so that without denormalization, (X Y) + Y gives Y! However, if the result of (X Y) is denormalized, we get


-9+ .0034
+ -9+ .1200
= -9+ .1234

denormalized difference (X-Y)


Y
normalized result = X

and (X Y) + Y gives X, the result we expect.


Denormalized numbers are the default result of gradual underflow.
Of course, normal underflow can occur. In FPF(10,4), if we multiply [ 6+ .2000] by itself, the
intermediate result is [ 12+ .0400]. Deormalizing this result while retaining a nonzero fraction
can only generate [ 10+ .0004], so that one further denormalization step to increase the exponent to 9 generates a zero fraction. This is a true underflow.
It sometimes helps to visualize a line of binary floating-point values close to zero. If values
smaller than E min are normalized (or flushed to zero), there are no represented values between
E min and zero. However, with gradual underflow there are as many values between between Emin
and zero as between between Emin and between E min + 1. In Figure 406 (a magnification of the
region near zero in Figure 400 on page 629), we suppose the binary floating-point numbers have
3 fraction bits:
abrupt underflow range






0
Emin
Emin+1
Emin+2
EMin+3








gradual underflow range
1 ulp
1 ulp
Figure 406. Values representable with gradual underflow

As noted in Section 32.8 on page 567, an ulp of a number varies with the magnitude of the
number. As the figure illustrates, an ulp is proportional to the spacing between neighboring
representable values.

634

Assembler Language Programming for IBM z System Servers

Version 1.00

34.3.3. Arithmetic with Zero, Infinity, and NaNs


The IEEE standard defines actions taken when operations involve zero, infinity, or NaNs.
1. Zero
In operations with finite values Fn, zero behaves as you would expect: 0Fn is zero, 0 F n
and Fn 0 all return that finite number Fn. 213
Some situations require creation of 0, such as:
+ 0(negative finite number), or 0(positive finite number)
+ 0 (negative finite number), or 0 (positive finite number)
(F n F n), rounded toward
( 0) + ( 0)
Square root of 0
2. Infinity
Valid arithmetic on infinities is always exact, and correctly signed. If Fn is a finite number,
then:

Fn =
| | + | | =
Fn =
Fn = 0
Fn 0 =

and other similar operations.


Note, however, that infinity doesnt behave like a finite number, where (1 X)X = 1 ,
X X=1, and X X = 0 . I f X = , none of these relations apply!
3. NaNs
NaN operands in arithmetic operations have several possible results:
A SNaN will either cause an invalid-operation exception or produce a QNaN as the
result, depending on the setting of a mask bit (described shortly, in Section 34.4).
QNaNs are propagated without causing an exception; if both operands are QNaNs, the
CPU will deliver operand 1.

Exercises
34.3.1.(3) Show in hexadecimal the result generated if you calculate (Min)-(DMin) in short
binary floating-point.
Details
The next section describes binary floating-point exceptions. If you are
interested mainly in the arithmetic operations, skip ahead to Section 34.5.

34.4. Binary Floating-Point Exceptions, Interruptions, and Controls


The IEEE binary floating-point standard also defines a rich set of controls for exceptions, when a
valid result cannot be generated. Unlike hexadecimal floating-point, where only exponent underflow and lost significance can be controlled by bits in the Program Mask, binary floating-point
lets you control five exception conditions.
1. Invalid operation has two causes:
Mathematically meaningless operations, such as

213

A Cornell student once asked a professor, Is zero a number? He replied, Oh yes! Its one of the best!
Chapter IX: Floating-Point Data and Operations

635

a.
b.
c.
d.
e.
f.

| | | |
0

0 0
Remainder of X Y with X = or Y = 0
Square root of a negative value

Computationally meaningless operations, such as


a. an operation on a Signaling NaN (SNaN)
b. a comparison operation involving a NaN (an unordered comparison)
c. an integer-conversion fault (where the source operand is a NaN, , or is too large for
the target operand)
2. Division by zero (0 0 is an invalid operation).
3. Exponent overflow: the magnitude of the result is too large for the target format.
4. Exponent underflow: the magnitude of the result is too small for the target format.
5. Inexact result occurs when a rounding operation changes the value of the exact infiniteprecision unbounded-range result. This condition can occur with others.

34.4.1. Binary Floating-Point Exceptions (*)


Exceptions can cause an interruption (the IEEE standard calls it a trap), or set a status flag bit.
Which of these two actions occurs depends on the setting of a mask bit.
The mask bits and the status flags are held in the Floating-Point Control (FPC) Register; it is
distinct from all other registers. In addition to the mask and status flag bits, the FPC register
contains a Data Exception Code (DXC) and bits for the global rounding mode. Figure 407
illustrates the format of the FPCR.

Data Excep n Rounding

Mask Bits
Flag Bits Code (DXC) Mode Bits

i z o u x 0 0 0i z o u x 0 0 0i z o u x y 0 00 0 0 0 0 0 BRM

8
8
8
8
Figure 407. Floating-Point Control (FPC) register

The mask and flag bits in the first and second bytes are indicated by single letters:
Bit

Meaning

i (bit 0)

Invalid operation

z (bit 1)

Divide by zero

o (bit 2)

Overflow

u (bit 3)

Underflow

x (bit 4)

Inexact result

When an exception occurs, the CPU takes one of two actions:

If the corresponding mask bit is one an interruption occurs, the Interruption Code is set to
7, and information about the cause is placed in the Data Exception Code (DXC) byte and
in memory at address 147 (X 9 3 ). The corresponding flag bit is unchanged.

If the corresponding mask bit is zero a default action is taken, no interruption occurs, its
corresponding status flag bit is set to 1, and the DXC remains unchanged. A default result
value is generated.
Once a status flag bit is set to 1, it is unchanged until it is explicitly reset by an instruction
that changes the contents of the FPC register.

636

Assembler Language Programming for IBM z System Servers

Version 1.00

Sometimes the mask bits in the first byte are called Interruption Mask bits, abbreviated IMi,
IMz, etc.; and the flag bits in the second byte are called Status Flag bits, abbreviated SFi,
SFz, etc.
The third byte of the FPC register holds the DXC; its value is set when an interruption
occurs. The y in Figure 407 appears only in the DXC:
Bit

Meaning

y (bit 5)

The result was incremented

Note that the first five bits of the DXC shown in Figure 407 correspond from left to right to
the first five bits of the mask and flag bits.
If an interruption occurs the Interruption Code is set to 7, the same IC used for the (packed
decimal) Data Exception. To learn whether the interruption is due to a binary floating-point
or packed decimal operation, you must test the DXC for zero (packed decimal) or nonzero
(binary floating-point).
Table 271 describes the values placed in the DXC:
DXC
00
01
02
08
0C
10
18
1C
20
28
2C
40
80

Meaning
Decimal data exception (for invalid packed decimal data, as discussed in Section 29)
An invalid Floating-Point Register is used by a floating-point instruction; the registers are available on this CPU, but are not enabled
a BFP instruction is attempting to execute on a CPU where BFP instructions are
available, but are not enabled
IEEE inexact exception; the result was truncated
IEEE inexact exception; the result was incremented
IEEE underflow exception; the result is exact
IEEE underflow exception; the result is inexact and was truncated
IEEE underflow exception; the result is inexact and was incremented
IEEE overflow exception; the result is exact
IEEE overflow exception; the result is inexact and was truncated
IEEE overflow exception; the result is inexact and was incremented
IEEE division by zero
IEEE invalid operation

Table 271. Binary floating-point DXC values

The binary floating-point rounding mode is specified by the two low-order bits of the fourth
byte of the FPC register, indicated by BRM in Figure 407. They have the same values we saw
for the rounding modes discussed in Section 34.3.1 on page 633:
BRM

Meaning

B 0 0

To nearest

B 0 1

Toward zero (truncate)

B 1 0

Up (toward + )

B 1 1

Down (toward )

34.4.2. FPC Register Instructions (*)


The five instructions in Table 272 are used to manage the FPC register.

Chapter IX: Floating-Point Data and Operations

637

Op
B29D
B384
B38C
B299

Mnem
LFPC
SFPC
EFPC
SRNM

Type
S
RRE
RRE
S

Instruction
Load F P C
Set F P C
Extract F P C
Set BFP Rounding Mode

Op
B2BD
B385
B29C

Mnem
LFAS
SFASR
STFPC

Type
S
RRE
S

Instruction
Load FPC and Signal
Set FPC and Signal
Store F P C

Table 272. Binary floating-point F P C register control instructions

The Load FPC and Store FPC instructions use a 32-bit operand in memory. They are used to set
the mask and Rounding Mode bits. For example:
STFPC OldFPC
LFPC NewFPC

Store current FPCR into memory


Load new FPCR from memory

The flag bits and the Data Exception Code are set by the CPU when an exception condition
occurs.
The Set FPC and Extract FPC instructions use a 32-bit operand in the rightmost 32 bits of a
general register; bits 0-31 in the left half of the register are unaffected. For example:
SFPC 1
EFPC 1

Set FPCR from GPR 1


Extract FPCR into GPR 1

The SRNM (Set BFP Rounding Mode) instruction takes its operand from the rightmost 2 bits of
its Effective Address and puts them in the BRM (Binary Rounding Mode) bits of the FPCR.
The rest of the FPCR is unchanged. For example:
SRNM 0(5)
SRNM 1

Set BRM from last 2 bits of GPR5


Set rounding mode to toward zero

The LFAS and SFASR instructions load and set the FPCR, but with the side effect of possibly
generating a specific exception condition. They are used to simulate BFP exception conditions
without needing to perform actual BPF operations that would generate the exceptions. They
make it easier to write and test exception handling routines. Because their use is specialized, we
wont discuss them further.

34.4.3. Exception Actions (*)


When an exception occurs, the generated result depends on whether an interruption occurs (the
corresponding mask bit is 1) or does not (the corresponding mask bit is 0).
1. Invalid operation
Mask bit = 1
An interruption occurs: the DXC is set to
X 8 0 , and the instruction is suppressed (registers remain unchanged). The i flag bit is
unchanged.

Mask bit = 0
A special hardware generated QNaN is
delivered as the default result: its first fraction bit is 1, and the rest of the fraction is
zero. If an operand was a SNaN, the corresponding QNaN is delivered. The i flag bit
is set to 1.

Table 273. Invalid operation binary floating-point exception

If the two operands are QNaN and SNaN, the SNaN takes precedence as the result, even if it
is forced to a QNaN.
2. Divide by zero

638

Assembler Language Programming for IBM z System Servers

Version 1.00

Mask bit = 1
An interruption occurs: the DXC is set to
X 4 0 , and the instruction is suppressed (registers remain unchanged). The z flag bit is
unchanged.

Mask bit = 0
A infinity is delivered. The z flag bit is set
to 1.

Table 274. Divide by zero binary floating-point exception

3. Overflow
Mask bit = 1
An interruption occurs: the DXC is set to
X 2 0 , X 2 8 , or X 2C , and the exponent of
the result is scaled. The o flag bit is
unchanged.

Mask bit = 0
A correctly signed infinity or MaxReal is
delivered, depending on the current rounding
mode. The o and x flag bits are set to 1.

Table 275. Exponent overflow binary floating-point exception

Be Careful!
If possible, dont set overflowed results to MaxReal. MaxReal is a
valid finite number, so it might propagate unnoticed through subsequent computations.
4. Underflow
Mask bit = 1
An interruption occurs: the DXC is set to
X 1 0 , X 1 8 , or X 1C , and the exponent of
the result is scaled. The u flag bit is
unchanged.

Mask bit = 0
A zero or denormalized result is delivered.
The u flag bit is set to 1, and the x flag bit is
set to 1 if the result is inexact.

Table 276. Exponent underflow binary floating-point exception

5. Inexact result (An inexact exception can also occur with BFP overflow or underflow.)
Mask bit = 1
An interruption occurs: the DXC is set to
X 0 9 X 0C . The x flag bit is unchanged.

Mask bit = 0
The result is delivered. The x flag bit is set
to 1.

Table 277. Inexact result binary floating-point exception

The mask and flag bits in the FPC register are ignored for HFP and FP Support instructions.
Remember
Binary floating-point exceptions may or may not cause a program interruption, depending on the settings of mask bits in the FPC register, and
the generated results can be quite different.

34.4.4. Scaled Exponents (*)


When an exponent overflow or underflow is not masked the CPU generates a program interruption, and the characteristic of the result is adjusted or scaled by adding (for underflows) or
subtracting (for overflows) a fixed quantity. This adjustment brings the scaled result near the
middle of the characteristic range, so that the decimal exponent is nearer to zero than the ends of
the exponent range. The scaling factors are shown in Table 278 on page 640.

Chapter IX: Floating-Point Data and Operations

639

Data length
Short
Long
Extended

Scale Factor
192
1536
24576

Table 278. BFP overflow/underflow scale factors

To see how this works, consider multiplying two short binary floating-point numbers that cause
overflow. If their exponents are both Emax = + 127, the exponent of the product will be about
+ 254. By subtracting the scale factor (192), the exponent of the product will be about + 62, nearly
half of Emax , and easier to manage if further adjustments are needed.

Exercises
34.4.1.(1) + What binary floating-point exception conditions and rounding mode will be set by
this instruction?
LFPC =X30000003
34.4.2.(2) What will be the effect of executing these three instructions?
EFPC 9
NILH 9,=X 7 F00
SFPC 9
34.4.3.(2) + In Table 271, a Data Exception Code X 0 2 means that you have tried to execute a
BFP instruction on a CPU where BFP instructions are available, but not enabled. What do
you think will happen if you try to execute a BFP instruction on a CPU where the BFP
instructions are not available?
34.4.4.(1) + Refer to Table 271 on page 637 and construct a table that identifies the meaning of
each of the 8 bits in the DXC.

34.5. Basic Binary Floating-Point Instructions


Before we discuss the basic binary floating-point instructions, its worth reviewing the instructions
in Section 31.9 starting on page 555. Those instructions can move floating-point operands of all
representations, so they can be used with hexadecimal floating-point, binary floating-point, and
decimal floating-point data.
Some general points to remember about binary floating-point instructions:
Almost all binary floating-point instruction mnemonics contain a letter B
Their actions are more complex than the equivalent operations in hexadecimal floating-point,
due to the presence of rounding modes, NaNs and infinities, maskable exceptions, and different exponent ranges.
Instructions involving extended-precision operands must specify a valid pair of floating-point
registers.
They support a full range of common algebraic operations.
Unlike hexadecimal floating-point, binary floating-point supports non-numeric values. Because
its difficult to test an operand for a special value by examining its bit patterns, we use the Test
Data Class instructions listed in Table 279.

640

Assembler Language Programming for IBM z System Servers

Version 1.00

Op
ED10
ED12

Mnem
TCEB
TCXB

Type
RXE
RXE

Instruction
Test Data Class (Short)
Test Data Class
(Extended)

Op
Mnem
ED11 TCDB

Type
RXE

Instruction
Test Data Class (Long)

Table 279. Binary floating-point Test Data Class instructions

A bit pattern in the rightmost 12 bits of the Effective Address of the second operand address tests
selected classes of the first operand. The test bits are shown in Table 280.
Class
Zero
Norm
Denorm
Infinity
QNaN
SNaN

+ sign
52
54

sign
53
55

56
58
60
62

57
59
61
63

Table 280. Test Data Class second-operand bits

Another view of the corresponding positions of the bits in the second operand Effective Address
and the tested value is illustrated in Table 281.
60

61

62

63
SNaN

+ Denormal

59

+ SNaN

Normal

58

QNaN

+ Normal

57

+ QNaN

56

Infinity

55

+ Infinity

54

Denormal

53
Zero

Ignored

52
+ Zero

Bits 0-51

Table 281. Test Data Class second-operand test-bit/tested-value correspondence

If any test bit corresponds to the class of the first operand, the Condition Code is set to 1; otherwise, it is set to 0. You can use these instructions to test for SNaNs without causing an invalidoperation Exception.
The 12 bits of the test pattern fit in the instructions displacement field, so you can specify it both
at assembly time and at execution time. For example, suppose you want to test a short binary
floating-point operand for infinity:
LE
2,FPData
TCEB 2,X030
JNZ AnInfin

Get the operand


Test for + or - infinity
Branch if yes

LA
9,B110000
TCEB 2,0(,9)
JNZ AnInfin

Put test mask bits in GR9


Same test
Branch if yes

or

The TDEB instructions use the same test bit pattern.

Exercises
34.5.1.(2) Given a binary floating-point operand in FPR0, which data classes will these
instructions detect?

Chapter IX: Floating-Point Data and Operations

641

(a)
(b)
(c)
(d)

TCEB
TCDB
TCXB
TCDB

0,29
0,4095
0,15
0,X C00

34.5.2.(3) What result would you expect from executing each pair of these instructions:
(a)
(b)
(c)

LE
TCEB
LE
TCXB
LE
TCDB

2,=DB ( Inf)
2,X 3 0
4,=EB 4 2
4,X300
6,=EB 4 2
6,X300

Test for infinity


Test for normal
Test for normal

34.5.3.(1) + Which instruction in Exercise 34.5.1 is redundant?


34.5.4.(3) For each data item in Exercise 34.2.3, what operand of the TCxB instruction should
be used to correctly determine the class of the item?

34.6. Binary Floating-Point RR-Type Data Movement Instructions


Remember that the instructions described in Section 31.9 can be used to move any floating-point
data between registers and memory. The instructions in Table 282 differ from the related
representation-independent instructions because they are sensitive to the presence of NaN operands.
Op
B302

Mnem
LTEBR

Type
RRE

Instruction
Load and Test (Short)

Op
B303

Mnem
LCEBR

Type
RRE

B301

LNEBR

RRE

Load Negative (Short)

B300

LPEBR

RRE

B312

LTDBR

RRE

Load and Test (Long)

B313

LCDBR

RRE

B311

LNDBR

RRE

Load Negative (Long)

B310

LPDBR

RRE

B342

LTXBR

RRE

Load and Test (Extended)

B343

LCXBR

RRE

B341

LNXBR

RRE

Load Negative (Extended)

B340

LPXBR

RRE

Instruction
Load Complement
(Short)
Load Positive (Short)
Load Complement
(Long)
Load Positive (Long)
Load Complement
(Extended)
Load Positive
(Extended)

Table 282. Binary floating-point RR-type data movement instructions

For the operations Load Complement, Load Negative, and Load Positive, the result placed at the
first operand will be unmodified except for a possible sign change, even if the operand is a NaN.
For short operands, the right half of the target register is unchanged.
The CC setting is shown in Table 283:
CC
0
1
2
3

Meaning
Operand is zero
Operand is less than zero
Operand is greater than zero
Operand is a NaN

Table 283. CC settings for BFP data movement instructions

The Load and Test instructions are sensitive to the difference between a QNaN and an SNaN. If
the second operand is a Signaling NaN, an invalid operation exception occurs, and the result
depends on the setting of the invalid-operation mask bit in the FPCR:

642

Assembler Language Programming for IBM z System Servers

Version 1.00

If the mask bit in the FPCR for an invalid operation is 1, an interruption occurs, and the
Condition Code is unchanged.
If the mask bit is 0, no interruption occurs, and the result is the corresponding QNaN.
If no interruption occurs, the Condition Code is set by the Load and Test instructions as
shown in Table 283.
Figure 408 shows some examples of these instructions:
LE
LCEBR
LTEBR
LNEBR

0,=EB ( QNaN)
2,0
4,0
6,0

c(FPR0)=X 7 FE00000
c(FPR2)=X FFE00000 , CC=1
c(FPR4)=X 7 FE00000 , CC=3
c(FPR6)=X FFE00000 , CC=1

*
LD
0,=DB -3.14
LTDBR 0,0
LPDBR 2,0

c(FPR0)=X C0091EB851EB851F
CC=1
c(FPR2)=X40091EB851EB851F , CC=2

Figure 408. Examples of binary floating-point data movement instructions

Dont mix floating-point data types


You might accidentally use a hexadecimal floating-point operation on
binary floating-point data, or vice versa. The results may be unexpected!

Exercises
34.6.1.(1) If you execute these instructions:
LD
4,=X50123456789ABCDE
LD
6,=X FEDCBA9876543210
LTXBR 0,4
What will be in the register pair FPR(0,2), and what will be the CC setting?
34.6.2.(2) Suppose c(FPR0)=X 0 A123456789ABCDE and c(FPR2)=X42857196DBB93310 . Show
the CC setting and the contents of the result register or registers after executing each of the
following instructions:
(1)
(2)
(3)
(4)

LPEBR
LTDBR
LCXBR
LCDBR

4,2
2,2
4,0
4,2

34.6.3.(2) Suppose you execute these sets of instructions. What will be the resulting CC setting
for each case?
(a)

LE
0,=EB ( SNaN)
LTER 0,0

(b)

LE
2,=X FFFFFFFF
LCEBR 2,2

34.6.4. Which instruction in Exercise 34.5.1 could be replaced by one other instruction, and
what is that instruction?

Chapter IX: Floating-Point Data and Operations

643

34.7. Binary Floating-Point Multiplication


Table 284 lists the instructions for binary floating-point multiplication. None of them change the
Condition Code.
Op
ED17

Mnem
MEEB

Type
RXE

ED0C

MDEB

RXE

ED1C

MDB

RXE

ED07

MXDB

RXE

Instruction
Multiply
(ShortShortShort)
Multiply
(LongShortShort)
Multiply
(LongLongLong)

Op
B317

Mnem
MEEBR

Type
RRE

B30C M D E B R

RRE

B31C M D B R

RRE

Multiply
(ExtendedLongLong)

B307

MXDBR RRE

B34C M X B R

RRE

Instruction
Multiply
(ShortShortShort)
Multiply
(LongShortShort)
Multiply
(LongLongLong)
Multiply
(ExtendedLongLong)
Multiply
(Ext.Ext.Ext.)

Table 284. Binary floating-point Multiply instructions

As the table indicates, five instructions (MEEB, MEEBR, MDB, MDBR, and MXBR) generate
a product the same length as the two operands, while four others (MDEB, MDEBR, MXDB,
and MXDBR) generate a double-length product. As with other multiply instructions, the sign of
the product is the XOR of the signs of the two operands, even if they are zero or infinity.
MXBR, like other instructions handling extended-precision operands, must refer to valid floatingpoint register pairs.
Multiplying two finite values gives the expected rounded result, determined by the rounding mode
in the FPCR, so long as there is no overflow or underflow. Figure 409 gives an example, where
weve assumed the default rounding mode (to nearest).
LE
0,=EB 0 . 1
MDEB 0,=EB -0.2
LE

0,=EB 0 . 1

*
MEEB 0,=EB -0.2

c(FPR0)=X 3 DCCCCCD
c(FPR0)=X BF947AE151EB8520 Long product
c(FPR0)=X 3 DCCCCCD
Multiply by X BE4CCCCD (= -0.2)
c(FPR0)=X BCA3D70B
Short product

Figure 409. Example of binary floating-point multiply instructions

The first multiplication (using MDEB) creates a double-length product of the two operands; its
fraction digits start with X47AE151E... . The single-length product (using MEEB) has a shorter
exponent field, so its fraction digits are X47AE16 . Because the longer result is slightly closer to
X47AE16 than to X47AE14 , default rounding generates the indicated result.
But: the short product is not exact. If the inexact (x) mask bit in the FPCR is 1, a program
interruption will occur. Because we normally dont care about unused trailing bits of a product,
that mask bit is often set to zero to suppress the inexact exception.
Figure 410 shows how overflow and underflow can occur when we multiply two sufficiently large
or sufficiently small numbers:

644

Assembler Language Programming for IBM z System Servers

Version 1.00

* (1) With the


LFPC
LE
MEEBR
LE
MEEBR

overflow mask bit set to 1:


=X F8000000
All mask bits = 1 (allow interrupts)
0,=EB 1 E20
c(FPR0)=X60AD78EC
0,0
c(FPR0)=X21EB1950 Overflowed result
0,=EB 1 E-30
c(FPR0)=X 0 DA24260
0,0
c(FPR0)=X 3 BCDB025 Underflowed result

* (2) With the


LFPC
LE
MEEBR
LE
MEEBR

overflow and underflow mask bits set to 0:


=F 0
All mask bits = 0 (no interrupts)
0,=EB 1 E20
c(FPR0)=X60AD78EC
0,=EB -(Inf)
c(FPR0)=X 7 F800000 Overflow to +infinity
0,=EB 1 E-30
c(FPR0)=X 0 DA24260
0,0
c(FPR0)=X00000000 Underflow to zero

Figure 410. Examples of binary floating-point multiplication overflow and underflow

In case (1), both MEEBR instructions cause interruptions, and the result in FPR0 is set to a
scaled result: the significand is correct, but the exponent has been adjusted by a fixed amount to
bring the result into a more manageable range. Further computation with this result must take
account of the exponent scaling.
In case (2) both interruptions are suppressed, and the default result is + infinity for overflow, and
zero for underflow.
Figure 411 shows two examples with signed zeros and infinities:
LE
0,=EB -0.
MEEBR 0,0

c(FPR0)=X80000000 (-0)
c(FPR0)=X00000000 (-0)*(-0) = +0

LE
0,=EB ( Inf)
MEEBR 0,=EB -(Inf)

c(FPR0)=X 7 F800000 (+infinity)


c(FPR0)=X FF800000 ( -infinity)

Figure 411. Examples of binary floating-point multiply instructions

Figure 412 shows how a denormalized result can be generated:


LFPC =F 0
LE
0,=EB 1 E-21
MEEBR 0,0

Set all mask bits to zero


c(FPR0)=X 1 C971DA0
c(FPR0)=X000002CA

Figure 412. Example of binary floating-point denormalized product

If the mask bit for exponent underflow had not been set to zero, an underflow exception would
have occurred, and the result would have a wrapped exponent rather than a denormalized
number.
Table 284 shows that the product of two extended operands is formed by the RRE-type instruction MXBR, so that both operands must be loaded into register pairs, as illustrated in Figure 413:

LD
LD
LD
LD
MXBR
Now,

0,=LB 0 . 1
c(FPR0)=X 3 FFB999999999999
2,=LB0.1+8
c(FPR2)=X999999999999999A
4,=LB -0.2
c(FPR4)=X BFFC999999999999
6,=LB -0.2+8
c(FPR6)=X999999999999999A
0,4
c(FPR0,FPR2)=X BFF947AE147AE147 AE147AE147AE147C

Figure 413. Example of binary floating-point extended-precision operands

The product contains a repeating digit pattern X147AE ; the final digit has been rounded up to the
nearest even value. As in Figure 409, if the mask bit for inexact result had been one, an interruption for an inexact exception would have occurred.
If the operands are not finite numbers, some special rules apply:
Multiplying two infinities, or a finite nonzero number by infinity, generates an infinity.
Chapter IX: Floating-Point Data and Operations

645

Multiplying zero and infinity generates an invalid-operation exception. If the corresponding


mask bit is zero, the generated result is a default QNaN.
If both operands are QNaNs, the first operand is generated.
If either operand is a SNaN, an invalid-operation exception is generated. If the corresponding
mask bit is zero, the generated result is the corresponding QNaN. (If both operands are
SNaNs, the first operand is used to create the corresponding QNaN.)
As these rules indicate, the result depends on the order of the operands only if one or both is a
NaN. For other values, the order of the operands doesnt matter.

Exercises
34.7.1.(2) Show the actual bit patterns of the two products in Figure 409 and determine how
the rounded product of the second multiplication is formed.
34.7.2.(2) Write a program segment using binary floating-point arithmetic that will compute a
table of the cubes of the first 100 integers, and store them as short binary floating-point
numbers starting at BCubes.
34.7.3.(3) + How can you generate the maximum positive short-precision binary floating-point
number by multiplying two finite short binary floating-point values?
34.7.4.(2) In Figure 410 part (1), determine the exponent of each operand before executing the
instruction, and the scaled exponent of each result.

34.8. Binary Floating-Point Division


Table 285 lists the five binary floating-point divide instructions. None of them generate a
remainder; the instructions described in Section 34.13 on page 655 can be used to calculate a
remainder in most cases. The Condition Code is unchanged.
Op
ED0D
ED1D

Mnem
DEB
DDB

Type
RXE
RXE

Instruction
Divide (Short)
Divide (Long)

Op
B30D
B31D
B34D

Mnem
DEBR
DDBR
DXBR

Type
RRE
RRE
RRE

Instruction
Divide (Short)
Divide (Long)
Divide (Extended)

Table 285. Binary floating-point Divide instructions

As this table shows, none of the instructions operate on mixed-length operands: dividend, divisor,
and quotient all have the same length. DXBR, like other instructions handling extendedprecision operands, must refer to valid floating-point register pairs.
If the result is finite, zero, or infinity (and not a NaN), the sign of the quotient is the XOR of the
operand signs.
Figure 414 shows two examples of binary floating-point division.
LE
DEB

2,=EB 7
2,=EB 2

Result = 3.5 = X40600000

LD
DDB

0,=DB987654321
0,=DB 3

Result = 329218107 = X41B39F783B000000

Figure 414. Examples of binary floating-point division

The quotient is rounded according to the current rounding mode in the Floating-Point Control
Register.

646

Assembler Language Programming for IBM z System Servers

Version 1.00

Division can also generate overflow and underflow exceptions, as illustrated in Figure 415:
* (1) With the
LFPC
LE
LER
LE
DEBR
DEBR

overflow mask bit set to 1:


=X F8000000
All mask bits = 1 (allow interrupts)
0,=EB 1 E20
c(FPR0)=X60AD78EC
4,0
Copy to FPR4
2,=EB 1 E-30
c(FPR2)=X 0 DA24260
0,2
c(FPR0)=X3288D876 Overflowed result
2,4
c(FPR0)=X 4 C6F73D2 Underflowed result

* (2) With the


LFPC
LE
LER
LE
DEBR
DEBR

overflow and underflow mask bits set to 0:


=F 0
All mask bits = 0 (no interrupts)
0,=EB 1 E20
c(FPR0)=X60AD78EC
4,0
Copy to FPR4
2,=EB 1 E-30
c(FPR2)=X 0 DA24260
0,2
c(FPR0)=X 7 F800000 Overflow to +infinity
2,4
c(FPR0)=X00000000 Underflow to zero

Figure 415. Examples of binary floating-point division overflow and underflow

In case (1), the overflow and underflow exceptions cause an interruption, and the result in the
first-operand register has the correct significand and a scaled exponent. In case (2), no interruption
occurs, and the default result is delivered (as indicated in the comment fields of the DEBR
instructions).
Special cases are treated as follows:
A finite number divided by infinity returns a correctly signed zero.
A finite number divided by zero causes a divide-by-zero exception. If the z mask bit is zero,
a properly signed infinity is generated. For example:
LFPC =F 0
LE
2,=EB -3
DEB 2,=EB+0

Mask off all exceptions


Finite dividend to divide by zero
Result = X FF800000 = -infinity

0 0 and cause an invalid-operation exception. If masked off, they deliver the default
QNaN of the appropriate length.
If neither operand is a SNaN, but one or both is a QNaN, then QNaN is the generated result.
An invalid-operation exception results if either operand is a SNaN. If the exception is masked
off, the corresponding QNaN is the delivered result.

Exercises
34.8.1.(3) How can you generate the maximum positive short-precision binary floating-point
number by dividing two finite short binary floating-point values?
34.8.2.(1) Show the short binary floating-point result of each of these division operations:
1. + 1 1
2. 0 +
3. + 1
34.8.3.(1) + What values will result from these operations?
1. + 2.4
2. 2.5
3. + 2.6 2.6
34.8.4.(3) Using binary floating-point divide instructions (no Test Data Class), how can you
distinguish between + 0 and 0?

Chapter IX: Floating-Point Data and Operations

647

34.9. Binary Floating-Point Addition and Subtraction


Table 286 lists the instructions for binary floating-point addition and subtraction. As with the
multiplication and division instructions, extended operands use only RR-type instructions that
require valid floating-point register pairs.
Op
ED0A
ED1A

Mnem
AEB
ADB

Type
RXE
RXE

Instruction
Add (Short)
Add (Long)

Op
B30A
B31A
B34A

Mnem
AEBR
ADBR
AXBR

Type
RRE
RRE
RRE

Instruction
Add (Short)
Add (Long)
Add (Extended)

ED0B
ED1B

SEB
SDB

RXE
RXE

Subtract (Short)
Subtract (Long)

B30B SEBR
B31B SDBR
B34B SXBR

RRE
RRE
RRE

Subtract (Short)
Subtract (Long)
Subtract (Extended)

Table 286. Binary floating-point Add and Subtract instructions

The machine instruction statement format for these instructions is written


mnemonic R1,R2
The second operand is added to or subtracted from the first operand, and the resulting sum or
difference replaces the first operand.
Table 287 shows the Condition Code settings:
CC
0
1
2
3

Meaning
Result is zero
Result is < zero
Result is > zero
Result is a NaN

Table 287. CC settings after BFP add/subtract instructions

For example:
LE
AEB

2,=EB 2 . 5 5
2,=EB -2.77

CC=1, result < 0

These considerations apply to the instructions:


1. The current rounding mode in the Floating-Point Control Register is used.
2. Denormalized operands are valid, and the result may be denormalized.
3. If both operands are QNaNs, the result is the first operand; and if both operands are SNaNs
and the invalid-operation exception is masked off, the result is the QNaN derived from the
first operand.
4. There are no instructions for adding or subtracting operands of different lengths. If you need
to use mixed-length operands, you must use one of the rounding instructions (to make an
operand shorter) or lengthening instructions (to make an operand longer) described in Section
34.11 on page 651.
Figure 416 shows examples of binary floating-point addition and subtraction:
LD
ADBR
LD
SDBR

0,=DB 1 . 1 E4
0,0
2,=DB 1 . 9 E4
2,0

c(FPR0)=X40C57C0000000000
c(FPR0)=X40D57C0000000000 , CC=2
c(FPR2)=X40D28E0000000000
c(FPR2)=X C0A7700000000000 , CC=1

Figure 416. Examples of binary floating-point addition and subtraction

648

Assembler Language Programming for IBM z System Servers

Version 1.00

Because the ADBR instruction in Figure 416 doubles the number in FPR0, its significand is
unchanged and its exponent is increased by 1.

Exercises
34.9.1.(1) + In each binary floating-point representation, show the hexadecimal value of
(DMin) + (DMin). Assume that all exceptions are masked off.
34.9.2.(2) + In each binary floating-point representation, show the hexadecimal value of
(Min) + (Min). Do not assume that all exceptions are masked off.
34.9.3.(1) + What is the result of (a) (+ ) ( ), (b) (+ ) (+ )?

34.10. Binary Floating-Point Comparison


Table 288 lists the normal BFP compare instructions (the special instructions are in Section
34.10.1):
Op
ED09
ED19

Mnem
CEB
CDB

Type
RXE
RXE

Instruction
Compare (Short)
Compare (Long)

Op
B309
B319
B349

Mnem
CEBR
CDBR
CXBR

Type
RRE
RRE
RRE

Instruction
Compare (Short)
Compare (Long)
Compare (Extended)

Table 288. Binary floating-point Compare instructions

For instructions dealing with extended-precision operands, the operands must be loaded into the
floating-point registers.
None of the comparison instructions compare mixed-length operands, but the lengthening
instructions described in Section 34.11.2 on page 651 can be used to extend a shorter operand to
the length of the longer before comparing.
The Condition Code settings for the compare instructions are shown in Table 288:
CC
0
1
2
3

Meaning
Operand1 = Operand2
Operand1 < Operand2
Operand1 > Operand2
Operands are unordered

Table 289. CC settings for BFP comparisons

All values other than NaNs can be compared:

+ infinity is greater than all values, other than + infinity (to which it compares equal).

infinity is less than all values, other than infinity (to which it compares equal).

+ 0 and 0 compare equal. (They are the only two distinct binary floating-point bit patterns
for numeric values that compare equal.)

When one or both operands is a QNaN, the comparison is unordered and the CC is set to 3. If
either operand is a SNaN, an invalid-operation exception either causes an interruption (if the corresponding mask bit is 1), or sets the CC to 3 (if the mask bit is 0).
Figure 417 shows examples of binary floating-point comparisons.

Chapter IX: Floating-Point Data and Operations

649

LE
CEB
CEB
CEB
CEB

0,=EB+0
0,=EB -(Inf)
0,=EB -0
0,=EB ( QNaN)
0,=EB + ( Inf)

CDBR 6,11
CDB 4,=DB5.75E4
CXBR 0,4

c(FPR0) = +0
CC=2 (0 > -infinity)
CC=0 (+0 = -0)
CC=3 (unordered)
CC=1 (0 < +infinity)
c(FPR6) : c(FPR11) (long operands)
c(FPR6) : 5.75E4 (long operands)
c(FPR0,FPR2) : c(FPR4,FPR6) (ext.)

Figure 417. Examples of binary floating-point comparison

Remember that Condition Code 3 does not occur for hexadecimal floating-point comparisons.

34.10.1. Compare and Signal (*)


Specialized uses
These instructions are used mainly for testing binary floating-point applications.
The binary floating-point compare and signal instructions in Table 290 behave just like the
normal binary floating-point comparisons in Table 288, except that any NaN causes an invalidoperation exception. Thus, these compare and signal instructions are very useful in helping to
prevent propagation of invalid results throughout a calculation.
Op
ED08

Mnem
KEB

Type
RXE

ED18

KDB

RXE

Instruction
Compare and Signal
(Short)
Compare and Signal
(Long)

Op
B308

Mnem
KEBR

Type
RRE

B318

KDBR

RRE

B348

KXBR

RRE

Instruction
Compare and Signal
(Short)
Compare and Signal
(Long)
Compare and Signal
(Extended)

Table 290. Binary floating-point Compare and Signal instructions

The CC settings for these instructions are the same as in Table 289. As with the normal comparisons, masking off the invalid-operation interruption will set CC=3.
Figure 418 shows examples of binary floating-point compare and signal instructions.
LE
KEB
KEB
KEB

0,=EB+0
0,=EB -(Inf)
0,=EB -0
0,=EB ( QNaN)

c(FPR0) = +0
CC=2 (0 > -infinity)
CC=0 (+0 = -0)
Invalid Operation; CC=3 if masked off

Figure 418. Examples of binary floating-point compare and signal instructions

Exercises
34.10.1.(2) + Given operands A= + 1 , B = 0 , C = + , D = (Min), and E= , show the
Condition Code setting resulting from comparing each to the other four.
34.10.2.(2) Will the results you found in Exercise 34.10.1 be different if you use compare and
signal instructions instead?
34.10.3.(4) A programmer claimed that two numeric short or long precision binary floatingpoint numbers X and Y satisfy the relation X < Y when compared as binary floating-point
numbers and when they are compared as signed twos complement binary integers. Is this true
or not?

650

Assembler Language Programming for IBM z System Servers

Version 1.00

34.11. Binary Floating-Point Rounding and Lengthening Instructions (*)


These two groups of instructions convert longer to shorter formats (with rounding) and shorter to
longer formats.

34.11.1. Rounding Instructions (*)


The three Load Rounded instructions in Table 291 round a longer operand to a shorter form
using the default Binary Rounding Mode in the FPCR. None of the instructions change the
Condition Code.
Op
B344

Mnem
LEDBR

Type
RRE

Instruction
Load Rounded
(ShortLong)

B345

LDXBR

RRE

Load Rounded
(LongExtended)

Op
B346

Mnem
LEXBR

Type
RRE

Instruction
Load Rounded
(ShortExtended)

Table 291. Binary floating-point Round instructions

Because each longer operand format has a wider exponent range than the range of the target
operand, exponent overflow or underflow can be generated. (They are handled as described in
Section 34.4.3 on page 638.) Figure 419 shows some examples:

LD
0,=LB1.23456789012345678901234567890123
LD
2,=LB1.23456789012345678901234567890123+8
c(FPR0,FPR2)=X 3 FFF3C0CA428C59F B71A7BE16B6B6D43
LEXBR 4,0
Extended to short: c(FPR4)=X 3 F9E0652
LDXBR 4,0
Extended to long: c(FPR4)=X 3 FF3C0CA428C59FB
LEDBR 4,0
Long to Short(??) c(FPR4)=X 3 FF9E065

Figure 419. Examples of binary floating-point rounding instructions

The last example (using LEDBR) is invalid, because the second operand is the high-order half of
an extended-precision value, while the LEDBR instruction expects a long precision second
operand! Unlike hexadecimal floating-point operands, binary floating-point exponent field widths
are different for each format, so you must be careful to ensure your instructions deal with the
correct operand lengths.
The treatment of NaNs is interesting:
The low-order bits of QNaNs are discarded. (The exponent field is adjusted to the proper
length for the shorter format.)
SNaNs cause an invalid-operation exception. If masked off, the result is the same as for
QNaNs.

34.11.2. Lengthening Instructions (*)


The instructions in Table 292 extend a shorter operand to a longer format, by adjusting the exponent and appending zeros to the low-order bits of the significand. The Condition Code is
unchanged.
Op
ED04

Mnem
LDEB

Type
RXE

ED06

LXEB

RXE

ED05

LXDB

RXE

Instruction
Load Lengthened
(LongShort)
Load Lengthened
(ExtendedShort)
Load Lengthened
(ExtendedLong)

Op
B304

Mnem
LDEBR

Type
RRE

B306

LXEBR

RRE

B305

LXDBR

RRE

Instruction
Load Lengthened
(LongShort)
Load Lengthened
(ExtendedShort)
Load Lengthened
(ExtendedLong)

Chapter IX: Floating-Point Data and Operations

651

Table 292. Binary floating-point Lengthening instructions

These instructions are simpler than the Load Rounded instructions, because numeric values in a
shorter format can always be represented correctly in a longer format. For example:
LE
0,=EB 0 . 1
c(FPR0)=X 3 DCCCCCD
LDEBR 2,0
c(FPR2)=X 3 FB99999A0000000
LXDBR 4,2
c(FPR4,FPR6)=X 3 FFB99999A000000 0000000000000000
Figure 420. Examples of BFP load lengthened instructions

Figure 420 shows that lengthening an operand doesnt increase its accuracy, even though the
longer value has greater precision.214
QNaNs are simply extended with zeros; SNaNs cause an invalid-operation exception, and place
the corresponding QNaN in the first-operand register. Figure 421 shows some examples:
LE
0,=EB ( QNaN)
LDEBR 2,0

c(FPR0)=X 7 FE00000 (Short QNaN)


c(FPR2)=X 7 FFC000000000000 (Long QNaN)

LE
0,=EB ( SNaN)
LDEBR 2,0

c(FPR0)=X 7 FA00000 (Short SNaN)


c(FPR2)=X 7 FFC000000000000 (Long QNaN)

Figure 421. Examples of BFP load lengthened instructions with NaNs

Exercises
34.11.1.(1) Can the Load Rounded instructions be considered shortening or truncating
instructions? Why or why not?
34.11.2.(2) + Suppose you round a long binary floating-point operand X to short format, and
then extend it to long format again. Estimate the difference between the original and final
lengthened values.
34.11.3.(4) + Suppose you execute these instructions for each of the short precision binary
floating-point operands listed below:
LZDR 0
LE
0,data_item
1.
2.
3.
4.
5.
6.

Set FPR0 to zero


Load a short data item

=EB 1 . 0
=EB ( Min)
=EB ( Dmin)
=EB ( QNaN)
=EB ( SNaN)
=EB ( Inf)

In each case, if you then treat the number in FPR0 as a long binary floating-point value, what
will that long value be? What can you infer from the results?

214

652

If you set a value like to 9.876543210987654321..., the number may have great precision but no accuracy.
Assembler Language Programming for IBM z System Servers

Version 1.00

34.12. Converting Between BFP and Binary Integers (*)


z System instructions let you convert binary integers in the general registers to binary floatingpoint format, and vice versa. Well start with the integer-to-float instructions.

34.12.1. Converting Binary Integers to Binary Floating-Point (*)


The instructions in Table 293 convert the binary integer in the second-operand general register to
one of the three binary floating-point formats in the first-operand floating-point register, using the
current rounding mode in the FPCR if needed. None of them affect the Condition Code.
Op
B394

Mnem
CEFBR

Type
RRE

B395

CDFBR

RRE

B396

CXFBR

RRE

Instruction
Convert from Fixed
(Short32)
Convert from Fixed
(Long32)
Convert from Fixed
(Extended32)

Op
Mnem
B3A4 CEGBR

Type
RRE

B3A5 C D G B R

RRE

B3A6 CXGBR

RRE

Instruction
Convert from Fixed
(Short64)
Convert from Fixed
(Long64)
Convert from Fixed
(Extended64)

Table 293. Binary integer to binary floating-point conversion instructions

Some examples are shown in Figure 422.


L
SRNM
CEFBR
SRNM
CEFBR

c(GR0)= X 7 FFFFFFF
Set rounding mode to
c(FPR4)=X 4 EFFFFFF ,
Set rounding mode to
c(FPR0)=X 4 F000000 ,

0,=F2147483647
1(0)
4,0
0(0)
4,0

LG
1,=FD -99
CDGBR 6,1

truncate
truncated
to nearest
rounded

c(GG1)= X FFFFFFFFFFFFFF9D
c(FPR6)=X C058C00000000000

Figure 422. Examples of binary integer to binary floating-point instructions

Because the value in register GG1 is small enough, the result in FPR6 needed no rounding.

34.12.2. Converting Binary Floating-Point to Binary Integers (*)


These instructions convert binary floating-point operands in a floating-point register to a twos
complement fixed-point binary value in a general register:
Op
B398

Mnem
CFEBR

Type
RRF

B399

CFDBR

RRF

B39A

CFXBR

RRF

Instruction
Convert to Fixed
(32Short)
Convert to Fixed
(32Long)
Convert to Fixed
(32Extended)

Op
Mnem
B3A8 CGEBR

Type
RRF

B3A9 C G D B R

RRF

B3AA CGXBR

RRF

Instruction
Convert to Fixed
(64Short)
Convert to Fixed
(64Long)
Convert to Fixed
(64Extended)

Table 294. Binary floating-point to integer conversion instructions

The six instructions in Table 294 have an additional mask operand specifying a local rounding
mode that takes effect only for that single instruction. Their format is illustrated in Table 295:
Opcode

M3

R1

R2

Table 295. Format of BFP Convert To Fixed instructions

Even though the local rounding mode mask is called M3, it appears in the machine instruction
statements operand field as the second operand:
Chapter IX: Floating-Point Data and Operations

653

Mnemonic R1,M3,R2
As noted in Section 34.3 on page 633, the meanings of the local rounding mode field M3 are:
M3
B0000
B0001
B0100
B0101
B0110
B0111

Meaning
Round according to the current global rounding mode in the FPCR
Biased round to nearest (ties round away from zero; the same as adding 1 to the
first lost bit)
Unbiased round to nearest
Round toward zero (truncate)
Round toward +
Round toward

Table 296. Rounding modifier for BFP convert to fixed instructions

Local rounding mode 1 is the traditional round up action.


The effect of the rounding modifiers on fraction-to-integer conversion is illustrated in Figure 423.
Up:
Down:
To Zero:
To Nearest:
To Nearest:
Biased Round:

+
+
+

3.5
3.5
3.5
3.4
3.5
3.5

+
+
+

4,
3,
3,
3,
4,
4,

3.5
3.5
3.5
2.6
2.5
2.5

3
4
3
3
2 (ties to even)
3 (away from zero)

Figure 423. Examples of converting binary floating-point fractions to integers with rounding

To obtain these results we can use the instructions in Figure 424:


LE
CFEBR
CFEBR
CFEBR
CFEBR
CFEBR
LE
CFEBR

8,=EB 3 . 5
11,B0110,8
12,B0111,8
13,B0101,8
14,B0100,8
15,B0001,8
6,=EB 2 . 5
10,B0100,6

c(FPR8)=X40600000
c(GR11)=X00000004
c(GR12)=X00000003
c(GR13)=X00000003
c(GR14)=X00000004
c(GR15)=X00000004
c(FPR6)=X40200000
c(GR10)=X00000002

(Round up)
(Round down)
(Round toward 0)
(To nearest even)
(Biased round)
(To nearest even)

Figure 424. Examples of Convert to Fixed instructions

The Condition Code is set as shown in Table 297:


CC
0
1
2
3

Meaning
Source was zero
Source was less than zero
Source was greater than zero
Special case

Table 297. CC settings after convert to binary instructions

These are the special cases resulting in CC=3:


The size of the binary floating-point value lies outside the representable range of a 32- or
64-bit integer; an invalid operation exception is signaled.

654

If the mask bit is zero, CC3 is set, and the maximum correctly signed integer is placed in
the target R 1 general register.

If the mask bit is one, a program interruption occurs.

Assembler Language Programming for IBM z System Servers

Version 1.00

If the source operand is a NaN and the invalid-operation mask bit is 1, a program interruption
occurs; otherwise, the target R1 general register is set to the maximum negative number.
An inexact exception may also occur, but these interruptions are typically masked off.
These instructions make it very easy to choose the rounding you want to use for converting
binary floating-point values to binary integers.

Exercises
34.12.1.(2) An array of fullword integers is stored starting at IntData and the number of elements in the list is stored as a fullword integer at NItems. Write an instruction sequence to
compute and store at IntAvg the binary floating-point average of the list of integers. Take into
account the possibility that the integer sum may overflow a general register.
34.12.2.(1) + Can the instructions for converting a binary integer to binary floating-point generate an exponent underflow or overflow?
34.12.3.(2) + What integer values satisfying
230 value < 231
can be converted without loss of precision to short binary floating-point form?

34.13. Binary Floating-Point Integers and Remainders (*)


z System provides two groups of instructions for deriving integer values of binary floating-point
numbers, and for calculating remainders.
As with other binary floating-point instructions, a QNaN operand leads to a QNaN result, and a
SNaN operand causes an invalid operation exception. If masked off, the result is the corresponding QNaN.

34.13.1. Load FP Integer Instructions


The three Load FP Integer instructions in Table 298 round a second-operand binary floatingpoint operand to a first-operand integer value in the same format.
Op
B357
B347

Mnem
FIEBR
FIXBR

Type
RRF
RRF

Instruction
Load FP Integer (Short)
Load FP Integer
(Extended)

Op
Mnem
B35F F I D B R

Type
RRF

Instruction
Load FP Integer (Long)

Table 298. Load floating-point integer instructions

The three instructions have the format shown in Table 295. The format of the machine instruction statement is
mnemonic R1,M3,R2
where M 3 is a rounding modifier with values shown in Table 299:

Chapter IX: Floating-Point Data and Operations

655

M3
B0000
B0001
B0100
B0101
B0110
B0111

Meaning
Round according to the current BFP rounding mode
Round to nearest with ties away from 0
Round to nearest with ties to even
Round toward 0
Round toward +
Round toward

Table 299. Rounding mode modifiers for BFP load integer instructions

If we execute the instructions in Figure 425, the results in FPR2 are as shown:
LE
FIEBR
FIEBR
FIEBR
FIEBR

0,=EB5.6789012
2,B0100,0
2,B0001,0
2,B0101,0
2,B0111,0

c(FPR0)=X40B5B98F
c(FPR2)=X40C00000
c(FPR2)=X40C00000
c(FPR2)=X40A00000
c(FPR2)=X40A00000

( Round
( Round
( Round
( Round

to nearest)
away from 0)
toward 0)
down)

Figure 425. Examples of load F P integer instructions

The second and third results have value + 6, and the third and fourth results have value + 5.
Because the initial operand in FPR0 is not already an integer, there will be an exception condition
for an inexact result; if not masked off, and an interruption will occur.
Remember
These instructions produce a binary floating-point integer-valued result in
a floating-point register, not a binary integer in a general register.

34.13.2. Divide to Integer Instructions (*)


Table 300 lists the two instructions215 used to calculate binary floating-point remainders:
Op
B353

Mnem
DIEBR

Type
RRF

Instruction
Divide to Integer (Short)

Op
Mnem
B35B DIDBR

Type
RRF

Instruction
Divide to Integer (Long)

Table 300. Binary floating-point Divide to Integer instructions

The format of these two instructions is shown in Table 301:


Opcode

R3

M4

R1

R2

Table 301. Format of BFP Divide to Integer instructions

The format of the machine instruction statement is


mnemonic R1,R3,R2,M4
where all the register operands must be different, and M4 is a rounding modifier with the same
values shown in Table 299 above. Note that only the final quotient is rounded.
The first operand is divided by the second operand, and the integer quotient replaces the third
operand; the remainder replaces the dividend in the first operand.
If you divide x by y, a floating-point remainder is defined by the relation
r = x (yn)

215

656

These instructions are complex; before using them you should study their description in the z/Architecture Principles
of Operation.
Assembler Language Programming for IBM z System Servers

Version 1.00

where n is the integer nearest the exact value of x/y.


For example, suppose we want the remainder of 6.5/2.0. The quotient is 3 and the remainder is
0.5. However, if we want the remainder of 7.5/2.0, the true quotient n is again 3 and the true
remainder is 1.5. Depending on the rounding mode chosen for the final quotient, the remainder
could be -0.5! This shows why:
6.5/2.0 with rounding toward zero:
7.5/2.0 with rounding toward zero:

qexact=3.25, so q=3.0, r=+0.5


qexact=3.75, so q=3.0, r=+1.5

6.5/2.0 with rounding toward nearest: qexact=3.25, so q=3.0, r=+0.5


7.5/2.0 with rounding toward nearest: qexact=3.75, so q=4.0, r=-1.5
The instructions in Figure 426 show this behavior (where the rounding mode is to nearest):
LE
0,=EB 6 . 5
LE
2,=EB 2 . 0
DIEBR 0,4,2,B0100

c(FPR0)=X40D00000
c(FPR0)=X40000000
c(FPR0)=X 3 F000000 (Remainder=+0.5)
c(FPR4)=X40400000 (Quotient =+3.0)

LE
0,=EB 7 . 5
DIEBR 0,4,2,B0100

c(FPR0)=X40F00000
c(FPR0)=X BF000000 ( Remainder=-0.5)
c(FPR4)=X40800000 (Quotient =+4.0)

Figure 426. Examples of divide to integer instructions

Sometimes the calculation of a remainder is lengthy, so the CPU sets the CC to indicate that the
operation is incomplete, as we saw for instructions like MVCLE and CLCLE in Section 25. The
CC settings are shown in Table 302:
CC
0
1
2
3

Meaning
Remainder
Remainder
Remainder
Remainder

complete, normal quotient


complete, quotient overflow or NaN
incomplete, normal quotient
incomplete, quotient overflow or NaN

Table 302. CC settings after divide to integer instructions

These CC settings are somewhat unusual. Rather than indicating an exception condition for quotient overflow, CC values 1 and 3 indicate that the exponent of the quotient has been scaled. CC
values 2 or 3 mean you should repeat the instruction until the remainder is complete.
If a quotient overflow occurs or if an operand is a SNaN, an invalid operation exception is indicated. If masked off, the result is a QNaN.
To illustrate, suppose we execute the instructions in Figure 427:

Div
*

LE
8,=EB 1 E28
LE
3,=EB . 7 3 E-9
DIEBR 8,0,3,B0100
BC

3,Div

Dividend is large, X 6 E013F39


Divisor is small, X3048A92F
Partial quotient in FPR0,
partial remainder in FPR8
Iterate if not complete

Figure 427. Example of iterative divide to integer

A final result requires five iterations. The CC setting, the values in FPR8 and FPR0, and the
partial remainders (PR) and partial quotients (PQ) are developed in these steps:

Chapter IX: Floating-Point Data and Operations

657

Execution
Execution
Execution
Execution
Execution

CC
2
2
2
2
0

1
2
3
4
5

FPR8
X60985BC8
X54A2FBB9
X48A5FFF8
X399F6040
X AFB07DDA

FPR0
X 7 D24E429
X 6 FC26069
X63CFEE78
X57D3C7B1
X48CB5460

PR=8.78E19
PR=5.60E12
PR=3.40E5
PR=3.04E-4
PR=-3.21E-10

PQ=1.37E37
PQ=1.20E29
PQ=7.67E21
PQ=4.66E14
PQ=4.16E5

Figure 428. Iterative execution of a divide to integer instruction

Calculating the quotient manually gives a value 1.3698E37, as we see in the partial quotient of the
first iteration.

Exercises
34.13.1.(2) + Show the result in FPR2 of executing
LE
0,=EB 3 . 5
FIEBR 2,mask,0
for mask values 1, 4, 5, 6, and 7.
34.13.2.(3) + What result will appear in FPR2 after executing
LD
0,=DB 9 . 5
FIEBR 2,4,0
Be careful!
34.13.3.(4) Show that the rule requiring the generation of an even quotient in the case when
|n-x/y |=1/2 and the rounding mode is to nearest even leads to a remainder satisfying
|r| y/2.

34.14. Binary Floating-Point Square Root Instructions (*)


Four of the square root instructions in Table 303 have both RX- and RR-type forms; SQXBR
has only RR format.
Op
ED14
ED15

Mnem
SQEB
SQDB

Type
RXE
RXE

Instruction
Square Root (Short)
Square Root (Long)

Op
B314
B315
B316

Mnem
SQEBR
SQDBR
SQXBR

Type
RRE
RRE
RRE

Instruction
Square Root (Short)
Square Root (Long)
Square Root (Extended)

Table 303. Binary floating-point Square Root instructions

The square root of the binary floating-point second operand is evaluated, rounded according to
the current BFP rounding mode, and placed in the R 1 floating-point register. Negative nonzero
values and SNaNs cause an invalid-operation exception; if masked off, the result is a QNaN. The
square root of + is + .216
Figure 429 shows some examples of the binary floating-point square root instructions.

216

658

Seems reasonable.
Assembler Language Programming for IBM z System Servers

Version 1.00

SQEB
SQDB
LD
LD
SQXBR

0,=EB 1 0
2,=DB9999
4,=LB 0 . 1
6,=LB0.1+8
4,4

*
SQEB 0,=EB ( QNaN)
SQEB 2,=EB ( Inf)

c(FPR0)=X404A62C2
c(FPR2)=X4058FFAE13F4A7D3
c(FPR4)=X 3 FFB999999999999
c(FPR6)=X999999999999999A
c(FPR4)=X 3 FFD43D136248490 ,
c(FPR6)=X EDB36E896CF3D7B0
c(FPR0)=X 7 FE00000 (QNaN)
c(FPR2)=X 7 F800000 (+infinity)

Figure 429. Examples of binary floating-point square root instructions

Exercises
34.14.1.(1) + Estimate the value of the square root of BFP (Max), (Min), and (DMin) values.
34.14.2.(2) + What result will appear in FPR0 if you execute this instruction?
SQEB 0,=DB 1 6
Be careful!

34.15. Binary Floating-Point Multiply and Add/Subtract (*)


Table 304 lists the binary floating-point multiply and add and multiply and subtract
instructions. The Condition Code is unchanged.
Op
ED0E

Mnem
MAEB

Type
RXF

Instruction
Multiply and Add (Short)

Op
Mnem
B30E MAEBR

Type
RRF

ED1E

MADB

RXF

Multiply and Add (Long)

B31E M A D B R

RRF

ED0F

MSEB

RXF

B30F MSEBR

RRF

ED1F

MSDB

RXF

Multiply and Subtract


(Short)
Multiply and Subtract
(Long)

B31F MSDBR

RRF

Instruction
Multiply and
(Short)
Multiply and
(Long)
Multiply and
(Short)
Multiply and
(Long)

Add
Add
Subtract
Subtract

Table 304. Binary floating-point Multiply and Add/Subtract instructions

The Assembler instruction statement format for these instructions is


R1,R3,R2
R1,R3,D2(X2,B2)

For RRF-format
For RXF-format

These instructions provide a more precise result for a very common mathematical operation:
operand1 = (operand3 operand2) operand1
The product is formed internally to double length without rounding, and then operand1 is added
or subtracted. This result is then rounded to the target operand length according to the current
BFP rounding mode. This means that
the product is more precise than would be delivered by a single multiplication operation, and
the first operand is added to an unrounded product, with possibly more bits participating.
To illustrate the difference between using multiply and add compared to using a multiply and
then an add instruction, consider the instructions shown in Figure 430:

Chapter IX: Floating-Point Data and Operations

659

LE
2,Operand2
LE
6,Operand1
MAEBR 6,2,2

c(FPR2)=Operand2 (and Operand3)


c(FPR6)=Operand1
c(FPR0)=Operand1+(Operand2**2)

LE
2,Operand2
MEEBR 2,2
AEB 2,Operand1

c(FPR2)=Operand2 (and Operand3)


c(FPR2)=Operand2**2
c(FPR2)=Operand1+(Operand2**2)

Figure 430. Example of binary floating-point multiply and add instructions

In many cases, the results will differ by very little, perhaps by a single bit. But if these operations
are part of a long loop involving sums of many products, the accumulated differences can be significant.
If the operands are close to overflow or underflow threshholds, the results can be quite different.
For example:
LE
0,=EB1.85E19
MEEBR 0,0
AEB 0,=EB -(Max)

c(FPR0) = X 5 F805E9A
c(FPR0) = X 1 F80BD7A ( overflow)
c(FPR0) = X FF7FFFFF -(Max)

LE
0,=EB1.85E19
LE
2,=EB -(Max)
MAEBR 2,0,0

c(FPR0) = X 5 F805E9A
c(FPR2) = X FF7FFFFF
c(FPR2) = X 7 BBD7A6B

The first three instructions multiply an operand slightly larger than the square root of (Max), generating an overflowed result with characteristic wrap. Subtracting (Max) overwhelms the wrapped
result, leaving (Max) as the result. The second three instructions add (Max) to the intermediate result, generating a finite (and correct) result.
If any operand is a QNaN, the result is a QNaN taken from the original operands in order of
precedence operand3, operand2, operand1. Any SNaN causes an invalid operation exception; if it
is masked off, a default QNaN is delivered as the result.

Exercises
34.15.1.(2) + Rewrite the example in Figure 381 on page 595 to use binary floating-point data
and multiply-add instructions.
34.15.2.(2) Rewrite the example in Figure 382 on page 595 to use binary floating-point data
and multiply-add instructions.

34.16. Summary
The binary floating-point instructions for several operation types are summarized in Table 305.
All of these operations use operands of uniform lengths.
Table 305 (Page 1 of 2). Summary of binary floating-point instructions with
uniform operand lengths

Function
Add/Subtract
(register)
Add/Subtract
(storage)
Compare (register)
Compare (storage)

660

4 bytes
AEBR
SEBR
AEB
SEB
CEBR
CEB

Assembler Language Programming for IBM z System Servers

Operand Length
8 bytes
16 bytes
ADBR
AXBR
SDBR
SXBR
ADB
SDB
CDBR
CXBR
CDB

Version 1.00

Table 305 (Page 2 of 2). Summary of binary floating-point instructions with


uniform operand lengths

Function

4 bytes
DEBR
DEB
DIEBR
KEBR

Divide (register)
Divide (storage)
Divide to Integer
Compare and Signal
(register)
Compare and Signal
(storage)
Load Positive (register)
Load Negative (register)
Load Complement (register)
Load and Test (register)
Load FP Integer
Multiply and Add/Subtract
(register)
Multiply and Add/Subtract
(storage)
Square Root (register)
Square Root (storage)
Test Data Class (register)

Operand Length
8 bytes
16 bytes
DDBR
DXBR
DDB
DIDBR
KDBR
KXBR

KEB

KDB

LPEBR
LNEBR
LCEBR
LTEBR
FIEBR
MAEBR
MSEBR
MAEB
MSEB
SQEBR
SQEB
TCEB

LPDBR
LNDBR
LCDBR
LTDBR
FIDBR
MADBR
MSDBR
MADB
MSDB
SQDBR
SQDB
TCDB

LPXBR
LNXBR
LCXBR
LTXBR
FIXBR

SQXBR
TCXB

Tables 306 through 310 summarize instructions whose operands may have mixed lengths.
The binary floating-point multiplication instructions are summarized in Table 306.
Source Length
Product Length
Multiply (registers)
Multiply (storage)

Function

4 bytes
4 bytes
8 bytes
MEEBR
MDEBR
MEEB
MDEB

8 bytes
8 bytes
16 bytes
MDBR
MXDBR
MDB
MXDB

16 bytes
16 bytes
MXBR

Table 306. Binary floating-point Multiply instructions

The binary floating-point rounding instructions are summarized in Table 307.


Function

Source Length
Result Length
Round

8 bytes
4 bytes
LEDBR

16 bytes
4 bytes
LEXBR

16 bytes
8 bytes
LDXBR

Table 307. Binary floating-point Round instructions

The binary floating-point operand-lengthening instructions are summarized in Table 308.


Source Length
Result Length
Lengthen (register)
Lengthen (storage)

Function

4 bytes
8 bytes
16 bytes
LDEBR
LXEBR
LDEB
LXEB

8 bytes
16 bytes
LXDBR
LXDB

Table 308. Binary floating-point Lengthening instructions

The instructions for converting binary floating-point operands to binary integers are summarized
in Table 309.
Chapter IX: Floating-Point Data and Operations

661

Source Length
Target Length
Convert float to binary

Function

4 bytes
32 bits
64 bits
CFEBR
CGEBR

8 bytes
32 bits
64 bits
CFDBR
CGDBR

16 bytes
32 bits
64 bits
CFXBR
CGXBR

Table 309. Convert binary floating-point to binary integer instructions

The instructions for converting binary integer operands to binary floating-point are summarized in
Table 310.
Function

Source Length
Target Length

Convert binary to float

32 bits
4 bytes

8 bytes

CEFBR

CDFBR

64 bits
16
bytes
CXFBR

4 bytes

8 bytes

CEGBR

CDGBR

16
bytes
CXGBR

Table 310. Convert binary integer to binary floating-point instructions

Table 311 summarizes the binary floating-point exception conditions that might be caused by the
instructions described in this section. F denotes a finite value, and IMax is the largest representable binary integer in the target format.
Operation

Invalid Operation

Divide
by Zero

Overflow
Yes

Underflow
Yes

Inexact

Add, Subtract
SNaN,
Yes
Compare,

SNaN
Compare and Signal

Convert to Fixed
NaN, | F | > |IMax |
Yes
Divide
SNaN, 0 0,
F 0
Yes
Yes
Yes

Divide to Integer
SNaN, Any
Yes
Yes

Load and Test


SNaN

Load FP Integer
SNaN
Yes

Load Lengthened
SNaN

Load Rounded
SNaN
Yes
Yes
Yes

Multiply
SNaN, 0
Yes
Yes
Yes
Multiply & Add,

SNaN, , 0
Yes
Yes
Yes
Multiply & Subtract

Square Root
SNaN, , F < 0
Yes
Note: F is any finite value; IMax is the largest available signed integer in the target format.

Table 311. Summary of binary floating-point operations and exceptions

Instructions Discussed in this Section


The instruction mnemonics and opcodes are shown in the following table:

662

Assembler Language Programming for IBM z System Servers

Version 1.00

Mnemonic
ADB

Opcode
ED1A

Mnemonic
FIXBR

Opcode
B347

Mnemonic
MAEBR

Opcode
B30E

ADBR

B31A

KDB

ED18

MDB

ED1C

AEB

ED0A

KDBR

B318

MDBR

B31C

AEBR

B30A

KEB

ED08

MDEB

ED0C

AXBR

B34A

KEBR

B308

MDEBR

B30C

CDB

ED19

KXBR

B348

MEEB

ED17

CDBR

B319

LCDBR

B313

MEEBR

B317

CDFBR

B395

LCEBR

B303

MSDB

ED1F

CDGBR

B3A5

LCXBR

B343

MSDBR

B31F

CEB

ED09

LDEB

ED04

MSEB

ED0F

CEBR

B309

LDEBR

B304

MSEBR

B30F

CEFBR

B394

LDXBR

B345

MXBR

B34C

CEGBR

B3A4

LEDBR

B344

MXDB

ED07

CFDBR

B399

LEXBR

B346

MXDBR

B307

CFEBR

B398

LFAS

B2BD

SDB

ED1B

CFXBR

B39A

LFPC

B29D

SDBR

B31B

CGDBR

B3A9

LNDBR

B311

SEB

ED0B

CGEBR

B3A8

LNEBR

B301

SEBR

B30B

CGXBR

B3AA

LNXBR

B341

SFASR

B385

CXBR

B349

LPDBR

B310

SFPC

B384

CXFBR

B396

LPEBR

B300

SQDB

ED15

CXGBR

B3A6

LPXBR

B340

SQDBR

B315

DDB

ED1D

LTDBR

B312

SQEB

ED14

DDBR

B31D

LTEBR

B302

SQEBR

B314

DEB

ED0D

LTXBR

B342

SQXBR

B316

DEBR

B30D

LXDB

ED05

SRNM

B299

DIDBR

B35B

LXEB

ED06

STFPC

B29C

DIEBR

B353

LXEBR

B306

SXBR

B34B

DXBR

B34D

LXDBR

B305

TCDB

ED11

EFPC

B38C

MADB

ED1E

TCEB

ED10

FIDBR

B35F

MADBR

B31E

TCXB

ED12

FIEBR

B357

MAEB

ED0E

The instruction opcodes and mnemonics are shown in the following table:

Chapter IX: Floating-Point Data and Operations

663

Opcode
B299

Mnemonic
SRNM

Opcode
B31C

Mnemonic
MDBR

Opcode
B3A5

Mnemonic
CDGBR

B29C

STFPC

B31D

DDBR

B3A6

CXGBR

B29D

LFPC

B31E

MADBR

B3A8

CGEBR

B2BD

LFAS

B31F

MSDBR

B3A9

CGDBR

B300

LPEBR

B340

LPXBR

B3AA

CGXBR

B301

LNEBR

B341

LNXBR

ED04

LDEB

B302

LTEBR

B342

LTXBR

ED05

LXDB

B303

LCEBR

B343

LCXBR

ED06

LXEB

B304

LDEBR

B344

LEDBR

ED07

MXDB

B305

LXDBR

B345

LDXBR

ED08

KEB

B306

LXEBR

B346

LEXBR

ED09

CEB

B307

MXDBR

B347

FIXBR

ED0A

AEB

B308

KEBR

B348

KXBR

ED0B

SEB

B309

CEBR

B349

CXBR

ED0C

MDEB

B30A

AEBR

B34A

AXBR

ED0D

DEB

B30B

SEBR

B34B

SXBR

ED0E

MAEB

B30C

MDEBR

B34C

MXBR

ED0F

MSEB

B30D

DEBR

B34D

DXBR

ED10

TCEB

B30E

MAEBR

B353

DIEBR

ED11

TCDB

B30F

MSEBR

B357

FIEBR

ED12

TCXB

B310

LPDBR

B35B

DIDBR

ED14

SQEB

B311

LNDBR

B35F

FIDBR

ED15

SQDB

B312

LTDBR

B384

SFPC

ED17

MEEB

B313

LCDBR

B385

SFASR

ED18

KDB

B314

SQEBR

B38C

EFPC

ED19

CDB

B315

SQDBR

B394

CEFBR

ED1A

ADB

B316

SQXBR

B395

CDFBR

ED1B

SDB

B317

MEEBR

B396

CXFBR

ED1C

MDB

B318

KDBR

B398

CFEBR

ED1D

DDB

B319

CDBR

B399

CFDBR

ED1E

MADB

B31A

ADBR

B39A

CFXBR

ED1F

MSDB

B31B

SDBR

B3A4

CEGBR

Terms and Definitions


Floating-Point Control Register (FPCR)
A special register containing IEEE masks, status indicators, Data Exception Code, and
rounding mode.
mask
A bit in the FPCR controlling the actions to be taken when an exception condition occurs.
status flag
A bit in the FPCR indicating that an exception condition has occurred.

664

Assembler Language Programming for IBM z System Servers

Version 1.00

DXC
Data Exception Code, a field in the FPCR.
Data Exception Code
A field in the FPCR indicating which of various floating-point and packed decimal
exceptions have occurred.
Rounding Mode
A field in the FPCR indicating the rounding action to be taken after a binary floating-point
operation.
denormalized number
A nonzero binary floating-point value with characteristic zero and a nonzero fraction.
gradual underflow
A technique allowing numbers to become denormalized when they are finite and smaller than
the smallest normalized magnitude.
NaN
A Not-a-Number having no numeric or mathematical meaning.
QNaN
A Quiet Not-a-Number that does not cause an exception condition in any arithmetic operation.
SNaN
A Signaling Not-a-Number that does cause an exception condition in an arithmetic operation.
special value
A zero, a denormalized number, an infinity, a QNaN, or an SNaN.
exception condition
One of five conditions defined by the IEEE Floating-Point Standard: invalid operation, division by zero, exponent overflow, exponent underflow, and inexact result.
rounding modifier
A field in an instruction specifying the type of rounding to be performed on the result of the
operation.

Programming Problems
Problem 34.1.(2) Write a program using binary floating-point operands to generate each of the
five exception conditions. First, set the five mask bits to zero, and see what default results are
delivered for each exception type; then, generate the same exceptions with each mask bit set to
one. Determine the ways your operating system reports the interruptions.
Problem 34.2.(4) Write a program that will read records containing eight hex digits representing
short binary floating-point numbers. Then, print the approximate (but reasonably accurate)
decimal value of the binary floating-point number to five significant digits, in the form
s.dddddEsnn, where s is the sign of the number and of its exponent, ddddd are the significant
decimal digits, and nn is the decimal exponent. If the number is a NaN or infinity, print an
appropriate indication. (See Problem 33.3.)
Problem 34.3.(2) Write a program that calculates a table of the square roots of short precision
binary floating-point integer values from 1 to 20. For each square root value, also calculate its
square and compare the result to the original integer value. Then, display the original value, its
square root, and the difference between the integer value and the squared square root. (If you
can display the results as decimal values, perhaps using your solution to Problem 34.2, so much
the better!)
Problem 34.4.(3) A programmer claimed that evaluating (1.0/N)*N in binary floating-point
arithmetic (with (default) rounding to nearest even) for values of N from 1 to 100 does not
always produce 1.0. Write a program that will test this claim in short, long, and extended binary
floating-point arithmetic.

Chapter IX: Floating-Point Data and Operations

665

Problem 34.5.(3) Using the iterative technique described in Section 31.3.1 on page 544, write a
program to evaluate the square root of 2 to 10 significant digits using long binary floating-point
arithmetic, and without using any square-root instructions. Format and print the result as a
fixed-point value.

666

Assembler Language Programming for IBM z System Servers

Version 1.00

35. Decimal Floating-Point Data and Operations

3333333333
333333333333
33
33
33
33
3333
3333
33
33
33
33
333333333333
3333333333

55555555555
555555555555
55
55
555555555
5555555555
555
55
55
555
55555555555
555555555

Having seen in Sections 33 and 34 that z System supports both hexadecimal and binary floatingpoint, you might ask why yet another is needed.
We are ten-fingered creatures: (almost) all humans count in decimal, and non-decimal arithmetic is highly unintuitive for most people.217
When calculations using hexadecimal or binary floating-point are compared with hand calculations in decimal, the results may be different. Decimal notation and arithmetic is pervasive
in business use, and is often a legal requirement.
If your processor is capable of scaled fixed-point decimal arithmetic (like packed decimal), such
computations are difficult because the position of the decimal point must be remembered.

Even when you can do this the resulting code may be complex, difficult to understand and
maintain, and slow.

One of the most annoying aspects of non-decimal arithmetic is that representations of decimal
fractions (e.g., 1/10) are imprecise and must be rounded, which can cause accumulated errors.

Laws in many countries require exact decimal rounding for financial calculations.

Conversions between decimal and hexadecimal or binary are complicated, and can be quite
difficult to do correctly. Imprecise conversions can lead in either binary or packed decimal to
many other problems.
Floating-point remainders are often not what you would expect in bases other than ten.
The decimal precision of a binary or hexadecimal floating-point number is often not what it
seems. The question How many significant digits? almost always implies decimal digits.
The results of floating-point comparisons can be surprising: two values that you think should
be algebraically equal may not be.
Decimal floating-point is now an international standard (IEEE Std 754-2008).
A desired solution should have these properties:
Intuitive, familiar decimal arithmetic
Exact representation of (most) decimal numbers

217

Old joke: There are 10 types of people who understand binary: those who do, and those who dont.
Chapter IX: Floating-Point Data and Operations

667

Problems with repeating non-decimal fractions like 1/3 are well known and understood.

Automatic tracking of the decimal points placement


No conversions between decimal and hex or binary are needed, so there are fewer misconceptions about the decimal precision of a number
Rounding uses decimal rules, not binary or hexadecimal

More rounding modes are supported.

Low-order digits are preserved whenever possible


Integer, fixed point, and floating-point values are supported without extra effort.

Businesses need all three, for things like counts, currency, and interest and tax rates.

As we will see, the z System decimal floating-point data types and instructions have these properties.

Exercises
35.0.1.(0) Many cartoon characters are drawn with only three fingers and a thumb on each
hand. Use that property to devise examples for teaching children octal (base-8) arithmetic.
35.0.2.(1) What other number bases are in widespread use today?

35.1. Representations
The significand in the binary and hexadecimal floating-point representations is a string of
hexadecimal or binary digits, packaged with a sign and an exponent:
 hex digits

s exponent h h h h h h h h h h h h Hex

 bits

s exponent bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb Binary

Figure 431. Hexadecimal and binary floating-point representations

You might reasonably expect something similar for decimal:


 decimal digits

s exponent d d d d d d d d d d d d d d d d d d Decimal

Three possible representations could be considered:


1. Like hexadecimal floating-point, the significand could contain BCD (not EBCDIC!) digits.218
This has some advantages and disadvantages:
No conversion of external decimal data to and from binary or hexadecimal is needed.
Rounding can use similar techniques as for the packed decimal instruction SRP (discussed
in Section 29.7).

218

668

One of the earliest time-sharing systems on System/360 was known as RUSH; its decimal floating-point representation used BCD rather than hexadecimal digits, and its implementation used part of the packed decimal microcode.
Assembler Language Programming for IBM z System Servers

Version 1.00

Because the operations would be done in the floating-point registers rather than in
storage, they could be faster than for packed decimal.
The representation is somewhat wasteful, using only 62.5 percent of the available bit
space (digits A-F are not present). Encoding decimal values with BCD digits is inefficient because each 3 BCD digits require 12 bits, but values from 000 to 999 can be stored
in 10 bits.
2. The significand could be a binary integer, as sketched in this figure:

s exponent
binary integer

This has some advantages and disadvantages:


The representation is compact; no significand bit combinations are disallowed.
Arithmetic should be about as fast as for the binary floating-point instructions.
Data would require conversion from BCD formats.
A serious disadvantage is that decimal rounding, shifting, and scaling are complicated and
possibly expensive.
This format is actually defined by the IEEE standard, but is not supported by z System. (If
youre interested, see Section 35.14 on page 716.)
3. The significand could contain compressed BCD digits.
This has some advantages and disadvantages:
The representation can be made very efficient, having the compactness of binary and the
ease of scaling, shifting, and rounding of decimal.
The encoding is complex and quite unintuitive.
Decimal operations are natural.
The encoding chosen for z System to represent decimal floating-point data is the last one.

35.1.1. Conceptual View of the Decimal Floating-Point Representation


Its easiest to think of decimal floating-point data having the representation shown in Figure 432.
As with hexadecimal and binary floating-point representations, the exponent field contains a characteristic (the exponent plus a bias to ensure that its nonnegative).
 decimal digits

implied
s exponent 0 0 0 0 0 0 0 d d d d d d d d d d d d.  decimal

point



Leftmost Digit (LMD)
 Significant Units Digit
Leftmost Significant Digit
Digits
Figure 432. Conceptual decimal floating-point representation

An important property of decimal floating-point data is that it is not always normalized, either as
a fraction or as an integer. This means that it is easy to generate equal values that dont have the
same representation. For example, 1103 and 100101 have the same value but different representations.
The set of redundant representations with the same value is called a cohort: 219 each such
number is a cohort member.

219

The term cohort actually refers to a division of 300 to 600 troops of a Roman army legion. Its informal meaning
of a group of associates (not an associate of a hort) is intended here.
Chapter IX: Floating-Point Data and Operations

669

To illustrate a decimal floating-point cohort, consider the notation we used in Section 32.9, where
a 4-digit decimal floating-point number is represented as [exponentsignificand]. The decimal
number 100 then has four possible representations: [ 11000], [00100], [ + 10010], and
[ + 20001]; this cohort has 4 members.
None of the values is necessarily normalized, either as a fraction (as in the FPF(10,4) representation) nor as an integer (as in the FPI(10,4) representation), even though the first and last cohort
members appear to be left- and right-normalized.
A new term is introduced in place of the ulp (unit in the last place) we saw in discussing
hexadecimal and binary floating-point: the units-digit value, 1 10exponent , is called the quantum.
Remember!
Finite numbers with the same exponent have the same quantum.
Each of the four representations above has a different quantum, respectively 110 1, 1100,
110 + 1, and 110 + 2. This shows how the quantum of a value depends on which member of a
cohort is chosen.
Comment
The z/Architecture Principles of Operation uses quantum in describing
decimal floating-point data and operations. Its much simpler to think of
a decimal floating-point value as an integer with an exponent (as in
Figure 432).
For example, the three numbers in Figure 433 represent the same value, 12345107, so they are
members of the same cohort. But they have different exponents (and therefore, different quanta).

+
7 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 2 3 4 5

+
6 0 0 0 0 0 0 0 0 0 0 0 0 0 1 2 3 4 5 0

+
3 0 0 0 0 0 0 0 0 0 0 1 2 3 4 5 0 0 0 0

Figure 433. Three decimal floating-point representations of the same value

You may remember from Section 27.4 on page 461 that a packed decimal number can have multiple representations with the same value, and that different values can have the same representation. Different decimal floating-point values always have different representations.
Table 312 summarizes the properties of the z System decimal floating-point representation, where
approximations are given for Max, Min, and DMin values. Because decimal floating-point
numbers arent usually normalized, the column headed Max Norm. refers to values with
nonzero leftmost digit, and the two Min columns refer to values with only 1 in the units digit.
Byte
length
4
8
16

Char.
(bits)
8
10
14

Min
exp.
95
383
6143

Max
exp.
+ 96
+ 384
+ 6144

Char.
Bias
+ 101
+ 398
+ 6176

Precision
7
16
34

Max Norm.
(Max)
1.010 + 97
1.010 + 385
1.010 + 6145

Min Norm.
(Min)
1.010 95
1.010 383
1.010 6143

Min Denorm.
(DMin)
1.010 101
1.010 398
1.010 6176

Table 312. Decimal floating-point data representations

The 1.010 N values in Table 312 are actually 0.9999...10 N , which were rounded for simplicity.
Decimal floating-point has many advantages over packed decimal:

670

Assembler Language Programming for IBM z System Servers

Version 1.00

Its behavior is governed by industry standards.


It keeps track of the decimal point automatically.
Fewer programming languages support packed decimal.
Its performance is faster because arithmetic is done in registers, rather than in memory.
Rounding support is far more varied than the simple round-by-adding of the SRP instruction.

Exercises
35.1.1.(2) Short hexadecimal and binary floating-point data can correctly represent only 6
decimal digits. Assuming a 7-bit exponent, show how you would create a 24-bit decimal
floating-point data item with BCD digits used for the significand. What should be the minimum
and maximum values of the exponent, EMax and EMin, and what should be the characteristic
bias?
35.1.2.(2) + In Figure 433, what is the quantum of each value?
35.1.3.(1) + Suppose two decimal floating-point numbers have representations of 7 and 16 digits
respectively. If their exponents are equal, do they also have the same quantum?
35.1.4.(2) + In Figure 433, how many significant digits are there in each value?
35.1.5.(2) + In Figure 433, how many members are there in the cohort of each value?
35.1.6.(3) + Suppose a decimal floating-point representation supports p significand digits. If a
nonzero value has n digits between its leftmost and rightmost nonzero digits, how many
members are in its cohort, assuming the value is well within the limits of the representations
exponent range? (For example, if p=11 and the significand is 00057036000, then n=5.)

35.2. z System Decimal Floating-Point Data Encoding and Representation (*)


Details Follow
This next section describes the interesting (and complex!) details of the
z System decimal floating-point format, but you dont need to understand it to make good use of decimal floating-point instructions and
arithmetic. The conceptual representation in Figure 432 is an adequate
description for almost all your needs.
Well start by showing how three BCD digits are encoded in 10 bits.

35.2.1. Decimal Floating-Point Data Encoding (*)


To efficiently encode decimal values between 0 and 999, we could use 10-bit binary integers. (The
values from 1000 to 1023 would be unused, but this is a small price to pay.) However, because
we want to do decimal arithmetic, we should avoid frequent internal conversions between binary
and decimal. Thus, this 10-bit binary-integer format was rejected.
Instead, an efficient and unusual densely packed decimal (DPD) encoding is used. Three BCD
digits (12 bits) are mapped into an unusual 10-bit grouping220 called a declet.

220

The details are ugly or elegant, depending on your perspective.


Chapter IX: Floating-Point Data and Operations

671

The actual encoding takes this form: let 3 BCD digits be represented by the 12 bits
abcd efgh ijkm, and let a a 10-bit declet be represented by pqr stu v wxy. Converting from
BCD digits to a declet is done in two steps:
1. Extract the high-order bits of the three BCD digits (aei).
2. Select one of eight 10-bit declet encodings, based on the remaining nine bits of the BCD
string. Table 313 shows the bit selections:
aei
000
001
010
011
100
101
110
111

pqr
bcd
bcd
bcd
bcd
jkd
fgd
jkd
00d

stu
fgh
fgh
jkh
10h
fgh
01h
00h
11h

v
0
1
1
1
1
1
1
1

wxy
jkm
00m
01m
11m
10m
11m
11m
11m

Table 313. Declet encoding for BCD


digits

For example, suppose you want to encode the BCD digits 579 into a declet. The bits of the BCD
digits are 0101 0111 1001, so the aei bits are 001. The remaining three bits (bcd) of the first BCD
digit are 101; the remaining three bits of the second BCD digit (fgh) are 111, and the remaining
bits (jkm) of the last BCD digit are 001. When combined, the result is 101 111 1 001. (The jk
bits are zero because the final BCD digit is 9, so they are ignored in forming the declet!)
Because we are encoding only 1000 values (from 000 to 999), the remaining 24 possible bit patterns are called non-preferred, and assigned 3 each to 8 BCD values. They have bit patterns
01x11x111x, 10x11x111x, and 11x11x111x, where x can be either 0 or 1. The preferred encodings
are called canonical encodings. Non-preferred encodings are accepted as arithmetic operands, but
are never generated as a result.
Figure 463 on page 720 shows all the BCD-to-DPD encodings, including the 24 non-preferred
declet encodings. Figure 464 on page 721 shows all the DPD-to-BCD encodings, and Table 379
on page 719 summarizes the non-canonical declets and their BCD equivalents.
Declets can be converted to BCD digits according the rules shown in Table 314, where the - is
a dont care indicator meaning the bit may be 0 or 1. (The same notation for declet bits and
BCD-digit bits is used as in Table 313.)
vwxst
0---100-101-110-11100
11101
11110
11111

abcd
0pqr
0pqr
0pqr
100r
100r
100r
0pqr
100r

efgh
0stu
0stu
100u
0stu
100u
0pqu
100u
100u

ijkm
0wxy
100y
0sty
0pqy
0pqy
100y
100y
100y

Table 314. Converting decimal floating-point declets to BCD digits

For example, suppose you start with a declet 1011111001, where the bits are denoted pqrstuvwxy,
and the bits of the three BCD digits are denoted abcd &efgh ijkm. The vwxst bits are then 10011.
This corresponds to the second row of Table 314, so we construct the abcd (first BCD) digit from
0101, the efgh (second BCD) digit from 0111, and the ijkm (third BCD) digit from 1001. Thus,
the three BCD digits are 579, as desired.

672

Assembler Language Programming for IBM z System Servers

Version 1.00

This may seem an enormous amount of effort and a great complication, just to encode three
BCD digits. But it has a great advantage from the perspective of the CPU designers:
DPD-to-BCD and BCD-to-DPD conversions can be done efficiently with simple logical operations; 221 no arithmetic is needed!
Remember that all the non-preferred digit encodings have bit representations 01x11x111x,
10x11x111x, and 11x11x111x, where x is either 0 or 1.

35.2.2. Decimal Floating-Point Data Representation (*)


Now that we know how declets are created, well see how they and the exponent are actually
packaged. Unlike Figure 432, the decimal floating-point representation takes the form shown in
Figure 434:

s Combination
Trailing Significand Field

Field (CF)
(TSF) or (T)

Figure 434. Decimal floating-point data representation

The key properties of the representation shown in Figure 434 are:


The coefficient is a string of encoded decimal digits, to the left of an implied decimal point
following the low-order digit. The value of the exponent determines the true position of the
decimal point (as weve seen for hexadecimal and binary floating-point data).
The rightmost digit is the units digit. It may be zero, because the significand is not rightnormalized.
The leftmost nonzero digit is called the leftmost significant digit.
The high-order digit (whether or not its zero) is the leftmost digit, Thus, the significand
digits are the leftmost digit through the low-order units digit, while the significant digits are the
leftmost nonzero digit through the low-order units digit.
Then, the value of a number is ( 1)sign coefficient 10exponent
Figure 435 shows the 32-, 64-, and 128-bit formats. Each Trailing Significand Field (sometimes
abbreviated TSF) is a multiple of 10 bits long, because it contains 2, 5, or 11 declets.
Single
(32 bit)
Format

1
11
20

s Combo Fld
TSF

Double
(64 bit)
Format

1
13
50

s Combo Fld
Trailing Significand Field

1
17
110
Extended / // /
(128 bit) s Combo Field
Trailing Significand Field

Format
/ // /
Figure 435. z System decimal floating-point representations

The 32-bit format is not encouraged by the IEEE standard, but is supported by the Assembler as
a storage format. There are no arithmetic operations on the 32-bit format, but special instructions
make it easy to convert to and from long and extended formats.

221

The logical operations are described in the IEEE Standard.


Chapter IX: Floating-Point Data and Operations

673

The Combination Field is unusual: it contains the exponent and the leftmost significand digit!
The Trailing Significand Field contains the remaining significand digits, encoded as 10-bit declets.
Thus, the precisions of the three representations are 6( + 1)=7, 15( + 1)=16, and 33( + 1 ) = 3 4
decimal digits respectively.

35.2.3. Decimal Floating-Point Combination Field (*)


The representation of the exponent is unusual: the first five bits of the Combination Field222 (CF)
contain the leftmost significand digit and the first two bits of the characteristic (the biased exponent), and the remaining 6, 8, or 12 bits contain the rest of the characteristic.
The first five bits allow 32 combinations; two are reserved for the special values shown in Table
315:
CF bits 0-4
11111
11110
All others

Meaning
NaN
Infinity
Finite numbers

Table 315. First five bits of special-values Combination Field

When the first 5 bits are 11111, the data item is a NaN. If the next bit (bit 6 of the representation; remember, the sign bit is bit 0) is zero, the item is a QNaN, and if one, a SNaN.
Canonical NaNs set all other bits of the data item to zero.
When the first 5 bits are 11110, the data item is an infinity, no matter what the remaining bits are.
Canonical infinity values set all the other bits of the data item to zero.
The remaining 30 possible combinations of Combination Field are used to encode finite values.
The five bits contain the Leftmost Digit (LMD) of the significand and the first two bits of the
characteristic, as shown in Table 316.
LMD
0
1
2
3
4
5
6
7
8
9

First 2 characteristic bits


00
01
10
00000
01000
10000
00001
01001
10001
00010
01010
10010
00011
01011
10011
00100
01100
10100
00101
01101
10101
00110
01110
10110
00111
01111
10111
11000
11010
11100
11001
11011
11101

Table 316. First 5 bits of finite-value Combination Field

A zero value has all significand digits zero, and any representable exponent.
Suppose we want to represent the value 8765432 as a short decimal floating-point number. The
rightmost 6 digits are encoded into two declets X 3 E5 (representing 765) and X232 (representing
432). Thus, the rightmost five hex digits of the data item contain X F9632 . (Remember, the
declet representing 765 was shifted right 2 bits.)

222

674

The IEEE 754-2008 standard calls these bits G 0 through G 4.


Assembler Language Programming for IBM z System Servers

Version 1.00

The exponent is zero, so the characteristic is decimal 101 (the characteristic bias, shown in Table
317) or B0110 0101 . Because the Combination Field is 11 bits wide and its first 5 bits are the
L M D + Leading CF bits, we must extract the two leading bits of the characteristic, or 01. Then,
we see in Table 316 that the LMD 8 means that the leading 5 bits of the CF contains 11010. With
a zero for the sign bit, we can put the pieces together:

0 (Sign Bit)
11010 (initial 5 bits of Combination Field)
100101 (rest of the characteristic)
X F9632 (20-bit trailing significand)

so the final data item has representation X 6 A5F9632 .


Decimal floating-point encodings are difficult!
As this example shows, its best to let the Assembler and the CPU generate encoded values for you.
Table 317 summarizes properties of the decimal floating-point representation. The values in the
row denoted Characteristic length show that two of its bits are encoded in the Combination
Field.
Property
Format length (bits)
Combination field length (bits)
Characteristic length (bits)
Trailing Significand Field length (bits)
Precision (decimal digits)
Exponent range
Exponent bias
Max Normalized Value (N max )
Min Normalized Value (N min )
Smallest DeNorm Value (D min )
Effective exponent range (of all representable values)

Short format

Long format

32
11
6+2
20
7
95, + 96
101
10 + 97
10 95
10 101

64
13
8+2
50
16
383, + 384
398
10 + 385
10 383
10 398

Extended
format
128
17
12 + 2
110
34
6143, + 6144
6176
10 + 6145
10 6143
10 6176

101, + 90

398, + 369

6176, + 6111

Table 317. Properties of decimal floating-point representations

The unusual format of the combination field allows the exponent range to be wider: normally an
n-bit exponent would allow 2 n values, but the DFP encoding allows approximately 32(n-1) or 1.5
times as many values.

Exercises
35.2.1.(2) + Using a decimal floating-point notation like that used in the text on page 670, what
are the quanta of each member of the cohorts of these numbers?
1. [ 37430]
2. [ + 10009]
3. [ 20340]
35.2.2.(1) In Figure 435 on page 673, how many declets appear in each of the decimal floatingpoint representations?
35.2.3.(2) Suppose the significand of a long decimal floating-point number has eight nonzero
significant digits, such as 12345678. How many members does its cohort have?

Chapter IX: Floating-Point Data and Operations

675

35.2.4.(3) Suppose the significand of a long decimal floating-point number has eight significant
digits, but you dont know their values. How many members does its cohort have?
35.2.5.(2) What is the declet encoding of the BCD digits 987? Show the steps you used to
derive your result.
35.2.6.(2) Decode the declet 1011001101 to BCD digits. Show the steps you used to derive your
result.
35.2.7.(2) What type of long decimal floating-point special value is represented by these strings?
1. X827C000000000000
2. X 7 EF00049826BA3B0
3. X FB7388215142D357
35.2.8.(1) Write and assemble a test program to verify that the representation of the short
decimal floating-point value 8765432 is as derived following Table 316.
35.2.9.(2) + Convert the value 3.141593 to short and long decimal floating-point using the
method shown following Table 316.
35.2.10.(2) Why is the low-order digit of a decimal floating-point value often the same as the
low-order digit of its decimal value?

35.3. Decimal Floating-Point Constants


Decimal floating-point constants are generated by DC statements with types E, D, and L for
short, long, and extended formats respectively. The type extension must be D:
ED

Short format decimal floating-point


2614D2E7

DD

DC ED123.4567

Long format decimal floating-point


261934B9C1E28E56

LD

7 digits

DC DD12345678.90123456

16 digits

Extended format decimal floating-point


2603534B9C1E28E5
6F3C127177823534

DC LD123456789012345.6789012345678901234

34 digits

These three statements generate the short, long, and extended decimal floating-point representations of 100:
DC
DC
DC

ED100
DD100
LD100

Generates X22500080
Generates X2238000000000080
Generates X2208000000000000 0000000000000080

Because decimal floating-point values are not normalized, equivalent values (members of a
cohort) can generate different constants. For example, each of these constants has numeric value
100;
DC
DC
DC
DC

ED100.00
ED100.0
ED100
ED 1 E2

Generates
Generates
Generates
Generates

X22304000
X22400400
X22500080
X22700001

but the generated constants depend on the number of significant digits in the nominal value: in
the first three constants, the trailing zero digits are significant.
You can also generate constants with the four special values infinity, NaN, SNaN, and QNaN, as
well as the three finite values Max, Min, and DMin. These are shown in Table 318:

676

Assembler Language Programming for IBM z System Servers

Version 1.00

Value
(Inf)

Short
78000000

Long
7800000000000000

Extended
7800000000000000 0000000000000000

(NaN)

7C000000

7C00000000000000

7C00000000000000 0000000000000000

(SNaN)

7E000000

7E00000000000000

7E00000000000000 0000000000000000

(QNaN)

7C000000

7C00000000000000

7C00000000000000 0000000000000000

(Max)

77F3FCFF

77FCFF3FCFF3FCFF

77FFCFF3FCFF3FCF F3FCFF3FCFF3FCFF

(Min)

04000000

0400000000000000

0400000000000000 0000000000000000

(DMin)

00000001

0000000000000001

0000000000000000 0000000000000001

Table 318. Assembled decimal floating-point special-value constants

Unlike binary floating-point, the only decimal floating-point special value that is not simply a
short constant extended with zeros is the (Max) constant. (Compare these values with those in
Table 269 on page 631.)
Decimal floating-point zeros do not have a unique representation, as illustrated in Table 319. This
lack of uniqueness can have possibly unexpected effects in decimal floating-point arithmetic operations; some examples are given in Section 36.7.
DC Operand
ED 0

Generated Constant
X22500000

ED 0 . 0

X22400000

ED . 0 0

X22300000

ED 0 E-101

X00000000

DD 0

X22380000 00000000

DD 0 E1

X223C0000 00000000

DD 0 E369

X43FC0000 00000000

DD 0 E-398

X00000000 00000000

Table 319. Examples of decimal floating-point short precision zeros

Unlike hexadecimal and binary floating-point zeros, decimal floating-point zeros can have a wide
variety of representations.

35.3.1. Rounding-Mode Suffixes for Decimal Floating-Point Constants


In the absence of a specific rounding request, the Assembler rounds decimal floating-point constants to nearest even. For directed rounding, you can specify a rounding-mode suffix of the
form Rn, where n is one of the numbers 8 through 15; Rn must given as a single token with no
embedded blanks.
Table 320 lists the rounding-mode suffixes and their meanings.
Mode
8
9
10
11
12
13
14
15

Rn
R8
R9
R10
R11
R12
R13
R14
R15

Description
Round to nearest; ties to nearest even (half-even)
Round toward zero (truncate)
Round to + ; if , truncate
Round to ; if + , truncate
Round to nearest; ties away from 0 (half-up)
Round to nearest; ties toward 0 (half-down)
Round up (away from zero)
Round for reround, or prepare for shorter precision

Table 320. Assembler rounding-mode suffixes for D F P constants


Chapter IX: Floating-Point Data and Operations

677

Well discuss these various rounding options in more detail later.


In this short-precision example, the nominal value is rounded up:
2614D2E7
2614D2E8
2614D2E8

DC ED123.4567
DC ED123.45678R10
DC ED123.45678R14

Default rounding
Rounded to +infinity
Rounded away from zero

In this long-precision example, the nominal value is rounded down:


261934B9C1E28E58
261934B9C1E28E57

DC DD12345678.901234577
Default rounding
DC DD12345678.901234577R11 Rounded to -infinity

In this extended-precision example, the nominal value is rounded toward zero (truncated):
2603534B9C1E28E5
6F3C127177823535
2603534B9C1E28E5
6F3C127177823534

DC LD123456789012345.67890123456789012349

Default rounding

DC LD123456789012345.67890123456789012349R9 Rounded to 0

35.3.2. Decimal Exponents and Modifiers


You can specify a decimal exponent as part of the nominal value, or an exponent modifier that
applies to all the nominal values in the operand. Figure 436 shows some examples; the letters E,
M, and B in the comments fields mean the constant has a decimal Exponent, an exponent
Modifier, or Both. The also comments show different ways to generate the same constant. All
the constants have value 100, so are members of the same cohort.
DC
DC
DC
DC
DC
DC
DC
DC
DC
DC

ED10000E-2
EDE-210000
ED1000E-1
EDE-11000
ED100
ED10E1
ED 1 E2
EDE1 1 E1
EDE-5 1 E7
ED . 1 E3

E:
M:
E:
M:
E:
E:
B:
B:
M:

generates
generates
generates
generates
Generates
generates
generates
generates
generates
generates

X22304000
X22304000
X22400400
X22400400
X22500080
X22600010
X22700001
X22700001
X22700001
X22700001

also.
also.

also,
also, and
also.

Figure 436. DFP constants with exponent modifiers and decimal exponents

The only other modifier allowed with decimal floating-point constants is Length, and it must be 4
for short precision values, 8 for long, or 16 for extended. The only effect is that the generated
constants are not aligned on their respective natural boundaries: word, doubleword, and
doubleword.

Exercises
35.3.1.(2) + A four-byte area of memory contains the bit pattern X4040405C . What possibilities
are represented by that pattern?
35.3.2.(3) Write three decimal floating-point constants that generate a value one ulp smaller
than the (Max) constant in short, long, and extended representations.
35.3.3.(2) Write three decimal floating-point constants with numeric operands that generate a
value equal to that generated by a (Max) operand.
35.3.4.(2) + Hexadecimal and binary floating-point constants allow a variety of length modifiers.
Why do decimal floating-point constants not allow length modifiers other than 4 (for short), 8
(for long), or 16 (for extended)?

678

Assembler Language Programming for IBM z System Servers

Version 1.00

35.3.5.(2) + How many members are there in the cohort of + 0 in a short decimal floating-point
representation?
35.3.6.(2) + How many members are there in the cohort of + 0 in a long decimal floating-point
representation?
35.3.7.(2) + Assemble the following sixteen short DFP constants, and study the generated
values, particularly the encoding of the significands. Which of the values are NMin, and
which are DMin, having the minimum exponent?
10000000.E-95
1000000.E-95
100000.E-95
10000.E-95
1000.E-95
100.E-95
10.E-95
1.E-95
.1E-95
.01E-95
.001E-95
.0001E-95
.00001E-95
.000001E-95
.0000001E-95
.00000001E-95

35.4. Decimal Floating-Point Data Classes (*)


Like binary floating-point data types, decimal floating-point data occurs in six classes:
1. Zeros may have any exponent and either sign, and have a zero significand.223 0s are distinct,
but compare equal.
2. Subnormal numbers X lie in the range D min |X| < N min
3. Normal values X lie in the range Nmin |X| N max
4. Infinity requires that the first five bits of the Combination Field be 11110. The contents of
the Trailing Significand Field is ignored. Infinities are valid in decimal floating-point arithmetic operations.
5. Quiet NaNs require that the first five bits of the Combination Field be 11111, and that the
next bit of the CF is 0.
6. Signaling NaNs require that the first five bits of the Combination Field be 11111, and that the
next bit of the CF is 1.
Operations involving SNaNs usually cause and Invalid Operation exception, and may be
masked off by setting mask bits in the Floating-Point Control Register (to be described in
34.4. Binary Floating-Point Exceptions, Interruptions, and Controls on page 635).
Table 321 lists the three instructions used to test operands in the floating-point registers:

223

Binary floating-point zeros must have zero characteristic and zero significand. Hexadecimal floating-point true zeros
have zero characteristic and zero fraction, but pseudo-zeros have a zero fraction and nonzero characteristic.
Chapter IX: Floating-Point Data and Operations

679

Op
ED50
ED58

Mnem
TDCET
TDCXT

Type
RXE
RXE

Instruction
Test Data Class (Short)
Test Data Class
(Extended)

Op
Mnem
ED54 T D C D T

Type
RXE

Instruction
Test Data Class (Long)

Table 321. Decimal floating-point Test Data Class instructions

The operands of these instructions have the format


R1,D2(X2,B2)
where R 1 designates a FPR.
A bit pattern in the rightmost 12 bits of the Effective Address of the second operand address tests
selected classes of the first operand; the remaining bits of the Effective Address are ignored. The
instruction sets the CC to 1 if a bit in the Effective Address matches the operands data class, or
to zero if not.
Table 322 shows the test bits; the bit numbering corresponds to a 64-bit Effective Address.
Class
Zero
Subnormal
Normal
Infinity
QNaN
SNaN

+ sign

sign

52
54
56
58
60
62

53
55
57
59
61
63

Table 322. DFP Test Data Class second-operand bits

Note:
The order of the test bits in the second operands Effective Address of
these decimal floating-point instructions is different from the order of the
test bits in the corresponding binary floating-point instructions.
(Compare Table 322 to Table 280 on page 641.)
To illustrate, the Condition Code after each of these TDCET instructions in Figure 437 will be 1,
because the bits in the Effective Address match the class of the data in FPR0.
LZER
TDCET
LE
TDCET
LE
TDCET
LE
TDCET
LE
TDCET
LE
TDCET

0
0,B110000000000
0,=ED 1 E-100
0,B001100000000
0,=ED 1
0,B000011000000
0,=ED ( Inf)
0,B000000110000
0,=ED ( QNaN)
0,B000000001100
0,=ED ( SNaN)
0,B000000000011

c(FPR0) = X00000000,
Test for zero
c(FPR0) = X00100001,
Test for subnormal
c(FPR0) = X22500001,
Test for normal
c(FPR0) = X78000000,
Test for infinity
c(FPR0) = X 7 C000000 ,
Test for QNaN
c(FPR0) = X 7 E000000 ,
Test for SNaN

zero
subnormal
normal
infinity
QNaN
SNaN

Figure 437. Examples of decimal floating-point Test Data Class instructions

Table 323 shows another way to visualize the left-to-right order of the test bits and the tested
classes:

680

Assembler Language Programming for IBM z System Servers

Version 1.00

60

61

62

63
SNaN

+ Normal

59

+ SNaN

Subnormal

58

QNaN

+ Subnormal

57

+ QNaN

56

Infinity

55

+ Infinity

54

Normal

53
Zero

Ignored

52
+ Zero

Bits 0-51

Table 323. Test Data Class test-bit vs. tested-class correspondence

Three related Test Data Group instructions are described in Section 35.12.7 on page 712.

Exercises
35.4.1.(2) Given a decimal floating-point operand in FPR0, which data classes will these
instructions detect?
(a)
(b)
(c)
(d)

TDCET
TDCDT
TDCXT
TDCDT

0,29
0,4095
0,15
0,X C00

35.5. Decimal Floating-Point Operations: Rounding, Quanta, and Exceptions


Decimal floating-point operations offer rich choices of rounding options; well describe them
briefly. Because many instructions involve selecting the quantum of the final result, well see
some examples to clarify the concepts involved.

35.5.1. Rounding
Rounding a result requires choosing a Permissible Value among the possible values; it is usually
one of the values allowed by the destination precision. (Infinity is not a permissible value.)
Suppose Z is the infinitely precise result.
If Z is exactly representable, its value is always selected as the delivered result, independent of
the rounding mode.
Otherwise, the two adjacent values with same sign as Z are candidates for the delivered result.
To illustrate, suppose Z is the intermediate result of an operation, as sketched in Figure 438.
Increase Z

Infinitely precise value

Decrease Z







-  +
Z1
Z Z2
0
Z3
Z Z4




Closest Representable values
Figure 438. Illustration of decimal floating-point rounding candidates

Let Z1 and Z2, or Z3 and Z4 be the nearest representable values to the infinitely precise value. If
Z is not representable, either Z1 or Z2 is chosen (if Z is negative), or Z3 or Z4 is chosen (if Z is
positive). Z2 or Z3 can be zero.

Chapter IX: Floating-Point Data and Operations

681

Assuming Z is not between Z2 and Z3, the standard rounding modes from Z to one of the
nearest candidate values are as follows:
If Z lies exactly halfway between the two candidates, a tie occurs: choose the candidate with
an even low-order digit. (Round to nearest even)
If Z lies exactly halfway between the two candidates, a tie occurs: choose the candidate with
the larger magnitude. (Z1 or Z4) (Round half-up)
Choose the candidate toward + (Z2 or Z4) (Round up)
Choose the candidate toward (Z1 or Z3) (Round down)
Choose the candidate closer to zero (Z2 or Z3) (Round toward zero; Truncate)
If Z lies anywhere between the two candidates, choose the candidate with the larger magnitude
(Z1 or Z4) (Round away from zero)
If Z is a very small number close to zero, there are two cases to consider:
-  +
-DMin
Z?
0
Z?
+DMin
Figure 439. Illustration of decimal floating-point rounding candidates near zero

If -DMin < Z < 0, then

-DMin is selected for for rounding toward or for rounding away from zero
Otherwise, 0 is selected.

If 0 < Z < +DMin, then

+DMin is selected for for rounding toward + or for rounding away from zero
Otherwise, 0 is selected.

These rounding modes are illustrated in Table 324:


Rounding Mode
Round to nearest, ties to even
Round to nearest, ties away
from zero
Round toward +
Round toward
Round toward zero (truncate)
Round away from zero

12.341
12.34

12.345
12.34

12.349
12.35

12.355
12.36

12.345
12.34

12.34

12.35

12.35

12.36

12.35

12.35
12.34
12.34
12.35

12.35
12.34
12.34
12.35

12.35
12.34
12.34
12.35

12.36
12.35
12.35
12.36

12.34
12.35
12.34
12.35

Table 324. Example of D F P rounding modes

Well see how to set a default global decimal floating-point rounding mode in Section 35.12
starting on page 704; one other rounding type (Round to prepare for shorter precision) is
described there.

35.5.2. Preferred Exponent and Quantum


When a decimal floating-point calculation generates a result, a choice must sometimes be made
among several possible cohort members having the correct value. Using numbers with seven-digit
maximum precision, suppose we add two numbers having the same exponent (and quantum):
123.450
+ 6.228
129.678

123450.10**-3 Quantum = .001


6228.10**-3 Quantum = .001
129628.10**-3 Quantum = .001

the sum has the same exponent and quantum so long as greater precision isnt needed for the
significand.
Suppose the two numbers have different exponents/quanta:

682

Assembler Language Programming for IBM z System Servers

Version 1.00

123.45
+ 6.228
129.678

12345.10**-2 Exponent = -2, Quantum = .01


6228.10**-3 Exponent = -3, Quantum = .001
129628.10**-3 Exponent = -3, Quantum = .001

In this case, the same result should have the same quantum as before, so we assign the smaller
exponent/quantum of the two operands. This choice preserves all the significant digits.
It doesnt matter if the low-order digit is zero; the smaller quantum is still chosen: this is the
preferred quantum for exact results.
123.45
+ 6.220
129.670

12345.10**-2 Exponent = -2, Quantum = .01


6220.10**-3 Exponent = -3, Quantum = .001
129670.10**-3 Exponent = -3, Quantum = .001

If the result is inexact, a different rule is needed. Using 7-digit precision, suppose we add:
123.45
+ 6.22801
129.67801

12345.10**-2 Exponent = -2, Quantum = .01


622801.10**-5 Exponent = -5, Quantum = .00001
Quantum = ???, inexact result

The result will be inexact because it must be rounded to seven significant digits (the example uses
rounding toward zero). Thus, the possible same-valued results with 7 digits are 129.6780 and
0129.678; these are two members of a cohort having quanta .0001 and .001 respectively. The
smaller quantum is preferred, so the first value 129.6780 is delivered; it is the result with the
greater precision.
A similar rule applies to multiplication: the exponent of the product is the sum of the two
operand exponents, and the product quantum is the product of the two operand quanta.
Assuming 7-digit precision,
11.11
22.2
246.642

1111.10**-2 Exponent = -2, Quantum = .01


222.10**-1 Exponent = -1, Quantum = .1
246642.10**-3 Exponent = -3, Quantum = .001, exact result

For an exact result, the exponent is the sum of the two exponents, and the quantum is the
product of the quanta of the two operands. Now, suppose we generate the inexact product of
11.001 and 22.002, and the exact result 242.242020 must be rounded:
11.001
22.002
242.242020

11001.10**-3 Exponent - =3, Quantum = .001


22002.10**-3 Exponent = -3, Quantum = .001
242242020.10**-6 Exponent = -6, Quantum = .000001, inexact

Again assuming the result is truncated to 7 significant digits, we must choose one of two possible
cohort members: 242.2420 (with quantum .0001) and 0242.242 (with quantum .001). As we saw
for addition, the preferred quantum is the smaller, so the delivered result is 242.2420, with the
greater precision.
Similar considerations apply to division. The exponent of the quotient is the exponent of the
divisor subtracted from the exponent of the dividend, and the quantum of the quotient is the
quantum of the dividend divided by the quantum of the divisor. Consider an exact result:
655.36
12.8
51.2

65536.10**-2 Exponent = -2, Quantum = .01


128.10**-1 Exponent = -1, Quantum = .1
512.10**-1 Exponent = -1, Quantum = .1

For this exact result, the preferred quantum is the quotient of the operand quanta, in this case
.01 .1 = .1.
Now, consider an inexact result: the quotient of 10000.1 2.0001 is 4999.8000099..., which must
be rounded to seven significant digits:

10000.1
2.0001
4999.800...

100001.10**-1 Exponent = -1, Quantum = .1


20001.10**-4 Exponent = -4, Quantum = .0001
Quantum = .001

Chapter IX: Floating-Point Data and Operations

683

The cohort containing the result has three members: 004999.8 (with quantum 0.1) 04999.80 (with
quantum .01), and 4999.800 (with quantum .001). The chosen result is the last of these, with the
smallest exponent and quantum, and the largest number of significant digits.
This example shows an inexact quotient with only one cohort member:
10.
.03
333.3333...

0.10**0 Exponent = 0, Quantum = 1


3.10**-2 Exponent = -2, Quantum = .01
Quantum = .0001

where the infinitely-repeating result has been truncated to 7 digits. If the result had been exact,
the quantum would have been 100; but for an inexact result, the cohort member (in this case,
theres only one!) with the smallest quantum is chosen.
These rules are summarized in Table 325.
Operation
Add, Subtract

Multiply
Divide

Result
Exact
Inexact
Exact
Inexact
Exact
Inexact

Preferred Quantum
Smaller of the two source quanta, or the
quantum closest to it
Smallest quantum of results cohort members
Product of the two source quanta
Smallest quantum of results cohort members
Quotient of the two source quanta
Smallest quantum of results cohort members

Table 325. Preferred quanta for some decimal floating-point operations

These examples help show that the exponent and quantum chosen for a delivered result generally
retain the maximum number of significant digits. Low-order digits are preserved until the number
of significant digits exceeds the precision p of the representation. Thus, values are rightnormalized so long as the number of significant digits is less than p, and left-normalized when the
number is greater than p.
We might characterize the treatment of preferred exponent and quantum 224 this way:
Preferred Exponent and Quantum
Decimal floating-point arithmetic tries to give the best available fixedpoint result unless it cant, and then it gives you the most precise available rounded floating-point result.

35.5.3. DFP Exceptions


In addition to the exceptions described in Section 34.4 starting on page 635, the quantum exception is provided for decimal floating-point. This exception condition is caused when a result has a
different quantum from the preferred quantum. This is rarely a concern to most programs.
There are two decimal floating-point q bits defined in the Floating-Point Control Register,
shown in Figure 440. (The decimal floating-point rounding mode bits are described in Section
35.12.)

224

Rather than the term preferred quantum, the IEEE-754 standard uses preferred exponent instead:
For all computational operations except quantize and roundToIntegralExact, if the result is inexact the
cohort member of least possible exponent is used to get the maximum number of significant digits. If the
result is exact, the cohort member is selected based on the preferred exponent for a result of that operation,
a function of the exponents of the inputs. Thus, for finite x, depending on the representation of zero, 0 + x
might result in a different member of xs cohort. If the results cohort does not include a member with the
preferred exponent, the member with the exponent closest to the preferred exponent is used.

684

Assembler Language Programming for IBM z System Servers

Version 1.00

8
8
8
8

Data Excep n Rounding

Mask Bits
Flag Bits Code (DXC) Mode Bits

i z o u x q 0 0i z o u x q 0 0i z o u x y 0 00 DRM 0 0 BRM

Figure 440. Floating-Point Control (FPC) register

Bit

Meaning

q (bit 5)

Quantum exception

In addition to the Data Exception Code values listed Table 271 on page 637, there are two
further codes that might be placed in the DXC when you execute a DFP instruction:
DXC
03

Meaning
a DFP instruction is attempting to execute on a CPU where DFP instructions are
available, but are not enabled.

04

a DFP instruction has delivered a result with a quantum that is different from the
preferred quantum.

Table 326. Decimal floating-point additional DXC value

The CPUs behavior for a quantum exception is shown in Table 327:


Mask bit = 1
An interruption occurs: the DXC is set to
X 0 4 , and the quantum of the result is set to
the quantum closest to the preferred
quantum.

Mask bit = 0
The result is the cohort member with
quantum closest to the preferred quantum.
The q flag bit is set to 1.

Table 327. Decimal floating-point quantum exception

In other words, the delivered result is the same whether or not you enable an exception.
The other exceptions generated by decimal floating-point operations are the same as those for
binary floating-point described in Section 34.4.3 on page 638, and the other mask and flag bits in
the first and second bytes are as described in Section 34.4 on page 635.

35.4.4. Overflow/Underflow Scale Factors (*)


When exponent overflow and underflow exceptions are enabled, the exponent of the delivered
result is scaled by adding or subtracting a factor that causes the exponent to lie near the middle of
the exponent range for that representation. These scale factors are shown in Table 328.
Long
576

Extended
9216

Table 328. Decimal floating-point scale factors for exponent


spills

For overflows, the scale factor is subtracted from the overflowed exponent, and for underflows it
is added to the underflowed exponent.

Exercises
35.5.1.(2) + Does the choice of the smallest quantum for an inexact result mean that the
significand is left-normalized?

Chapter IX: Floating-Point Data and Operations

685

35.5.2.(1) What will happen if you attempt to execute a DFP instruction on a CPU where
DFP instructions are not available?

35.6. Decimal Floating-Point Data Movement Instructions


These instructions were described in Section 31.9 starting on page 555, and are mentioned here
because they can be used for decimal floating-point operands. They have no dependence on any
floating-point representation, and the CC is not changed.

35.6.1. Copy Sign


The CPSDR instruction copies the long second operand to the first operand register, giving it the
sign of the third operand.
Op
B372

Mnem
CPSDR

Type
RRF

Instruction
Copy Sign (Long)

Table 329. Copy Sign instruction

The instruction format is


CPSDR R1,R3,R2
so you could write
CPSDR 1,5,8

Copy FPR8 to FPR1 with FPR5 s sign

35.6.2. Copy between General and Floating-Point Registers


The LDGR and LGDR instructions copy long operands between a GPR and a FPR.
Op
B3C1

Mnem
LDGR

Type
RXY

Instruction
Load FPR from GPR
(Long)

Op
Mnem
B3CD L G D R

Type
RXY

Instruction
Load GPR from FPR
(Long)

Table 330. Instructions moving data between FPRs and GPRs

Their instruction format is


mnemonic R1,R2
To copy the contents of GG3 to FPR6, and from FPR2 to GG0, you could write
LDGR
LGDR

6,3
0,2

Copy c(GG3) to FPR6


Copy c(FPR2) to GG0

35.6.3. Copy Among Floating-Point Registers


Table 331 lists the instructions for moving floating-point operands among the floating-point registers. (They were introduced in System/360 for moving hexadecimal floating-point operands, but
can just as well be used for binary and decimal operands.)
Op
38

Mnem
LER

B365

LXR

Type Instruction
RR
Load FPR from FPR
(Short)
R R E Load FPR from FPR
(Extended)

Op
28

Mnem
LDR

Table 331. Instructions copying data between FPRs

For example:

686

Assembler Language Programming for IBM z System Servers

Version 1.00

Type Instruction
RR
Load FPR from FPR
(Long)

LER
LDR
LXR

5,8
4,2
1,12

Copy short c(FPR8) to FPR5


Copy long c(FPR4) to FPR2
Copy extended c(FPR12,FPR14) to (FPR1,FPR3)

Always remember that both operands of the LXR instruction must refer to valid FPR pairs.

Exercises
35.6.1.(1) What is the difference between these instructions?
LDR
LDR

8,1
10,3

LXR

8,1

and

35.7. Decimal Floating-Point Arithmetic Instructions


Well start with the basic arithmetic operations: multiplication, division, addition, and subtraction;
the instructions are listed in Table 332. All the operations are rounded according to the current
rounding mode in the FPCR.
Op
B3D0
B3D0

Mnem
MDTR
MDTRA

Type
RRR
RRR

Instruction
Multiply (Long)
Multiply (Long)

Op
Mnem
B3D8 M X T R
B3D8 M X T R A

Type
RRR
RRR

Instruction
Multiply (Extended)
Multiply (Extended)

B3D1
B3D1

DDTR
DDTRA

RRR
RRR

Divide (Long)
Divide (Long)

B3D9 D X T R
B3D9 D X T R A

RRR
RRR

Divide (Extended)
Divide (Extended)

B3D2
B3D2

ADTR
ADTRA

RRR
RRR

Add (Long)
Add (Long)

B3DA AXTR
B3DA AXTRA

RRR
RRR

Add (Extended)
Add (Extended)

B3D3
B3D3

SDTR
SDTRA

RRR
RRR

Subtract (Long)
Subtract (Long)

B3DB SXDR
B3DB SXDRA

RRR
RRR

Subtract (Extended)
Subtract (Extended)

Table 332. Decimal floating-point basic arithmetic instructions

All decimal floating-point arithmetic instructions are register-register operations, unlike some
hexadecimal and binary floating-point instructions that support register-storage operations. all
can be non-destructive because neither source operand need be overwritten by the result.
The format of the instructions without an A suffix on the mnemonics is shown in Table 333:
opcode

R3

R1

R2

Table 333. Format of D F P arithmetic instructions

Their assembler instruction statements have operand format


mnemonic R1,R2,R3
where the two source operands are in floating-point registers R2 and R 3, and the result is placed
in floating-point register R1.
The operands must all be long or all extended precision; there are no arithmetic operations for
short-precision or mixed-length operands.
The format of the instructions with an A suffix on the mnemonics is shown in Table 334:

Chapter IX: Floating-Point Data and Operations

687

opcode

R3

M4

R1

R2

Table 334. Format of D F P arithmetic instructions with rounding


mask

Their assembler instruction statements have operand format


mnemonic R1,M4,R2,R3
Again, the two source operands are in floating-point registers R2 and R 3, and the result is placed
in floating-point register R1. The rounding mask M 4 applies only to the current instruction, and
has the values and effects shown in Table 335:
Mask
B0000
B0001
B0010
B0011
B0100

Effect

Mask

Use current DFP rounding mode


Round to nearest with ties away
from 0 (traditional round)
Use current DFP rounding mode
Round to prepare for shorter precision
Round to nearest with ties to
even

Effect

B1000

Round to nearest with ties to


even

B1001

Round toward 0

B1010

Round toward +

B1011

Round toward

B1100

B0101

Round toward 0

B1101

B0110

Round toward +

B1110

B0111

Round toward

B1111

Round to nearest with ties away


from 0
Round to nearest with ties
toward 0
Round away from 0
Round to prepare for shorter
precision

Table 335. Instruction-specific rounding mask values

The mnemonics with the A suffix have the same opcodes as the instructions without a suffix.
The new mnemonics were introduced so the Assembler can correctly identify the four operands.

35.7.1. Multiplication
The decimal floating-point multiply instructions leave the Condition Code unchanged. You can
think of the operation this way:
operand1 operand2 operand3
The exponent of the product is the sum of the exponents of the two operands.
Unlike hexadecimal and binary floating-point multiplication, there are no instructions to form
double-length products from single-length operands; results have the same format as the
operands. For example:
LD
4,=DD75.22
MDTR 1,4,4

c(FPR1) = c(FPR4)**2

LD
0,=LD 0 . 1
LD
2,=LD0.1+8
MXTR 8,0,0

High-order half to FPR0


Low-order half to FPR2
c(FPR8,FPR10) = c(FPR0,FPR2)**2

LD
8,=DD1.41421
MDTR 2,4,8

c(FPR2)=75.22*1.41421

For finite results, the quantum of the product is chosen as shown in Table 325.

688

Assembler Language Programming for IBM z System Servers

Version 1.00

If underflow or overflow occur, the appropriate exception is signaled; if enabled, the rounded
result is delivered to the target register and an interruption occurs. Otherwise, the exponent is
scaled and the corresponding flag bit in the FPCR is set to 1.
If either operand is a QNaN, that QNaN is the delivered result; if both are QNaNs, the R2
operand is the result. Any SNaN operand, or multiplying zero and infinity, causes an invalidoperation exception.
To illustrate exponent scaling on overflow, suppose we multiply N max by itself, with the interruption enabled for exponent overflow:
LD
0,=DD ( Max)
MDTR 2,0,0

c(FPR0) = X77FCFF3FCFF3FCFF
c(FPR2) = X7500FF3FCFF3FCFE

The overflowed exponent (384 + 384=768) is scaled by subtracting 576 (from Table 328 on
page 685), giving a scaled exponent 192, which happens to be exactly half the maximum exponent, 384. The scaled result is now in mid-range.

35.7.2. Division
The decimal floating-point divide instructions leave the Condition Code unchanged, and no
remainder integer or fractionis calculated. The second operand (the dividend) is divided by the
third operand (the divisor). The quotient is rounded according to the current DFP rounding
mode, and replaces the first operand. You can think of the operation this way:
operand1 operand2 operand3
The exponent of the quotient is the exponent of the divisor subtracted from the exponent of the
dividend. For example:
LD
0,=DD 1
LD
1,=DD 3
DDTR 2,0,1

c(FPR0) = 1 = X2238000000000001
c(FPR1) = 3 = X2238000000000003
c(FPR2) = 1/3 = X 2 DF9B36CDB36CDB3

For finite results, the quantum of the quotient is chosen as shown in Table 325.
If underflow or overflow occur, the appropriate exception is signaled; if enabled, the rounded
result is delivered to the target register and an interruption occurs. Otherwise, the exponent is
scaled and the corresponding flag bit in the FPCR is set to 1.
Dividing a finite number by infinity returns a zero quotient, and dividing a finite number by zero
causes a divide-by-zero exception (which if masked off, returns infinity as the quotient).
Dividing zero by zero or infinity by infinity, or any SNaN operand, causes an invalid-operation
exception. A SNaN operand is returned, unless both are SNaNs in which case the dividend SNaN
is delivered. A QNaN divisor returns a canonical QNaN.

35.7.3. Addition and Subtraction


You can think of these operations this way:
operand1 operand2 operand3
The results from addition and subtraction depend on whether or not the result is exact. Well
illustrate using 7-digit operands:
If the result is exact, the preferred quantum is the smaller of the quanta of the two source
operands, or (if the smaller cant be represented) the quantum closest to the smaller.
For example, this sum produces an exact result:
1.234
+ .34567
1.57967

Quantum = .001
Quantum = .00001
Quantum = .00001

Chapter IX: Floating-Point Data and Operations

689

and the result has the smaller quantum. In this example, the result is exact but the smaller
quantum cant be assigned:
1.234000
+ .3456700
1.5796700

Quantum = .000001 = 10**-6


Quantum = .0000001 = 10**-7
Quantum = .0000001 ?

In this case there are two cohort members with the same value: 1.579670 and 01.57967, with
quanta 10 6 and 10 5 respectively. The quantum closest to the preferred value (10 7) is 10 6,
so the delivered result is 1.579670.
If the result is inexact, the preferred quantum is the smallest of the quanta of the results
cohort members.
For example, this sum produces an inexact result:
1.234321
+ .3454321
1.579753

Quantum = .000001
Quantum = .0000001
Quantum = .000001

and the (rounded) sum has the smaller quantum.


There may be more than one member of the cohort containing the result. For example:
1.111201
- .1111009
1.000100

Quantum = .000001
Quantum = .0000001
Quantum = .000001

where the rounded result has discarded the low-order one. There are three cohort members:
1.000100, 01.00010, and 001.0001; the first has the smallest quantum and greatest number of
significant digits among these cohort members.
These rules preserve as many low-order digits as possible.
Adding a finite number to infinity produces infinity, as does adding like-signed infinities. Adding
infinities of opposite signs causes an invalid-operation exception. If the exception is masked off a
default QNaN is delivered and the CC is set to 3.
Any SNaN operand delivers a SNaN result, and the CC is set to 3. QNaNs generate an invalidoperation exception; if masked off, the CC is set to 3.
For example:
LD
LD
ADTR
ADTR
SDTR
SDTR

0,=DD 1
4,=DD ( Inf)
2,0,0
2,0,4
2,0,4
2,4,4

c(FPR0) = 1
c(FPR4) = +infinity
c(FPR2) = 2, CC=2
c(FPR2) = +infinity, CC=2
c(FPR2) = -infinity, CC=1
Invalid-operation exception

Table 336 shows how the decimal floating-point add and subtract instructions set the Condition
Code:
CC
0
1
2
3

Meaning
Result is zero
Result is less than zero
Result is greater than zero
Result is a NaN

Table 336. CC settings for Add/Subtract instructions

690

Assembler Language Programming for IBM z System Servers

Version 1.00

Exercises
35.7.1.(2) + Assuming the same initial contents of FPR0 and FPR2 in each case, what result of
each of these operations will be in FPR4?

(a)
(b)
(c)
(d)

LD
LD

0,=DD -1
2,=DD -(Inf)

DDTR
DDTR
MDTR
SDTR

4,0,2
4,2,0
4,2,0
4,0,2

35.8. Decimal Floating-Point Compare Instructions


Well look at three groups of decimal floating-point compare instructions:
arithmetic compare
compare and signal
compare biased exponent (characteristic)
All have operand format R1,R 2. The first operand is compared to the second, and the CC is set to
indicate the result, as shown in Table 337. All these compare instructions set the Condition Code
in the same way.
CC
0
1
2
3

Meaning
Operands are
First operand
First operand
Operands are

equal
is low
is high
unordered

Table 337. CC settings for Compare instructions

35.8.1. Compare
These two instructions work just like other arithmetic comparisons, except that the presence of
any QNaN sets the CC to 3. If either operand is a SNaN, an invalid operation exception occurs;
if it is masked off, the CC is set to 3.
Op
B3E4

Mnem
CDTR

Type
RRE

Instruction
Compare (Long)

Op
Mnem
B3EC C X T R

Type
RRE

Instruction
Compare (Extended)

Table 338. Decimal floating-point Compare instructions

For example, these comparisons set the CC as indicated in the comments:

Chapter IX: Floating-Point Data and Operations

691

LD
LD
LD
LD

0,=DD ( Inf)
1,=DD ( QNaN)
2,=DD 2
3,=DD ( SNaN)

c(FPR0)
c(FPR1)
c(FPR0)
c(FPR0)

CDTR
CDTR
CDTR
CDTR
CDTR

0,2
0,1
2,0
2,2
2,3

CC = 2 (+Infinity > +2)


CC = 3 (unordered)
CC = 1 (+2 < +Infinity)
CC = 0
Invalid operation exception

=
=
=
=

+Infinity
+QNaN
+2
+SNaN

35.8.2. Compare and Signal


The two Compare and Signal instructions behave just like the ordinary compare instructions,
except that any NaN, Quiet or Signaling, causes an invalid operation exception. Again, if the
exception is masked off, the CC is set to 3.
Op
B3E0

Mnem
KDTR

Type
RRE

Instruction
Compare and Signal
(Long)

Op
Mnem
B3E8 K X T R

Type
RRE

Instruction
Compare and Signal
(Extended)

Table 339. Decimal floating-point Compare and Signal instructions

These comparisons set the CC as indicated in the comments:


LD
LD
LD
LD

0,=DD ( Inf)
1,=DD ( QNaN)
2,=DD 2
3,=DD ( SNaN)

c(FPR0)
c(FPR1)
c(FPR0)
c(FPR0)

KDTR
KDTR
KDTR
KDTR
KDTR

0,2
0,1
2,0
2,2
2,3

CC = 2 (+Infinity > +2)


Invalid operation exception
CC = 1 (+2 < +Infinity)
CC = 0
Invalid operation exception

=
=
=
=

+Infinity
+QNaN
+2
+SNaN

The main reason to use the Compare and Signal instructions is to avoid the propagation of NaNs
through a computation, perhaps to stop before useless results have been generated.

35.8.3. Compare Biased Exponent


It is sometimes useful to compare the characteristics of two decimal floating-point operands using
the instructions in Table 340.
Op
B3F4

Mnem
CEDTR

Type
RRE

Instruction
Compare Biased Exponent
(Long)

Op
Mnem
B3FC C E X T R

Type
RRE

Instruction
Compare Biased Exponent (Extended)

Table 340. Decimal floating-point Compare Biased Exponent instructions

These instructions compare the biased exponent (characteristic) of the operands, including infinity
and any type of NaN. Table 341 shows the Condition Code setting:
CC
0
1
2
3

Meaning
Characteristics equal
First-operand characteristic is low
First-operand characteristic is high
Operands are unordered

Table 341. CC settings for Compare Biased Exponent instructions

692

Assembler Language Programming for IBM z System Servers

Version 1.00

The CC is set to 1 or 2 only if both operands are finite; otherwise, comparing the characteristic of
any infinity to another, or of any NaN to another, sets the CC to zero. Other combinations of
operands set the CC to 3.
These examples show some biased exponent comparisons:
LD
LD
LD
LD

0,=DD ( Inf)
1,=DD ( QNaN)
2,=DD 2
3,=DD 2 E75

c(FPR0)
c(FPR1)
c(FPR0)
c(FPR0)

CEDTR
CEDTR
CEDTR
CEDTR
CEDTR

0,2
1,1
2,1
2,3
0,0

CC
CC
CC
CC
CC

=
=
=
=

+Infinity
+QNaN
+2
+2*(10**75)

*
=
=
=
=
=

3
0
3
1
0

(Finite vs. Infinity)


(NaN vs. NaN)
(Finite vs. NaN)
(2 vs. 2*(10**75))
(Infinity vs. Infinity)

Exercises
35.8.1.(1) + Make a table showing the CC settings after comparing the biased exponents (characteristics) of a finite value, a NaN, and an infinity among one another.

35.9. Converting Decimal Floating-Point To and From Fixed Binary


The instructions in Table 342 convert fixed-point binary integers in a general register to and from
a decimal floating-point value in a floating-point register.
Op
B3F1

Mnem
CDGTR

Type
RRE

B3F9

CXGTR

RRE

B3E1

CGDTR

RRF

B3E9

CGXTR

RRF

Instruction
Convert from Fixed
(Long64)
Convert from Fixed
(Extended64)
Convert to Fixed
(64Long)
Convert to Fixed
(64Extended)

Op
Mnem
Type
B3F1 C D G T R A R R E
B3F9 CXGTRA R R E
B3E1 C G D T R A R R F
B3E9 CGXTRA R R F

Instruction
Convert from Fixed
(Long64)
Convert from Fixed
(Extended64)
Convert to Fixed
(64Long)
Convert to Fixed
(64Extended)

Table 342. Decimal floating-point convert to/from fixed binary instructions

35.9.1. Convert From Fixed Binary to DFP


These four instructions convert a 64-bit binary integer in the R2 general register to a long or
extended decimal floating-point value in the R1 floating-point register, and the Condition Code is
unchanged. For the instructions without an A suffix, the instruction format is
mnemonic R1,R2
For the instructions with an A suffix, the instruction format is
mnemonic R1,M3,R2,M4
The values of the M3 rounding mask are shown in Table 335 on page 688, and the M4 mask has
bit settings to optionally suppress certain exception conditions.
The preferred quantum for an exact result is 1; for an inexact result, an exception might be indicated, and the preferred quantum is the smallest.
To illustrate, suppose we convert three binary values containing 17 decimal digits to long decimal
floating-point, with default rounding:
Chapter IX: Floating-Point Data and Operations

693

LG
0,=FD12345678901234560
17 digits
CDGTR 0,0
c(FPR0)=X263D34B9C1E28E56
LG
0,=FD12345678901234565
17 digits
CDGTR 0,0
c(FPR0)=X263D34B9C1E28E56
LG
0,=FD12345678901234569
17 digits
CDGTR 0,0
c(FPR0)=X263D34B9C1E28E57
In the first case, the result is exact because the final decimal digit is zero. The second case is
rounded to the same value because the DFP value lies exactly between two decimal values so the
result has an even low-order digit, and the third is rounded up to the next higher value.
Converting very large binary values does not cause overflow:
LG
0,=X 7 FFFFFFFFFFFFFFF
CDGTR 0,0

Maximum positive value


c(FPR0)=X 6 E45237C836973F6

but because 2 63 1 is 19 digits long, the decimal floating-point result was rounded to 16 decimal
digits.

35.9.2. Convert From DFP To Fixed Binary


The instructions that convert from decimal floating-point to binary integers whose mnemonics
have no suffix have the format shown in Table 343:
opcode

M3

R1

R2

Table 343. Format of Convert to Fixed Binary instructions

The assembler instruction statement format is


mnemonic R1,M3,R2
For the instructions with a suffix A, the instruction format is shown in Table 344:
opcode

M3

M4

R1

R2

Table 344. Format of Convert to Fixed Binary instructions

Their assembler instruction statement format is


mnemonic R1,M3,R2,M4
As noted above, the M 4 field can be used to mask certain exception conditions.
The decimal floating-point operand in the R2 floating-point register is rounded to a binary integer
in the R 1 general register according to the M3 rounding modifier described in Table 335 on page
688.
Figure 441 shows some examples of proper conversions; those with CGXTR instructions use
16-byte extended-precision values that can hold all the digits of the full 19-digit maximum-integer
value.

694

Assembler Language Programming for IBM z System Servers

Version 1.00

LD
CGDTR
LD
CGDTR

0,=DD127
0,B0000,0
0,=DD -3
0,B0000,0

c(GG0)=X000000000000007F
c(GG0)=X FFFFFFFFFFFFFFFD

LD
0,=LD9223372036854775807
2**63-1 = +MaxPos
LD
2,=LD9223372036854775807+8 2**63-1 = +MaxPos
CGXTR 0,B0000,0
c(GG0)=X 7 FFFFFFFFFFFFFFF
LD
0,=LD -9223372036854775808
-2**63 = -MaxNeg
LD
2,=LD -9223372036854775808+8 -2**63 = -MaxNeg
CGXTR 0,B0000,0
c(GG0)=X8000000000000000
Figure 441. Examples of converting decimal floating-point to fixed binary

In each case, the Condition Code is set according to the result, as shown in Table 345:
CC
0
1
2
3

Meaning
Source was zero
Source was less than zero
Source was greater than zero
Special case

Table 345. CC settings for Convert to Fixed instructions

Cases where the decimal floating-point value exceeds the representable range of a 64-bit binary
integer are handled either by causing an invalid operation exception, or (if the exception is masked
off) by setting the CC to 3 and the result to the maximum positive or negative integer, according
to the sign of the decimal floating-point operand.
The following CGXTR instructions each cause an invalid operation exception, but because the
exception is masked off the CC is set to 3 and the results are the default maximum and minimum
integer values.
LFPC
LD
LD
CGXTR

=F 0
0,=LD9223372036854775808
2,=LD9223372036854775808+8
0,B0000,0

Mask off all exceptions


2**63 = +MaxPos+1
Low-order half
c(GG0)=X 7 FFFFFFFFFFFFFFF

LD
0,=LD -9223372036854775809
-2**63-1 = -MaxNeg-1
LD
2,=LD -9223372036854775809+8 Low-order half
CGXTR 0,B0000,0
c(GG0)=X8000000000000000
Figure 442. Examples of converting decimal floating-point to binary integer

Exercises
35.9.1.(3) + Suppose two extended precision decimal floating-point numbers have the value of
the 64-bit maximum positive integer plus 1/2 and the maximum negative integer minus 1/2:
LD
0,=LD9223372036854775807.5
LD
2,=LD9223372036854775807.5+8
CGXTR 0,Mp,0

+MaxPos+1/2
+MaxPos+1/2

LD
0,=LD -9223372036854775808.5
LD
2,=LD -9223372036854775808.5+8
CGXTR 0,Mm,0

-MaxNeg-1/2
-MaxNeg-1/2

For what values of the rounding modifier mask fields Mp and Mm will an invalid operation exception be avoided?
Chapter IX: Floating-Point Data and Operations

695

35.10. Converting Decimal Floating-Point To/From Packed and Zoned Decimal


As you might expect, converting decimal floating-point data to displayable decimal digits is far
simpler than for hexadecimal and binary floating-point data. These instructions make the process
quite simple. None of the instructions change the Condition Code.
The packed decimal operands are in general registers, not in memory.

35.10.1. Convert To/From Signed Packed Decimal


For signed packed decimal operands, use the instructions in Table 346:
Op
B3F3

Mnem
CDSTR

Type
RRE

Instruction
Convert from 64-bit
Signed Packed (Long)

Op
Mnem
B3FB CXSTR

Type
RRE

B3E3

CSDTR

RRF

Convert to 64-bit
Signed Packed (Long)

B3EB CSXTR

RRF

Instruction
Convert from 128-bit
Signed Packed
(Extended)
Convert to 128-bit Signed
Packed (Extended)

Table 346. Decimal floating-point convert to/from signed packed decimal instructions

When converting from packed decimal to decimal floating-point you dont need to worry about
rounding, because 15-digit and 31-digit packed decimal operands in a general register or general
register pair (respectively) can be represented exactly in long and extended formats.
When you convert to packed decimal from decimal floating-point using the CSDTR and CSXTR
instructions, you might want to select the sign code. the instruction format in Table 347 provides
an M 4 field to select the sign code:
opcode

M4

R1

R2

Table 347. Format of Convert to Signed Packed instructions

The M 4 mask uses only a single bit. If M4=0, the sign code of the packed decimal result is X C ,
and if M4=1, the sign code is X F .225
The machine instruction statement operands for converting to packed decimal are written
mnemonic R1,R2,M4
and those for converting from packed decimal are written
mnemonic R1,R2
First, consider converting from signed packed decimal to decimal floating-point:
LG
7,=PL8123456789012345
CDSTR 4,7

c(GG7)=X123456789012345C
c(FPR4)=X2238A395BCF049C5

LG
8,=X1234567890123456
High-order 16 digits
LG
9,=X789012345678901C
Low-order 15 digits, sign
CXSTR 0,8
Convert to extended DFP
c(FPR0,FPR2)=X22080014D2E7078A 395BCF049C5DE08D

Figure 443. Converting signed packed decimal to decimal floating-point

As this example indicates, both operands of the CXSTR instruction must be register pairs.

225

696

Since M 4 is only a single bit, its not really a mask; the other bit positions are reserved.
Assembler Language Programming for IBM z System Servers

Version 1.00

Converting from packed decimal to decimal floating-point is straightforward. Converting in the


other direction, however, is a bit more complex. First, well start with the decimal floating-point
values in Figure 443, and convert them to signed packed decimal.

LD
4,=X2238A395BCF049C5
CSDTR 7,4,B0000

c(FPR4)=DD123456789012345
c(GG7)=X123456789012345C

LD
0,=X22080014D2E7078A
LD
2,=X395BCF049C5DE08D
CXSTR 8,0,B0000
c(GG8,GG9)=X1234567890123456

High-order half
Low-order half
Convert to packed decimal
789012345678901C

Figure 444. Converting decimal floating-point to signed packed decimal

In Figure 444 we started with decimal floating-point values containing 15 and 31 significant digits.
Because long and extended decimal floating-point data can hold 16 and 34 significant digits, these
two instructions will convert only the rightmost 15 and 31 digits to packed decimal, as shown in
Figure 445.
LD
0,=DD1234567890123456 16 significant digits
CSDTR 3,0,B0000
c(GG3)=X234567890123456C

LD
1,=LD1234567890123456789012345678901234 34 digits
LD
3,=LD1234567890123456789012345678901234+8 34 digits
CSXTR 4,1,B0000
Convert to packed decimal
c(GG4,GG5)=X4567890123456789 012345678901234C

Figure 445. Converting decimal floating-point to signed packed decimal

This example shows that one or three high-order digits can be lost when converting from decimal
floating-point to signed packed decimal.
It doesnt matter if the DFP operand is a NaN or infinity; the significand is converted anyway.
For example:
LD
0,=DD ( Inf)
CSDTR 1,0,B0000

c(FPR0)=X7800000000000000
c(GG1)=X000000000000000C

LD
0,=DD ( SNaN)
CSDTR 2,0,B0000

c(FPR0)=X 7 E00000000000000
c(GG2)=X000000000000000C

Be Careful!
When converting decimal floating-point data to signed packed decimal
using the CSDTR instruction, you may lose one high-order digit; and
when using CSXTR, you may lose three high-order digits.
Well see in Section 35.12.4 that the shift-significand instructions let you convert the lost digits.

35.10.2. Convert To/From Unsigned Packed Decimal


The instructions in Table 348 convert decimal floating-point data to unsigned packed decimal
digits in a general register.
Op
B3F2

Mnem
CDUTR

Type
RRE

B3E2

CUDTR

RRE

Instruction
Convert from 64-bit
Unsigned Packed
(Long)
Convert to 64-bit
Unsigned Packed
(Long)

Op
Mnem
B3FA C X U T R

Type
RRE

B3EA C U X T R

RRE

Instruction
Convert from 128-bit
Unsigned Packed
(Extended)
Convert to 128-bit
Unsigned Packed
(Extended)

Table 348. Decimal floating-point convert to/from unsigned packed decimal instructions
Chapter IX: Floating-Point Data and Operations

697

Because no sign code is generated for the unsigned packed decimal results, 16 or 32 digits can be
converted, and no digits are lost for long precision decimal floating-point data. CUXTR, however,
loses the two high-order digits.
CUDTR and CUXTR provide no M 4 operand as do CSDTR and CSXTR, so their machine
instruction statement operand format is R 1,R 2.
Well use the examples as for conversions to signed packed decimal, to see the difference in the
number of generated digits. Figure 446 shows how to convert from unsigned packed decimal to
decimal floating-point.
LG
7,=XL81234567890123456
CDUTR 4,7

c(GG7)=X123456789012345C
c(FPR4)=X263934B9C1E28E56

LG
8,=X1234567890123456
High-order 16 digits
LG
9,=X7890123456789012
Low-order 15 digits, sign
CXUTR 0,8
Convert to extended DFP
c(FPR0,FPR2)=X2208012717782353 4B9C1E28E56F3C12

Figure 446. Converting unsigned packed decimal to decimal floating-point

These examples convert from decimal floating-point to unsigned packed decimal:


LD
4,=DD1234567890123456
CUDTR 7,4

c(FPR4)=X263934B9C1E28E56
c(GG0)=X1234567890123456

LD
0,=LD12345678901234567890123456789012
High half
LD
2,=LD12345678901234567890123456789012+8 Low half
CUXTR 8,0
Convert to packed decimal
c(GG8,GG9)=X1234567890123456 7890123456789012

Figure 447. Converting decimal floating-point to unsigned packed decimal

If we compare Figure 447 to Figure 445, we see that the lack of a sign code lets us generate one
more packed decimal digit in place of the sign code.
Because its easy to determine the sign of a decimal floating-point number, most programs converting decimal floating-point to packed decimal will probably use the unsigned conversions, to
generate the largest possible number of digits.
NaNs and infinity are converted to unsigned packed decimal without causing exceptions:
LD
0,=DD ( Inf)
CUDTR 1,0

c(FPR0)=X7800000000000000
c(GG1)=X0000000000000000

LD
0,=DD ( SNaN)
CUDTR 2,0

c(FPR0)=X 7 E00000000000000
c(GG2)=X0000000000000000

Be Careful!
When converting decimal floating-point data to unsigned packed decimal
using the CUXTR instruction, you may lose two high-order digits.
Well see in Section 35.12.4 on page 707 that the shift-significand instructions let you capture the
lost digits.

35.10.3. Convert To/From Zoned Decimal


The instructions in Table 349 on page 699 convert data between decimal floating-point and
zoned decimal, saving the need to use packed decimal as an intermediate step.

698

Assembler Language Programming for IBM z System Servers

Version 1.00

Op
EDAA

Mnem
CDZT

Type
RSL

Instruction
Convert from Zoned
(LongZoned)

Op
Mnem
EDAB CXZT

Type
RSL

Instruction
Convert from Zoned
(ExtendedZoned)

EDA8

CZDT

RSL

Convert to Zoned
(ZonedLong)

EDA9 CZXT

RSL

Convert to Zoned
(ZonedExtended)

Table 349. Instructions converting between decimal floating-point and zoned decimal

All the instructions have the format shown in Table 350:


opcode

L2

B2

D2

R1

M3

Opcode

Table 350. Format of DFP/zoned decimal conversion instructions

The decimal floating-point operand is in FPR R 1, and the zoned decimal operand is in memory
at the Effective Address of the second operand.
The machine instruction statement format of the instructions is
mnemonic R1,D2(N2,B2),M3
where N 2 is the true number of bytes in the second operand. (Remember from Section 24.2 on
page 369 that you specify the true length in the Assembler Language machine instruction statement, but the CPU uses the encoded length in the machine language instruction, which is one
less.)
Because the decimal floating-point operand is at most 16 or 34 digits long, the CPU requires that
the length of the zoned decimal operand satisfy
0 L2 15 (or 1 N2 16) for Long DFP
0 L2 33 (or 1 N2 34) for Extended DFP
The Convert from Zoned instructions are simpler: the N2 zoned decimal digits at the second
operand are converted to decimal floating-point; the Condition Code is unchanged.
The leftmost bit of the M3 field determines the treatment of a possible sign code in the rightmost
byte of the zoned operand:
If M 3 = B1000, the zoned operand is assumed to have a standard sign code (X A,C,E,F for
+ , (X B,D for ); the decimal floating-point operand is given that sign.
If M 3 = B0000, the zoned operand is assumed to have no sign code, so the sign bit of the
decimal floating-point operand is set to zero to indicate plus. (This is important for numeric
ASCII characters that have zone digit X 3 that would otherwise cause a decimal data exception.)
The preferred quantum of the result is one, meaning that the exponent assigned is set to zero so
the result is treated as an integer.
Figure Figure 448 shows the effect of the two values of the M3 operand:

ZoneA

CDZT 0,ZoneA,B1000
CDZT 0,ZoneA,B0000
- - DC
Z -12345

c(FPR0) = X A2380000000049C5
c(FPR0) = X22380000000049C5
X F1F2F3F4D5

Figure 448. Effect of the mask operand on Convert from Zoned results

The first instruction generates a negative result because M3 = B1000, while the second instruction ignores the sign code in the last zoned byte and returns a positive result.
The Convert to Zoned instructions convert the specified number of rightmost digits of the decimal
floating-point operand to zoned, with the same restrictions on L2 (and N 2).
The bits of the M3 operand control how zone and sign digits are assigned; for convenience, the
bits are designated SZPF from left to right.

Chapter IX: Floating-Point Data and Operations

699

is bit zero of M3: B S... . If S=0, the zoned result does not have a sign, and all zone digits
are determined by the Z bit. If S=1, the zoned operand has a sign; its form is controlled by
the P and F bits.

is bit one of M3: B . Z.. . If Z=0, the zone fields of the result are X F ; if Z=1, the zone
fields are X 3 . If S=1, the final zone (the sign) depends on the P and F bits.

is bit two of M3: B . . P. . If S=0, the P bit is ignored (assumed to be zero) and the sign
code depends on the Z bit. Otherwise, if P=0, the sign code for non-negative results is set
to X F ; if P=1, the plus sign code is X C .

is bit three of M3: B . . . F . If S=0, the F bit is ignored (assumed to be zero). Otherwise, if
F=0, nothing happens. If F=1 and the absolute value of the zoned result is zero, the sign
code is set to a plus code as determined by the P bit. (This is so that the zoned result cant
be a negative zero.)

The field allocated for the zoned result may be too short for all the significant digits of the
decimal floating-point operand. Because only the requested number of rightmost digits are converted, its possible that significant digits could be lost. (This is one reason why the F bit tests for
a zero result.)
The Convert to Zoned instructions set the Condition Code, as shown in 351:
CC
0
1
2
3

Meaning
Source operand is zero
Source operand is less than zero
Source operand is greater than zero
Source operand is infinity, QNaN, SNaN, or a
partial result was generated

Table 351. Condition Code settings for Convert to Zoned

To illustrate, suppose we convert these DFP operands to zoned:

ZoneB
ZoneC
ZoneD

LD
CZDT
CZDT
CZDT
CZDT

0,=DD -12345
0,ZoneB,B0000
0,ZoneB,B1000
0,ZoneB,B0100
0,ZoneB,B1100

Result
Result
Result
Result

LD
CZDT
CZDT
CZDT

0,=DD+12345
0,ZoneC,B1010
0,ZoneC,B0000
0,ZoneD,B0000

Result = X F0F1F2F3F4F5 , CC=2


Result = X F0F1F2F3F4F5 , CC=2
Result = X F2F3F4F5 ,
CC=3

LD
CZDT
CZDT
- - DS
DS
DS

0,=DD -12000000
0,ZoneD,B1000
0,ZoneD,B1001

Result = X F0F0F0D0 ,
Result = X F0F0F0C0 ,

=
=
=
=

X F0F1F2F3F4F5 ,
X F0F1F2F3F4D5 ,
X303132333435,
X3031323334D5 ,

CC=1
CC=1
CC=1
CC=1

CC=3
CC=3

ZL6
ZL6
ZL4

Figure 449. Examples of converting decimal floating-point to zoned

Most of the results in Figure 449 are what you might expect, but some may look unusual:
In the first group, the fourth CZDT instructions M 3 digit is B1100: the S bit means the
result should be signed, and because the result is negative, the Z, P, and F bits dont apply.
In the second group, the first CZDT instructions M 3 digit is B1010: the S bit means the
result should be signed, the Z bit is zero so the results zone is X F independent of the P and
F bits. The third CZDT instruction sets the CC=3 because a partial result was generated.
In the third group, both CZDT instruction set CC=3 because the result is partial.

700

Assembler Language Programming for IBM z System Servers

Version 1.00

Exercises
35.10.1.(2) + If you are converting decimal floating-point data to signed packed decimal, what
instructions can you use to test beforehand whether or not any high-order digits might be lost?
35.10.2.(2) Why do CUDTR and CUXTR need no M 4 operand?
35.10.3.(2) + In Figure 443 on page 696, what is the LeftMost Digit (LMD) of the decimal
floating-point result in (FPR0,FPR2)? Why?
35.10.4.(2) Can a source operand of CZDT be zero and cause Condition Code 3? If yes, give an
example; if not, explain why.
35.10.5.(3) + Make a table showing the effect of all possible combinations of the SZPF bits in
the M 3 field of a CZDT instruction.

35.11. Decimal Floating-Point Load Operations


This section describes four groups of instructions; all the instructions are register-register operations.

Load
Load
Load
Load

and Test, plus Load Complement, Load Negative, and Load Positive
Floating-Point Integer
Lengthened
Rounded

35.11.1. Load and Test, Complement, Negative, and Positive


The instructions in Tables 352 and 354 have operand format R1,R 2.
Op
B3D6

Mnem
LTDTR

Type
RRE

Instruction
Load and Test (Long)

Op
Mnem
B3DE L T X T R

Type
RRE

Instruction
Load and Test
(Extended)

Table 352. Decimal floating-point Load and Test instructions

If the source operand is a QNaN, the CC is set to 3; if it is a SNaN, an invalid operation exception occurs; if masked off, the corresponding QNaN is placed in the first-operand location.
Table 353 shows the Condition Code setting.
CC
0
1
2
3

Meaning
Operand is zero
Operand is less than zero
Operand is greater than zero
Operand is a NaN

Table 353. CC setting after D F P Load and Test instructions

The three instructions in Table 354 set the sign bit as indicated by the instruction name.
Op
B373
B370

Mnem
Type Instruction
L C D F R R R E Load Complement (Long)
L P D F R R R E Load Positive (Long)

Op
Mnem
Type Instruction
B371 L N D F R R R E Load Negative (Long)

Table 354. Instructions copying/complementing data between FPRs

Chapter IX: Floating-Point Data and Operations

701

These instructions can be used for both decimal and binary floating-point operands: they are typeinsensitive and dont care if the operand is a NaN or infinity. Unlike the corresponding
instructions for hexadecimal floating-point operands, they dont change the Condition Code.
Some examples of these instructions, showing that only the sign bit changes:
LD
LCDFR
LNDFR
LPDFR

0,=DD -21.43
1,0
2,1
3,2

c(FPR0)
c(FPR1)
c(FPR2)
c(FPR3)

=
=
=
=

X A2300000000008C3
X22300000000008C3
X A2300000000008C3
X22300000000008C3

35.11.2. Load Floating-Point Integer


The two Load Floating-Point Integer instructions in Table 355 convert a decimal floating-point
second operand to an integer-valued first operand in the same format. The CC is unchanged.
Op
B3D7

Mnem
FIDTR

Type
RRF

Instruction
Load Floating-Point
Integer (Long)

Op
Mnem
B3DF F I X T R

Type
RRF

Instruction
Load Floating-Point
Integer (Extended)

Table 355. Decimal floating-point Load Floating-point Integer instructions

The instructions have two mask fields, M3 and M 4, shown in Table 356:
opcode

M3

M4

R1

R2

Table 356. Format of Load F P Integer instructions

The machine instruction statement format specifies the operands in this order:
mnemonic R1,M3,R2,M4
The M 3 mask controls rounding of the delivered operand; its possible values are given in
Table 335 on page 688.
The M 4 mask controls recognition of the inexact exception. If the value of the result is different
from the value of the second operand it is inexact; then, if bit 1 (B0100) of M4 is one, no inexact
exception will occur.
If the second operand is a QNaN, so is the result. If the second operand is a SNaN, an invalid
operation exception occurs; if masked off, the corresponding QNaN is the result. To illustrate:
LD
6,=DD 7 . 2
FIDTR 2,B1000,6,4

Fractional operand X2234000000000072


No exception:
X2238000000000007

LD
6,=DD 7 . 2
FIDTR 2,B1000,6,0

Same fractional operand


Same result, inexact exception

35.11.3. Load Lengthened


Table 357 lists the two instructions that convert a decimal floating-point operand to a longer
format. They can be used to convert from the short storage format to long or extended format
for computations.
Because a longer format has greater precision and range, no rounding is needed. only infinity and
SNaNs need special treatment; QNaNs are converted to the longer format with the payload (if
any) extended with zeros on the left. Neither instruction changes the CC.
Op
B3D4

Mnem
LDETR

Type
RRF

Instruction
Load Lengthened
(Short to Long)

Op
Mnem
B3DC L X D T R

Table 357. Decimal floating-point Load Lengthened instructions

702

Assembler Language Programming for IBM z System Servers

Version 1.00

Type
RRF

Instruction
Load Lengthened (Long
to Extended)

They have the instruction format illustrated in Table 343 on page 694, and machine instruction
statement format
mnemonic R1,R2,M4
The second operand is extended to the next longer format, and placed in the first operand register.
Table 358 shows how the M4 mask controls the treatment of an infinity or SNaN.
Operand
Infinity

SNaN

M4
0
8
0
8

Action
Canonical infinity for the target format
Source infinity with payload padded with zeros on the left
Invalid operation exception; if masked, deliver corresponding
QNaN with payload padded with zeros on the left
Source SNaN with payload padded with zeros on the left

Table 358. Load Lengthened special operand control mask

For finite values, the M4 mask makes no difference:

LE
2,=ED ( QNaN)
LDETR 4,2,0

Short source operand X 7 C000000


Long result X 7 C00000000000000

LE
2,=ED123.4567
LDETR 4,2,0

Short source operand X2614D2E7


Long result X222800000014D2E7

LD
1,=DD7654.321
Long operand X222C0000007D51A1
LXDTR 5,1,0
Extended format
c(FPR5,FPR7)= X2207400000000000 00000000007D51A1

35.11.4. Load Rounded


The two Load Rounded instructions in Table 359 convert an operand to the next shorter format:
extended to long, and long to short. Because the shorter format has less precision and narrower
range, the M3 rounding mask field is provided in the instruction, as shown in Table 335 on
page 688. If the source operand is finite, these instructions can indicate underflow, overflow, and
inexact exceptions.
Neither instruction changes the CC.
Op
B3D5

Mnem
LEDTR

Type
RRF

Instruction
Load Rounded (Long
to Short)

Op

Mnem

B3DD L D X T R

Type
RRF

Instruction
Load Rounded
(Extended to Long)

Table 359. Decimal floating-point rounding/lengthening instructions

If the source operands range causes an overflow or underflow condition when rounded to the
shorter format, an interruption will occur if the mask bits in the Floating-Point Control Register
are one. If the appropriate mask bit is zero, the exponent is scaled to be in range.
The B1000 bit in the M4 mask controls the treatment of infinity and SNaNs:
If the source operand is infinity and the M4 bit is zero, the result is a canonical infinity; and if
the M 4 bit is one, trailing exponent bits are set to zero and the payload is shortened by
removing high-order digits.
If the source operand is a SNaN and the M4 bit is zero, an invalid operation condition occurs;
if the interruption is masked off, the result is the corresponding QNaN with shortened
payload. If the M4 bit is one, the invalid operation condition is suppressed and the result is a
canonicalized SNaN with shortened payload.
Note that LDETR and LEDTR are the only DFP instructions that operate on short DFP operands.
(TDCET tests a short operand, but doesnt operate on it.) Arithmetic on short-format data requires
Chapter IX: Floating-Point Data and Operations

703

lengthening the source operands and rounding the result back to short format. Suppose we need
the short-format quotient of 24 7:
LE
LDETR
LE
LDETR
DDTR
LEDTR
STE

2,=ED 2 4
2,2,B0000
6,=ED 7
6,6,B0000
2,2,6
2,B0000,2,0
2,Quotient

Load first operand


X22500024
Lengthen it X2238000000000024
Load second operand X22500007
Lengthen it X2238000000000007
Long quotient X 2 DFE28BC628BC629
Round to short format X 2 DF8A2F1
Store the short result

Figure 450. DFP arithmetic with short operands

Both the division and rounding instructions indicate an inexact result; 24 7 is not a finite fraction.

Exercises
35.11.1.(3) Suppose the source operand of a Load Rounded instruction is a SNaN. Show the
possible combinations of M4 mask bit and FPCR invalid-operation mask, and the delivered
result for each case.
35.11.2.(1) With reference to Figure 450, what is the true value of 24 7?
35.11.3.(1) + Table 354 has no instructions for extended precision operands. How then could
you do a Load Complement of an extended precision operand?
35.11.4.(2) Under what circumstances would you use a Test Data Class instruction in preference to a Load and Test instruction?

35.12. Decimal Floating-Point Miscellaneous Operations (*)


This subsection describes some operations of (possibly) less interest or less frequent use:

Set Decimal Rounding Mode


Extract and Insert Biased Exponent
Extract Significance
Shift Coefficient Left and Right
Quantize
Reround
Test Data Group

35.12.1. Set Decimal Rounding Mode


The SRNMT instruction in Table 360 sets the DFP rounding mode.
Op
B2B9

Mnem
SRNMT

Type
S

Instruction
Set Decimal Rounding
Mode

Op

Mnem

Type

Instruction

Table 360. Decimal floating-point Set Rounding Mode instruction

The machine instruction statement is written with a single operand:


SRNMT D2(B2)
The rightmost three bits of the Effective Address are placed in the FPCRs rightmost byte, in the
bits indicated by DRM in Figure 451. The CC is unchanged.

704

Assembler Language Programming for IBM z System Servers

Version 1.00

Comparing this figure to Figure 407 on page 636, the only difference is the presence of the q
mask and flag bits (for the quantum exception), and the three added DRM bits for the decimal
rounding mode.

Data Excep n Rounding

Mask Bits
Flag Bits Code (DXC) Mode Bits


i z o u x q 0 0i z o u x q 0 0i z o u x y 0 00 DRM 0 0 BRM

8
8
8
8
Figure 451. Floating-Point Control Register showing Decimal Rounding Mode bits

The rightmost 2 bits of the DRM field have the same meaning as for the Binary Rounding Mode
(BRM):
BRM/DRM
B000
B001
B010
B011

Rounding Action
To nearest (default; ties round to even),
Toward zero (truncate; chop)
Up (toward + )
Down (toward )

There are four additional decimal floating-point rounding modes when the leftmost DRM bit is 1:
DRM
B100
B101
B110
B111

Rounding Action
To nearest, with ties away from 0 (instead of to even)
To nearest, with ties toward 0
Round away from 0
Round to prepare for shorter precision

For example, to set the decimal rounding mode to the default, you could execute
SRNMT B000

Set DRM to unbiased round to nearest

35.12.2. Extract and Insert Biased Exponent


Because the representation of the true biased exponent of a DFP number is so complex, z System
provides the instructions listed in Table 361 to extract and to insert its value.
Op
B3E5

Mnem
EEDTR

Type
RRE

B3F6

IEDTR

RRF

Instruction
Extract Biased Exponent (Long)
Insert Biased Exponent
(Long)

Op
Mnem
B3ED EEXTR

Type
RRE

B3FE IEXTR

RRF

Instruction
Extract Biased Exponent
(Extended)
Insert Biased Exponent
(Extended)

Table 361. Decimal floating-point Insert/Extract Biased Exponent instructions

None of the instructions change the Condition Code.


Machine instruction statements for the extract instructions have two operands:
EEDTR R1,R2
where the R 2 floating-point register holds a decimal floating-point number and its biased exponent is placed in the general register specified by R1. For example:
LD
5,=DD 2 . 5
EEDTR 3,5
AHI 3,-398
*

Long DFP operand X2234000000000025


Result in GG3 = X18D = 397
Remove exponent bias
c(GG3) = -1, the unbiased exponent

Figure 452. Example of extracting D F P biased exponent

The value in FPR5 is 2.510 1; the exponent bias for a long DFP number is 398, so the true
exponent is 397 398 = 1, as expected.
Chapter IX: Floating-Point Data and Operations

705

For special values, a negative value is placed in the R1 general register, as shown in Table 362:
DFP operand
Infinity
QNaN
SNaN

Binary result
1
2
3

Table 362. Extracted Biased Exponent for D F P special


values

Thus, the IEXTR and IEDTR extract instructions can be applied to any DFP operand.
The instructions that insert a biased exponent have three operands:
IEDTR R1,R3,R2
where the source DFP operand is in floating-point register R3, the new biased exponent is in
general register R2, and the result is placed in floating-point register R1. For example:
LD
5,=DD 2 . 5
LG
9,=FD399
IEDTR 2,5,9

Source operand = X2234000000000025


New biased exponent
Insert; result = X223C000000000025

Figure 453. Example of inserting a biased D F P exponent

In this case, the significand is unchanged, and the new biased exponent (399) means that the new
true exponent is 399 398 = + 1, so the value of the number in FPR2 is 2510 + 1, or 250.
Thus, the Insert Biased Exponent instructions provide an easy way to multiply or divide finite
numbers by a power of 10, without changing significance.
Special values are treated in a way much like that for the extract instructions. The results are illustrated in Table 363, where CMax represents the largest characteristic (biased exponent) value.
R2 operand
Value > CMax
0 Value CMax
Value = 1
Value = 2
Value = 3
Value 4

Finite
QNaN
Finite
Infinity
QNaN
SNaN
QNaN

DFP source operand in R3


Infinity
QNaN
QNaN
QNaN
Finite
Finite
Infinity
Infinity
QNaN
QNaN
SNaN
SNaN
QNaN
QNaN

SNaN
QNaN
Finite
Infinity
QNaN
SNaN
QNaN

Table 363. DFP Insert Biased Exponent results

35.12.3. Extract Significance


The instructions in Table 364 let you determine the number of significant digits in a DFP
operand. Neither instruction changes the Condition Code.
Op
B3E7

Mnem
ESDTR

Type
RRE

Instruction
Extract Significance
(Long)

Op
Mnem
B3EF ESXTR

Type
RRE

Instruction
Extract Significance
(Extended)

Table 364. Decimal floating-point Extract Significance instructions

The second operand of the machine instruction statement is the DFP number, and the result is
placed in the R1 general register. For example:

706

Assembler Language Programming for IBM z System Servers

Version 1.00

LD
ESDTR
LD
ESDTR
LD
ESDTR

0,=DD 2 . 5
0,0
1,=DD 2 . 5 E10
1,1
2,=DD2.5000000
2,2

2 digits, value = X2234000000000025


Result = 2
2 digits, value = X225C000000000025
Result = 2
8 digits, value = X221C000002500000
Result = 8

Figure 454. Examples of D F P Extract Significance instructions

Special values return zero (for zeros), 1 for infinities, 2 for QNaNs, and 3 for SNaNs.

35.12.4. Shift Significand Left/Right


Table 365 list the four instructions for shifting decimal floating-point operands left and right.
Op
ED40

Mnem
SLDT

Type
RXF

ED41

SRDT

RXF

Instruction
Shift Significand Left
(Long)
Shift Significand Right
(Long)

Op
Mnem
ED48 SLXT

Type
RXF

ED49 SRXT

RXF

Instruction
Shift Significand Left
(Extended)
Shift Significand Right
(Extended)

Table 365. Decimal floating-point Shift Significand instructions

All four leave the CC unchanged, and cause no exceptions.


These shifts are similar to the logical shift instructions for binary data in the general registers:
digits shifted off either end are lost, and zeros are inserted into positions vacated by the shift.
Exponents are unchanged, and the results are not rounded.
The instruction format 226 is illustrated in Table 366:
opcode

R3

X2

B2

D2

R1

opcode

Table 366. Format of D F P shift instructions

The operands of the assembler instruction statements have format R1,R 3,D 2(X 2,B 2), where the
source operand is in FPR R 3, the result is placed in FPR R1, and the shift amount is determined
by the rightmost 6 bits of the Effective Address. For example, shifting right by one digit effectively
divides the source operand by 10, truncating the lost digits:
LD
0,=DD1000000
SRDT 0,0,1

Source = X2238000000100000
Result = X2238000000020000

LD
0,=DD1234567
SRDT 0,0,1

Source = X223800000014D2E7
Result = X2238000000028E56

Left shifts are similar, except that the high-order digit of the significand moves into the Combination Field; the previous occupant is lost. For example:

LD
0,=DD1000000000 Source = X2238000040000000
SLDT 0,0,6
Result = X2638000000000000
Leftmost digit now in Combo Field

LD
0,=DD1000000000 Source = X2238000040000000
SLDT 0,0,7
Result = X2238000000000000
Zero significand, all digits lost

In the first case, the significant digit is shifted into the Combination Field, and in the second case
it is shifted completely out leaving a zero significand with exponent + 9.

226

This format is unusual in placing the R3 operand in the position where most instructions put the R 1 operand.
Chapter IX: Floating-Point Data and Operations

707

Because the exponent is not changed, you might consider these instructions as a way to multiply
or divide by 10; but be cautious. The significance of the operand is changed depending on the
direction and amount of the shift.
The significands of infinity, SNaN, and QNaN are shifted without regard to the type of operand,
and without causing any exceptions.
With these shift instructions, we can now convert all 34 digits of an extended decimal floatingpoint value to packed decimal, using instructions like those in Figure 455.

Packed

LD
LD
CSXTR
STMG
SRXT
CUXTR
STH
- - DS

0,=LD1234567890123456789012345678901234 34 digits
2,=LD1234567890123456789012345678901234+8
4,0,0
Convert 31 signed digits to (GG3,GG4)
4,5,Packed+2
Store low-order 31 digits and sign
0,0,31
Shift, keeping 3 high-order digits
4,0
Convert 3 unsigned digits
5,Packed
Store remaining 3 digits
XL18

34 Packed digits and sign

Figure 455. Converting an extended decimal floating-point value to packed decimal

The result at Packed is X01234567890123456789012345678901234C . Because the symbol Packed


may not be aligned on a halfword preceding a doubleword boundary, the Assembler may diagnose a possibly unfavorable operand alignment; such messages can be avoided by preceding the
DS instruction with
ORG

*+2,8,-2

Halfword preceding doubleword

You can consult the High Level Assembler Language Reference for details.

35.12.5. Quantize
The quantize instructions in Table 367 do a very simple operation: they make one operand have
the same decimal point alignment as another.
Op
B3F5

Mnem
QADTR

Type
RRF

Instruction
Quantize (Long)

Op
Mnem
B3FD QAXTR

Type
RRF

Instruction
Quantize (Extended)

Table 367. Decimal floating-point Quantize instructions

The instruction format in Table 368 has four operands:


opcode

R3

M4

R1

R2

Table 368. Format of decimal floating-point Quantize instructions

and the assembler instruction statement is written


QADTR R1,R3,R2,M4
The source operand is in FPR R 3 and the result is placed in FPR R1; the operand in R 2 (the
quantizing operand) provides the quantum to be assigned to the R 3 operand. The M 4
rounding mask controls the rounding of the result, and takes the values listed in Table 335 on
page 688. The Condition Code is unchanged.
The idea is to make the result have the same exponent (and quantum) as the R2 operand, preserving the value of the R3 operand to the greatest possible extent.
For example, suppose we have two values, 12789 (12789100) and 12.789 (1278910 3).
A
B

708

DC
DC

DD12789
DD12789E-3

Generates X2238000000004BCF
Generates X222C000000004BCF

Assembler Language Programming for IBM z System Servers

Version 1.00

Both have the same significand, 12789, but their exponents differ by 3. Now, suppose we want to
quantize A to have the same quantum/exponent as B, while preserving the value of A.
LD
0,A
LD
2,B
QADTR 4,0,2,B1000

c(FPR0) = X2238000000004BCF
c(FPR2) = X222C000000004BCF
c(FPR4) = X222C0000012F3C00=12789000

The result in FPR4 has the same quantum/exponent as B, but the significand 12789000 has effectively been shifted left three digits and is now larger by 1000. Because the result has Bs exponent
( 3), its value is 12789000.10 3, the same as the value of A.
Now, consider quantizing B to have the same quantum/exponent as A.
LD
0,A
LD
2,B
QADTR 4,2,0,B1000

c(FPR0) = X2238000000004BCF
c(FPR2) = X222C000000004BCF
c(FPR4) = X2238000000000013=13

Because the result in FPR4 must have the same quantum as A, the significand of B must effectively be shifted right by three digits. The rounding mask causes 12.789 to be rounded to 13100.
Infinity as either the source or quantizing operand produces an invalid operation exception; if
masked off the result is a canonical QNaN:
LD
LD
QADTR
QADTR

0,A
2,=DD ( Inf)
4,0,2,B0000
6,2,0,B0000

Finite value in FPR0


Infinity in FPR2
Quantize A with infinity; c(FPR4) = QNaN
Quantize infinity with A; c(FPR6) = QNaN

Quantizing with QNaNs always produces QNaNs. Quantizing with SNaNs produces an invalid
operation exception; if masked off, the result is the corresponding QNaN.
These examples illustrate the rules for quantizing operations:
1. If the exponent of the result is being decreased (as in the first example), and the result does
not have more digits than supported by the operand format, the result has the same value as
the source operand. But if the result would have more digits than supported, an invalid operation is signaled; if masked off, the result is a default QNaN.
For example:
LD
0,A
LD
2,=DD12789E-12
QADTR 4,0,2,B1000

Source operand = X2238000000004BCF=12789


Second operand = X2208000000004BCF
Invalid operation

If the quantum/exponent of the result in FPR4 were to be the same as the second operands,
the significand of A would have to be shifted left 12 digits, giving 12789000000000000. But
this is 17 digits long, too many digits for a long decimal floating-point operand.
2. If the exponent of the result is being increased (as in the second example), the result is
rounded according to the M 4 rounding modifier. This can possibly generate an inexact exception if the value of the result is different from the value of the source operand. A zero value
with nonzero exponent can be generated.
3. If the source or quantizing operand is infinity, the result is a canonical infinity.
Because the exponent of the result is the same as that of the second (quantizing) operand, no
overflow or underflow occurs. A finite result always has the requested quantum/exponent.
To summarize the exception conditions for finite operands:
If the requested quantum/exponent (from the quantizing operand) is smaller than the quantum
of the source operand, the only possible exception is an invalid operation exception that might
occur if the significand would have too many digits.
If the requested quantum/exponent (from the quantizing operand) is greater than the quantum
of the source operand, the only possible exception is an inexact exception that might occur if
nonzero digits were lost.

Chapter IX: Floating-Point Data and Operations

709

Heres a practical example using a quantize instruction. Suppose you must calculate the final
price of an item costing $923.85 after adding tax of 8.25 percent. You would probably start with
something like this:

Price
Tax
Cost

LD
LD
MDTR
STD
- - DC
DC
DS

0,Price
2,Tax
0,2,0
0,Cost

Get item price (923.85)


Load tax rate (1.0825)
Calculate price+tax (1000.067625)
Store final cost (1000.067625)

DD923.85
DD1.0825
DD

Item price
Tax rate + 1 for price
Calculated item cost

Figure 456. Calculate price plus tax

The product was calculated by the MDTR instruction to 16 digits, and rounded according to the
current rounding mode. But you will want to display the cost with only two decimal places, as
$1000.07; because its important to avoid double rounding, how should you proceed?
First, calculate the product without rounding, by setting the Decimal Rounding Mode to prepare
for shorter precision:
SRNMT 7

Set rounding mode to B111

This rounding mode selects the result of the MDTR instruction with the smaller magnitude,
unless the rounding digit is 0 or 5, when the result with the largest magnitude is chosen.
The calculated result has too many digits, so we must round the result to two decimal digits. But
since we dont know how many digits are to the left of the decimal point, we can use a quantize
operation. We know that the original price had two decimal digits, so we can use it as the quantizing operand:
SRNMT
LD
LD
MDTR
QADTR
STD
- - -

7
4,Price
2,Tax
2,2,4
0,2,4,B1100
0,Cost

Set rounding mode to B111


Item price (923.85) in FPR4
Tax rate (1.0825) in FPR2
Price+tax (1000.067625) in FPR2
Quantize to 2 decimal digits
Store final cost (1000.07)
Convert and format for display

Figure 457. Correctly rounding a cost to two decimal digits

The rounding mask (12) of the QADTR instruction rounds to nearest with ties away from zero;
this is the familiar decimal rounding used for many business calculations.

35.12.6. Reround
The instructions in Table 369 perform a reround operation. In effect, rerounding simply changes
the number of significant digits.
Op
B3F7

Mnem
RRDTR

Type
RRF

Instruction
Reround (Long)

Op
Mnem
B3FF R R X T R

Type
RRF

Instruction
Reround (Extended)

Table 369. Decimal floating-point Reround instructions

The instruction format is shown in Table 368, and assembler instruction statements are written as
shown following that table. Neither instruction changes the Condition Code.
These instructions let you simulate a DFP operation with a different precision from any supported format, and with the effect of a single rounding. You start by specifying Round to
prepare for shorter precision in the operation, and then you follow that with the desired
rounding method in the reround instruction.
The reround instructions work like this:

710

Assembler Language Programming for IBM z System Servers

Version 1.00

The desired significance is an unsigned integer in GPR R2.


The operand in FPR R 3 is rounded to the significance specified in GPR R2, and the result is
placed in FPR R 1.
If the requested significance is less than or equal to the significance of the third operand, it is
placed unchanged in R1.
If the requested significance is greater than the significance of the third operand, it is rounded
to the requested significance using the rounding mask specified by the M4 operand.
If the instruction cant represent the result to the requested significance, or if the source
operand is a SNaN or infinity, an invalid operation is signaled. If the exception is disabled, the
delivered result is a default QNaN.
As with other operations, if the result differs in value from the source operand in R3, an
inexact exception is signaled.
These instructions may seem strange: you already have rounding options for all the arithmetic
operations, so why would you want to use a reround instruction?
Suppose you are offering to do some work, and you calculate your total cost as $1783. You probably prefer to quote a slightly larger rounder number, such as $1800. You can do this with a
reround instruction:
LD
LA
RRDTR
SLDT
- - -

4,=DD1783
5,2
6,4,5,B1110
6,6,2

Calculated total cost


2 significant digits
Round to 2 digits, away from zero
Shift left 2 digits
Convert result to printable form

Figure 458. Example of a reround instruction

and the result in FPR6 is 1800, the value to be quoted.


This example works for a total cost with at most 4 digits, but you would like to use it for larger
values. Supposing that you still want to quote values with two low-order zero digits, you can
modify the example in Figure 458:
Final0s Equ
LD
ESDTR
AHI
RRDTR
SLDT
- - -

2
4,=DD1783333
5,4
5,-Final0s
6,4,5,B1110
0,6,Final0s

Calculated total cost = $1,783,333


Extract its significance into GR5
Reduce by number of final zeros
Round to to specified significance
Compensate for digits removed
Convert to printable format

Figure 459. Example of rerounding arbitrary amounts

Because we have rounded away from zero, the result in FPR0 is 1783400. (For large values like
this you would probably want to set Final0s to 3, to round to thousands.)
Because the reround instructions can round longer operands to shorter, the Assembler supports a
round for reround modifier. These 17-digit constants have an even final digit and rounding
digits 4, 5, and 6. You can see that the R15 rounding option leaves the final digit unchanged.

Chapter IX: Floating-Point Data and Operations

711

DC
DC
DC

DD12345678901234564R8
DD12345678901234565R8
DD12345678901234566R8

Generates X263D34B9C1E28E56
Generates X263D34B9C1E28E56
Generates X263D34B9C1E28E57

DC
DC
DC

DD12345678901234564R15 Generates X263D34B9C1E28E56


DD12345678901234565R15 Generates X263D34B9C1E28E56
DD12345678901234566R15 Generates X263D34B9C1E28E56

DC
DC
DC

DD12345678901234574R8
DD12345678901234575R8
DD12345678901234576R8

DC
DC
DC

DD12345678901234574R15 Generates X263D34B9C1E28E57


DD12345678901234575R15 Generates X263D34B9C1E28E57
DD12345678901234576R15 Generates X263D34B9C1E28E57

Generates X263D34B9C1E28E57
Generates X263D34B9C1E28E58
Generates X263D34B9C1E28E58

Figure 460. Examples of assembled D F P constants using rounding for reround

These constants are now prepared for rerounding if desired.227

35.12.7. Decimal Floating-Point Data Groups (*)


You may find in evaluating a complex expression that you need to do parts of the calculation in a
longer format, and want to know whether the result will have the same value and quantum as if
the calculation had been done in the shorter format. The Test Data Group instructions in Table
370 provide this information.
The instructions used to test the data group of an operand are shown in Table 370:
Op
ED51
ED59

Mnem
TDGET
TDGXT

Type
RXE
RXE

Instruction
Test Data Group (Short)
Test Data Group
(Extended)

Op
Mnem
ED55 T D G D T

Type
RXE

Instruction
Test Data Group (Long)

Table 370. Decimal floating-point Test Data Group instructions

Like the Test Data Class instructions in Section 35.4 on page 679, you can test the properties of
an operand without causing any exceptions. The assembler instruction statement is written
mnemonic R1,D2(X2,B2)
The rightmost 12 bits of the second operands Effective Address test the operand in R1. Using
the same bit numbering as in Table 322, the tested groups are shown in Table 371.
+
sign
52
54
56
58
60
62

sign
53
55
57
59
61
63

Group
Zero with non-extreme exponent
Zero with extreme exponent
Normal or subnormal with extreme exponent
Normal with non-extreme exponent and zero leftmost digit
Normal with non-extreme exponent and nonzero leftmost digit
Infinity or NaN

Table 371. Test Data Group second-operand bits

If a 1-bit in the Effective Address matches one of the properties in the table, the Condition Code
is set to 1; otherwise, it is set to 0.

227

712

Most applications would probably define separate constants of the required length, rather than rounding longer ones.
Assembler Language Programming for IBM z System Servers

Version 1.00

The main use of these instructions is checking an operand to verify it has these properties:

its value is finite,


its exponent is not extreme (neither maximum nor minimum),
its leftmost significant digit is zero,
calculating the operand in a wider format would have produced the same value and quantum.

If the result satisfies these conditions, it is said to be safe.


For example, suppose you multiply the number 100000000105 by itself in long and extended
arithmetic. Because it has 9 significant digits, the extended precision product has 17 significant
digits:
LD
0,=LD100000000E5
LD
2,=LD100000000E5+8
MXTR 0,0,0

c(FPR0)=X2209400000000000
c(FPR2)=X0000000008000000
Form extended product

The result in (FPR0,FPR2) is X220A800000000000 0040000000000000 and the exponent is 10.


When we form the same product in long precision:
LD
0,=DD100000000E5
MDTR 0,0,0

c(FPR0)=X224C000008000000
c(FPR0)=X2664000000000000

where the most significant digit is also the leftmost digit, and the exponent is 11. If we test the
data group of this result:
TDGDT 0,B000000001100

Test normal value, nonzero LMD

the Condition Code is set to 1, indicating that this would not be a safe result. The value of the
result is the same, but the exponents (and therefore quanta) were different.

Exercises
35.12.1.(2) Assuming you start with the same operand in FPR2 for each shift instruction, what
will be the result of extracting the significance of the result after executing each of these
instructions?

(a)
(b)
(c)
(d)
(e)

LD
- - SLDT
SLDT
SRDT
SLDT
SRDT

2,=DD12340000E3

Initial value for each shift

2,2,0
2,2,3
2,2,6
2,2,10
2,2,8

35.12.2.(2) In Figure 454, it appears that the third DFP operand (X221C000002500000 ) has
only seven significant digits, but the result of extracting its significance is 8. Why are they different?
35.12.3.(2) The shift instructions effectively multiply or divide the source operand by a power of
10. Why or why not use them in place of the regular multiply and divide instructions?
35.12.4.(2) Give an example showing how a quantize operation can generate a non-canonical
zero, a zero result with nonzero exponent.
35.12.5.(1) + In Figure 455 on page 708, why was the symbol Packed not defined as PL18?

Chapter IX: Floating-Point Data and Operations

713

35.13. Example of a Decimal Floating-Point Business Computation


Well repeat the simple business computation that used packed decimal arithmetic in Section
29.11 on page 517, now using decimal floating-point arithmetic.
This is the situation: we suppose a wholesaler and a retailer complete an order.
1. The retailer orders from the wholesaler 60 high-tech widgets at $74.65 each.
(60$74.65 = $4479.00)
2. For this large order, the wholesaler discounts the price by 4.7%.
($4479.000.047 = $210.513, so the discounted price is $4479.00 $210.51 = $4268.49)
3. The wholesaler adds 9.75% local sales tax, and a $4.00 per-item shipping charge.
(4268.491.0975 = 4684.67; the shipping charge is 60$4.00 = $240.00, so the total is
$4684.67 + $240.00 = $4924.67.)
4. The retailers pre-payment of $1000.00 is deducted. The result is the wholesalers bill to the
retailer.
($4294.67 $1000.00 = $3294.67)
Then, the retailer calculates his necessary markup and the sale price:
5. The retailer calculates his base cost for each item.
($4294.67/60 = $82.07785 or $82.08)
6. He then applies his retail markup (about 37%), adjusted to a sale cost just below one dollar.
(The markup is $82.081.37 = $112.4496 or $112.45, and the adjustment is
$0.54 + $112.45 = $112.99)
7. Each item a customer buys must include 9.25% sales tax and a $7.50 recycling fee.
(The sales tax is $112.991.0925 = $123.44; adding the recycling fee gives the final customer
cost: $123.44 + $7.50 = $130.94)
8. The result is the final cost per item to the customer.
9. The retailers gross profit per item is (sale cost) (base cost).
($112.99 $82.08 = $30.91. The percent gross profit is $30.91/$82.08 = 0.376 or 38%)

35.13.1. The Wholesalers Calculation


We will use long decimal floating-point values. Because all arithmetic is done in the floatingpoint registers, we wont define constants with names, but use literals with the same values as in
Section 29.11.1.
The values in the comments fields show the value of each operand as a decimal floating-point
number.
LD
LD
MDTR
LD
MDTR
SDTR
LD
MDTR
LD
MDTR
ADTR
LD
SDTR

F1,=DD 6 0
F2,=DD74.65
F3,F1,F2
F4,=DD . 0 4 7
F5,F3,F4
F3,F3,F5
F6,=DD1.0975
F3,F3,F6
F7,=DD 4 . 0 0
F7,F7,F1
F3,F7,F3
F8,=DD1000.00
F3,F3,F8

Number of items
Wholesale price per widget
Price of all 60 items
Discount % for a large order
Discount amount
Subtract the discount
Sales tax multiplier
Price with sales tax
Shipping charge per item
Shipping charge for 60 items
Add shipping charge
Retailer s prepayment
Result = bill to retailer

60.E+0
7465.E-2
447900.E-2
47.E-3
21051300.E-5
426848700.E-5
10975.E-4
4684664482500.E-9
400.E-2
24000.E-2
4924664482500.E-9
100000.E-2
3924664482500.E-9

So, we calculate that the final bill to the retailer is $3924.66. But this is one cent less than the
packed decimal value! What happened?
Aha! We didnt use something like the Shift and Round Decimal (SRP) instruction to round
intermediate results. So, well try again, using QADTR quantize instructions to round interme-

714

Assembler Language Programming for IBM z System Servers

Version 1.00

diate results to two decimal places, as was done with the SRP instructions in the packed decimal
example.
LD
LD
MDTR
LD
MDTR
QADTR
SDTR
LD
MDTR
QADTR
LD
MDTR
ADTR
LD
SDTR

F1,=DD 6 0
Number of items
F2,=DD74.65
Wholesale price per widget
F3,F1,F2
Price of all 60 items
F4,=DD . 0 4 7
Discount % for a large order
F5,F3,F4
Discount amount
F5,F5,F2,B0001 * Round to two decimals
F3,F3,F5
Subtract the discount
F6,=DD1.0975
Sales tax multiplier
F3,F3,F6
Price with sales tax
F3,F3,F2,B0001 * Round to two decimals
F7,=DD 4 . 0 0
Shipping charge per item
F7,F7,F1
Shipping charge for 60 items
F3,F7,F3
Add shipping charge
F8,=DD1000.00
Retailer s prepayment
F3,F3,F8
Result = bill to retailer

60.E+0
7465.E-2
447900.E-2
47.E-3
21051300.E-5
21051.E-2
426849.E-2
10975.E-4
4684667775.E-6
468467.E-2
400.E-2
24000.E-2
492467.E-2
100000.E-2
392467.E-2

Now, the calculated final bill to the retailer is $3924.67, matching the packed decimal calculation.

35.13.2. The Retailers Calculation


Again, well use quantization instructions to mimic SRP rounding:
LD
LD
LD
LD
LD
LD
DDTR
QADTR
MDTR
QADTR
ADTR
MDTR
QADTR
ADTR
ADTR
SDTR
DDTR
QADTR

F1,=DD 6 0
F2,=DD4924.67
F3,=DD 1 . 3 7
F4,=DD . 5 4
F5,=DD.0925
F6,=DD 7 . 5 0
F7,F2,F1
F7,F7,F3,B0001
F8,F7,F2
F8,F8,F3,B0001
F8,F8,F4
F9,F8,F5
F9,F9,F3,B0001
F10,F9,F8
F10,F10,F6
F8,F8,F7
F8,F8,F7
F8,F8,F5,B0001

*
*

Number of items
60.E+0
Wholesale charge
492467.E-2
Retail markup
137.E-2
Retail fudge factor
54.E-2
Retailer s sales tax
925.E-4
Recycle charge per item
750.E-2
Base cost per item
8207783333333333.E-14
Round to 2 decimals
8208.E-2
Calculate retail markup
1124496.E-4
Round to 2 decimals
11245.E-2
Add retail fudge
11299.E-2
Calculate sales tax
10451575.E-6
Round to 2 decimals
1045.E-2
Cost/item with sales tax
12344.E-2
Add recycle fee for cust cost
13094.E-2
Gross profit/item
3092.E-2
Gross profit %
3765838206627680.E-16
Round % to xx.xx
3766.E-4

We get the same results as we did with packed decimal: $130.94 for the total cost to the consumer, and a 37.66% profit margin for the retailer.

35.13.3. Comparing Packed and Floating Decimal


In the packed decimal calculations we had to keep track of the decimal point for each calculation.
Furthermore, all packed decimal operations are storage-to-storage; on modern CPUs, the cost of
memory references grows much faster than processor speed, so storage references are relatively
expensive. Temporary work areas (as in Figures 320 and 322) add to the amount of storage
needed, and intermediate results must often be copied to temporaries for later use.
Although neither the packed decimal nor the decimal floating-point example showed how the
results would be formatted for printing, packed decimal formatting must know where to put the
decimal point, and how many significant digits are in the value.
Decimal floating-point takes care of all the hard work for you! For example:

Chapter IX: Floating-Point Data and Operations

715

All 16 floating-point registers are available, so temporary work areas in storage are rarely
needed.
Non-destructive operations minimize the need for copying data.
Decimal floating-point knows where the decimal point is, and how many significant digits are
present; instructions are available to easily determine both.
A simple timing test showed that the decimal floating-point computation was several times
faster than the packed decimal computation.
Comparing the two examples, you can see how programming decimal-arithmetic financial and
business calculations can be much easier using decimal floating-point values and arithmetic.

35.14. Decimal Floating-Point Binary-Significand Format (*)


For other architectures
This format is not supported by z System.
We mentioned briefly on page 669 that a binary-integer significand could be used for decimal
floating-point data. The IEEE 754-2008 standard defines this representation; it is intended mainly
for implementations not using the complex hardware logic of the DPD formats.
The binary-significand encoding uses a simpler significand, and like the DPD representation, the
Combination Field also mixes part of the characteristic and the leading significand digits.
As in the DPD representation, the first five bits of the CF are used to indicate infinity and NaNs:
If the bits are 11110, the value is an infinity. In a canonical infinity, all remaining bits are zero.
If the bits are 11111, the data item is a NaN; the following bit is zero for a QNaN and 1 for a
SNaN. In a canonical NaN, all bits after the sixth are zero.
The standard defines the Combination Field to be w + 5 bits long, where the five bits are reserved.
This means that for short, long, and extended representations, w is 6, 8, and 11 respectively. The
CF bits are denoted gn, where n takes values from 0 to (5 + w 1). If we call the significand T, then
the value of a number in this format is defined this way:
1. If g0 and g1 are one of 00, 01, or 10, then the biased exponent E is formed from g0 through
g(w + 1) and the significand is formed from bits g(w + 2) through the end of the encoding
(including T).
2. if g0 and g1 together are 11 and g2 and g3 are one of 00, 01, or 10, then the biased exponent E
is formed from g2 through g (w + 3) and the significand is formed by prefixing the 4 bits
( 8 + g (w + 4)) to T.
3. Exponent biases are the same as for the decimal encodings.
Figure 461 sketches this representation:
1  5+w

sabcdefghijklmnopq
T=binary significand

Figure 461. Example of D F P binary-significand format

Figure 462 shows a short-format value in this representation, where w=6:


1 11 bits  20 bits

sabcdefghijk
T=binary significand

Figure 462. Sketch of short binary-significand format

716

Assembler Language Programming for IBM z System Servers

Version 1.00

Thus, if bits ab are 00, 01, or 10, then the characteristic is bits abcdefgh , and the binary
significand is formed from bits ijk concatenated at the front of T (23 bits).
Similarly, if bits ab are 11 and bits cd are 00, 01, or 10, then the characteristic is bits
cdefghij and the binary significand is formed from the four bits (8 + k ) concatenated at the
front of T (24 bits).
We can derive the value of the short binary-encoded number X 3 FFFFFFF this way:
The sign bit is 0, so the number is positive.
The eleven bits of the Combination Field are B011 1111 1111 . The ab bits are 01, so the
biased exponent is B011 1111 1 or X 7F = 127 decimal. Because the exponent bias is 101,
the true exponent is 127 101 = 26.
The significand is the remaining 3 bits of the CF, B111, followed by the 20 bits of the TSF,
giving X 7 FFFFF , or 8388607 in decimal.
Thus, the value is + 83886071026 .
If J is the number of 10-bit, 3-BCD-digit declets in the Trailing Significand Field of a
DPD-encoded number (2, 5, or 11), then the maximum valid value of the binary-encoded
significand is the same as that of the corresponding decimal-encoded significand: 10(3 J + 1) 1 for
numeric values, or 10(3J) 1 when T is used as the payload of a NaN. If the value exceeds this
maximum, the significand is non-canonical and the value used is zero.
Computational operations in both decimal- and binary-significand representations produce only
canonical significands, and always accept non-canonical significands as input operands.

Exercises
35.14.1.(3) Create a 32-bit binary-significand representation whose value exceeds the maximum
value 1097 1.
35.14.2.(4) Construct a short-format binary-significand decimal floating-point number Max, the
maximum valid value. Show its hexadecimal representation.
35.14.3.(2) Construct a short-format binary-significand decimal floating-point number Min, the
minimum valid value. Show its hexadecimal representation.
35.14.4.(3) A binary-significand decimal floating-point number has representation X 5 FFFFFFF .
Is it valid? If so, what is its value?

35.15. Summary
This section has covered a wide range of topics, some of which most programmers wont need to
worry about. The key operations are the arithmetic, loading, and type-conversion instructions; the
others are useful to know about, but arent as frequently used.
We might describe decimal floating-point arithmetic this way:
Decimal floating-point arithmetic
It can behave like fixed-point arithmetic until it cant, and then it behaves
like floating-point arithmetic.
Table 372 lists the instructions that test data classes and data groups.

Chapter IX: Floating-Point Data and Operations

717

Function
Test Data Class
Test Data Group

Operand Length
Short
Long
Extended
TDCET
TDCDT
TDCXT
TDGET
TDGDT
TDGXT

Table 372. DFP Test Data Class and Test Data Group instructions

Table 373 lists the decimal floating-point arithmetic and related instructions.
Operand
Long
ADTR
SDTR
DDTR
MDTR
CDTR
KDTR
CEDTR
FIDTR
EEFTR
IEFTR
ESDTR
SLDT
SRDT
QADTR
RRDTR

Function
Add
Subtract
Divide
Multiply
Compare
Compare and Signal
Compare Biased Exponent
Load FP Integer
Extract Biased Exponent
Insert Biased Exponent
Extract Significance
Shift Significand Left
Shift Significand Right
Quantize
Reround

Length
Extended
AXTR
SXTR
DXTR
MXTR
CXTR
KXTR
CEXTR
FIXTR
EEXTR
IEXTR
ESXTR
SLXT
SRXT
QAXTR
RRXTR

Table 373. DFP Arithmetic and related instructions

Table 374 summarizes instructions that convert decimal floating-point data to and from different
lengths and different data types.
To
From
Short DFP
Long DFP
Ext. DFP
64-bit binary
Signed BCD
Unsigned BCD
Zoned decimal

Short
DFP

Long
DFP
LDETR

Ext.
DFP

64-bit
binary

Signed
BCD

LEDTR

LXDTR

LDXTR
CDGTR
CDSTR
CDUTR
CDZT

CGDTR
CGXTR

CSDTR
CSXTR

CUDTR
CUXTR

CZDT
CZXT

CXGTR
CXSTR
CXUTR
CZXT

Unsigned Zoned
BCD
decimal

Table 374. DFP length and type conversion instructions

Table 375 lists the decimal floating-point rounding and lengthening instructions.
Function
Long to Short
Short to Long
Extended to Long
Long to Extended

718

Assembler Language Programming for IBM z System Servers

Round
LEDTR

Lengthen
LDETR

LDXTR
LXDTR

Version 1.00

Table 375. DFP rounding and lengthening instructions

Table 376 lists instructions that move data among the floating-point registers.
Function
Copy Sign
Load Complement
Load Negative
Load Positive
Load and Test

Long
CPSDR
LCDFR
LNDFR
LPDFR
LTDTR

Extended

LTXTR

Table 376. DFP data-loading instructions

Table 377 lists instructions that move data among the floating-point registers.
Function
Copy FPR to GPR
Copy GPR to FPR

Instruction
LGDR
LDGR

Table 377. Instructions copying between FPRs and GPRs

Table 378 lists the instruction that sets the decimal rounding model.
Function
Set Decimal Rounding Mode

Instruction
SRNMT

Table 378. Instruction setting decimal rounding mode

Table 379 summarizes the non-preferred declet encodings. (They are also shown in parentheses
with all the declet encodings in Figure 464.)
Noncanonical declets
16E
26E
36E

BCD digits
888

Canonical declet
06E

16F

26F

36F

889

06F

17E

27E

37E

898

07E

17F

27F

37F

899

07F

1EE

2EE

3EE

988

0EE

1EF

2EF

3EF

989

0EF

1FE

2FE

3FE

988

0FE

1FF

2FF

3FF

999

0FF

Table 379. Non-canonical declets

Chapter IX: Floating-Point Data and Operations

719

The following table shows how sets of three BCD digits are encoded into a canonical declet. The
first two BCD digits are selected from a row, and the final BCD digit is selected from a column.

0 1 2 3 4 5 6 7 8 9
0 1 2 3 4 5 6 7 8 9

00_ 000 001 002 003 004 005 006 007 008 009 50_ 280 281 282 283 284 285 286 287 288 289
01_ 010 011 012 013 014 015 016 017 018 019 51_ 290 291 292 293 294 295 296 297 298 299
02_ 020 021 022 023 024 025 026 027 028 029 52_ 2A0 2A1 2A2 2A3 2A4 2A5 2A6 2A7 2A8 2A9
03_ 030 031 032 033 034 035 036 037 038 039 53_ 2B0 2B1 2B2 2B3 2B4 2B5 2B6 2B7 2B8 2B9
04_ 040 041 042 043 044 045 046 047 048 049 54_ 2C0 2C1 2C2 2C3 2C4 2C5 2C6 2C7 2C8 2C9
05_ 050 051 052 053 054 055 056 057 058 059 55_ 2D0 2D1 2D2 2D3 2D4 2D5 2D6 2D7 2D8 2D9
06_ 060 061 062 063 064 065 066 067 068 069 56_ 2E0 2E1 2E2 2E3 2E4 2E5 2E6 2E7 2E8 2E9
07_ 070 071 072 073 074 075 076 077 078 079 57_ 2F0 2F1 2F2 2F3 2F4 2F5 2F6 2F7 2F8 2F9
08_ 00A 00B 02A 02B 04A 04B 06A 06B 04E 04F 58_ 28A 28B 2AA 2AB 2CA 2CB 2EA 2EB 2CE 2CF
09_ 01A 01B 03A 03B 05A 05B 07A 07B 05E 05F 59_ 29A 29B 2BA 2BB 2DA 2DB 2FA 2FB 2DE 2DF
10_ 080 081 082 083 084 085 086 087 088 089 60_ 300 301 302 303 304 305 306 307 308 309
11_ 090 091 092 093 094 095 096 097 098 099 61_ 310 311 312 313 314 315 316 317 318 319
12_ 0A0 0A1 0A2 0A3 0A4 0A5 0A6 0A7 0A8 0A9 62_ 320 321 322 323 324 325 326 327 328 329
13_ 0B0 0B1 0B2 0B3 0B4 0B5 0B6 0B7 0B8 0B9 63_ 330 331 332 333 334 335 336 337 338 339
14_ 0C0 0C1 0C2 0C3 0C4 0C5 0C6 0C7 0C8 0C9 64_ 340 341 342 343 344 345 346 347 348 349
15_ 0D0 0D1 0D2 0D3 0D4 0D5 0D6 0D7 0D8 0D9 65_ 350 351 352 353 354 355 356 357 358 359
16_ 0E0 0E1 0E2 0E3 0E4 0E5 0E6 0E7 0E8 0E9 66_ 360 361 362 363 364 365 366 367 368 369
17_ 0F0 0F1 0F2 0F3 0F4 0F5 0F6 0F7 0F8 0F9 67_ 370 371 372 373 374 375 376 377 378 379
18_ 08A 08B 0AA 0AB 0CA 0CB 0EA 0EB 0CE 0CF 68_ 30A 30B 32A 32B 34A 34B 36A 36B 34E 34F
19_ 09A 09B 0BA 0BB 0DA 0DB 0FA 0FB 0DE 0DF 69_ 31A 31B 33A 33B 35A 35B 37A 37B 35E 35F
20_ 100 101 102 103 104 105 106 107 108 109 70_ 380 381 382 383 384 385 386 387 388 389
21_ 110 111 112 113 114 115 116 117 118 119 71_ 390 391 392 393 394 395 396 397 398 399
22_ 120 121 122 123 124 125 126 127 128 129 72_ 3A0 3A1 3A2 3A3 3A4 3A5 3A6 3A7 3A8 3A9
23_ 130 131 132 133 134 135 136 137 138 139 73_ 3B0 3B1 3B2 3B3 3B4 3B5 3B6 3B7 3B8 3B9
24_ 140 141 142 143 144 145 146 147 148 149 74_ 3C0 3C1 3C2 3C3 3C4 3C5 3C6 3C7 3C8 3C9
25_ 150 151 152 153 154 155 156 157 158 159 75_ 3D0 3D1 3D2 3D3 3D4 3D5 3D6 3D7 3D8 3D9
26_ 160 161 162 163 164 165 166 167 168 169 76_ 3E0 3E1 3E2 3E3 3E4 3E5 3E6 3E7 3E8 3E9
27_ 170 171 172 173 174 175 176 177 178 179 77_ 3F0 3F1 3F2 3F3 3F4 3F5 3F6 3F7 3F8 3F9
28_ 10A 10B 12A 12B 14A 14B 16A 16B 14E 14F 78_ 38A 38B 3AA 3AB 3CA 3CB 3EA 3EB 3CE 3CF
29_ 11A 11B 13A 13B 15A 15B 17A 17B 15E 15F 79_ 39A 39B 3BA 3BB 3DA 3DB 3FA 3FB 3DE 3DF
30_ 180 181 182 183 184 185 186 187 188 189 80_ 00C 00D 10C 10D 20C 20D 30C 30D 02E 02F
31_ 190 191 192 193 194 195 196 197 198 199 81_ 01C 01D 11C 11D 21C 21D 31C 31D 03E 03F
32_ 1A0 1A1 1A2 1A3 1A4 1A5 1A6 1A7 1A8 1A9 82_ 02C 02D 12C 12D 22C 22D 32C 32D 12E 12F
33_ 1B0 1B1 1B2 1B3 1B4 1B5 1B6 1B7 1B8 1B9 83_ 03C 03D 13C 13D 23C 23D 33C 33D 13E 13F
34_ 1C0 1C1 1C2 1C3 1C4 1C5 1C6 1C7 1C8 1C9 84_ 04C 04D 14C 14D 24C 24D 34C 34D 22E 22F
35_ 1D0 1D1 1D2 1D3 1D4 1D5 1D6 1D7 1D8 1D9 85_ 05C 05D 15C 15D 25C 25D 35C 35D 23E 23F
36_ 1E0 1E1 1E2 1E3 1E4 1E5 1E6 1E7 1E8 1E9 86_ 06C 06D 16C 16D 26C 26D 36C 36D 32E 32F
37_ 1F0 1F1 1F2 1F3 1F4 1F5 1F6 1F7 1F8 1F9 87_ 07C 07D 17C 17D 27C 27D 37C 37D 33E 33F
38_ 18A 18B 1AA 1AB 1CA 1CB 1EA 1EB 1CE 1CF 88_ 00E 00F 10E 10F 20E 20F 30E 30F 06E 06F
39_ 19A 19B 1BA 1BB 1DA 1DB 1FA 1FB 1DE 1DF 89_ 01E 01F 11E 11F 21E 21F 31E 31F 07E 07F
40_ 200 201 202 203 204 205 206 207 208 209 90_ 08C 08D 18C 18D 28C 28D 38C 38D 0AE 0AF
41_ 210 211 212 213 214 215 216 217 218 219 91_ 09C 09D 19C 19D 29C 29D 39C 39D 0BE 0BF
42_ 220 221 222 223 224 225 226 227 228 229 92_ 0AC 0AD 1AC 1AD 2AC 2AD 3AC 3AD 1AE 1AF
43_ 230 231 232 233 234 235 236 237 238 239 93_ 0BC 0BD 1BC 1BD 2BC 2BD 3BC 3BD 1BE 1BF
44_ 240 241 242 243 244 245 246 247 248 249 94_ 0CC 0CD 1CC 1CD 2CC 2CD 3CC 3CD 2AE 2AF
45_ 250 251 252 253 254 255 256 257 258 259 95_ 0DC 0DD 1DC 1DD 2DC 2DD 3DC 3DD 2BE 2BF
46_ 260 261 262 263 264 265 266 267 268 269 96_ 0EC 0ED 1EC 1ED 2EC 2ED 3EC 3ED 3AE 3AF
47_ 270 271 272 273 274 275 276 277 278 279 97_ 0FC 0FD 1FC 1FD 2FC 2FD 3FC 3FD 3BE 3BF
48_ 20A 20B 22A 22B 24A 24B 26A 26B 24E 24F 98_ 08E 08F 18E 18F 28E 28F 38E 38F 0EE 0EF
49_ 21A 21B 23A 23B 25A 25B 27A 27B 25E 25F 99_ 09E 09F 19E 19F 29E 29F 39E 39F 0FE 0FF

Figure 463. BCD-to-DPD encodings

720

Assembler Language Programming for IBM z System Servers

Version 1.00

The following table shows how declets are converted to groups of three BCD digits. The parenthesized values in the table are non-preferred encodings; they are accepted as input values, but are
not generated by any arithmetic operation.

0 1 2 3 4 5 6 7 8 9 A B C D E F

00_ 000 001 002 003 004 005 006 007 008 009 080 081 800 801 880 881
01_ 010 011 012 013 014 015 016 017 018 019 090 091 810 811 890 891
02_ 020 021 022 023 024 025 026 027 028 029 082 083 820 821 808 809
03_ 030 031 032 033 034 035 036 037 038 039 092 093 830 831 818 819
04_ 040 041 042 043 044 045 046 047 048 049 084 085 840 841 088 089
05_ 050 051 052 053 054 055 056 057 058 059 094 095 850 851 098 099
06_ 060 061 062 063 064 065 066 067 068 069 086 087 860 861 888 889
07_ 070 071 072 073 074 075 076 077 078 079 096 097 870 871 898 899
08_ 100 101 102 103 104 105 106 107 108 109 180 181 900 901 980 981
09_ 110 111 112 113 114 115 116 117 118 119 190 191 910 911 990 991
0A_ 120 121 122 123 124 125 126 127 128 129 182 183 920 921 908 909
0B_ 130 131 132 133 134 135 136 137 138 139 192 193 930 931 918 919
0C_ 140 141 142 143 144 145 146 147 148 149 184 185 940 941 188 189
0D_ 150 151 152 153 154 155 156 157 158 159 194 195 950 951 198 199
0E_ 160 161 162 163 164 165 166 167 168 169 186 187 960 961 988 989
0F_ 170 171 172 173 174 175 176 177 178 179 196 197 970 971 998 999
10_ 200 201 202 203 204 205 206 207 208 209 280 281 802 803 882 883
11_ 210 211 212 213 214 215 216 217 218 219 290 291 812 813 892 893
12_ 220 221 222 223 224 225 226 227 228 229 282 283 822 823 828 829
13_ 230 231 232 233 234 235 236 237 238 239 292 293 832 833 838 839
14_ 240 241 242 243 244 245 246 247 248 249 284 285 842 843 288 289
15_ 250 251 252 253 254 255 256 257 258 259 294 295 852 853 298 299
16_ 260 261 262 263 264 265 266 267 268 269 286 287 862 863 (888)(889)
17_ 270 271 272 273 274 275 276 277 278 279 296 297 872 873 (898)(899)
18_ 300 301 302 303 304 305 306 307 308 309 380 381 902 903 982 983
19_ 310 311 312 313 314 315 316 317 318 319 390 391 912 913 992 993
1A_ 320 321 322 323 324 325 326 327 328 329 382 383 922 923 928 929
1B_ 330 331 332 333 334 335 336 337 338 339 392 393 932 933 938 939
1C_ 340 341 342 343 344 345 346 347 348 349 384 385 942 943 388 389
1D_ 350 351 352 353 354 355 356 357 358 359 394 395 952 953 398 399
1E_ 360 361 362 363 364 365 366 367 368 369 386 387 962 963 (988)(989)
1F_ 370 371 372 373 374 375 376 377 378 379 396 397 972 973 (998)(999)
20_ 400 401 402 403 404 405 406 407 408 409 480 481 804 805 884 885
21_ 410 411 412 413 414 415 416 417 418 419 490 491 814 815 894 895
22_ 420 421 422 423 424 425 426 427 428 429 482 483 824 825 848 849
23_ 430 431 432 433 434 435 436 437 438 439 492 493 834 835 858 859
24_ 440 441 442 443 444 445 446 447 448 449 484 485 844 845 488 489
25_ 450 451 452 453 454 455 456 457 458 459 494 495 854 855 498 499
26_ 460 461 462 463 464 465 466 467 468 469 486 487 864 865 (888)(889)
27_ 470 471 472 473 474 475 476 477 478 479 496 497 874 875 (898)(899)
28_ 500 501 502 503 504 505 506 507 508 509 580 581 904 905 984 985
29_ 510 511 512 513 514 515 516 517 518 519 590 591 914 915 994 995
2A_ 520 521 522 523 524 525 526 527 528 529 582 583 924 925 948 949
2B_ 530 531 532 533 534 535 536 537 538 539 592 593 934 935 958 959
2C_ 540 541 542 543 544 545 546 547 548 549 584 585 944 945 588 589
2D_ 550 551 552 553 554 555 556 557 558 559 594 595 954 955 598 599
2E_ 560 561 562 563 564 565 566 567 568 569 586 587 964 965 (988)(989)
2F_ 570 571 572 573 574 575 576 577 578 579 596 597 974 975 (998)(999)
30_ 600 601 602 603 604 605 606 607 608 609 680 681 806 807 886 887
31_ 610 611 612 613 614 615 616 617 618 619 690 691 816 817 896 897
32_ 620 621 622 623 624 625 626 627 628 629 682 683 826 827 868 869
33_ 630 631 632 633 634 635 636 637 638 639 692 693 836 837 878 879
34_ 640 641 642 643 644 645 646 647 648 649 684 685 846 847 688 689
35_ 650 651 652 653 654 655 656 657 658 659 694 695 856 857 698 699
36_ 660 661 662 663 664 665 666 667 668 669 686 687 866 867 (888)(889)
37_ 670 671 672 673 674 675 676 677 678 679 696 697 876 877 (898)(899)
38_ 700 701 702 703 704 705 706 707 708 709 780 781 906 907 986 987
39_ 710 711 712 713 714 715 716 717 718 719 790 791 916 917 996 997
3A_ 720 721 722 723 724 725 726 727 728 729 782 783 926 927 968 969
3B_ 730 731 732 733 734 735 736 737 738 739 792 793 936 937 978 979
3C_ 740 741 742 743 744 745 746 747 748 749 784 785 946 947 788 789
3D_ 750 751 752 753 754 755 756 757 758 759 794 795 956 957 798 799
3E_ 760 761 762 763 764 765 766 767 768 769 786 787 966 967 (988)(989)
3F_ 770 771 772 773 774 775 776 777 778 779 796 797 976 977 (998)(999)

Figure 464. DPD-to-BCD translation

Chapter IX: Floating-Point Data and Operations

721

Instructions Discussed in this Section


The instruction mnemonics and opcodes are shown in the following table:

722

Mnemonic
ADTR

Opcode
B3D2

Mnemonic
CXFTR

Opcode
B359

Mnemonic
LGDR

Opcode
B3CD

ADTRA

B3D2

CXGTR

B3F9

LNDFR

B371

AXTR

B3DA

CXGTRA

B3F9

LPDFR

B370

AXTRA

B3DA

CXLFTR

B95B

LTDTR

B3D6

CDFTR

B351

CXLGTR

B95A

LTXTR

B3DE

CDGTR

B3F1

CXSTR

B3FB

LXDTR

B3DC

CDGTRA

B3F1

CXTR

B3EC

MDTR

B3D0

CDLFTR

B353

CXUTR

B3FA

MDTRA

B3D0

CDLGTR

B952

CXZT

EDAB

MXTR

B3D8

CDSTR

B3F3

CZDT

EDA8

MXTRA

B3D8

CDTR

B3E4

CZXT

EDA9

QADTR

B3F5

CDUTR

B3F2

DDTR

B3D1

QAXTR

B3FD

CDZT

EDAA

DDTRA

B3D1

RRDTR

B3F7

CEDTR

B3F4

DXTR

B3D9

RRXTR

B3FF

CEXTR

B3FC

DXTRA

B3D9

SDTR

B3D3

CFDTR

B941

EEDTR

B3E5

SDTRA

B3D3

CFXTR

B949

EEXTR

B3ED

SLDT

ED40

CGDTR

B3E1

ESDTR

B3E7

SLXT

ED48

CGDTRA

B3E1

ESXTR

B3EF

SRDT

ED41

CGXTR

B3E9

FIDTR

B3D7

SRNMT

B2B9

CGXTRA

B3E9

FIXTR

B3DF

SRXT

ED49

CLFDTR

B943

IEDTR

B3F6

SXTR

B3DB

CLFXTR

B94B

IEXTR

B3FE

SXTRA

B3DB

CLGXTR

B94A

KDTR

B3E0

TDCDT

ED54

CLGDTR

B942

KXTR

B3E8

TDCET

ED50

CPSDR

B372

LCDFR

B373

TDCXT

ED58

CSDTR

B3E3

LDETR

B3D4

TDGDT

ED55

CSXTR

B3EB

LDGR

B3C1

TDGET

ED51

CUDTR

B3E2

LDXTR

B3DD

TDGXT

ED59

CUXTR

B3EA

LEDTR

B3D5

Assembler Language Programming for IBM z System Servers

Version 1.00

The instruction opcodes and mnemonics are shown in the following table:
Opcode
B2B9

Mnemonic
SRNMT

Opcode
B3ED

Mnemonic
EEXTR

Opcode
B353

Mnemonic
CDLFTR

B3CD

LGDR

B3EF

ESXTR

B359

CXFTR

B3C1

LDGR

B3E0

KDTR

B370

LPDFR

B3DA

AXTR

B3E1

CGDTR

B371

LNDFR

B3DA

AXTRA

B3E1

CGDTRA

B372

CPSDR

B3DB

SXTR

B3E2

CUDTR

B373

LCDFR

B3DB

SXTRA

B3E3

CSDTR

B94A

CLGXTR

B3DC

LXDTR

B3E4

CDTR

B94B

CLFXTR

B3DD

LDXTR

B3E5

EEDTR

B941

CFDTR

B3DE

LTXTR

B3E7

ESDTR

B942

CLGDTR

B3DF

FIXTR

B3E8

KXTR

B943

CLFDTR

B3D0

MDTR

B3E9

CGXTR

B949

CFXTR

B3D0

MDTRA

B3E9

CGXTRA

B95A

CXLGTR

B3D1

DDTR

B3FA

CXUTR

B95B

CXLFTR

B3D1

DDTRA

B3FB

CXSTR

B952

CDLGTR

B3D2

ADTR

B3FC

CEXTR

ED40

SLDT

B3D2

ADTRA

B3FD

QAXTR

ED41

SRDT

B3D3

SDTR

B3FE

IEXTR

ED48

SLXT

B3D3

SDTRA

B3FF

RRXTR

ED49

SRXT

B3D4

LDETR

B3F1

CDGTR

ED50

TDCET

B3D5

LEDTR

B3F1

CDGTRA

ED51

TDGET

B3D6

LTDTR

B3F2

CDUTR

ED54

TDCDT

B3D7

FIDTR

B3F3

CDSTR

ED55

TDGDT

B3D8

MXTR

B3F4

CEDTR

ED58

TDCXT

B3D8

MXTRA

B3F5

QADTR

ED59

TDGXT

B3D9

DXTR

B3F6

IEDTR

EDA8

CZDT

B3D9

DXTRA

B3F7

RRDTR

EDA9

CZXT

B3EA

CUXTR

B3F9

CXGTR

EDAA

CDZT

B3EB

CSXTR

B3F9

CXGTRA

EDAB

CXZT

B3EC

CXTR

B351

CDFTR

Exercises
35.15.1.(3) Several decimal floating-point instructions have an M4 mask field. Make a table
showing (a) its possible values, (b) the type or types of instructions to which each value applies,
and (c) the effect of each value for the affected instructions.

Terms and Definitions


cohort
In a given format, a set of decimal floating-point numbers having the same numeric value but
different quanta.
Chapter IX: Floating-Point Data and Operations

723

quantum
The value of a unit in the low-order digit of a decimal floating-point number.
preferred quantum
The quantum selected for the result of an operation that maximizes the number of significant
digits, including low-order zero digits. Equivalent to preferred exponent.
declet
A 10-bit encoding of three Binary Coded Decimal (BCD) digits. Declets may have two
forms:
canonical: preferred (and generated) values, and
non-canonical: any of 24 non-preferred encodings accepted as operands, but not generated
by any arithmetic operation.
DPD
Densely Packed Decimal; an encoding into declets.
extreme exponent
An exponent with maximum positive or negative value.
payload
Diagnostic information contained in a the significand of a NaN.
preferred exponent
The exponent of the result of every numeric operation has a preferred value, either that of
one of the operands or a value providing the maximum number of significant digits.

Programming Problems
Problem 35.1.(3) + Write a program that reads records containing eight hex digits representing a
short decimal floating-point number. Then, display the value of the number in scientific
format: sd.ddddddEsdd where s is a sign, and d represents decimal digits. If the hex digits represent a special value, print its sign followed by Inf, QNaN, or SNaN as appropriate.
Problem 35.2.(4) In decimal floating-point arithmetic, the equation (1.0/N)N=1.0 is true for
some values of N between 1 and 100 and not for others. Write a program that tests this relation
in long and extended precision decimal floating-point arithmetic. Show the values of N for
which the relation fails for both lengths, and for which the relation fails for only one of the
lengths.
For your own edification and/or extra credit:
For those values of N for which the equation fails, determine the relative difference between
1.0 and the result of (1.0/N)N.
What rounding modes should be used for your solution? How would other choices affect
the results?
What property is shared by all the values that fail?
Problem 35.3.(3) + Write a subroutine named DPD2BCD that converts a declet to the decimal
equivalent 3 hex digits that represent the value of the declet.
Then, write a driver program that will call DPD2BCD for each of the 1024 possible bit combinations, and display in tabular form (a) the decimal value of the declet, (b) the declet as three
hexadecimal digits, and (c) the decimal number between 0 and 999 represented by the declet.

724

Assembler Language Programming for IBM z System Servers

Version 1.00

36. Floating-Point Summary

3333333333
333333333333
33
33
33
33
3333
3333
33
33
33
33
333333333333
3333333333

6666666666
666666666666
66
66
66
66
66666666666
666666666666
66
66
66
66
66
66
666666666666
6666666666

This chapter has covered a wide range of topics; this final section summarizes properties of
floating-point data and arithmetic, and provides some general observations and reminders.

36.1. Floating-Point Data Representations


The three z System floating-point representations are summarized in Table 380 for short, long,
and extended precision data respectively.
Table 380 (Page 1 of 2). Summary of z System floating-point representations

Property
Operand width, in bits
Base/radix
Representation of
significand digits

Hexadecimal
32, 64, 128
16

Binary
32, 64, 128
2

Decimal
32, 64, 128
10

Fraction

Fraction

Integer or fraction

Significant digits

All are present

Implicit high-order bit


for normalized data

All are present; highorder digit is part of


Combination Field

6, 14, 28

24, 53, 113

7, 16, 34

6, 15, 32

6, 15, 33

7, 16, 34

Always 7

8, 11, 15

8, 10, 14

Binary

Binary

Binary

In biased exponent
64
+ 63
64

In biased exponent
127, 1023, 16383
+ 127, + 1023, + 16383
126, 1022, 16382

In biased exponent
101, 398, 6176
+ 96, + 384, + 6144
95, 383, 6143

Significand width, in
radix digits
Maximum equivalent
decimal precision
Exponent width, in bits
Exponent representation
Exponent sign
Exponent bias
Maximum exponent
Minimum exponent

Chapter IX: Floating-Point Data and Operations

725

Table 380 (Page 2 of 2). Summary of z System floating-point representations

Property

Hexadecimal

Maximum normalized
value

7.210 + 75

Minimum normalized
value

7.210 79

Minimum denormalized value

5.110 85
1.210 94
1.710 111

Scale factor for


overflow/underflow
exponent wrap
Scale factor for Load
Rounded exponent
wrap
Special values
Multiple representations of a value
Unnormalized values
Rounding options for
arithmetic
Sign of zero arithmetically significant

none

Binary
3.410 + 38
1.810 + 308
1.210 + 4392
1.210 38
2.210 308
3.410 4392
1.410 45
4.910 324
6.510 4966
192
1536
24576

Decimal
10 + 97
10 + 385
10 + 6145
10 95
10 383
10 6143
10 101
10 398
10 6176

576
9216

none

512
8192

192
3072

None

QNaN, SNaN, Infinity

QNaN, SNaN, Infinity

Yes

No

Yes

Yes

Yes (for tiny values)

Yes

None

4 modes

8 modes

No

Yes

Yes

Each representation has advantages and disadvantages:


Hexadecimal floating-point has a fixed-width characteristic, so its easier to extract the
significand and to extend or shorten operands; it supports redundant representations.
Binary floating-point has no redundant values or representations, but lengthening or shortening operands requires special instructions.
Decimal floating-point has a very complex representation and supports redundant values, but
its arithmetic is more intuitive than hexadecimal or binary.
Precisions have minor differences:

Short binary has 0 to 3 more fraction bits than short hexadecimal

Long binary has 0 to 3 fewer fraction bits than long hexadecimal

Extended IEEE binary has 1 to 4 more fraction bits than extended hexadecimal

Decimal floating-point has greater decimal precision than either hexadecimal or binary
floating-point, for all operand lengths.

Exercises
36.1.1.(1) What possibilities must you consider in converting short-precision floating-point data
between hexadecimal and binary representations?
36.1.2.(1) What possibilities must you consider in converting long-precision floating-point data
between hexadecimal and binary representations?
36.1.3.(1) What possibilities must you consider in converting extended-precision floating-point
data between hexadecimal and binary representations?

726

Assembler Language Programming for IBM z System Servers

Version 1.00

36.2. Floating-Point Properties


Because precision and range are limited, the fundamental behaviors of floating-point are always
present; and, some numbers cannot be represented exactly. For example, consider the decimal
value 0.1: its value in binary is 0.0001 1001 1001 1001 1001 1001 1001 1001 ..., an unbounded
bit string. When representing 0.1 as a normalized short hexadecimal floating-point value, the fraction has 21 significant bits: X19999A , with relative error 2 22. When represented as a short
precision binary floating-point value, the fraction has 24 significant bits: X CCCCCD , with relative
error 2 25 .
This representation error may lead to unexpected results. Suppose we add 0.1 to itself 8 times,
and multiply 0.1 by 8, using short binary and hexadecimal arithmetic. The results are shown in
Table 381, where the differences from the decimal result are due to the imprecise representation of
0.1 in hexadecimal and binary.
Operation
Add 0.1 8 times
Multiply 0.1 8 times

Binary
.8000000715...
.8000000119...

Hexadecimal
.8000000119...
.8000000119...

Decimal
.8000000
.8000000

Table 381. Adding 0.1 in hexadecimal, binary, and decimal floating-point

This repeating-fraction problem doesnt go away when you use decimal floating-point: it cannot
precisely represent fractions like 2/3 and 1/7.

Exercises
36.2.1.(2) + Using 6-digit decimal floating-point numbers and arithmetic (not a type used in
z System!), add 2/3 to 1.00000 3 times, with rounding to the nearest 6-digit value at each step.
If you start (a) with 2/3 = 0.666667 and (b) with 2/3 = 0.666666, what are the results?
36.2.2.(2) + Using the same 6-digit decimal floating-point numbers as in Exercise 36.2.1, add
three copies of each representation of 2/3 to itself, and then add 1.00000. What are the results?

36.3. Floating-Point Exceptions


Hexadecimal and binary/decimal exceptions have similarities and differences, as summarized in
Tables 382 and 383.
Exception
Exponent overflow
Exponent underflow
Zero divide
Lost significance

Maskable
No
Yes
No
Yes

Masked result

True zero

True zero

Interrupt action/result
Scaled exponent
Scaled exponent
Dividend operand unchanged
Pseudo-zero

Table 382. Exception behavior for hexadecimal floating-point

Exception
Invalid operation
Zero divide
Exponent overflow
Exponent underflow
Inexact result
Quantum exception
(DFP only)

Maskable
Yes
Yes
Yes
Yes
Yes
Yes

Masked result
QNaN
Signed infinity
Infinity or MaxReal
Zero (or BFP de-norm)
Calculated result

Interrupt action/result
Operation suppressed
Operation suppressed
Scaled exponent
Scaled exponent
Calculated result

Calculated result

Calculated result

Chapter IX: Floating-Point Data and Operations

727

Table 383. Exception behavior for binary and decimal floating-point

Differences to consider
Both hexadecimal and IEEE BFP/DFP results can differ significantly
between masked and unmasked actions.

36.4. Defining Floating-Point Constants


Each type allows you to specify a length modifier, as shown in Table 384. The hexadecimal and
binary types can be generated at less than their default lengths, but decimal floating-point constants must have fixed lengths even if they are not aligned on default boundaries. (Bit-length
modifiers were described in Section 17.5 on page 257.)
Constant Type
E,EH (hexadecimal)
EB (binary)
ED (decimal)

Default Length
4
4
4

Length Modifier Range


.12 to 8
.9 to 4
.32 or 4 only

D,DH (hexadecimal)
DB (binary)
D D (decimal

8
8
8

.12 to 8
.12 to 8
.64 or 16 only

L,LH,LQ (hexadecimal)
LB (binary)
LD (decimal)

8
16
16

.12 to 16
.16 to 16
.128 or 16 only

Table 384. Length modifiers of floating-point constants

Table 385 summarizes the rounding-mode suffixes you can use when defining floating-point constants. Values less than 8 are used for hexadecimal and binary constants. and values greater than
or equal to 8 are used for decimal floating-point constants.
Mode
1
4
5
6
7

Rn
R1
R4
R5
R6
R7

Description
Round half-up (to nearest, ties away from 0) (HFP default)
Round half-even (to nearest, ties to nearest even) (BFP Default)
Round toward zero (truncate)
Round to + ; if , truncate
Round to ; if + , truncate

8
9
10
11
12
13
14
15

R8
R9
R10
R11
R12
R13
R14
R15

Round half-even (to nearest, ties to nearest even) (default)


Round toward zero (truncate)
Round to + ; if , truncate
Round to ; if + , truncate
Round half-up (to nearest, ties away from 0)
Round half-down (to nearest, ties toward 0)
Round up (away from zero)
Round for reround (prepare for shorter precision)

Table 385. Assembler rounding-mode suffixes for floating-point constants

728

Assembler Language Programming for IBM z System Servers

Version 1.00

Exercises
36.4.1.(2) Table 384 indicates that the minimum bit length for hexadecimal floating-point constants is 12 bits. However,
DC

EL.9 8

is quite acceptable to the Assembler. Why then is the stated minimum bit length 12?
36.4.2.(3) + Consider the representations of the decimal constant 0.1: Its short binary floatingpoint representation is X 3 DCCCCCD and its short decimal floating-point representation is
X22400001. What are the values of these two words if they are mistakenly interpreted as short
hexadecimal floating-point constants?
36.4.3.(3) + The short hexadecimal floating-point representation of 0.1 is X4019999A . What
would be the value of this constant if treated as if it is binary and decimal floating-point?
36.4.4.(3) + The short decimal floating-point representation of 1 is X22500001. What would
be the value of this constant if treated as if it is hexadecimal and binary floating-point?
36.4.5.(3) + These four floating-point constants were found in a program that didnt document
their type. What values would they take if interpreted as short hexadecimal, binary, and decimal
floating-point constants?
(a)
(b)
(c)
(d)

X 3 F800000
X41100000
X42640000
X 7 FFFFFFF

36.5. Converting Among Decimal, Hexadecimal and Binary Representations


When you display the values of floating-point numbers, they will almost always be wanted in
decimal form. For decimal floating-point, you only need to format the results; no conversion is
needed because values are already in decimal format. For the other two representations, however,
the data must be converted from a binary format (including hexadecimal) to decimal. These conversions can be very difficult to do correctly: approximate conversions between decimal and hex
or binary are easy, but some common values require great care. Well discuss this problem in two
forms, known as In-Out and Out-In conversions.
An In conversion converts data from decimal to a machine radix (hexadecimal or binary) and
an Out conversion converts data from a from machine radix to decimal. The conversions
between decimal and binary correctly must be correctly rounded for all values228 for these rules to
apply.

36.5.1. In-Out Conversions


When we convert external data from a decimal representation to internal hexadecimal or binary
floating-point, do some computations, and then convert the internal floating-point values back to
decimal for display or printing, we have done an In-Out conversion. To be assured that the results
are reliable, we must answer this question:
If the precision of the external decimal data is D digits, what internal precision p is required to
be sure we can correctly represent the decimal value (the In conversion); and when converted back to decimal (the Out conversion), can we correctly recover all D decimal digits?

228

Today, these conversions are almost always correctly rounded, but for many years their complexity was not well
understood.
Chapter IX: Floating-Point Data and Operations

729

This observation helps define the term equivalent decimal digits. Using a floating-point system
FP(r,p) with radix r and p base-r digits, if
1. 10 J r K for any nonzero J and K (that is, no power of 2 is a power of 10, which is true for
both hexadecimal and binary), and
2. all D-digit decimal floating-point numbers can be correctly converted to a member of
FP(r,p), and when converted back to decimal will correctly recover the original decimal value,
and
3. conversions are exact (that is, deliver the nearest neighbor of the infinitely precise value), and
are correctly rounded.
then we say that FP(r,p) can faithfully represent D-digit decimal numbers.
Starting with decimal data with precision D, the required internal hexadecimal and binary
floating-point precisions for faithful conversion are summarized in Table 386.
Precision

Decimal Digits

Short
Long

6
15
32
33

Extended

Hexadecimal
Digits

Binary Digits

6
14

21
51

28

111

Table 386. Internal precision required for faithful In-Out conversion

For example, suppose the decimal data has precision 6 digits. Faithful conversion to hexadecimal
or binary requires 6 hexadecimal digits or 21 binary digits, so decimal data with 6 digits is
faithfully represented in both short floating-point representations. But if the decimal data has 7
digits, the number of internal hexadecimal and binary digits is too small, so seven-digit decimal
numbers cannot be faithfully represented in short floating-point. Thus we say that FP(16,6) and
FP(2,24) faithfully represent 6 decimal digits. This result may not be what you would expect
from calculating the weight of the low-order bit of a floating-point number. In short hexadecimal
floating-point, even though 16 6 0.5910 7, all 6-digit decimal floating-point values but not
all 7-digit decimal floating-point values can can be converted to hexadecimal and back with complete recovery.
Similar considerations apply to long floating-point: at most 15 decimal digits can be faithfully
represented in hexadecimal and binary. For extended precision, the two representations behave
differently: hexadecimal floating-point can faithfully represent 32 decimal digits, while binary
floating-point can faithfully represent 33.

36.5.2. Out-In Conversions


For Out-In conversions, we start with internal floating-point data, convert it to external decimal
format, and then want to convert it back to internal format without losing the precision of the
original internal values. This means we must know how many decimal digits are required; they are
shown in Table 387.
Precision

Binary Digits

Short

24

Hexadecimal
Digits
6

Long

53

14

Extended

28

113

Decimal Digits
9
17
18
35
36

Table 387. Decimal precision required for faithful Out-In conversion

For example, to recover long internal floating-point values converted to decimal and back,
long binary requires 17 decimal digits for faithful representation of the internal value,
long hexadecimal requires 18 decimal digits,

730

Assembler Language Programming for IBM z System Servers

Version 1.00

and (as for In-Out conversions) correct conversion is required.


This is a useful Rule of Thumb for In-Out and Out-In conversions:
In-Out and Out-In Conversions
Out-In conversions need 3 more decimal digits than In-Out.

36.5.3. The PFPO Instruction (*)


The z System PFPO instruction converts floating-point data formats among one another.
Op
010A

Mnem
PFPO

Type
E

Instruction
Perform Floating-Point
Operation

Op

Mnem

Type

Instruction

Table 388. Perform Floating-Point Operation instruction

Its assembler instruction statement has no operands! The floating-point source and target operands are in FPR4 and FPR0 respectively (with their paired registers for extended-precision operands). GR0 is set to a complex bit pattern describing the format of the source and target
operands, and GR1 contains the return code. For example, to convert a short BFP operand in
FPR4 to a long HFP operand in FPR0, you could write
LE
L
PFPO
STD
LTR
JNZ
- - HFPLong DS

4,=EB3.141592645
0,=X01010501
,
0,HFPLong
1,1
WhatNext

Source operand in FPR4, X40490FDB


Convert according to current BFP mode
Convert short BFP to long HFP
Store result, X413243F6C0000000
Check return code
Do something if nonzero

Converted HFP result

The instruction handles many operand combinations; for details, see the z/Architecture Principles
of Operation.

Exercises
36.5.1.(2) + Write a short Assembler Language program defining hexadecimal floating-point
constants for the six 7-digit decimal floating-point values 0.625000xE 1, where x takes values
from 3 to 8. What hexadecimal floating-point values are generated?
36.5.2.(3) If the short hexadecimal floating-point number X40100001 is converted to 7-digit
decimal, what is the result?

36.6. Real and Realistic (Floating-Point) Arithmetic


Computation uses actual numbers, not mathematical real-number abstractions, so we must cope
with problems of precision, rounding, significance, etc. The mathematicians real numbers
provide elegant analyses, but dont always describe the realistic world where weights, dimensions, and other values are known only imprecisely. The quantities used for computation necessarily have finite precision and errors of measurement or estimation, and computational
techniques have finite precision.
The abstract formulation of a problem can help define the form of a computation, but its important to remember that usable results may depend on knowing the behavior of the adaptations you
make in order to calculate meaningful results.

Chapter IX: Floating-Point Data and Operations

731

The laws of real arithmetic such as associativity, distributivity, etc. apply only to abstract
numbers and in limited ways to realistic numbers, so you may sometimes unknowingly make
unsafe assumptions when you write your programs. Well compare real and realistic laws in
Table 389, where real numbers are represented by lower case letters (a,b), and floating-point
numbers are represented by capital letters (A,B).229 The letter r denotes the radix of the representation.
Table 389 (Page 1 of 2). Laws of real and realistic arithmetic

Law

Arithmetic with
real numbers

Closure

The product and sum


of real numbers a and b
are reals.

Commutative
Associative
Addition
Associative
Multiplication

a+b = b+a, ab = ba

Distributive

a(b+c) = ab+bc

Additive Unit
Multiplicative
Unit
Additive
Inverse

(a+b)+c = a+(b+c)
(ab)c = a(bc)

There is a real number


0 such that
a+0 = 0+a = a
There is a real number
1 such that
a1 = 1 a = a
For any real a there is a
real a with
a + ( a)=( a ) + a = 0

Arithmetic with realistic numbers


The product (AB) and sum (A+B) of the floating-point
numbers A and B may not exist in FPF(r,p). Example:
FPF(16,6) (HFP) contains 90009.0 and 0.84375, but not
their sum, difference, quotient, or product.
True for z System and almost all other systems.
Fails. If A, B, and C have the same sign, the results may
differ by r ulps.
Fails. If both products are in range, the results may differ by
2r ulps (fails spectacularly if exponent spills occur).
Fails. If B and C have the same sign, then the results differ
by at most r ulps.
True for most systems (unless underflow intrudes).

True for z System and almost all other systems.

True in all known systems.


Fails to hold in many systems.; there may be no representable inverses. (z System hexadecimal floating-point has no
inverse for any magnitude X02100000= 1 6 63).

Multiplicative
Inverse

Zero Divisor

Cancellation

Division

229

732

For any real a, if a 0


there is a real a 1 with
aa 1 = a 1a = 1

If ab = 0, then at least
one of a or b must
vanish
1. (a b) b = a
2. a( b / a ) = b
3. If ab = ac and
a 0, then b=c
If b 0, and a/b means
ab 1, then b(a/b) = a

Several A values may have the same A 1 ( = 1 A)


Some A 1 values give A A 1 1
In HFP, A(1/A) may differ from 1 by 16 ulps.
If r > 2, a number with fraction 1 r p has r 1 inverses
in FPF(r,p) with chopped arithmetic, and approximately
(r 1)/2 inverses with rounded arithmetic
In HFP, A 1= B 1 means only that A and B may
differ by 16 ulps
In HFP, numbers with fraction 1 nr p have inverse r 1
if 1 n 15
Frequently fails if overflow or underflow occurs.
1. Fails, especially in the presence of underflow or overflow.
2. Fails.
3. Fails. B and C may differ by r 1 ulps.
Fails. If B(A/B) = C, then | A | and | C | may differ by r ulps.

A useful reference is Floating-Point Computation by Pat H. Sterbenz, Prentice-Hall, 1974.


Assembler Language Programming for IBM z System Servers

Version 1.00

Table 389 (Page 2 of 2). Laws of real and realistic arithmetic

Arithmetic with
real numbers

Law
Subtraction

Inequalities

If (a b) means
a + ( b), then
(a+b) b = a
1. a < b
2. If a < b then for
all c, a+c < b + c
3. If a < b and c < d
then a+c < b + d
4. If b < c and a > 0
then ab < ac

Arithmetic with realistic numbers


Frequently fails near underflow threshholds, or if |B| greatly
exceeds |A|.
Fails; strict inequalities must be weakened to tolerate
equality.
1.
2.
3.
4.

A B
A+C B+C
A+C B+D
AB AC

1. Floating-point numbers are actually a subset of the rational numbers, but they also dont
satisfy all the mathematical properties of rationals (which have unbounded numerator and
denominator).
2. Neither equalities nor inequalities reliably persist across floating-point operations.
3. Multiplying any fraction by a power of the radix leaves the fraction unchanged, unless there
is no guard digit and the product is truncated.
4. Inverses of tiny hex numbers overflow: the inverse of X02100001 = HexMax, but any
smaller value causes exponent overflow.
5. An advantage of the binary floating-point representation: inverses exist for all normal values.
6. Some operations create meaningless results. Even in well-behaved programs, ordinary algebraic rules may fail:
Calculation
0 / X 0 ?
1 * X X ?
0 * X 0 ?
X - X 0 ?
X / X 1 ?
X = X TRUE ?
X > Y Y < X ?
-X = 0 - X ?

Possible Problems
Fails for X = 0
Fails for X = NaN
Fails for X = NaN or infinity
Fails for X = NaN or infinity
Fails for X = NaN or infinity
Fails for X = NaN
Fails for X = NaN
Fails for X = +0

This table shows that NaNs and infinity violate many common arithmetic laws.
Numerical analysis is a realistic discipline, coping with realistic problems in a world of realistic
numbers; the real analysis of advanced mathematics is a helpful but occasionally misleading
abstraction because it requires unrealistic conditions such as infinite precision and unbounded
magnitudes.

Exercises
36.6.1.(2) + Table 389 indicates that the additive unit is zero. Give an example of a nonzero
hexadecimal floating-point value A such that A + 0 A.
36.6.2.(2) + Table 389 indicates that the additive unit is zero. Give examples of a nonzero
numeric binary and decimal floating-point value A such that A + 0 A.
36.6.3.(4) Find a short HFP constant A such that A(1/A) differs from 1 by at least 15 ulps.
36.6.4.(2) + In hexadecimal floating-point, what is the value of MaxMin?
36.6.5.(3) + For each floating-point representation, create an example that shows the failure of
additive association.

Chapter IX: Floating-Point Data and Operations

733

36.6.6.(3) + For each floating-point representation, create an example that shows the failure of
multiplicative association.
36.6.7.(3) + For each floating-point representation, create an example that shows the failure of
multiplicative association.
36.6.8.(3) + For each floating-point representation, create an example that shows the failure of
the distributive law.

36.7. When Does Zero Not Behave Like Zero? (*)


Fascinating details
Mathematically, we would expect X 0 = X , X 0=0, and 0 X=0 (for
x 0). In floating-point arithmetic, a zero value doesnt always behave
like a mathematical zero, especially in addition and subtraction.

36.7.1. Hexadecimal Floating-Point


Hexadecimal floating-point Pseudo-zeros have zero fraction and nonzero characteristic. For
example:
Precision
Single
Double
Extended

A representative pseudo-zero
X41000000
X41000000 00000000
X41000000 00000000 33000000 00000000

Table 390. Examples of hexadecimal floating-point pseudo-zeros

If a pseudo-zero is an operand in a multiply operation, or is the dividend in a division operation,


the result is a true zero (that is, + 0). Thus, multiplication and division are well-behaved mathematically in hexadecimal floating-point arithmetic.
For addition and subtraction, the result depends on the differences between the characteristics of
the operands. Figure 465 shows some examples using short-precision operands: the precision of
the sum is degraded as the characteristic difference grows.
LE
LER
AE
LER
AE
LER
AE
LER
AE
LER
AE

4,=E123.456
0,4
0,=X45000000
0,4
0,=X46000000
0,4
0,=X47000000
0,4
0,=X48000000
0,4
0,=X49000000

c(FPR4) = X427B74BC = 123.456


Copy starting value to FPR0
c(FPR4) = X427B7400 = 123.453
Copy starting value to FPR0
c(FPR4) = X427B7000 = 123.434
Copy starting value to FPR0
c(FPR4) = X427B0000 = 123.000
Copy starting value to FPR0
c(FPR4) = X42700000 = 112.000
Copy starting value to FPR0
c(FPR4) = X00000000 = 0.0

Figure 465. Degraded precision in adding hexadecimal floating-point pseudo-zeros

Because the fraction of the operand with the smaller characteristic is shifted right until the characteristics are equal, more and more significant digits are lost.
In the first example, the characteristic difference is 3, so the fraction X 7 B74BC is shifted right
three places; the digit 4 becomes the guard digit and then appears in the normalized result, so
only two digits are lost.
In the last example, a zero fraction is generated and a significance exception is indicated.
Hexadecimal floating-point pseudo-zeros should be used rarely, and only with care.

734

Assembler Language Programming for IBM z System Servers

Version 1.00

36.7.2. Binary Floating-Point


Binary floating-point does not support pseudo-zeros: every zero and nonzero finite number has a
unique representation in each precision, except that zero may have either sign. Arithmetic results
have the mathematically-expected values:
Adding zero to or subtracting zero from any operand that is not a NaN produces the original
operand. (The sign of an exact zero result depends on the rounding mode.)
Dividing zero by any finite operand that is not a NaN produces 0.
Multiplying zero by any operand that is not a NaN produces 0.
The square root of zero is a zero with the same sign.
Operations with behave sensibly.

36.7.3. Decimal Floating-Point


As described in Section 35.3 on page 676, decimal floating-point zeros can have many representations. This can sometimes lead to unintuitive or unexpected results. For example, suppose we
add 1 and 0.0000000:
LD
LD
ADTR
EEDTR
AHI
CUDTR

4,=DD0.0000000
2,=DD 1
0,2,4
6,0
6,-398
7,0

0E-7
Sum in FPR0
Biased exponent in GG6
Exponent in GR6 = -7
c(GG7) = X00000000 10000000

so that the result is 10000000.10 7, with value 1. We see that 1+0=1, but the result in this case
has a very different representation than ordinary arithmetic might predict. If the decimal floatingpoint zero operand had been defined by
4,=DD 0 . 0 0

LD

and the same instructions were executed, the result would be 100.10 2 = 1.00, with value 1
(again!) but with yet another representation.
This behavior isnt limited to zero constants. If the result of an arithmetic operation is zero, we
can get similar results:
LD
SDTR
LD
ADTR
CUDTR
EEDTR
AHI

4,=DD123.456
2,4,4
0,=DD 1
4,2,0
3,4
5,4
6,-398

c(FPR4)=X222C0000 00028E56
c(FPR2)=X222C0000 00000000 ( zero)
c(FPR0)=X22380000 00000001
c(FPR4)=X222C0000 00000400
c(GG3) =C00000000 00001000
Extract biased exponent
Remove bias; c(GR6)=X FFFFFFFD=-3

The operands of the SDTR instruction have 3 significant decimal places, so the resulting zero in
FPR2 has the same quantum. When 1 is added the quantum is preserved, and the result is
100010 3 = 1.000, with value 1 as expected.
As noted earlier, these results are numerically reasonable, but their representation may not be as
easily predictable as with fixed-point binary or decimal arithmetic.

Exercises
36.7.1.(1) + In a hexadecimal floating-point representation of each precision, how many different pseudo-zeros can be created?
36.7.2.(2) In Figure 465, what result will be generated if the second operand is X43000000?
That is, what is the result of this operation:
LE
AE

4,=E123.456
4,=X43000000

c(FPR4) = X427B74BC = 123.456


c(FPR4) = ?
Chapter IX: Floating-Point Data and Operations

735

36.8. Examples of Former Floating-Point Representations and Behaviors (*)


In Table 391, a sample of floating-point representations shows the processor, the base (radix) B
of the significand, the number of base-B digits in the significand, the equivalent number of
decimal digits represented, the exponent width in bits, the instruction format, and the representation of the significand.230
Processor and representation
Pr1me 550 series single
IEEE binary short precision
IBM hex short precision
Burroughs 6700 short precision
CDC 6600/CYBER 70

Base
B
2

Base-B
Digits
23

Equiv.
Dec.
6

Exp.
Wid.
8

2
16
8
2

24
6
13
48

6
6
10
14

8
7
6
11

Format
s/f/e
s/c/f
s/c/f
S/s/e/i
s/e/i

Cray-2 single precision


2
48
14
15
s/e/f
IEEE binary double precision
2
53
15
11
s/c/f
IBM hex double precision
16
14
15
7
s/c/f
IBM hex extended precision
16
28
32
7
s/c/f
Note: s = sign, e = signed exponent, c = characteristic, f = fraction, i = integer.

Significand
Representation
Twos complement
Sign-magnitude
Sign-magnitude
Sign-magnitude
Sign-magnitude
Sign-magnitude
Sign-magnitude
Sign-magnitude
Sign-magnitude

Table 391. Examples of other floating-point representations

Most of these representations use a biased characteristic, but the Cray-2 used a signed exponent.
Two processors (Burroughs and CDC) used a right-adjusted integer significand rather than a leftadjusted fraction, and Burroughs used sign-magnitude representations for both the exponent and
the integer significand.
Some processors had representations for special values:
CDC processors provided representations for infinity and indefinite (what we now call Not
a Number).
The IBM 7030 Stretch provided representations for infinity, infinitesimal (), and OMZ
(Order of Magnitude Zero with significand = 0).
The DEC VAX systems provided a reserved operand with minus sign and exponent zero
that caused an interruption when accessed.
The wide variety of floating-point implementations on past processors led to some of the following oddities that happened on widely used processors:

230

736

Some processors responded to exponent spills by delivering zero, , MaxReal, or MinReal.


Some numbers had no inverse.
A number a had a precisely representable inverse, but aa 1 1.
Some processors treated all sufficiently tiny nonzero numbers z as if they were zero during
multiplication and division, but not during addition or subtraction.
z = y but z t y t for reasonable values of z, y, and t.
1/3 9/27.
y z z y (for example, the Cray-1 traded commutativity for speed).
z 1z 0.
y/z < 0.99 but y z = 0 (caused by underflow to 0).
|z| < 1, but the processor claimed |z| 1.

To see some other floating-point representations, you may enjoy exploring the web for the formats on other old
processors such as the IBM 7030 Stretch, the DEC VAX, and the Harris Series 500.
Assembler Language Programming for IBM z System Servers

Version 1.00

The expressions x < y and (x y) < 0 were exactly equivalent on some systems but not on
others.
Some processors had different over/underflow thresholds for multiplication and/or division
than for addition and/or subtraction.
These many inconsistencies made it quite difficult (if not impossible) to create reliable numeric
software that worked on many systems. 231 This led to the IEEE Floating-Point standard for
binary floating-point, adopted in 1975; its format quickly became an industry standard,
supplanting most of the formats sketched in Table 391.

Exercises
36.8.1.(2) Sketch the formats of the floating-point representations in Table 391 for
Pr1me 550 series single precision
CDC 6600
Cray-2 single precision
36.8.2.(2) + In Table 389, the description of Additive Units says that underflow may cause the
identity to fail. Give an example in hexadecimal floating-point where this can occur.
36.8.3.(3) + The list of computational oddities included the possibility that z = y but
z t y t. Create sensible (non-extreme) short hexadecimal floating-point values that
exhibit this behavior.
36.8.4.(2) Search the web to find the representation used by the Burroughs 6700 for short
floating-point numbers.
36.8.5.(2) + Show the character, integer, and the binary, hexadecimal, and decimal floating-point
values of these four words: X81818181, X A3A3A3A3 , X F5F5F5F5 , X FEFEFEFE .

36.9. Summary
Given the 32-, 64-, and 128-bit floating-point representations, the equivalent decimal precisions
that can be faithfully represented are shown in Table 392.
floating-point
precision
32 bits
64 bits
128 bits

hexadecimal
floating-point
6 digits
15 digits
32 digits

binary floatingpoint
6 digits
15 digits
33 digits

decimal
floating-point
7 digits
16 digits
34 digits

Table 392. Equivalent decimal and floating-point precisions

If precision equivalent to decimal is important, decimal floating-point is best.


Some things to keep in mind:
1. Be careful about optimizing arithmetic expressions. The possible presence of signed zeros,
NaNs, and infinities require care.
2. Predictability is more important than efficiency; getting wrong answers fast helps no one.
3. Respect the parentheses in coded expressions: they often specify a required order of evaluation.

231

Such oddities led someone to propose Murphys Law of Floating-Point: Anything that can go wrong, does on some
computer.
Chapter IX: Floating-Point Data and Operations

737

4. Dont accidentally mix operand lengths (except possibly with hexadecimal floating-point, and
then only if youre very careful!). A number in a floating-point register may have very different representations; for example, the three binary and decimal representations have different exponent field and significand widths.
5. It is best to do all computations in a single mode: hexadecimal, binary, or decimal, with a
single representation for constants and literals.
6. Binary floating-point permits exceptions where none would occur with hexadecimal, such as
when shortening an operand or creating inexact and invalid operation exceptions.
7. Inequalities do not persist across floating-point operations!
8. Dont compare floating-point values for strict equality; use either an inequality, or a comparison for equality within an acceptable tolerance.
9. A smaller radix means that relative error grows more slowly, but more exponent bits are
needed for a given exponent range. For example, binary requires 2 more exponent bits than
hexadecimal for same range.
10. Rounding (as in BFP and DFP arithmetic) compared to truncation (in HFP arithmetic)
means that the magnitude of average error tends to be smaller.
11. Dont confuse the ulp (for HFP and BFP) with the quantum (for DFP). They might seem
to describe the same concept, but an ulp(x) depends on the value of x and may vary by a
factor of 2 (BFP) or 16 (HFP), while the magnitude of a quantum depends only on the
exponent of the number. An ulp if a DFP number is meaningless, because DFP values arent
normalized.
12. The two signed zeros (in BFP and DFP) are distinguishable arithmetically only by division
by zero (producing signed infinities) or using the copy sign instructions. (See Exercise 34.8.3.)
You must think differently about floating-point numbers and arithmetic; so why do we rely on
floating-point arithmetic?
1. It closely approximates the way most of us do most of our calculations, most of the time.
2. It handles most of the hard work automatically.
3. But, remember that it can be difficult to know with certainty when it doesnt work!
4. The secret of success of floating-point computation lies in the fact that we continue to do
arithmetic to p digits of precision even though the accuracy of our intermediate results has
degraded so that we can only guarantee that a few digits are significant.232

Terms and Definitions


real numbers
A powerful abstraction used by mathematicians.
realistic numbers
Numbers used for computation with finite range, precision, and accuracy.
mantissa
A term sometimes used to describe the significand of a floating-point number. Because it can
be confused with the mantissa (fractional part) of a logarithm, avoid its use when describing
floating-point representations.

Programming Problems
Problem 36.1.(5) Suppose your processor does not provide instructions to automatically convert
between floating-point representations. Write a program that accepts strings of 8 hex digits
representing a short binary floating-point value, and converts them to a short hexadecimal

232

738

Quoted from Floating-Point Computation by Pat H. Sterbenz, Prentice-Hall, 1974.


Assembler Language Programming for IBM z System Servers

Version 1.00

floating-point representation using half-up rounding. Display the original and converted values
in hexadecimal, and generate appropriate messages if any conversion problems arise.
Suggested test values include: X80000000, X 7 FFFFFFF , X 7 F7FFFFF , X 3 DCCCCCD ,
X80800000, X FF800000 , and X007FFFFF , but you should create others.
Problem 36.2.(4) Suppose your processor does not provide instructions to automatically convert
between floating-point representations. Write a program that accepts strings of 16 hex digits
representing a long hexadecimal floating-point value, and converts them to a long binary
floating-point representation using rounding to half-even. Display the original and converted
values in hexadecimal. If the HFP value is unnormalized, generate a canonical QNaN.
Suggested test values include: X80000000 00000000 , X 7 FFFFFFF FFFFFFFF ,
X40199999 9999999A , X470CCCCC CCCCCCC5 , X80100000 00000000, and
X413243F6 A8885A31 , but you should create others.
Problem 36.3.(5) Suppose your processor does not provide instructions to automatically convert
between floating-point representations. Write a program that accepts 16 hex digits representing
a long binary floating-point value, and converts them to a long hexadecimal floating-point representation using half-up rounding. Display the original and converted values in hexadecimal,
and generate appropriate messages if any conversion problems arise.
Suggested test values include: X80000000 00000000 , X 7 FFFFFFF FFFFFFFF ,
X 7 FEFFFFF FFFFFFFF , X 3 DCCCCCC CCCCCCCD , X80100000 00000000, and
X FFF00000 00000000 , but you should create others.
Problem 36.4.(3) For each floating-point representation, write instructions that will create a
table of the values of N Factorial (N!) starting at 1! = 1 in the 8-byte floating-point representation. Determine the maximum representable value without causing overflow or underflow
exceptions, and store the value of N for that maximum value as a word integer at HFactMax,
BFactMax, and DFactMax for hexadecimal, binary, and decimal floating-point values respectively.

Chapter IX: Floating-Point Data and Operations

739

740

Assembler Language Programming for IBM z System Servers

Version 1.00

Chapter X: Large Programs and Modularization

XX
XX
XX
XX
XX
XX
XX
XX
XX XX
XXXX
XXXX
XX XX
XX
XX
XX
XX
XX
XX
XX
XX

The two sections of this chapter discuss program modularization:


Section 37 introduces the basic concepts of internal subroutines, focusing on the fundamental
processes of subroutine linkage, argument passing, and status preservation. It then describes
the general linkage conventions used on z System operating systems.
Section 38 describes:

Techniques for managing addressability in large programs (and how the powerful LOCTR
instruction can help).

Separately assembled multi-module applications.

How to write external subroutines callable from Assembler Language and other programming languages.

How separately assembled modules are linked together to form an executable load module
or program object, and how they are loaded into memory.

How to handle changes in addressing modes.

Chapter X: Large Programs and Modularization

741

37. Subroutines and Linkage Conventions

3333333333 777777777777
333333333333 777777777777
33
33 77
77
33
77
33
77
3333
77
3333
77
33
77
33
77
33
33
77
333333333333
77
3333333333
77

Program modularization is a fundamental application development process. We divide a task into


smaller pieces that can be written and tested independently. In this and the next section we will
examine some general features of subroutines, a basic form of modularization.
Subroutines help you divide a programming problem into smaller and more manageable parts. A
calculation needed at many places within a program can be done by including the necessary
instructions at each place they are needed, but it is usually more economical to write the needed
instructions once, and then execute them as needed.
Of course, if a calculation is needed at only one point in a program, it might seem easiest to insert
the instructions there. But we will see that using a subroutine is justifiable because it simplifies
program planning, organization, coding, and debugging. Often, a tested subroutine can be used in
other programs.

37.1. Basic Concepts


Well start with three basic concepts:
Linkage: how to pass control to a subroutine and return.
Argument passing: how to provide data needed by the subroutine and access its results.
Status preservation: how to be sure that nothing important is lost, modified, or destroyed in
the process.
We call the main program the routine that transfers control to the subroutine. The former is said
to call the latter, so the main program is the calling program (or caller) and the subroutine is the
called program (or callee).
The rest of Section 37.1 uses simple examples to illustrate these three basic concepts; many of
them are used in the general linkage conventions discussed in sections 37.2-37.4. For now, well
consider only 32-bit registers.

742

Assembler Language Programming for IBM z System Servers

Version 1.00

37.1.1. Linkage
This problem is relatively simple: we must find a way to transfer control from the caller to the
callee and for the callee to then return to the caller. The calling program must know where to
transfer control to execute the called program, and the called program must know how and where
to return control to the calling program.
To use a trivial (and nonsensical) example, suppose the subroutine starting at an instruction
named ZSet sets the byte named Flag to zero. (For the following examples, assume GR12 has
been established as a base register.)

Next

ZSet

- - J
ZSet
L
2,Noodle
- - - - MVI Flag,0
J
Next

Main program calculates something


Then branches to the subroutine (1)
And then continues
...with something else
Subroutine sets the byte to zero
And returns to the main program (2)

Figure 466. Trivial example of a subroutine (1)

The processing performed by this subroutine can obviously be done more simply without a
subroutine call. The point is that we have (1) transferred control to a subroutine which does
something and then (2) returns control to the caller. In its most primitive form, a subroutine can
be written as a instruction sequence to which a branch is made, and which returns by branching
elsewhere.
Now, suppose we want to call the subroutine starting at ZSet from several different places in the
main program. We see that the return in Figure 466 always branches to the same instruction
(named Next) in the calling program. But we may want to do something different before and after
calling the subroutine each time. Thus we must solve the second half of the linkage problem:
specify where control should be transferred when the subroutine ends.
We can solve this problem by agreeing that when control is transferred to ZSet, GR14 will
contain a return address, the address of the instruction to which the subroutine should branch
when it completes. Then we can make two calls to the subroutine at ZSet as shown in Figure
467.

Next

Ret2
ZSet

- - LA
14,Next
J
ZSet
L
2,Noodle
- - ST
2,Result
LA
14,Ret2
J
ZSet
L
3,Poodle
- - MVI Flag,0
BR
14

Calculate something
Set return address in GR14
Branch to subroutine
On return, begin calculating
...something else
And store it
Set new return address in GR14
Branch to subroutine
...and so forth
Subroutine does its work
And returns to the address in GR14

Figure 467. Trivial example of a subroutine (2)

The Branch and Save instructions provide a simpler solution.

37.1.2. The Branch and Save Instructions


The Branch and Save instructions let you execute both the branch to the called program, and set
the return address. The four instructions are shown in Table 393.

Chapter X: Large Programs and Modularization

743

Op
0D

Mnem Type
BASR R R

Instruction
Branch and Save
(Register)

Op
4D

Mnem
BAS

Type
RX

Instruction
Branch and Save

A75

BRAS

Branch Relative and


Save

C05

BRASL

RIL

Branch Relative and Save


(Long)

RI

Table 393. Branch and Save instructions

We first encountered BASR in Section 10 when we discussed addressability, but there the R2 digit
was assumed to be zero. BAS is an RX-type instruction with the operand format shown in
Section 9.5, and BASR is an RR-type instruction with the operand format illustrated in Section
9.2. BRAS and BRASL use relative-immediate addressing, as discussed in Section 20.1.3.
As with other branch-relative instructions, we often use the extended mnemonics JAS for BRAS
and JASL for BRASL.
The first step in executing a Branch and Save instruction is determining the branch address: for
BASR it is the address in the R2 register (unless R2 is zero, in which case the instruction doesnt
branch) and for the other three instructions the branch address is the Effective Address.
The second step places the Instruction Address from the PSW into general register R1, so that R 1
contains the address of the instruction following the Branch and Save instruction. 233
If the addressing mode is 24 or 31, bit 32 of the R1 register is set to 0 or 1 accordingly, and
bits 0 to 31 are unchanged.
The third and final step replaces the contents of the IA in the PSW with the branch address, so
the next instruction executed will be at the branch address.
Reminder
Remember that the Branch and Save instructions are modal. The address
in the R 1 register depends on the current addressing mode, as described
in Section 20.2.
We can rewrite Figure 467 to use a BAS instruction:

ZSet

- - BAS 14,ZSet
L
2,Noodle
- - ST
2,Result
BAS 14,ZSet
L
3,Poodle
- - MVI Flag,0
BR
14

Main program labors


Branch to subroutine, set GR14
On return, labor again
Store a new result
Call subroutine again
...etc.
Subroutine does required work
Return to address in GR14

Figure 468. Subroutine linkage using a BAS instruction

This program segment is functionally identical to Figure 467 but requires fewer instructions (and
symbols) because the BAS instructions provide both the return addresses (formerly generated by
LA instructions) and the branches to the subroutine (formerly done by the J ZSet instructions).
The RX-type BAS instruction requires a base register to resolve the target address; you can also
use the relative branch form, JAS, to eliminate the need for one or more base registers for instruction addressing.
A BASR instruction can be used in a similar sequence:

233

744

If the Branch and Save instruction is the subject of an EXecute instruction, R1 contains the address of the instruction
following the execute instruction.
Assembler Language Programming for IBM z System Servers

Version 1.00

ZSet

- - LA
BASR
L
- - ST
BASR
L
- - MVI
BR

2,Result
14,15
3,Poodle

Same main program


Put subroutine address in GR15
Branch to subroutine
...etc
Assume that GR15 is unmodified
...etc
Call subroutine again
...etc

FLAG,0
14

Subroutine
Returns to caller

15,ZSet
14,15
2,Noodle

Figure 469. Subroutine linkage using a BASR instruction

This program segment is identical to that in the previous example, except that the BAS
instructions have been replaced by BASR, and GR15 has been preset to contain the entry point
address of the subroutine.
This convention is widely used for calling subroutines. In Figures 468 and 469, we assumed that
the symbol ZSet was addressable from the BAS and LA instructions. If the source program is
large the entry point of the subroutine may be far away, so you might use a technique like this:
- - L
BASR
L
- - ST
BASR
L
- - AdrZSet DC
- - ZSet
MVI
BR
LZSet

2,Result
14,15
3,Poodle

Same main program


Put subroutine address in GR15
Branch to subroutine
...etc
Assume that GR15 is unmodified
...etc
Call subroutine again
...etc

A(ZSet)

Addressable from instruction LZSet

FLAG,0
14

Subroutine (quite far from LZset)


Returns to caller

15,AdrZSet
14,15
2,Noodle

Figure 470. Subroutine linkage using an address constant

Section 38 will explore this theme in more detail.

37.1.3. Argument Passing


Subroutines are rarely this trivial. A subroutine usually operates on data provided to it, and either
modifies the data or uses it to compute new values. The data provided to a subroutine are called
its arguments.234
The caller and callee must agree on the method(s) used for passing arguments. We will sketch a
few simple techniques that require different amounts of information be known to both routines.
For these examples, suppose we must write a subroutine starting with an instruction named
ShftRt which is has two arguments: a logical fullword to be shifted and a fullword integer N. The
subroutine will shift the first argument logically to the right by 2+max(N,0) bit positions: if N is
negative shift right two places, and if N is positive shift N + 2 places.
One simple method places the arguments into agreed-upon general registers. This works only for
data which naturally fits in registers; a different method would be needed for packed decimal or
character data.

234

This terminology comes from the mathematical concept of a function of one or more arguments. Because mathematical functions such as SIN and EXP in higher-level languages are almost always implemented by subroutine calls, we
use the same terminology to describe similar situations even when the called routines are not mathematical functions.
Chapter X: Large Programs and Modularization

745

Now, let the two arguments for the subroutine at ShftRt be placed in registers GR0 and GR1
respectively: the logical argument is in GR0 and the integer N is in GR1. The shifted result is left
in GR0 when control is returned to the caller. As above, we assume the return address is in
GR14.
*
ShftRt

ShftOK

ShftRt Arguments in registers 0 and 1


LTR 1,1
Test value of N
JNM ShftOK
Branch if nonnegative
SR
1,1
Set N to zero if it was minus
SRL 0,2(1)
Shift (2+max(N,0)) bit positions
BR
14
Return to caller

Figure 471. Simple shift subroutine (1)

While this instruction sequence is straightforward, a possibly undesirable side-effect is created by


the subroutine: if the argument N in GR1 is negative, GR1 is set to zero. If the calling program
did not need to use the contents of GR1 after the call there is no problem. Otherwise, we might
rewrite the routine as in Figure 472:
ShftRt

SRL
LTR
BNPR
SRL
BR

0,2
1,1
14
0,0(1)
14

Shift logical argument 2 places


Test integer value N
Return to caller if not positive
Otherwise shift N more places
And return to caller

Figure 472. Simple shift subroutine (2)

This is better because the subroutine makes as few changes to the callers registers as possible.
A second way to pass arguments is to place them in named memory areas. This is sometimes
used for operands (such as packed decimal data and character strings) that must be processed in
memory. For example, suppose the argument to be shifted is stored in a word named Logic and
the integer value N is stored in a word named NN. Assuming again that the caller expects the
shifted result to be returned in GR0, we could write the subroutine as in Figure 473.
ShftRt

ShftOK

L
L
LTR
JNM
SR
SRL
BR

0,Logic
1,NN
1,1
ShftOK
1,1
0,2(1)
14

Get argument to be shifted


Get number of shifts, N
Check shift count
Branch if not negative
Set count to zero
Shift by required amount
Return result to caller in GR0

Figure 473. Simple shift subroutine with named arguments (3)

In this case we have used the same technique as in Figure 466, but no harm is done by the SR
instruction that sets GR1 to zero because the value of N stored at NN is unchanged. You can mix
these techniques; some variations are illustrated in the Exercises.
A more powerful technique is to use argument addresses. Then, arguments can be anywhere in
memory, and the subroutine is passed the addresses of the arguments. This method can be used
for arguments of any type and is preferable as a general scheme; the simpler methods just
described are efficient when restricted to particular types of data. First, suppose the address of the
logical argument is in GR2, and the address of N is in GR3.

746

Assembler Language Programming for IBM z System Servers

Version 1.00

*
ShftRt

ShftRt argument addresses in GR2, GR3


L
0,0(0,2)
Get logical argument
L
1,0(0,3)
Get integer argument
SRL 0,2
Shift logical argument 2 places
LTR 1,1
Now test integer argument
BNPR 14
Return if negative or zero
SRL 0,0(1)
Shift N places
BR
14
And return result in GR0

Figure 474. Simple shift subroutine (4) using argument addresses

A key advantage of passing arguments or their addresses in registers is that the subroutine need
not know where the arguments are, nor whether they would be addressable within the subroutine.
Now, suppose the argument addresses are also in memory: let the address of the logical argument
be in a word named AdrLogic and the address of the integer argument N be in a word named
AdrN. Then we can write the subroutine as in Figure 475:
*
ShftRt

ShftRt argument addresses in named memory locations


L
1,AdrLogic
Get first argument address
L
0,0(0,1)
Get logical argument in GR0
SRL 0,2
Shift right 2 bit positions
L
1,AdrN
Get second argument address
L
1,0(0,1)
Get integer argument in GR1
LTR 1,1
Test sign of N
BNPR 14
Return if not positive
SRL 0,0(1)
Shift remaining N bit positions
BR
14
And return

Figure 475. Simple shift subroutine (5) with argument addresses in memory

This example is close to the standard argument-passing convention used by z System operating
systems that well discuss in Section 37.2.
In some specialized cases the return address can be used to address the arguments or the argument
addresses. This is done by placing them inline: the data or data addresses are placed into the
instruction sequence following the Branch and Save that links to the subroutine.
To illustrate inline arguments, first suppose the ShftRt subroutine is written so that the logical
argument is in GR0 on entry and return, but the number of shifts is contained in a halfword
immediately following the Branch and Save instruction. On entry to the subroutine, R14 contains
the address of the halfword integer shift amount, and control must return to the instruction following that halfword.
- - L
0,Data1
BAS 14,ShftRt1
DC
H 5
ST
0,Result1
- - L
0,Data2
BAS 14,ShftRt1
DC
H -4
ST
0,Result2

Call the subroutine


Get first logical data item
Call ShftRt1 subroutine
Shift amount = +5
Store shifted result
Get second data item
Call subroutine again
Shift amount = -4
Store second result

Figure 476. Subroutine call with inline arguments

We cant use the address in R14 for the return address, because we would branch to the halfword
constant! The subroutine must account for the 2-byte length of the inline parameter when it
returns:

Chapter X: Large Programs and Modularization

747

*
Subroutine ShftRt1 with inline halfword shift-count argument
ShftRt1 LH
1,0(0,14)
Get halfword shift argument N
LTR 1,1
Test sign
JNM ShftOK
Branch if not negative
SR
1,1
Clear GR1 to zero
ShftOK SRL 0,2(1)
Perform required shifts
B
2(,14) 
Return, stepping past argument
Figure 477. Subroutine returning past inline argument

For a further variation on this inline-argument scheme, suppose the arguments are two fullwords
containing the addresses of the arguments. The call to the subroutine could then be written:

Logic
NN
Result

- - CNOP
BAS
DC
ST
- - DS
DS
DS

0,4
14,ShftRt2
A(Logic,NN)
0,Result

Align to fullword boundary


Call ShftRt2 subroutine
Argument addresses
Store shifted result

F
F
F

Logical datum to be shifted


Shift amount
Space for result

Figure 478. Subroutine call with inline argument addresses

The CNOP statement is needed to guarantee that the 4-byte BAS instruction falls on a fullword
boundary, so that no space will be wasted between the BAS and the address constants. Otherwise, a program interruption might be generated by the subroutine. (See Exercise 37.1.6.)
A ShftRt2 subroutine called with these arguments could be written as follows:
ShftRt2 LM
L
L
SRL
LTR
BNP
SRL
B

1,2,0(14)
0,0(0,1)
1,0(0,2)
0,2(0)
1,1
8(0,14) 
0,0(1)
8(0,14) 

Get argument addresses


Fetch logical datum
...and shift amount
Shift two places
Now test shift amount
If not +, return to caller
Otherwise perform remaining shifts
...and return

In both versions of this subroutine, the RX form of the return branch instruction (rather than
RR form) must be used so that the displacement of the BC instruction can contain the length of
the arguments to be skipped.
The technique of inline arguments is discouraged today because it can seriously impact program
performance, but it was widely used in the past and sometimes appears in instructions generated
by operating system macros. It is especially inefficient if the inline arguments vary each time the
subroutine is called.

37.1.4. Returned Values


Each of the schemes for passing arguments to the subroutine can be also used for returning computed results to the calling program. (See Exercise 37.1.2.)
When the returned value can be held naturally in a register, we often return it in a register; or, we
might store it in a specified place in memory. To illustrate the latter, suppose our general
argument-passing scheme above is used with three address arguments. The first two address the
logical word and shift count, and the third address in the address list points to a word where the
result is to be stored. Assuming GR1 contains the address of the first of the three argument
addresses, we can write the subroutine as follows:

748

Assembler Language Programming for IBM z System Servers

Version 1.00

*
GR1 has address of argument and result addresses
ShftRt3 LM
2,4,0(1)
Get argument and result addresses
L
0,0(0,2)
Load logical argument
L
1,0(0,3)
Load shift amount N
LTR 1,1
Test sign of shift count
JNM ShftOK
Branch if not negative
SR
1,1
Set shift to zero otherwise
ShftOK SRL 0,2(1)
Perform the required shifts
ST
0,0(0,4)
Store result in given location
BR
14
Return to caller
Figure 479. Subroutine with argument address list

The important feature of this example is that GR1 points to a list of argument addresses; well see
this again in Section 37.3.

37.1.5. Status Preservation


The previous examples assumed that all registers except GR14 were available for use and could be
modified by the subroutine. This could conflict with registers used in the calling program. For
example, in Figure 479 registers GR0 through GR4 were modified.
Two decisions must be made: what should be preserved, and which routine should do the preserving: caller or callee? Among items that might need to be saved for later use by the caller are
the general registers, the floating-point registers, and other things like the Condition Code and
Program Mask.
Consider first the problem of determining which routine should do the status preservation. For
simplicity, we take this to mean saving and restoring of the general registers. If the calling program
saves all the registers before branching to the subroutine, and restores them on return, it might be
doing a lot of unnecessary work; a subroutine like ShftRt uses very few registers, but the writer of
the calling program would typically prepare for the worst and save all the registers.
More critically, whatever registers were used for addressability in the calling program may have
been destroyed by the subroutine, which needs only to branch to the instruction at the return
address. This could cause serious problems when the caller tries to restore its registers. (See Exercise 37.1.7.)
Thus, its better for the called routine to save and restore registers. The subroutine can take
advantage of its (possibly) economical use of registers by saving and restoring only the ones it
modifies.
There are also advantages to not preserving some registers. In Figure 475 only GR1 is modified,
so there could easily be a convention between caller and callee that GR1 may be used for any
necessary purpose without preserving its contents. (Such a register is sometimes called a scratch
register or a volatile register: its contents may evaporate across calls.) The extra time and
memory needed for status preservation on each subroutine call may be less if we agree to let the
subroutine modify and not restore a designated group of registers.
There are many solutions to the problems of status preservation; this example shows a simple
technique. Suppose we rewrite Figure 479 so that only GR0 is modified (containing the result),
and GR1 through GR3 are restored before returning.

Chapter X: Large Programs and Modularization

749

*
ShftRt4 subroutine saves and restores GR1-GR3
ShftRt4 STM 1,3,ShftSave
Save GR1 through GR3
LM
2,3,0(1)
Get argument addresses
L
0,0(0,2)
Get first argument in GR0
L
3,0(0,3)
Get second argument in GR3
LTR 3,3
Test sign of shift amount
JNM ShftOK
Branch if non-negative
SR
3,3
Set shift count to zero
ShftOK SRL 0,2(3)
Shift by required amount
LM
1,3,ShftSave
Restore GR1-GR3
BR
14
Return to caller
ShftSave DS
3F
Save area for 3 registers
Figure 480. Subroutine saves and restores registers

Exercises
37.1.1.(1) Write a version of the ShftRt subroutine that receives the logical argument in GR0,
and the integer argument N is in a fullword area of memory named NN. The return address is
in GR14.
37.1.2.(1) Write a version of the ShftRt subroutine that expects its arguments to be in fullword
areas of memory named Logic and NN and which leaves the result in a fullword area of memory
named Result. The return address is in GR14.
37.1.3.(2) + What will be found in GR R 1, and what instruction will be fetched next, if the
subject instruction of an EX is a Branch and Save?
37.1.4.(3) + A programmer asked whether or how the actions of the two instructions
BASR 2,0

and

BASR 2,2

differ; he believed that they are identical except that the latter takes slightly longer. Explain how
and why this is incorrect.
37.1.5.(3) Describe the action of the following sequence of instructions:
BASR 3,0
- - BASR 3,3
- - BASR 3,3
- - -

First block of code


Second block of code
Etc.

37.1.6.(2) + In Figure 478, what problems might occur if the CNOP instruction is omitted?
37.1.7.(3) Suppose the calling program saves and restores its own registers, and that the called
routine returns to its caller using this (nonstandard) instruction sequence:
LR
S
LM
B

1,14
1,=F4095
2,15,=14F 0
4095(,1)

Move return address to GR1


Subtract 4095 from ret addr
Have fun with the other regs
And return to the caller, with
An odd address in GR14 (HaHa)

State the conditions under which the calling program could re-establish its own registers.
37.1.8.(3) The BASR instruction with operands R 1,R 2, when used for subroutine branching,
is functionally identical to the instruction
BAS

750

R1,0(0,R2)

Assembler Language Programming for IBM z System Servers

Version 1.00

Why then is there any use for BASR? Can you think of any reasons why the CPU architects
included it in the instruction set? (Apply the same considerations to the instruction pairs
BC/BCR and BCT/BCTR.)
37.1.9.(2) + What will happen at execution time when these instructions are executed?
LA
4,XYZ
BASR 5,0
BASR 4,5

Address of XYZ in GR4

37.1.10.(2) + Rewrite the instructions in Figure 480 so that only two registers need to be saved
and restored.
37.1.11.(2) + Rewrite the instructions in Figure 480 so that only one register needs to be saved
and restored. Is this solution likely to be more or less efficient than your solution to Exercise
37.1.10?

37.2. A General Linkage Convention


Section 37.1 described basic aspects of internal subroutines written as part of your source
program. You can use these basic techniques to write internal subroutines using almost any workable conventions. (Well discuss external subroutines in Section 38.)
As your subroutines grow in size and complexity, you will want to use a more standard set of
conventions.
Section 37.3 describes a general scheme for passing arguments.
Section 37.4 describes status preservation using save areas and register-saving conventions.
Some additional conventions are described in Section 37.5.
Section 37.4 will summarize the conventions used by most operating systems on z System.
We describe subroutines using several important terms.
The entry point of a subroutine is the first instruction to be executed when it receives control
from the caller.
The return address is set by the caller to the address of the first instruction to receive control
when the subroutine terminates its execution.
Values passed to a subroutine are arguments and variables using those values in the subroutine
are parameters.
This example may help: suppose we need a subroutine Add2 that adds two integers and stores
their sum. We might define Add2(X,Y,Z) to mean Add the values of X and Y and store their
sum at Z, even though we dont know the values associated with X and Y. We might think
of the subroutine doing something like this:
L
A
ST

0,X
0,Y
0,Z

Get first value from caller


Add second value from caller
Store sum where caller specifies

If we want the Add2 subroutine to add the integers at A and B and store their sum at C, we
could write something like CALL Add2(A,B,C). In this case, A, B, and C are the arguments of
the call to Add2, and X, Y, and Z are the parameters of Add2. We associate arguments and
parameters in order from left to right: argument A is associated with parameter X, B with Y,
and C with Z. Another invocation like CALL Add2(D,E,F) will associate D with X, E with Y,
and F with Z.
Thus, arguments have values supplied by the caller, while parameters are place-holders in the
called subroutine. Parameters let the called routine use its own names to refer to the callers
arguments (whose names may not be known to the callee); this is especially true for separately
assembled routines.

Chapter X: Large Programs and Modularization

751

37.3. Argument Passing


The previous examples have illustrated many ways to pass arguments. One further refinement
provides a very general method. Suppose, as in Figure 480, that the addresses of the arguments
are in successive words in memory, and when the subroutine is called register GR1 contains the
address of the first address; this is illustrated in Figure 481, where we use 32-bit addresses. (Well
discuss 64-bit addresses shortly.)

GR1
A(arg 1)
first argument

A(arg 2)


second argument

argument address list

Figure 481. General argument-passing scheme

The argument addresses in the successive fullwords in memory form the argument address list.
Figure 482 illustrates a call to a ShftRt5 subroutine; the first instruction is Load Address, not
Load, so GR1 contains the address of the argument address list.
LA
1,ArgList
BAS 14,ShftRt5
ST
0,Result
- - Logic
DS
F
ArgList DC
A(Logic,NN)
Result DS
F
NN
DS
F

GR1 points to address list


Call ShftRt5 subroutine
Store shifted result
Argument to be shifted
Argument address list
Space for result
Number of shifts

Figure 482. Subroutine call using an argument address list

The arguments (Logic and NN) could have had any names and could be anywhere in the program;
only the two address constants containing their addresses need be contiguous (and in this
example, addressable). A ShftRt5 subroutine using this argument-passing convention is shown in
Figure 483.
*
Argument address list pointer in GR1
ShftRt5 LM
2,3,0(1)
Get argument addresses in GR2, GR3
L
0,0(0,2)
Get 1st (logical) argument in GR0
L
1,0(0,3)
Get 2nd (integer) argument in GR1
SRL 0,2
Shift 2 places
LTR 1,1
Test second argument
BNPR 14
Return if it s not positive
SRL 0,0(1)
Otherwise shift N places
BR
14
And return
Figure 483. Subroutine called with an argument address list

With the exception of the first instruction, this example is essentially the same as in Figure 474.
If we want to call this subroutine with other arguments, we can write instructions to build the
argument address list, as illustrated in Figure 484.

752

Assembler Language Programming for IBM z System Servers

Version 1.00

ST
7,LogicTmp
ST
4,NTemp
LA
0,LogicTmp
LA
1,NTemp
STM 0,1,ArgList
LA
1,ArgList
JAS 14,ShftRt5
- - ArgList DS
2A
NTemp
DS
F
LogicTmp DS
F

Store a different logical variable


Store a different shift count
c(GR0) = A(LogicTmp)
c(GR1) = A(NTemp)
Store argument addresses in list
c(GR1) = A(argument address list)
Call the ShftRt5 subroutine
Space for 2 argument addresses
Space for a shift count
Space for a logical variable

Figure 484. Constructing an argument address list

37.3.1. Variable-Length Argument Lists


Sometimes a subroutine may accept a variable number of arguments. Thus, we need a way for a
subroutine to determine the number of arguments passed to it. This is done by setting the leftmost bit of the each 32-bit argument address to zero, except for the last argument address where
we set its leftmost bit to 1. For example, to call a subroutine with two and then with three arguments, we could define the argument address lists as
ArgList1 DC
ArgList2 DC

A(ArgA1,ArgA2+X80000000)
A(ArgB1,ArgB2,ArgB3+X80000000)

Two arguments
Three arguments

Figure 485. Two variable-length argument lists

and the subroutine can determine the number of arguments passed to it. To illustrate, suppose a
subroutine named AddHW is called with these two argument address lists. The routine is to return
the sum of the halfword integer arguments in GR0. We can call the subroutine with instructions
like these:
LA
1,ArgPtrs
GR1 points to argument list
JAS 14,AddHW
- - HiBit
Equ X80000000
High-order bit for 32-bit address
ArgPtrs DC
A(Arg1,Val4,Whenever,Track+HiBit) Arg address list
Track
DC
H13030
A halfword value
Val4
DC
H -7294
Another
Whenever DC
H2015
Another halfword value
Arg1
DC
H12345
Still another halfword value
Figure 486. Calling a subroutine with a variable-length argument list

This example shows that the arguments can be anywhere in the calling program, not necessarily
in any order. The AddHW subroutine could be written as in Figure 487:
AddHW
SR
AddLoop L
AH
LA
LTR
JNM
BR

0,0
2,0(0,1)
0,0(0,2)
1,4(0,1)
2,2
AddLoop
14

Clear GR0 for sum


Pick up an argument address
Add the argument to the sum
Increment address list pointer
Test if we just added the last
Branch if not done
Otherwise return sum to caller

Figure 487. Subroutine called with a variable-length argument list

The LTR instruction checks the high-order bit of the address of the just-added argument to test
whether it was the last in the list.
In 24- and 31-bit addressing mode, where addresses can be held in a 32-bit register and word, a
variable-length argument list looks like this:

Chapter X: Large Programs and Modularization

753

GR1
0
A(argument 1)

0
A(argument 2)

:
:
:
:

1
A(argument n)

Figure 488. Sketch of a variable-length argument list

This is the standard argument address list for 32-bit addresses: the high-order bit of the address of
the last argument is set to 1.

37.3.2. Argument Lists with 64-Bit Addresses


At the time of this writing, no conventions have been established for variable-length lists of 64-bit
argument addresses, or for setting a return flag. Some possible methods include the following; all
require agreement between caller and callee; each method assumes GR1 (or GG1) contains the
address of the list.
1. After the last argument address, add a doubleword of all one-bits. (This is sometimes called a
fence.)

GR1 or GG1

AD(argument 1)

:
:

AD(argument n)

X FFFFFFFFFFFFFFFFF

2. After the last argument address, add a doubleword of all zero-bits.


3. Immediately precede the list with a halfword integer containing the number of argument
addresses. (This requires correct alignment of the halfword.)
ORG *+2,8,-2
Arglist DC
Y(NArgs)
DC
AD(Argument_1)
- - DC
AD(Argument_n)
NArgs
Equ (*-(Arglist+2))/8

Align to halfword before doubleword


Number of argument addresses
Address of 1st argument
Address of nth argument
Number of argument addresses

Figure 489. Sample 64-bit argument list addresses

(See Exercise 37.3.5.)


4. The first doubleword in the argument list contains the number of argument addresses that
follow it:
Arglist DC
AD(NArgs)
DC
AD(Argument_1)
- - DC
AD(Argument_n)
NArgs
Equ (*-Arglist)/8-1

754

Number of argument addresses


Address of 1st argument
Address of nth argument
Number of argument addresses

Assembler Language Programming for IBM z System Servers

Version 1.00

Exercises
37.3.1.(2) Write a version of the ShftRt subroutine that uses an argument address list like that
in Figure 481. The first and second addresses point to the word to be shifted and the shift
count. The third address in the list is the address of the fullword area where the result is to be
stored. The return address is in R14. Restore all registers to the contents they had on entry to
the subroutine.
37.3.2.(3) + Write a subroutine starting at an instruction named AMax that has two arguments,
passed according to the general scheme illustrated in Figure 481. The first argument is the
lowest addressed element of an array of word integers, and the second argument is a positive
word integer containing the number of elements in the array. The subroutine should return to
the address in GR14 with the largest element of the array in GR0. The subroutine should save
and restore the contents of any registers modified by the subroutine.
37.3.3.(3) Write a subroutine starting at an instruction named CMax like that in Exercise 37.3.2,
except that the array elements are addresses pointing to character strings prefixed with a
halfword length field containing the number of bytes in the following string. Compare the
strings, and return in GR1 the address of the string comparing higher than any of the others.
Assume that shorter strings are padded with blanks. (Hint: the CLCL instruction may help.)
37.3.4.(3) + Write a subroutine to count the number of 1-bits in a string of bytes. The subroutine entry point should be named NBITS and a typical standard call from a high-level language
would look like
CALL NBITS( String, StrgLen, NCount )
The first argument is the address of the first byte of the string, the second argument is a word
integer containing the number of bytes in the string (not including the length of this word!), and
the third argument is where the count of 1-bits should be stored. If the second argument is not
strictly positive, set the bit count to zero.
37.3.5.(2) + In Figure 489 on page 754, explain why the first operand of the ORG instruction
is *+2 instead of simply *.
37.3.6.(2) + Criticize the following schemes for passing a variable-length list of arguments to a
subroutine, using 32-bit argument addresses, and compare them to the standard convention.
1. The number of arguments is contained in the leftmost byte of R1 on entry to the subroutine.
2. The end of the argument list is indicated by the presence of a fullword zero following the
last valid argument address.
3. The first fullword in the argument address list holds the number of argument addresses in
the rest of the list.
37.3.7.(2) The IBM Model 026 card punch produces holes in a card according the the old BCD
character representation. The important differences between it and the EBCDIC representation
are that the BCD characters =+() punched by an 026 produce the same hole configurations as
the characters @#&>< in the EBCDIC representation produced by a Model 029 card punch.
Write a subroutine named CONVT that will convert all occurrences of the characters @#&>< in a
character string to the characters =+() respectively. That is, replace each @ by , each # by =,
each & by +, and so forth. The subroutine should use standard linkage, parameter passing, and
status-preservation conventions. There are two parameters: the string of characters, and the
length of the string. (Table 166 on page 430 may help.)

Chapter X: Large Programs and Modularization

755

37.4. Save Areas


Well start with conventions used for 32-bit registers.
If a register save area is used within a program, we must necessarily modify some part of the
program itself. While this is not a problem for many applications, there are times when we want
to write re-enterable code that can be shared by many simultaneously executing programs. This
requires different techniques for allocating save areas.
For now, well consider programs that contain internal save areas. Such programs are not reentrant; well see the changes needed to support re-entrant programs in Chapter XI.
By convention, the caller provides a standard 18-word save area, and its address is passed to the
callee in GR13. The general registers are stored starting at offset + 12 in the order GR14, GR15,
GR0, GR1, GR2, ..., GR12. The easiest way to save the registers is to execute the instruction
STM

14,12,12(13)

Save GR14-GR12 in caller s save area

before the called program modifies any of them. This is often one of the first instructions executed
by a called program.
Table 394 shows the contents of a standard 18-word save area. (Note that words are numbered
starting at zero.)
Word
0
1

Offset
0
4

Offset
X 0
X 4

X 8

3
4
5
6
7
...
17

12
16
20
24
28
...
68

X C
X 1 0
X 1 4
X 1 8
X 1C
...
X 4 4

How this word is used


Special Purpose Data; not to be modified
Address of callers save area; stored here by the
routine containing this save area (back chain)
Address of the save area in the subroutine most
recently called by this routine; put here by that subroutine (forward chain)
c(GR14) (return address to caller)
c(GR15) (entry point address of this routine)
c(GR0)
c(GR1)
c(GR2)
...
c(GR12)

Table 394. Standard (Format-0) Save Area

Assuming that our routine B was called by routine A, and that B will call routine C, Figure 490
shows a sketch of a standard save area that we provide:

756

Assembler Language Programming for IBM z System Servers

Version 1.00

 4 bytes

Offset 0 Reserved

Save area provided by this routine

+4 Back chain
Caller A s Save Area

+8 Forward chain
Callee C s Save Area

+12 Save c(GR14)

+16 Save c(GR15)

+20 Save c(GR0)

+24 Save c(GR1)

:
:
:
:

+64 Save c(GR11)

+68 Save c(GR12)

Figure 490. Standard save area layout

The first word of the save area is used for special purposes by some high-level languages, and
should not be modified in any way.235 The second and third words are used to chain (link) the
save areas in a doubly-linked list.
Suppose the save area is in routine B, that routine B was called from routine A, and that B will
call routine C, as in Figure 491.
Routine A
Routine B
Routine C

Call C

Call B

A s save area
B s save area
C s save area

Figure 491. Sample subroutine calling sequence

To show how save areas are used and how they are chained, we suppose routine B is called by
routine A. Figure 492 shows instructions used at the entry point of B; these are typical of many
subroutines.

235

In your Assembler Language routine it may be prudent to zero the first word of the save area you provide to routines
you call. But dont touch the first word of any other routines save area if it was created by a high-level language.
Chapter X: Large Programs and Modularization

757

STM
BASR
Using
ST

14,12,12(13)
12,0
*,12
13,BSave+4

*
*

Save registers in A s area


Establish local base for B
Addressability for B
Store address of the caller s
... area at word 2 of our area
... (back chain from B to A)
Copy GR13 temporarily to GR2
Establish address of our area
... in GR13 for calls to C
And store the address of our
... save area in A s save area
... (forward chain from A to B)

LR
LA

2,13
13,BSave

ST

13,8(0,2)

- - BSave DC
18F 0

Save area in routine B

*
*

Figure 492. Save area chaining instructions

These instructions put the address of Bs save area into R13, so that routine B can call lower-level
routines such as C. After a sequence of subroutine calls, the chained save areas would then
appear as in Figure 493.
Routine A
Routine B
Routine C
:
:
:
:
:
:
:
:
:
:
:
:






back chain back chain back chain



forward chain forward chain forward chain

:
:
:
:
:
:
: A s registers :
: B s registers :
:
:
: saved by B
:
: saved by C
:
:
:
:
:
:
:
:
:

Save Area in A
Save Area in B
Save Area in C
Figure 493. Chained save areas

To return control to the calling program, we restore the registers and branch to the return address.
For a routine having its own save area (as for B, in Figure 492), the address of the save area in
the calling program A must be retrieved before As registers can be reloaded. Because the address
of Bs save area is in GR13, we use the typical subroutine return instructions shown in Figure
494.
L
LM
BR

13,4(,13)
14,12,12(13)
14

Retrieve address of caller s area


Restore all registers
Return to caller

Figure 494. Reloading registers and returning to a caller

It is not necessary to save and then restore all the general registers, so long as the others are not
modified in any way.

758

Assembler Language Programming for IBM z System Servers

Version 1.00

37.4.1. Extended Save Area Conventions (*)


When your programs are executed in an environment using 64-bit registers, the save area conventions can be more complex. There are three situations to consider:
1. Your calling and called programs use only 32-bit registers.
You dont need to do anything different; continue to use the standard (Format-0) save areas
shown in Table 394.
2. Your calling program has provided a 144-byte save area, or your program is executing in
64-bit addressing mode.
Use the Format-4 save area described in Section 37.4.2, Table 395.
3. Your calling program uses only 32-bit registers (and provides a standard 72-byte, 18-word
save area) but your (called) program uses 64-bit registers.
Use the Format-5 save area described in Section 37.4.3, Table 396 on page 761.
As before, we assume the save areas are internal to the programs.

37.4.2. Format-4 Save Area Conventions for 64-bit Registers (*)


We cant use a standard 18-word save area because forward and back chains are 64-bit addresses.
Instead, we use the Format-4 save area shown in Table 395. The chain-address fields are now
at the end of a Format-4 save area. (Note that words are numbered starting at zero.)
The second word of a Format-4 save area contains the identifying characters F4SA. This is used by
diagnostic tools to know how to display the contents of the save area.
Word
0
1

Offset
0
4

Offset
X 0
X 4

2-3
4-5
6-7
8-9
10-11
...
30-31
32-33

8
16
24
32
40
...
120
128

X 8
X 1 0
X 1 8
X 2 0
X 2 8
...
X 7 8
X 8 0

34-35

136

X 8 8

How this field is used


Special Purpose Data; not to be modified
CF4SA (Used by diagnostic tools to properly
display register contents and locate chain addresses.)
c(GG14) (return address in the caller)
c(GG15) (entry point address in the called routine)
c(GG0)
c(GG1)
c(GR2)
...
c(GG12)
Address of the save area in the subroutine that called
this routine (back chain)
Address of the save area in the subroutine most
recently called by this routine; put here by that subroutine (forward chain)

Table 395. Standard Format-4 save area

A representation of a Format-4 save area is shown in Figure 495.

Chapter X: Large Programs and Modularization

759

 8 bytes

Offset 0 Reserved
C F4SA

+8
Save c(GG14)

+16
Save c(GG15)

+24
Save c(GG0)

:
:
:
:

+112
Save c(GG11)

+120
Save c(GG12)

+128 AD(previous save area)

+136 AD(next save area)

Figure 495. Format-4 save area layout

To show how to use a Format-4 save area in a program executing in 64-bit addressing mode that
was called by a program providing a Format-4 save area, you might use instructions like those in
Figure 496:
CSECT64 CSect ,
CSECT64 AMode 64
Addressing mode 64
CSECT64 RMode Any
Residence anywhere below the bar
STMG 14,12,8(13)
Save 64-bit registers in caller s area
LARL 12,CSECT64
Set local base register
USing CSECT64,12
Establish addressability
LA
11,MySave
Point to local save area
STG 11,136(,13)
Save forward link in caller s area
STG 13,MySave+128
Save backward link in local area
LGR 13,11
Set GG13 to point to local area
- - Do good things
Return LG
13,MySave+128
Retrieve caller s are address
LMG 14,12,8(13)
Restore registers
BR
14
Return
MySave DC
F 0 , C F4SA , 1 7D 0
Format-4 save area
Figure 496. Example of using a Format-4 save area

37.4.3. Format-5 Save Area Conventions for 32- and 64-bit Registers (*)
In this case, your caller has provided a standard 18-word save area, but your routine will need to
save the high-order halves of the general registers because his caller might be using all 64 bits of
the registers. In this case, you need a Format-5 save area for your routine, as described in Table
396 and illustrated in Figure 496.

760

Assembler Language Programming for IBM z System Servers

Version 1.00

Word
0
1

Offset
0
4

Offset
X 0
X 4

2-3

X 8

4-5
6-7
8-9
10-11
...
30-31
32-33

16
24
32
40
...
120
128

X 1 0
X 1 8
X 2 0
X 2 8
...
X 7 8
X 8 0

34-35

136

X 8 8

36-51

144

X 9 0

How this field is used


Special Purpose Data; not to be modified
CF5SA (Used by diagnostic tools to properly
display register contents and determine chaining
links.)
c(GG14) (return address in A)
c(GG15) (entry point address in B)
c(GG0)
c(GG1)
c(GR2)
...
c(GG12)
Address of the save area in the subroutine (A) that
called this routine (B) (back chain)
Address of the save area in the subroutine most
recently called by B; put here by that subroutine (C)
(forward chain)
High halves of c(GG0)-c(GG15)

Table 396. Standard Format-5 save area

Figure 497 shows the layout of a Format-5 save area.


 8 bytes

Offset 0 Reserved
C F5SA

+8
Save c(GG14)

+16
Save c(GG15)

+24
Save c(GG0)

:
:
:
:

+112
Save c(GG11)

+120
Save c(GG12)

+128 AD(previous save area)

+136 AD(next save area)

+144
HiHalf(GG0)

HiHalf(GG1)

:
:
:
:
:
:

+200
HiHalf(GG14)
HiHalf(GG15)

For
saving
our (B)
registers
when
calling
a lower
level
routine (C)

For
saving our
caller s (A)
high-order
registers
before we
use them

Figure 497. Format-5 save area layout

First, you save the callers 32-bit registers in his save area, as in Figure 492. Then, you save the
high-order halves of all 16 general registers in your Format-5 save area in the 16 words starting at
offset + 144.
Chapter X: Large Programs and Modularization

761

STM
STMH
STG
LA
ST
LGR
- - BSave5 DS
DS
DC
DS
BSaveBCh DS
BSaveFCh DS
BSaveHiH DS

14,12,12(13)
0,15,BSaveHiH
13,BSaveBCh
1,BSave5
1,8(,13)
13,1

Save low-order halves of GG14-GG12


Save high-order halves of GG0-GG15
Save 64-bit back chain address
31-bit addr of our Format-5 save area
Store forward chain in caller s area
Point GG13 to our save area

0D
F
C F5SA
13D
D
D
8D

208-byte Format-5 save area


Reserved
Format identifier
Save area for GG14-GG12
Back chain address
Forward chain address
Save high halves of GG0-GG15

Figure 498. Saving registers using a Format-5 save area

After executing these instructions your program can use the 64-bit general registers. When its
time to return to the caller, the high-order halves of the registers must be restored, as in Figure
499.
LMH
LG
LM
BR

0,15,BSaveHiH
13,BSaveBCh
14,12,12(13)
14

Reload high-order halves


Get address of caller s save area
Reload low-order halves
Return to caller

Figure 499. Return from a routine using a Format-5 save area

To summarize the three main types of save area:


Format-0

The traditional 72-byte save area that saves only the low-order 32 bits of the general
registers.

Format-4

C F4SA in the second word indicates a 144-byte save area for all 64 bits of the
general registers.

Format-5

C F5SA in the second word indicates a 208-byte save area used when a program
executing in 24- or 31-bit addressing mode calls a program executing in 64-bit
mode. The first 144 bytes are the same as in the Format-4 save area. The loworder 32 bits of the callers registers are saved in his Format-0 save area, and the
high-order 32 bits of the callers registers are saved in the 64 bytes starting at offset
144, and are used by programs that this program calls.

Exercises
37.4.1.(2) + The second word of a Format-4 or Format-5 save area contains the characters F4SA
or F5SA. Why can this not be confused with the back-chain address of a standard save area?
37.4.2.(2) In Figure 499, the LMH instruction changes the high half of GG14. Why wont this
affect the return address?

37.5. Additional Conventions (*)


Some other conventions can be used in subroutine calls: entry point identifiers, calling point
identifiers, return flags, and return codes. Other than return codes, they are used largely for
program debugging and error diagnostics: if your program terminates abnormally the Supervisors diagnostic programs can check for these three items and display them as part of memory
dumps and other post-mortem information. Also, entry point identifiers and calling point identifiers can be used to provide execution-time flow tracing information.

762

Assembler Language Programming for IBM z System Servers

Version 1.00

37.5.1. Entry Point Identifiers (*)


An entry point identifier is a string of characters describing the called routines entry point in
some way; a typical identification is the name of the entry point. The entry point identifier (sometimes abbreviated EPID) is constructed as follows:
1. The first instruction at the actual entry point is an unconditional branch to the STM instruction that will save the registers.
2. The next byte contains a count of the number of characters in the following character string.
3. The identifier string of 1 to 255 characters follows immediately after the count byte.
4. The following instruction is the halfword-aligned STM instruction that saves the registers in
the callers save area.
Figure 500 shows how an entry point identifier is created:
Sample
EPID
Saver

Using
B
DC
DC
STM
- - -

*,15
Saver
AL1(L EPID)
C Sample
14,2,12(13)

Use caller s preset GR15


Branch to STM to save regs
Length of identifier
Entry point identifying string
Save registers
etc...

Figure 500. Example of an entry point identifier

In this case the ID string is the name of the entry point instruction, but it can be any useful
information:
Sample
EPID
Saver

Using
B
DC
DC
STM
- - -

*,15
Use caller s preset GR15
Saver
Branch to STM to save regs
AL1(L EPID)
Length of identifier
C Sample routine s EPID created 30 Feb 2035, 14:45 19 Jan 2015, 15:13
14,2,12(13)
Save registers
etc...

To save you having to worry about the details of identifying an entry point and storing registers,
the Library of Macro Instructions available to the Assembler (see Figure 23 on page 74) will
usually contain a SAVE macro-instruction. You use it in one of these three forms:
name
name
name

SAVE (R1,R2)
SAVE (R1,R2),,character-string
SAVE (R1,R2),,*

where the name entry is optional.


The first form generates only the a STM instruction which saves registers R1 through R 2 in the
callers save area. The second generates the character-string as an entry point identifier, and then
the STM instruction. The third form generates an entry point identifier consisting either of the
name-field symbol name if its present or the name of the control section in which the SAVE
appears, and then generates the STM instruction.
Thus, we could have written the last four statements of Figure 500 as the single statement
Sample

SAVE (14,2),,*

Identify entry, save registers

and the generated instructions would look like these:


Sample

B
DC
DC
STM

12(0,15)
AL1(6)
CL6 Sample
14,2,12(13)

BRANCH AROUND ID
IDENTIFIER
SAVE REGISTERS

For more about using macro-instructions like SAVE, see the IBM publications for your operating
system environment.

Chapter X: Large Programs and Modularization

763

37.5.2. Calling Point Identifiers (*)


A calling point identifier is a NOP instruction (described in Section 15.4) following the BAS or
BASR. It contains a halfword integer like an identification number or statement number. For
example, we can call a subroutine named Dummy with the two variable-length argument lists in
Figure 485:
L
LA
BASR
NOP
L
LA
BASR
NOP

15,=A(Dummy)
1,List1
14,15
1
15,=A(Dummy)
1,List2
14,15
2

Dummy is a separate subroutine


Point to first argument address list
Link to subroutine
Calling point ID = 1
As above (making sure GR15 is correct)
Point to second arg address list
Link to subroutine
Calling point ID = 2

Figure 501. Example of two calling point identifiers

When the called routine returns to the instruction whose address was passed to it in GR14,
control will immediately continue to the instruction after the NOP.236 The logic of your program
is not affected by the presence of a calling point identifier.

37.5.3. Save Area Return Flags (*)


A save area return flag is helpful as a diagnostic device for programs that might terminate
unexpectedly. Suppose there isnt enough information in the registers for you to determine which
routine was most recently in control. You can examine the chain of save areas in a memory
display to tell which routines have called one another, but you might not be able to tell which
routines have returned to their callers. This added bit of information is provided by a return flag.
After the callers registers have been reloaded and just before branching to the instruction whose
address is in R14, the callee executes the instruction
OI

15(13),X 0 1

This sets the low-order bit of the fourth word of the callers save area to 1. Since the callers
GR14 (saved at offset + 12) has been reloaded before the OI is executed, the contents of GR14 on
return is the same as when the call was made. We can revise the example in Figure 494 to set the
return flag:
L
LM
OI
BR

13,BSave+4
14,12,12(13)
15(13),X 0 1
14

Retrieve address of caller s area


Restore all registers
Set return flag in save area
Return to caller

Figure 502. Setting a return flag

If you wonder why the low-order bit of the byte at offset + 15 in the save area might not already
be 1: if your program was not invoked in 64-bit addressing mode with the BASSM or BSM
instructions, its the address of an instruction to which control is returned, so it must be an even
address. If your program was invoked in 64-bit mode with BASSM or BSM instructions, then
this bit is already on and cannot be used to convey other information.

236

764

With certain options, the High Level Assembler will view the NOP instruction like any other branch, and check
whether the Effective Address appears to reference the lowest 4K bytes of memory without a base register. In such
cases, you might write NOP 1(,0), or specify other Assembler options.
Assembler Language Programming for IBM z System Servers

Version 1.00

Be careful!
If your subroutine can execute in any addressing mode (including 64-bit
mode) and is called by a caller executing in 24- or 31-bit mode, dont use
this technique to set a return flag. If your program was invoked in 64-bit
mode, this bit was already set to 1 and cant be used to convey return
information.
Well see the reasons for this when we discuss mode-changing instructions in Section 38.

37.5.4. Return Codes (*)


Return codes are used often when you communicate with Operating System services. They are
usually small nonnegative integers, returned to the caller in GR15. Normally, the calling routine
wont expect the contents of R15 to be restored, so the called routine can use GR15 to pass a
return code to the caller. This could be any value, but by convention only multiples of 4 such as
0, 4, 8, and so forth are used as return codes.
For example, suppose a subroutine does a calculation and returns the result in GR0, with GR15
set to zero. If the subroutine has been passed an invalid argument (so that it cant do the calculation correctly), it can set GR15 to + 4 to indicate the error condition and let the caller analyze
and maybe correct the situation.
The instructions in Figure 504 show how the subroutine could set the return code for a good
and a bad return.
*
- - GoodRet L
13,Save+4
L
14,12(0,13)
LM
1,12,24(13)
SR
15,15
OI
15(13),X 0 1
BR
14
*
- - BadRet L
13,Save+4
LM
14,12,12(13)
LA
15,4
OI
15(13),X 0 1
BR
14

Valid calculated result is in GR0


Retrieve pointer to caller s area
Restore caller s GR14
Restore GR1 through GR12
Set return code to zero
Set return flag
Return to caller
Invalid argument, no result in GR0
Retrieve addr of caller s save area
Restore all the registers
Ret return code to +4
Set return flag
Return to caller

Figure 503. Setting a return code in register 15

Another way to set a return code that might have been given different values in the called
program:
L
L
L
LM
BR

13,4(,13)
14,12(,13)
15,Retcode
0,12,20(13)
14

Retrieve caller s save area address


Restore return address
Put return code in GR15
Restore remaining registers
Return to caller

L
MVC
LM
BR

13,4(,13)
16(4,13),Retcode
14,12,12(13)
14

Retrieve caller s save area address


Put return code in GR15 slot
Restore registers
Return to caller

or

Figure 504 shows how the calling program can test the return code to validate the result:

Chapter X: Large Programs and Modularization

765

ArgLst

L
LA
BASR
LTR
JNZ
ST
- - DC

15,=A(Sub)
1,ArgLst
14,15
15,15
Error
0,Result

Entry point address in GR15


Argument address list
Link to subroutine
Test return code in GR15
If nonzero, error indicated
Store valid result

A(DataItem)

Address of data for SUB

Figure 504. Testing a return code returned in register 15

When the return code can take on more values, it can be used as an index into a list of branch
instructions.
- - BASR
CHI
JH
Br2List B
J
J
J
J
- - -

14,15
15,MaxRC
BadRC
*+4(15)
Ret000
Ret004
Ret008
Ret012

Set up registers for linkage


Link to subroutine as usual
Check for return code too large
Go do something if so
Indexed branch into list
Return code = 0
Return code = 4
Return code = 8
Return code = 12
etc...

Figure 505. Using a return code as a branch index

If you are using relative branch instructions to minimize (or eliminate) the need for base registers
to address your instructions, you cant use the RX-type B instruction named Br2List in Figure
505. Instead, use instructions like those in Figure 506:

JList

- - BASR
LARL
AR
BR
J
J
J
J
- - -

14,15
14,JList
14,15
14
Ret000
Ret004
Ret008
Ret012

Set up registers for linkage


Link to subroutine as usual
Address of branch list
Add return code to list address
One-hop branch to correct routine
Return code = 0
Return code = 4
Return code = 8
Return code = 12
etc...

Figure 506. Using a return code as a branch index with relative branch instructions

It is always prudent to check the value of the return code if the called program isnt known or
trusted:
- - BASR
CHI
JE
CHI
JE
CHI
JE
J

14,15
15,0
Ret000
15,4
Ret004
15,8
Ret008
BadRetCd

Set up registers for linkage


Link to subroutine as usual
Check for return code 0
Return code = 0
Check for return code 4
Return code = 4
Check for return code 8
Return code = 8
Unknown/invalid return code

Figure 507. Checking for valid return code values

Subroutines that do very complex operations may need to give more detailed information about
the reason for a particular return code. A common convention is to put a reason code in GR0, as
illustrated in Figure 508:

766

Assembler Language Programming for IBM z System Servers

Version 1.00

BadRet

L
L
L
LM
LA
OI
BR
ReasonCd DC

13,Save+4
0,ReasonCd
14,12(,13)
1,12,24(31)
15,4
15(13),X 0 1
14
X0022006D

Retrieve addr of caller s save area


Load the reason code into GR0
Restore the return address
Restore GR1 through GR12
Ret return code to +4
Set return flag in caller s area
Return to caller
Reason code for a specific problem

Figure 508. Setting a reason code in register 0

As with the SAVE macro-instruction, a RETURN macro is available in the macro library for use
by Assembler Language programs. You usually use one of these forms (where the name-field
entry name is optional):
name
name
name
name

RETURN
RETURN
RETURN
RETURN

(R1,R2)
(R1,R2),T
(R1,R2),T,RC=nn
(R1,R2),T,RC=(15)

Restore
Restore
Restore
Restore

registers
regs, set return flag
regs, set flag and retcode
regs, set flag and retcode

The first operand generates an LM instruction to reload registers R1 through R 2, assuming that
GR13 contains the address of the callers save area before the RETURN macro-instruction is executed. The second operand (T) causes the return flag to be set, and the third operand causes the
value nn or the existing contents of GR15 to be used as the return code. The second operand
can be omitted in the third and fourth forms of the RETURN macro-instruction.
We can rewrite Figure 503 to use RETURN macros:
*
- - GoodRet L
13,Save+4
RETURN (14,12),T,RC=0
BadRet L
13,Save+4
RETURN (14,12),T,RC=4

Valid result in GR0


Restore caller s save area address
Restore registers, etc, RC = 0
Restore save area pointer
Restore registers, set RC = 4

Figure 509. Using R E T U R N macros to set return flags and return codes

The RETURN macros put the specified return codes in GR15, and then reload GR14 and the
other registers.
Sometimes, an alternate return branch does not put a return code in GR15, but returns instead at
the equivalent offset from the address in GR14. A revision of Figure 503 shows how this might be
done:
*
- - GoodRet L
13,Save+4
LM
14,12,12(13)
OI
15(13),X 0 1
BR
14
*
- - BadRet L
13,Save+4
LM
14,12,12(13)
OI
15(13),X 0 1
B
4(,14)


Valid calculated result is in GR0


Retrieve pointer to caller s area
Restore GR14 through GR12
Set return flag
Return to caller
Invalid argument, no result in GR0
Retrieve addr of caller s save area
Restore all the registers
Set return flag
Return to caller at offset + 4

Figure 510. Returning to an error branch without a return code

For this to work, the caller must have placed enough 4-byte branch instructions after the BAS or
BASR, as in Figure 511 on page 768. Unlike Figure 505, caller and callee must agree which
method will be used to handle error returns.

Chapter X: Large Programs and Modularization

767

- - BAS 14,MySub
B
Ret000
B
Ret004
B
Ret008
B
Ret012
- - -

Call my subroutine
Return code 0, no problems
Return code 4, minor problem
Return code 8, middling problem
Return code 12, major problem

Figure 511. Call with error branch instructions

If the called routine returns at a larger offset (say, 16) in Figure 511 than the calling routine
expected, control would be given to something unexpected.

37.5.5. Conventions for Floating-Point Registers.


If a called subroutine modifies the floating-point registers, it is responsible for saving some of
them: FPRs 0-7 are considered volatile and their contents need not be preserved, but the contents of FPRs 8-15 must be saved and restored across calls. That is, the called routine must save
and restore modified non-volatile FPRs; this allows you to optimize certain variables into nonvolatile registers across calls.

37.5.6. Main-Program Parameters


When you invoke a main program you often pass parameters, typically in the PARM field of a
JCL statement:
//

EXEC PGM=MYPROG,PARM= YES,NO,UP,DOWN

The string of characters is passed to your program as shown in Figure 512:


GR1
2

A(Addr1) A(Parms) Len YES,NO,UP,DOWN

Figure 512. Convention for passing main-program parameters

where the halfword Len contains the number of bytes in the following character string.
One of three methods may be used to indicate there are no parameters for the main program:
The address in GR1, A(Addr1) may be zero.
The address pointed to by GR1, A(Parms) may be zero.
The halfword length Len may be zero.

Exercises
37.5.1.(4) In the early days of System/360, all programs executed in 24-bit addressing mode, and
a return flag was set with this instruction:
MVI

12(13),X FF

Set return flag

which set the high-order byte of the return address to all 1-bits. Why could the high-order byte
of the return address not be all 1-bits resulting from a normal subroutine call? (You may have
to do some historical research to answer this question!)
37.5.2.(2) + A programmer decided to use this calling sequence to his subroutine:

768

Assembler Language Programming for IBM z System Servers

Version 1.00

Return

CNOP
LA
L
LA
BASR
DC
DC
NOP

2,4
Align to middle of fullword
13,MySave
Point GR13 to my save area
15,=A(SUB)
Set GR15 to entry point address
14,Return
Set GR14 to return address
1,15
GR1 points to parm list; call SUB
A(P1,P2,P3)
Argument address list, with
AL3(P4+X80000000)
... variable-length flag bit
999
Calling point identifier

Does this sequence conform to standard calling conventions?


37.5.3.(3) + The instructions in Figures 505 and 506 assume that the return code in GR15 is a
nonnegative multiple of 4. Assuming that the return code must be less than or equal to 12,
revise the instructions as follows:
If the return code is negative, set it to 12.
If the return code is greater than 12, set it to 12.
If the return code is not a multiple of 4, round it to the next higher multiple of 4.
37.5.4.(3) Write a subroutine named WHO that determines if there is an entry point identifier at
the entry point of its caller, and print it if there is one. For example, if WHO was called from
WHAT, it might print
WHO called from WHAT
37.5.5.(3) Write a subroutine WHO2 (as in Exercise 37.5.4) that will also print the callers calling
point identifier if it is present.
37.5.6.(2) + The technique for using return codes illustrated in Figure 506 is unsafe if the called
routine does not place a valid return code in GR15. Rewrite the code sequence so that valid
return codes 0, 4, 8, and 13 will branch as desired, and invalid codes will cause a branch to
InvCode.
37.5.7.(1) What is the maximum possible value of a calling point identifier?
37.5.8.(1) + A programmer suggested this instruction sequence for returning to a caller with a
return code in GR15: will it work? Explain.
L
MVC
LM
BR

13,4(,13)
16(4,13),RetCode
14,12,12(13)
14

Restore caller s save area addr


Move my return code to GR15 slot
Restore registers
Return to caller

37.5.9.(2) + Show how you can use a based branch to branch into a branch table (as in 506)
without requiring a base register.
37.5.10.(1) Show a way to test whether a return code is a multiple of four. If it isnt, branch to
BadRC.
37.5.11.(2) + A programmer claimed that you can test whether the return code in GR15 is a
multiple of 4 using these instructions:
Choice

CLI
EX
BNE

*+1,B11111100
15,*-4
Error

Branch if not a multiple of 4

Prove or disprove his claim.

Chapter X: Large Programs and Modularization

769

37.6. Assisted Linkage (*)


Up to now we have discussed direct linkage: the calling program transfers control directly to the
subroutines entry point. It is sometimes more convenient to use an indirect or assisted linkage:
instead of branching directly to the called program, control passes to an intermediate assisting
routine to do some useful activities (such as tracing, status preservation, and counting) and then
branch to the subroutine.
This technique can relieve caller and callee of much of the labor associated with subroutine linkages, but it requires careful planning of conventions used to communicate with the intermediate
assisting routine.
To illustrate, suppose ShftRt and Print are two subroutines called in a complex program. To call
a routine, we place its subroutine number into GR15 and then link to an internal Caller
routine that eventually branches to the desired subroutine. We can create the subroutine
numbers by appending a # character to the actual routine name, and defining Equ statements
to generate the number. Figure 513 shows how you might use an assisted linkage:
- - LA
15,ShftRt#
BAS 14,Caller
- - LA
15,Print#
BAS 14,Caller

Load subroutine number for ShftRt


Link to ShftRt via Caller routine
Load subroutine number for Print
Link to Print routine via Caller

Figure 513. Example of calling with assisted linkage

A simple form of Caller could be written as in Figure 514:


Caller

L
BR
AdrTbl DC
ShftRt# Equ
DC
Print# Equ
DC
- - -

15,AdrTbl(15)
15
0A(0)
*-AdrTbl
A(ShftRt)
*-AdrTbl
A(Print)

Get true subroutine address


Branch to subroutine
Align start of table
Subroutine number for ShftRt
True address of ShftRt
Subroutine number for Print
True address of Print

Figure 514. Example of a routine to implement assisted linkage

The called routine will not be aware of the indirect nature of the call, and the return from callee
to caller will be direct, bypassing the linkage routine.
This scheme apparently wastes instructions in getting from one routine to another. However, by
expanding information kept by the Caller routine it can, for example, display the name and
address of the routine being called and of its caller, the addresses of the arguments, the return
address, and so forth.
For example, the Caller routine could keep a count of the number of times each routine is
called. Figure 515 shows a way to do this; we assume that no base registers are available to
provide addressability in the Caller routine.

770

Assembler Language Programming for IBM z System Servers

Version 1.00

Caller

ST
LARL
AR
L
AHI
ST
L
L
BR
AdrTbl DC
ShftRt# Equ
DC
DC
Print# Equ
DC
DC
- - -

14,12(,13)
14,AdrTbl
14,15
15,4(,14)
15,1
15,4(,14)
15,0(,14)
14,12(,13)
15
0A(0)
*-AdrTbl
A(ShftRt)
F 0
*-AdrTbl
A(Print)
F 0

Save GR14 in caller s area


Set c(GR14) = A(AdrTbl)
Form address of table entry
Get count for called routine
Add 1
Restore count
Load true entry point address
Restore caller s return address
Branch to chosen subroutine
Align start of table
Subroutine number for ShftRt
Address of ShftRt
Count of calls to ShftRt
Subroutine number for print
Address of print
Count of calls to Print

Figure 515. Assisted linkage routine with counters

In large programs this tracing information can be extremely helpful in finding errors in logic and
flow of control. The routines called using assisted linkages may have been tested, but difficulties
always appear when smaller routines are combined into large programs.
The value of such a tracing and diagnostic tool often far outweighs its minor costs; and the overheads of the indirect subroutine linkage can be minimized by setting a flag to indicate whether or
not traces and diagnostics are wanted, or if the indirect call should go directly to the chosen
routine.

Exercises
37.6.1.(2) + Assuming each of the called routines in Figure 515 has an entry point ID, show the
instructions youd add to the Caller routine to load GR1 and GR2 with the address and length
of the called routines ID.
37.6.2.(4) + Assuming each of the called routines in Figure 515 has an entry point ID, show the
instructions youd add to the Caller routine to load GR1 and GR2 with the address and length
of the ID of the calling routine.
37.6.3.(2) + In Figure 515 the first instruction saves registers in the callers save area. Will it
matter whether or not the called routine (that eventually receives control from Caller) also executes the same instruction?
37.6.4.(2) + Suppose the call to the Caller routine is changed to pass the subroutine number as
a halfword following the BAS instruction:
BAS 14,Caller
DC
Y(ShftRt#)
- - -

Link to Caller routine


With inline subroutine number
Return here from called routine

The Caller routine could be modified like this:

AdrTbl

LA
AH
L
AHI
BR
DC
DC
- - -

15,AdrTbl
15,0(0,14)
15,0(0,15)
14,2
15
A(ShftRt)
A(Print)

Address of zero-th target routine


Add subroutine number to GR15
Load correct entry point address
Increment return address by 2
Enter called routine
True address of ShftRt
True address of Print
...etc...

Chapter X: Large Programs and Modularization

771

Show how the interface could be slightly modified to not require incrementing the address in
GR14 by two.
37.6.5. Revise the instruction sequences in Exercise 37.6.4 to pass the subroutine number in
GR0 to the Caller program.

37.7. Lowest Level Subroutines


If a routine makes no calls to Lower-level routines (including calls to I/O or other Supervisor
services), it need not contain a save area.
Suppose we need a subroutine that sets a string of bytes to zero; we will write a lowest level
subroutine ClearMem that will zero up to 256 bytes at a time. Its first argument gives the address
of the first byte of the area to be cleared, and the second is the address of a positive fullword
integer specifying the number of bytes.
Using
ClearMem STM
XC
LM
L
BCTR
EX
LM
BR
Zero
XC
Drop

*,15
14,2,12(13)
8(4,13),8(13)
1,2,0(1)
2,0(0,2)
2,0
2,Zero
1,2,24(13)
14
0(0,1),0(1)
15

Caller will preset GR15


Save GR14 through GR2
Zero the caller s forward chain
Get argument addresses
Load number of bytes to zero
Decrement by 1 for EX instruction
Execute XC instruction
Restore modified registers
Return to caller
Clear a variable-length area
Base in GR15 no longer available

Figure 516. Example of a lowest level subroutine

Because no calls are made by this routine, GR15 can be used as its base register. The only registers changed are GR1 and GR2, which are restored on return.
We could have saved only GR1 and GR2, but its good practice to always save registers GR14
and GR15 in the callers save area. Because those registers define the addresses from and to which
the call is made, those addresses in the save area can help diagnose difficulties if a program goes
astray.
The technique shown in Figure 516 should be used only if you are absolutely certain that the
routine will never be modified to call another lower-level routine. If that routine causes an interruption, debugging your program will be much more difficult.

Exercises
37.7.1.(2) Assume that the ShftRt5 routine in in Figure 483 on page 752 is a lowest level
routine that returns its result in GR0. Revise it to save and restore the minimum necessary
number of general registers.
37.7.2.(3) + Write a RanInt subroutine that calculates random integers according to the formula
Xnew = A Xold (modulo p)
where A = 16807 and p = 2 31 1 = 2147483647. That is, given a previous random integer
Xold, Xnew is the remainder of (AXold)/p. The subroutine should conform to these conventions:

772

The return address is in GR14.


GR13 contains the address of a save area.
The entry point instruction should be named RanInt.
When control reaches the entry point its address will be in GR15.

Assembler Language Programming for IBM z System Servers

Version 1.00

The value of Xold is passed to the routine in GR0.


The new random number Xnew is returned to the caller in GR0.
Restore all registers except GR0 to their original contents.
Note: The quality of the random sequences generated by this routine is not high enough for
serious or lengthy simulations.
37.7.3.(2) Suppose in Figure 516 that the LM instruction to restore the registers had been
written with operand field entry 1,12,24(13) instead of 1,2,24(13). Describe what differences
this (not unusual) programming error might make in the behavior of the program.

37.8. Summary
This section has discussed topics that can help you divide a complex application into smaller parts
that can be assembled and tested individually. Weve seen conventions used for
the registers used for standard linkage conventions
techniques used for argument passing, including variable-length argument lists
standard save areas
status preservation
useful instructions supporting these activities.
Internal subroutines 237 can use any convenient convention for linkage and argument passing that
are agreed between caller and callee, and used consistently. These local conventions can be
simple and efficient, but subroutines using them can be difficult to extract for use in other programs.
Subroutines using standard linkage conventions can be written once, assembled, and installed in a
Library of object and load modules (see Figure 24 on page 75) for use by many programs.
Reusing existing subroutines makes it easier to share code, and simplifies and speeds application
development.

37.8.1. Standard Linkage Conventions


This is a summary of the standard linkage conventions used in many operating system environments on z System.
1. The entry point address is in general register 15 on entry to the called routine.
2. The return address is in general register 14 on entry to the called routine.
3. The address of the list of argument addresses is in general register 1 on entry to the called
routine. If there are no arguments, general register 1 is set to zero.
For calls to routines using 32-bit argument addresses and in which the number of arguments
is known to be fixed and invariable, it is not necessary to set the high-order bit of the last
argument address (but its always a good practice!).
4. For calling programs using only 32-bit general registers, the address of an 18-word save area
is in GR13 on entry to the called routine.
5. The setting of the Condition Code on entry to the called routine need not be preserved.
6. Subroutines that calculate an integer value often return it in general register 0.
7. The contents of floating-point registers 0-7 need not be preserved by the called routine; if any
of floating-point registers 8-15 will be used their contents must be saved and restored before
returning to the caller. That is, FPR0-FPR7 are considered volatile.

237

More precisely: internal subroutines within a single control section. Well see why this is important in Section 38,
when we discuss separately assembled routines.
Chapter X: Large Programs and Modularization

773

Routines that calculate floating-point values often return them in FPR0 or (FPR0,FPR2).
8. General registers 2 through 14 must be saved by the callee and restored to their original
values before control is returned to the caller. (In general, it is best to restore the contents of
all registers not containing return values whenever practical.) Some operating system services
may not restore all registers; be sure to check the systems documentation.
If the called routine uses 64-bit registers, it must save and restore the low halves of general
registers 2-13 and the high halves of general registers 2-14.
Many Operating System services expect GR13 to point to a standard save area, and may not
restore general registers 14, 15, 0, and 1.
9. In the Floating-Point Control Register, preserve the mask and rounding bits. The flag bits
and Data Exception Code (DXC) need not be saved.
10. Return codes, if used, are integer multiples of 4 in GR15 on return.
Sometimes more detailed information is returned than a single integer in GR15 can provide;
if so, a reason code is often returned in general register 0.
11. For programs executing in 64-bit addressing mode, the caller must provide a 144-byte
doubleword aligned Format-4 save area with the characters F4SA in the second word.
Other conventions are used for identifying entry and calling points, and a return flag.

Terms and Definitions


argument
A value supplied by a calling program.
parameter
A place-holder in a called program, to be assigned a value from an argument provided by a
calling program.
linkage convention
An agreed set of rules for transferring control between a calling and a called program, passing
arguments and receiving results, and preserving caller information during the execution of the
subroutine so it can be restored on return to the caller.
calling point identifier
A NOP instruction with a halfword identifying number in place of its addressing halfword, of
the form X4700nnnn .
entry point
The first instruction to receive control when a routine is invoked.
entry point identifier
A string of characters following the first instruction at an entry point, providing descriptive
information about the entry.
return address
The address of an instruction to which control should be passed when a routine completes its
execution.
return code
A small integer value (usually a multiple of 4) placed in GR15 prior to returning to a calling
program.

Programming Problems
Problem 37.1. Write a program to print the 168 prime numbers less than 1000. Create an
internal subroutine to convert a number from its internal binary representation to character
form and print it.

774

Assembler Language Programming for IBM z System Servers

Version 1.00

Problem 37.2. Write a subroutine named PD2CH with two arguments: the first (input argument) is a valid packed decimal number 6 bytes long, and the second (output argument) is a
character string 12 bytes long containing a blank character followed by the digits of the result.
Your routine should replace leading zero digits by blanks.
Problem 37.3. Do as in Problem 37.2, but now write a subroutine named PD2CHN that
accepts two input arguments: the packed decimal number and its length in bytes. Use the
second argument to determine the minimum necessary length of the third (output) argument.
Problem 37.4.(3) + Write a subroutine named GCD that calculates the greatest common divisor of
two positive 32-bit integer arguments, using standard linkage conventions. The subroutine
should accept either two or three arguments:
The first two arguments are the integers whose GCD is to be found. In this case, return
their GCD in GR0.
If a third argument address is provided, store the GCD at that address.
The greatest common divisor function GCD(x,y) can be defined by
GCD(x,y) = if x=0 then y else GCD(remainder[y/x],x).
Restore all registers other than GR0 and GR1.
Problem 37.5.(2) + Write a subroutine with entry name PMax with a single argument: a pointer
in GR1 to a list of addresses. Each address in the list points to a packed decimal number
preceded by a single byte containing the length in bytes of the packed decimal number, as in
DC

AL1(3),P1234

Only the address of the last item in the list has its high-order bit set to 1.
The subroutine should return in GR1 the address of the list item with the largest magnitude.
None of the data in the list may be modified.

Chapter X: Large Programs and Modularization

775

38. Large Programs, Control Sections, and Linking

3333333333
333333333333
33
33
33
33
3333
3333
33
33
33
33
333333333333
3333333333

8888888888
888888888888
88
88
88
88
88
88
88888888
88888888
88
88
88
88
88
88
888888888888
8888888888

As programs grow, we need to consider (at least) three issues:


1. How to provide addressability for parts of the program that require it.
2. How to subdivide a program into smaller, more manageable pieces
within a single assembly,
with separate assemblies.
3. How to combine the separate pieces into a complete application.
Thus far, weve discussed programs where a single base register was enough to provide addressability for the entire program. But programs frequently grow large enough that more than one
base register might be needed.
Well consider two techniques for providing addressability in large programs:
1. We can allocate enough base registers to ensure that every byte of the program can be
addressed; we call this uniform addressability.
2. We can rearrange parts of the program into segments that require addressability, and segments that dont.

38.1. Uniform Addressability for Large Programs


If two or three general registers can be assigned as base registers for the duration of the program,
we use some simple techniques.
For the following examples, suppose we need three base registers to provide addressability for the
entire program, and that we have assigned GR10, GR11, and GR12 for this purpose. (Three
base registers can provide uniform addressability for up to 12K bytes.) A typical instruction
sequence for initializing these base registers is shown in Figure 517.

776

Assembler Language Programming for IBM z System Servers

Version 1.00

PROG

Start
BASR
Using
BaseLoc LAY
Using
LAY
Using

0
10,0
BaseLoc,10
11,4096(,10)
BaseLoc+4096,11
12,8192(,10)
BaseLoc+8192,12

Start LC at zero
Establish first base register
Inform assembler
Create c(GR10)+4096 in GR11
Inform assembler of 2nd base
Create c(GR10)+8192 in GR12
And inform the assembler again

Figure 517. Establish three base registers (1)

The USING statements need not appear exactly where they are placed in Figure 517. Because
none of the LAY instructions contains an implied address, we can place the all USING statements after the BASR:
PROG

Start
BASR
Using
Using
Using
LAY
LAY

0
10,0
*,10
*+4096,11
*+8192,12
11,4096(0,10)
12,8192(0,10)

Set first base register


Addressability based on GR10
Addressability based on GR11
Addressability based on GR12
Create second base
And third base

Figure 518. Establish three base registers (2)

Or, we can place them after the LAY instructions:


PROG

Start
BASR
BaseLoc LAY
LAY
Using
Using
Using

0
10,0
11,4096(0,10)
12,8192(0,10)
BaseLoc,10
BaseLoc+4096,11
BaseLoc+8192,12

Create second base


And third base
Addressability based on GR10
Addressability based on GR11
Addressability based on GR12

Figure 519. Establish three base registers (3)

In situations like this its easier use a more general form of the USING statement. Instead of
writing a single register number after the first operand, we can write up to 15 register numbers:238
Using

value,regnum1,regnum2,...,regnumk

When the Assembler processes this statement, the entries made in the Using Table (described in
Section 10.8 on page 127) are identical to the entries that would be made from these statements:
Using
Using
Using
- - Using

value,regnum1
value+4096,regnum2
value+8192,regnum3
value+(k-1)*4096,regnumk

That is, each register specified in the third and following operands is assumed to contain a value
4096 larger than the value assigned to the previous register. We could therefore have written
Figure 518 in the simpler form shown below.

238

A program needing 15 base registers for addressability wouldnt be able to do much with the one remaining register!
Well see that relative addressing can help a lot.
Chapter X: Large Programs and Modularization

777

PROG

Start
BASR
Using
LAY
LAY

0
10,0
*,10,11,12
11,4096(0,10)
12,8192(0,10)

Establish base in r10


Using Table entries for GR10/GR11/GR12
c(GR11) = c(GR10)+4096
c(GR12) = c(GR10)+8192

Figure 520. Establish three base registers (4)

Similarly, Figure 519 could have been written this way:


PROG

Start
BASR
BaseLoc LAY
LAY
Using

0
10,0
11,4096(0,10)
12,8192(0,10)
BaseLoc,10,11,12

Figure 521. Establish three base registers (5)

You can also use arithmetic instructions with immediate operands instead of the LAY
instructions:
PROG

Start
BASR
BaseLoc LR
AHI
LR
AHI
Using

0
10,0
11,10
11,4096
12,11
12,4096
BaseLoc,10,11,12

Even though the same number of bytes are generated, two more instructions must be executed.

38.1.1. Other Techniques (*)


You can create the base addresses in GR11 and GR12 shown in Figures 517 to 521 in other
ways. If a binary halfword integer constant 4096 is in an area named HW4096, we might write the
following:
PROG

Start
BASR
Using
LR
AH
LR
AH

0
10,0
*,10,11,12
11,10
11,HW4096
12,11
12,HW4096

Establish first base register


Make entries in using table
Copy base to GR11
Add 4096 to old value
Copy second base to GR12
Add 4096 to get third base

Figure 522. Establish three base registers with risks (6)

This example contains a serious pitfall: since we do not necessarily know where the constant
named HW4096 is located, we also do not know which base register will be chosen by the Assembler when the implied addresses of the AH instructions are resolved into base-displacement form!
Indeed, the Assembler has been instructed by the USING statement to assume that R11 and R12
may be used for addressing at a point in the program which logically precedes the point where the
necessary addresses have been placed in the registers. Thus, we might find that the Assembler has
resolved the implied addresses in a way that leads to execution-time errors. (See Exercises 38.1.5
and 38.1.14.)
To be safe, we must place the constant in a part of the program where we know it will be
addressed relative to a register whose contents at execution time have been correctly established.

778

Assembler Language Programming for IBM z System Servers

Version 1.00

PROG

HW4096
Next

Start
BASR
Using
LR
AH
LR
AH
J
DC
- - -

0
10,0
*,10,11,12
11,10
11,HW4096
12,11
12,HW4096
Next
H4096

GR10 will be okay as our base reg


Move base to GR11
Add 4096 to get second base
Move second base to GR12
Add 4096 more for 3rd base
Jump over the constant
(addressed by GR10 as base)
...rest of program...

Figure 523. Establish three base registers (7)

We can also load base addresses into registers using address constants.239 Suppose we define two
fullword address constants with the statement
Addrs

DC

A(BaseLoc+4096,BaseLoc+8192)

We will see in Section 38.7.2 how the true execution-time addresses corresponding to the
expressions BaseLoc+4096 and BaseLoc+8192 are placed into the two fullword locations
when the Supervisor loads our program into memory for execution. Then we could write
PROG

Start
BASR
Using
BaseLoc LM

0
10,0
*,10,11,12
11,12,Addrs

Set initial base register


Load GR11 and GR12

Figure 524. Establish three base registers (8)

Problems can also arise here if the constants at Addrs are far enough away from BaseLoc that the
value of the implied address of Addrs causes the Assembler to resolve the addressing halfword of
the LM instruction with GR11 or GR12 as the base register before its value has been established!
To be safe, we should rewrite Figure 524 to be sure that the symbol Addrs will be addressable
only by GR10.
PROG

Start
BASR
Using
BaseLoc LM
J
Addrs
DC
Next
- - -

0
Set value of location counter
10,0
Establish first base
*,10,11,12
Make Using Table entries
11,12,Addrs
Set GR11 and GR12 from adcons
Next
Jump over constants
A(BaseLoc+4096,BASELoc+8192)
...continuation of program...

Figure 525. Establish three base registers (9)

In Section 38.2 we will examine cases where it is either undesirable or impossible to use the above
techniques for maintaining addressability throughout an entire program.

Exercises
38.1.1.(2) + In Figure 519, why could we not write
Using *,10
Using *+4096,11
Using *+8192,12
as in Figure 518?

239

Or, adcons, for short. We first encountered them in Section 12.2, where we noted that the expression in an A-type
constant may be relocatable or absolute.
Chapter X: Large Programs and Modularization

779

38.1.2.(2) + In Figures 519 and 521 why isnt at least one USING needed immediately following
the BASR?
38.1.3.(3) + The addressing range of an instruction with a signed 20-bit displacement is about
512K bytes. Instead of the three base registers in Figures 517 to 519, why cant we write
something like this, to be able to address over a million bytes with just one base register?
Prog

Start
BASR
BaseLoc LAY
USING
- - -

0
10,0
10,512000(,10)
Establish base register
BaseLoc+512000,10 Provide lots of addressability

The next three exercises illustrate suggested methods for providing uniform addressability
using address constants. Each contains an error for you to find.
38.1.4.(2) + Whats wrong?
Prog
Begin

Start
BASR
Using
LM

0
3,0
*,3,4,5
4,5,=A(Begin+4096,Begin+8192)

38.1.5.(2) + Whats wrong?


Prog
Begin

Exec

Start
BASR
Using
LM
B
LTORG
EQU

0
3,0
*,3,4,5
4,5,=A(Begin+4096,Begin+8192)
Exec
*

38.1.6.(2) + Whats wrong?


Prog
Begin

Start
BASR
Using
LM
B
BaseAdr DC
Exec
EQU

0
3,0
*,3,4,5
4,5,BaseAdr
Exec
A(Begin+4096,Begin+8192)
*

38.1.7.(2) A programmer was asked the following question: Suppose your program is
covered by base registers 2, 3, and 4. A part of the code requires register 2 for another
purpose. Re-establish register 2 as a base after that computation is finished. Criticize his proposed solution below, assuming GR2 originally contained the address of Origin.
- - DROP 2
- - - - - - LA
2,Origin
Using Origin,2

Don t use GR2 as a base


Do arithmetic with GR2
Restore GR2 to original value
And re-issue USING

38.1.8.(2) + In Figure 525, what would happen if the statement


Using

BaseLoc,10,11,12

is placed after the LM instruction?

780

Assembler Language Programming for IBM z System Servers

Version 1.00

38.1.9.(2) + You have written a subroutine with entry point SubRtn and you know that GR15
will contain its address when control arrives there. Give an example to illustrate and explain
why the following USING statement may be incorrect:
SubRtn

Using *,15
ST
2,SaveR2
- - -

First instruction of SubRtn


Rest of subroutine

38.1.10.(2) + A programmer initialized his base registers with these instructions. Why might this
not work?
Prog

Start
Using
LM
Using
Drop

0
*,15
11,12,=A(Prog,Prog+4096)
*,11,12
15

The instruction sequences in Exercises 38.1.11 through 38.1.19 were proposed as solutions
to the problem of initializing multiple base registers at the beginning of a program; find
their errors. (If the errors are hard to find, try assembling each, study the assembled code,
and calculate what would actually appear in the designated registers when the instructions
were executed.)
38.1.11.(1) + Whats wrong?
Prog

Start
BAS
Using
LA

0
10,0
*,10,11
11,Prog+4096

What object code is generated?

38.1.12.(1) + Whats wrong?


Prog

Start
BASR
Using
LR
AH

0
10,0
*,10,11
11,10
11,=H4096

38.1.13.(2) + Whats wrong?


Prog

Start
BASR
Using
LA

0
10,0
*,11
11,Prog+4096

38.1.14.(1) + Whats wrong?


Prog

Start
BASR
Using
LA
LA

0
10,0
*,10,11,12
11,Prog+4096
12,Prog+8192

38.1.15.(1) + Whats wrong?


Prog
Here

Start
BASR
Using
LA
LA
LA

0
2,0
*,2,3,4,5
3,Here+4096
4,Here+8192
5,Here+12288

Chapter X: Large Programs and Modularization

781

38.1.16.(1) + Whats wrong?


Prog

Start
BASR
Using
LA

0
10,0
*,10,11
11,*+4096

38.1.17.(1) + Whats wrong?


Prog
Here

Start
BASR
Using
LA

0
10,0
Here,10,11
11,Here+4096

38.1.18.(1) + Whats wrong?


Prog

Here

Start
BASR
Using
LA

0
10,0
Here,10,11
11,Here+4096

38.1.19.(2) + Whats wrong?


Prog

Start
BASR
Using
LA
LA
Using

0
10,0
*,10
11,4095(,10)
11,1(,11)
*+4096,11

38.1.20.(2) A programmer decided not to use LAY instructions in Figure 518, and wrote
BASR
Using
Using
Using
LA
LA

10,0
*,10
*+4095,11
*+8190,12
11,4095(,10)
12,4095(,11)

Is there anything wrong with this method? If so, why?


38.1.21.(2) + Suppose the program segment in Figure 522 is rewritten as follows:
Prog

Start
BASR
Using
BaseLoc LR
AH
Using
LR
AH
Using

0
10,0
*,10
11,10
11,HW4096
BaseLoc+4096,11
12,11
12,HW4096
BaseLoc+8192,12

If the halfword area of memory named HW4096 actually contains X1000, and the program is
less than 10,000 bytes long, will this segment work correctly? Explain your answer.
38.1.22.(2) + In Figure 523, what would happen if the operand of the DC instruction is changed
to H4000? If it is changed to H5000? What changes might be needed to the other
instructions?
38.1.23.(3) In Figure 522, a risky method for initializing base registers is illustrated. Assuming
that the value of the symbol HW4096 is X1234, determine (1) the bases and displacements
assigned to the implied addresses of the AH instructions, and (2) the addresses that would be

782

Assembler Language Programming for IBM z System Servers

Version 1.00

found in GR10, GR11, and GR12 if the program is loaded into memory beginning at address
X20000, and the instructions in the program segment are executed. (That is, the BASR is at
address X20000.) Then repeat the above two calculations, on the assumptions that the value
of the symbol HW4096 is X2234, and then X3234. Explain your results.
38.1.24.(2) + In Figure 522, show how to use immediate operands to eliminate the memory references to the constant named HW4096.
38.1.25.(2) + Revise Figures 517 through 523 to use arithmetic-immediate instructions.
38.1.26.(2) Modify the instructions in Figure 520 on page 778 to use LA instructions instead of
LAY instructions.
38.1.27.(1) Modify the instructions in Figure 525 on page 779 to initialize four base registers
rather than three.

38.2. Simplifying Addressability Problems in Large Programs


As programs (inevitably) grow larger, more base registers may be needed to address the entire
program. For programs of reasonable size, this is usually not a problem. However, if a program
becomes large enough that many registers are required for addressability and few are left for the
business of the program, we need to find ways to simplify the program.
First, well look at cases where enough base registers are available; then well discuss several techniques that can be used to reduce the number of required base registers.

38.2.1. Internal Subroutines Without Local Addressability


Most often, internal subroutines can use the global addressability provided for the entire
program.
Here is a ShftRt subroutine like the one we saw in Figure 471 on page 746:
*
ShftRt

ShftOK

ShftRt Arguments in registers 0 and 1


LTR 1,1
Test value of N
BNM ShftOK
Branch if nonnegative
SR
1,1
Set N to zero if it was minus
SRL 0,2(1)
Shift (2+max(N,0)) bit positions
BR
14
Return to caller

Because it contains an implied address reference, it requires local addressability. But if the containing program has provided uniform addressability for the entire program, we need no local base
register(s) to provide addressability for the reference to the symbol ShftOK.
Occasionally we can rewrite a subroutine by replacing a based branch instruction with a relative
branch, and no base register may be needed.
*
ShftRt

ShftOK

ShftRt Arguments in registers 0 and 1


LTR 1,1
Test value of N
JNM ShftOK
Branch relative if nonnegative
SR
1,1
Set N to zero if it was minus
SRL 0,2(1)
Shift (2+max(N,0)) bit positions
BR
14
Return to caller

Well see more examples of this technique.


Internal subroutines typically use either the standard linkage conventions described in Section 37.2
on page 751, or local conventions specific to the needs of the internal subroutine. Figure 526
shows an unusual way to call a subroutine that doesnt need a local base register.
Chapter X: Large Programs and Modularization

783

Logic
Shift
Result
AdShft

L
L
L
BASR
ST
- - DS
DS
DS
DC

0,Logic
1,Shift
14,AdShft
14,14
0,Result
F
F
F
A(ShftRt)

Place arguments in GR0 ...


...and in GR1
Subroutine address in GR14 now
Funny branch to subroutine
Store answer
...and move on
Logical datum
Shift amount
Address of subroutine

Figure 526. Calling a subroutine not needing local addressability

The unusual aspect of this program segment is that GR14 (not GR15!) is used to contain (briefly)
the entry point address, and also the return address!
While this technique is not very general, it can be useful when the number of available registers is
severely limited.

38.2.2. Internal Subroutines With Local Addressability


Some programs are so big it is impractical to provide addressability for the entire program. We
will look at simple ways to divide a large program into smaller and more manageable parts,
starting with internal subroutines.
Suppose the ShftRt subroutine in Figures 471 through 475 starting on page 746 is part of a large
program, and we dont know
where the subroutine will be placed relative to the rest of the program, nor
whether addressability will be available in the subroutine.
For now, well assume that the arguments are passed from the caller to the subroutine in registers
GR0 and GR1, as in Figures 471 and 472.
Because the caller cant always be sure the first instruction of the subroutine is addressable, he
cant safely call it using a
BAS

14,ShftRt

instruction as before. If the address of the instruction named ShftRt is available, we can load the
address into a register and branch to the subroutine. If the caller and the subroutine agree that
GR15 will contain the address of the first executed instruction of the subroutine (its entry point
address), we could write

Logic
Shift
Result
AdShft

L
L
L
BASR
ST
- - DS
DS
DS
DC

0,Logic
1,Shift
15,AdShft
14,15
0,Result
F
F
F
A(ShftRt)

Get datum to be shifted in GR0


Shift amount goes in GR1
Load GR15 with subroutine address
Branch to subroutine
Store shifted result
...and continue
Logical datum
Shift amount
Address of subroutine

Figure 527. Calling a subroutine not locally addressable

As in Figure Figure 466 on page 743 and those immediately following it, we assumed that GR12
provides addressability for the calling program, so the four fullwords of data are addressable (as
we expect from the implied addresses in the Load and Store instructions). Because the instruction
named ShftRt may not be addressable, we require only that the address constant named AdShft
containing its address be addressable. Also, choosing GR14 and GR15 to contain the return and
entry point addresses is a matter of convention; but a convention that assumes that neither GR14
nor GR15 provides addressability in the calling program.

784

Assembler Language Programming for IBM z System Servers

Version 1.00

The ShftRt subroutine now takes advantage of its address having been put in GR15 by the caller,
so we can write it as follows:
ShftRt

ShftOK

Using
LTR
BNM
SR
SRL
BR
DROP

*,15
1,1
ShftOK
1,1
0,2(1)
14
15

Caller will preset GR15


Test shift count
Branch (based) if not negative
Set count to zero
Perform shifts
And return to caller
Nobody should use GR15 hereafter

Figure 528. Subroutine with local addressability

We didnt execute a BASR 15,0 before the USING statement because the USING statement
merely tells the Assembler what to assume for assigning bases and displacements. Because the
caller places the correct address in GR15 before branching to the subroutine, there is no need to
do anything more to establish addressability. Of course, if the caller neglects to preset GR15, the
BNM instruction (if taken) might cause a branch into unknown parts of memory; but thats the
fault of the caller, since the subroutine is correctly written.
The DROP statement at the end of the subroutine is important: if its not present, the Assembler
must assume GR15 is available for addressing purposes in statements following the subroutine. If
GR15 is used as the base register in a subsequent implied address, serious errors could occur,
because GR15 may not contain the address of ShftRt after return to the caller.
It may seem we havent gained much flexibility in this simple example. However, remember that
the instruction sequence in Figure 528 could have been part of a small test program for checking
that the subroutine worked correctly. By extracting the statements of the subroutine and putting
the USING and DROP statements before and after them, the subroutine can be put in any convenient part of a larger program.
This is a major reason for using subroutines: you can break your large problem into smaller and
more manageable pieces for testing before you combine them into a bigger program.

38.2.3. Minimizing the Number of Base Registers


Well investigate two basic ideas:
Replace based-addressing instructions wherever possible with relative-addressing instructions,
and replace references to constants and literals by instructions with immediate operands.
Separate the instructions and data so that the instructions need no base registers to address
themselves.

38.2.4. Relative Branches, Immediate Operands, and Long Displacements


First, we can take advantage of the relative branch instructions (and their extended mnemonics)
listed in Table 117 on page 331 to replace based branches with relative branches:
Before
B
Next
BZ
ZeroVal
BC
12,NoCarry
BAS 14,Sub

After
J
JZ
JC
JAS

Next
ZeroVal
12,NoCarry
14,Sub

Figure 529. Replacing based branch instructions with relative-immediates

Each based branch instruction requires a base register to resolve its Effective Address; relative
branches require no base register.
Similarly, each (based) EX instruction can be replaced by its relative-addressing form, EXRL:

Chapter X: Large Programs and Modularization

785

Before
EX
2,MoveData

After
EXRL 2,MoveData

Figure 530. Replacing a based EXecute instruction with EXRL

Next, we can use the instructions with immediate operands described in Section 21 on page 317
to replace based references to constants and literals:
Before
S
8,=F5000
LH
3,=Y(L Buffer)
L
5,=F2147483647

After
AHI 8,-5000
LHI 3,L Buffer
LGFI 5,2147483647

Figure 531. Replacing references to constants with immediate operands

Finally, we can use instructions with long 20-bit signed displacements to refer to much more of
the program than is possible with instructions using unsigned 12-bit displacements:
Before
L
9,=A(SomeData)
L
9,0(,9)
LA
1,ArgList

After
LY
9,SomeData
LAY

1,ArgList

Figure 532. Replacing short unsigned displacements with long signed displacements

Using relative branches and immediate operands, we can replace some instructions with basedisplacement addressing that require base registers. However, instructions that load, store, and
move data typically require base-displacement addressing.

38.2.5. Separating Instructions and Data


To reduce the number of required base registers, you can put data that will be read, written, or
moved into an area addressable with a base register, and put as many of the instructions as possible into an area not requiring a base register to address them. For example, this program fragment mixes instructions and data areas, and requires a base register for both instructions and data.
Using
L
A
ST
BP
- - X
DC
Y
DC
Z
DS
- - Positive L
- - PlusCode DC

*,12
2,X
2,Y
2,Z
Positive

Base register for entire program

F123456789
F7654321
F

Some sum

O,PlusCode

Indicate positive sum

F+12

A small number

Figure 533. A program fragment needing reorganization

The program fragment in 533 can be reorganized this way:

786

Assembler Language Programming for IBM z System Servers

Version 1.00

Using
LGFI
AGFI
ST
JP
- - Positive LHI
- - Data
DS
Z
DS
- - -

*,Data
2,123456789
2,7654321
2,Z
Positive
O,+12
0D
F

 Note the different USING base


 Note immediate operand
 Note immediate operand
Use a relative branch instead
Indicate positive sum  Moved!
 Eliminated 3 fullwords
Some sum

Figure 534. A program fragment after reorganization

Now, only the data areas following the symbol Data are addressable; none of the instructions is
addressableand none needs to be! If this was part of a large program, its possible we could have
eliminated the need for one or more base registers.
It seems logical to put the instructions at the start of the program and the constants and work
areas at the end. Because most programs will already have a register assigned to the entry point at
the start of the program, its easier to use that register as the base register for data items referenced
by instructions that require base-displacement addressability, as shown in Figure 535:

Prog
Start

J
Entry
 Jump over read/write area

Using Prog,15
 Base register for read/write
Data
DC
C Message 1

work area
Packed DS
PL5

TenE24 DC
D10E24

... etc.

SaveArea DS
18F

LTORG


Entry
STM 14,12,12(13)
 Start of program instructions

LTR 1,1

that use only relative branch

JZ
NoArglist

instructions; all base

CP
Packed,=P 0

displacement references are

JE
NoPacked

are resolved with GR15

... rest of program

Figure 535. Reorganizing a program to minimize base registers

As a general rule its best to keep groups of instructions and groups of data in separate areas, for
these reasons:
1. Youll very probably need fewer base registers, so you can use those registers for better purposes.
2. There is less likelihood of overwriting instructions (yes, it happens...).
3. Keeping read-only data such as constants separate from read-write work areas can help
improve performance.
4. Modern processors buffer instructions and data from storage into different caches; if address
references to one overlap with references to the other, the CPU can be slowed considerably.
Advice
To improve performance and minimize the number of base registers,
keep instructions and data separated in the generated program.

Chapter X: Large Programs and Modularization

787

Exercises
38.2.1.(2) + Usually, we put USING statements after the BASR instructions that set the contents of the registers in the USINGs. In Figure 528, why didnt we place the USING statement
after the instruction whose address is in GR15?
38.2.2.(2) + Explain the operation of the BASR 14,14 instruction in Figure 526.
38.2.3.(2) + In Figure Figure 526 on page 784, what would happen if the ShftRt subroutine
contains a USING *,14 statement at its entry point?
38.2.4.(1) + In Figure 531 on page 786, what results will be different between executing the L
and LGFI instructions?

38.3. Separate Assemblies


Up to now we have treated all programs as self-contained. The entire program was translated in a
single assembly; all instructions and declared data were processed by the Assembler as a single
program. In practice it is often convenient (or even necessary) to assemble parts of programs separately, and link the parts later. While the parts could possibly be combined after debugging, and
assembled in one large assembly, doing so is unnecessarily clumsy.
We now examine preparing programs as separately assembled segments, and how external
symbols and address constants are used so that such routines can reference each other and their
data areas.
We usually dont care exactly where a routine is in memory, so long as we can call it and have it
produce the desired results. The ShftRt subroutine in Figure 528 illustrates such a situation; the
routine in Figure 527 that calls it makes no assumptions about the actual location of the subroutine, only that the address constant at AdShft will contain the correct address.
Writing a routine once and using it often is more economical, so z System operating systems
support various forms of program segmentation. The Linker combines separately assembled components into a complete program; well see how this works in Section 38.7.
The basic elements managed by the Linker are control sections and external symbols.

38.4. Control Sections


A control section is a segment of instructions or data (or both) that must be kept in one contiguous block in storage when the program is linked and executed. More precisely:
Control Section
A control section is the smallest indivisible contiguous segment of
instructions and/or data which may be relocated independently of all
other such segments, without affecting the logical operation of the
program.
Correct execution of a program requires certain of its parts to maintain known and fixed relationships relative to one another. For example, the Assembler assigns Location Counter values within
each assembly so it can correctly resolve the positions of implied addresses; if those positions are
changed later, theres no guarantee the program will execute correctly
The following assembler instruction statements define a control section; for each, the name of the
control section is provided in the name field entry of the statement. The first three identify what

788

Assembler Language Programming for IBM z System Servers

Version 1.00

the High Level Assembler Language Reference calls executable control sections: they are part of
the completed, linked program. Despite the executable name, they need not contain any executable instructions.
START

START defines the beginning of a control section, and can set the initial value of
the Location Counter to the operand, if specified. This initial value is rounded up
to the next multiple of a doubleword (or other SECTALGN-specified) section
alignment. For example,
MyProg

START 100

Set initial LC for MyProg

would (by default) cause the Assembler to round the initial LC setting to
104 = X000068, the next doubleword boundary. If the operand is omitted, zero
is assumed. If a comment field is present when the operand is omitted, an isolated
comma must separate it from the mnemonic, as in
MyProg

START ,

Control section for MyProg

A START statement must be the first or only executable control section definition
in a program. (It may be preceded by reference control sections, which are described
below.)
CSECT

A CSECT statement 240 defines a control section, and has no operand. Your
program may define many control sections. If a comment field is present, an isolated comma should separate it from the mnemonic, as in
MySect7 CSECT ,

Control section for MySect7

Unlike START, multiple CSECT statements are allowed in a single assembly.


RSECT

The RSECT statement is exactly the same as a CSECT statement, with the additional property that the Assembler will check for possible modifications of areas
within that control section. (This is sometimes called reenterability checking.)

The next three statements identify what the High Level Assembler Language Reference calls reference control sections: they generate no data or instructions. They can describe the organization of
a data structure; only COM allocates storage for it.
COM

Common control sections define work areas that can be shared by multiple control
sections that may or may not be in the same assembly. They contain no assemblytime generated machine language instructions or data, but are part of the completed,
linked program. COM statements have no operands.

DSECT

A Dummy control section is a template or mapping of a memory area that contains


no machine language object code.241 Dummy sections are typically used to provide
detailed symbolic descriptions of a data structure. (Well see lots of examples in
Chapter XI.)

DXD

The DXD (Define External Dummy) instruction defines one component of a


DSect-like structure created by the Linker. (Well describe DXD and related topics
in Section 38.7.3.)

The Assembler maintains a separate Location Counter for each control section, and associates the
control section name with the first byte of the control section. You can think of each control
section as having its own addressing space.
The only statements that may precede a control section definition are comments, PRINT controls, macro-instruction definitions, and a few others of minor interest.

240

241

Occasionally, a control section is called a CSect (pronounced See-Sect). We usually know from context whether
we are referring to a control section or to the assembler instruction statement with mnemonic CSECT.
As with CSECT, a DSECT is often pronounced Dee-Sect.
Chapter X: Large Programs and Modularization

789

Be Careful!
If any statement that depends on or affects the LC, or which defines or
declares a symbol, appears before any control section definition statement, an unnamed control section is automatically started with the LC
initialized to zero. If a subsequent START statement appears, it is
flagged as an error.
Each control section has its own relocation attribute, so you cant make implied-address references from one control section to another without additional USING statements. For example:
MyProg

Start
Using
LA
- - MySub
CSect
- - SubData DC

0
*,15
1,SubData

My program
Establish local addressability
Address of subroutine s data (Bad!)

My subroutine

F1234

Data in MySub

Figure 536. Incorrect implied reference to a different control section

The LA instruction will be diagnosed as an error, because there is no USING statement with the
relocation attribute of MySub. To reference a field in a separate control section, we need something like this:
MyProg

Start
Using
L
Using
LA
- - ASub
DC
- - MySub
CSect
- - SubData DC

0
*,15
12,ASub
MySub,12
1,SubData

My program
Establish local addressability
Get address of MySub
Establish addressability
Address of subroutine s data (Good!)

A(MySub)

Address of MySub

My subroutine

F1234

Data in MySub

Figure 537. Correct implied reference to a different control section

After the second USING statement, the USING Table would contain two entries: one for register
15 with Relocation Attribute 01 and a second for register 12 with Relocation Attribute 02, illustrated in Figure 538.

basereg base location RA

15
00000000 01

12 Loc of MySub 02

Figure 538. USING Table with two entries

Suppose a main program and our ShftRt subroutine are assembled together, but the subroutine is
placed in a separate control section. Figure 539 shows how this can be done:

790

Assembler Language Programming for IBM z System Servers

Version 1.00

MyProg

Start 0
BASR 12,0
Using *,12
- - L
0,Logic
L
1,Shift
L
15,AdShf
BASR 14,15
ST
0,Result
- - Logic
DS
F
Shift
DS
F
Result DS
F
AdShf
DC
A(ShftRt)
DROP 12
********************************
*
ShftRt Subroutine
*
********************************
ShftRt CSect ,
Using *,15
LTR 1,1
JNM ShftOK
SR
1,1
ShftOK SRL 0,2(1)
BR
14
END MyProg

Main program
Establish base for main program

Load GR0 and GR1


...with parameters
GR15 has subroutine address
Link to subroutine
Store result

Can t use GR12 elsewhere

Separate control section for ShftRt


Use caller s preset base register
Test shift count
Branch if not minus
Set shift count to zero
Shift desired number of places
Return to caller
Begin execution in main program

Figure 539. Main program and subroutine in one assembly

The Assembler knows the location of ShftRt, and includes information in the object module so
that the adcon named AdShf will contain the correct address at execution time. The two control
sections (MyProg and ShftRt) are separately relocatable, so we should DROP the main programs
base register before starting the code of the subroutine. Because none of the implied addresses in
either control section refer to locations in the other, there is no need to provide addressability for
more than one control section at a time.
To show how a COMMON control section can be shared between two executable control
sections, well revise Figure 539 to put the items passed from MyProg to ShftRt in a common
section named ShfCom. Figure 540 shows how this can be done:

Chapter X: Large Programs and Modularization

791

MyProg

Start 0
BASR 12,0
Using *,12
L
11,AdCom
Using ShfCom,11
- - ST
0,Logic
ST
1,Shift
L
15,AdShf
BASR 14,15
ST
0,Result
- - AdShf
DC
A(ShftRt)
AdCom
DC
A(ShfCom)
- - DROP 12,11
ShfCom COM ,
Logic
DS
F
Shift
DS
F
Result DS
F
********************************
*
ShftRt Subroutine
*
********************************
ShftRt CSect ,
Using *,15
L
2,ACom
Using ShfCom,2
L
0,Logic
LT
1,Shift
JNM ShftOK
SR
1,1
ShftOK SRL 0,2(1)
BR
14
ACom
DC
A(ShfCom)
END MyProg

Main program
Establish base for main program
Addressability for MyProg
Load address of ShfCom section
Provide addressability
Calculate argument values
Store Logic argument in ShfCom
Store Shift argument in ShfCom
GR15 has subroutine address
Link to subroutine
Store result
Address of ShftRt subroutine
Address of common section
Can t use GR12, GR11 elsewhere
Declare common control section
Work areas in ShfCom
- - - - -

Separate control section for ShftRt


Use caller s preset base register
Load address of common area
Establish addressability
Get argument to be shifted
Load and test shift count
Branch if not minus
Set shift count to zero
Shift desired number of places
Return to caller
Address of common area
Begin execution in main program

Figure 540. Main program, subroutine, and common section in one assembly

38.4.1. Resuming Control Sections


You need not put all the statements belonging to a given control section together. That is, you
can start a control section, then start another, and then resume the first one and the Assembler
will keep all the related pieces together in the generated object code. For example:
First
A
B
Second
W
X
First
C
Second
Y

CSECT
DC
DC
CSECT
DC
DC
CSECT
DC
CSECT
DC

,
F101
F103
,
F -107
F -109
,
F113
,
F -127

Start a control section

Start another control section


Resume the First control section
Resume the Second control section

Figure 541. Resuming control sections

In the control section named First, the fullword constants named A, B, and C will have locations
X 0 , X 4 , and X 8 relative to the origin of the control section; similarly, the locations of the
three constants W, X, and Y in control section Second will have the same offsets relative to the
origin of that control section.

792

Assembler Language Programming for IBM z System Servers

Version 1.00

A more typical example to show how a CSECT statement can be used to resume a control
section, we will rewrite Figure 539 in the form shown in Figure 542, where the contributions to
CSECT MyProg are defined in two separate segments.
MyProg

*
ShftRt

ShftOK

*
MyProg

Logic
SHIFT
Answer
AdShr

Start
BASR
Using
- - L
L
L
BASR
Drop

0
12,0
*,12

Start of main program


Make a base
Inform the assembler

0,Logic
1,Shift
15,AdShf
14,15
12

Set up arguments in GRO


... and GR1
Subroutine address to GR15
Link to subroutine
Can t use main base here

CSect
Using
LTR
JNM
SR
SRL
BR
Drop

,
*,15
1,1
ShftOK
1,1
0,2(1)
14
15

Start of subroutine
Addressability provided by GR15
Test shift count
Skip next instruction if not minus
Clear shift count
Shift,
And return
Can t use subroutine base here

CSect
Using
ST
- - DS
DS
DS
DC

,
MyProg+2,12
0,Answer

Resume the main program CSECT


Re-establish Using information
Store answer (GR12 is base)

F
F
F
A(ShftRt)

Logical value to be shifted


Shift amount
Result
...and continue with program

Figure 542. Main program and subroutine in one assembly, multiple CSects

The MyProg CSect is defined in two pieces, and the necessary USING and DROP statements are
inserted to ensure that implied addresses are correctly resolved. The USING MyProg+2,12 statement
is placed before the following ST instruction so that the implied address will be resolved with
GR12 as the base register. Because this very simple subroutine has no implied addresses (and
needs no local base register and no USING *,15) we could have omitted the DROP 12 before
the subroutine; but its always a good programming practice to limit the range of each USING
statement.
Advice
Limit the range of USING resolution to the minimum necessary; otherwise the Assembler may resolve implied addresses with base registers
whose contents are no longer valid.
We can now see how an expression can have a complex relocation attribute. Suppose in the
assembly in Figure 542 we wanted to calculate the offset of ShftRt relative to MyProg and wrote
this statement:
LA

2,ShftRt-MyProg

Because the two control sections are separately and independently relocatable (and the two
symbols ShftRt and MAIN therefore have different relocation attributes), there is no way the
Assembler can assign a base register and an absolute displacement to the instruction.

Chapter X: Large Programs and Modularization

793

38.4.2. Literals in Multi-Section Assemblies (*)


Be careful when you use literals in programs with more than one control section. Literals are
symbols, so they can have all the addressability problems of ordinary symbols. In particular, the
Assembler could place the literals in a part of the program that is not addressable!
If any literals are left in the Assemblers literal table at the end of the assembly, they are placed at
the end of the first executable control section defined in the program. This may or may not be
what you intended. Either (1) dont use literals in a multi-CSect assembly, or (2) use LTORG
statements at the end of each control section, so that the literals used in each control section will
be defined within it.
For example:
Section1 Start
- - L
- - Section2 CSect
- - L
- - End

0
2,=F 1
,
7,=F 4 3

Because there is no LTORG in control section Section2, both literals will be placed in a literal
pool at the end of Section1. This probably means that references in Section2 to literals will
generate addressability errors.

38.4.3. Location Counter Discontinuities (*)


Because the Assembler uses multiple, separate Location Counters for control sections, they can
also be used to manage discontinuities in the Location Counter. Suppose we write these statements, and the Assembler knows the value of the Location Counter when it processes the first
statement:
Loc
000046
?
?
?
000005

Statement
A
DS
B
DS
C
DS
D
DS
N
Equ

XL(N)
F
CL(3*N)
F
5

N is not defined yet


Aligned Fullword
Another discontinuity
Aligned Fullword
Finally, define N

Figure 543. Statements with Location Counter discontinuities

Because the value of the symbol N is not yet known, the location and alignment of the symbol B
cant be assigned. So, the Assembler assigns a temporary separate Location Counter to those two
statements and saves information about this group of two statements until the value of N is
known. Similarly, the statements named C and D represent another discontinuity group with their
own temporary Location Counter.
When the END statement is reached, the unresolved discontinuity-group segments are analyzed.
If resolvable (as in this case) the temporary Location Counter values are stitched into their
proper places among the preceding and following segments. Thus, if the value of the Location
Counter is X000046 when the first statement in Figure 543 is processed, the value of the symbol
B will be X00004C .
If any group cannot be resolved, the Assembler issues a diagnostic and ignores the faulty statement:
G
DS
XL(K)
K is not defined yet
** ASMA080E Statement is unresolvable
H
DS
F
Aligned Fullword
K
Equ *-G
Now, G is defined (?)
** ASMA044E Undefined symbol - G

794

Assembler Language Programming for IBM z System Servers

Version 1.00

Because the symbol G couldnt be assigned a value (that is, be defined) until the value of K was
known, the alignment of H was unknown and therefore resolving the value of K could not be
completed.

38.4.4. Section Alignment (*)


The first byte of an executable or COMMON control section is always placed in memory on an
aligned boundary. By default, all control sections are aligned on a doubleword boundary, but
occasionally you may require a more stringent alignment. If you specify the SECTALGN option, the
Assembler will align all control sections on the boundary you specify.
For example, if you specify the SECTALGN(16) option, all control sections will be aligned on a
quadword boundary. 242
When your program is linked with other control sections, this may waste a few bytes if the preceding control section does not end just before such a boundary. However, the Linker and
Program Loader will respect your alignment request and load the executing program on the
requested boundary. This means that boundary alignments within a control section (due to
CNOP, ORG, DC, or DS statements) are preserved relative to the start of the control section.
In some cases, you can adjust the LC within a CSECT to a stricter boundary than the default,
and then rely on Linker controls to request that the CSECT be aligned on (for example) a page
boundary, thus guaranteeing that the stricter internal alignment will be honored when the
program is linked. For example, suppose you want to force a CSECT to be an exact number of
4K pageslong, by adding enough bytes at the end to force its length to be a multiple of 4096:
Prog

CSECT
- - LtOrg
*
Round
DC
ProgLen Equ
End

Start a control section


Add lots of statements
,
Insert the literals now
the LC to a page boundary
((((*-Prog)+4095)/4096)*4096-(*-Prog))X 0 0
*-Prog
Will now be a multiple of X1000

Figure 544. Technique for rounding the length of a CSECT

38.4.5. Threaded Location Counters (*)


Location Counter values in multi-CSECT assemblies are occasionally puzzling: the leftmost
column of the Assemblers listing shows the value of the LC assigned to each statement. When a
single control section is being assembled, these LC values increase predictably as succeeding bytes
are assembled.
In a multi-CSect assembly, the values of the LC may appear to vary as the control section
changes. Even though the statements belonging to different CSects are interleaved, the LC values
look as though the statements had been rearranged within each control section, as noted in
Section 38.4.1 above.
Remember that the Assembler maintains a separate Location Counter for each control section in
an assembly. Except for the first CSECT (whose LC may be initialized to a nonzero value on a
START statement), these LC values are set to zero whenever a new control section is encountered. Then, whenever a CSECT statement indicates that a different control section is to be begun
or resumed, the Assembler uses a new LC to continue the assembly.
After the first pass of the assembly is complete, the Assembler processes its collection of Location
Counters. First, the length of each CSECT is determined; this is possible because the Assembler
knows both the current and the maximum value of the LC for each control section. Then, beginning with the first CSECT (whose initial LC value is known), the Assembler adds the initial LC
value for each control section to its length, rounds the sum up to the next alignment boundary,

242

Not every system Linker supports quadword alignment, so you should try a simple test. Section alignments stricter
than quadword require specifying the GOFF object-file option, or providing control statements to the Linker.
Chapter X: Large Programs and Modularization

795

and assigns the resulting value as the initial LC value of the next CSECT. In this way, the control
sections appear to have been unscrambled and assembled end-to-end.
During the second assembly pass, the Assembler uses these adjusted LC values to compute the
values of expressions involving symbols and Location Counter references. The relocation attribute
of the symbol tells which CSECT the symbol belongs in, and therefore what LC value should be
added to the symbols value found in the symbol table.
Adjusting the LC values so that each control section starts at the next aligned boundary following
the end of the previous one is called threading the location counters. With no threading, each
control section starts at location zero.
Why does the Assembler perform threading? In the earliest days of System/360, programs were
not organized into complex load modules by the Linkage Editor, but were loaded directly into
memory from object modules. Because the address where loading began was often known in
advance, that address could be assigned as the initial LC value in a START statement. Thus, the
LC values printed on the Assemblers listing corresponded exactly to the addresses in memory
occupied by the assembled and loaded program. This made debugging simpler, because an interruption address could be immediately identified with the offending instruction in the listing.
Threading was intended as a convenience for you. We will see in discussing program linking that
the LC values must be un-threaded by the Linker so it can correctly relocate the program.
Whether threading is a help or hindrance is a matter of personal preference.
Sometimes its easier to debug programs if each control section starts at location zero (except possibly the first if its LC value is set by a START statement). If you specify the NOTHREAD option,
the Assembler will not thread LC values for each new control section.

38.4.6. The Location Counter Instruction LOCTR (*)


As discussed in Section 38.4.2 on on page 794, the Assembler can create separate Location
Counters to handle discontinuities. The Assembler lets you create your own Location Counter
discontinuities in Assembler Language programs with the LOCTR 243 instruction.
LOCTR can help you group segments of your program so that the order of statements in each
control section of the source program need not be the same as the order of the generated
instructions and data in the object program, as was done in all our previous examples.
The LOCTR instruction starts (or continues) a separate group of statements having its own
Location Counter. When the end of the source program is reached, the Assembler collects the
portions of each LOCTR group in the order they were declared into a single group, and assigns a
sequential Location Counter value to each item within each named group. Figure 545 illustrates
this process:

243

796

The LOCTR instruction describes a Location Counter group, so its pronunciation would logically be LOKE-ter. But
the people who invented it called it LOCK-ter. Your preference?
Assembler Language Programming for IBM z System Servers

Version 1.00

Group X

Group P

Group X

Group P

Group X

Source Sequence
Object Sequence

X CSect

X CSect

AAAAA
AAAAA

BBBBB
BBBBB

P LOCTR
DDDDD

CCCCC

FFFFF

X LOCTR

DDDDD

CCCCC

P LOCTR

EEEEE

EEEEE

X LOCTR

FFFFF

Figure 545. Rearrangement of source groups by LOCTR

The three portions of LOCTR group X appear first in the generated object code, followed by the
three portions of LOCTR group P. All the statements of the two LOCTR groups are part of the
control section named X.
Note that all the statements are in control section X and that we have simply reordered the
normal connection between source and object components of that control section. Conversely,
multiple CSECT statements dont change the ordering relation between statement sequence and
the object code generated for each control section.
Figure 545 illustrates important properties of LOCTR groups:
1. A statement starting a control section (like CSECT) starts a LOCTR group with the name of
the control section. Thus, each control section is its own LOCTR group!
2. The name of a LOCTR group appears in the name field of the LOCTR assembler instruction statement. Statements following the LOCTR belong to that group. Thus, the two
groups in the figure are named X and P.
3. The object sequence of source statements is in the order of the first appearance of the groups
declaration on (1) a statement that initiates a control section (START, CSECT, DSECT,
RSECT, COM) or (2) a LOCTR statement.
4. A LOCTR group can be interrupted by other LOCTR groups, and then resumed later in the
source program. The same capability for control sections was described in Section 38.4.1..
These simple examples illustrate the effects of LOCTR:
1. This example starts LOCTR group ALoc and does not resume the LOCTR group of control
section A.
A
ALoc

CSect
DC
LOCTR
DC
End

,
X 0 0
,
X 0 1

Define LOCTR group A


Location = X000000
Define LOCTR group ALoc
Location = X000001

Figure 546. Simple example of LOCTR (1)

2. This example resumes the LOCTR of control section A after the ALoc LOCTR was defined.

Chapter X: Large Programs and Modularization

797

A
ALoc
A

CSect
LOCTR
DC
LOCTR
DC
End

,
,
X 0 1
,
X 0 0

Define LOCTR group A


Define LOCTR group ALoc
Location = X000001
Resume LOCTR group A
Location = X000000

Figure 547. Simple example of LOCTR (2)

3. In this example, both LOCTR groups are first defined and then resumed.
A
ALoc
A
ALoc

CSect
LOCTR
LOCTR
DC
LOCTR
DC
End

,
,
,
X 0 0
,
X 0 1

Define LOCTR group


Define LOCTR group
Resume LOCTR group
Location = X000000
Resume LOCTR group
Location = X000001

A
ALoc
A
ALoc

Figure 548. Simple example of LOCTR (3)

While many programs dont need the capability provided by LOCTR, it can improve readability
and understandability by keeping related portions of the source program close together, while also
keeping them separated in the object program. For example, though the simple program fragment
in Figure 533 on page 786 may be more understandable in that form, we may eventually want
the generated instructions and data to appear as in Figure 534.244 Figure 549 uses LOCTR groups
named Code and Data to do this:
Using
- - Code
LOCTR
L
A
ST
- - JP
- - Data
LOCTR
X
DC
Y
DC
Z
DS
Code
LOCTR
- - Positive L
- - Data
LOCTR
PlusCode DC

Data,12
,
2,X
2,Y
2,Z

Start LOCTR group for instructions

Positive
,
F something
F something_else
F
,

Start LOCTR group for data

Some sum
Resume LOCTR group for instructions

0,Plus Code

Indicate positive sum

,
F some number

Resume LOCTR group for data

Figure 549. A program fragment using LOCTR for reorganization

The object code generated by this program fragment would be the same as that generated in
Figure 534.
Organizing a program using LOCTR to keep instructions and data separated is sketched in Figure
550:

244

798

Closely mixing instructions and data as in Figure 533 on page 786 can have significant negative effects on program
performance.
Assembler Language Programming for IBM z System Servers

Version 1.00

MyProg

CSect
J
Consts LOCTR
Msg1L
DC
Message1 DC
Data
LOCTR
Number DS
Code
LOCTR
Start
STM
LR
Using
L
- - OI
- - LB
- - Consts LOCTR
LTORG
End

,
Start of My Program
Start
Relative branch to instruction LOCTR
,
Start a LOCTR group for constants
AL1(L Message1)
Length of message
C This is a message string
,
Start a LOCTR group for writable data
CL12
Binary number converted to dec. chars
,
Start of LOCTR group for instructions
14,12,12,(13)
Save registers in caller s save area
12,15
GR12 is base register for Consts/Data
MyProg,12
Addressability for Constants and Data
4,=F -23456
Load value from literal pool
Number+L Number,X F0

Make last converted digit EBCDIC

1,Msg1L

Get length of Message 1

,
,

Return to constants LOCTR group


Put literals in Consts LOCTR group

Figure 550. Organizing a program to minimize addressability problems

After assembly, the program in Figure 550 appears as though it had been written this way:
MyProg

CSect
J
Msg1L
DC
Message1 DC
LTORG
Number DS
Start
STM
LR
Using
L
- - OI
- - LB
- - End

,
Start of My Program
Start
Relative branch to instruction LOCTR
AL1(L Message1)
Length of message
C This is a message string
,
Emit literals in Consts LOCTR group
CL12
Binary number converted to dec. chars
14,12,12,(13)
Save registers in caller s save area
12,15
GR12 is base register for Consts/Data
MyProg,12
Addressability for Constants and Data
4,=F -23456
Load value from literal pool
Number+L Number,X F0
1,Msg1L

Make last converted digit EBCDIC

Get length of Message 1

Figure 551. Organizing a program to minimize addressability problems

Aside from the reordered statements, note these differences between Figures 551 and 550:
All the constants and read-write areas are close to the origin of the control section, so will
probably be within the range of addressability of the single USING statement.
The literal in the program follows the LTORG statement; but because LTORG appeared at
the end of the source program the literal will be generated with the other constants near the
start of the object program.
Branch instructions in the Code LOCTR group can now be changed to relative-immediate
instructions, so no additional addressability is needed within that LOCTR group. In larger
programs, this can free up previous base registers for more productive use.
Thus, it may be possible that all based references to the Consts and Data LOCTR groups can
be addressed with a single base register. And, if you use relative-addressing branch instructions
in the Code LOCTR group, then you shouldnt need a base register to a address any
instructions.

Chapter X: Large Programs and Modularization

799

LOCTR also facilitates correctly defining the target of an EX instruction, since its definition
will be close to the EX that references it. This helps ensure that the current USING
instructions will be honored in both the EX and the target instruction.
Program Loctr ,
- - EX
1,Target
Constant Loctr ,
Target <the target instruction>
Program Loctr ,

Group for mainline instructions


Reference the target instruction
Put the target with constants
Resume the mainline instructions

Some unexpected behaviors may arise when you mix control section and LOCTR statements.
1. This example uses both CSECT and LOCTR, where we define LOCTR groups in more
than one control section:
A

CSect
DC
CSect
DC
LOCTR
DC
LOCTR
DC
End

B
A
B

,
X 0 0
,
X 0 2
,
X 0 1
,
X 0 3

Define LOCTR group


Location = X000000
Define LOCTR group
Location = X000008
Resume LOCTR group
Location = X000001
Resume LOCTR group
Location = X000009

A
B
A
B

Figure 552. Simple example of LOCTR (4)

While control section B is active, the following A LOCTR statement resumes control section
A. Resuming a LOCTR group can cause a change of control section.
2. This example inserts a second A CSECT statement, with interesting results:
A
ALoc
A

CSect
DC
LOCTR
DC
CSECT
DC
End

,
X 0 0
,
X 0 1
,
X 0 2

Define LOCTR group


Location = X000000
Define LOCTR group
Location = X000001
Resume LOCTR group
Location = X000002

A
ALoc
A?  Note!
!

Figure 553. Example of unexpected LOCTR behavior (1)

Resuming CSECT A does not resume its Location Counter! You might have expected that the
last DC statement would follow the first. But, as the Location values of the constants indicate,
resuming a control section resumes the most recently active LOCTR group in that control section,
not the LOCTR group associated with the control section name.
3. Heres another example that illustrates this behavior:

800

Assembler Language Programming for IBM z System Servers

Version 1.00

A
ALoc
B
BLoc
A
B

CSect
DC
LOCTR
DC
CSect
DC
LOCTR
DC
CSect
DC
CSect
DC
End

,
X 0 0
,
X 0 1
,
X 0 2
,
X 0 3
,
X 0 4
,
X 0 5

Define LOCTR group A


Location = X000000
Define LOCTR group ALoc
Location = X000001
Define LOCTR group B
Location = X000008
Define LOCTR group BLoc
Location = X000009
Try to resume LOCTR group A
Location = X000002 (not X000001!)
Try to resume LOCTR group B
Location = X00000A ( not X000009!)

Figure 554. Example of unexpected LOCTR behavior (2)

You might have expected both CSECT statements to resume their LOCTR groups; they instead
resume the most recently active LOCTR groups within their sections. Thats why the constant
X 0 4 does not follow X 0 0 , but X 0 4 instead follows X 0 1 . The constants in control section B
behave similarly.
We can summarize these rules for using LOCTR statements and statements naming control
sections.
1. A LOCTR group does not start a separate or different control section unless the LOCTR
statement is the first LC-dependent statement in the program (it does depend on the
Location Counter), in which case a Private Code control section is initiated by the Assembler. (Starting a program with LOCTR isnt a good idea!)
2. A LOCTR group is part of the control section in which the group is first declared. The
portions of a LOCTR group belong to the control section being assembled when its first
LOCTR statement appears. That is, the statements in a LOCTR group have the same relocatability attribute as the owning control section in which they appear.
3. Resuming a control section resumes the most recently processed LOCTR group in that
control section. If no LOCTR group has been defined in the control section, the control
section is resumed normally. That is, you can use a LOCTR group name to resume a
control section, but a control section name cannot safely be used to resume a LOCTR
group. Instead, it resumes the most recently used LOCTR group in that control section.
4. To resume a control section in which LOCTR groups have been defined, issue a LOCTR
statement with the name of the control section.
5. A change of LOCTR group may also change the current control section.
6. ORG in a LOCTR group pertains only to that group, and cannot be used to switch the
Location Counter to a different control section.
Thus, the Assembler knows how to manage groups of statements with their own temporary
Location Counters; the LOCTR statement lets you declare and determine the order of your own
groups of statements.
Advice
Dont use a LOCTR name as a branch target, because you may not
know which of many possible occurrences of the name is the actual
target.

Exercises
38.4.1.(2) + In this program fragment, where will the literals =F 1 be generated?

Chapter X: Large Programs and Modularization

801

AAA

BBB

CSect
- - L
- - LTORG
CSect
- - S
- - End

,
3,=F 1
,
8,=F 1

38.4.2.(2) In this program fragment, where will the literals =F 1 be generated?


CCC

DDD

CSect
- - L
- - LTORG
CSect
- - S
- - LTORG
End

,
3,=F 1
,
8,=F 1

38.4.3.(1) In Figure 539 on page 791, why is a DROP 15 statement not needed at the end of the
ShftRt subroutine?
38.4.4.(2) + In Figure 539 on page 791, why is the USING statement in the ShftRt control
section not needed? Is there any reason why should it be retained?
38.4.5.(2) In Figure 542 on page 793, why is it a good idea to leave the USING *,15 statement
at the start of the ShftRt subroutine, even though its not required?
38.4.6.(1) + In Figure 543 on page 794, determine the values of all symbols if symbol A has
value X001240. Now, do Exercise 38.4.7.
38.4.7.(2) + In Figure 543, why is the value of the symbol B not the value of the symbol A plus
five, or X00004B ?
38.4.8.(2) + First, make a complete and correct Assembler Language program using the
instructions in Figure 540 on page 792. Then, assemble it twice: first with the THREAD
option, and again with the NOTHREAD option. Study the Assemblers Location Counter
values for each control section.
38.4.9.(2) + What values are assigned to the symbols naming DS statements in this program?
Prog
A
NewGroup
B
Prog
C
NewGroup
D

Start
DS
LOCTR
DS
LOCTR
DS
LOCTR
DS
End

X2000
X
,
H
,
F
,
F

38.4.10.(3) + In Figure 544 on page 795, explain how the expressions in the DC statement generate the desired alignment.

802

Assembler Language Programming for IBM z System Servers

Version 1.00

38.4.11.(2) In this little program, in which control sections will each constant reside? Assuming
normal doubleword section alignment, what will be their locations if the Location Counter
values are threaded?
A
B
C
B
C
A
C

Start
DC
CSECT
DC
CSECT
DC
CSect
DC
CSect
DC
CSect
DC
CSect
DC
End

0
X 1
,
X 2
,
X 3
,
X 4
,
X 5
,
X 6
,
X 7

38.4.12.(2) + What values are assigned to the symbols naming DS statements in this program?
Loc
H
ALoc
A
BLoc
B
Loc
C
ALoc
D
BLoc
E
Loc
F

CSect
DS
LOCTR
DS
LOCTR
DS
LOCTR
DS
LOCTR
DS
LOCTR
DS
LOCTR
DS
End

,
X
,
X
,
X
,
X
,
X
,
X
,
X

38.4.13.(3) + If you assemble this program, what will be the Location Counter values assigned
to each symbol?
SectA
H
ALoc
B
SectB
A
BLoc
C
ALoc
D
BLoc
E
SectA
F
BLoc
G
SectB
N

CSect
DS
LOCTR
DS
CSect
DS
LOCTR
DS
LOCTR
DS
LOCTR
DS
CSect
DS
LOCTR
DS
LOCTR
DS

,
X
,
X
,
X
,
X
,
X
,
X
,
X
,
X
,
H

Chapter X: Large Programs and Modularization

803

38.4.14.(2) Section 38.4.2 noted that literals not previously generated by LTORG statements
are placed at the end of the first executable control section when the END statement is processed. How do you think the Assembler does that?

38.5. External Symbols


Usually, none of the symbols you used to write your program are available after the completion
of its assembly, except for the program name. To communicate among routines assembled or
compiled at different times, we need the additional information provided by external symbols..
An external symbol may be one of the following five types, and the statements used to declare
them are shown in parentheses.
1. Control section name (CSECT, RSECT, START)
A control section name is the name of a block of instructions or data. The name identifies the
control section; it is used by the Linker to build an executable load module. Names of
executable control sections defined by START, CSECT, and RSECT instructions are
always external symbols.
2. Common section definition (COM)
A common section is a reference control section that generates no assembly-time machine
language instructions or data. Typically, COM sections are shared work areas among executing CSECTs in a loaded program. (That is, they are commonly available to multiple
code CSECTs.) They provide an easy way to reference large data aggregates without passing
their addresses as subroutine arguments.
3. External reference (EXTRN, WXTRN)
An external reference is a symbol that is not assigned a value at assembly
the name of an instruction or data area that will be supplied and resolved
linking, often from the Library of Object and Load Modules illustrated
page 75. EXTRN and WXTRN statements are needed only for symbols
assembly in which references to those symbols are needed.

time. It is usually
during program
in Figure 24 on
not defined in the

External references are typically used in address constants that, after program linking is complete, will contain addresses of other program segments.
V-con operands are automatically declared EXTRN.
4. Entry name (ENTRY)
An entry name is associated with a particular location within a control section. For example,
library routines calculating the trigonometric functions SIN and COS use nearly identical
algorithms, so a single control section may have separate entry names for SIN and COS.
5. Dummy external section (DXD, and DSECT in special cases)
Dummy external sections are sometimes called PseudoRegisters. They have specialized uses
that well describe briefly in Section 38.7.3. Their names may match other external symbol
names without conflict.
The Assembler maintains a special symbol table called the External Symbol Dictionary (ESD) for
external symbol information. 245 Each item in the External Symbol Dictionary (other than
ENTRY names) is assigned an ESD ID number, or ESDID. (An ENTRY name is given an
Owning ID, the ESDID of the section to which it belongs.)

245

804

Some of this information may also appear in the Symbol Table for ordinary (internal) symbols.
Assembler Language Programming for IBM z System Servers

Version 1.00

38.5.1. EXTRN and WXTRN Statements


Suppose our ShftRt subroutine has already been assembled as a separate program, to be combined by the Linker with our calling program. The symbol ShftRt will be defined somewhere
outside our calling programto the caller, it is an external symbol. Thus, the Assembler must
provide information to the Linker indicating that we want to reference that symbol. This is done
with the EXTRN statement.
For example, the subroutine call in Figure 527 on page 784 can be modified to make ShftRt an
external symbol.

Logic
Shift
Result
AdShft

EXTRN
- - L
L
L
BASR
ST
- - DS
DS
DS
DC

ShftRt

Declare ShftTt to be external

0,Logic
1,Shift
15,AdShft
14,15
0,Result

Datum to be shifted, in GR0


Shift amount, in GR1
Subroutine address, in GR15
Link to subroutine
Store shifted result

F
F
F
A(ShftRt)

Space for arguments,


...
And result
Subroutine address

Figure 555. Calling ShftRt as an external routine

When we compare the examples in Figure 527 on page 784 and Figure 555 above, the only difference is the presence of the EXTRN statement. The true address of ShftRt in the address constant named AdShft will be created by the Program Loader when the program is loaded into
memory.
We can write the ShftRt routine as a separately assembled routine. First, we create a complete
program in which the subroutine is defined as a control section named ShftRt. Because a control
section name is already an external name, no EXTRN declaration is needed.
ShftRt

ShftOK

Start
Using
LTR
BNM
SR
SRL
BR
END

0
*,15
1,1
ShftOK
1,1
0,2(1)
14

Define control section name


GR15 preset by caller
Test shift count
Branch if not minus
Set shift to zero
Perform the shifts
Return to caller

Figure 556. ShftRt subroutine as a separate assembly

This assembly generates an object module with the single ShftRt control section, 14 bytes long.
The only symbol in the External Symbol Dictionary in the object module will be the control
section name. The program name is not an operand of the END statement, because we are not
writing a main program that should be executed starting at ShftRt.
You can also use external symbols with relative branch instructions.246 For example, you can use
references like these:

246

While the Assembler supports relative-immediate external references, you should verify that the Linker(s) in your
operating system environment also supports them.
Chapter X: Large Programs and Modularization

805

EXTRN A,B
- - BRAS 14,A
- - BRASL 14,B

Call nearby external routine A


Call distant external routine B

Figure 557. External references using relative branch instructions

The Assembler encodes the 2-byte (for BRAS) and 4-byte (for BRASL) relative references in the
object module. BRAS would typically be used to refer to external routines in a linked program
not longer than (say) 50K bytes, while BRASL can be used for very large programs or programs
in which different parts are widely separated.
The EXTRN and WXTRN assembler instruction statements have no name-field entry. The
operand field is a symbol or list of symbols separated by commas. Each symbol is entered in the
Assemblers External Symbol Dictionary, and given its own relocation attribute because the
Assembler must assume it is independently relocatable.
The only difference between EXTRN and WXTRN symbols occurs during linking: if all the
input object and load modules provided to the Linker do not have a definition of the symbol,
EXTRN causes a library search for a definition, while WXTRN does not.
You can use WXTRN to declare and test for external symbols that are not linked with the completed program. The example in Figure 558 shows how you can do this:
WXTRN
EXTRN
- - LT
JZ
BRAS
- - CallSub2 L
BRAS
- - ASub1
DC
ASub2
DC

Sub1
Sub2

Weak reference for Sub1


Strong reference for Sub2

15,ASub1
CallSub2
14,15

Test if Sub1 was linked


Branch if it s not available
It s available, call it

15,ASub2
14,15

Get the address of Sub2


... and call it

A(Sub1)
A(Sub2)

Address of Sub1, if linked


Address of Sub2

Figure 558. Using W X T R N to test whether a routine was linked

An external name declared in a WXTRN statement will not cause any Linker diagnostics if the
name cannot be linked. Then, you can test the address constant referencing the name for zero to
determine whether or not it is present in the linked program.
A symbol cannot appear both as an operand of an EXTRN or WXTRN statement and also as
the name-field symbol in a statement which would assign a value to it, because this combination
would be an attempt to declare that the symbol both is, and is not, defined external to this
program.
EXTRN NotGood
NotGood DC
C Not So Good
Internal symbol
** ASMA043E Previously defined symbol - NotGood

38.5.2. V-Type Address Constants


Calling an external subroutine can be simplified if you use V-type address constants. The presence
of a symbol in a V-type adcon automatically and implicitly declares the symbol as external. We
could rewrite Figure 555 as shown in Figure 559. The differences are the omission of the
EXTRN statement, and using a V-type adcon in place of an A-type adcon.

806

Assembler Language Programming for IBM z System Servers

Version 1.00

Logic
Shift
Result
AdShft

EXTRN
- - L
L
L
BASR
ST
- - DS
DS
DS
DC

ShftRt

Not needed, we re using a V-con

0,Logic
1,Shift
15,AdShft
14,15
0,Result

Datum to be shifted, in GR0


Shift amount, in GR1
Subroutine address, in GR15
Link to subroutine
Store shifted result

F
F
F
V(ShftRt)

Space for arguments,


...
And result
Subroutine address in a V-con

Figure 559. Calling ShftRt as an external routine

Before converting programs using EXTRN declarations and A-type address constants to use
V-type adcons, take note of these considerations:
1. The operand of a V-type address constant may be a symbol only.
2. In the object module, an additional flag is attached to the external symbols that appear in
V-type address constants. This flag means that the symbol is the name of a routine or entry
point to which control may be passed, as well as possibly the name of a data area.
There is no distinction between a V-type adcon and an A-type plus EXTRN unless the
routine to which control may be transferred might use an assisted linkage.247 In this special
case, the branch will actually go to a linkage-assist routine that loads the target routine into
memory if necessary and then branches to it.
This is why an expression cannot be allowed in a V-type adcon: the branch may go not to
the target routine but to a linkage-assist routine, so no added factors can be allowed in the
address. Assisted linkage is (fortunately) usually invisible.
3. The symbol in a V-type constant may also be explicitly declared in an EXTRN or WXTRN
statement.
Some useful programming conventions for V-type constants and external symbols are:
1. All external symbols should be explicitly declared in EXTRN statements, even though an
implicit declaration could have been used.
2. All external branch addresses should be referenced through V-type constants. If you know
that calling a routine will never use an assisted linkage, you can replace V-type constants by
A-type constants (but retain the EXTRN declarations youve done already).
3. Data areas should never be addressed using V-type address constants: if assisted linkages are
used at some later time, the address in the V-con might not be the address of the data area!
And, if you store data at the address referenced by the constant, you might be destroying
important linkage information.

38.5.3 ENTRY Statement


In addition to specifying ShftRt as a control section name, you can use an ENTRY statement to
identify ShftRt as the name of a location in a control section with a different name. As with
EXTRN, symbols identified as entry points are written as operands of an ENTRY statement,
separated by commas.
ENTRY symbols must be defined in the program in which the ENTRY statement occurs. Otherwise, there would be no position in the control section that could be identified as the desired entry
point.

247

This was particularly true for load modules formed into overlay structures, which are little used today; but other
forms of assisted linkage exist, such as Dynamic Link Libraries (DLLs).
Chapter X: Large Programs and Modularization

807

Suppose we rewrite the ShftRt subroutine as part of a control section named SubShf2. (We use
the argument-passing convention of Figure 483 on page 752 in which the result address is also
provided as an argument, and all registers are preserved.)
SubShf2 Start
ENTRY
Using
ShftRt STM
LM
L
L
SRL
LTR
JNP
SRL
Finish ST
LM
BR
Save
DS
END

0
ShftRt
*,15
0,4,Save
2,4,0(1)
0,0(0,2)
1,0(0,3)
0,2
1,1
Finish
0,0(1)
0,0(0,4)
0,4,Save
14
5F

Set control section name and LC


Identify entry point
Assume standard linkage
Save GR0 through GR4
Get argument and result addresses
Logical datum to GR0
Shift amount in GR1
Perform initial shift
Test additional shift count
Branch if not positive
Perform rest of shift
Store result at given location
Restore all registers we used
And return to caller via r14
Register save area

Figure 560. ShftRt subroutine in a different CSect

The External Symbol Dictionary for this assembly contains the CSect name SubShf2 and the
entry name ShftRt, and information to indicate the type of each symbol.
To illustrate a typical use of the ENTRY statement, suppose a Main routine calls a subroutine
Subr. The data for the subroutine is in the main program, named Data. Rather than passing the
address of the data area to the subroutine, the main program identifies it with an ENTRY statement.
Main

ASubr
Data

Start
ENTRY
BASR
Using
- - L
BASR
- - DC
DS
END

0
DATA
12,0
*,12
15,ASubr
14,15
V(Subr)
200F
Main

Main program
Identify entry point of Data
Establish base register
Assembler resolves displacements
Compute something in data area
Get subroutine address
Branch to subroutine
Do something with the results
External subroutine address
Data area
Start execution in main program

Figure 561. Main program with E N T R Y for data

The separately assembled subroutine Subr could be written as in Figure 562:


Subr

AData
Save

Start
EXTRN
Using
STM
L
L
- - LM
BR
DC
DS
END

0
Data
*,15
0,6,Save
6,AData
0,0(0,6)
0,6,Save
14
A(Data)
7F

Define control section Subr


Mark Data as external
Standard linkage assumed
Assume we need only GR0-GR6
Get address of data area
First data word to GR0
Work with all the data
Restore GR0-GR6
Return to master
Address of external data area
Save area for registers GR0-GR6

Figure 562. Subroutine using E X T R N to reference data

808

Assembler Language Programming for IBM z System Servers

Version 1.00

Each of these programs refers to a name defined in the other by using an EXTRN declaration
and an appropriate address constant.
We can use address constants for addressing data in many ways. For example, suppose the data
area accessed by the subroutine contains several sub-areas that begin at DATA, DATA+60, and at
DATA+453. We also suppose the subroutine refers to these sub-areas often enough that it keeps
their addresses in registers. Because A-type address constants may contain expressions involving
external symbols, we can define three adcons to point to the parts of the data area.
Subr

Subr

Start
EXTRN
Using
STM
LM

0
Data
*,15
0,6,SAVE
4,6,ADatas

*
*

ADatas

Save

- - LM
0,6,Save
BR
14
DC
A(Data)
DC
A(Data+60)
DC
A(Data+453)
DS
7F
END

Define the CSect name


Indicate external symbol
Caller will preset GR15
Save GR0-GR6
C(GR4) = A(start of data area),
GR5 points to second data area,
And GR6 points to the third
... work with the data
Restore registers we used
Return to caller
Address of base of data area
Address of next sub-area
Address of last data sub-area
Register save area

Figure 563. Subroutine using E X T R N and adcons to reference data

The usage illustrated in Figure 563 cannot be simplified by using V-type constants such as
V(DATA+60).
Because multiple operands are allowed in address constants, we could also have written
ADatas

DC

A(Data,Data+60,Data+453)

or we could have used a literal, and written the LM instruction as


LM

4,6,=A(Data,Data+60,Data+453)

Adcons containing expressions involving external symbols must be used with care. If the referenced routine reorders the statements defining the data, the offsets encoded in the adcons will
probably be incorrect. Its better to identify such entry points by name, not by offset from
another symbol.
Sometimes we must write two or more subroutines that do almost the same thing, but only
minor variations are needed in each. We can combine the routines into a single CSect and use as
much common coding as possible.
Suppose we need not only the ShftRt subroutine, but also one with identical parameters named
ShfLft, which does a logical left shift instead. First, we will sketch an example with no common
coding; assume the parameters are passed in GR0 and GR1:

Chapter X: Large Programs and Modularization

809

Shifter CSect
ENTRY
Using
ShftRt LTR
BNM
SR
ShfOKR SRL
BR
Using
ShfLft LTR
BNM
SR
ShfOKL SLL
BR
End

,
ShftRt,ShfLft
*,15
1,1
ShfOKR
1,1
0,2(1)
14
*,15
1,1
ShfOKL
1,1
0,2(1)
14
,

Control section with 2 entry points


Declare the two entry points
Caller presets R15
Test right shift count
Branch if not negative
Set to zero if it was negative
Shift right
Return
Caller presets R15
Test left shift count
Branch if not negative
Set to zero if it was negative
Shift left
Return

Figure 564. Subroutine with entries for two similar functions

Now, we will rewrite the example to use some instructions common to the two subroutines. The
routine isnt shorter, but illustrates a technique you can use when multiple entry points in a
routine have common instruction sequences that can be shared by each entry.
Shifter CSect
ENTRY
Using
ShftRt MVI
B
Using
ShfLft MVI
ShftAA BASR
Using
LTR
BNM
SR
ShftOK TM
BZ
SLL
BR
ShfR
SRL
BR
ShFlag DS
DROP

,
ShftRt,ShfLft
*,15
ShFlag,0
ShftAA
*,15
ShFlag,1
15,0
*,15
1,1
ShftOK
1,1
ShFlag,1
ShfR
0,2(1)
14
0,2(1)
14
X
15

Control section with 2 entry points


Declare the two entry points
Caller sets base register
Set flag byte for right shift
And enter common code
Using for second entry point
Set flag byte for left shift
Reset base register for local use
And set up correct using info
Test shift count
Branch if not minus
Otherwise set to zero
Test direction of shift
Branch if 0, meaning right
Perform left shifts
Return to caller
Perform right shifts
Return to caller
Flag byte

Figure 565. Subroutine with two similar functions and some common code

The BASR instruction named ShftAA and its associated USING are needed to establish a base
register with a known value for the following instructions. If they had been omitted, the implied
addresses of the subsequent instructions might use the wrong base. If the entry had been at
ShftRt GR15 would contain its address, whereas the USING in effect later will assume that
GR15 contains the address of ShfLft.

38.5.4. The External Symbol Dictionary Listing


When the assembly is complete, the ESD information is encoded into the object module and displayed in the Assembler listings External Symbol Dictionary. 248 For example, if we assemble this
little program:

248

810

You can suppress this part of the listing by specifying the Assemblers NOESD option.
Assembler Language Programming for IBM z System Servers

Version 1.00

Main

ASection
ASecEnt

RSection
ComSect
ADummy

Start
DS
EXTRN
CSect
DS
Equ
ENTRY
DS
RSect
DS
COM
DS
DXD
End

X2400
24D
SomeSym
,
XL137
*
ASecEnt
XL131
,
XL149
,
200F
CL44

Main control section


External symbol declaration
Second control section
Declare internal symbol
Declare internal entry point
Third control section
Fourth control section
Dummy external section

Figure 566. Sample assembly with external symbols

the Assemblers External Symbol Dictionary listing looks like Figure 567:
External Symbol Dictionary
Symbol
MAIN
SOMESYM
ASECTION
ASECENT
RSECTION
COMSECT
ADUMMY

Type
SD
ER
SD
LD
SD
CM
XD

Id

Address Length

Owner Id Flags

00000001 00002400 000000C0


00000002
00000003 000024C0 0000010C
00002549
00000003
00000004 000025D0 00000095
00000005 00000000 00000320
00000006 00000000 0000002C

00
00
08  RSECT flag
00

Figure 567. External symbol dictionary from sample assembly

The seven fields in Figure 567 are:


1. Symbol: the external symbol, converted to upper-case letters.249
2. Type: the type of external symbol, described in Section 38.5 on page 804.
3. Id: the ESDID of the symbol. Note that the symbol ASECENT has no ESDID of its own,
because it is in the control section ASECTION, identified by Owner Id X00000003.
4. Address: the location at which the control section begins. For entry names (identified by
Type LD), the address is the location of the entry point within the owning control section.
Note that each section address has been rounded up to the next doubleword boundary. For
example, ASECTION starts at location X24C0 and is X10C bytes long, so the first available
location is X25CC and RSECTION starts at the next doubleword, X25D0 .
5. Length: the length of the control section.
6. Owner Id: for entry names (Type LD), the ESDID of the control section in which the entry
point resides.
7. Flags: bits indicating the addressing and residence modes and RSECT status declared for
each control section. In this example, all have specified 24-bit addressing mode and residence
below the 16MB line.
We can now give a complete definition of a symbols relocation attribute:

249

Upper-cased external symbols have roots in the days of System/360, when almost all programs were created on
punched cards using upper-case letters. You can generate external symbols with mixed-case letters and other characters using the ALIAS instruction; see the High Level Assembler Language Reference for details.
Chapter X: Large Programs and Modularization

811

1. If a symbol appears in the ESD only, or in the ESD and in the ordinary symbol table, its
relocation attribute is its ESDID.
2. If a symbol appears only in the ordinary symbol table, its relocation attribute is the ESDID
of the control section in which it appears. (Undefined symbols may have ESDID zero.)
A special Type indication (PC) appears in the Assemblers External Symbol Dictionary listing for
unnamed control sections; PC stands for Private Code. 250 As noted on page 790, Private Code
sections may be generated if you put some statements that could affect the Location Counter
ahead of the first START or CSECT statement; the Assembler automatically creates a blanknamed CSECT.
For example, this set of statements:
R1
Main

Equ 1
Csect ,
- - End

EQU can affect the Location Counter!


Start of a control section
Rest of Main CSect

could produce an External Symbol Dictionary listing like this:


Symbol

MAIN

Type

Id

Address Length

PC 00000001 00000000 00000000


SD 00000002 00000000 000002D4

 Unnamed zero-length CSect

Unfortunately, PC sections can sometimes cause the generated load module to have unintended
addressing and residence modes.
ESD records describe four types of external symbols. These two-letter Type abbreviations identify
the symbols type:
SD,CM,PC

Section Definition: the name of a control section, CM identifies COMmon sections


having no machine language text, and PC identifies a blank-named control section;
these three are doubleword aligned by default.

LD

Label Definition entries identify the name of a position at a fixed offset within an
owning Control Section. They are used to identify entry points. Because Label Definitions belong to another CSect, they are the only symbol type having no ESDID of
their own.

ER,WX

These two external symbol types are for External References to symbols not defined
in this module, but to a symbol defined elsewhere to which this module wants to
refer. A special form of external symbol is called WX or Weak EXternal; this type of
reference might not be resolved at link time, without error.

XD

The name of an EXternal Dummy Section; sometimes called a PseudoRegister


(PR). XD names are in a separate link-time name space from all other external
symbols, and may match non-XD external names without conflict. Section 38.7.3 will
discuss their use.

If you specify the SECTALGN(16) option, three different Type identifiers are used for quadwordaligned control sections:
SQ

for a quadword-aligned control section,

CQ

for a quadword-aligned COMMON control section.

PQ

for a quadword-aligned private (unnamed) control section,

To illustrate, well assemble the simple program in Figure 568 with each SECTALGN option:

250

812

Private because you cant refer to such a control section by its nonexistent section name!
Assembler Language Programming for IBM z System Servers

Version 1.00

CSect ,
Blank CSect name (Private Code)

DS
XL5

Section CSect ,
Named control section

DS
XL7

Common COM ,
Common section

DS
XL3

End

Figure 568. Program assembled with different SECTALGN options

Then, Figure 569 shows the key parts of the External Symbol Dictionary listing with each option;
only the Type and Address columns are different.

With SECTALGN(8)

With SECTALGN(16)

Symbol Type Id Address Length Symbol Type Id Address Length

PC 00001 0000000 0000005


PQ 00001 0000000 0000005
SECTION SD 00002 0000008 0000007 SECTION SQ 00002 0000010 0000007
COMMON
CM 00003 0000000 0000003 COMMON
CQ 00003 0000000 0000003

Figure 569. Example of ESD listings with different SECTALGN options

The forms of ESD data in an object module, and how each is processed, will be discussed starting
in Section 38.6.

38.5.5. External Symbol Addressing and Residence Modes


External symbols defining executable control sections (START, CSECT, and RSECT) or COM
reference sections can be assigned mode attributes specifying where in memory you want the
section to be loaded (its residence mode or RMODE), and what addressing mode (its AMODE)
should be assigned by the Program Loader when it passes control to that symbol (assuming the
symbol is designated as the programs entry point). These attributes are assigned by the AMODE
and RMODE assembler instruction statements.
The allowed values of AMODE and their meanings are shown in Table 397.
AMODE
24
31
64
ANY,
ANY31
ANY64

Meaning
The instructions in this control section, or at this
should receive control in 24-bit addressing mode.
The instructions in this control section, or at this
should receive control in 31-bit addressing mode.
The instructions in this control section, or at this
should receive control in 64-bit addressing mode.
The instructions in this control section, or at this
may receive control in 24-bit or 31-bit addressing
The instructions in this control section, or at this
may receive control in any addressing mode.

entry point,
entry point,
entry point,
entry point,
mode.
entry point,

Table 397. AMODE values

The allowed values of RMODE and their meanings are shown in Table 398 on page 814. (For
an illustration of the 16MB line and the 2GB bar, see Figure 149 on page 308.)

Chapter X: Large Programs and Modularization

813

RMODE
24
31, ANY
64

Meaning
The control section should be loaded below the 16MB line.
The control section should be loaded below the 2GB bar,
either above or below 16MB
The control section may be loaded anywhere in memory.

Table 398. RMODE values

If either AMODE or RMODE (or neither) is specified for a section, the Assembler assigns the
values shown in Table 399.
Declared Mode

Assigned Mode
AMODE 24,
R M O D E 24

none
AMODE24, AMODE 31, AMODE ANY,
AMODE ANY31
R M O D E 24
RMODE 31, RMODE ANY
AMODE 64, AMODE ANY64
R M O D E 64

R M O D E 24
AMODE
AMODE
RMODE
AMODE

24
31
31
64

Table 399. Default A M O D E and R M O D E values

Only certain combinations of AMODE and RMODE values are valid, as shown in Table 400.
Mode
AMODE 24
AMODE 31, AMODE ANY,
AMODE ANY31
AMODE 64, AMODE ANY64

Valid values
R M O D E 24
RMODE 24, RMODE 31
RMODE 24, RMODE 31,
RMODE 64

Table 400. Valid combinations of A M O D E and R M O D E values

Figure 570 shows how mode values are assigned to external symbols:
Sect1
Sect1
Sect1

Sect2
Sect2
Sect2

Sect3
Sect3
Sect3
Sect4
Sect4
Sect4

CSect
RMODE
AMODE
STM
- - CSect
RMODE
AMODE
DR
- - CSect
RMODE
AMODE
- - CSect
RMODE
AMODE
- - -

,
24
24
14,12,12(13)
,
24
31
2,11

Assign residence mode


Assign addressing mode
Entry point: save registers, ...

Assign residence mode


Assign addressing mode

,
31
31

Assign residence mode


Assign addressing mode

,
31
64

Assign residence mode


Assign addressing mode

Figure 570. Assigning R M O D E and A M O D E to a section name

The ESD listing from assembling this little fragment is shown in Figure 571 on page 815:

814

Assembler Language Programming for IBM z System Servers

Version 1.00

Symbol

Type

SECT1
SECT2
SECT3
SECT4

SD
SD
SD
SD

Id

00000001
00000002
00000003
00000004

Address Length
00000000
00000008
00000010
00000010

00000004
00000002
00000000
00000000

Owner Id Flags
01
02
06
14

Figure 571. ESD showing R M O D E and A M O D E of section names

To help you understand the Flags field, do Exercise 38.5.17.


The addressing mode in effect when your program runs determines which register bits are used to
form Effective Addresss, as shown in the following figures:
0
40
63

 ignored  24bit address  AMode 24

0
33
63

 ignored  31bit address  AMode 31

0
63

64bit address  AMode 64

Exercises
38.5.1.(2) + Assemble the program in Figure 566 on page 811 with the NOTHREAD option. Which
values in the ESD portion of the listing have different values from those in Figure 567 on
page 811? Why?
38.5.2.(1) + Which assembler instruction statements define define executable control sections
and which define reference sections? Which define space in the object module?
38.5.3.(2) + Rewrite Figure 565 on page 810 so that the MVI instructions modify the operation
code of a single shift instruction, so that it will perform the shifts in the desired direction.
Remove all references to the flag byte.
Note! This is a very poor coding technique; this exercise is included only to show (what were
believed to be clever) techniques used in olden days that now cause programs to run much
more slowly.
38.5.4.(1) Why would specifying the SECTALGN(16) option be useful?
38.5.5.(1) Can you think of any use for Private Code sections?
38.5.6.(2) Write, assemble, and link a small program with unnamed CSECT and COM statements. Describe what happens.
38.5.7.(4) In Exercise 38.5.6 you wrote and assembled a small program with unnamed CSECT
and COM statements. How could you refer to each from separately assembled modules?
38.5.8.(2) + Determine whether the following variation on Figure 565 will work correctly, and
correct it if you think it wont. Explain your conclusions in either case.

Chapter X: Large Programs and Modularization

815

ShftRt
ShfLft
SHFTAA

Using
MVI
B
LA
MVI
LTR

*,15
SHFLAG,0
SHFTAA
15,ShftRt
SHFLAG,1
1,1

Set flag to zero


Branch to common code
Set common base register
Set flag for left shift
...etc...

38.5.9.(4) + Suppose a programmer wrote Figure 565 without the BASR at ShftAA and the following USING, and then attached the name ShftAA to the LTR instruction. Compute bases
and displacements for all the instructions in the program (or, assemble it if necessary), and
determine exactly what happens for correct calls to ShftRt and ShfLft.
38.5.10.(2) + Write an external subroutine named BYTE with two arguments passed using
standard conventions. The first argument is a byte, and the second argument is an 8-byte area
where the subroutine will place 8 EBCDIC zero and one characters representing the bits of the
byte argument.
38.5.11.(2) + Write a separately-assembled subroutine named SIGNUM with a word integer argument that returns in GR0 the value 1 if the argument is negative, + 1 if the argument is strictly
positive, and 0 if the argument is zero. Assume standard linkage conventions, and restore all
modified registers except GR0.
38.5.12.(2) + In Figure 562, the first Load instruction places the address of Data in GR6. Why
cant it be replaced by this instruction?
LA

6,Data

38.5.13.(3) Suppose you are writing a large program that needs an internal debugging aid that
will dump areas of memory in hexadecimal in some readable format. Write a separatelyassembled subroutine named MemDump with this standard calling sequence:
L
CNOP
BASR
DC
DC

15,=V(MemDump)
2,4
14,15
A(start_address)
A(end_address)

Align to halfword boundary

You can use the PRINTLIN instruction to print the formatted lines.
38.5.14.(3) Revise your solution to Exercise 38.5.13 to allow either one or two memory
addresses to be specified in the list following the BASR instruction, in this form:
BASR 14,15
DC
A(X80000000+start_address) For one argument
or
BASR 14,15
DC
A(start_address)
DC
A(X80000000+end_address)

For two arguments

where the high-order bit indicates the last memory address. If only a single argument is given,
display 32 bytes starting at the start_address.
38.5.15.(3) Write an external subroutine named I2D that converts the signed 32-bit integer value
in GR0 to a long hexadecimal floating-point value in FPR0.
38.5.16.(3) Write an external subroutine that converts the short hexadecimal floating-point
number in FPR0 to a fullword integer in GR0. If the floating-point number is too large, return
the maximum negative number in GR0 and set return code 4 in GR15.
38.5.17.(3) + The rightmost six bits of the Flags field indicate the AMODE and RMODE
associated with the external symbol (remember that bit numbering starts at zero):

816

Assembler Language Programming for IBM z System Servers

Version 1.00

Bit 2 (R bit):
Bit 3 (A bit):
Bit 4 (s bit):
Bit 5 (r bit):
Bits 6,7 (aa bits):
Bits 6,7:
Bits 6,7:
Bits 6,7:

1
1
1
1
00
01
10
11

=
=
=
=
=
=
=
=

RMODE
AMODE
RSECT
RMODE
AMODE
AMODE
AMODE
AMODE

64; 0 = use r bit 5


64; 0 = use aa bits 6 and 7
31
24 (default)
24 (declared)
31
ANY

Using the information in Table 400 on page 814, determine all valid values of the Flags field.

38.6. Object Modules


While you dont usually need to know whats in your object modules, every executable program
begins as an (un-executable) object module that must be transformed to a loadable/executable
format. Any functional limitations in what can go into an object module 251 will also limit how we
can think about and build our programs.
Well first look at how the Assembler generates object modules from your source program, and
then in Section 38.7 at how object modules are linked into executable load modules. Finally, in
Section 38.8 well see how load modules and program objects are loaded into storage for execution.
The traditional (OBJ) object module consists of 80-byte card-image records, with X 0 2 in
column 1, and an identifying 3-character tag in columns 2-4. The 3-character tags are:
SYM

This identifies records describing the internal symbols of your program. SYM records are
rarely used now.

ESD

ESD records contain the external symbols of your program and their types. Each symbol
(except LD) is identified by an ID number called its External Symbol Dictionary ID, or
ESDID. Each ESD entry for a control section specifies its length and starting address.
The four types of external symbols are:

TXT

Section Definition: the name of a control section.


Label Definition: the name of an entry point.
External Reference and Weak EXternal reference
EXternal Dummy section

These records contain the machine language instructions and data (the Text) of your
program. Each record indicates how many bytes of data it contains (the length of the
data), which control section it belongs to (its position ID, the ESDID of the control
section owning the text), and where within that control section it goes (its starting
address).
There are no gaps in the data on TXT records, even though there may have been uninitialized gaps visible in the listing.

RLD

Relocation Dictionary records contain data about each relocatable address constant in
your program: its type, where it is within its control section (its Position ID, identified
by the control sections ESDID), its location within that control section (its address), and
what should be put in that field (specified by the ESDID of another external symbol, its
Relocation ID).
RLD records encode information about four types of address constant:
1. A-type: resolves directly to the target address
2. V-type: resolves directly to the target address, or to an indirect linkage assist

251

The format of an object module is described in detail in the High Level Assembler Programmer s Guide. The GOFF
(Generalized Object File Format) object module allows more freedom than the traditional object module format; it
is described in Section 38.8.1., and documented in the MVS Program Management Advanced Facilities manual.
Chapter X: Large Programs and Modularization

817

3. Q-type: resolves to an offset value provided by the Linker (used for referring to
external dummy sections)
4. Cumulative External Dummy: a length constant; the Linker inserts the total length of
all external dummy sections in the bound program. (More about this in Section
38.7.3.)
END

The END record is the last record of an object module, and contains some additional
IDR data identifying the program that created the object module. If your source
program specifies an operand on the END statement (as in Figure 33 on page 83)
requesting that the executed program receive control at that operand, that information is
also encoded on this record.

There is at least one control section per object module, and one object module per assembly. If
you specify the Assemblers BATCH option, one invocation of the Assembler may produce
multiple object modules.

38.6.1. Relocation Dictionary and External Symbol Dictionary


Suppose we assemble the statements in the following figure; its listing extract shows how the
Assembler describes relocation information:
Loc Object Code ... Stmt
000000

000000
000004
000008
00000C

00000000
00000000
00000000
00000000

...
...
...
...
...
...
...
...
...

Source Statement

1 AA
2
3
4 DummyX
5
6 YY
7
8
9

CSect
EXTRN
ENTRY
DXD
DC
DC
DC
CXD
End

,
XX
YY
D
A(XX)
V(XX)
Q(DummyX)
,
,

Start of a control section


External symbol
Entry name
Dummy External Section
A-type constant
V-type constant
Q-type constant
Cumulative external dummy size

The Assemblers External Symbol and Relocation Dictionaries in the listing look like this:
External Symbol Dictionary
Symbol
AA
XX
YY
DUMMYX

Pos.Id

00000001
00000001
00000001
00000001

Type

Id

Address Length

Owner Id

SD 00000001 00000000 00000010


ER 00000002
LD
00000004
00000001
XD 00000003 00000007 00000008

Relocation Dictionary

Rel.Id Address Type Action

00000000 0000000C J 4
ST
 CXDtype constant
00000002 00000000 A 4
+
 Atype constant
00000002 00000004 V 4
ST
 Vtype constant
00000003 00000008 Q 4
ST
 Qtype constant

All the RLD items have Position ID (Pos. Id) X00000001, meaning that all the adcons are
found in control section AA with that ESDID.
The Relocation ID (Rel. Id) gives the ESDID with respect to which the relocation will be
done.

818

Assembler Language Programming for IBM z System Servers

Version 1.00

For example, both the A-type and V-type adcons are relocated with respect to the symbol XX
which has ESDID 2. The Q-type constant relocates with respect to the symbol DUMMYX which
has ESDID 3. CXD items have Relocation ID zero.
The Address field shows the position within the owning control section (identified by the Position ID) where the adcon starts.
For example, the V-type adcon resides in section AA with ESDID 1, at location X00000004.
The Type field indicates the type and length of the adcon. Type J is used for length constants.
The Action field indicates whether the relocation value will be added (+) or subtracted (-) from
the contents of the field in the object text identified by the Position ID and Address, or
whether the relocation value is stored (ST) in the object-text field.

Exercises
38.6.1.(4) + Assemble this little program with the OBJECT option.
Prog

B
D
PRVLen
C

CSect
Extrn
Entry
DC
DC
DC
DXD
DC
CXD
COM
DS
End

,
X
B
F -987
A(X,PRVLen)
V(Y)
3H
Q(D)
,
,
4F

Control section name


External name
Entry name
Constant
A-type address constant
V-type address constant
External dummy section item
Offset of D
Cumulative external dummy length
Common section
Space in the common section

Use any convenient method to display the object module in hexadecimal format. With the
High Level Assembler Programmer s Guide as a guide, study the object module to understand
how the ESD, TXT, and RLD records are encoded.
38.6.2.(2) + What are the differences in the effects of these two types of statements?
DC

V(X)

and

EXTRN X
DC
A(X)

38.7. Program Linking: Combining Object Modules


We will use a simple example to show how two object modules are linked and loaded directly
into memory. The principles are very similar to creating a load module; well explain the differences in Section 38.8. Suppose a program consists of these two source modules:

Chapter X: Large Programs and Modularization

819

Module 1
Loc
000 MAIN
Start 0

CALL SUB

200 ASub
DC
A(Sub)

204 ACom
DC
A(Work)

208 ADat
DC
A(XData)

Entry XData

XData DC
160X 0 1

Work
COM ,

DS
XL(X600)

End MAIN

Module 2
Loc
000 SUB
Start 0

EXTRN XDATA

700 AWork DC
A(Work)

704 AXData DC
A(XDATA)

Work
COM ,

DS
XL(X400)

End

Figure 572. Example of two source modules to be linked

Program MAIN contains the XDATA entry point, and refers to the subroutine SUB and the
common control section WORK, which it requires to be X600 bytes long.
Subroutine SUB refers to the external name XDATA and to the common control section WORK,
which it requires to be X400 bytes long.
Assembling the source modules produces two object modules. The object module for Module 1
would look roughly like this:

ESD SD ID=1 MAIN Addr=000 Len=300

ESD CM ID=2 WORK Addr=000 Len=600

ESD LD ID=1 XDATA Addr=260

ESD ER ID=3 SUB

TXT
ID=1 Addr=000
abcdefghijk...

TXT
ID=1 ...
etc.

TXT
ID=1 Addr=100
mnopqrstuvw...

TXT
ID=1 Addr=208
00000260

TXT
ID=1 Addr=260
01234567890...

TXT
ID=1 ...
etc.

RLD
PID=1 RID=3 Addr=200 Len=4 Type=V Dir=+
RLD
PID=1 RID=2 Addr=204 Len=4 Type=A Dir=+
RLD
PID=1 RID=1 Addr=208 Len=4 Type=A Dir=+
END
Entry=MAIN

SD for CSECT MAIN, ESDID=1, Len=300


CM for COMMON WORK, ESDID=2, Len=600
LD for Entry XDATA, ESDID=1, Addr=260
ER for reference to SUB, ESDID=3
Text in MAIN, address 000
Text in MAIN
Text in MAIN, address 100
Text in MAIN, internal adcon offset
Text in MAIN, address 260
Text in MAIN
RLD item for Addr(SUB)
RLD item for Addr(WORK)
RLD item for Addr(XDATA)
Module end; request entry at MAIN

Figure 573. Sketch of object module from source module 1

The object module contains:


ESD records for two control sections (MAIN and WORK), one entry (XDATA), and one external
reference (to SUB).
RLD records with information about the three address constants. PID represents the Position ID, RID the Relocation ID, and Dir indicates whether the relocation value will be
added or subtracted.
TXT records with machine language instructions and data. The TXT record for Addr(XDATA)
contains the location (X00000260) within control section MAIN because the target of the adcon
is internal to the section.
The object module for Module 2 would look roughly like this:

820

Assembler Language Programming for IBM z System Servers

Version 1.00


ESD SD ID=1 SUB Addr=000 Len=800

ESD CM ID=2 WORK Addr=000 Len=400

ESD ER ID=3 XDATA

TXT
ID=1 Addr=040
qweruiopasd...

TXT
ID=1 ...
etc.

TXT
ID=1 Addr=180
jklzxcvbnm...

TXT
ID=1 ...
etc.

RLD
PID=1 RID=2 Addr=700 Len=4 Type=A Dir=+
RLD
PID=1 RID=3 Addr=704 Len=4 Type=A Dir=+
END

SD for CSECT SUB, ESDID=1, Len=800


CM for COMMON WORK, ESDID=2, Len=400
ER for reference to XDATA, ESDID=3
Text in SUB, address 040
Text in SUB
Text in SUB, address 180
Text in SUB
RLD item for Addr(WORK)
RLD item for Addr(XDATA)
Module end; IDR data

Figure 574. Sketch of object module from source module 2

The ESD records define two control sections (SUB and WORK) and one external reference (to
XDATA).
The RLD records contain information about two address constants.
Note that both object modules assign ESDIDs starting at 1.
First, the Linker/Loader must reserve some memory to hold the loaded program; well suppose
that block of memory starts at X00123500; this is called the load address.
As the object modules are read by the Linker/loader, the external symbols are entered into a
Composite External Symbol Dictionary (CESD). It will contain all external symbols used in
each of the object modules being linked and loaded. After the first object module has been read
and the TXT data has been moved into memory starting at the load address, the CESD would
look like this:

Symbol
Type ESDID Address Length

MAIN
SD 0001 123500
300

WORK
CM 0002

600

XDATA
LD *0001 123760

SUB
ER 0003

Figure 575. Composite ESD after reading first object module

In the CESD entry for XDATA, the * on the ESDID means that 0001 is its owning sections
ESDID. That is, XDATA is an entry point in control section MAIN.
When the second object module is read, its ESDIDs also start at 1. For those of its ESDIDs that
differ from symbols already in the CESD, new ESDIDs must be assigned to prevent conflicts; this
process is called renumbering. The Position and Relocation IDs of address constants are also
renumbered.
The Linker adds new external names to the CESD (in this case, there are no new names) and
adjusts the start address of SUB to start at the next doubleword boundary after the end of MAIN.
The CESD would then look like this:

Chapter X: Large Programs and Modularization

821


Symbol
Type ESDID Address Length

MAIN
SD 0001 123500
300

WORK
CM 0002

600

XDATA
LD *0001 123760

SUB
SD 0003 123800
800

SUB
ER 0003 123800

Figure 576. Composite ESD after loading second object module

The symbol SUB appears twice in the Composite ESD because it is both a section definition and
an external reference.

38.7.1. Assigning COMMON Sections


When reading the ESD of the second object module, the Linker notes that the requested length of
the common block WORK is X400, which is less than the X600 length requested by the MAIN
program. The Linker always retains the longest requested length for common sections, so the
length X600 remains unchanged.
The Linker can now assign an address to WORK at the next doubleword boundary following the
end of Sub. The final, updated CESD then looks like this:

Symbol
Type ESDID Address Length

MAIN
SD 0001 123500
300

WORK
CM 0002 124000
600

XDATA
LD *0001 123760

SUB
SD 0003 123800
800

SUB
ER 0003 123800

Figure 577. Composite ESD after assigning memory addresses

38.7.2. Relocating Address Constants


Well use the three adcons from sample program module 1 (see Figure 573 on page 820) to show
how address constants are relocated.
1. A(XDATA):
The Linker finds an RLD item referring to XDATA. Its position is in MAIN (ESDID=0001) at
offset X208, and it relocates relative to Relocation ID 0001 because the target is an entry in
MAIN. Because its an A-type constant, and the object text at the adcons address contains
X00000260, the Linker loads that word. And because the Dir field indicates that the relocation value is to be added, the loader adds the relocation address X123500 to the contents
of the field at address X123708 and stores the result, X123760, back in Main at address
X123708.
The same process is used for the A(XDATA) adcon in routine SUB.
2. A(WORK):

822

Assembler Language Programming for IBM z System Servers

Version 1.00

The Linker finds an RLD item referring to WORK. Its position is in MAIN (ESDID=0001) at
offset X204, and it relocates relative to Relocation ID 0002. Because its an A-type constant
with no offset, the loader adds the relocation address X124000 to the (zero) contents of the
field at address X123704 and stores the result back in MAIN at address X123704.
The same process is used for the adcon referencing WORK in subroutine SUB.
3. V(SUB):
The Linker finds an RLD item referring to SUB. Its position is in MAIN (ESDID=0001) at
offset X200, and it relocates relative to Relocation ID 0003. Because a V-type constant
cannot have an offset, the loader stores the relocation address X128000 at address X123700
in MAIN.
Now that addresses have been assigned to all external symbols, the address constants have been
relocated by adding or subtracting the relocation value to or from each adcons P-field contents
(for A-type adcons), or by storing the relocation value in V-cons.
After loading and relocation are complete, the program in memory would look like this:
123500 (MAIN)
123800 (SUB)
124000 (WORK) 124600
(end)
abcdefghijk...
...text...
length=600

...more text...

qweruiopasd...

...more text...

...text...

mnopqrstuvw...

...text...

...

jklzxcvbnm...


...text...

A(SUB)00123800

A(WORK)00124000

A(XDATA)00123760

Adcons

00124000 A(WORK)

00123760
A(XDATA)

(XDATA)

01234567890...

Adcons

...
...

Figure 578. Memory layout of loaded program

To summarize:
Storage was allocated for three control sections (two SD, one CM); any excess memory
(including that for the CESD) is freed.
Address constants were resolved to the designated addresses.
The program was given control at the entry point requested by the END statement of the
MAIN program, at address X123500.
The loaded program is X1100 bytes long.
This example has ignored what happens to unresolved strong external references after all object
modules have been read. In practice, the Linker searches a library for names matching the
remaining ERs and loads them in the same way it loaded the object modules. For example, if the
MAIN program had contained an EXTRN for COS and COS was not defined in one of the input
modules, the Linker will search the library for a member of that name. Its important that this
search is done after all primary inputs have been processed, because you may have written your
own COS routine!

38.7.3. External Dummy Sections (*)

Chapter X: Large Programs and Modularization

823

External Dummy Sections 252 are used in situations like these:


Separately assembled or compiled modules must share access to a resource by name, such as
an output file like FILE1.
The complete linked program may be loaded into memory once, but executed simultaneously
by more than one invoker. Thus, it cannot safely modify any of its own internal areas. Such
programs are called reenterable.253
None of the programs declaring the name of an external dummy item component of an External
Dummy Section defines the area of storage it names; the allocation of memory to the External
Dummy Section is done at execution time, as well see.
Using an External Dummy Section requires actions at three different stages: during assembly,
during linking, and at execution time. Well see shortly why its called an External Dummy
Section, and will give an example to show how these three stages work together.
Assembly time: You declare your external dummy item contributions to the External Dummy

Section in one of two ways:


1. Write a DXD statement defining the name, length, and alignment of your external dummy
item component of the External Dummy Section. This example defines two External
Dummy Sections:
FILE1CB DXD
RANDOM DXD

A
D

4 bytes, word aligned


8 bytes, doubleword aligned

Figure 579. Sample D X D declarations

2. Define a Dummy control section (DSECT) and use its name in a Q-type address constant;
this automatically makes the DSECT name an External Dummy Section:
TreeHead
LftLink
RgtLink
SymLen
Symbol

DSect
DS
DS
DS
DS

,
A
A
X
CL63

Head of a binary tree for symbols

Figure 580. External dummy section declaration

Then, define a Q-type constant referring to the DSECT or DXD name:


File1CBP DC
RandomP DC
TreeHdP DC

Q(FILE1CB)
Q(RANDOM)
Q(TreeHead)

External Dummy Section offset


External Dummy Section offset
External Dummy Section offset

Figure 581. Referencing external dummy items with Q-cons

The Assemblers External Symbol Dictionary entries for these three symbols are shown in this
excerpt:

Symbol Type Id
Address Length

FILE1CB XD 00000002 00000003 00000004


RANDOM
XD 00000003 00000007 00000008
TREEHEAD XD 00000004 00000007 00000048

Figure 582. External dummy items in ESD listing

252
253

824

Ordinary Dummy Control Sections (DSects) will be discussed extensively in Chapter XI.
The more common term is reentrant, but this also refers to a type of mathematical curve, which doesnt apply
here.
Assembler Language Programming for IBM z System Servers

Version 1.00

The Address field is actually an alignment mask: the requested alignment for the External
Dummy Section item as a power of two, less one. (See Exercise 38.7.3.)
Link time: The Linker collects all the External Dummy Section contributions from the set of

object modules is it linking, and constructs the template for the complete External Dummy
Section. Each item is aligned according to its definition, and space is reserved according to its
length. If more than one contribution has the same name, the Linker assigns the strictest alignment and longest length to that name. Thus, the Linker is creating something like a link-time
Dummy Section; like a DSECT, it only describes an area of memory without actually allocating
it.
For example, if a separate module also defined the DXD symbol RANDOM as in Figure 583,
RANDOM

DXD

16 bytes, doubleword aligned

Figure 583. Separate D X D declaration

the Linker would use the longer of this value and the one in Figure 579 on page 824, and assign
length 16 and doubleword alignment to that name.
The completed External Dummy Section might look like this:
Offset

38 FILE1CB XD item

40 RANDOM
XD item

50

6C TreeHead XD item

B4

DC

other items...
length 4, word aligned
length 16, doubleword aligned

length 72, word aligned

Total length of the External Dummy Section

Figure 584. Example of a completed External Dummy Section

After the Linker has assigned all external dummy items offsets in the External Dummy Section, it
then resolves the Q-type address constants by placing the offset from the start of the External
Dummy Section of the operand name. Thus, for example, any Q-type address constant referring
to FILE1CB would contain X00000038; if the Q-con had explicit length 2, it would contain
X0038.
Finally, the Linker puts the accumulated length (X000000DC ) of the entire External Dummy
Section into each CXD-type address constant. (You can now understand why CXD means
Cumulative External Dummy. Usually, theres only one CXD in a completed program; well
see why in a moment.)
When linking is complete, all address constants of types A, V, Q, and CXD have been resolved:
A- and V-type for internal and external symbol references, Q-type for External Dummy Section
offsets, and CXD-type for the cumulative length of the External Dummy Section.
Execution time: During initialization, each invocation of the main program uses operating

system services to allocate an area of memory whose length is determined by the link-time value
placed in the CXD-type constant, and sets the area to zeros. The address of this new area is put
in a general register known to all routines that will access fields in the External Dummy Section.
Suppose GR11 has been assigned to hold this address:

Chapter X: Large Programs and Modularization

825

EDSLen

L
0,EDSLen
GetMain R,LV=(0)
LR 11,1
- - CXD ,

Get length of External Dummy Section


Get storage
Carry E.D.S. address in R11
Initialize contents to zero
Linker inserted total length of E.D.S.

Now, suppose one of several modules in the complete program wants to write records to FILE1,
and has declared an external dummy item as in Figure 579 on page 824. It retrieves the FILE1CB
item (a file control block giving access to the I/O routines) from the External Dummy Section:
L
AR
L

2,=Q(FILE1CB) Get EDS offset of FILE1CB pointer


2,11
Storage address of FILE1CB pointer
2,0(,2)
Pointer to FILE1CB now in R2

Figure 585. Retrieving an External Dummy Section item

The routine can now call the routine that writes records, passing the addresses of the record, its
length, and the address of the FILE1CB field in the External Dummy Section (which will initially
be zero). The write routine notes the zero FILE1CB field and allocates more storage to hold the
control blocks and other items needed to complete the write operation. It then stores the address
of these control blocks back in the FILE1CB field in the External Dummy Section.
Later, any other routine that wants to write records to FILE1 will retrieve the updated FILE1CB
pointer from the External Dummy Section as in Figure 585; the write routine can then access the
already-established control blocks to write the record.
Some history:
External Dummy Sections and external dummy items were originally used in OS/360 for reenterable PL/I applications to allow sharing by name of dynamically managed external objects
such as files, areas, and controlled variables that were defined in separately translated reenterable programs.
PL/I called the external dummy items PseudoRegisters (PRs), and the External Dummy
Section a PseudoRegister Vector (or PRV). Each PR item was a 4-byte address, so it was
natural to think of them as representing additional registers, and the External Dummy
Section as a vector of PRs.
Instructions referring to PR items were usually RX-type Load instructions. For example, the
generated instruction was carefully arranged to do the same as in Figure 585, but saving one
instruction:
L
ORG
DC

2,0(11,0)
*-2
QL2(FILE1CB)

Zero displacement and base fields!


Displacement (and zero base)

Figure 586. PL/I technique for loading Pseudo Registers

so that the generated instruction would be X582B 0xxx where 0xxx is the PR offset in the
QL2-con, and the assigned External Dummy Section address (in GR11) is specified in the
index register field of the L instruction. Thus, PL/Is PRV allowed up to 1024 more 32-bit
pseudo registers.
PseudoRegisters are not used frequently today.
COMMONs and DXD items have similarities and differences, as outlined in Table 401 on
page 827.

826

Assembler Language Programming for IBM z System Servers

Version 1.00

Link-time
behavior

COMMON
Space allocated in the load
module

Storage
Allocation
Initialization

Static: part of the load


module
None

Copies
External
names

External dummy item


No space allocated; a mapping of all items
into a virtual External Dummy Section
Dynamic: at execution time
Execution-time responsibility

One per load module; not


reenterable
One per common, one per
load module

Internal
names

As many as you want

References

Direct, with adcons

One per reenterable load module,


instantiated during each execution
One per item; no conflict with non-External
Dummy Section names
None (but you can map the items inner
structure with a DSECT)
One level of indirection via Q-con offsets
and the base register anchoring the allocated
storage

Table 401. Differences in linking COMMONs and External dummy items

To summarize:
An External Dummy Section is like a component of a DSECT, but no space allocated in the
programs that define the external dummy items that compose it. It is a template, a datastructure mapping created at link time. (Hence the Assemblers name, External Dummy, as
indicated by the XD type in the External Symbol Dictionary listing.)
An external dummy item can have internal structure if it is mapped by a DSECT whose name
appears in a Q-type constant.

38.7.4. Loading Object Modules (*)


To show how linkers load object modules, we will sketch the behavior of a simple loader; a real
loader must handle complexities that well ignore here. The basic steps are
1. Clear the ESDID Translation Table at the start of reading each object module.
2. Get an external symbol
3. Search the CESD to see if the symbol is already known from previous object modules.
For each input symbol type, search for a possible match among symbols of the types shown in
Table 402. (During processing, LD types are sometimes re-typed as LR, meaning Label
Reference.) As mentioned previously, PR symbols need not differ from the other types of
symbols.
Input
Type
SD
LD
ER
CM
PR

Search These Types


ER,
ER,
ER,
ER,

LD, SD,
LD, SD,
LD, SD,
LD, SD,
P R Only

CM
CM
CM
CM

Table 402. ESD symbol search types

Different processing is required, depending on whether the incoming symbol already exists in the
CESD (match processing) or not (no-match processing).
No-Match Processing
If the incoming symbol is not found in the CESD, the loader takes these steps:

Chapter X: Large Programs and Modularization

827

1. Make an entry in the ESDID Translation Table, unless the symbol is type LD (its ESDID is
that of its owning section).

Indexed by Input ESDID CESDID

ESDID

17
 Newly assigned CESDID value for

the new symbol identified by this

ESDID

Figure 587. ESDID Translation Table entry for an incoming symbol

2. Perform processing, depending on symbol type:


SD
a. Determine the next available memory location (by adding the lengths of all previous control sections to the initial load address, rounding up each CSect address
(origin + Length) to the next doubleword boundary.
b. Enter the name and start address of the new CSect in its CESD entry. Assign a
new translation ID in the ESDID translation table to convert the ESDID of the
current entry to the newly assigned CESDID of the symbol, as shown in
Figure 587. Chain RLDs in this section to the CESD entry.
A typical CESD entry might look like this:

Symbol Type Load address Rel. Reloc. Const.  RLDs

Length, Alignment  for PR items

Figure 588. A typical load-time CESD entry

where the Load Address is the true address assigned to the symbol, and the Relative Relocation Constant is used to adjust translator-assigned addresses to true
addresses.
c. Test for table overflows, and terminate loading if any.
d. Determine the relative relocation constant from the expression
(Linker-assigned CSect address) - (translator-assigned address)
where the translator-assigned address in the address field of the ESD entry.
e. Set a flag if this is a zero-length CSect; otherwise add its length to the current load
address and round up to the next doubleword boundary.
LD
a. Make a CESD entry for the symbol.
b. Determine the true address of the symbol by adding the relative relocation constant (address) of the CSect owning this LD item (the owning ID can be found in
the CESD by using the ESDID Translation Table) to the input address of the LD
item.
c. Make no ESDID Translation Table entry for this LD symbol (it has no separate
ESDID entry).
ER

828

Make a CESD entry for the symbol, and chain any associated RLD items to it.

Assembler Language Programming for IBM z System Servers

Version 1.00

CM
a. Make a CESD entry, and chain related RLDs to it. Set the Load Address to zero.
b. Enter the Commons length and input address to the CESD entry.
PR
a. Make a CESD entry for the symbol, enter the PR length and alignment, and
chain related RLD items (Q-type constants) to it.
Match Processing
If the incoming symbol is found in the CESD, the loader must take more complex actions,
depending on the types of the new and existing CESD symbols. Because Private Code (PC)
names are not unique, treat each PC as a new, unique SD: make a translation table entry, and
create a CESD entry with its load address, length, and relative relocation constant, and chain any
associated RLD items to the entry.
(1) Existing CESD Symbol is SD

New Symbol
SD
CM
LD
ER
PR

Processing
Error: duplicate section. Set a flag to ignore TXT and RLD items for this
ESDID.
Check for CM length > SD length, error if so (CM references could overwrite subsequent CSects). Relocate RLDs referencing this symbol.
Error: conflicting types.
Make a Translation Table entry referring to the SD in the CESD.
Ignore.

Table 403. Matching existing CESD SD symbol to incoming symbols


(2) Existing CESD Symbol is LD

New Symbol
SD
CM
LD
ER
PR

Processing
Error: ESDID SD symbol matches an existing entry point. Set a flag to
ignore TXT and RLD items for this ESDID.
Error: ESDID CM symbol matches an existing entry point.
Error: matching symbols with conflicting types.
Make a translation table entry referring to the CESD LD.
Ignore.

Table 404. Matching existing CESD L D symbol to incoming symbols


(3) Existing CESD Symbol is CM

New Symbol
SD
CM
LD
ER
PR

Processing
Assign the greater of the lengths of the CESD CM and the incoming ESDID
CM, and change the CESD CM symbol to SD.
Assign the greater of the lengths of the CESD CM and the ESDID CM to
the CESD CM.
Error: matching symbols with conflicting types.
Make a translation table entry referring to the CM.
Ignore.

Table 405. Matching existing CESD C M symbol to incoming symbols


(4) Existing CESD Symbol is ER

Chapter X: Large Programs and Modularization

829

New Symbol
SD
CM
LD
ER
PR

Processing
Change the CESD entry to SD, and update the cumulative length of the
loaded program. Relocate RLDs chained to the ER item.
Change the CESD entry to CM. Make a translation table entry for the
ESDID CM.
Change the CESD ER symbol to LD. Update the relocation constant to
refer to the assigned LD address, and relocate RLDs.
Make a translation table entry referring to the CESD ER symbol. If both
ERs are WX, leave the WX flag on; otherwise set it off.
Ignore.

Table 406. Matching existing CESD E R symbol to incoming symbols


(5) Existing CESD Symbol is PR

New Symbol
SD
CM
LD
ER
PR

Processing
Ignore
Ignore
Ignore
Ignore
Set the CESD length to the greater of the CESD and ESDID PR lengths,
and the alignment to the stricter of the two alignments.

Table 407. Matching existing CESD E R symbol to incoming symbols


TXT Record Processing: The loader checks the ESDID of the TXT record; if invalid, it discards

the record. If valid, it checks the length of the TXT data against the current load address to see if
available storage would be exceeded, and terminates loading if so. Otherwise it moves the text to
the assigned address, and updates the load address.
END Record Processing: If no entry-point address has been assigned, and one is defined on the

END record, save it. If an entry address has already been assigned, ignore the END record.
Final Processing

1. Unresolved ERs: If any unresolved ER items remain, search the Load Library (if requested),
and load and relocate the members whose names match the unresolved ER names.
2. Commons: After the text has been loaded, space for each CM section is allocated, checking
the length against the amount of available storage. The storage address of each CM is
updated in the CESD.
3. PR Processing: Knowing the length and alignment of each PR item, the loader assigns a
virtual offset to each, respecting the requested alignments, and noting the maximum final
offset. These offsets are used in relocating Q-type address constants referring to the PR
symbols, and the total length (the maximum offset) is assigned to CXD-type address constants.
4. RLD Processing: The address of each symbol in the CESD is now known, so the RLD
items assigned to each can be relocated. (Remember that the address of the operand of a
V-type address constant is stored in its text field, while the address of the operand of an
A-type address constant is added to its text field.)
5. Release working storage, and enter the loaded module at its entry address.

Exercises
38.7.1.(1) + In Figure 577, why does the symbol XDATA have the same ESDID as the symbol
MAIN?

830

Assembler Language Programming for IBM z System Servers

Version 1.00

38.7.2.(3) Common sections cannot have entry points. Suppose you are expected to write a
routine that uses a symbol YourData that is defined at an unknown offset in another programs
common section named MyCom, but you have no way of knowing in advance what that offset is,
nor can you define an EXTRN for YourData.
Can you devise a way for the owner of the MyCom common section to help you determine the
address of YourData? (It can be done!)
38.7.3.(2) + Show how the Address fields in Figure 582 on page 824 can be used as alignment
masks.
38.7.4.(2) + The comment following Figure 586 on page 826 says that this technique allowed
PL/I to define up to 1024 PRs. Why at most 1024, and not more?

38.8. Load Modules and Program Objects


We often want to save a linked program so it can be executed more than once without repeating
the full linkage process. This is done by having the Linker create a load module.
We will describe the load module format used on MVS-based operating systems (including z/OS).
Other operating environments use different formats, but the general principles are similar.
An executable load module that can be loaded and executed many times is created following the
same steps illustrated in Section 38.7, with these differences:
Instead of allocating an area of memory and loading the object text directly into that area, the
Linker builds a file with assumed origin zero. Thus, the first control section is assigned address
X000000, and subsequent control sections are added in order, following alignment of their
offset from the origin.
The completed load module file is written into a Partitioned Data Set (PDS) library from
which it can be loaded for execution, or used as input to the Linker for relinking.
The final assignment of memory addresses and adcon relocation happens when the Program
Loader brings the load module into memory for execution; well describe that process in
Section 38.9 on page 841.
Suppose we use the two object modules in Figures 573 and 574 to create a load module. Now,
all addresses in the CESD are assigned relative to a zero origin, as shown in Figure 589:

Symbol
Type ESDID Address Length

MAIN
SD 0001 000000
300

WORK
CM 0002 000300
600

XDATA
LD *0001 000260

SUB
SD 0003 000900
800

SUB
ER 0003 000900
800

Figure 589. Composite ESD after assigning load module addresses

As in Figure 577 on page 822, the symbol SUB appears twice; in this case the ER belongs to the
MAIN program, while the SD belongs to SUB. If the subroutine SUB is replaced by a newer
version, you wont want the ER to be deleted because MAIN must still be able to call SUB.
The address fields of all RLD items are adjusted relative to zero. The text fields of adcons (such
as those referencing WORK and XDATA) are updated to contain the offset relative to the zero assumed
origin of their respective targets.
Chapter X: Large Programs and Modularization

831

The length of the bound program is the same, X1100 bytes.


As before, if there are unresolved external references the Linker will search one or more libraries
and include them in the load module. When this process is completed, the load module is written
to the library.
The records of a load module are similar to the records of an object module (which simplifies
processing each):
SYM

Object-module SYM records are copied directly into load modules. They are included
only at user request.254

IDR

Identification records (from object module END records, the Linker, the user, and
other maintenance programs).

CESD

The Composite External Symbol Dictionary; this is needed if the load module will be
relinked.

TEXT

Machine language instructions and data.

CTL/RLD

Control records, for reading and relocating text records, and including Relocation Dictionary information.

EOM

End of module (a flag field in a control record).

A sketch of a load module as it is written to the library is shown in Figure 590. (The library
for load modules is a Partitioned Data Set, or PDS.)

SYM

CESD

IDR

CTL

Text

:
:

CTL/RLD

:
:

Text

EOM/RLD

(If any)

Length/address of first text record


First text record, placed at load address

Relocation data for first text record;


length/address of second text record

Last text record


Relocation data for last text record

Figure 590. Sketch of a load module

When loaded into memory, a load module is a single, one-dimensional set of contiguous control
sections:

254

832

SYM records were originally used to help debuggers, but are rarely used now.
Assembler Language Programming for IBM z System Servers

Version 1.00


 Loaded Text
 Data Never Loaded



CSECT CSECT CSECT
SYM IDR RLD ESD
AA BB CC
Data Data Data Data






What you see in storage
Hard to access


Figure 591. A load module after loading

The format of a load module was fixed very early in System/360 days, and many tools and products depended on its format not changing; this made it nearly impossible to add new function.
The z/OS Binder now supports Application Programming Interfaces (APIs) that can extract
and update any interesting information in a load module.

38.8.1. External Subroutines and Assisted Linkage: Overlay (*)


Assisted linkages with external subroutines are more complicated than for the internal subroutines
we discussed in Section 37.6 on page 770, where uniform addressability was assumed.
If the routine providing the assisted linkage (such as the Caller routine in Figure 513 on
page 770) is external to the routines making the calls, the subroutine numbers will have been
defined there, so the values of subroutine numbers like Print# wont be known to the calling
routines.
There are several ways to solve this problem, such as defining a table of subroutine numbers that
can can be copied into any program using Caller. Another is to create a macro-instruction that
defines the subroutine numbers, and any calling program can invoke the macro.
Overlay: An early technique for providing indirect linkage was called overlay. It was used extensively in programs that needed more memory than was economically available at the time.

For example, suppose you had a MAIN program that needed to call subroutines SUBA and
SUBB, but neither subroutine was called by the other. A typical arrangement in storage might
look like this, if there was enough room in memory:

MAIN

CALL SUBA
CALL SUBB

SUBB

SUBA

In this case, the V-type address constants in MAIN for each of SUBA and SUBB would be
resolved directly to their targets.
But if there wasnt enough room for all three at the same time, you could arrange them like this,
if you had a way to tell the Linker and Program Loader how to arrange the three routines:

Chapter X: Large Programs and Modularization

833


MAIN

 SUBA and SUBB can overlay each other


SUBA
SUBB

The solution was provided by the Linkers overlay control statements. The Linker would
arrange the routines so that the contents of memory looked like this when MAIN was loaded:

ENTAB

 Small Entry Table


SUBB stub
SUBA stub

MAIN

CALL SUBA
CALL SUBB

: SUBA or SUBB :  Where SUBA or SUBB will be loaded

The Entry Table is constructed by the Linker, and contains short stub routines to which the
V-type address constants in MAIN were resolved. Each stub called the Supervisor to load either
SUBA or SUBB into memory if it wasnt already there. The stub also contained an A-type
address constant with the memory address of the subroutines entry point where it would be after
is was loaded. The stub could then branch directly to the subroutine.
For example, suppose MAIN called SUBA first, so it was loaded into memory by the Supervisor.
When SUBA returned control to MAIN it called SUBB; the Supervisor would then load SUBB
into the same area of memory just occupied by SUBA, overlaying it.
If an area of working memory needed to be shared among MAIN, SUBA, and SUBB, the usual
solution was to define a Common section that would be loaded with MAIN. Because its address
would be known to all three routines, A-type address constants were used for direct references.
The cost of memory has dropped rapidly since the days when overlay was needed, so its little
used today. But its an interesting example of how to manage assisted linkage among separately
translated routines.

38.8.2. Program Objects (*)


Program objects are the newest form of z/OS loadable module. 255 A program object provides
many enhancements compared to Load Modules: they can be much larger, portions can be
loaded into distinct areas of memory, and they can retain many more forms of useful information
that need not be loaded into memory along with machine instructions and data. The summary in
Section 38.11 will compare these differences in greater detail.
A key feature of program objects is support for classes.256 Whereas a load module is a collection
of control sections loaded as a single entity into one area of memory, a program object is a collection of independently relocatable classes that can be loaded into multiple disjoint areas of
memory. Well describe program object loading in Section 38.9 on page 841.
You can create classes with the Assembler in several ways:
1. Generate traditional object modules as described in Section 38.6 on page 817. At link time,
direct the Binder (the z/OS Linker) to save the generated result in a PDSE (Partitioned Data

255
256

834

Some support is provided on z/CMS.


These are not the same as classes as defined in object-oriented programming languages.
Assembler Language Programming for IBM z System Servers

Version 1.00

Set Extended), a more modern form of library. The Binder will create default classes for
you. (Section 38.8.4 explains how this is done.)
2. Specify the GOFF (Generalized Object File Format) option to the Assembler for the same
source program. The Assembler will generate the new-format object file and assign default
classes for you. The presence of classes will usually require the Binder to save the generated
program object in a PDSE.
3. Specify the GOFF Assembler option, and create your own classes using the CATTR (Class Attributes) Assembler instruction.
The first two of these ways to generate a program object require no changes to your source
program.
Classes and Sections: Its easiest to think of the structure of a program object as having two

dimensions, one defined by a Section and the other by a Class.


 Classes
Sections
Class X
Class Y
Class Z

Section A Element Element Element

Section B Element Element Element

Figure 592. Sketch of program object structure

The term Section is used in a different sense with program objects. Rather than naming a
control section (as with load modules), it names a set of contributions to one or more classes.
The contribution of a Section to a Class is called an Element. Elements are analogous to
control sections from ordinary assemblies: they are an indivisible collection of machine language
instructions and data.
Thus in Figure 592, Sections A and B each contribute instructions or data (or both) to Classes
X, Y, and Z. A Section can contribute (or not) to any number of Classes.
Each class in a program object has uniform binding and loading attributes and behavior; these are
assigned when the class is defined in your program.
As an example, suppose we assemble this little program and specify the GOFF option:
A
*
B

CSect
STM
- - CSect
DC
End

,
14,12,12(13)
,
3A(*-B+1)

Figure 593. Sample program assembled with the G O F F option

Key parts of the External Symbol Dictionary listing from this assembly look like this:

Chapter X: Large Programs and Modularization

835

Symbol
A
B_IDRL
B_PRV
B_TEXT
A
B
B_IDRL
B_PRV
B_TEXT
B

Type Id
SD 00000001
ED 00000002
ED 00000003
ED 00000004
LD 00000005
SD 00000006
ED 00000007
ED 00000008
ED 00000009
LD 0000000A

Address Length

Owner Id

00000001
00000001
00000000 00000004 00000001
00000000
00000004
00000006
00000006
00000008 0000000C 00000006
00000008
00000009












Section
Class for IDR data
Class for DXD items
Class for object text
Entry
Section
Class
Class
Class
Entry

Figure 594. ESD from program assembled with the G O F F option

There are many differences from what youd see if the program had been assembled without the
GOFF option:
Although CSects A and B are shown as SD items, they have no address or length. They are
simply owners or containers for the contributions to Classes.
For each executable control section, the Assembler automatically generates three Classes, as
indicated by the ED (for Element Definition) in the Type column: 257
B_IDRL

A Class to contain IDR (identification) data for each Section.

B_PRV

A Class to contain external dummy item data for each Section, in case any are generated.

B_TEXT

A Class that contains the generated object code for each Section. Each ED item in
this class has an address (the starting address of the element) and a length. This is
the default Class if no class was explicitly defined by the CATTR instruction.

Each ED item has its own ESDID, and its Owner Id is the ESDID of the section to which it
belongs.
Because you may want to refer to instruction or data items in a CSECT by name, the Assembler generates an LD entry-point item for each control sections name at the origin of the
B_TEXT Class into which the object code is generated. Thus, the LD entry for symbol A indicates it is at location 0 in the Class with ID 00000004, B_TEXT.
Each LD item has an ESDID, because it can be assigned attributes not available without the
GOFF option.
Because program objects can be much larger than load modules (which are limited to 16MB
in size), all address fields in the listing are 8 digits long rather than the 6 digits for an assembly
without the GOFF option.
Similar comments apply to the External Symbol Dictionary entries from CSECT B.
Because the little program in Figure 593 on page 835 (and others like it) dont specify more than
a single Class for instructions and data, either a load module or a program object can be created
by the z/OS Binder.
When you specify the GOFF option, you can assign AMODEs to entry (LD) and external (ER)
symbols. For example:

257

836

These three classes are generated so that older programs that define no explicit classes so the Binder can link them
more easily into program objects, giving compatible behavior between the load module and program object forms of
the same program.
Assembler Language Programming for IBM z System Servers

Version 1.00

AModes
A
A
B

CSect
DC
AMODE
AMODE
Extrn
Entry

,
V(B)
24
64
B
A

External symbol

Entry point

Figure 595. Assigning A M O D E to an entry symbol

The corresponding ESD listing is shown in Figure 596. (the AMODE for symbol B is properly
encoded in the GOFF object file.)
Symbol

Type

AMODES
B_IDRL
B_PRV
B_TEXT
AMODES
B
A

SD
ED
ED
ED
LD
ER
LD

Id

Address Length

Owner Id Flags

00000001
00000002
00000001
00000003
00000001
00000004 00000000 00000004 00000001
00000005 00000000
00000004
00000006
00000001
00000007 00000000
00000004

00
00
01

Figure 596. ESD showing A M O D E assigned to entry and external symbols

This technique can be useful if you create a module with more than one entry point, and wish to
receive control in the intended addressing mode.

38.8.3. The Class Attribute Instruction CATTR


As sketched in Figure 592 on page 835, we need to specify both the Section and the Class to
define the elements to which which our data and instructions belong. The Section is defined by
the traditional CSECT and RSECT instructions, and the Class is defined by the CATTR instruction. For example, the following assembly defines two Sections (SECT_A and SECT_B and three
Classes (B_TEXT, CLASS_X, and CLASS_Y):
SECT_A
CLASS_X
Msg_1
SECT_B
CLASS_X
Msg_2
SECT_A
CLASS_Y
Msg_3
SECT_B
CLASS_Y
Msg_4

CSect
STM
CATTR
DC
CSect
LM
CATTR
DC
CSect
CATTR
DC
CSect
CATTR
DC

,
14,12,12(13)
,
C A message
,
14,12,12(13)
,
C Good News
,
,
C Better News
,
,
C Enough!

Appears in Class B_TEXT


Appears in Class CLASS_X
Appears in Class B_TEXT
Appears in Class CLASS_X

Appears in Class CLASS_Y

Appears in Class CLASS_Y

Figure 597. Sample program defining two Sections and three Classes

The assignment of instructions and data to the six elements defined by the Sections and Classes
looks like this:
B_TEXT
CLASS_X CLASS_Y

SECT_A STM
Msg_1 Msg_3

SECT_B LM
Msg_2 Msg_4

Figure 598. Assignment of instructions and data into elements

Chapter X: Large Programs and Modularization

837

The (slightly abbreviated) assembly listing of the program is shown in Figure 599 on page 838:
Loc
00000000
00000000
00000008
00000008
00000020
00000020
00000011
00000011
00000004
00000028
00000028
00000024
00000033
00000033

... Stmt Source


...
1 SECT_A
...
2
...
3 CLASS_X
...
4 Msg_1
...
5 SECT_B
...
6
...
7 CLASS_X
...
8 Msg_2
...
9 SECT_A
...
10 CLASS_Y
...
11 Msg_3
...
12 SECT_B
...
13 CLASS_Y
...
14 Msg_4

Statement
CSect ,
STM 14,12,12(13)
CATTR ,
DC
C A message
CSect ,
LM
14,12,12(13)
CATTR ,
DC
C Good News
CSect ,
CATTR ,
DC
C Better News
CSect ,
CATTR ,
DC
C Enough!

Appears in Class B_TEXT


Appears in Class CLASS_X
Appears in Class B_TEXT
Appears in Class CLASS_X

Appears in Class CLASS_Y

Appears in Class CLASS_Y

Figure 599. Assembly listing for sample program

This listing excerpt shows several things:


1. The Location Counter values are 8 hexadecimal digits long. This is because portions of a
program object can be larger than 16MB, can be loaded above the 16MB line.
2. Each Class starts on a doubleword boundary. (You can use the ALIGN operand of the
CATTR instruction to modify this.)
3. The contributions to CLASS_X are the constants named Msg_1 and Msg_2, both being 9 bytes
long. Thus the contributions to CLASS_X total 18 bytes.
4. The contributions to CLASS_Y are the constants named Msg_3 and Msg_4, respectively 11 and 7
bytes long. Thus the contributions to CLASS_Y also total 18 bytes.
The External Symbol Dictionary created from assembling the program in Figure 593 on page 835
looks like this:
Symbol Type Id
SECT_A
SD 00000001
B_IDRL
ED 00000002
B_PRV
ED 00000003
B_TEXT
ED 00000004
SECT_A
LD 00000005
CLASS_X ED 00000006
SECT_B
SD 00000007
B_IDRL
ED 00000008
B_PRV
ED 00000009
B_TEXT
ED 0000000A
SECT_B
LD 0000000B
CLASS_Y ED 0000000C

Address Length

Owner Id

00000001
00000001
00000000 00000004 00000001
00000000
00000004
00000008 00000012 00000001









Section
Generated by Assembler
Same
STM instruction
SECT_A entry
Class
Section

00000007
00000007
00000020 00000004 00000007  LM instruction
00000020
0000000A  SECT_B entry
00000028 00000012 00000007

Figure 600. External symbol dictionary for sample program

From this ESD listing, we see that:


1. The address assigned to each Class starts on a doubleword boundary.
2. The lengths of classes CLASS_X and CLASS_Y are both X00000012 or 18 bytes.
3. The contributions to Class B_TEXT are each 4 bytes long.
The CATTR instruction supports several operands; the most useful are the RMODE and loadability
attributes:
RMODE(n)

838

This allows you to specify the region of memory where the Program Loader should
place the Class. The allowed values of n are 24, 31, and 64.

Assembler Language Programming for IBM z System Servers

Version 1.00

ALIGN(n)

You can specify other than the default alignment for the Class. n is an exponent of
2 and takes values from 0 to 12, meaning byte to page alignment.

DEFLOAD

A Class with this attribute can be loaded by the Program Loader when requested. It
is used by reenterable programs to contain data and instructions needed for each of
many simultaneous executions of the same program.

NOLOAD

A Class with this attribute will be included in the program object by the Binder, but
will not be loaded by the Program Loader. NOLOAD classes are typically used for
symbol tables, source code, and other record-oriented information you want to keep
with the executable program.
If neither DEFLOAD or NOLOAD operands are specified, the default is LOAD, meaning that
the class will be loaded when the program object is put in memory by the Program
Loader.

PART(name)

A Part is a named subdivision of an element that can have internal structure and be
addressed by its name.

An example of defining a PART is shown in Figure 601:


PartSect CSect ,
ClassA CATTR Part(P1)
DC
2D 1 . 2 3
ClassA CATTR Part(P2)
DC
C Hello!
Figure 601. Example of declaring parts in a G O F F class

The corresponding ESD is shown in Figure 602; note that Parts are given type PD by the Assembler.
Symbol
PARTSECT
B_IDRL
B_PRV
B_TEXT
PARTSECT
CLASSA
P1
P2

Type
SD
ED
ED
ED
LD
ED
PD
PD

Id

00000001
00000002
00000003
00000004
00000005
00000006
00000007
00000008

Address Length

00000000
00000000
00000000
00000000
00000000

00000000
00000000
00000010
00000006

Owner Id Flags

00000001
00000001
00000001
00000004
00000001
00000006
00000006

00
00
00
00

Figure 602. ESD for parts in a G O F F class

An element in a given section and class may contain several Parts; you can visualize them like
this:
:
:

Part T

Part P1

Part P2


:
:

An Element in a Load Class


or a Deferred-Load Class

Chapter X: Large Programs and Modularization

839

38.8.4. Programming for Program Objects


When writing programs that utilize classes and parts:
1. You must specify the GOFF option. In not, CATTR statements are simply checked for
correct syntax, and are otherwise ignored.
2. Literals are generated wherever a LTORG statement appears; be careful where you write
your LTORGs.
3. If any literals appear in your program after the last LTORG statement, check carefully that
the Assembler generates them where you intended.
4. To resume a class, use its name in a CATTR statement with no operands. LOCTR statements cant be used to resume a class.
5. Be careful when using ORG with a class or part name, especially if the class name appears in
more than one section.
6. You can specify an AMODE for entry point names and external references that can be used
in some situations to help set the correct addressing mode for references to such symbols. For
example:
Prog
ClassA
XA
XA
XB

CSect
DC
CATTR
DC
ENTRY
AMODE
EXTRN
AMODE

,
C 1
,
C 2
XA
31
XB
64

 Entry XA has AMODE 31


 External symbol XB has AMODE 64

The ESD listing from assembling this little program with the GOFF option is:
Symbol

Type

PROG
B_IDRL
B_PRV
B_TEXT
PROG
CLASSA
XA
XB

SD
ED
ED
ED
LD
ED
LD
ER

Id

00000001
00000002
00000003
00000004
00000005
00000006
00000007
00000008

Address Length

Owner Id Flags

00000001
00000001
00000000 00000001 00000001
00000000
00000004
00000008 00000001 00000001
00000008
00000006
00000001

00
00
02  AMODE 31

Even though the AMODE of symbol XB isnt shown in the Flags column, it is properly
defined in the GOFF object file.

38.8.5. Comparing Load Modules and Program Objects


The z/OS Binder can create either a load module or a program object from old OBJ-format
object modules. If the generated executable is a program object, the Binder makes a few internal
changes:
SD items: in addition to the control section name, the Binder creates an ED (Element Definition) for Class B_TEXT with the RMODE of the section, and an LD (Label Definition) at the
origin of this element with the AMODE attribute of the original control section.
CM (Common) sections are treated almost like SD items, and a Common flag is set.
TXT records for the control section are assigned to the B_TEXT element. (There are no TXT items
for Common sections.)
XD items cause the Binder to create an ED item for the B_PRV class.
In creating a program object, the Binder may note that several classes may have identical binding
and loading attributes, and combine the elements in those classes into single segments, to reduce
loading time. The segments inherit boundary alignments of member classes.

840

Assembler Language Programming for IBM z System Servers

Version 1.00

From GOFF or OBJ object modules, the Binder can create either a load module or a program
object, but a generated load module is necessarily limited to a narrower range of capabilities, as
shown in Table 408 on page 841:

Library type
Executable
module
Size limit
External
symbols
Symbol types
Additional
module data
Extensibility

Load Modules
PDS
One-dimension; single AMODE,
RMODE

Program Objects
PDSE, z/OS Unix HFS
Two-dimensions; multiple segments and A/RMODEs

16MB

1GB

8 characters

32K characters

SD, LD, ER, WX, PR


IDR only; no system support for
access
Not possible

Same, plus ED
Any data; Binder Programming
Interfaces for access
Open-ended architecture

Table 408. Comparing load modules and program objects

Exercises
38.8.1.(2) + Assemble the little program in Figure 593 on page 835 with and then without the
GOFF option, and compare their External Symbol Dictionaries. Which fields are significantly different?
38.8.2.(2) Compare the CESDs in Figure 577 on page 822 and Figure 589 on page 831 and
explain the differences.
38.8.3.(1) The older Linkage Editor supported an extended form of overlay called regions that
provided up to four distinct areas in which distinct overlays were supported. Try to find (and
study) information about overlay regions.

38.9. Loading Saved Modules into Storage


The Program Loader brings load modules and program objects into storage, and relocates all
address constants.

38.9.1. Loading Load Modules


As indicated in Figure 591 on page 833, a load module is a single unit of instructions, data, and
uninitialized space. It has a single set of attributes: AMODE, RMODE, and reenterability
(RENT) status, used by the Program Loader to load the module in the proper area of memory,
and set the addressing mode before transferring control to the modules entry point. 258
Adcon relocation is simple: the modules single load address is added to the text field at the offset
given by the (linker-adjusted) Position address in the RLD item. This relocation is fast and efficient. Its important to remember that two stages of relocation are involved:
1. When the load module is created, the Linker (or Binder) relocates addresses relative to the
zero module origin.
2. When the load module is brought into memory by the Program Loader, it relocates addresses
relative to the modules load address.

258

If the RENT option was specified during linking, the Program Loader will enable memory protection on the area
where the module is loaded, so that any attempt to store in that area will cause a memory-protection program interruption.
Chapter X: Large Programs and Modularization

841

To save having to read (and discard) the SYM, IDR, RLD, and CESD records, a copy of the first
control record is saved in the PDS directory. It is used so the Program Loader can start reading
the load module at the first text record. Each control record contains the length and the relative
address of the following text record, and RLD information for adcons in that block of text.
The first block of text is loaded starting on a boundary aligned as specified by the SECTALGN option
or by Linker and Binder control statements. If RMODE(ANY) was specified, the load module
can be placed either above or below the 16MB line.

38.9.2. Loading Program Objects


Program objects add flexibility by allowing you to arrange groups of Classes that are loaded into
more than one area of memory. With z System, available memory is divided into three areas, as
sketched in Figure 603, showing the three areas into which programs and data can be loaded.259
 2**64 bytes
RMODE(64)

:
:

 2**31 bytes (the bar)


RMODE(31)

:
:

 2**16 bytes (the line)


RMODE(24)

:
:

Figure 603. Sketch of virtual memory

The RMODE operand of the CATTR statement lets you indicate into which of these three areas you
want the class to be loaded by the Program Loader. Suppose the little program in Figure 597 on
page 837 has been revised as in Figure 604, where we have simply added an RMODE(31)
operand to the first CATTR statement for CLASS_Y:
SECT_A
CLASS_X
Msg_1
SECT_B
CLASS_X
Msg_2
SECT_A
CLASS_Y
Msg_3
SECT_B
CLASS_Y
Msg_4

CSect
STM
CATTR
DC
CSect
LM
CATTR
DC
CSect
CATTR
DC
CSect
CATTR
DC

,
14,12,12(13)
,
C A message
,
14,12,12(13)
,
C Good News
,
RMODE(31)
C Better News
,
,
C Enough!

Appears in Class B_TEXT


Appears in Class CLASS_X
Appears in Class B_TEXT
Appears in Class CLASS_X
Specify RMODE(31) for CLASS_Y 
Appears in Class CLASS_Y

Appears in Class CLASS_Y

Figure 604. Sample program defining two Sections and three Classes

259

842

At the time of this writing, only data can be loaded into the area above the bar.
Assembler Language Programming for IBM z System Servers

Version 1.00

If the GOFF object file from this assembly is linked into a program object, the Binder creates
three segments from classes having the same attributes. The segments contain the items shown in
Figure 598 on page 837, but now CLASS_Y has a different RMODE:
B_TEXT

Residence mode 24 (the default)

CLASS_X

Residence mode 24 (also the default)

CLASS_Y

Residence mode 31 (as declared)

The Binder creates a program object with these segments; when the Program Loader brings the
program into memory, the first two segments will be loaded below the line in the RMODE(24)
area, and the CLASS_Y segment will be loaded above the line, below the bar in the RMODE(31)
area.
To simplify loading, the Binder may combine segments with identical attributes into a single
loading segment. In Figure 605, the B_TEXT and CLASS_X segments may be combined, so the
loaded program could look somewhat like this:

:
:

:
:
Msg_3

Msg_4

STM

LM

Msg_1

Msg_2

:
:

 2**64 bytes

 2**31 bytes (the bar)

 Load address for CLASS_Y segment


 2**16 bytes (the line)

 Load address for B_TEXT, CLASS_X segments

 0

Figure 605. Sketch of classes in virtual memory

Loadable segments are loaded as separately relocatable discontiguous entities. Each is loaded as a
single block, similar to a load module, and inter-segment references are resolved correctly, even
across different RMODEs.
The great value of loading different parts of a program into different areas of memory is that each
segment may contain address constants referencing positions loaded into a different area! Unlike
Load Modules that are loaded into only one area (and therefore can use address constants to refer
only to positions within the loaded module), program objects can reference other areas.
In Section 38.10 we will see how to pass control among routines using different addressing modes,
and how to reference different areas of memory.

Exercises
38.9.1.(2) + Create a program with more than one control section, with references among the
sections and their entry points. When the program is loaded into memory, dump its contents
and verify that all address constants have been relocated correctly.
38.9.2.(1) + Create a loadable module on your system and use whatever tools are available to
display or dump its format prior to loading.

Chapter X: Large Programs and Modularization

843

38.10. Changing Addressing Modes


Most application programs dont need to change addressing mode. They can access Operating
System services that may change mode, but they restore your addressing mode on completion so
the process is invisible to you.
These are typical situations where you might want or need to change addressing mode:
Your application is loaded above the line and executes in 31-bit mode. It needs to call a
program loaded below the line that runs in 24-bit mode.
Your application is loaded below the line and runs in 24-bit mode, and needs to access data
that resides above the line.
First, we describe five instructions you can use to change addressing mode, and one to test the
current addressing mode. Of these instructions, BASSM and BSM are the most useful. Then
well see how to use them.
Op
0B

Mnem
BSM

010C
010E

SAM24
SAM64

Type Instruction
R R Branch and Set Mode
E
E

Op
0C

Mnem
Type Instruction
BASSM R R Branch and Save and Set
Mode
010D SAM31 E
Set Addressing Mode (31)
010B TAM
E
Test Addressing Mode

Set Addressing Mode (24)


Set Addressing Mode (64)

Table 409. Instructions to change addressing mode

SAM24, SAM31, and SAM64 simply change the addressing mode to the indicated value, and
TAM sets the Condition Code according to the current addressing mode:
AMODE
24

TAM CC
B 0 0

31

B 0 1

64

B 1 1

Table 410. CC settings for T A M instruction

As noted in 20.2. Addressing Modes on page 306, the two PSW bits that determine the
addressing mode, the extended addressing mode bit E and the basic addressing mode bit B, are
shown in Figure 606.
 128bit PSW 

EB

Instruction Address (IA)

0
31 32
63 64
127
Figure 606. z System PSW showing addressing-mode bits

The meanings of the E and B bit settings are:


E
0
0
1
1

B
0
1
0
1

Addressing mode
24-bit mode
31-bit mode
Invalid combination
64-bit mode

Table 411. PSW addressing-mode bits

Note that the CC bit settings for TAM (in Table 410) are the same as the PSW E and B bit values
(in Table 411).

844

Assembler Language Programming for IBM z System Servers

Version 1.00

The easiest way to change addressing modes is to execute one of the SAMxx instructions; this
requires keeping track of the current and the new addressing modes in case you need to change
back to the previous mode.

38.10.1. The BASSM Instruction


If your program (the caller) wants to call another program (the callee, or target program) in
another addressing mode, use the BASSM instruction:
BASSM R1,R2
The important b and e bits in the R1 and R 2 registers are shown in Figure 607:
////

b
e
////
0
32 33
63
Figure 607. Important addressing mode bits for BASSM

When BASSM is executed, the CPU first completes the contents of GR R 1 or GG R 1, as shown
in Figure 608. Thus, the R 1 register reflects the addressing mode of the calling program.
0
32
39 40
63

 unchanged 00000000 24-bit address  AM24

0
32
63

 unchanged 1 31-bit address  AM31

0
62 63

64-bit address 1 AM64

Figure 608. BASSM setting of first-operand register for 24-, 31-, and 64-bit addressing modes

If the R 2 digit is 0, the instruction is complete; no branch occurs, and the current addressing
mode is unchanged.
If the R 2 digit is not 0, the CPU examines the contents of GR R 2:
1. If the e bit is zero (as you would expect for the address of the callee), then the PSW
addressing mode is set according to the value of the b bit:
If b = 0, the E and B bits in the PSW are set to B 0 0 , for addressing mode 24.
If b = 1, the E and B bits in the PSW are set to B 0 1 , for addressing mode 31.
The contents of GR R 1 are then set to the IA in the PSW (the address of the instruction
following BASSM), using the new addressing mode:
2. If the e bit of GR R 2 is one, the addressing mode E and B bits in the PSW are set to B 1 1 ,
and the CPU will execute in 64-bit addressing mode.
The contents of GG R 2 are then set using the target address in GR R 2, using the new
addressing mode, and the low-order bit of GG R 1 is set to one. (Well see why this is done
when we describe the BSM instruction.)
To complete the instruction, the CPU takes these additional steps:
1. If the new addressing mode is 24 or 31, the branch is taken and the next instruction will
come from the address in GR R 2.

Chapter X: Large Programs and Modularization

845

2. If the new addressing mode is 64, the low-order bit of GG R 2 was set to one (so the branch
address will appear to be odd!), but the CPU ignores the low-order one bit and takes the next
instruction from the even address, without changing that low-order bit.
Instruction fetching then continues at the target address in the new addressing mode.
A summary of the operation of BASSM is shown in Table 412:
BASSM
from
24/31

from
64

G P R R1 :

to 24/31
bits 0-31 unchanged
bit 32 = B bit
bits 33-63 = PSW IA

to 64
same
same
same

PSW IA = A(GPR R2 )
PSW E bit = 0
PSW B bit = GPR R2 bit 32
Note: GPR R2 bit 63 = 0
G P R R1 bits 0-63 = PSW IA

PSW IA = A(GPR R2 )
PSW E bit = 0
PSW B bit = 1
Note: GPR R2 bit 63 = 1
same

PSW IA = A(GPR R2 )
PSW E bit = 0
PSW B bit = GPR R2 bit 32
Note: GPR R2 bit 63 = 0

PSW IA = A(GPR R2 )
PSW E bit = 1
PSW B bit = 1
Note: GPR R2 bit 63 = 1

Table 412. BASSM actions summary

38.10.2. The BSM Instruction


The BSM instruction is used to restore the addressing mode of a calling program before returning.
Its operation is summarized in Table 413; well use the notations in Table 410 on page 844 and
Figure 607 on page 845 to refer to specific PSW and register bits.
Value
0
0

R1 operand
R 1 register unchanged
In AMODE 24 or 31,
put the PSW B bit into
the b bit of GR R 1;
remainder of GR R 1 is
unchanged.
In AMODE 64, insert a
1-bit into the e bit of
G R R 1; remainder of
G R R 1 is unchanged.

R2 operand
No branch, no change to addressing mode
If the e bit of GR R 2 is zero, set the PSW E bit
to 0; the b bit of GR R 2 is put in the PSW B bit;
AMODE is now 24 or 31. The branch address
replaces the PSW IA.
If the e bit of GR R 2 is one, set the PSW EB bits
to B 1 1 ; AMODE is now 64. The branch
address in bits 0-62 of GR R 2 replaces the PSW
IA with a low-order zero bit appended.

Table 413. Operation of BSM instruction

Of these combinations, the R 1 operand is almost always zero.


A similar summary of the operation of BSM is shown in Table 414 on page 847:

846

Assembler Language Programming for IBM z System Servers

Version 1.00

BSM
from
24/31

from
64

G P R R1 :

to 24/31
bits 0-31 unchanged
bit 32 = B bit
bits 33-63 unchanged

PSW IA = A(GPR R2 )
PSW E bit = 0
PSW B bit = GPR R2 bit 32
Note: GPR R2 bit 63 = 0
G P R R1 bits 0-62 unchanged
G P R R1 bit 63 = 1
PSW IA = A(GPR R2 ) (mod 2)
PSW E bit = 0
PSW B bit = GPR R2 bit 32

to 64
same
same
same
PSW IA = A(GPR R2 ) (mod 2)
PSW E bit = 1
PSW B bit = 1
Note: GPR R2 bit 63 = 1
same
G P R R2 bit 63 = 1
PSW IA = A(GPR
PSW E bit = 1
PSW B bit = 1

R2 )

Table 414. BSM actions summary

38.10.3. Branch and Return With Addressing Mode Change


Changes of addressing mode are usually used for calls among programs loaded into different areas
of memory, that execute in different addressing modes. Such programs or memory areas may not
be accessible in the current addressing mode, or must execute in a different mode.
1. Suppose your program A executes in AMode 31 and you must call a program B that executes
in AM24 (and was therefore loaded below the 16MB line).
L
15,=V(B)
BASSM 14,15

Address of B (X00xxxxxx )
Call B

B will be entered in 24-bit mode because bit 32 of GR15 is 0 (remember that the Program
Loader sets the high-order 8 bits of a 4-byte adcon to zero if the target symbol is below
16MB). The b bit in GR14 will be set to 1 because the BASSM instruction was executed in
AMode 31. B will then return with
BSM

0,14

Return from B to A

and the addressing mode will be changed from 24- to 31-bit mode because the b bit in GR14
was 1.
2. Suppose your program C executes in AMode 24 and you must call a program D that executes
in AMode 31 (and was therefore loaded above the 16MB line).
L
15,=A(D+X80000000)
BASSM 14,15

Address of D with bit 32 = 1


Call D

D will be entered in 31-bit mode because bit 32 of GR15 is 1 because we set that bit by
adding X80000000) to its address. The b bit in GR14 will be set to 0 because the BASSM
instruction was executed in AMode 24. D will then return with
BSM

0,14

Return from D to C

and the addressing mode will be changed from 31- to 24-bit mode because the b bit in GR14
was 0.
3. Suppose your program E executes in AMode 31 and you must refer to data named F that
resides below the 16MB line.
L

15,=V(F)

Address of D with bit 32 = 1

You can now refer to the data at F because 31-bit mode lets you address anything below the
2GB bar.
4. Suppose your program G executes in AMode 24 and you must refer to data named H that
resides above the 16MB line but below the 2GB bar.
L
15,=V(H)
SAM31 ,

Address of H
Set addressing mode 31

Chapter X: Large Programs and Modularization

847

You can now refer to the data at H because 31-bit mode lets you address anything below the
2GB bar. If your program must later execute in 24-bit addressing mode, you will need to
execute a SAM24 instruction.
The following Table 415 shows combinations of instructions that may safely be used by programs
executing in the From addressing mode to call programs that execute in the To mode.

From

Call

AM24

BALR
BAS
BASR
BRAS
BRASL

AM31

AM64

BASSM

BASSM

To AM24
Return

To AM31
Return

Call

Call

To AM64
Return

BR
BSM

BASSM

BSM

BASSM

BSM

BSM

BALR
BAS
BASR
BRAS
BRASL

BR
BSM

BASSM

BSM

BSM

BAL
BALR
BAS
BASR
BRAS
BRASL

BR

BSM

BASSM

Table 415. Instruction pairs for call/return with possible A M O D E change

Note that the BAL instruction appears in the table only for branch and return in 64-bit mode.
BAL should be used only in combination with BR and never with BSM as the return instruction
when your program is executing in addressing mode 24.260 (See Exercise 38.10.7.)
Table Table 416 shows ways you can do internal subroutine calls that change addressing modes
within a single assembly.
Caller
* To 24-bit mode from any mode
LARL 15,Code24
BASSM 14,15

Subroutine Entry
* Entry to 24-bit mode
Code24 DC
0H
Must be below the line
- - BSM
0,14
Return to caller
* Entry to 31-bit mode
Code31 DC
0H
Above or below the line
- - BSM
0,14
Return to caller
* Entry to 64-bit mode
Code64 DC
0H
Anywhere in memory
- - BSM
0,14
Return to caller

* To 31-bit mode from any mode


LARL 15,Code31
OILH 15,X8000
BASSM 14,15
* To 64-bit mode from any mode
XGR
15,15
For 24 or 31 to 64
LARL 15,Code64
OILL 15,X0001
BASSM 14,15
Table 416. Calling among addressing modes within an assembly

When a program executes in 64-bit addressing mode, it can address any byte with addresses
between 231 and 264 1. However, on z/OS systems the addresses between 231 and 232 1 are not
made available; this area is sometimes called the Blackout Area, as sketched in Figure 609 on
page 849.

260

848

The official term describing BAL and BALR is that their use is deprecated. This means that if you get in trouble
using them, you cant say you werent warned.
Assembler Language Programming for IBM z System Servers

Version 1.00


RMODE(64):

Addressing requires
AMODE 64

:
:

Blackout Area

RMODE(31):

Addressable with

AMODEs 64 and 31

:
:

RMODE(24):

Addressable with

AMODEs 64, 31, 24

:
:

 2**64 bytes

 2**32 bytes
 2**31 bytes (the bar)

 2**16 bytes (the line)

Figure 609. Sketch of residence and addressing modes

This was done because many existing programs used the convention shown in Section 37.3.1 on
page 753 that set the high-order bit of a 4-byte address to 1 to indicate the last argument address
in a list. If such an address is used in 64-bit addressing mode it will (accidentally) try to refer to an
address in the Blackout Area, rather than the intended address below the 2GB bar.
To help avoid such problems we can use the LLGT and LLGTR instructions:
Op
E317

Mnem
LLGT

Type Instruction
RXY Load Logical Thirty One Bits

Op
Mnem
Type Instruction
B917 L L G T R R R E Load Logical Thirty One
Bits

Table 417. LLGT and L L G T R instructions

These two instructions load a 32-bit word into the low-order 32 bits of the GR R 1 register, set bit
32 to 0 (the bit that could potentially be 1) and set the remaining 32 high-order bits of GR R 1 to
zero. This means that the resulting address can safely be used by a program executing in 64-bit
mode to refer to addresses below the 2GB bar. For example:
LLGT 4,=X FEDCBA98

c(GG5=X00000000 7EDCBA98 )

and bit 32 of GG4 has been set to zero.


The example in Figure 610 shows why this can be important. Suppose your program runs in
AMode 31, and then changes to AMode 64.
Prog31
Prog31

Move
A
B

CSect
AMODE
BASR
USING
- - SAM64
- - MVC
- - DS
DC

,
31
12,0
*,12

Execute in AMode 31
Establish base register
Establish addressability

Change to AMode 64

A,B

Move some data

CL10
C A Message!

Target field
Source field

Figure 610. Example showing why L L G T / L L G T R are necessary

Chapter X: Large Programs and Modularization

849

The MVC instruction named Move may cause a protection exception for either of two reasons.
The BASR instruction, because it is executed in AMode 31, sets bit 32 of GG12 (the b bit) to 1.
When the Effective Addresses of the MVC operands A and B are generated, the presence of the
1-bit means that
if bits 0-31 of GG12 are zero, the Effective Address of A lies in the Blackout Area;
otherwise, if bits 0-31 of GG12 are not zero, the Effective Address of A lies somewhere above
232, in an area very probably not accessible to your program.
To avoid both forms of this problem, insert a LLGTR instruction:

Move

- - SAM64 ,
LLGTR 12,12
MVC A,B
- - -

Change to AMode 64
Force bits 0-32 of GG12 to zero
Move some data

This example shows why LLGTR can be important: if you call a program executing in 64-bit
mode from another program located below the bar, you must be sure that its safe to refer to
the callers save area:
Code64
Code64

CSect
AMode
Using
STMH
LLGTR
STM
- - Return LMD
BSM
HighRegs DS

,
64
*,15
14,12,HighRegs+12
13,13
14,12,12(13)

64-bit addressing mode


Local base register
Save high halves of registers locally
Clean address or caller s area in GG13
Save low halves of registers safely

14,12,HighRegs+12,12(13) Restore both halves of registers


0,14
Return to caller
18F
Save area for high halves of registers

Without the LLGTR instruction, any nonzero bits in positions 0-33 of GG13 could cause a protection exception.

Exercises
38.10.1.(1) + When a program is loaded into memory, what is the maximum allowed difference
between the addresses of BRAS and BRASL instructions and their targets?
38.10.2.(1) Show which PSW addressing mode bits (Figure 606 on page 844 may help) are set
to what values by each of the SAMxx instructions in Table 409 on page 844.
38.10.3.(1) + Show how the CC settings in Table 410 on page 844 correspond the the settings
of the E and B addressing-mode bits in the PSW, as illustrated in Figure 606 on page 844.
38.10.4.(2) + Describe the differences among BALR r,0 and BASR r,0 and BASSM r,0.
38.10.5.(1) + The z/Architecture Principles of Operation states that if the current addressing
mode is 24 or 31, the BSM instruction can be used to return from a program that was entered
using a BAS, BASR, BRAS, and BRASL instruction. Explain why this is so.
38.10.6.(1) Can BASSM 0,0 or BSM 0,0 be used as a no-operation instruction, like NOPR 0?
38.10.7.(2) + The paragraph after Table 415 on page 848 states that BAL should never be used
with BSM as its return instruction when your program executes in AMODE 24. Why? Why is
AMODE 31 not included in this warning?
38.10.8.(2) In Table 415 on page 848, why not use BASSM and BSM for a branch and return
within the same addressing mode?

850

Assembler Language Programming for IBM z System Servers

Version 1.00

38.11. Summary
This chapter has covered a wide variety of topics. Key suggestions include:
1. Put all constants that cant be replaced by immediate operands in one LOCTR group. It will
probably need addressability.
2. Put all read/write data areas in one LOCTR group. It will probably need addressability.
3. Arrange for all instructions to be in one LOCTR group. Use relative branch, immediate, and
long-displacement instructions wherever possible. Ideally, this LOCTR group will not need
addressability.
4. Avoid using BAL/BALR except in applications with no changes of addressing mode.

Instructions Discussed in this Section


The instruction mnemonics and opcodes are shown in the following table:
Mnemonic
BASSM

Opcode
0C

Mnemonic
LLGTR

Opcode
B917

Mnemonic
SAM64

Opcode
010E

BSM

0B

SAM24

010C

TAM

010B

LLGT

E317

SAM31

010D

The instruction opcodes and mnemonics are shown in the following table:
Opcode
010B

Mnemonic
TAM

Opcode
010E

Mnemonic
SAM64

Opcode
B917

Mnemonic
LLGTR

010C

SAM24

0B

BSM

E317

LLGT

010D

SAM31

0C

BASSM

Terms and Definitions


address constant (adcon)
A field within a control section into which a value (typically, an address) is placed during
program binding, relocation, and/or loading.
Class
A cross-section of Program Object data with uniform format, content, function, and behavioral attributes.
Common
A CSECT having length and alignment attributes (but no text) for which space is reserved in
the Program Object.
External Symbol Dictionary
The set of external symbols created by an assembly. They are displayed in the Assemblers
listing and are encoded in the ESD records of the generated object module.
Relocation Dictionary
A summary of each relocatable address constant in an assembly, displayed in the Assemblers
listing and encoded in the RLD records of the generated object module.

Chapter X: Large Programs and Modularization

851

program linking
Resolve external names into offsets or addresses; combine multiple input name spaces into
composite output name space.
text
The instructions and data generated by an assembly, encoded in the TXT records of an
object module.
linking loader
Places modules into storage with linking, immediately prior to program execution.
object module
Records containing the external symbols, machine language text, and relocation dictionary
information required for program linking, in either the older 80-byte card image OBJ
format or in the newer GOFF format.
load module (LM)
The original form of MVS executable, stored in a Partitioned Data Set (PDS) program
library in record format.
program object (PO)
A newer form of executable on z/OS, stored in a PDSE (Partitioned Data Set Extended)
program library.
PseudoRegister (PR), External Dummy (XD)
A PseudoRegister or external data item having length and alignment attributes. Space in the
loaded module is reserved for Common control sections; space for external dummy sections
must be obtained at execution time.
executable control section
A control section containing machine language instructions or data, defined by CSECT,
RSECT, or START instructions.
reference control section
A control section containing no machine language instructions or data, defined by DSECT,
COM, or DXD instructions.
relocate
Assign actual-storage or module-origin-relative addresses to address constants.
relocating loader
Places modules into storage and adjusts addresses to their correct final value.
relocation
The load-time conversion of address constants from module or class displacements to virtual
addresses. The assignment of actual or module-origin-relative addresses to address constants.
section
(1) A generic term for control section, dummy section, common section, etc.. A collection of
items that must be bound or relocated as an indivisible unit.
(2) A collection of elements belonging to specified Classes in a program object. Elements
defined by a section are added or deleted as a group. Not the name of a control section.
Class
A component of a program object with specified loading properties, containing elements supplied by sections. Loadable classes are independently relocatable. Indicated in the External
Symbol Directory listing with type ED.
element
A component of a program object Class, defined by the combination of its section name and
its Class name. The smallest indivisible and separately relocatable portion of a program
object.
segment
A component of a program object containing classes with the same properties such as
RMODE and loadability.
text
The portions of an object module containing machine language instructions and data.

852

Assembler Language Programming for IBM z System Servers

Version 1.00

A-type address constant


A field containing an absolute, relocatable, or complex relocatable expression. Absolute
expressions are resolved by the Assembler, the others during linking and loading.
V-type address constant
A field containing the address of an external symbol, resolved during linking and loading.
Q-type address constant
A field containing the offset (not the address) of a Dummy External Symbol (or
PseudoRegister) from the start of a virtual area mapped at link time and allocated at execution time.
CXD-type address constant
A word holding the length (not the address) of the virtual area created at link time from all
the Dummy External Sections (or PseudoRegisters) in the complete program.
AMODE
Addressing mode, one of 24, 31, or 64.
RMODE
Residence mode, an indication of the desired placement in memory of a Control Section or
class.

Programming Problems
Problem 38.1.(2) Use the external subroutines you wrote in solving Exercises 38.5.15 and
38.5.16 to create a complete program calling the subroutines. Verify your results by converting
word integers to hexadecimal floating-point and then back to word integers; display the original
and final integer values and the hexadecimal floating-point intermediate value. Be sure to test
values such as
DC
DC
DC

F -0
F2147483647
F -2147483648

Problem 38.2.(4) + Days of the week can be calculated using Zellers Congruence:261
D_W = (D_M + ((M+1)*13)/5) + Y + Y/4 + 6*(Y/100) + Y/400) (mod 7)
where D_M is the day of the month, M is the month, and Y is the year. D_W is the day of
the week, starting with 0=Saturday through 7=Friday. All divisions (except the one calculating the day of the week (mod 7)) discard remainders.
Write a separately assembled subroutine Zeller to accept three integer arguments Y, M, and
D_M and return D_W in GR0. Then, write a calling program that reads records with the three
argument values right-justified in columns 1-10, 11-20, and 21-30. For example, some input
records might be
2009
2000
1900

6
1
1

30
1
1

Create several test cases that display the day of the week, the month, day of the month, and the
year. Even better, provide the names of the day and month.
Problem 38.3.(2) + Using the definitions of ulp(x) in Section 32.8 on page 567, and with the
assumptions in Exercises 33.19.3, 33.19.5, and 33.19.7, write three callable subroutines using
standard calling conventions that are all in a single control section named HexUlp. Your
CSECT should have three entry points: HxUlpE, HxUlpD, HxUlpL, having a short, long, and
extended precision hexadecimal floating-point argument respectively.
Each entry should calculate the ulp of its argument and return the result in floating-point register 0 (for HxUlpE and HxUlpD) and in floating-point registers 0 and 2 for HxUlpL.

261

Due to Christian Zeller, in 1882-85. The formula is valid only for the Gregorian calendar.
Chapter X: Large Programs and Modularization

853

Your routines should preserve the contents of general registers 2-15 and floating-point registers
8-15 if they are modified in any way. Assume that the values of the arguments are large
enough that no exponent underflows will occur in calculating each ulp.
Problem 38.4.(3) As you did in Problem 38.3, write a program in a CSECT named BinUlp with
three similar entry points that will evaluate an ulp of a short, long, and extended precision
binary floating-point argument.
Problem 38.5.(2) Write a callable routine named ConvI with two arguments: a 32-bit binary
integer, and a 12-byte character string. Convert the binary integer to characters, right-adjusted
in the string, and preceded by a minus sign if the integer is negative. Insignificant leading zeros
should be omitted, and at least one digit must be produced. Be sure to test values like
DC
DC
DC
DC

F 0
F -1
F2147483647
F -2147483648

Problem 38.6.(2) Write a callable routine named ConvZ with two arguments: a 32-bit word and
an 8-byte character string. Convert the word to 8 EBCDIC characters representing the
hexadecimal representation of the word.
Problem 38.7.(4) + Write a program to display the contents of an 80-byte OBJ object module
in hexadecimal.
Problem 38.8.(2) + Write at least two separately-assembled routines referring to DXD items,
some of which have identical names. Include Q-type address constants of lengths 2 to 4 referring to each item, and at least one CXD-type item. Link the routines together and execute the
linked program.
Examine (and print) the contents of all the Q-cons and CXD constants to understand how the
Linker allocated the entries in the External Dummy Section.
Problem 38.9.(1) Write a short program to illustrate the settings of the R1 register when you
execute BASSM and BASR instructions with R 2 = 0, in each of the three addressing modes.
(Be careful if you use the PRINTOUT macro to print the results, because it executes only in
AMODE 24.)
Problem 38.10.(2) Write and test a subroutine named HexExp that will evaluate and return in
GR0 the exponent of a hexadecimal floating-point argument passed using standard linkage conventions. (You need not restore the contents of GR1.)

854

Assembler Language Programming for IBM z System Servers

Version 1.00

Chapter XI: Dummy Sections, Enhanced USINGs, and Data


Structures

XX
XX
XX
XX
XX
XX
XX
XX
XX XX
XXXX
XXXX
XX XX
XX
XX
XX
XX
XX
XX
XX
XX

IIIIIIIIII
IIIIIIIIII
II
II
II
II
II
II
II
II
IIIIIIIIII
IIIIIIIIII

This chapter describes some basic techniques for arranging and describing data items in memory,
including arrays, stacks, linked lists, and hash tables.
Section 39 introduces the Dummy Control Section (DSECT) for mapping data objects, and
then reviews the ordinary USING statement before introducing the enhanced Labeled USING,
Dependent USING, and Labeled Dependent USING assembler instruction statements.
Section 40 describes some basic techniques for arranging data items in memory, including
arrays, stacks, linked lists, and hash tables.

Chapter XI: Dummy Sections, Enhanced USINGs, and Data Structures

855

39. Dummy Control Sections and Enhanced USING Statements

3333333333
333333333333
33
33
33
33
3333
3333
33
33
33
33
333333333333
3333333333

9999999999
999999999999
99
99
99
99
99
99
999999999999
999999999999
99
99
99
99
999999999999
9999999999

This section describes two powerful programming aids: Dummy Control Sections and enhanced
USING statements.
Dummy Control Sections are powerful tools for symbolic description of any area of memory.
They are especially valuable when programs work with shared or multiple instances of data structures such as records.
Any addressing method should provide as many of the following benefits as possible:
1. Coding should be simple, clear, understandable, and efficient. These help with simplicity,
readability, and maintainability.
2. All instructions should use fully symbolic references. These help with readability and maintainability.
3. Base registers and displacements should always be automatically assigned by the assembler
from information provided in USING statements, and never as constants or by manual calculations. These also help with quality, readability, and maintainability.
Ordinary USINGs can easily fail in one or more of these respects, as some of the following illustrations will show; we will see how the new USING statements can avoid most of them.

39.1. Dummy Control Sections


In Sections 6.4 and 6.5 we mentioned that the START and CSECT assembler instruction statements initiate a control section containing instructions and data.262 A Dummy Control Section (or
DSECT) is a control section like a control section initiated by CSECT or START, with these
similarities and differences:
A DSECT never generates any machine language object code, even if it contains instructions
and constants.

262

856

The Assembler defines two types of control section: (a) an executable control section containing machine-language
instructions and data (even though it might contain only data and no executable instructions, or even nothing at all!),
and (b) a reference control section, most often a DSECT. (A reference control section can also be a COM section
or an external dummy section, described in Section 38.4.)
Assembler Language Programming for IBM z System Servers

Version 1.00

A DSECT has its own relocation attribute (RA). Because it generates nothing that will appear
in the object module, its RA starts at (unsigned) X FFFFFFFF and counts down for each new
DSECT. (You may remember from Section 38 that external symbols have relocation attributes
defined by their ESDIDs, which count up from 1.)
The Location Counter (LC) for a DSECT always starts at zero. Normal alignment rules
apply to each statement in a DSECT.
A DSECT is a template or mapping of an area of memory, and is used to make symbolic references.263 To illustrate, suppose we declare a DSECT named DummyS:
DummyS
A
B
C
D

DSect
DS
DS
DS
DS

,
F
H
CL25
D

Declare dummy control section DummyS


Fullword named A
Halfword named B
25-byte character string named C
Doubleword named D

Figure 611. Example of a dummy control section

The symbol table entries for the four symbols might look like this:
Symbol
A
B
C
D

Location
X000000
X000004
X000006
X000020

RA
X FF
X FF
X FF
X FF

Table 418. Symbol table entries for DSECT symbols

The Relocation Attribute of each symbol in the DSECT is the same as the RA of its owning
control section.
Now, suppose we can address a work area named WorkA. We can use symbols to refer to fields in
the work area, as in Figure 612:
Sample

WorkA

Start
BASR
Using
- - LA
Using
L
AH
CLC
JE
LM
- - DS

0
12,0
*,12

Establish a base register


Provide addressability

7,WorkA
DummyS,7
3,A
3,B
C,0(12)
ElseWhere
0,1,D

c(GR7) = Address of WorkA


Provide symbolic mapping of WorkA
Load a fullword from WorkA
Add a halfword from WorkA
Compare 25 bytes of WorkA
Do something about the comparison
Load two words from doubleword

0D,XL84

Work area

Figure 612. Example using a dummy control section

The instructions referencing symbols defined in the DSECT are generated using the normal resolution rules for implied addresses. With the same notation as in Sections 10.8-10.10, the USING
Table would look like Figure 613:

263

You can think of a DSECT as though its a transparent overlay that lets you make symbolic references to fields
anywhere in memory. (This description is attributed to Jim Morrison.)
Chapter XI: Dummy Sections, Enhanced USINGs, and Data Structures

857


basereg base location RA

12
00000002 01

7
00000000 FF  Relocation ID for the DSECT

Figure 613. USING Table with two entries, one for a dummy section

References to the symbols defined in the DSECT can be resolved only with base register GR7,
because the RA of the implied addresses in Figure 612 must match the RA of a base address in
the USING Table. The generated instructions are shown in Figure 614:
Loc
....
....
....
....
....

Object Code
5830 7000
4A30 7004
D518 7006 C000
A784 ....
9801 7020

Statement
L
3,A
AH
3,B
CLC C,0(12)
JE
ElseWhere
LM
0,1,D

Figure 614. Object code from references to a dummy control section

The symbol C is at location X000006 in the DSECT; the second USING statement tells the
Assembler that the base address is location X000000, so the addressing halfword is X7006.
Now, suppose we refer to a different work area, so that the address in GR7 is different:

WorkA

- - LA
Using
L
AH
CLC
JE
LM
- - DS

7,WorkA+43
DummyS,7
3,A
3,B
C,0(12)
ElseWhere
0,1,D

c(GR7) = A(WorkA)
Provide symbolic mapping of WorkA
Load a fullword from WorkA
Add a halfword from WorkA
Compare 25 bytes of WorkA
Do something about the comparison
Load two words from doubleword

XL84

Work area

Figure 615. Example using a dummy control section

The generated object code is identical to that in Figure 614, because exactly the same base
expression and register are declared in the USING statement. In resolving the implied addresses,
the Assembler doesnt know that the address in GR7 may not be aligned on proper boundaries; it
only knows about alignments within the DSECT.
The examples in Figures 612 and 615 show how the DSECT template can be overlaid on any
area of storage to provide symbolic references (the symbols A, B, C, and D to fields in the storage
area.
Because a DSECT generates no machine language object code, we could have defined the
DSECT in Figure 611 with DC (rather than DS) statements, with exactly the same results:
DummyS
A
B
C
D

DSect
DC
DC
DC
DC

,
F 0
H -45
CL25 String
D -1.732

Declare dummy control section DummyS


Fullword named A
Halfword named B
25-byte character string named C
Doubleword named D

The Length Attribute of a symbol naming a DSECT is 1, and not the total length of the DSECT
itself.

858

Assembler Language Programming for IBM z System Servers

Version 1.00

Exercises
39.1.1.(1) In this DSECT, show the values of each symbol.
D39_1_1
A
B
C
D
E
F

DSect
DS
DS
DS
DS
DS
Equ

,
CL9
F
X
H
D
*-D39_1_1

39.1.2.(1) + Figure 57 on page 163 shows statements describing a typical Assembler Language
statement. Create a DSECT named ALStmt with those statements.
39.1.3.(2) + In the DSECT you wrote in Exercise 39.1.2, what are the values and length attributes of all symbols?

39.2. Multiple Data Structures


You will often find that your program must work with more than one copy of an identical data
structure. For example, suppose your program must read a data record from an old master file
and update it in two ways:
Copy the Old record to a New copy.
Put the current processing date in the Old record and write it to an archive file for backup
(and auditing) purposes.
Make updates to the New record and write it to a master file.
In outline form, the main steps of your program might look like this:
BAS
BAS
BAS
BAS
BAS
BAS

14,Read_Old_Master
14,Copy_Record
14,Do_Old_Date
14,Write_Archive_Record
14,Update_New_Record
14,Write_New_Master

Read a record for processing


Copy the old record to new area
Put date stamp in old record
Write old record to archive
Make updates to new record
Write new record to master file

When you work with more than one copy of a data structure, your programs are simpler when
the structures are described by a DSECT. Thus, each subroutine needs to know the structure and
length of the record. Suppose the two record descriptions had been written as two separate groups
of statements:
New Record Description
Old Record Description

NewRec DS
0D
OldRec DS
0D
NewType DS
CL10 Record type
OldType DS
CL10
NewID
DS
CL4
Record ID
OldID
DS
CL4
NewName DS
CL40 Name
OldName DS
CL40
NewAddr DS
CL66 Address
OldAddr DS
CL66
NewPhone DS
CL12 Phone number
NewPhone DS
CL12

etc.



etc.


NewYear DS
F
Processing year
OldYear DS
F
NewDay DS
F
Day of year
OldDay DS
F

etc.


Figure 616. A poor method for describing two instances of a record
Chapter XI: Dummy Sections, Enhanced USINGs, and Data Structures

859

and so forth for many fields. Any error in keeping the New and Old descriptions exactly the same
could lead to serious errors if fields appeared at different offsets.
It is much better to describe the record with a DSECT:
Record
RecType
RecID
RecName
RecAddr
RecPhone

DSect
DS
DS
DS
DS
DS
- - - - RecYear DS
RecDay DS
- - RecLen Equ

,
CL10
CL4
CL40
CL66
CL12

F
F
*-Record

Record description
Record type
Record ID
Name
Address
Phone number
etc.
etc.
Processing year
Processing day of year
etc.
Record length

Figure 617. A better record description with a DSECT

and then use the DSECT in each subroutine to process the data. (Section 39.4 describes Labeled
USINGs, which make it even easier to handle multiple instances of a data structure.)
Advice
If your program references more than a single copy of a record or structure, or if a record or structure is shared by more than one program, all
references should (must!) use the same DSect mapping. Its best to write
only a single description of any data structure.
Your program can contain a mixture of both regular control sections and dummy control
sections. Standard programming practice usually groups all DSECT definitions either at the very
start or the very end of your program.

Exercises
39.2.1.(2) + Suppose you want to refer to the Record structure in Figure 617 as a string of
RecLen bytes. Define a symbol RecBase at offset zero in the DSECT having Length Attribute
RecLen.
39.2.2.(1) + Define a storage area named NewRec described by the Record DSECT in Figure 617
to start on a doubleword boundary, and have the correct length.

39.3. Shortcomings of Ordinary USING Statements


By ordinary USING we mean the USING statement weve seen many times previously, written
as in Figure 618:
USING base_location,register(s)

Ordinary USING statement

Figure 618. Ordinary USING statement syntax

The other three forms of USING statement well discuss are variations on this basic syntax.
We will use the DSECT describing a typical data record shown in Figure 617 to illustrate several
methods for copying the RecID field from the old record to the new. Each method has shortcomings; well see in Section 39.4 that these are easily overcome with Labeled USING statements.

860

Assembler Language Programming for IBM z System Servers

Version 1.00

Suppose our program refers to the new and old and instances of the Record DSECT, and that we
must move the RecID field from the Old instance of the record to the New instance, as sketched in
Figure 619:
* New record
Record DSect
RecType DS
- - RecID DS
CL4
- - - etc. - - -

 copy

* Old record
Record DSect
RecType DS
- - RecID DS
CL4
- - - etc. - - -

Figure 619. Copying a field from Old record to New

First, we will see examples of five ways we might move the data, specifying only ordinary USING
statements:
Example 1: Incorrect addressing with ordinary USINGs.
Example 2: Ordinary USINGs, with manually-specified displacements.
Example 3: Unusual ordinary USINGs, with manually-specified displacements.
Example 4: Ordinary USINGs and an intermediate temporary variable.
Example 5: Duplicated (but differently-named) copies of the DSECT.
For each example, we will assume that
GR5 and GR7 contain the addresses of the New and Old record instances respectively, and
a single MVC instruction is the desired efficient solution.

39.3.1. Ordinary USINGs


We will illustrate several approaches to managing the two copies of the Record DSECT with ordinary USING statements. Some of them are clearly incorrect; they are included to show how
(apparently) obvious and simple solutions can lead to unexpected pitfalls.
Example 1 Obviously Incorrect Usage: Suppose we wrote either of the two following

sequences of statements:
Using Record,5
Using Record,7
MVC RecID,RecID

or

Using Record,7
Using Record,5
MVC RecID,RecID

We want the Assembler to generate the machine language instruction X D203 500A 700A .
Both sequences fail because only GR7 will be used to address the fields of the Record DSECT.
(If two registers are based on the same location, the assembler chooses the higher-numbered register for base-displacement resolutions.) Thus, the generated machine language instruction is
X D203 700A 700A , and the MVC instructions will move the RecID of the Old record onto itself,
producing no result whatever!264
The defects of this first technique are:
incorrect code.
Example 2 Correct (But Poor) Usage with Manually-Specified Displacements and
Registers: Suppose now that we now rewrite these simple statements to avoid the previous

problems, by specifying the displacement and base to be used:


Using Record,5
MVC RecID,RecID-Record(7)

264

Map New instance of Record


Move from Old to New

The Assembler can provide a diagnostic message warning about the fact that GR5 has been nullified as a base
register to alert you to this situation.
Chapter XI: Dummy Sections, Enhanced USINGs, and Data Structures

861

This sequence has the disadvantage that the displacement and base register are assigned by the
programmer, rather than by the assembler. If there is ever a need to reassign base registers (so
that GR7 is given a different use), all references to GR7 must be located and inspected to see if
they need changing.
In summary, the defects of this technique are
more complex coding;
more difficult maintenance.
Having seen that you can explicitly assign the base and displacement this way, you might be
tempted to use the same technique for the first operand of the MVC instruction:
Using Record,7
MVC RecID-Record(5),RecID

Map Old instance of Record


Move from Old to New

Figure 620. Incorrect addressing with ordinary USING

While this is syntactically correct it will undoubtedly be wrong. The syntax rules of the Assembler Language state that if the first operand of an SS-type instruction is written in the form
expr1(expr2), then expr1 provides the implied address and expr2 provides the operands explicit
Length Expression.
The more serious flaw is that because expr1 is absolute, the first operand will be resolved with
base register zero, and therefore refer to the low-addressed end of storage, and may cause an interruption during program execution! 265 (See Exercise 39.3.2.)
Consider how much more difficult this problem would have been to find if you had used a
common register notation:
USING Record,R7
Map Old Record with GR7
MVC RecID-Record(R5),RecID Move Old to New (based on GR5)
The symbol R5 in the MVC statement could lead many readers to believe that it was a correct
register reference, while in fact it is the Length Expression! It will be a rare coincidence if the
implied length of the RecID field is the same as the value of the symbol R5, so this might be
correct by chance (but almost always incorrect) despite the lack of any diagnostics.
The correct form requires a comma in the first operand to indicate that its implied length should
be used:
USING Record,7
Map Old instance of Record
MVC RecID-Record(,5),RecID Move from Old to New
Figure 621. Correct but awkward addressing with ordinary USING

This requires remembering an obscure Assembler Language rule that may not be obvious to
everyone. (See Exercise 39.3.3.)
Another potential trap in manually assigning registers is that USINGs may be in effect for both
the Old and New register numbers, in such a way that a statement may assemble correctly but its
operand(s) may be resolved with respect to the wrong register.
Example 2a A Digression about Devious Programming: To avoid these syntactic difficulties,

a clever programmer might observe that a manually-calculated displacement can be resolved


without having to specify a base register explicitly by specifying a zero base address and the
desired register:
USING Record,5
USING 0,7
MVC RecID,RecID-Record

265

862

Map new instance of Record


Map old instance of Record (??)
Move from Old to New

The Assembler will try to diagnose such low-storage references if you specify the FLAG(PAGE0) option.
Assembler Language Programming for IBM z System Servers

Version 1.00

and the MVC instruction will now resolve correctly.266


However, if you forget to DROP register 0, later statements that depend on absolute expressions
resolving with register 0 may not give the correct object code:
- - LA
1,100

More statements (forgetting to drop R7)


Resolved by GR7! (X41107064 )

Clever programming has its limits.267


Example 3 Problems with Manual Assignment: Suppose the data structure mapped by the

Record DSECT grows to be larger than 4096 bytes. You would establish two base registers to
map each of the two instances:

LAY
USING
LAY
USING

6,4096(0,5)
Record,5,6
8,4096(0,7)
Record,7,8

Increment GR5 by 4096 into GR6 ...


Map New instance of Record
Increment GR7 by 4096 into GR8 ...
Implicit map of Old instance of A

Then, if you write


MVC

RecID,RecID-Record(7)

Is (RecID-Record) now > 4095?

The correctness of the second operand depends on whether the manually-assigned displacement
RecID Record is less than 4095. If not, the displacement will be too large, and the manuallyassigned register (7) will be incorrect. Thus, you might have to write something like this:
MVC

RecID,RecID-Record-4096(8)

If (RecID-Record) > 4095

Figure 622. Manual coding of base and displacement for a large DSECT

This is obviously error-prone, since it depends on the current size of the Record DSECT and the
known offset of the RecID field; both could change as the program evolves.
In summary, the defects of the techniques in Examples 2 and 3 are

greater likelihood of undetected error;


deeper understanding required of language details;
more complex coding;
more difficult maintenance.

Example 4 Correct (But Still Poor) Usage with an Intermediate Temporary: Correct references to the specific instances of the Record DSECT can be obtained (apparently) by using an
intermediate temporary storage area:

USING
MVC
USING
MVC

Record,7
Temp(L RecID),RecId
Record,5
RecId,Temp

Map Old instance of Record


Move from Old to Temp
Map New instance of Record
Move from Temp to New

Unfortunately, this version fails because if two registers are based at the same location, the highernumbered register will be used for calculating displacements. Thus, the second MVC instruction
will move the data from Temp back to where it started in the Old record!

266
267

The Assembler will tell you that your USING with absolute base address zero overlaps with its implicit USING 0,0.
To avoid the danger of improper resolutions using base register zero, a very clever programmer observed that setting
a large absolute offset in the USING statement and in the manually calculated displacement avoids contaminating
later resolutions intended for GR0:
USING Record,5
Map New instance of Record
USING 0+X F999 , 7
Map Old instance of A (differently)
MVC
RecID,RecID-Record+X F999
Move from Old to New
The code is correct, but at the cost of complexity and obscure coding unlikely to be understood by later maintainers.
Chapter XI: Dummy Sections, Enhanced USINGs, and Data Structures

863

The solution for ordinary USINGs is to insert a DROP statement for GR7:
USING
MVC
Drop
USING
MVC

Record,7
Temp(L RecID),RecId
7
Record,5
RecId,Temp

Map Old instance of Record


Move from Old to Temp
Delete mapping of Old instance
Map New instance of Record
Move from Temp to New

In summary, the defects of these two techniques are

greater likelihood of undetected error;


deeper understanding required of language details;
more complex coding;
less efficient instruction sequences;
more difficult maintenance.

Example 5 Correct (But Not Recommended) Usage with Duplicated DSECTs: A pro-

grammer observing the defects of the above methods of managing two instances of the Record
DSECT might decide that the best solution is to make a second copy with a different name, to
avoid having to write confusing USING and DROP statements. Thus, he might define an exact
copy of Record now named Record2:
Record2
RecType2
RecID2
RecName2
RecAddr2

DSect
DS
DS
DS
DS
- - RecLen2 Equ

,
CL10
CL4
CL40
CL66
*-Record2

Record description
Record type
Record ID
Name
Address
etc.
Record length

Then, the desired instruction sequence is much cleaner and simpler:


USING Record2,7
USING Record,5
MVC RecID,RecID2

Map Old instance of Record (Record2)


Map new instance of Record
Move from Old to New

While it gives the desired sequence, this technique can lead to difficulties in maintenance if the
maintainer doesnt appreciate that Record2 must be an exact duplicate of Record. If changes are
made to the Record DSECT, the differences in DSECT and symbol naming make it easy to overlook the need to make equivalent and identical changes to Record2.
It is also less obvious that the symbols in this code fragment actually refer to the same objects.
In summary, the defects of this technique are
greater likelihood of maintenance problems;
greater difficulty in understanding the code.
Example 5a Another (But Still Not Recommended) Way with Macro-Duplicated DSECTs:

Occasionally, this duplicate definition technique is encapsulated in a macro definition. If


someone writes a macro named DDSECT to define copies of the Record DSECT, the macro can
generate as many copies of the DSECT as needed, adding a specified prefix to each of the generated symbols, as illustrated in the following (where the + sign is the Assemblers indication that
the statement was generated by a macro-instruction):

864

Assembler Language Programming for IBM z System Servers

Version 1.00

DDSECT Prefix=Old
DSECT
DS
- - DS
CL4
- - DDSECT Prefix=New
+NewRec DSECT
+NewType DS
- - +NewID DS
CL4
+
- - USING NewRec,5
USING OldRec,7
MVC NewID,OldID

Record DSECT, symbols prefixed Old

+OldRec
+OldType
+OldID
+

Record DSECT, symbols prefixed New

Move RecID from OldRec to NewRec

This technique (the most satisfactory of the approaches discussed so far) ensures that only a single
source file containing the DSECTs definition is maintained (inside the macro). The defects of
this approach are:
it introduces new symbols and DSECTs into the program, many of which are alternate names
for what is really one object;
it requires that an additional and complex piece of code (the macro definition) be defined and
maintained;
all references to the fields in the DSECT must use prefixed names, even when only a single
instance of the object is active (unless a third set of names is generated, with no (or a default)
prefix!).
These examples illustrate one of several problems with Ordinary USING statements:
1. You cannot make simultaneous symbolic references to a symbol belonging to multiple of
instances of a given control section (usually, a DSECT).
2. Ordinary USING statements offer only meager solutions to basic problems of symbolic reference to symbols in multiple instances of a data structure.
We will see other shortcomings that are removed by enhanced USING statements.

Exercises
39.3.1.(1) + In Figure 622, explain the presence of -4096 and GR8 in the second operand of the
MVC instruction.
39.3.2.(2) + In Figure 620, these statements are said to be a poor programming practice:
Using Record,7
MVC RecID-Record(5),RecID

Map Old instance of Record


Move from Old to New

Assuming that RecID-Record=X00A , what object code is generated by the MVC instruction?
Why is it wrong?
39.3.3.(2) + In Figure 621, the final instruction in Example 2 was written
USING Record,7
Map Old instance of Record
MVC RecID-Record(,5),RecID Move from Old to New
Again assuming that RecID-Record=X00A , what object code is generated by the MVC instruction? Why is it correct?
39.3.4. In Example 2a on page 863 (and in the footnote at the end of the example), what would
happen if the LA 1,100 instruction had been written instead as
LAY

1,100000

Chapter XI: Dummy Sections, Enhanced USINGs, and Data Structures

865

39.4. Labeled USING Statements and Qualified Symbols


We want to use fully symbolic references to the fields of the records in Figure 617 on page 860,
and not have to use explicit addressing for one of the operands. This capability is provided by
Labeled USING statements, which let you symbolically reference more than one instance of a
given DSECT at the same time.
Unlike ordinary USING statements, Labeled USING statements have a name field entry. The
name field entry of a Labeled USING is called a qualifier, as illustrated in Figure 623.
qualifier USING base_location,register(s)
USING base_location,register(s)

Labeled USING statement


Ordinary USING statement

Figure 623. Labeled USING statement syntax

A key concept in using Labeled USING statements is the qualifier or qualifying label. A qualifier
follows the rules for proper forms of ordinary symbols. A symbol is defined to be a qualifier only
by its appearance in the name field of a USING statement, and it may not be used as an ordinary
symbol. The presence of this name field symbol distinguishes Labeled USINGs from other
USING statements.

39.4.1. Qualified Symbols


A qualified symbol is a pair of symbols separated by a period: the first symbol is the qualifier and
the second is the ordinary symbol. The syntax for qualified symbols is shown in Figure 624.
qualified_symbol = qualifier.ordinary_symbol
Figure 624. Qualified symbol syntax

Some examples of qualified symbols are:


A.B
Left.Data
Record.Field4
In these examples, the qualifiers are A, Left, and Record; the ordinary symbols are B, Data, and
Field4.
Only symbols may be qualified. Other terms may not be qualified.
We can write USING statements defining these qualifiers as in Figure 625:
A
Using Z,5
Left
Using Block,9
Record Using Mapping,3

Qualifier A
Qualifier Left
Qualifier Record1

Figure 625. Examples of qualifier definitions

If a qualifying symbol is not present, the USING statement is interpreted by the Assembler as an
ordinary USING. Because qualifiers are kept in the same symbol table as ordinary symbols, they
must be distinct from other symbols. Thus, a qualified symbol like X.X is invalid.
The resolution rule for Labeled USINGs and qualified symbols is simple: if a symbol is qualified,
it may be resolved only with respect to the base register(s) specified in the Labeled USING statement with the qualifier label.
Symbol qualification is no guarantee of addressability! Address resolution still requires that displacements not exceed 4095 (for unsigned 12-bit displacements) or 500K (for signed 20-bit displacements), and that the relocation attributes of the addressing expression and the base location
in the USING statement must match.

866

Assembler Language Programming for IBM z System Servers

Version 1.00

Remember!
Base-displacement resolution of qualified symbol operands is restricted to
symbolic operands whose qualifier matches the qualifier defined on a
valid Labeled USING statement.
Labeled USINGs provide a clean and simple solution to our problem of copying the RecID field
from the Old record to the New. Suppose the Record DSECT has been defined as in Figure 617
on page 860. By specifying two Labeled USING statements and by writing qualified symbols, the
resulting code is much simpler and easier to understand. Again supposing that GR7 and GR5
contain respectively the addresses of the old and new instances of the record, we can write:
Old 1 USING Record,7
New 2 USING Record,5
MVC
New.RecID,Old.RecID
4
3

Map old instance of Record


Map new instance of Record
Move field from Old to New

Figure 626. Copying a field with Labeled USINGs

The Labeled USING with qualifier Old (at 1) qualifies the second occurrence of the symbol
RecID (at 3). Similarly, the Labeled USING with qualifier New (at 2) qualifies the first occurrence of the symbol RecID (at 4). Because both occurrences of RecID are qualified, they can be
resolved into base-displacement form only with respect to the register with the corresponding
qualifier, thus generating the desired X D203 500A 700A .
Appropriate choices of qualifier names also make the code easier to read and understand!
This example illustrates several advantages of Labeled USINGs:
1. Data objects need be defined only once, no matter how many times they may are referenced
concurrently.
2. All references are fully symbolic, and neither explicit base registers nor manually-calculated
displacements need to be assigned.
3. The desired, efficient solution is simple, direct, and readable.
4. You need not understand the details of instruction syntax or the address resolution rules for
ordinary USING statements.

39.4.2. Dropping a Labeled USING Statement


You can DROP a Labeled USING statement with the DROP statement, but with a qualifier
name in place of the register number:
DROP qualifier
Figure 627. DROP statement for Labeled USING

Thus, to DROP the Labeled USINGs in Figure 626, we would write


Drop Old,New

Drop two Labeled USINGs

39.4.3. Labeled USING Statement Summary


Labeled USING statements have interesting properties:
Though it is written like an ordinary symbol, a qualifier cannot be used both as a qualifier and
as an ordinary symbol.
No symbol without a qualifier matching the qualifying label can be resolved with that USING.
Because symbol resolution for unqualified symbols and qualified symbols relies on different
USING information, you could have more than one USING statement active for a particular
base register at the same time. For example:

Chapter XI: Dummy Sections, Enhanced USINGs, and Data Structures

867

Using
Using
- - LA
LA
Drop
LA

QQ

A,9
A,9

Ordinary USING
Labeled USING, qualifier QQ

0,A+40
1,QQ.A+40
9
2,QQ.A+40

Resolved only
Resolved only
Drop ordinary
Resolved only

with Ordinary USING


with Labeled USING
USING; Labeled still active
with Labeled USING

Figure 628. Concurrently active Ordinary and Labeled USINGs

Implied addresses containing symbols without qualifiers will be resolved with the ordinary
USING, and qualified symbols will be resolved only with the matching Labeled USING. As
Figure 628 shows, the DROP statement deletes the Using Table entry for the ordinary
USING, but the Labeled USING remains in effect.
This style of programming should be avoided because it could cause resolution errors as well
as making the code more confusing and difficult to understand. Dont use more than a single
USING based on a given register.
DROP statements for Labeled USINGs must be specified by the qualifier, not by the register.
Normal base-displacement address resolution rules are still in effect:

The relocation attribute of the qualified symbols implied address must match one of the
entries in the USING Table before a displacement can be calculated.

Valid displacements still cannot exceed 4095 (for 12-bit displacements) or 500K (for
20-bit displacements).
Warning
An ordinary and a Labeled USING based on the same register should be
avoided because it is potentially very confusing and error-prone.

Exercises
39.4.1.(2) + Suppose you write instructions like these:

Qual
*
ABC

Using
LA
Using
LA
- - DS

*,12
1,ABC
*,9
2,Qual.ABC
F

What object code will be generated for the two LA instructions?


39.4.2.(2) + Suppose you write instructions like these:
Qual

*
ABC

Using
Using
LA
LA
- - DS

*,9
*,6
1,ABC
2,Qual.ABC
F

What object code will be generated for the two LA instructions? How are the Addressing
Halfwords resolved, and why?
39.4.3.(2) + Suppose you used the statements in Figure 628 in a program like this:

868

Assembler Language Programming for IBM z System Servers

Version 1.00

QQ
*

*
A

Using A,9
Using A,9

Ordinary USING
Labeled USING, qualifier QQ

LA
LA
Drop
LA
- - DS

Resolved only
Resolved only
Drop ordinary
Resolved only

0,A+40
1,QQ.A+40
9
2,QQ.A+40

with Ordinary USING


with Labeled USING
USING; Labeled still active
with Labeled USING

XL80

What addressing halfword will be generated for each of the three LA instructions?
39.4.4.(2) Suppose you wrote
A
Qual

Equ 1024
Using 512,7
LA
3,Q.A

What do you expect the generated object code to be for the LA instruction?

39.5. Dependent USING Statements


Complex data structures often have sub-structures that are described by their own DSECTs. For
example, in Figure 617 on page 860, the RecAddr field of the Record DSECT describes an
address. Because an address is itself a complex data structure, it should be defined by its own
DSECT, as in Figure 629:
Addr
AddrNum
AddrStrt
AddrApt
AddrCity
AddrStat
AddrPost
PostCtry
AddrLen

DSect
DS
DS
DS
DS
DS
DS
DS
Equ

,
CL8
CL22
CL4
CL20
CL2
CL8
CL2
*-Addr

Address-field dummy section


Street number
Street name
Apartment number
City name
State abbreviation
Postal code
Country code
Length of address field

Figure 629. Dummy control section for record address

We should immediately rewrite the Record DSECT to utilize the length information in the Addr
DSECT, as shown in Figure 630:
Record
RecType
RecID
RecName
RecAddr
RecPhone

DSect
DS
DS
DS
DS
DS
- - - - RecYear DS
RecDay DS
- - RecLen Equ

,
CL10
CL4
CL40
CL(AddrLen)
CL12

F
F
*-Record

Record description
Record type
Record ID
Name
Address (length from Addr DSect)
Phone number
etc.
etc.
Processing year
Processing day of year
etc.
Record length

Figure 630. Improved definition of a record description

The only change from Figure 617 is that the length of the RecAddr field is now defined by the
length of the Addr DSECT, rather than by a hand-counted length. This technique should be used
whenever possible.

Chapter XI: Dummy Sections, Enhanced USINGs, and Data Structures

869

Now, suppose GR7 contains the address of a record in memory, and we must update the postal
code field AddrPost from the new value stored at NewPost. With ordinary USING instructions,
we could map the address structure with the Addr DSECT, as in Figure 631:
Using
LA
Using
MVC
Drop

Record,7
9,RecAddr
Addr,9
AddrPost,NewPost
9

GR7 maps the entire record structure


Put address of RecAddr field in GR9
Map the address substructure
Update the postal code
No further updates to Addr fields

Figure 631. Mapping a substructure with a second DSECT

But because we have addressability to the entire Record structure (provided by GR7), we know
the RecAddr field is already addressable. The displacement of the LA instruction with operand
RecAddr will be (RecAddr-Record).268 Unfortunately, we have used a second and unneeded base
register to map the Addr DSECT in the proper position. Assigning an extra register can be quite
inconvenient if many of the general registers are already needed for arithmetic or other addresses.
Thus, we want a way to tell the Assembler that it can use a single base register (GR7 in Figure
631) to address both the Record and Addr structures, while letting us make fully symbolic references to fields in the inner Addr DSECT. Dependent USINGs let us do this.

39.5.1. Definition of Dependent USING Statements


Dependent USING statements look like ordinary USING statements:
USING base_location,operand2 Ordinary USING (usually!)
but with an important difference!
If the second operand of the USING statement (operand2) is absolute, then it must have a value
between zero and fifteen to designate the base register of an ordinary USING statement.
However, if the second operand is relocatable, it is used as the base location at which the first
operand is to be based or anchored. The USING statement is then a Dependent USING
statement.
This base or anchor location must itself be within the range of, or depend on an existing ordinary
USING statement: implied operand addresses must still be addressable so they can be resolved
into base-displacement form with respect to a declared base register and base location.
The syntax of a Dependent USING statement is therefore:
USING base_location,addressable_location Dependent USING statement
Figure 632. Dependent USING statement syntax

Dependent USINGs let you address multiple DSECTs with a single base register.

39.5.2. Examples of Dependent USING Statements


Dependent USING statements allow any object normally, a DSECT to be anchored or
based at any location already addressable by an existing USING statement.
We can now revise the instructions in Figure 631 to use a Dependent USING instruction and a
single base register, where the two now-unnecessary statements have been commented out with
the *** asterisks:

268

870

We have assumed that the Record DSECT is less than 4096 bytes long. Even if the Record DSECT is much larger,
we can either assign more than one base register to provide addressability to all its fields, or use instructions with
signed 20-bit displacements.
Assembler Language Programming for IBM z System Servers

Version 1.00

***

***

Using
LA
Using
MVC
Drop

Record,7
9,RecAddr
Addr,RecAddr
AddrPost,NewPost
9

GR7 maps the entire record structure


Put address of RecAddr field in GR9
Map the address substructure
Update the postal code
No further updates to Addr fields

Figure 633. Anchoring an internal DSECT with a Dependent USING

One fewer instruction and one fewer base register are needed now.
The Assembler requires the second operand of a Dependent USING to be addressable at the time
the Dependent USING is encountered. This addressability may actually support more than one
Dependent USING. For example, suppose we want to describe two subordinate DSECTs B and
C within an outer DSECT A, as sketched in Figure 634:
Offset
X000

DSECT A
X020
B1 DS D
DSECT B
B2 DS D


X030
C1 DS CL80
DSECT C
C2 DS XL8

:
:

X100
Figure 634. Outer DSECT with two nested DSECTs

The Assembler listing extract in Figure 635 shows how addresses of various fields are resolved:
The ordinary USING at statement 9 maps the location of the outer DSECT A, to provide
addressability for all three DSECTs.
The Dependent USING at statement 10 anchors DSECT B at offset X 2 0 from the start of
DSECT A.
DSECT C is anchored by the Dependent USING at statement 14 at offset X 1 0 from the start
of DSECT B.

Chapter XI: Dummy Sections, Enhanced USINGs, and Data Structures

871

R:F 00000
1 F 020 00000 00020
00058 4100 F028

00008

2 F 030 00000 00010


0005C 4100 F080
00000
00000
00008
00000
00000
00050
00000
00000

00050

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

USING A,15
USING B,A+32

Ordinary: Addr(A) in R15


Dependent: B offset X20 from A

LA

B2 at offset X28 from A

*
0,B2

*
USING C,B+16

Dependent: C offset X10 from B

LA

C2 at offset X80 from A

*
*
B
B1
B2
*
C
C1
C2
*
A

0,C2

DSECT
DS
D
DS
D

Offset
Offset

DSECT
DS
CL80
DS
XL8

Offset
0 from C
Offset X50 from C

0 from B
8 from B

DSECT
DS
XL256

Figure 635. Assembler listing of multiple Dependent USINGs and DSECTs

In statement 10, the Assembler indicates (at 1) that the anchoring base location of the first
Dependent USING is at offset X020 from the location specified for base register X F . Statement 14 shows (at 2) that the anchoring base location of the second Dependent USING is at
offset X 3 0 .269 Even though three distinct DSECTs are referenced, only one base register (GR15)
is needed for the two LA instructions.
If the three DSECTs in Figure 634 are mutually independent, they need not be nested and can
still be defined to use only a single base register, as sketched in Figure 636:
Offset
X000

DSECT A

:
:

X100
B1
DS
D
DSECT B
B2
DS
D

X110
C1
DS
CL80
DSECT C
C2
DS
XL8

C3
DS
H

X170
Figure 636. Three independent data structures with one base register

We can define the three independent data structures mapped by DSECTs A, B, and C with these
statements:

269

872

Unfortunately, two of the USING statements in Figure 635 use absolute offsets. See Exercise 39.5.4 for a better
approach.
Assembler Language Programming for IBM z System Servers

Version 1.00

B
B1
B2
BLen
C
C1
C2
C3
CLen
A

ALen

DSect
DS
DS
DS
Equ
DSect
DS
DS
DS
DS
Equ
DSect
DS
DS
Equ

D
D
0D
*-B
CL80
XL8
H
0D
*-C
XL256
0D
*-A

Round up length to a doubleword

Round up length to a doubleword

Round up length to a doubleword

Figure 637. Defining DSECTs for three independent data structures

Unlike the DSECT definitions in Figure 635, each DSECT defines a symbol for its length after
rounding to a doubleword boundary. This is a good practice in case you need to allocate storage
for multiple structures to be based on a single base register, because you should ensure proper
alignment of each structure. Suppose we allocate enough storage for all three structures:
TotalLen Equ

ALen+BLen+CLen

Total amount of storage needed

Now, suppose GR7 contains the address of TotalLen allocated bytes aligned on a doubleword
boundary. We can use one ordinary and two Dependent USINGs to map all three structures:
*

TotalLen bytes addressed by GR7


- - Using A,7
Map DSECT A first
Using B,A+ALen
Map DSECT B following A
Using C,B+BLen
Map DSECT C following B
- - -

Figure 638. Defining a mapping of three independent but contiguous data structures

Instructions referencing any of the fields within the three structures will be resolved with base register 7, assuming that TotalLen is small enough that a single base register can address all the fields.

39.5.3. Mapping a CSECT as a DSECT


Dependent USINGs let you do very interesting things. For example, suppose you need to construct a message into which several insertions will be made in known positions. First, construct
the message skeletons in a separate CSECT in the same assembly as the Program CSECT:
MsgSkels CSect ,
Msg1
DC
C This message for
Msg1To DC
C totototo
DC
C is from
Msg1From DC
C fromfrom
Msg1L
Equ *-Msg1
- - - - -

Message skeletons
Message 1
Modified field: To name
Additional message characters
Modified field: From name
Length of message 1
Other messages follow

Figure 639. Example of a message-skeleton CSECT

We complete the message in the Program CSECT by first moving the message skeleton from the
MsgSkels CSECT to an output area named OutMsg. Then, the Dependent USING maps the
structure of the skeleton on the OutMsg where the completed message is constructed:

Chapter XI: Dummy Sections, Enhanced USINGs, and Data Structures

873

Program CSect
BASR
Using
L
L
Using
Using
MVC
Drop
Using
MVC
MVC
Drop
- - ToName DC
FromName DC
AddrMsgs DC
AOutMsg DC
- - OutMsg DS

,
12,0
*,12
10,AddrMsgs
11,AOutMsg
MsgSkels,10
OutMsg,11
OutMsg(Msg1L),Msg1
10
Msg1,OutMsg
Msg1To,ToName
Msg1From,FromName
11

Set base register


Provide local addressability
Point to messages
Point to buffer area
Addressability for Messages CSECT
Addressability for OutMsg area
Move skeleton to buffer
Don t reference original skeleton
Map original skeleton onto buffer
Move To name
Move From name
Done with buffer addressing

CL(L Msg1To) You


CL(L Msg1From) Me
A(MsgSkels)
A(OutMsg)

Addressee name
Sender name
Address of Messages CSECT
Address of OutMsg area

CL121

Area for constructing messages

Figure 640. Example of mapping a CSECT as though it is a DSECT

The key statement is the Dependent USING statement:


Using Msg1,OutMsg

Map original skeleton onto buffer

directs the Assembler to resolve the first-operand addresses in the two following MVC
instructions with offsets defined in the MsgSkels CSECT, but mapped on the OutMsg area. Note
that when those two MVCs are executed, the MsgSkels CSECT is no longer addressable! The
Dependent USING statement mapping the skeleton constant onto the OutMsg buffer avoids the
need to define a DSECT for each message, and also avoids manually calculating displacements
and assigning base registers.

39.5.4. Dropping Dependent USINGs


Unlike ordinary and Labeled USING statements, you must DROP a Dependent USING by
dropping the ordinary USING on which it depends. For example, in Figure 634 on page 871, we
cant remove addressability to DSECT C separately; we must DROP the USING statement that
provides addressability for all three DSECTs. In Figure 640, to drop the USING in the statement
Using Msg1,OutMsg

Map original skeleton onto buffer

we must drop the USING on which it depends:


Drop 11

Drop GR11

because the mapping of Msg1 is anchored at OutMsg which in turn is based on GR11.
Well see in Section 39.6 how Labeled Dependent USING statements can help.

39.5.5. Dependent USING Statement Summary


Dependent USINGs can provide elegant solutions to problems involving the management of data
structures that are adjacent, nested, or overlapping in storage.
They provide addressability with a minimum number of registers.
They allow fully symbolic structure and substructure mappings with independent DSECTs.
They encourage simple mappings of complex data structures.
They let you map variant records in which the structure of parts of the record depend on
preceding data values, with different mappings along different code paths.
One way to view the difference between ordinary Dependent USINGs is by the way the firstoperand location is based or anchored.

874

Assembler Language Programming for IBM z System Servers

Version 1.00

For ordinary USINGs, the first operand is based on the base register specified by the second
operand. Instructions set the register contents at execution time.
For dependent USINGs, the first operand is based or anchored on the location specified
by the second operand; this location must already be addressable. The relative position of the
first operand is set at assembly time by the Assembler.

Exercises
39.5.1.(2) + Using the instructions sketched in Figures 639 and 640, create a program that can
be correctly assembled. Study the displacements in the MVC instructions to verify that the
intended data is moved to the correct fields.
39.5.2.(2) In Figure 636, will it make any difference if the three DSECTs are arranged in a different order?
39.5.3.(2) + The first paragraph in Section 39.5.3 says that the MsgSkels CSECT containing the
message skeletons is in the same assembly as the Program CSECT. What will happen if it is in a
separate assembly?
39.5.4.(2) + Revise the DSECT statements in Figure 635 on page 872 to make all references
fully symbolic, without offsets like A+32 and B+16.

39.6. Labeled Dependent USING Statements


Labeled Dependent USINGs combine the benefits of Labeled USINGs and Dependent USINGs:
multiple copies of an object may be active simultaneously (Labeled)
many objects may be addressed with a single base register (Dependent).
We start with several examples that illustrate typical problems when we use ordinary USINGs,
and how easily we can solve them with Labeled Dependent USINGs.
The syntax of a Labeled Dependent USING requires a qualifying label in the name field of the
USING statement, and a relocatable second operand indicates where the first operand is to be
anchored or based.
qualifier USING base_location,addressable_location Labeled Dependent USING
Figure 641. Labeled Dependent USING statement syntax

As with unlabeled Dependent USINGs, the second operand must be addressable with reference to
an ordinary USING statement somewhere earlier in the program.
Suppose we have a data structure containing several data items, including two identical substructures described by a single DSECT. The substructure is defined by a DSECT named Inner:
Inner
IVarJ
IVarK
InnerLen

DSect
DS
DS
Equ

,
XL5
XL7
*-Inner

Length of Inner structure

and the containing data structure is described by a DSECT named Outer:

Chapter XI: Dummy Sections, Enhanced USINGs, and Data Structures

875

Outer
OutVarA
Out_Inr1
OutVarB
Out_Inr2
OutVarC
OuterLen

DSect
DS
DS
DS
DS
DS
Equ

,
CL12
XL(InnerLen)
CL33
XL(InnerLen)
XL3
*-Outer

First substructure
Second substructure
Length of Outer structure

Figure 642. Nesting two identical structures within a third

Out_Inr1 and Out_Inr2 are the positions within the Outer DSECT where the two sub-structures
are mapped.
We will examine three approaches to managing the description and addressing of the data elements in these structures:
first, we consider ordinary USINGs and the problems they present;
second, we examine Labeled USINGs;
third, we will see how Labeled Dependent USINGs provide a solution free of the defects of
the two previous approaches.

39.6.1. Nesting Structures Addressed with Ordinary USINGs


To address the three structures with ordinary USINGs, we need to provide three base registers
and three USING statements. As in Section 39.4, we want to manage two active instances of the
Inner DSECT, but only one active instance is allowed with ordinary USINGs.
We could make a second copy of the Inner DSECT, and then address it and the original copy
with separate USINGs.
Znner
ZVarJ
ZVarK
ZnnerLen

DSect
DS
DS
Equ

,
XL5
XL7
*-Znner

Length of Znner structure

The three DSECTs can now be addressed with statements like the following:
Using
LA
Using
LA
Using

Outer,10
11,Out_Inr1
Inner,11
12,Out_Inr2
Znner,12

GR10 points to the


GR11 points to 1st
USING for 1st copy
GR12 points to 2nd
USING for 2nd copy

Outer DSECT
copy of Inner
of Inner
copy of Inner
(now named Znner)

Weve already described the defects and difficulties with ordinary USINGs in this context: maintenance and readability problems are much greater when more than one name is used for the same
thing.

39.6.2. Nesting Structures Addressed with Labeled USINGs


A somewhat better solution involves Labeled USINGs. They allow the two instances of the
Inner DSECT to be addressed using a single definition of Inner, eliminating any need for a Znner
DSECT:

In1
In2

Using
LA
Using
LA
Using

Outer,10
11,Out_Inr1
Inner,11
12,Out_Inr2
Inner,12

GR10 points to Outer DSECT


GR11 points to 1st copy of
Labeled USING for 1st copy
GR12 points to 2nd copy of
Labeled USING for 2nd copy

Inner
of Inner
Inner
of Inner

The implied addresses in both LA instructions will be resolved with register 10 as the base register.

876

Assembler Language Programming for IBM z System Servers

Version 1.00

The remaining defect in this example is the need to use three addressing registers when only one is
actually needed. Labeled Dependent USINGs provide the desired saving.

39.6.3. Nested Structures Addressed with Labeled Dependent USINGs


The best solution involves Labeled Dependent USINGs: they allow the entire structure and all its
components to be addressed with the minimum number of registers, and with proper naming for
all components.
Assume again that the address of the containing Outer structure is placed in GR10; then, we can
write:
In1
In2

Using Outer,10
Using Inner,Out_Inr1
Using Inner,Out_Inr2

GR10 addresses Outer DSECT


Labeled Dependent USING for 1st Inner
Labeled Dependent USING for 2nd Inner

Figure 643. Addressing two nested DSECTs with Labeled Dependent USINGs

The first instance of Inner is anchored at Out_Inr1, and references to its components are made
using qualifier In1. Similarly, the second instance of Inner is anchored at at Out_Inr2, and its
components can be qualified with In2. References to the fields in the three structures can then be
made freely, and only a single register is needed to address the entire structure. Figure 644 shows
how references can be made to fields within the three DSECTs:
CLC In1.IVarK,In2.IvarK
- - MVC OutVarC,In2.IVarK
- - PACK In1.IvarK,OutVarC

Compare the two IVarK fields


Copy 3 bytes of 2nd IVarK
Pack part of OutVarC to 1st IVarK

Figure 644. Data in nested DSECTs addressed with Labeled Dependent USINGs

39.6.4. Multiple Nesting of Identical Structures


As the number and nesting of data structures increases, addressing the components becomes more
difficult. For example, suppose we wish to create a data structure in which an outermost structure described by the Top DSECT contains three copies of a structure described by the Mid
DSECT, and each of those contains three copies of a structure described by the Bot DSECT. The
complete structure might look somewhat like Figure 645, where the three Mid DSECTs are identified as M1, M2, and M3, and the Bot DSECTs are identified as B1, B2, and B3.

Top
Mid
M1 Bot
B1

Bot
B2

Bot
B3

Mid
M2 Bot
B1

Bot
B2

Bot
B3

Mid
M3 Bot
B1

Bot
B2

Bot
B3

Figure 645. Multiply-Nested Data Structures

Chapter XI: Dummy Sections, Enhanced USINGs, and Data Structures

877

If ordinary USINGs address all components of this set of structures, we will need thirteen base
registers! This is beyond the capabilities of most programs, so that we would be forced to use
unnatural solutions if we are restricted to ordinary USING statements.
Dependent USINGs will help only a little, because of the high degree of repetition among the
inner structures.270
Suppose the three DSECTs named Top, Mid, and Bot in Figure 645 are described by the DSECTs
in Figure 635:
Bot
X1
X2
L_Bot
Mid
MidVar1
B1
MidVar2
B2
MidVar3
B3
MidVar4
L_Mid
Top
M1
M2
M3

DSect
DS
DS
DS
Equ

,
XL5
XL5
0D
*-Bot

Third-level DSECT (bottom level)


First data element
Second data element
Round length to a doubleword
Length of Bot DSect

DSect
DS
DS
DS
DS
DS
DS
DS
DS
Equ

,
CL40
XL(L_Bot)
CL60
XL(L_Bot)
CL20
XL(L_Bot)
CL30
0D
*-Mid

Second-level DSECT (middle level)


Data in second-level DSect
First third-level DSect
Data in second-level DSect
Second third-level DSect
Data in second-level DSect
Third third-level DSect
Data in second-level DSect
Round length to a doubleword
Length of Mid DSect

DSect
DS
DS
DS
DS

,
XL(L_Mid)
XL(L_Mid)
XL(L_Mid)
0D

First-level DSECT (top level)


First second-level DSect
Second second-level DSect
Third second-level DSect
Round length to a doubleword

Figure 646. Doubly Nested DSECT definitions

Addressing this structure with ordinary USINGs is nearly impossible to do cleanly, and a solution
with Labeled USINGs also requires thirteen registers to address the thirteen different active
DSECTs.
Labeled Dependent USINGs provide the only manageable solution. Though the example in
Figure 647 looks somewhat complicated, it has a simple basic structure.

270

878

This example is rather artificial, but helps show the power of Labeled Dependent USINGs. Two more-realistic examples are described in Sections 39.6.6 and 39.7.
Assembler Language Programming for IBM z System Servers

Version 1.00

Using Top,7
*
Mid1
*
M1B1
M1B2
M1B3
*
Mid2
*
M2B1
M2B2
M2B3
*
Mid3
*
M3B1
M3B2
M3B3

Using Mid,M1
Using Bot,Mid1.B1
Using Bot,Mid1.B2
Using Bot,Mid1.B3
Using Mid,M2
Using Bot,Mid2.B1
Using Bot,Mid2.B2
Using Bot,Mid2.B3
Using Mid,M3
Using Bot,Mid3.B1
Using Bot,Mid3.B2
Using Bot,Mid3.B3

1
2
2
2
1
3
3
3
1
4
4
4

1
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|

Top level
2
|
|
|
|
2
|
|
|
|
|
2
|
|
|
|
|

Map Mid into Top at M1


Bottom level:
3 Map Bot into Mid1 at
3 Map Bot into Mid1 at
3 Map Bot into Mid1 at
Middle level:
Map Mid into Top at M2
Bottom level:
3 Map Bot into Mid2 at
3 Map Bot into Mid2 at
3 Map Bot into Mid2 at
Middle level:
Map Mid into Top at M3
Bottom level:
3 Map Bot into Mid3 at
3 Map Bot into Mid3 at
3 Map Bot into Mid3 at

B1
B2
B3

B1
B2
B3

B1
B2
B3

Figure 647. Addressing doubly nested DSECT definitions

The three Labeled Dependent USING statements in Figure 647 (tagged 1) map the middle-level
DSECT Mid into the outermost DSECT Top. Because there will be three instances of Mid simultaneously active, the qualifiers Mid1, Mid2, and Mid3 distinguish the first, second, and third
instances of Mid within Top. The three instances of Mid are anchored at the positions within Top
defined by the fields named M1, M2, and M3 respectively.
The three innermost instances of the Bot DSECT are mapped into the three instances of Mid similarly. For example, the three Labeled Dependent USING statements for the first instance of Mid
(tagged 2) anchor the three instances of Bot within Mid at the positions named B1, B2, and B3
respectively. (Referring to Figure 645 may help.)
Because there will be three different active instances of those labels, we use the qualifier Mid1 to
qualify the references to B1, B2, and B3. Thus the second operand of each of the three Labeled
Dependent USING statements tagged 2 is qualified with Mid1. The qualifiers on those three
USINGs, M1B1, M1B2, and M1B3, are used to qualify references to the first three of the nine possible instances of the fields X1 and X2. The qualifier M1B3 means first Mid and third Bot. This
shows how appropriately chosen qualifiers can help you to understand complex structures more
easily.
The mappings of the second and third sets of instances of the Bot DSECT are defined similarly, in
the sets of three Labeled Dependent USINGs tagged 3 and 4. The qualifiers M2B1 through
M3B3 are then used to qualify references to the fields within the DSECT named Bot.
We can then write instructions to reference these fields, with appropriate qualifiers, as illustrated
in Figure 648. All symbolic references will be resolved with the base register (or registers) specified
in the USING statement for Top.

Chapter XI: Dummy Sections, Enhanced USINGs, and Data Structures

879

Move
MVC
MVC
MVC
MVC

fields X1 and X2 within Bot DSECTs


M1B1.X1,M1B1.X2
Within bottom-level
M1B3.X2,M1B1.X1
Across bottom-level
M3B2.X2,M3B3.X2
Across bottom-level
M2B1.X1,M3B2.X2
Across bottom-level

DSECT M1B1
DSECTs in M1
DSECTs in M3
DSECTs in M2, M3

Move complete Bot DSECTs within Mid DSECTs


MVC Mid3.B1,Mid3.B3
Within mid-level DSECT Mid3
MVC Mid1.B3,Mid2.B1
Across mid-level DSECTs Mid1, Mid2

Copy fields across Mid DSECTs


MVC Mid2.MidVar3,Mid3.MidVar1

Across two middle DSECTs

Move complete Mid DSECTs within Top DSECT


MVC M1,M2
Across top-level DSECTs Top

Figure 648. Using the Labeled Dependent USINGs to move data

As you can appreciate, coding instructions like these with ordinary USING statements would be
much more difficult to write and understand.
Remember!
Qualified symbols may be used to declare the anchor operand in a
Labeled Dependent USING statement that itself defines another qualifier!

39.6.5. Mapping an Array of Identical Data Structures


Suppose you have a small array of identical data structures, and you want to refer to fields within
different array elements. First, you could define a DSECT describing the data structure:
Struc
StrF1
StrF2
StrF3
LStruc

DSect
DS
DS
DS
Equ

,
CL8
F
A
*-Struc

Structure of an array element


First field
Second field
Third field
Structure Length

Then, suppose GR9 contains the address of the first element of the array. You can then map the
first few elements of the array with Labeled Dependent USINGs:
EL1
EL2
EL3
EL4

Using
Using
Using
Using
- - -

Struc,9
Struc,EL1.Struc+1*LStruc
Struc,EL1.Struc+2*LStruc
Struc,EL1.Struc+3*LStruc

Map first
Map second
Map third
Map fourth
etc.

element
element
element
element

Then, you can refer to fields within each element of the array:
L
A
MVC

1,EL3.StrF2
1,EL5.StrF3
EL2.StrF1,EL4.StrF1

Get field 2 from element 3


Add field 3 from element 5
Move field 1 from element 4 to 2

This technique is limited to small arrays because the number of Labeled Dependent USING
statements grows with the number of elements to be referenced. If you need to refer to fields in
two widely separated elements, it may be easier to assign a base register to each and map the
elements with Labeled USINGs instead.

880

Assembler Language Programming for IBM z System Servers

Version 1.00

39.6.6. Two MVS Data Control Blocks (DCBs) in a Program


This small example shows how you can benefit from Labeled Dependent USINGs in a program,
where the program base register also addresses two embedded DSECT-mapped structures.
Many programs contain two or more Data Control Blocks (DCBs) for input and output data
sets, and are often coded in the same program as the instructions that refer to them. If only
ordinary USINGs are available, (at least) three registers must be used for addressability: one (or
more) for the program itself, and one for each DCB. Furthermore, only one of the DCBs can be
mapped with the IBM-provided IHADCB DSECT 271 because both cannot be mapped simultaneously with distinct registers.
With ordinary USING statements, a typical instruction sequence to copy the two-byte logical
record length (DCBLRECL) from the input DCB to the output DCB might look like this:

InDCB
OutDCB

Using
- - LA
LA
Using
MVC
- - DCB
DCB
- - DCBD

*,12

Program base register

3,OutDCB
Point GR3
2,InDCB
Point GR2
IHADCB,2
Map Input
DCBLRECL-IHADCB(,3),DCBLRECL

to Output DCB
to Input DCB
DCB
Copy InDCB LRECL to OutDCB

DDNAME=..., etc.
DDNAME=..., etc.

Input DCB
Output DCB

...,etc.

Generate IHADCB DSECT

Figure 649. Addressing two DCBs with ordinary USINGs

Three registers must be assigned, and one of the operands in the MVC instruction must be
written with explicitly assigned base and displacement.
Its better to make symbolic references to fields in both DCBs at the same time. Iin Figure 650,
the two Labeled Dependent USINGs with qualifiers In and Out let you make fully symbolic references to both DCBs, and without needing additional base registers.
Using
- - In 1 Using
Out 2 Using
- - MVC

InDCB
OutDCB

*,12

Program base register

IHADCB,InDCB
IHADCB,OutDCB

Labeled Dependent USING


Labeled Dependent USING

Out.DCBLRECL,In.DCBLRECL Addresses resolved with GR12


2
1

- - DCB DDNAME=..., etc.


DCB DDNAME=..., etc.
- - DCBD ...,etc.

Input DCB
Output DCB
Generate IHADCB DSECT

Figure 650. Addressing instructions and DCBs with one register

The base address in the first USING can be anchored at any addressable location that provides
addressability to the two DCBs and the MVC instruction.

Exercises
39.6.1.(2) Referring to Figure 645, sketch the movement of data caused by the instructions in
Figure 648.

271

Generated by the DCBD macro. (IHADCB is sometimes nicknamed I Had A Control Block.)
Chapter XI: Dummy Sections, Enhanced USINGs, and Data Structures

881

39.6.2.(1) In Figure 642, write ordinary USING statements to provide addressability to all three
DSECTs.
39.6.3.(2) + In Figures 646 and 647, what are the offsets from the origin of the Top DSECT of
these qualified symbols?

M1B1.X1
Mid1.MidVar1
M3B2.X2
Mid3.MidVar4

39.6.4.(3) + Create a complete program and assemble the statements in Figures 646, 647, and
648. Study the generated object code to verify that all addressing halfwords are generated correctly.

39.7. Example of a Large Personnel-File Record (*)


The power of Dependent and Labeled Dependent USINGs is most evident when you must
handle complex data records, especially when the structure of fields in later parts of the record
depends on data values in earlier fields, or where repeated identically-structured fields (mapped by
the same DSECT) appear several times within the records structure.
Note: This example, while rather complex, shows how you can use the Assemblers Dummy
Control Sections and Labeled Dependent USINGs for tasks once thought to be manageable only
by high-level language.
Suppose our program must refer to various fields in records maintained in a personnel file. Each
record contains information about an employee, and fields within the record contain different
kinds of information.
First, we define the layout of the employee record with an Employee DSECT. All symbols start
with the letter E.
Employee
EPerson
EHire
EWAddr
EPhoneW
EPhoneF
EMarital
ESpouse
E#Deps
EDep1
EDep2
EDep3
EmployeL

DSect
DS
DS
DS
DS
DS
DS
DS
DS
DS
DS
DS
EQU

,
CL(PersonL)
CL(DateL)
CL(AddrL)
CL(PhoneL)
CL(PhoneL)
X
CL(PersonL)
PL2
CL(PersonL)
CL(PersonL)
CL(PersonL)
*-Employee

Employee record
Person field
Date of hire
Work (external) address
Work telephone
Work Fax telephone
Marital Status
Spouse field
Number of dependents
Dependent 1
Dependent 2
Dependent 3
Length of Employee record

Figure 651. Define a personnel-file record

The record contains information about the employee: a description of the person, the employees
spouse and first three dependents, work address, date of hire, work telephone, and so forth. Space
is provided in the Employee DSECT for several other nested or overlaid DSECTs described
below.
The description of each person (employee, spouse, dependents) is similarly defined by a Person
DSECT shown in Figure 652:

882

Assembler Language Programming for IBM z System Servers

Version 1.00

Person
PFName
PGName
PInits
PDoB
PAddr
PPhone
PSSN
PSex
PersonL

DSect
DS
DS
DS
DS
DS
DS
DS
DS
EQU

,
CL20
CL15
CL3
CL(DateL)
CL(AddrL)
CL(PhoneL)
CL9
CL1
*-Person

Define a Person field


Last (Family) name
First (Given) name
Initials
Date of birth
Home address
Home telephone number
Social Security Number
Gender
Length of Person field

Figure 652. Employee-record Person DSECT

The fields in the Person DSECT describe their name, date of birth, home address and telephone,
and other items. Again, space has been reserved for three other nested DSECTs describing a
date, an address, and a telephone number.
Three more DSECTs might be defined as follows. First, the Date DSECT:
Date
Year
Month
Day
DateL
DateF

DSect ,
DS
CL4
DS
CL2
DS
CL2
EQU *-Date
ORG Date
DS 0CL(DateL)
ORG ,

Define a calendar date field


YYYY
MM
DD
Length of Date field
Full YYYYMMDD date field

Figure 653. Employee-record Date DSECT

The last three statements are used to define the symbol DateF as a single field containing the
entire contents of the three Date fields.
The Addr DSECT, describing a postal address, is defined in a similar way:
Addr
AStr#
APOBApDp
ACity
AState
AZip
AddrL
AddrF

DSect ,
DS
CL30
DS
CL15
DS
CL24
DS
CL2
DS
CL9
EQU *-Addr
ORG Addr
DS 0CL(AddrL)
ORG ,

Define an address field


Street number
P.O.Box, Apartment, or Department
City name
State abbreviation
U.S. Post Office Zip Code
Length of Address field
Full address structure

Figure 654. Employee-record Address DSECT

Again, the last three statements are used to define the symbol AddrF as a single field containing
the entire contents of all the Addr fields.
Finally, we define the Phone DSECT, describing a (U.S.) commercial telephone number:
Phone
PhCtry
PhArea
PhLocal
PhExt
PhoneL
PhoneF

DSect ,
DS
CL2
DS
CL3
DS
CL7
DS
CL4
EQU *-Phone
ORG Phone
DS 0CL(PhoneL)
ORG ,

Define a Telephone field


Country code
Area Code
Local number
Extension
Length of Phone field
Full telephone number structure

Figure 655. Employee-record Phone DSECT


Chapter XI: Dummy Sections, Enhanced USINGs, and Data Structures

883

As before, the last three statements define the symbol PhoneF to name a single field containing the
entire contents of all the Phone fields.
At this point, its worth sketching the nesting of these various DSECTs.
The Date DSECT appears at two different levels of nesting: the Date-of-Hire field (EHire) in
the Employee DSECT is nested two levels deep, and the Date-of-Birth fields (PDoB) in each
Person DSECT are nested three levels deep (because the Person DSECT is nested two levels
deep in the Employee DSECT).
The Addr DSECT is nested two levels deep (as the employees work address), and three levels
deep (as the home-address field (PAddr) within each Person DSECT).
Finally, the Phone DSECT is also nested two levels deep (PPhone, for the employees home)
and three levels deep (EPhoneW, the employees work number).
These nesting levels are shown in the upper right corners of the boxes in Figure 656.
While this example may seem a bit complex, we will use it again in discussing Labeled Dependent
USINGs, where the full power of those statements can be shown.
Assume that the Employee, Person, Date, Addr, and Phone structures have been defined as illustrated in Figures 651 through 655.
First, we show how Dependent USINGs can help with mapping this structure. Suppose such an
employee record has been placed in memory and its address is in GR10; we now wish to manipulate various fields within the record. The necessary DSECT addressing can be established as
follows:
USING
USING
USING
USING
USING

Employee,10
Person,EPerson
Date,PDoB
Addr,PAddr
Phone,PPhone

R10 points to Employee record


Anchor Person DSECT at EPerson
Anchor Date DSECT at PDoB field
Anchor Addr DSECT at PAddr field
Anchor Phone DSECT at PPhone field

Figure 657. Anchoring various DSECTs within Employee record

The five USING statements in Figure 657 provide addressability to five different DSECTS:
The Employee DSECT is based on an ordinary USING statement with base register GR10. All
other implied address resolutions within the Employee DSECT will be resolved using GR10 as
the base register.
The Person DSECT is anchored by the first Dependent USING at the Eperson field in the
Employee DSECT.
Within the Person DSECT, the Date DSECT is anchored by the second Dependent USING
at the PDoB field in the Person DSECT.
Within the Person DSECT, the Addr DSECT is anchored by the third Dependent USING at
the PAddr field in the Person DSECT.
Within the Person DSECT, the Phone DSECT is anchored by the fourth and last Dependent
USING at the PPhone field in the Person DSECT.
All symbolic references to fields in any of the five DSECTs will be resolved with a single base
register, so long as the size of the Employee record does not exceed 4096 bytes. If it does, the
problem is easy to fix: simply add another base register to the ordinary USING statement in
Figure 657, and another 4096 bytes will be addressable automatically.
We can now use these definitions to access and manipulate some fields described by those five
DSECTs, as in Figure 658:

884

Assembler Language Programming for IBM z System Servers

Version 1.00

Employee
| EPerson
| | PFName
| | PGName
| | PInits
| | PDoB
| | | Year
| | | Month
| | | Day
| | PAddr
| | | AStr#
| | | APOBApDp
| | | ACity
| | | AState
| | | AZip
| | PPhone
| | | PhArea
| | | PhLocal
| | | PhExt
| | PSSN
| | PSex
| EHire
| | Year
| | Month
| | Day
| EWAddr
| | AStr#
| | APOBApDp
| | ACity
| | AState
| | AZip
| EPhoneW
| | PhArea
| | PhLocal
| | PhExt
| EPhoneF
| | PhArea
| | PhLocal
| | PhExt
| EMarital
| ESpouse
| | PFName
| | PGName
| (omitted)
| | |
| E#Deps
| EDep1
| | PFName
| | PGName
| | (omitted)
| |
| (omitted)
|
|

Employee1
Person2

Date3

End of Date
Addr3

End of Addr
Phone3

End of Phone

End of Person
Date2

End of Date
Addr2

End of Addr
Phone2

End of Phone
Phone2

End of Phone

Person2

:: (and so forth)
::
End of Person

Person2

:: (and so forth)
::
End of Person
:
(and so forth)
:

End of Employee

Figure 656. DSECT nesting in an employee record

Chapter XI: Dummy Sections, Enhanced USINGs, and Data Structures

885

CLC PGname,Input_Name
- - MVC PhExt,=CL(L PhExt)
- - CLC AZip,=C95141

Compare record name to input


Blank phone extension field
Check for a specified Zip Code

Figure 658. Manipulating fields within an Employee record

The primary limitation of the Dependent USINGs shown in this example is that only a single
instance of each DSECT is addressable at any one time. In many applications this may be adequate; if not, Labeled Dependent USINGs will help.
If ordinary USING statements had been required in Figure 657, the resulting burden on the
general registers could have been severe. Statements such as these might have been required:
USING
LA
USING
LA
USING
LA
USING
LA
USING

Employee,10
9,Eperson
Person,9
8,PDoB
Date,8
7,PAddr
Addr,7
6,PPhone
Phone,6

R10 points to Employee record


Address of EPerson field
Anchor Person DSECT at EPerson field
Address of PDoB field
Anchor Date DSECT at PDoB field
Address of PAddr field
Anchor Addr DSECT at PAddr field
Address of PPhone field
Anchor Phone DSECT at PPhone field

Figure 659. Addressing DSECTs within Employee record with ordinary USINGs

The coding is likely to be less efficient, and the number of opportunities for misunderstanding and
error has also increased.
Now, we will consider addressing multiple active instances of the inner structures in this Employee
record. We assume that the program has placed the Employee record into memory at an address
referenced by GR10 again.

39.7.1. Personnel-File Record Example: Comparing Birth Dates


Suppose we must compare the birth dates of the employee and the employees spouse. Because
the birth date is a component of the Person DSECT, we must establish mappings of the two
instances of that DSECT. In Figure 660 this is done with two Labeled Dependent USING statements:
* Example 1: Compare Employee and Spouse Family Dates of Birth
USING Employee,10
PE 1 USING Person,EPerson
PS 2 USING Person,ESpouse
CLC

PE.PDoB,PS.PDoB
1
2

Assume R10 points to the record


Overlay Person DSECT on Empl. field
Overlay Person DSECT on Spouse field
Compare Employee/Spouse birth dates

Figure 660. Comparing dates of birth in Employee record

The first Labeled Dependent USING statement (1) maps the Person structure onto the
Employee record at the position defined by EPerson with qualifier PE; this describes information
about the employee. The second Labeled Dependent USING statement (2) maps the Person
structure onto the Employee record at the position defined by ESpouse with qualifier PS, describing
information about the employees spouse.
The CLC instruction compares the dates. Both instances of the Person structure are nested at the
same level within the Employee structure, so that similar styles of qualification are used for the two
occurrences of the symbol PDoB.

886

Assembler Language Programming for IBM z System Servers

Version 1.00

39.7.2. Personnel-File Record Example: Comparing Different Dates


Suppose our second requirement is to check the employee record to see if the date of birth of the
first dependent is later than the employees date of hire. In this case, we must deal with two different levels of nesting of the Date structure: one (the employees date of hire) is nested directly
within the Employee DSECT at the position named EHire, while the birth date of the first
dependent is nested in the Employee DSECT at position EDep1 within the first-dependent Person
DSECT at position PDoB. Thus, we will need additional Labeled Dependent USINGs to properly
establish addressability to the PDoB field.
* Example 2: Compare Date of Hire to Birth Date of Dependent 1
EHD 3 USING Date,EHire

Overlay Date DSECT on Date of Hire

PD1 4 USING Person,EDep1


DD1 5 USING Date,PD1.PDoB
4

Overlay Person DSECT on Dependent 1


Overlay Date DSECT on Dependent 1

CLC

EHD.DateF,DD1.DateF
3
5

DROP EHD,DD1

Compare hire date to Dep 1 DoB

Remove both date associations

Figure 661. Comparing date fields in different parts of an Employee record

In order to map the two instances of the Date DSECT, we first issue a Labeled Dependent using
with qualifier EHD to describe the employees date of hire (at EHire, 3). Then, to map the first
dependents date of birth, we must first map a Person DSECT onto the employee record (at
EDep1, 4) with qualifier PD1. Finally, within that Person DSECT, we describe the dependents
date of birth by mapping the Date DSECT onto the Person structure (at PDoB, 5) with qualifier
DD1.
The CLC instruction refers to two complete date fields DateF, qualified to associate one with the
date of hire and the other with the first dependents date of birth.
This example, while not obvious at first encounter, is worth some study: it shows how you can
use Labeled Dependent USINGs to map very complex structures in a natural, readable way that
does not require you to understand what pointers may have been established in which registers
many lines earlier in the program.
Note that the DROP statement, by specifying the two qualifiers, removes the mappings of both
Date DSECTs.

39.7.3. Personnel-File Record Example: Copying Addresses


Suppose our third requirement is to update the employee record so that the second dependents
address is made to be the same as that of the employee. In this case, the addresses are at the same
level of nesting: the Addr structure: the persons home address is nested within the Person DSECT
at the position Labeled PAddr. This means that we must provide addressability to two different
Addr DSECTs, as shown in Figure 662.

Chapter XI: Dummy Sections, Enhanced USINGs, and Data Structures

887

* Example 3: Copy Employee Address to Dependent 2 address


AE 6 USING Addr,PE.PAddr
1
PD2 7 USING Person,EDep2
AD2 8 USING Addr,PD2.PAddr
7
MVC

Overlay Addr DSECT on Employee name


Overlay Person DSECT on Dependent 2
Overlay Addr DSECT on Dep. 2 Person

AD2.AddrF,AE.AddrF Copy Employee Addr to Dependent 2


8
6

DROP PD2

Remove all Dependent-2 associations

Figure 662. Copying addresses with an Employee Record

This technique is like that of the previous example: we establish addressability to the instances of
the Addr DSECT within the two instances of the Person DSECT, one for the employee at
EPerson, qualified with PE (1) in Figure 659, and one for the second dependent at EDep2, qualified with PD2 (7).
Within the two instances of the Person DSECT are the two instances of the Addr DSECT, one for
the employee at PE.PAddr, qualified by AE (6), and one for the second dependent at PD2.PAddr
(7), qualified by AD2 (8). The move instruction then uses the address qualifiers AE and AD2
to qualify the names of the field to be moved, AddrF.
The DROP statement specifies qualifier PD2. Because the Labeled Dependent USING with the
AD2 qualifier was based (or anchored) on that with qualifier PD2, dropping PD2 automatically
causes AD2 to be dropped also.

Exercises
39.7.1.(1) + What are the lengths of the Date, Addr, and Phone DSECTs?
39.7.2.(2) + Using the values you found in Exercise 39.7.1, find the lengths of the Person and
Employee DSECTs.
39.7.3.(2) + Assemble a program containing the five DSECTs used in the personnel record and
the statements in Figures 657, 660, 661, and 662. Study the generated object code to see how
the single ordinary USING statement provides a base register for all the instructions.
39.7.4.(2) + Create a definition of a 120-byte data structure named Person containing these
items, where their lengths are shown in parentheses:
Name, consisting of
Family name (20)
Given name (15)
Initial (1)
Address, consisting of
Number (5)
Street name (18)
Apartment number (3)
City (15)
State (13)
Postal ZIP code (5)
1. First, define each field using EQU statements as an offset from the symbol Person.
2. Second, define each field with DS statements.
3. Third, define each field in a Dummy Control Section named Person.
39.7.5.(2) + Suppose the last three statements in Figure 653 are replaced by
DateF

888

Equ

Date,DateL,C C

Assembler Language Programming for IBM z System Servers

Version 1.00

Will all symbols in the Date DSECT have identical attributes? (Write and assemble a short
program to verify your answer.)

39.8. Summary
Enhancements to the USING and DROP statements can help you to write simpler and more
efficient programs.

39.8.1. USING Statement Summary


The Assembler. provides two major extensions to the USING statement: Labeled and
Dependent. They may also be used in combination, as Labeled Dependent USINGs, providing a
choice of four different types of USING statement.
This gives you much greater control over assignment and resolution of base addresses in symbolic
expressions and helps improve the reliability, maintainability, and efficiency of Assembler Language applications.
Labeled USINGs let you simultaneously address multiple instances of a DSECT (or CSECT)
without additional ordinary USING and DROP statements, and without the need to explicitly
code offsets and base registers. Thus, you can concurrently manage multiple copies of the same
DSECT- or CSECT-defined data structure using the full symbolic capabilities of the Assembler Language.
Dependent USINGs let you address multiple DSECTs anchored by a single base register, so
you can describe adjacent, nested, or overlapping code and data structures. This means that
you can reduce the number of general registers required for addressing DSECTs and assign
them to other uses, creating more efficient code while retaining the advantages of fully symbolic addressing.
Dependent USINGs are dynamic because declarations can specify different mappings on different code paths.
Labeled Dependent USINGs combine the benefits of both. For example, you can describe
record structures containing multiple instances of nested substructures, or of substructures that
depend on a variable elsewhere in the containing structure. Such complex data structures are
commonly used in higher level languages; you can use them in your Assembler Language programs.
Heres another way of viewing the difference between Labeled and unlabeled USING statements:
An unlabeled USING requires a register to reference the data; or the base register implies the
data that can be addressed.
For a Labeled USING, the qualified data name implies the register: that is, the qualifier designates a specific base register.
The properties and behavior of the four types of USING statement are shown in Table 419:

Chapter XI: Dummy Sections, Enhanced USINGs, and Data Structures

889

USING
Type

Label

Register
Usage

Operand
1 Based
on

Operand 2

Operand 2
Location in
Storage

Ordinary

No

1 register
per
object

Register

Absolute
[0,15]

Anywhere in
storage

Labeled

Yes

1 register
per
object

Register

Absolute
[0,15]

Anywhere in
storage

Operand
2

Relocatable,
addressable

Addressable by
ordinary USINGs

Multiple active
objects of different types

Operand
2

Relocatable,
addressable

Addressable by
ordinary USINGs

Multiple different
active objects of
the same or different types

Dependent

Labeled
Dependent

No

Yes

Multiple
objects
per register
Multiple
objects
per register

Number of
Instances of
Active Objects
Only one active
instance of an
object at a time
As many active
instances of an
object as registers
assigned

Table 419. Summary of USING Statements

39.8.2. DROP Statement Summary


The DROP statement supports the enhancements to the USING statement, as summarized in
Table 419:
USING Type
Ordinary
Labeled
Dependent
Labeled Dependent

DROP Statement
By register number
By qualifying label (dropping the register has no effect)
By register number (all sub-dependent USINGs are dropped automatically)
By qualifying label (dropping the register has no effect)

Table 420. Summary of D R O P Statement Behaviors

These may be described as follows:


Ordinary USINGs
The normal rules for DROP statements apply, and the entry for the specified register is
removed from the Assemblers Using Table.
Labeled USINGs
The qualifying label from a previous Labeled USING is specified as the operand of the DROP
statement. Only the USING with that qualifier is inactivated; other USINGs specifying the
same base register (if any) are still active.
Dependent USINGs
The syntax of the ordinary DROP statement is used: a register is specified as the operand. Any
further Dependent USINGs based on the same register are automatically dropped at the same
time. The Assemblers Using Table entry for that register is removed.
Labeled Dependent
The qualifying label from a previous Labeled or Labeled Dependent USING is specified as the
operand of the DROP statement. Any dependent or Labeled Dependent USINGs that relied
on the qualifying label are also dropped. Other USINGs specifying the same base register (if
any) are still active.

890

Assembler Language Programming for IBM z System Servers

Version 1.00

Terms and Definitions


DSECT
A Dummy Control Section used to map the components of a data structure.
Ordinary USING
A USING statement directing resolution of unqualified implicit references to a specific base
register or registers.
Labeled USING
A USING statement directing resolution of implicit references to a specific base register. It is
distinguished from an ordinary USING statement by the presence of a qualifier in the name
field.
Dependent USING
A USING statement allowing implicit references to symbols in areas mapped by more than
one control section to be resolved with a single base register.
Labeled Dependent USING
A USING statement allowing implicit references to symbols in areas mapped by more than
one control section to be resolved with by a specific base register.
qualifier
A symbolic identifier defined in the name field of a Labeled USING or Labeled Dependent
USING statement. It may be used only as a qualifier, and not as an ordinary symbol.
qualified symbol
An ordinary symbol prefixed by a qualifier and separated from it by a period, as in
qualifier.symbol.

Chapter XI: Dummy Sections, Enhanced USINGs, and Data Structures

891

892

Assembler Language Programming for IBM z System Servers

Version 1.00

40. Basic Data Structures

44
444
4444
44 44
44 44
44 44
44444444444
444444444444
44
44
44
44

00000000
0000000000
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
0000000000
00000000

In this section we discuss several widely used data structures such as arrays, stacks, lists, queues,
trees, and hash tables.
The data structures used in computer programs are incredibly varied. For most purposes, understanding the simpler forms provides a basis for understanding all of the more complex ones.
The simplest data structure is the table or array, a grouping of elements of uniform type and
length into regularly spaced (and usually contiguous) memory locations. The major advantage
of the array is that the address of an array element can be calculated and the element accessed
directly, rather than searching the array to find the element.
A stack is a specialized form of array, often represented in memory in varied ways.
Other data structures involve multiple elements of (usually) uniform type and length that are not
contiguous or regularly spaced. Dummy Control Sections (DSECTs) and extended USING
statements provide powerful mechanisms for describing, mapping, and manipulating them.
A list or linked list is a linearly ordered structure in which each element contains a link to its
successor.
A queue or doubly linked list is a linearly ordered structure in which each element contains
links to its successor and to its predecessor.
The elements of a tree contain links to zero, one, two, or more successors.
Lists and trees can be used to store data in forms not well adapted to arrays, but their elements
must be searched for, instead of addressed directly.
A hash table provides a method for rapid retrieval of unordered data, by transforming an item
into a pseudo-subscript to locate its value quickly.
We will examine each of these basic structures in turn.272 Because we often arrange data in linear,
rectangular, or other array-like tabular formats, we will first examine some methods used to
manipulate data stored in this form.

272

The classic reference for data structures is Chapter 2 of The Art of Computer Programming, Volume 2: Fundamental
Algorithms, by Donald Knuth.
Chapter XI: Dummy Sections, Enhanced USINGs, and Data Structures

893

40.1. One-Dimensional Arrays


Many examples of loops in Section 22 involved indexing in an array, but we didnt describe
formal techniques for doing indexing arithmetic and selecting initial and final index values.
The most important new concept concerning array manipulation is that we may compute the
position of an element at execution time. Up to now we have discussed many basic assemblytime addressing expressions; now we consider instruction sequences that evaluate more complex
execution-time addressing expressions.
Suppose you have eleven halfword integers to manage as a group; the simplest arrangement is
successive halfwords in memory. Here is an array of halfwords, starting at the halfword named B.

B
B+2
B+4
B+6
B+8
B+10 B+12 B+14 B+16 B+18 B+20
Figure 663. Example of a one-dimensional array of halfwords

One-dimensional arrays are relatively simple: each successive data item or element is accessed by
adding the element spacing (usually, the element length) to the address of the preceding element.
If for example the eleven halfword integers in Figure 663 are stored starting at B, then the n-th
element B n is found at B+2n. That is, if the element with zero subscript (B 0) is found at B, the
address of an element with subscript n is simply B+2*n. If the array elements were fullwords or
doublewords, the corresponding addresses would be B+4*n and B+8*n respectively.
However, arrays may not contain a zero-th element, or the zero-th element may not be the
lowest-numbered element. For programs in many higher-level languages, the first element of an
array has subscript 1. Indeed, if the three low-numbered elements of the array are omitted, so
that B 4, B5, ..., B14 are stored beginning at B, and the length of a single array element is L, then
the n-th element B n is found at address addr(B)+L*(n 4).
We can see how to do the required subscript arithmetic: if the subscripts start at m, and the
lowest-subscripted element B m is stored at B, then the address of element B n is
addr(B(n)) = addr(B)+L*(n-m).
An example will help to illustrate this. Suppose an array of 13 fullword integers X5, X 6, ..., X17 is
stored beginning at XX, and we want to store their sum at XSum. Thus, the array starts with the
element with subscript 5. In Figure 664, we assume that the lower and upper subscript bounds of
5 and 17 are stored at LowerSub and UpperSub respectively. Because there are 13 elements in the
array starting at XX, we could simply add the 13 words. However, we want to illustrate a more
general technique for accessing array elements.
SR
0,0
L
1,LowerSub
SetNdx LR
2,1
S
2,LowerSub
SLL 2,2
A
0,XX(2)
LA
1,1(,1)
C
1,UpperSub
JNH SetNdx
ST
0,XSum
- - LowerSub DC
F 5
UpperSub DC
F 1 7
XSum
DS
F
XX
DC
13F12345

Initialize sum in GR0 to zero


Initialize subscript n to c(Lower)
Index N is calculated in GR2
(n-m)
4*(n-m): element length is 4
Sum = Sum + X(n)
Increment subscript by 1
Compare subscript to upper bound
If not greater, branch to repeat
Store sum
Lower subscript bound
Upper subscript bound
Space for sum
... for example

Figure 664. Sum of array elements with known subscript bounds

894

Assembler Language Programming for IBM z System Servers

Version 1.00

Now, suppose the lower and upper subscript bounds of the elements used in forming the sum
dont have known values like 5 and 17; we only know that the element with subscript 5 (X 5) is
stored at XX. We can then include a portion of the indexing arithmetic into the program at
assembly time. We extract the factor L*( m) from the implied address XX+L*(n-m); m has value 5
in this example, and L has value 4.
SR
LA
L
SLL
L
SLL
AddElem A
JXLE
ST

0,0
4,L XX
2,LowerSub
2,2
5,UpperSub
5,2
0,XX-5*4(2)
2,4,AddElem
0,XSum

Initialize sum to zero


Increment = element length = 4
Get initial (lowest) subscript
Multiply by element length, 4
Get highest subscript
Multiply by length, = 4 also
Add elements starting at X(5)
Increment index and loop
... etc.

Figure 665. Sum of array elements with unknown subscript bounds

In this more-efficient example, we see that if the contents of LowerSub and UpperSub are 5 and 17
respectively, the same result will be obtained as before. The address of the first element to be
added will be XX-20+(4*5), which is the same as XX. The Assembler requires that the location of
the implied address XX-5*4 be addressable; this requirement is sometimes a limitation on the use
of this time-saving technique.
The loop in this program segment needs only two instructions, while the loop in Figure 664 uses
seven. You can often improve the efficiency of array accesses by doing as much subscripting
arithmetic as possible at assembly time.
Even though we usually store arrays with ascending subscripts, the array elements could also be
stored in reverse order, from highest subscript to lowest: you can still calculate the address of
B(n) this way, even if n is not greater than m.

Exercises
40.1.1.(2) Suppose the instructions in Figure 664 had been written so that the lower and upper
subscript bounds were defined instead by the statements
LBound
HBound

Equ
Equ

5
17

Rewrite the three DC statements so that all values depending on the subscript bounds are
defined through references to the symbols LBound and HBound.
40.1.2.(2) + A programmer suggested the following technique as a method of indexing through a
table of words:
GetIt

- - L
0,Table
- - LH
1,GetIt+2
AH
1,=H 4
STH 1,GetIt+2
- - -

Initialize, etc.
Get a table entry
Do something with it
Fetch the addressing halfword
Add 4 to displacement
Replace halfword in instruction
Eventually branch back to GetIt

Assuming that this code sequence contains proper tests for reaching the end of the table, are
there any grounds (other than aesthetic) for criticizing this method of address modification?
40.1.3.(2) An array contains 523 elements. Each element is 7 bytes long: a 2-byte binary integer
followed by 5 characters.

integer
 5 bytes of character data

Chapter XI: Dummy Sections, Enhanced USINGs, and Data Structures

895

Give reasons for or against spacing successive elements of the array 8 bytes apart.
40.1.4.(2) In the example in Figure 665, what will happen if c(UpperSub) is less than
c(LowerSub)?
40.1.5.(2) + Each element of the array of 523 elements in Exercise 40.1.3 should be mapped by
a DSECT; create one.

40.2. Two-Dimensional Arrays


Two- and higher-dimensional arrays present added considerations, but they can be handled easily;
we will examine two simple methods for addressing array elements. In illustrating these methods,
we discuss only the two-dimensional array, or matrix. Figure 666 illustrates a small matrix:

A(1,1) A(1,2) A(1,3) Row 1

A(2,1) A(2,2) A(2,3) Row 2

Column 1
Column 2
Column 3
Figure 666. Typical arrangement of elements of a matrix

The element A i,j in the i-th row and j-th column of a matrix A is often denoted A(i,j). The row
subscript is traditionally given first, followed by the column subscript.
The basic problem is that we rarely know the values of the subscripts i and j at assembly time.
Instead, i and j are variables whose values are determined at execution time, so we must write
instructions using those values to find the address of the array element A(i,j).
First, we must reorganize this rectangular array form into a linear structure conforming to the
machines linear addressing of memory. This can be done in two ways:
Store successive columns of the array one after another. This is called column order or
column-major order, and is used, for example, by Fortran for storing its arrays. If the
column-ordered array A in Figure 666 has two rows and three columns, it would be stored as
shown in Figure 667. Note that the leftmost subscript is cycled most rapidly, so the linear
order of the elements is first column, then second column, etc.

A(1,1) A(2,1) A(1,2) A(2,2) A(1,3) A(2,3)

Figure 667. Storing an array in column order

Store successive rows of the array one after another. This is called row order or row-major
order, and is used, for example, by PL/I for storing its arrays. The same array stored in row
order would appear in storage as shown in Figure 668. Note that the rightmost subscript is
cycled most rapidly, so the linear order of the elements is first row, then second row, etc.

A(1,1) A(1,2) A(1,3) A(2,1) A(2,2) A(2,3)

Figure 668. Storing an array in row order

Either linear arrangement may be used; a choice between possibilities must be based on considerations such as convenience, the time and space required to retrieve a particular element, and (if

896

Assembler Language Programming for IBM z System Servers

Version 1.00

your array-handling instructions will be called from a program written in another language) the
requirements of that programming language.273
To retrieve element A(i,j) of the column-ordered array in Figure 667, we must calculate its
address: suppose A(1,1) is stored at AA. To obtain the address of the first element in the j-th
column, A(1,j), we need the address
addr(AA) + L * (j-1) * 2
where L is the element length in bytes, and the factor of 2 is the number of rows, accounting for
the presence of two elements in each column. Having obtained that address, the address of the
i-th element in the indicated column is found by adding L*(i-1) to the partially computed
address, giving finally an address
addr(A(i,j)) = addr(AA) + L * [ (i-1)+2*(j-1) ]
For example, the address of element A(2,3) is
addr(A(i,j)) = addr(AA) + 2 * [ (2-1)+2*(3-1) ]
= addr(AA) + 10
as we would expect from Figure 667.
The quantity added to addr(AA) is sometimes called a subscripting expression, a subscripting function, or a mapping function. We start with the address of the base element A(1,1) and the array
subscripts i and j of a particular element, and use them to compute the linear subscript that gives
the difference between the addresses of A(i,j) and A(1,1).
If a two-dimensional column-ordered array has r rows, the subscripting function is
L * [ (i-1)+r*(j-1) ]
Our choice of column ordering means that the subscripting function depends only on the number
of rows r of the array, and not on the number of columns.
Suppose a column-ordered array of words having 5
element A(1,1) at AA. We want to retrieve element
and j are contained in fullwords stored at ISub and
been stored in the array at AA by other parts of the
NRow
NCol

ISub
JSub
AIJ
AA

Equ
Equ
L
BCTR
MHI
A
BCTR
SLL
L
ST
- - DC
DC
DS
DS

rows and 7 columns is stored with base


A(i,j) and store it at AIJ. The subscripts i
JSub respectively. We assume values have
program.

5
7
6,JSub
6,0
6,NRow
6,ISub
6,0
6,2
0,AA(6)
0,AIJ

Number of rows
Number of columns
Get column index j
Form (j-1)
Multiply by number of rows
Add row index, i
Decrease by 1 to form ((i-1)+r*(j-1))
Multiply by element length, 4
Retrieve element A(i,j)
Store it at AIJ

F 3
F 6
F
(NRow*NCol)F

Possible value for i


Possible value for j
Element A(i,j) stored here
... Values already placed here

Figure 669. Retrieving a specified element of an array

As in Figure 665 on page 895 for one-dimensional arrays, part of the execution-time subscripting
arithmetic can be absorbed into the assembly-time address of the instruction that references the
array element. To do this, we must know the size of the array (at least, the number of rows, for a
column-ordered array) when the program is assembled. We now see that

273

Many programming language standards require that arrays be stored in a specific ordering of rows and columns.
Chapter XI: Dummy Sections, Enhanced USINGs, and Data Structures

897

addr(A(i,j)) = [addr(AA) - (L*(r+1))] + [L * (i + r*j)].


Only the second square-bracketed expression depends on i and j, so it must be computed at execution time. The instructions in Figure 669 can be rewritten as in Figure 670:
NRow
NCol

Equ
Equ
L
MHI
A
SLL
L
ST

5
Number of rows
7
Number of columns
6,JSub
Column index
6,NRow
* (Number of rows)
6,ISub
+ Row index
6,2
(All this) * (element length)
0,AA-L AA*(NRow+1)(6) c(GR0) = A(i,j)
0,AIJ
Store result at AIJ

Figure 670. Retrieving a specified element of an array efficiently

The address addr(AA)-L*(r+1) is the address of the element A(0,0), which may not actually be a
member of the array. 274 The term virtual origin describes the base element A(0,0), and the term
actual origin describes the address in memory where the array actually begins.
Most programming languages that support arrays allow many more than two dimensions, but the
terms row and column ordering are still used for higher-dimension arrays, even though these
names may seem misleading. (Should the third dimension be called a plane? The fourth dimension a cube or a parallelepiped?) Whatever the terminology, remember that the leftmost subscript
varies fastest for column ordering, and the rightmost for row ordering.
We will assume for now that all subscripts begin at 1, unless stated otherwise.

Exercises
40.2.1.(3) Suppose an N by N array of words is stored starting at SqArray, where N is greater
than 6 and is defined symbolically. Write a sequence of statements that will transpose the array:
that is, for all subscripts i and j, swap element SqArray(i,j) with element SqArray(j,i).
Do you need to know whether the array is stored in row order or column order?
How many swaps are needed?
40.2.2.(3) + There are two symbolically defined integers M and N, both greater than 5, and
M N. Given an N by M matrix of fullwords stored at AA, store at BB the M by N transpose
matrix of the matrix at AA, whose elements are defined by B(i,j) = A(j,i).
Do you need to know the ordering of the array?
40.2.3.(3) + Suppose you are given the address of the actual origin of a column-ordered array,
addr(A(1,1)). You also know the number of rows R and the number of columns C of the array,
and the length L of each element. Suppose the word at ElemAddr contains the address of an
unknown array element A(i,j).
First, write expressions that determine the values of i and j. Then, write instructions that calculate the subscripts i and j, and store them at ISub and JSub respectively.
40.2.4.(2) Row-ordering an array requires that the linear arrangement corresponds to cycling the
rightmost subscript most rapidly, then the next to last, and the leftmost most slowly. Show that
the subscripting function for a two-dimensional array of r rows and c columns is
addr(A(i,j)) = addr(A(1,1)) + L * [ c*(i-1)+(j-1) ].
40.2.5.(4) A physicist needed a table of values of a function S(i,j) for integer values of i = 2, 4,
6, ..., 20, and j = 3, 2, 1, 0, ..., 10. He found that S(i,j) obeys the recurrence relations

274

898

Unfortunately, its sometimes called the base address of the array, which can be confused with the address where
the array starts, or with a base address specified in a USING statement.
Assembler Language Programming for IBM z System Servers

Version 1.00

(a) S(i,j+2) = ((j+1)*S(i,j)+1/(i+j+2))/(j+3)


(b) S(i+2,j) = S(i,j) 1/((i+1)*(i+j+2)),
and that
S(2,-3) = 0.5, S(2,-2) = 0.3068528, and S(2,-1) = 0.23370055.
Write instructions to compute the complete table of 140 values in hexadecimal or binary
floating-point, applying first the relation (a) to compute S(2,j) for j = 0, 1, ..., 10, and then
using (b) to fill out the table.
40.2.6.(3) We can define two norms of a matrix as (1) the sum of the magnitudes of its elements, and (2) as the magnitude of of the largest element. Write a program segment which will
evaluate both norms of a square matrix of short hexadecimal or binary floating-point numbers
stored beginning at Matrix, and the dimension of the matrix is stored as a fullword integer at
MatDim.

40.3. General Array Subscripts


In the examples above we assumed that the subscripts took positive values only, and always had a
lower bound of 1. (This is why our subscripting expressions contain terms like (i-1) and (j-1).)
This is not a necessary condition; if the lower subscript bounds on i and j are i0 and j0 respectively, then the subscripting function for a two-dimensional column-ordered array with r rows
becomes
L * [ (i-i0)+r*(j-j0) ]
and for a two-dimensional row-ordered array with c columns,
L * [ c*(i-i0)+(j-j0) ]
In such cases it may be more difficult to include the constant factor that determines the arrays
virtual origin,
-(L*(i0+r*j0))

or

-(L*(c*i0)+j0))

in an expression at assembly time, since the resulting implied address may not be addressable.
Many high-level programming languages let you define arrays dynamically, so that subscript
bounds and origins are not known until execution time. References to such arrays customarily use
array descriptors containing the necessary information.
Arrays can take many forms. We will examine two: arrays of many dimensions, and arrays whose
columns are not identical.

40.3.1. Multi-Dimensional Arrays (*)


When you use arrays with more than two dimensions, you will need to calculate the linear index
of an element. For example, suppose D is the base element of a three-dimensional columnordered array with R rows, C columns, and P planes (for want of a better name for the third
dimension). Then to access element D(i,j,k) you can generalize the expression given in Section
40.2 as follows:
Addr(D(i,j,k)) = addr(D) + L * [ (i-1) + R*[(j-1) + C*(k-1)] ]
To help understand this expression, consider the element D(1,1,2): to access it starting at
D(1,1,1) you would cycle the i subscript R times, and the j subscript C times, once for each cycle
of the i subscript. Thus,
Addr(D(1,1,2)) = Addr(D) + L * [ (1-1) + R*(1-1) + R*C*(2-1) ]
= Addr(D) + L * (R*C)
where R*C is the number of elements in the first plane, so the accessed element will be the first
one in the second plane as desired.

Chapter XI: Dummy Sections, Enhanced USINGs, and Data Structures

899

In general, if an array A has p dimensions, and the subscripts k1, k2, ..., kp in each dimension
range from 1 to Maxj (where j is the number of subscript kj), then the subscripting function for
an element A(k1,k2,k3,...,kp) is
addr(A(k1,k2,k3,...,kp)) = addr(A(1,1,1,...,1)) +
L * [ (k1-1) + (k2-1)*Max1 + (k3-1)*Max1*Max2 + ... (kp-1)*Max1*Max2*...*Max(p-1) ]
Not obvious, perhaps, but sometimes useful to know!
As we noted in describing subscripts for two-dimensional arrays, the range of values for the rightmost subscript in a column-ordered array isnt used in the subscripting function. That is, for a
two-dimensional array, only the number of rows us important, not the number of columns. For a
row-ordered array, the range of the leftmost subscript is not used in the subscripting function.

40.3.2. Non-Homogeneous Arrays (Tables)


The term table often describes a one-dimensional array in which the columns dont necessarily
contain data items with the same type and length. For example, you might have a table of names
and identification numbers, where the numbers in the first column are 4-byte binary integers and
the names in the second column are 36-byte character strings.
ID Number
14142135
17320508
16180339
28571428
31415926
33550336
22360679
40353607
31622776
24137569
16777215
27182818
11235813

Name
Billy Uss
Norm D. Plume
Anna Lepsis
Carol F. DeBelz
Warren Pease
Sarah Bellum
Pete Moss
Polly Andress
Hugo Furst
Lou Gubrius
Anna Lemma
Dad Gummitt
Polly Connick

Table 421. Example of a non-homogeneous array

The methods for indexing one-dimensional arrays are used to access the rows of such tables; the
increment from row to row is the length of each row (40 in this example).
For example, suppose this table starts at DataTbl and there is an ID number at WhoIsIt. You
want to find the table entry corresponding to that ID number, and put its address in GR1. A
typical code fragment might look like Figure 671. (Note that it doesnt test whether all table
entries have been compared, to indicate theres no matching entry.)
EntryLen Equ
LA
L
Search C
JE
LA
J
FoundIt - - -

40
1,DataTbl
0,WhoIsIt
0,0(,1)
FoundIt
1,EntryLen(,1)
Search

Each table entry is 40 bytes long


c(GR1) = start of data table
c(GR0) = IDNumber being sought
Check for a matching ID number
They re equal, we have a match
Add length of each table entry
And repeat the search

Figure 671. Searching for a matching table entry

Each element in Table 421 might be described by this DSECT:

900

Assembler Language Programming for IBM z System Servers

Version 1.00

ID_Name DSECT ,
IDNumber DS
F
Name
DS
CL36

Dummy Control Section


4-byte integer ID number
36-character name

Because DSECTs generate no object code, you could also write the DSECT with DC statements:
ID_Name DSECT ,
IDNumber DC
F -1
Name
DC
CL36 Dummy Entry

Dummy Control Section


4-byte dummy integer ID number
36-character dummy name

The result is the same in both cases. Using DC statements can be helpful in cases where the
same statements can be included275 in both a CSECT for a declaration and in DSECTs for references.
We can rewrite the example in Figure 671 on page 900 to use the DSECT this way:

Search

FoundIt
ID_Name
IDNumber
Name
EntryLen

LA
Using
L
C
JE
LA
J
- - - - DSECT
DS
DS
Equ

1,DataTbl
ID_Name,1
0,WhoIsIt
0,IDNumber
FoundIt
1,EntryLen(,1)
Search

c(GR1) = start of data table


Base reg for ID_Name data structure
c(GR0) = IDNumber being sought
Check for a matching ID number
They re equal, we have a match
Add length of each table entry
And repeat the search

F
CL36
*-ID_Name

4-byte integer ID number


36-character name
Calculate length of each table entry

Figure 672. Searching for a table entry mapped by a DSECT

The second USING statement tells the Assembler that implicit references to any symbol in the
DSECT ID_Name should be resolved using GR1 as a base register. The USING Table is sketched
in Figure 673:

basereg base location RA

15

00000002 01

00000000 FF  Relocation ID for the DSECT

Figure 673. USING Table with two entries, one for a DSECT

Important differences between Figures 671 and 672 include:


The instruction named Search makes no explicit reference to GR1, but relies on the Assembler to calculate the correct base and displacement.
The second operand is the name of the field, and not its (known) offset in the table entry.
Advantages of this technique include:
Readability: the referenced field is identified by name, so you need not know its offset within
the table entry mapped by the DSECT.
If other data elements are later added to the table entries in the table, only the DSECT needs
to be changed. If explicit base and displacements had been used to reference components of a
table entry, each would have to be found and modified.

275

The COPY assembler instruction statement inserts a block of statements in its place.
Chapter XI: Dummy Sections, Enhanced USINGs, and Data Structures

901

The length of the table entry is calculated by the Assembler from information it knows about
the length of the DSECT.
If new components are added to the table entry, the Equ statement in Figure 671 isnt needed,
because the symbol EntryLen is automatically updated by the Assembler.

Exercises
40.3.1.(2) Do the same as in Exercise 40.2.2, but use no memory locations for temporary
storage. A simple solution will be satisfactory! Optimal solutions to this problem can be
rather complex.
40.3.2.(3) + Given two N by N square matrices of fullword integers stored in column order at
AA and BB respectively, the product matrix CC is defined by
C(i,j) = Sum( for k=1 to N ) [ (A(i,k) B(k,j)) ]
Assuming that N is defined symbolically and is greater than 4, write statements to store at CC in
column order the product matrix whose elements are given by the above rules for a product
matrix. Assume that no overflows occur in calculating C(i,j).
40.3.3.(2) Write the subscripting function for a p-dimensional row-ordered array.
40.3.4.(3) + It often occurs in processing square matrices that a matrix is symmetric: that is,
A(i,j) = A(j,i) for all subscripts i and j. To save space, such matrices are usually stored in
either
upper triangular form, where A(i,j) is not stored if (i>j); or
lower triangular form, where (i,j) is not stored if (i<j).
This saves roughly half the space needed to store the matrix.
For an N by N matrix of elements of length L, determine the subscripting function needed to
retrieve element A(i,j) for each type of triangular matrix.
40.3.5.(3) + Using your solution to Exercise 40.3.4, write instructions that place in GR1 the
address of the element A(i,j) of an upper triangular matrix, given that A(1,1) is stored at AA,
and the quantities i, j, N, and L are fullword integers stored at II, JJ, NN, and LL respectively.
Assume that the subscript values are valid.
40.3.6.(4) Suppose you have an n-dimensional column-ordered array for which the subscripts
range from 1 to Upper_k for each dimension k between 1 and n. Write an instruction sequence
that calculates the linear subscript of an arbitrary element, assuming:
The (1,1,...,1) element of the array is stored at ARRAY.
The subscripts from 1 to k of the desired element are fullword integers stored in an array at
SubScrs.
The upper limits Upper_k for each subscript are word integers stored in an array at
UpperLim.
The number of dimensions is stored in the word at NumDimen.
The length of each array element is stored in the halfword integer at ElLength.
40.3.7.(2) + In some applications involving large matrices, there may be few nonzero elements;
they are called sparse arrays. Instead of allocating storage for all N 2 elements of an N N
matrix, space can be saved by storing only the nonzero elements A(I,J) and their subscripts I
and J.
Suppose there are three linear arrays representing a sparse array A: IVal and JVal contain the
word subscripts I and J of the element stored at AVal, and the number of elements in each
linear array is stored in the word at NbrEls. Write an instruction sequence that forms the transpose of the matrix A. That is, for each element A(I,J), swap I and J.
40.3.8.(0) For fun: deduce the meanings of the ID Numbers in Table 421 on page 900.

902

Assembler Language Programming for IBM z System Servers

Version 1.00

40.4. Address Tables


A second method of array addressing is useful when processing speed is important, and occasionally finds application to arrays of irregularly-spaced or irregular-length data. We precompute
the addresses of portions of the array, and store those addresses in a separate address table or
access table. For example, suppose the addresses of the elements A(1,1), A(1,2), and A(1,3) in
Figure 666 on page 896 are stored as words in a list beginning at ColAddr, as shown in Table
422.
Location
ColAddr

Contents
addr(A(1,1))

ColAddr+4

addr(A(1,2))

ColAddr+8

addr(A(1,3))

Table 422. Array addressing with a table of addresses

The following example uses this table to retrieve element A(i,j) and store it at AIJ.
L
BCTR
SLL
L
L
BCTR
SLL
L
ST

7,JJ
7,0
7,2
6,ColAddr(7)
5,II
5,0
5,2
0,0(5,6)
0,AIJ

Get column index j from JJ


Decrease by 1 for indexing
Multiply by address length, 4
Get address of column j
Get row index i from II
Decrease by 1 for indexing
Multiply by element length, 4
Get A(i,j) from array
Store at AIJ

Figure 674. Creating a table of addresses

An advantage of this scheme is that it avoids the previously required multiplication by the
number of rows. The added expense is (1) the space required for the table, (2) the time required
for forming it, either during assembly or at execution time, and (3) the cost of an additional
memory access.
As a final example, suppose we want to store at AIJ the element A(i,j) of a 5-by-5 array of
fullwords stored in column order at AA. First, we construct a table of column addresses and store
them at AddrTab. If we actually compute the addresses of the first element in each column minus
4 (the length of each element), we can use the subscript i directly without subtracting 1 when
accessing the desired array element.
NRows
NCols

Equ 5
Equ 5
LA
6,NRows
SLL 6,2
LA
5,NCols
LA
9,AddrTab
LA
0,AA-4
StoreAdr ST
0,0(0,9)
AR
0,6
LA
9,4(0,9)
JCT 5,StoreAdr
- - AddrTab DC
(NCols)F

Number of rows
Number of columns
c(GR6) = number of rows
Multiply by element length
c(GR5) = No. Columns = loop count
Beginning address of table
(array address)-(element length)
Store an address in the table
Increase to address of next column
Increase table address to next word
Loop until all addresses computed
Space for column addresses

Figure 675. Creating a better table of addresses

Table 423 shows the tables contents after executing this code segment. The zero subscript in the
elements A(0,j) indicates that one element length has been subtracted from the address of the
beginning of the j-th column of the array.
Chapter XI: Dummy Sections, Enhanced USINGs, and Data Structures

903

Location

Contents

Element
Addressed

AddrTab

addr(AA-4)

A(0,1)

AddrTab+4

addr(AA-4+20)

A(0,2)

AddrTab+8

addr(AA-4+40)

A(0,3)

AddrTab+12

addr(AA-4+60)

A(0,4)

AddrTab+16

addr(AA-4+80)

A(0,5)

Table 423. Example of an address tables contents

Now, we can use this table to retrieve the desired element:


L
L
SLDL
L
L
ST

2,II
3,JJ
2,2
3,AddrTab-4(3)
0,0(2,3)
0,AIJ

Get row index i from II


Get column index j from JJ
Multiply both indexes by 4
Get column address from table
Retrieve the element A(i,j)
Store it at AIJ.

This example gives much faster access to the desired array element. It also uses the SLDL
instruction to take advantage of the fact that the array elements and the entries in the table of
addresses have the same length, which might not be true in general.
The address table can be constructed by the Assembler if the array dimensions are known. The
items in the middle column of Table 423 can be used as operands in DC statements, because the
expression in an A-type constant can be relocatable. Thus, we can generate the same address
table at assembly time.
NRows
Equ
L
Equ
AddrTab DC
DC
DC
DC
DC

5
4
A(AA-L)
A(AA+L*(NRows)-L)
A(AA+L*(NRows*2)-L)
A(AA+L*(NRows*3)-L)
A(AA+L*(NRows*4)-L)

Number of rows
Length of array element
Addr(first column) - L
Addr(second column) - L
Addr(third column) - L
Addr(fourth column) - L
Addr(fifth column) - L

Figure 676. Creating a table of addresses at assembly time

The expressions in the address constants are written so that you need only specify the value of
NRows in the first EQU statement, and the required addresses will be calculated by the Assembler.
The extension of address tables to higher-dimensioned arrays is straightforward. Each subscript is
used in turn to retrieve the address of the next lower-level address table, and the next-to-last subscript accesses a table like the one in Figure 676. The final subscript then accesses the desired data
element. This method is useful when the array cannot be kept entirely in storage, since only the
top-level table and some availability flags need be retained; the lower-level tables and the array
itself can be kept on secondary storage.

Exercises
40.4.1.(2) Create an address table (or address tables) for a three-dimensional array starting at
Box having 3 rows, 4 columns, and 5 planes. Thus, the array element with highest subscripts
is Box(3,4,5).
40.4.2.(2) + Construct an address table for a three-dimensional array A that has maximum subscripts of 4, 7, and 5 for the first, second, and third subscripts, respectively. How do the entries
in the address tables depend on the choice of row-ordering or column-ordering for the array?
40.4.3.(3) Improve the coding of Table 422 and Figure 674 by including factors of L*( m) in
the statements wherever possible.

904

Assembler Language Programming for IBM z System Servers

Version 1.00

40.4.4.(4) Given an N by M array P of fullword integers stored in column order at PP, replace
each element by the average of its four nearest neighbors. That is, calculate
P(i,j) = [(P(i+1,j) + P(i-1,j) + P(i,j+1) + P(i,j-1))]/4
For the edge elements, assume that the missing term (or terms) has value zero.
40.4.5.(3) + A two-dimensional array of fullword integers is stored in column order with element
X(1,1) at XX. The lower and upper bounds for the subscripts in each dimension are word integers stored at Lower1 and Upper1, and at Lower2 and Upper2, respectively. Write a program
segment to load into GR9 the element of the array whose subscripts are the word integers at
Sub1 and Sub2 respectively. That is, the desired element is X(c(Sub1),c(Sub2)).
If the subscripts lie outside the lower or upper bounds, branch to SubsErr.
40.4.6.(2) + Generate the address table in Figure 676 with a single DC statement, retaining the
symbolic definitions of NRows and L.

40.5. Searching an Ordered Array


We must often search an ordered array to find a match for a given value (called the key or search
argument). Once found, that array element may be modified; more often, its index is used to
retrieve associated data in other columns, or in similarly ordered arrays.
For a short array (of perhaps 10 or less elements), it is simplest to search the array linearly. To
illustrate, suppose an array of word integers at AA is arranged in order of increasing values, and
GR2 contains a positive integer. If a match is found between the search argument in GR2 and
one of the array elements, branch to Found with GR9 containing the offset of the matching
element; if no match occurs, branch to NoMatch.
N

Test

Equ
LA
LA
SR
C
JE
JXLE
J

10
10,4
11,4*(N-1)
9,9
2,AA(9)
Found
9,10,Test
NoMatch

Number of table entries


Increment = element length in GR10
Comparand = last element index in GR11
Initial index value = 0 in GR9
Compare c(GR2) to array element
Branch if a match occurs
Increment index, try again
No match found

These instructions make no use of the fact that the array at AA is ordered. If the value in GR2
matches none of the array elements, we always scan the entire array before branching to NoMatch.
We rectify this oversight with one added instruction, as follows:
N

Test

Equ
LA
LA
SR
C
JL
JE
JXLE
J

10
10,4
11,4*(N-1)
9,9
2,AA(9)
NoMatch
Found
9,10,Test
NoMatch

Number of table entries


Increment = element length
Comparand = index of last element
Initial index = 0
Compare c(GR2) to array element
No match if element is too small
Branch if a match occurs
Bump index by 4 and try again
c(GR2) is too big to match

In this example, we will exit from the loop whenever we know the number in GR2 cannot match
an array element. We might make use of the fact that taking the second branch to NoMatch
implies that c(GR2) is greater than any array element.
A major weakness of this linear search technique becomes apparent as the length of the array
increases. If we assume that GR2 contains one of the array elements chosen at random, then on
the average we must compare it to half the array elements to find a match. If the array contains N
elements, we will need an average of N/2 comparisons, which can become fairly expensive if the
array contains (say) 2000 elements.
Chapter XI: Dummy Sections, Enhanced USINGs, and Data Structures

905

There are two good solutions to this problem of rapidly increasing search costs, binary search and
hashing. Hash tables will be discussed in Section 40.10 on page 927.
For large ordered arrays, it is helpful to use the binary search or binary chop method. 276 Rather
than scan through the array in a sequential fashion, we start at the middle. If the search argument
(the key) is less than that array element, we ignore the second half of the array, because all its
elements must exceed the key; if the key is greater than the middle element, we ignore the first
half of the array, because all its elements are smaller than the key.
Next, we compare the key to the middle element of the remaining half of the array. By chopping
off half of the remaining array elements each time, we can greatly reduce the number of comparisons needed. Instead of the previous average of N/2 comparisons needed for a linear search, the
binary chop requires a number close to log 2(N), the base 2 logarithm of N. For an array of 2000
elements, there will be at most 11 comparisons, instead of as many as 2000 and an average of
1000 for a linear search.
We illustrate a binary search in Figure 677, using symbolically-defined registers and values. Its
main feature is two registers symbolically named LP and HP that point to the low-addressed and
high-addressed elements of the portion of the array AA being searched. The sequence of
instructions beginning at Setup determines the address of a byte halfway between the low and
high addresses. Because this midpoint might fall on an incorrect boundary, the NR instruction
aligns the midpoint address properly.
L
*
N
SA
X
HP
LP
M
*

Equ

Length of an array element, which...


...must be a power of two (for mask)
Number of array elements
Search argument register (key)
Indexing register
High-address pointer register
Low-address pointer register
Mask register (will contain -L)

Equ 2000
Equ 2
Equ 1
Equ 3
Equ 4
Equ 0
Initialize
LHI M,-L
-L used as mask and increment
L
LP,=A(AA)
Initial low pointer
L
HP,=A(AA+L*(N-1)) Initial high pointer
*
Set midpoint address
Setup
LR
X,HP
Move high pointer, ...
SR
X,LP
... - low pointer = portion size
JM
NoMatch
No match if pointers have crossed
SRL X,1
Halve size to get midpoint index
NR
X,M
Mask for proper alignment
*
Compare, and adjust the pointers
C
SA,0(X,LP)
Compare to selected element
JE
Matched
If equal, found a matching element
JL
Lower
Branch if below midpoint
LAY LP,L(X,LP)
Move low pointer upwards
J
Setup
And test for finish
Lower
LAY HP,-L(X,LP)
Move high pointer downwards, ...
J
Setup
And test for finish
*
Construct address of the item we found
Matched LA
9,0(X,LP)
Set addr of matched element in GR9
J
Found
And go away happy
Figure 677. Example of a binary search

The last two instructions place the address (rather than the index) of the matching element into
GR9.

276

906

You can impress your mathematically inclined friends by calling it the Bolzano-Weierstrass Algorithm.
Assembler Language Programming for IBM z System Servers

Version 1.00

There are many ways to sort arrays of data items, some very simple and some quite complex.277
For small arrays, you can use a simple exchange sort:
Take the first element and compare it to the second. If the first is larger, exchange them.
Now, compare the second and third, and again exchange them if the second is larger than the
third.
Continue this way until the last two elements have been compared (and possibly exchanged).
The largest element will now be in the last element of the array.
Start again with the first element, but continue only to the next to last item; this will become
the second-largest item in the array.
Repeat these steps until you have compared and exchanged only the first two elements; the
first element will then be the smallest in the array.
The number of comparisons in an exchange sort is proportional to the square of the number of
elements, so it should be used only for very small arrays.

Exercises
40.5.1.(1) If we must search through an entire two-dimensioned array for some value, is it preferable for the array to be stored in row order or in column order?
40.5.2.(2) Suppose the array AA in Figure 677 was ordered in descending order (the wrong
way). What will happen?
40.5.3.(3) In Figure 677 we assumed that the byte length of an array element was a power of
two: in this case, 4. Rewrite the code sequence assuming that the length of an array element is
contained in the word at ElemLen. To simplify, assume also that the part of the element to be
matched will be fullword-aligned at the start of the element.
40.5.4.(2) Suppose an ordered array contains both positive and negative values. Write a code
sequence that takes advantage of this fact by searching the array sequentially in a forward direction if the search argument is negative, and in a backward direction if it is positive.
40.5.5.(3) Assume the same ordered array as in Exercise 40.5.4. Write instructions that take
advantage of this fact to improve a binary search. What improvement do you expect?
40.5.6.(3) + Given an array of N word integers stored at Data, write instructions to sort the
integers using an exchange sort.
40.5.7.(3) What will happen if you do a binary search for an element in an array that is not
strictly ordered? Give an example.
40.5.8.(3) The discussion of an exchange sort above says that the number of comparisons is
proportional to the square of the number of elements. Give a more precise estimate.
40.5.9.(3) Suppose we must search an ordered array at Data that contains 2000 elements, each
53 bytes in length. The first 30 characters of an array element hold a name, and the remaining
23 bytes contain related data. The 30-byte search argument to be sought in the array is at SArg
a branch to Found is to be made with the address of the matched element in R9, or to None if
no match occurs. Write instructions to perform a binary search of the array, matching on the
30-character name.
40.5.10.(2) Compare the instructions you wrote in Exercise 40.5.9 to the following, and determine which is more efficient for an array of 2000 elements. Assume that matches are equally
likely for all elements.

277

The classic reference for sorting and searching is The Art of Computer Programming, Volume 3: Sorting and
Searching, by Donald Knuth.
Chapter XI: Dummy Sections, Enhanced USINGs, and Data Structures

907

LA
L
* ..(Largest
L
L
LA
Test
CR
JNL
CR
JL
CLC
JE
JH
Low
SR
J
Hign
AR
ChkEnd CR
JL
SRL
J

0,53
Element length, for compares
3,=A(1024*53)
Initial increment = (El Length)*..
power of 2 contained in (number of elements))
1,=A(Data)
Bottom address
2,=A(Data+53*2000) Top address, after last element
9,0(1,3)
Set initial compare address
9,2
Check addr against top
Low
If off top, subtract increment
9,1
Check addr against bottom
High
If off bottom, add increment
SArg(30),0(9)
Compare search arg to element
Found
Branch out if that s it
High
Jump if arg bigger than element
9,3
Subtract current increment
ChkEnd
Jump to test for end
9,3
Add current increment
3,0
Compare increm to element length
None
If smaller, no match
3,1
Halve increment
Test
And try again

What modifications would be required to these instructions if we wanted to scan an array containing (1) 3 elements, (2) 2047 elements, (3) 2048 elements?
40.5.11.(3) + In Figure 677 on page 906, the search argument is in a register and the array AA
was a table of word integers. Revise the instructions in Figure 677 assuming the array contains
the addresses of character strings of length SL and your search argument is the address of a
similar character string.
In this case, the strings can be anywhere in storage, but their addresses in the array AA refer to
them in sort order.

40.6. Stacks
Unlike an array, which usually contains a fixed number of elements, stacks, linked lists, and trees
usually contain varying numbers of elements. They are dynamic data structures, containing different numbers of elements as your program executes. Also, the organization of an array is tightly
constrained, usually to a contiguous grouping of elements. (If it wasnt, we couldnt use efficient
addressing expressions!) Stacks can be organized somewhat more loosely, while linked lists and
trees may be quite disjointed in their arrangement in memory.
A stack, as its name implies, is a data structure to which elements are added, and from which
elements are removed, at the top. The requirement that data be added and removed at only one
end is a characteristic property of a stack.
The terminology describing stack operations helps us visualize what is happening. When an
element is added to the top of the stack, the other elements are pushed down one level; hence
the name push-down stack. Similarly, removing an element from the top allows the others to
pop up one level.

40.6.1. An Example Using a Stack


Stacks can be used to convert expressions from their familiar infix form 278 such as 2+3*5, to a
form more readily adapted to evaluation or (as in a compiler) code generation. For example, the

278

908

Our traditional form of writing arithmetic expressions puts the operators between operands, with parentheses to indicate sub-expressions. Two forms more convenient for computer processing are the prefix and postfix notations. Both
involve the use of stacks.
Assembler Language Programming for IBM z System Servers

Version 1.00

expression 2+3*5 is by convention the same as 2+(3*5), because we assign a higher priority to
multiplication than to addition. This form of expression is inconvenient for direct evaluation: if in
scanning this infix expression from left to right, we might place the value 2 in a register and
prepare to add it to something, we would find that the something should have been evaluated
first. It helps to have converted from the standard infix notation to an operator suffix or postfix
form, but we wont show how to do that conversion here.
To evaluate an expression in postfix form, two simple rules are used. When an operand is
encountered in the left-to-right scan, its value is pushed onto the stack, and when an operator is
encountered, the top two elements of the stack are removed, the operator is applied to them, and
the result is pushed back onto the stack. For example, the infix expression 9*3+2 becomes 93*2+
in postfix form, and is evaluated this way:
1. Push 9 and then 3 onto the stack;
2. Remove them and apply the * operator, and place the result 27 back on the stack;
3. Push 2 onto the stack;
4. Remove the two values 27 and 2 from the stack, apply the + operator, and push the result 29
back onto the stack.
The stack now contains a single element, the value of the expression.
The infix expression 3+5*7 is represented in postfix notation as 357*+, so that all three operands
are on the stack before the * operator is applied. The value of the expression will be (5*7)+3, or
38. If the infix expression had been written (3+5)*7, its postfix equivalent would be 35+7*,
implying a very different order of evaluation: the operands 3 and 5 are stacked and then replaced
by their sum 8; the operand 7 is pushed onto the stack, and then the * operator replaces the 8 and
7 by 56, the value of the expression.

40.6.2. An Example Implementing a Stack


The simplest implementation of a stack uses two items: a linear array of elements, and a stack
pointer that may be either the subscript or the address of one of the array elements. By convention, the stack pointer locates the element on top of the stack. For example, Figure 678 shows a
stack containing the values 9, 2, and 6. It might be represented in memory as the first three elements of an array of fullwords.

Stack
9
 bottom element

stack pointer
6
 top element


 higher addresses
Figure 678. A stack growing toward higher addresses

The element 6 is at the top of the stack, and the element 9 is at the bottom.
We might implement this stack by allocating an array of 20 fullwords at Stack, and carrying the
index of the top element in GR1.

Chapter XI: Dummy Sections, Enhanced USINGs, and Data Structures

909

SP
EQU 1
StkSize EQU 20
LM
2,4,=F 9 , 2 , 6
STM 2,4,Stack
LA
SP,8
- - Stack
DS
(StkSize)F

GR1 contains stack pointer


Stack size (20 elements maximum)
Initialize with 3 elements
Put 3 items onto stack
Set index of stack top to 3rd word
Allocate space for the stack

Figure 679. A stack implemented as an array

Now, suppose the number in GR0 is to be pushed onto the stack: we simply increment the stack
pointer and store GR0 using the new index.
AHI
ST

SP,4
0,Stack(SP)

Increment stack pointer by 4


Store value at new top position

Figure 680. Pushing a data item onto a stack

If we think of the stack as an array, we have simply increased the subscript denoting the stack
pointer by one; this is a common way to visualize a stack.
To remove an element from the stack, we need only move the stack pointer down one element,
toward the bottom of the stack. Nothing need be done to the old top element, since it is now no
longer a part of the stack.279
AHI

SP,-4

Remove top element from the stack

Now, suppose we want to replace the two elements at the top of the stack by their sum. We can
do this by (1) popping the top two elements off the stack, (2) adding them, and (3) pushing the
sum back onto the stack.

*
*

L
AHI
A
AHI
AHI
ST

0,Stack(SP)
SP,-4
0,Stack(SP)
SP,-4
SP,+4
0,Stack(SP)

Retrieve top stack element


Now delete it from the stack
Add the new top element
(**) Remove it from the stack
(**) Push the sum back on the stack
Store new top element

Figure 681. Adding top two elements of a stack

The second and third AHI instructions (marked (**) in the comment statements) arent
needed: their actions mutually cancel. Because we know that something will immediately go back
onto the stack, it is safe to omit those two statements and leave the stack pointer momentarily
referring to an element that was removed.
Because we may want to refer to several elements at the top of the stack, we can take advantage
of the z System base-displacement addressing structure by placing the bottom of the stack at the
highest-addressed element.

279

910

There may be situations where you will want to erase or remove the data left in deleted stack elements, to protect the
data from being visible to other programs using the same stack (or peeking at activities in your program).
Assembler Language Programming for IBM z System Servers

Version 1.00


 lower addresses

stack pointer
6
 top element

9
 bottom element

Stack
Figure 682. A stack growing toward lower addresses

The advantage of using instructions with nonnegative displacements may not be needed if you can
access your stack elements using long-displacement instructions.
Pushing and popping are done as in Figure 681, except that the stack pointer now moves (arithmetically) in the opposite direction. We can refer to elements at and below the top of the stack
using nonnegative displacements for instructions referring to the stack via the stack pointer. The
example in Figure 683 evaluates the same sum as in Figure 681, except that the stack pointer now
contains the address of the stack top rather than its index.
SP
EQU 1
StkSize EQU 20
- - L
0,0(,SP)
A
0,4(,SP)
ST
0,4(,SP)
LA
SP,4(,SP)
- - DS
(StkSize)F
Stack
DS
0F

Register GR1 contains stack pointer


Stack size
Program puts data on stack
Get top stack element
Add next-to-top element
Store sum at next-to-top position
Pop stack once to adjust
Define space for stack elements
Define stack name just past bottom

Figure 683. Add top two elements of a stack

Because we assigned the stack name to the first element position past the bottom of the stack, all
legal values of the stack pointer in GR1 must be less than the address of Stack. We can use this
property to test for the possibility of stack underflow, which occurs when too many elements have
been removed from the stack. If the pointer is greater than or equal to the address of Stack, an
underflow is indicated.

UStack

LA
SP,4(,SP)
CL
SP,UStack
JNL UndrFlow
- - DC
A(Stack)

Pop an element off the stack


Compare to underflow address
Branch to error routine if underflow
One past bottom of stack

Similarly, we can test for the possibility of stack overflow (too many elements have been pushed
onto the stack).

OStack

AHI SP,-4
Push stack pointer one element
CL
SP,OStack
Check against stack overflow address
JL
OverFlow
Branch to overflow error routine
ST
0,0(,SP)
It s safe to store on the stack
- - DC
A(Stack-StkSize*L Stack) Overflow-test address

Checking for possible error conditions in manipulating stacks is strongly advised.


All these examples of stacks have used arrays as the underlying data structure. In Section 40.8, we
will see how a linked list can also provide the structure needed to implement a stack.

Chapter XI: Dummy Sections, Enhanced USINGs, and Data Structures

911

Exercises
40.6.1.(1) Given the stack arrangement in Figure 682, which of the following statements cannot
be used to push a new element on the top of the stack, and why?
(a)

ST
AHI

0,Stack-4(SP)
SP,-4

(b)

AHI
ST

SP,-4
0,Stack(SP)

(c)

ST
AHI

0,Stack(SP)
SP,-4

40.6.2.(1) Using the stack illustrated in Figure 682 and the instruction sequence in Figure 683,
write instructions to initialize the stack and the stack pointer to the contents shown in Figure
682.
40.6.3.(1) In Figure 678, an element can be pushed on the top of the stack by writing code as in
Figure 680, or by writing
ST
LA

0,Stack+4(SP)
SP,4(,SP)

Is one method preferable to the other? Why?


40.6.4.(2) + Show the result of evaluating the following postfix expressions, and show the contents of the operand stack at each step.
(a)
(b)
(c)

7 3 2 5 * * *
7 3 2 * 5 + *
7 3 + 2 5 * *

What would these expressions look like in infix notation?


40.6.5.(3) + Suppose a postfix expression is represented in memory as an array of pairs of
halfword integers. The first integer of the pair is a code describing the second integer: if the first
integer is 0, the second is an operand; if the first is +4, the second is an operator; if the first is
-1, it indicates end-of-expression. The values used to indicate operators are 0 for + , and + 1
for *. Thus the expression 234*+ is represented by the integers
0, 2, 0, 3, 0, 4, 4, 1, 4, 0, -1.
Assuming that this representation is stored in an array at Expressn, write a program segment
that will evaluate the expression and leave its value in GR1.
40.6.6.(3) + Extend your solution to Exercise 40.6.5 to include tests for valid operator codes and
for the possibility of stack overflow and underflow. Also, allow for subtraction and division,
which have operator codes +2 and +3 respectively.
For subtraction, treat the stack top as the minuend, the number to be subtracted from the
element below it; and for division, treat the stack top as the divisor and the element below it as
the dividend.
40.6.7.(3) + Show how two stacks of word elements Stk1 and Stk2 can be built in a single array
A of N words, in such a way that either stack could use all N words if the other stack is empty;
the two stacks grow from each end of the array toward each other.
Show how to implement Push1, Push2, Pop1, and Pop2 routines that will push and pop elements onto and from either stack, being careful to detect overflow and underflow conditions for
each stack.

912

Assembler Language Programming for IBM z System Servers

Version 1.00

40.7. Lists
Most people use the word list to mean a linear table of items, like a shopping list. In
computer-speak, a list has a more specific meaning.
The basic element of a linked list has two components, a data field and a link field. The data
field may contain more than one data value. The link (or successor or chain) field contains a
pointer to the next list element; the pointer may be its address, its offset relative to the current
element, its array subscript, or whatever is appropriate to the application. Often, the actual
address is used, especially when new list elements are allocated from available memory.
List head
List tail

link link link null

data
data
data
data

Figure 684. Sketch of a linked list

There are two ends to a list. The first element is sometimes called the head; it has no predecessor;
and the last element, the tail, has no successor. The absence of a link in the link field of a list
element is usually indicated by storing a special and easily identifiable null value such as 0 or 1.
Two basic operations on linked lists are insertion and deletion.

40.7.1. List Insertion


Suppose we have a list with elements E1 and E3 as shown in Figure 685, and we want to insert
element E2 between them.

E1 E3

E2

before
patiently awaiting insertion

E1
E3 after

E2

Figure 685. Inserting an element into a linked list

The insertion proceeds in two steps:


1. Move the link field pointing from E1 to E3 into the link field of E2, so that E2 now points
to E3.
2. Store a link pointing to E2 into the link field of E1.
E3 is not referenced during the insertion, only the link to it from E1.
To illustrate, suppose a list element consists of two successive fullwords, the first containing the
link and the second containing the data, as illustrated in Figure 684. (The link could be the actual
address of the successor element.) Suppose also that GR1 contains the address of E1, and GR2
contains the address of E2. First, well do this without using a DSECT:
Link

Equ
L
ST
ST

0
0,Link(,1)
0,Link(,2)
2,Link(,1)

Offset of link field in list element


Copy Link(E1) into GR0
Link E3 to E2
Now link E1 to E2

Figure 686. Example of inserting an element into a linked list


Chapter XI: Dummy Sections, Enhanced USINGs, and Data Structures

913

These instructions will work correctly even when E1 is the last element and E2 is to become the
new tail, because the previous link field of E1 was a null link.
The example in Figure 686 uses explicit addresses in the three instructions. Now, we define a
DSECT to describe the list element:
List_El
Link
Data
Elem_Len

DSECT
DS
DS
Equ

,
A
XL20
*-List_El

Describe a linked list element


Link address to successor
20-byte Data field
Length of a list element

Figure 687. DSECT describing a list element

We will use the DSECT mapping for each reference to a list element. It has the benefits of
DSECT mappings while letting the Labeled Using statements direct symbol resolutions to specific
registers; E1 and E2 are symbol qualifiers.
E1
E2

Using
Using
L
ST
ST
Drop

List_El,1
List_El,2
0,E1.Link
0,E2.Link
2,E1.Link
E1,E2

Map the E1 list element


Map the E2 list element
Load link to E3 from E1
Store link to E3 in E2 s link field
Store link to E2 in E1 s link field
DROP both Labeled Usings

Figure 688. Mapping multiple list elements with Labeled USINGs

This is much simpler (and clearer) than similar statements based on Ordinary USING statements.

40.7.3. List Deletion


Removing an element from a list is very simple. To delete E2 from its position between E1 and
E3, move the link field from E2 into the link field of E1, replacing the previous link to E2.

E1 E2 E3

E1 E2 E3

before

after

Figure 689. Deleting an element from a linked list

First, we delete E2 assuming the same register contents and definition of the Link offset as in
Figure 686:
L
ST

0,Link(,2)
0,Link(,1)

Link from E2 to E3 in GR0


Now link E1 directly to E3

Figure 690. Example of deleting an element from a linked list

These instructions work even when E2 is the last element of the list, because the link field of E2
(which then becomes the link field of E1) is then a null link.
With Labeled USINGs, the instructions in Figure 690 can be written as in Figure 691, where all
symbol references are implicit.
E1
E2

Using
Using
L
ST

List_El,1
List_El,2
0,E2.Link
0,E1.Link

Map the E1 list element


Map the E2 list element
Load link from E2 from E3
Store link to E3 in E1 s link field

Figure 691. Example of deleting an element from a linked list

914

Assembler Language Programming for IBM z System Servers

Version 1.00

As your data structures become more complex, Labeled USINGs and qualified symbols let you
write much clearer code.
These brief examples raise three questions that well need to answer:
1. Where do list elements come from? For example, Figure 685 shows a new element E2
without indicating how it was created.
2. When an element is deleted, what happens to it? In Figure 689, element E2 has no link
pointing to it; is it lost?
3. How do you find the first element (the head) of the list? In Figures 685 and 689, how should
we find E1?
The simplest answers to these questions are a free storage list and a list header or anchor.

40.7.4. Free Storage Lists


There are may ways to obtain new list elements. Requesting the needed bytes from the programs
operating environment each time you need a new element can be expensive, so the more usual
technique is to create a Free Storage List, or FSL. The program first acquires memory to hold
enough list elements for the application, either by defining space at assembly time or by
requesting the memory space when the program starts. For simplicity, our examples will define
the FSL at assembly time.
The FSL initially contains all the unused and available list elements in a single list. As elements
are needed for other lists, they are removed from the FSL, and as elements are deleted from other
lists, they are added back onto the FSL.
To define a free storage list of 20 two-part elements like the one in Figure 687, we could write
NLstItms
FSLCount
FSLHLink
FSLTLink
*
FSLHead
FSLTail

Equ
DC
DC
DC
DC
DC

20
Number of items on free storage list
A(NLstItms)
Count of free-storage list items
A(FSLHead)
List anchor: link to head element
A(FSLTail)
List anchor: link to tail element
Now, define the FSL
(NLstItms-1)A(*+Elem_Len-4,0,0,0,0,0) All but FSL tail
(Elem_Len/4)A(0) Tail element with null link field

Figure 692. Defining a free storage list as an array

Figure 692 shows why it may be better to initialize a FSL at execution time. The statement
named FSLHead required knowing the number of words in a list element, and the Assembler,
Linker, and Program Loader must process blocks of list elements. Also, the number of elements
in the FSL might be specified at execution time, when more elements can be added to the FSL as
needed.
We can also initialize a FSL at execution time, as shown in Figure 693:

FSLoop

Using
L
LA
LA
ST
LR
JCT
ST

List_El,1
1,FSLHLink
0,NLstItms-1
2,Elem_Len(,1)
2,Link
1,2
0,FSLoop
0,Link

Map the elements of the FSL


Point to first list element
Count (no. elements)-1 in GR0
Addr of next element
Store link in this element
Move next addr to this
Repeat for all but last
Store 0 for null link in tail

Figure 693. Initializing a free storage list as an array

Chapter XI: Dummy Sections, Enhanced USINGs, and Data Structures

915

A simple way to locate the head element of a list is to maintain a separate list anchor whose
location is known, and that points to the first (head) element on the list. If the list anchor contains a null link, the list it anchors is empty; otherwise it points to the head element.280
In addition to a pointer to the first list element, the list header might contain a count of list elements and a pointer to the last element in the list. Figure 694 illustrates such a list anchor.

Count of list items

link to first item

link to last item

Figure 694. Example of a list anchor

The free-storage list anchor can be mapped by its own DSECT:


FSLDSECT
FSLCount
FLSHLink
FSLTLink

DSect
DC
DC
DC

,
A(0)
A(0)
A(0)

Map a free storage list anchor


Count of list items
Link to head element
Link to tail element

Figure 695. DSECT mapping a list anchor

The count of list items field and the link to the list tail are optional, but they can help if you
need to know how many items are in the list. Also, keeping a count of the number of free elements makes it easier to know when you may need to allocate more free elements. These fields
can also help you check to make sure no list elements have vanished.281 The link to the last item
is useful if you need to insert an item at the end of the list, so you wont have to search the entire
list to find the last element.
If your program needs frequent access to the list anchor and a general register is readily available,
you can keep the anchor in a register and never need to store it.
An anchor for a working list could take the same form as the anchor for the FSL shown in
Figure 692:
WorkList
LstCount
LstHLink
LstTLink

DSECT
DC
DC
DC

,
A(0)
A(0)
A(0)

Map a free storage list anchor


Count of list items
Link to head element
Link to tail element

Figure 696. Defining an anchor for a working list

As items are taken from the FSL and added to the working list, the fields of the list anchor are
updated. For example, suppose we remove an element from the FSL defined in Figure 692 and
insert it at the head of the working list shown in Figure 696:

280

281

916

Sometimes it is convenient to include the first list element in the list anchor. Then, the list is never empty, and the
function of the list head is performed by the list anchor.
Leaving chunks of previously referenced and now inaccessible storage (known as memory leaks) is a very poor
programming practice. Some programming languages provide garbage collection, but garbage collectors still must
know what can safely be collected and what cannot.
Assembler Language Programming for IBM z System Servers

Version 1.00

- - Using
LT
JNP
L
Using
L
ST
BCTR
ST
- - Using
L
ST
ST
L
AHI
ST
Drop

FSLDsect,9
0,FSLCount
NoneLeft
1,FSLHLink
List_El,1
2,Link
2,FSLHLink
0,0
0,FSLCount
WorkList,5
2,LstHLink
1,LstHLink
2,Link
0,LstCount
0,1
0,LstCount
9,5

c(GR9) = A(FSL anchor)


Mapping of the FSL anchor
Check count of free elements
Must take some corrective action
Link to first free element in GR1
Map the new list element
Link to next free element in GR2
Previous 2nd element becomes head
Subtract 1 from availability count
Store updated free-element count
Assume c(GR5) = A(work list anchor)
Mapping of the FSL anchor
Get link to current work list head
Link to new list-head element
Old head becomes second element
Get current working list count
Increment by 1
Restore updated working list count
Release mappings of list anchors

Figure 697. Moving a list element from the FSL to the working list

GR1 will contain the address of the newly acquired WorkList element.
Removing an element from the working list and returning it to the FSL uses a similar sequence of
instructions.
The sum of the element counts in FSLCount and LstCount should always be the same as the
number of items originally on the FSL.
Sometimes its useful to link the list tail back to the list head, making the list circular. (See Exercises 40.7.2 through 40.7.6.)
If we restrict list insertion and deletion to the head element, we have an implemented a stack!
This can be useful in applications where a stack must share or compete for space with other list
structures, because you can allocate stack elements as needed.
The examples in Figures 692 and 693 used addresses as links. Another way to implement a linked
list is with a two-column array as the underlying structure. To illustrate, suppose we have an
array of NLItms rows and two columns: the first column contains a link index to a successor
element, and the second column holds the data for that element. Figure 698 shows how this
might look:
Index

Link
Data

... :
:
:

NLItms

Figure 698. A two-dimensional array to implement a linked list

We need two additional values: HeadNdx, the index of the first element in the working list, and
FreeNdx, the index of the first element of the free-element list. First, we initialize the list so that
all elements are on the free list:
1. Set HeadNdx to zero (no elements in the list).
Chapter XI: Dummy Sections, Enhanced USINGs, and Data Structures

917

2. Set FreeNdx to 1.
3. Set each Link to the index of its successor, except the last, which is set to zero to indicate the
end of the free list.
The list would then look like this:
Index

Link
Data
HeadNdx = 0

 FreeNdx = 1

... :
:
:

NLItms
0

Figure 699. Initializing a two-dimensional array implementing a linked list

Exercises 40.7.10 through 40.7.14 use this form of a linked list.

Exercises
40.7.1.(2) In Figure 697, what will happen to the fields of the working list anchor at LstAnchr if
deletions remove all list elements?
40.7.2.(1) Write instructions to initialize a circular free storage list.
40.7.3.(2) Write instructions to add an element to the end of a circular list.
40.7.4.(2) Write instructions to remove an element from a circular list.
40.7.5.(2) + Suppose you have implemented a circular list without maintaining a count field in
the list anchor. How can you tell when the list is empty?
40.7.6.(2) + Suppose you have implemented a circular list without maintaining a count field in
the list anchor. How can you tell when you have processed all the elements in the list?
40.7.7.(2) Rewrite the instructions in Figure 697 to delete the head element of the working list
and return it to the FSL.
40.7.8.(3) Write an instruction sequence to take a new element from the FSL and add it to the
tail of the working list.
40.7.9.(3) Write an instruction sequence to take an element from the tail of the working list and
return it to the FSL.
40.7.10.(2) In Figure 698, suppose the link field of each row is a word integer, and the length of
the data field is DataLen bytes, which has been defined symbolically and is a multiple of 4.
Write statements to allocate an array of NLItms rows (also defined symbolically), starting at
ArrStack.
40.7.11.(3) Using the definitions in your solution to Exercise 40.7.10, write a sequence of
instructions that will initialize the list at ArrStack as shown in Figure 699, and initialize the
values of HeadNdx and FreeNdx.
40.7.12.(3) Assume a list has been initialized as shown in Figure 699, and that the values of
HeadNdx and FreeNdx have been initialized also.

918

Assembler Language Programming for IBM z System Servers

Version 1.00

First, show the steps needed to take an element from the free list referenced by FreeNdx and
assign the index of this new element to NewNdx, and update FreeNdx appropriately.
Then, write a sequence of instructions to do these steps. If no free elements are left, branch to
NoneLeft.
40.7.13.(3) Suppose two data elements have been added to the list shown in Figure 699, where
the second element was added to the end of the list. Now, you need to add a new element with
index NewNdx to the list, after the existing element in the list with index PrevNdx.
First, show the steps needed to put the new element into the list at the specified position.
Then, write a sequence of instructions to do these steps.
40.7.14.(3) Suppose several elements have been added to the list shown in Figure 699, and you
need to remove the element with index CurrNdx and return it to the free storage list.
First, show the steps needed to remove the specified element from the list and return it to the
free list, and updating the working list to account for the removed element.
Then, write a sequence of instructions to do these steps.
40.7.15.(2) + Suppose the free storage list in Figure 692 on page 915 had been defined by
writing
FSLAnchr DC
DC
FSLHead Equ

A(FSLHead)
(Elem_Len/4)A(0),(NLstItms-1)A(*-4,0,0,0,0,0)
*-Elem_Len

How would instructions using this new list differ from those using the list in Figure 692?
40.7.16.(2) + Write a code sequence that obtains a list element from a free storage list anchored
at FSL and inserts it at the head of a list anchored at ListHead. If the free storage list is empty,
branch to AllOut.
40.7.17.(3) + Do as in Exercise 40.7.16, with this added requirement: the fullword integer at
DataInt is stored in the data field of the new element, and the new element is then inserted into
the list at a position where its data value exceeds none of its predecessors. That is, the list must
be arranged in descending order of data items.

40.8. Queues
Linked lists occur in many forms; an important form uses double chaining. We saw in the previous examples that simple lists can be scanned only in the forward direction, starting at the
head and chaining toward the tail.
It is often useful to be able to move in both directions, so the list elements must contain both a
forward link and a backward link. We call this doubly-chained structure a queue; elements can be
added and removed at both ends of such a list.
Figure 700 illustrates the structure of a queue element:

 predecessor link

successor link

data field

Figure 700. Structure of a queue element

A queue element contains links to its predecessor and successor elements (sometimes called
forward and backward links), as sketched in Figure 701.

Chapter XI: Dummy Sections, Enhanced USINGs, and Data Structures

919

 predecessor link  predecessor link  predecessor link

successor link successor link successor link

data field

data field

data field

Figure 701. A queue with several elements

Adding and deleting list elements other than the head or tail is more complicated than for singlylinked lists, because four links involving three elements must be manipulated. For example,
suppose we have defined a DSECT describing the queue elements with these statements:
Q_El
LLink
RLink
ElemData

DSECT
DS
DS
DS

,
A
A
XL(DataLen)

Mapping of a queue element


Link to (left) predecessor element
Link to (right) successor element
Space for the element s data

Figure 702. DSECT structure of a typical queue element

Now, suppose also that we have located two elements of the queue pointed to by GR2 and GR3,
and we want to insert the new element pointed to by GR5 between them, as in Figure 703.
GR2
GR3



 LLink
 LLink

RLink
RLink

ElemData
ElemData

Left element
Right element

GR5


ElemData

New element

Figure 703. An element to be inserted into a queue

After the new element has been inserted, we want the result to look like this, where the links that
must be changed during the insertion process are indicated in Figure 704 by the numbered keys
1 and 2 (the left links), and by 3 and 4 (the right links).
1 2
 LLink
 LLink
 LLink

RLink
RLink
RLink

3 4
ElemData
ElemData
ElemData

Left element
New element
Right element
Figure 704. A queue after insertion of a new element

Four steps are needed to do the insertion:


1. Copy the LLink (predecessor link) field from the Right element into the LLink field of the
New element (1). The predecessor of New is now Left.
2. Store a LLink to the New element into the LLink field of the Right element (2). The
predecessor of Right is now New.
3. Copy the RLink (successor link) field from the Left element into the RLink field of the New
element (3). The successor of New is now Right.
4. Store a RLink to the Right element into the RLink field of the New element (4). The
successor of New is now Right.

920

Assembler Language Programming for IBM z System Servers

Version 1.00

If we use actual addresses as the links, we could do this (where the numbered steps above are
shown in the comments fields):
L
ST
ST
L
ST
ST

0,LLink-Q_El(,3)
0,LLink-Q_El(,5)
5,LLink-Q_El(,3)
0,RLink-Q_El(,2)
0,RLink-Q_El(,5)
5,RLink-Q_El(,2)

Get left link from Right element


1 Store as left link of New element
2 Store left link from Right to New
Get right link from Left element
3 Store as right link of New element
4 Store right link from Left to New

Figure 705. Instructions to insert a new queue element

This style of coding is awkward and error-prone because explicit addressing is used for every
instruction. If any of the registers must be reassigned, every instruction using that register must
be found and updated.
We could use ordinary USING statements to refer to the fields in each element with proper symbolic addressing:
Using
L
ST
Drop
Using
L
ST
Drop
USING
ST
ST
Drop

Q_El,3
0,LLink
5,LLink
3
Q_El,2
1,RLink
5,RLink
2
Q_El,5
0,LLink
1,RLink
5

Map RIGHT element


Save old Right.LLink
Store new Right.LLink
Unmap RIGHT element
Map LEFT element
Save old Left.RLink
Store new Left.RLink
Unmap LEFT element
Map NEW element
Store new New.LLink
Store new New.RLink
Unmap NEW element

2

3

1
4

Figure 706. Insert a new list element with ordinary USINGs

The primary shortcomings of this method are


intermediate temporaries (in this case, registers 0 and 1) are used to hold some of the pointers;
it requires a precise sequence of USING and DROP statements to obtain correct address
resolutions;
two additional instructions are required (Load and Store via registers).
To eliminate the need for intermediate temporaries, we can use MVC instructions to move the
fields (with a presumed gain in efficiency):
RNew

Equ
USING
MVC
ST
MVC
ST

5
Q_El,RNew
LLink,LLink-Q_El(,3)
RNew,LLink-Q_El(,3)
RLink,RLink-Q_El(,2)
RNew,RLink-Q_El(,2)

R5 points to New element


Map NEW element
Move old Right.LLink 1
Store new Right.LLink 2
Move old Left.RLink 3
Store new Left.RLink 4

Figure 707. Ordinary-USING Code to Insert a New List Element

This sequence contains the efficient instructions, but its defects are:
greater difficulty of understanding;
increased likelihood of maintenance problems due to fixed register assignments in the
instructions.
The simplest and clearest solution is to use Labeled USINGs, with appropriate descriptive qualifiers Left, Right, and New. Thus, three instances of the DSECT named Q_El are concurrently
active.

Chapter XI: Dummy Sections, Enhanced USINGs, and Data Structures

921

RNew
Left
Right
New

Equ
Using
Using
Using
- - MVC
ST
MVC
ST

5
Q_El,2
Q_El,3
Q_El,RNew

R5 points to New element


Labeled USING for Left element
Labeled USING for Right element
Labeled USING for New element

New.LLink,Right.LLink
RNew,Right.LLink
New.RLink,Left.RLink
RNew,Left.RLink

1
2
3
4

Link
Link
Link
Link

from
from
from
from

New to Left
Right to New
Left to New
New to Right

Figure 708. Labeled USING example: inserting a new queue element

The advantages in clarity, readability, simplicity, and improved ease of maintenance are clear. The
only references to specific registers are in the USING statements. Without Labeled USINGs, the
code for these operations is more convoluted, and difficult to read, understand, and maintain.
A free storage list for queue elements can be the same as for a singly-linked list, because the freelist elements only need to be chained in one direction.
Queues are sometimes circular, where the last element is linked to the first and the first to the
last. This allows searching in either direction, starting at the queue head.

Exercises
40.8.1.(2) + Describe the steps necessary to delete element Q2 between elements Q1 and Q3 in a
queue. Use the queue-element definition in Figure 702.
40.8.2.(3) + Suppose you have defined a queue of elements with a 4-byte data field containing a
word integer. The elements are ordered along the forward links in descending value: that is, the
data in the element pointed to by the forward link (if it exists) is less than the value in the
element containing the link. The list anchor points to an arbitrary element of the queue. Write
instructions that search the queue for an element whose data item matches the word integer at
Value. If no match exists, branch to InsertIt.
40.8.3.(4) When inserting elements into an ordered queue, the list may become unbalanced if
most of the entries are added on one side of the center element pointed to by the anchor. To
remedy this, maintain a flag indicating which side of the center received the most recent
insertion. If two successive insertions occur on the same side, the anchor is changed so that the
center element is moved one element in that direction.282
Write an instruction sequence that constructs such a balanced queue from the array of 100
fullword integers starting at DataVals.

40.9. Trees
Trees are structures whose elements may contain pointers to more than one successor element.
In a binary tree, for example, each element (or node) contains a data field and links to at most
two successors. Because the term successor is not well defined when more than one is possible,
we sometimes use a more personified terminology and call the successors of the parent node
its left and right children. One parent node is distinguished by having no parent of its own; it
is called the root of the tree.
The literature on trees is vast, so we will simply give a few examples to illustrate possible implementations. The format of a typical tree element is illustrated in Figure 709.

282

922

This technique was used in the old IBM Fortran H compiler to construct its symbol tables.
Assembler Language Programming for IBM z System Servers

Version 1.00


 left subtree link

right subtree link

data field

Figure 709. Node of a binary tree

We can map the structure in Figure 709 with a DSECT like that in Figure 702:
Tree_El
LLink
RLink
ElemData

DSECT
DS
DS
DS

,
A
A
XL(DataLen)

Mapping of a tree element


Link to left subtree
Link to right subtree
Space for the element s data

Figure 710. DSECT structure of a typical tree element

The topmost node of a binary tree is its root node. All accesses to nodes in the tree start at the
root. An example of a binary tree with 3 nodes is shown in Figure 711.
Root node

 left link

right link


data field


0


0

data field

data field


left subtree


right subtree

Figure 711. Three nodes of a binary tree

This might look like a three-node queue with empty links, but a tree with more nodes might
look like Figure 712; we see that a tree structure cant be represented by a queue.

Chapter XI: Dummy Sections, Enhanced USINGs, and Data Structures

923

Root Node

 left link

right link


data field

 left link

 left link


right link
right link


data field
data field







left link
left link
left link
left link

right link
right link
right link
right link

data field
data field
data field
data field

Figure 712. A growing binary tree with seven nodes

Suppose we want to construct a symbol table using a binary tree, so that the symbols are maintained in alphabetic order. If we look at the symbol in a given node, all the symbols in the left
subtree (that is, the left subtree and its subtrees) precede the given symbol in alphabetic order,
and all the symbols in the right subtree and its subtrees follow the given symbol. Assume that
the tree elements are composed of three successive words, as illustrated in Figure 709. Let GR0
contain a 4-character symbol to be entered into the tree, and suppose GR1 contains the address
of an empty node obtained from a free storage list. As additional simplifications, we suppose the
tree already contains some entries, and if one of them matches the new symbol, we will branch to
FoundIt.
New
RW

Using
Equ
L
Compare LR
Using
CL
JL
JE
GoRight L
LTR
JNZ
ST
J
GoLeft L
LTR
JNZ
ST
Store
ST
XR
ST
ST
- - FoundIt - - -

Tree_El,1
3
RW,RootPtr
2,RW
Tree_El,2
0,ElemData
GoLeft
FoundIt
RW,RLink
RW,RW
Compare
1,RLink
Store
RW,LLink
RW,RW
Compare
1,LLink
0,New.ElemData
0,0
0,New.LLink
0,New.RLink

Map the new node based on GR1


Use GR3 as a work register
Pick up pointer to root node
Point to node to be compared
Anchor the tree element mapping
Compare symbol to current node
Symbol smaller, search left subtree
Symbol already in tree, exit.
Get link to right subtree
Check for right subtree
Right exists, scan right subtree
New node becomes right subtree
And go store symbol
Get link to left subtree
Check whether it s there
Branch if yes to search
New node becomes left subtree
Store symbol into new node
Clear GR0 for storing new links
Clear left and right links of...
...new node: it has no subtrees
Data already entered in the tree

Figure 713. Entering a new node in a binary tree

924

Assembler Language Programming for IBM z System Servers

Version 1.00

This method can be inefficient: if the symbols being entered in the tree are received in ascending
alphabetic order, we will generate a tree that is actually a linear list, chained along the right-tree
links. Techniques for balancing binary trees are beyond the scope of this section, but are described
in many programming references and textbooks if youre interested.
Having constructed a tree, we will need to search it to retrieve the symbols in alphabetic order.
Because all left subtrees precede their parents, and the right subtrees follow their parents, we must
scan the left subtrees of a node before processing the data in that node, followed by a scan of
the right subtrees. There are two problems to be solved: how to travel through a tree structure,
and how to keep track of which sons of a node have been visited, and which ones are still to be
processed.
As we work our way from the root toward the lower levels of the tree, we must retain some
information on how to return to the parents of the nodes already passed. This problem is easily
solved if each node contains a link to its parent, but this requires an extra link field in each node.
Similarly, if some space outside the data structure is available, we can also maintain a stack of
return links; each time we move from a parent node to one of its sons, the address of the parent
node is pushed onto the stack, to be popped off when we return to the parent. A third technique
is to reverse the links as we pass over them: when moving from parent to son, one of the links in
the son node is saved in a register, and the link field is replaced by a pointer to the parent node.
Then, when returning from son to parent, the links are restored to their original and correct orientation. (This method cannot be used if the tree may be traversed by more than one process at a
time, as might occur in large application programs such as reservation systems and similar data
bases.)
The second problem, keeping track of which subtrees of a node are still to be processed, requires
maintaining some kind of counter at each level. If we are using a stack to hold return links, we
can push the number or address of the next subtree to be processed onto the stack at the same
time. Otherwise, a field in the node must be available to hold the count. In a binary tree the
counter can be a single bit.
We will traverse the binary tree constructed in Figure 713, extract the symbols in alphabetic order,
and store them in a table of fullwords starting at Ordered. Assume there is a sufficiently large
array of fullwords at LStack that can be used to hold the return links. Since the tree is binary, we
need not maintain a count; to indicate that a node has been processed, the return link on the
stack will be stored as a negative value.

Chapter XI: Dummy Sections, Enhanced USINGs, and Data Structures

925

RW
RTbl
RStk

StackLnk

LookLft

Output

LookRgt

Return

LStack
Ordered

Equ
Equ
Equ
L
LA
LA
SR
ST
LA
LR
Using
L
LTR
JNZ
L
ST
LA
L
LTR
JZ
LCR
J
AHI
L
LTR
JM
JP
- - DS
DS

3
1
4
RW,RootPtr
RStk,LStack
RTbl,Ordered
2,2
2,0(,RStk)
RStk,4(,RStk)
2,RW
Tree_El,2
RW,LLink
RW,RW
StackLnk
0,Data(,2)
0,0(,RTbl)
RTbl,4(,RTbl)
RW,RLink
RW,RW
Return
2,2
StackLnk
RStk,-4
2,0(,RStk)
2,2
Return
Output
20F
100CL4

Use GR3 as a work register


Pointer to output table
Points to word past top of stack
Initialize work pointer to root
Initialize link stack pointer
Initialize output pointer
Node pointer = 0 indicates root
Put current node pointer on stack
Bump stack pointer by 4
Move to left subtree node
Map the tree node s structure
Get its left subtree link address
Does its left subtree exist...
If yes, stack link and continue
Process the data from the node...
...by storing it into the table
Increment table storage address
Get the right subtree link address
Does the right subtree exist...
Branch if not to return to parent
Form negative value for stack
Go stack link, look leftward
Pop stack pointer once
Retrieve popped return link
Check for already processed
Branch if yes, pop again
Go process the node if available
Otherwise if zero, we re all done
Stack for node links
Ordered output values

Figure 714. Retrieving data from a binary tree

The examples in Figures 713 and 714 have used one of three common ways to traverse a binary
tree. We assumed that each left subtree contains elements less than that of the parent node, and
each right subtree contains elements greater than the parent nodes. This is called inorder traversal. The other two forms are called preorder and postorder. The order of traversal for each
of the three forms is
preorder: parent, left subtree, right subtree
inorder: left subtree, parent, right subtree
postorder: left subtree, right subtree, parent
Consider the small tree with 3 nodes and 7 elements shown in Figure 715:
Root

A
B
C
D
E
F
G
Figure 715. Example of a binary tree of 7 elements

The order in which the elements are visited is


preorder traversal: A B D E C F G
inorder traversal: D B E A F C G
postorder traversal: D E B F G C A
Other types of trees with more than one data element and more than two links per node are
widely used; they are sometimes called B-trees or N-trees. For example, a B-tree node with
two data elements and three links might look like this:

926

Assembler Language Programming for IBM z System Servers

Version 1.00


number of data items here

data item 1 data item 2

link 1 link 2 link 3




link to node
link to node
link to node
with elements
with elements
with elements
< data item 1
between data
> data item 2
items 1 and 2
You will need to know the number of data items and links in a node so you can know how many
comparisons are needed, either to locate an item in this node or to follow a link to a lower node.
B-trees can mean that fewer nodes need to be searched to locate a particular data item.

Exercises
40.9.1.(2) The description of tree traversal methods always visits a left subtree before a
right subtree. What would happen if the order of left and right were interchanged?
40.9.2.(2) Figure 711 on page 923 shows a binary tree with 3 nodes. How many other 3-node
binary trees are possible?
40.9.3.(2) Now that you have solved Exercise 40.9.2, suppose your 3-node binary trees contain
the symbols A, B, and C in alphabetic order. If the trees are traversed using inorder traversal,
sketch what your trees will look like.
40.9.4.(3) Suppose an element of a tree can have up to four subtrees, of which the values in the
first two precede it and the values in the last two follow it, in whatever ordering is applied to
the contents of the data field. In addition, the subtrees are ordered (by the same relation) from
left to right. What additional fields are required in the node? What are the advantages of
such a representation over a binary tree?

40.10. Hash Tables


As with the other structures, the literature on hash tables is large. We will give only enough
background here to illustrate some implementation techniques for z System.
All of the previously described data structures suffer from one important defect: to locate an
element, the structure must be searched in an orderly and sometimes sequential fashion. We have
seen how to search arrays and lists linearly, and how to use binary trees, or binary search in an
array, to search more efficiently. When the number of data elements is large, however, even these
techniques become less efficient.
If the data need not be stored and retrieved in an ordered way, and if few deletions are performed,
hash addressing or hashing is an attractive alternative. This associative form of addressing
locates the element directly by its contents rather than by its position in an array, list, or tree.
There are many hash functions. The one you use is unimportant, so long as it creates a reasonably uniform distribution of hash values: you dont want too many data items to have the same
hash value, because your hash table will have too many items in some areas and too few in
others.
The item to be inserted or found in the table (called the key) is used to form a numeric hash, a
pseudo-random number generated from the datum itself. For example, the bits of the key may be
Chapter XI: Dummy Sections, Enhanced USINGs, and Data Structures

927

hashed by multiplying or dividing, or by adding or XORing pieces of the key together. This hash
value is then used as an index to look into (or probe) a table. If the probed position is vacant,
the datum is entered there; if it is not vacant and the datum occupying that position does not
match the key, a collision has occurred. We can make further probes to find either a match or an
empty place in the table, or create another data structure anchored at the hash position.
Figure 716 gives an example of a hash function; another is shown in Figure 717. Suppose the
word at DataItem should be placed into a hash table with 73 entries. Our hash function will XOR
the two halves of the data item, and divide the result by the number of table entries to create the
hash-table index.
HashEnts Equ
XR
LR
ICM
ICM
XR
XR
D
*

73
0,0
1,0
0,3,DataItem
1,3,DataItem+2
1,0
0,0
0,=A(HashEnts)

Number of hash table entries


Set GR0 to 0
And also GR1
First 2 bytes of data item in GR0
Last 2 bytes of data item in GR1
XOR the halves into GR1
Clear GR0 for a division
Divide by hash table size
Hash index is now in GR0

Figure 716. Example of searching a hash table

Suppose we have two fullword arrays starting at Symbols and Count, containing NE entries each.
Each element in the Symbols array may contain a 4-character alphanumeric symbol, and each
element of the Count array is an integer count of the number of occurrences of that symbol. We
wish to test if the symbol stored at InData appears in the table: if not, it will be entered and its
count will be set to 1; if there already, its count will be incremented by 1. A few further points
remain:
1. The number NE of table entries is usually chosen to be prime, giving a more uniform distribution of entries. We will use as a hash value the remainder from dividing the EBCDIC representation of the key by NE.
2. If we encounter a non-matching table entry (a collision), we will probe further simply by
moving to the next higher position in the table. If we run off the top, we begin again at the
bottom.
3. If no vacant position remains, and no match occurs after searching the entire table, branch to
FullUp.
In Figure 717, GR6 contains the hashed value of the key symbol; GR2 contains the symbol being
sought; GR0 contains zero (to test for vacant positions); and GR1 is used as an index for the
currently probed position of the table.

928

Assembler Language Programming for IBM z System Servers

Version 1.00

NE

Equ
SR
L
LR
SRDL
D
SLL
LR
Probe
CL
JE
CL
JE
LA
CL
JL
SR
NotOver CLR
JNE
J
NewSym ST
Match
L
AHI
ST
- - Syms
DS
Count
DS

101
0,0
2,InData
6,2
6,32
6,=A(NE)
6,2
1,6
0,Syms(1)
NewSym
2,Syms(1)
Match
1,L Syms(,1)
1,=A(NE*L Syms)
NotOver
1,1
1,6
Probe
FullUp
2,Syms(1)
2,Count(1)
2,1
2,Count(1)

(Prime) Number of possible entries


Initialize to zero
Load search key
Prepare to calculate hash value
Shift logically, GR6 zeroed
Divide by table size
Form fullword index
Initialize search index
See if empty slot
Branch if yes, store symbol
Is symbol already there?
Branch if in table
Move index to next position
Compare to top of table
Branch if not over
Reset index to bottom if over
Check for no empty slots at all
Loop if not finished
No space left
Store new symbol in table
Get count field
Increment by 1
And restore the counter

(NE)F
(NE)F

Define table for symbols


And for counts

Figure 717. Example of searching a hash table

This example isnt very useful, because the hash table cannot hold more data items than the
number of elements.
Hashing can be advantageously combined with other structures. For example, if each element of
the Syms array is the anchor for a linked list or a binary tree, the table can hold many more items
without much increase in search time. In such cases, we neednt worry about secondary probes in
the event of a collision; the list or tree anchored at that position is searched for a match, and if
none exists a new element is added to the structure.283 Searching such structures can be very efficient.
As with the other structures, the literature on hash tables is large.

Exercises
40.10.1.(2) Reduce the number of instructions in Figure 716 by using shifts.
40.10.2.(2) + In Figure 716, what will happen if the two ICM instructions are replaced by LH
instructions? Will a valid hash index be generated?

283

This method, with a linked list anchored at each hash table entry, was used to construct the symbol table in the
original System/360 IBM F-level Assembler.
Chapter XI: Dummy Sections, Enhanced USINGs, and Data Structures

929

40.11. Summary
The variety of data structures is huge; this section has tried to show how to handle some of the
more common types.

Terms and Definitions


array
A collection of data items usually of the same data type and length, arranged in contiguous
storage locations. Usually accessed using one or more index variables or subscripts.
table
A term often used to describe a one-dimensional array whose columns contain a mixture of
different data types and lengths.
column order
A way to store arrays so that the elements of each column follow one another in memory.
The normal ordering for one-dimensional arrays. For arrays of two or more dimensions,
subscripts cycle most rapidly from left to right.
row order
A way to store arrays so that the elements of each row follow one another in memory. For
arrays of two or more dimensions, subscripts cycle most rapidly from right to left.
linear subscript
For arrays of two or more dimensions, the evaluation of a subscript that treats the array as
having been mapped into a one-dimensional array corresponding to the CPUs linear
arrangement of bytes in memory.
virtual origin
The address of a (possibly nonexistent) array element all of whose subscripts are zero.
address table
A table of addresses of individual rows or columns of an array, allowing faster access to the
elements of that row or column.
binary search
A technique for searching ordered arrays by probing the midpoint of successively smaller
portions of the array.
list
A sequence of data elements each containing a link to its successor. If the first and last elements are identified and the next element to be accessed is the last, sometimes called a First
In, First Out (FIFO) list.
linked list
Same as list. Sometimes called a single-threaded list.
free storage list
A list containing unused and available elements. Abbreviated FSL.
stack
A data structure with a single visible element, the stack top. Sometimes called a Last In,
First Out (LIFO) list or queue.
queue
A sequence of data elements each containing links to its successor and to its predecessor.
Sometimes called a doubly-linked list.
doubly-linked list
Same as queue. Sometimes called a double-threaded list.
binary tree
A data structure in which each element contains links to two other elements, a left subtree
or left child, and a right subtree or right child.

930

Assembler Language Programming for IBM z System Servers

Version 1.00

preorder tree traversal


A technique for traversing a binary tree, visiting first the parent node, then the left subtree,
and then the right subtree.
inorder tree traversal
A technique for traversing a binary tree, visiting first the left subtree, then the parent node,
and then the right subtree.
postorder tree traversal
A technique for traversing a binary tree, visiting first the left subtree, then the right subtree,
and then the parent node.
hash function
A function that creates a randomized linear subscript from a data element. Used to avoid
lengthy table searches for large or complex data items.
hash table
A table of data items (possibly including lists and pointers to other data items or structures)
whose entries are accessed using the results of a hash function.
B-tree
A tree whose nodes contain more than one data element, and more than two links to successor nodes.
infix notation
The traditional form of writing arithmetic expressions, where operators are placed between
operands, as in 2*(3+4).
postfix notation
A representation of expressions convenient for evaluation. The infix form 2*(3+4) is represented as 2 3 4 + *.

Programming Problems
Problem 40.1.(3) This problem requires that you plot a graph to occupy a full page of printed
output that well assume is a two-dimensional array 60 lines high and 120 characters wide (that
is, 60 rows and 120 columns). Suppose we divide the page into 119 horizontal divisions
(columns) corresponding to X values in the range 59 X + 59, and 59 vertical divisions
(rows) corresponding to Y values in the range 29 Y + 29.
Set the first character in each line to a blank character, except on the first line, set it to C 1 .
On this page you should plot
1. an X-axis (use minus signs)
2. a Y-axis (use capital letter Is or vertical bars)
3. the Y-values corresponding to the functions
(a) Y = (X/2) + 6 (use X s for the points), and
(b) Y = 25 - (X*X)/50 (use asterisks for the points).
If a Y-value lies off the page, plot nothing. Your graph will look roughly like an inverted
parabola with a diagonal line through it, as in the following sketch (so you can tell whether
your graph is upside down or otherwise lopsided):

Chapter XI: Dummy Sections, Enhanced USINGs, and Data Structures

931

*****
XX

*** *** XX

**

XX

**
XX **

*
XX
*

*
XX
*

*
XX
*

*XX*

*
XX

* XX

* XX

*XX

*
XX

*
XX*

Use the PRINTLIN macro-instruction to print the 59 lines.


Problem 40.2.(3) Write a program to evaluate logical expressions of the form used in symbolic
logic. For example, if & represents AND and | represents OR, and A, B, and C are logical
variables, we might ask if the expression
A&B&(C|A)

Infix notation

is true for all possible true-false values of the three variables.


Let the possible values of variables be 0 (meaning FALSE) and 1 (meaning TRUE). We can
evaluate logical expressions in operator postfix notation using a stack; the above expression
would then be written
AB&CA|&

Postfix notation

Use the values B11110000, B11001100, and B10101010 to represent A, B, and C respectively, and let B11111111 and B00000000 represent the constants 1 (TRUE) and 0 (FALSE)
respectively.
Your program should read data records containing logical expressions in postfix notation, and
evaluate them using a byte stack (not a word stack). If the final value is B11111111 the
expression is always true, and if the value is B00000000 the value is always false; otherwise it is
indeterminate. Print the original postfix expression and a message describing the result of the
evaluation. Try your program with the expressions ABC01|||| and ABC01&&&& and as many
others as you can devise.
Some possible extensions:
1. Support the unary operator N (NOT) that forms the ones complement of the element on
top of the stack, and the binary operator X (XOR).
2. Create a stack of word entries, and define additional variables D and E appropriately.
Problem 40.3.(3) Write a program that will read 4-character symbols from the first 72 columns
of a record (there may be at most 18 symbols to a record). A symbol of all blank characters
indicates the end of the record. Insert the symbols in alphabetical order into a linked list whose
elements have two data fields (4 bytes for the symbol, and a word binary integer count) and a
fullword link field.
As the symbols are read from the record, scan the list. If the symbol is in the list, increment its
count by 1. If the symbol is not in the list, obtain a free element from a FSL, place the symbol
in it, initialize its count to 1, and insert it in the list in the correct position. If a symbol on the
record starts with an asterisk, print the contents of the list, giving each symbol and its count.
After the data in an element has been printed, return the element to the free storage list. Thus,
when the printing is done, all the data elements will be back on the FSL, and the data list will
be empty. Then read some more data records and build a new symbol table, until no more data
records are available.

932

Assembler Language Programming for IBM z System Servers

Version 1.00

Problem 40.4.(3) Write a program like that of Problem 40.3, but use a hash table to store the
symbols. You will have to devise a method to sort the symbols into alphabetic order before
printing them.
Problem 40.5.(4) Write a program like that of Problem 40.3, but use a binary tree to store the
symbols.
Problem 40.6.(3) A matrix is a two-dimensional array, as described in 40.2. Two-Dimensional
Arrays on page 896. Matrix multiplication is a common problem in data analysis; to calculate
the product matrix C of two N-by-N matrices A and B, we use the following formula:
C(i,j) = (k=1,N) A(i,k) * B(k,j)
Write a program to evaluate a product matrix containing fullword integer values. For example,
let N be 5, and initialize the A matrix with rows containing 1, 2, 3, 4, and 5, and initialize the B
matrix with rows containing 5, 4, 3, 2, and 1. Then test your program with A and B with all
elements initialized to 2. Assume that all sums and products dont exceed 30 significant bits.
Problem 40.7.(4) Do the same as in Problem 40.6, but this time move as much of the subscripting arithmetic as possible outside the loops. Then, use Branch on Index instructions to
increment and test the loop indices. Compare this solution to your solution to Problem 40.6.
Problem 40.8. Write a program to print a square centered on a 120-character print line (with
one additional initial character for carriage control spacing), centered on a 60-line page. The
square is 12 by 12; and its outer border is 12 1 characters, and its inner border is 10 0
characters. The rest of the page is blank. (Ignore the fact that character spacing on the printed
page may be different in horizontal and vertical directions.) For example, the upper left corner
of the square would look like this:
11111
10000
10
10
10
For extra credit: determine the actual character and line spacings used on your printer, and
adjust your printed output to more accurately resemble a square rather than a rectangle.
Problem 40.9. Do as in Problem 40.8, but rotate the square by 45 degrees to create a
diamond-shaped rhombus. Make the outer border 18 by 18 characters. The top of the diamond
would look like this:
1
101
10 01
10 01
For extra credit: determine the actual character and line spacings used on your printer, and
adjust your printed output to more accurately resemble a rotated square rather than a rhombus.
Problem 40.10. Write a program to print a circular ring centered on a 120-character print line
(with one additional initial character for carriage control spacing), and centered on a 60-line
page. The outer diameter of the ring is 60 characters (so it will fill a 60-line page). The width
of the ring should be 10 characters, so there will be an empty inner circle with diameter 40
characters. Use * characters to fill the ring, and leave the rest of the page blank.
For extra credit: determine the actual character and line spacings used on your printer, and
adjust your printed output to more accurately resemble a true circle rather than an ellipse.
Problem 40.11.(3) + This problem uses the representations introduced in Exercise 40.6.4. Write
a program that reads expressions in postfix form from data records, evaluates the expression,
and prints the result. The data records are prepared according to these rules: (1) all operands
are positive integers of 5 or fewer digits; (2) all operators and operands are separated by a single
blank; (3) the operators + - * / are represented by themselves; (4) the data record ends in

Chapter XI: Dummy Sections, Enhanced USINGs, and Data Structures

933

column 72. Your program should check for underflow and overflow; include some data to
verify that errors are correctly detected.
Problem 40.12.(2) Build a table of the first 25 members of an integer sequence defined by
S(N)=S(N-1)+S(N-2)+S(N-3), where S(1)=0, S(2)=1, and S(3)=2. Then, format and print all 25
members of the sequence; the largest is 1166220.
Then, dump the table and check that you can verify the values in hexadecimal.
Problem 40.13.(3) + Revise your solution to Problem 40.12, but this time put the address of the
table in a register and dont change it: all references to the table must be made using only its
address (as though the table is somewhere unknown). After building the table, format and print
the members of the sequence. Eliminate leading zeros from the results.
Problem 40.14.(3) Do as in Problem 40.13, but now build a second table containing the formatted values as character strings. Then, print the character values by stepping through the
array of character values.

934

Assembler Language Programming for IBM z System Servers

Version 1.00

Chapter XII: System Services, Reenterability, and Recursion

XX
XX
XX
XX
XX
XX
XX
XX
XX XX
XXXX
XXXX
XX XX
XX
XX
XX
XX
XX
XX
XX
XX

IIIIIIIIII
IIIIIIIIII
II
II
II
II
II
II
II
II
IIIIIIIIII
IIIIIIIIII

IIIIIIIIII
IIIIIIIIII
II
II
II
II
II
II
II
II
IIIIIIIIII
IIIIIIIIII

The two sections of this chapter discuss some advanced topics:


Section 41 sketches several types of operating system functions and how your programs can
utilize them.

General characteristics of macro instructions used to request Operating System services.

Purposely causing abnormal program termination.

Simple forms of storage management: how to acquire and release blocks of memory.

An overview of key elements of input and output.

Techniques for managing program interruptions, and a description of handling abnormal


terminations of any kind.

Section 42 describes:

Program reenterability: what it means and why it can be important.

Program recursion, and how to write programs to handle it.

Chapter XII: System Services, Reenterability, and Recursion

935

41. Using System Services

444
4444
44 44
44 44
44 44
44444444444
444444444444
44
44
44
44
44

11
111
1111
11
11
11
11
11
11
11
1111111111
1111111111

This section provides a brief overview of these topics:

Macro instructions used to access system services, and their typical formats
The SVC and PC instructions
Voluntary and involuntary abnormal termination of your program
Some basics of storage management
A short introduction to one common form of sequential Input/Output
Ways to handle some exceptions

This is only a sample of the many, many system services available to you. For all system services,
you should have the relevant manuals available.

41.1. Invoking System Services


These two instructions are most often used to invoke operating system services:
Op
0A

Mnem Type
SVC
I

Instruction
Supervisor Call

Op
B218

Mnem
PC

Type
S

Instruction
Program Call

Table 424. Supervisor and Program Call instructions

The SVC instruction has the form shown in Table 425 invokes the operating system Supervisor
by causing a Supervisor-Call interruption.
0A

Table 425. SVC instruction


format

SVC

where the second byte I of the SVC instruction contains an 8-bit number that is placed in the
Interruption Code portion of the old PSW in the fixed area at the low-address end of main
memory. (You may recall from Section 4.5 that Supervisor Call is one of the six classes of interruption: that is, execution of an SVC instruction invariably causes that type of interruption.) The
new PSW gives control first to an Interrupt Handler that saves the registers and the old PSW in

936

Assembler Language Programming for IBM z System Servers

Version 1.00

a safe place, and then passes control to a routine that examines the 8-bit Interruption Code and
decides what function is desired.
The Program Call instruction doesnt cause a program interruption, so it can sometimes operate
more efficiently than SVC. It normally causes a change from problem to supervisor state. Its
format is shown in Table 426:
..
B218

B1

D1

Table 426. PC instruction format

Its single operand is


PC

D2(B2)

so it can handle at least 224 possible operand values. Conversely, SVC can support at most 256
possible values, some of which are reserved for customer use.
Usually, further information such as flags and values, or addresses of other data, is placed in the
general registers just prior to executing the SVC or PC; registers 0 and 1, and sometimes 14 and
15, are almost always used. In some cases the Supervisor will place values into one or more registers before returning control to the program that executed the SVC or PC.

41.2. Invoking System Services with Macro Instructions


Most operating system services are invoked using macro instructions, or macros.
A macro instruction is an invocation of an assembly-time subroutine that is written in the conditional assembly language of the Assembler. You invoke (or call) it by writing its name in the
operation field of a statement, possibly with a name-field entry, and the arguments to the macro
in the operand field. The conditional assembly statements in the macro definition examine the
arguments and generate statements in the ordinary Assembler language that then form part of
your program.
There are generally two types of macro argument: positional, like the operands of a machine
instruction, and keyword, of the form name=value. Macro arguments are usually self-defining
terms or symbols naming objects or values in your program, or fixed character tokens known to
the macro.
The arguments for a macro may also be parenthesized lists, as in Figure 718. For example, you
might invoke the OPEN macro this way, using what is called the Standard form of the macro:
OpenOutS OPEN (OutFile,OUTPUT)
Figure 718. Sample macro invocation, Standard form

In Figure 718, the name field entry is the symbol OpenOutS, the macro name in the operation
field is OPEN, and the (single) argument in the operand field is (OutFile,OUTPUT), where OUTPUT is
one of several valid fixed tokens.
Because this OPEN macro generates statements that refer to the symbol OutFile, we must also
define it (this is actually the name of a Data Control Block, or DCB, that well describe
shortly).
In this case, the statements generated by this macro call are:

Chapter XII: System Services, Reenterability, and Recursion

937

000000
000000
000004
000008
000009
00000C

4110 C008
47F0 C00C
8F
000030
0A13

00008
0000C

2 OpenOutS
3+
4+OpenOutS
5+
6+
7+
8+

OPEN
CNOP
LA
B
DC
DC
SVC

(OutFile,OUTPUT)
0,4
1,*+8
*+8
AL1(143)
AL3(OutFile)
19

ALIGN LIST TO FULLWORD


LOAD R1 W/LIST ADR @V6PXJRU
BRANCH AROUND LIST @V6PXJRU
OPTION BYTE
DCB ADDRESS
ISSUE OPEN SVC

Figure 719. Generated statements from an OPEN macro

In Figure 719, statement 2 is the macro invocation. Statements 3 through 8 have a + sign following the statement number; this is the Assemblers indication that the statement is generated by
conditional assembly, and not part of the original source program. The name field symbol
OpenOutS was assigned to the first generated statement, and the final generated statement is a
Supervisor Call instruction.
Note!
Most System Interface macros and services save and restore general registers 2-13, but use (and dont restore) general registers 0, 1, 14, and 15.
Some macros return new values in one or more of those four registers.
Almost all macros that expect the name of a memory location or a length argument will accept an
argument with a register number enclosed in parentheses. In this example, the length value (LV=)
is in GR4, and the address argument (A=) is in GR7.
000246 1804
000248 4110 7000
00024C 0A0A

00000

292
293+
294+
295+

FREEMAIN R,LV=(4),A=(7)
LR
0,4
LA
1,0(0,7)
SVC 10

LOAD LENGTH
LOAD AREA ADDRESS
ISSUE FREEMAIN SVC

The examples below illustrate only a small subset of the options provided by these macros; see
the manuals listing in the Bibliography on page 1041 for further information.

Exercises
41.2.1.(1) + Write short programs that expand into instruction sequences, using the many variations on the SAVE and RETURN macros described in 37.5. Additional Conventions (*) on
page 762 and study the differences among the generated statements.
41.2.2.(1) + Identify the types of macro arguments in the FREEMAIN macro above.

41.3. Macro Formats: Standard, List, and Execute


The example in Figure 718 on page 937 uses Standard form, in which all generated statements,
including parameters to be passed to the Supervisor, are generated directly into the instruction
stream, as we saw in Figures 718 and 719. There are two other forms, the List and Execute forms
that dont mix instructions and data like the Standard form. Almost all system service macros
support all three forms.
The list form of a macro expansion simply generates the data structures to be passed to the
Supervisor, but doesnt generate executable instructions like the LA, branch, and SVC
instructions in Figure 719. For example:
OpenOutL OPEN (OutFile,OUTPUT),MF=L
Figure 720. Sample macro invocation using List form

The only difference from Figure 718 on page 937 is the additional keyword argument, MF=L
(where L means List form), that tells the OPEN macro to generate only the parameter list.

938

Assembler Language Programming for IBM z System Servers

Version 1.00

10 OpenOutL
11+OpenOutL
12+
13+

000030
000030 8F
000031 000058

OPEN
DC
DC
DC

(OutFile,OUTPUT),MF=L
0F 0
AL1(143)
AL3(OutFile)

ALIGN LIST TO FULLWORD


OPTION BYTE
DCB ADDRESS

Figure 721. Generated statements from a List form OPEN macro

In Figure 721, only the parameters for the OPEN macro are generated, corresponding to statements 6 and 7 in Figure 719 on page 938. These parameters are then used by an OPEN macro in
Execute form.
To write this sample macro in Execute form, we use the added argument MF=(E,listname), where
E means Execute form and the listname is the name of the parameter list generated by the List
form of the macro.
OpenOutE OPEN MF=(E,OpenList)
Figure 722. Sample macro invocation using Execute form

The expansion of this macro completes the set of instructions in statements 4 and 6 generated by
the Standard form in Figure 719 on page 938: GR1 points to the parameters, and issues the SVC
instruction:
000058 4110 C030
00005C 0A13

00030

15 OpenOutE OPEN MF=(E,OpenOutL)


17+OpenOutE LA
1,OpenOutL
18+
SVC 19

LOAD PARAMETER REG 1


ISSUE OPEN SVC

Figure 723. Generated statements from an Execute form OPEN macro

In this case, we omitted the operand describing OutFile and that we wanted to open it for OUTPUT;
the Execute form of the OPEN macro assumes that we have generated the necessary data in the
area named OpenOutL as in Figure 721, and simply puts its address in GR1 and issues the SVC.
41.3.1. List form with Empty Argument List

Sometimes we want to use the List form for other OPENs, so we first create an empty List form:
OpenLstX OPEN (,),MF=L
Figure 724. Sample macro invocation using empty List form

The generated instructions are simple:


20 OpenLstX
21+OpenLstX
22+
23+

000080
000080 80
000081 000000

OPEN
DC
DC
DC

(,),MF=L
0F 0
AL1(128)
AL3(0)

ALIGN LIST TO FULLWORD


OPTION BYTE
DCB ADDRESS

Figure 725. Generated instructions from empty List form

Then, to use this empty list to insert the name of the file and its input/output status, we write
OpenOutE OPEN (OutFile,OUTPUT),MF=(E,OpenList)
Figure 726. Sample macro invocation using Execute form

The macro expansion then inserts the parameter values into the argument list; note that GR14 is
used as a work register by the macro in statements 20 and 23.
000058
00005C
000060
000064
000068
00006C
000070
000074

4110
94F0
960F
43E1
4100
5001
42E1
0A13

C030
1000
1000
0000
C098
0000
0000

00030
00000
00000
00000
00098
00000
00000

15 OpenOutE
17+OpenOutE
18+
19+
20+
21+
22+
23+
24+

OPEN
LA
NI
OI
IC
LA
ST
STC
SVC

(OutFile,OUTPUT),MF=(E,OpenLstX)
1,OpenLstX
LOAD PARAMETER REG 1
0(1),X F0
CLEAR OPTION 1 BITS
0(1),15
INSERT OPTION BITS
14,0(1,0)
SAVE OPTION BYTE
0,OutFile
PICK UP DCB ADDRESS
0,0(1,0)
STORE INTO LIST
14,0(1,0)
RESTORE OPTION BYTE
19
ISSUE OPEN SVC

Figure 727. Generated statements from an Execute form OPEN macro

Chapter XII: System Services, Reenterability, and Recursion

939

Because we have specified the original (OutFile,OUTPUT) argument, the macro expansion carefully
inserts the new information into the empty parameter list at OpenLstX, competes the list, and then
issues the SVC.
This technique lets you use the same List form to open other data sets, as in
OpenOutE OPEN (InFile,INPUT),MF=(E,OpenList)
Figure 728. Another macro invocation using Execute form and same List form
41.3.2. Register Forms and Arguments

The examples of the OPEN macro above require that GR1 contain the address of a parameter list
in storage. Some macros, however, pass their arguments entirely in registers, such as some forms
of ABEND, GETMAIN, and FREEMAIN. Well see more examples of these R-Type macros
in later sections.
For example, we can write an ABEND macro like this:
ABEND 42
Figure 729. An R-Type macro invocation generating an argument in a register

Its expansion is:


000000
000000 4110 002A
000004 0A0D

0002A

3
4+
6+
7+

ABEND
DS
LA
SVC

42
0H
1,42
13

LOAD PARAMETER REG 1


LINK TO ABEND ROUTINE

Figure 730. Generated statements from R-Type macro

and the only argument is passed directly in GR1, not in memory.


If the address of a macro argument is already in a register, you can provide it directly by parenthesizing the register number, rather than by the name of the argument. For example:
LA
4,INDATA
LA
9,OUTDATA
OPEN ((4),(INPUT),(9),(OUTPUT))
Figure 731. A macro invocation with arguments in registers

The macro expansion in Figure 732 shows how the addresses in the registers are stored into the
generated argument list:
000032 4140 F0D0
000036 4190 F130
00003A
00003C
000040
000044
000048
00004C
000050
000054
000058

0700
4110 F044
47F0 F04C
00000000
00000000
5041 0000
5091 0004
928F 1004
0A13

000D0
00130
00044
0004C
00000
00004
00004

35
36
37
38+
39+
40+
41+
42+
43+
44+
45+
46+

LA
LA
OPEN
CNOP
LA
B
DC
DC
ST
ST
MVI
SVC

4,INDATA
9,OUTDATA
((4),(INPUT),(9),(OUTPUT))
0,4
1,*+8
*+12
A(0)
A(0)
4,0(1,0)
9,4(1,0)
4(1),143
19

ALIGN LIST TO FULLWORD


LOAD R1 W/LIST ADR
BRANCH AROUND LIST
OPT BYTE AND DCB ADDR.
OPT BYTE AND DCB ADDR.
STORE INTO LIST
STORE INTO LIST
MOVE IN OPTION BYTE
ISSUE OPEN SVC

Figure 732. Generated statements from a Standard-form macro with arguments in registers
41.3.3. MODE=24, MODE=31

In the expansions of the executable form of the OPEN macro, the parameter list contains a
3-byte address of the Data Control Block (DCB). Sometimes it may be important for some parts
of a macro expansion to use 4-byte addresses to refer to items above the 16MB line. Using the
OPEN macro as an example, we specify an additional argument, MODE=31:
OPEN (OutFile,(OUTPUT)),MODE=31
Figure 733. A Standard macro invocation specifying M O D E = 3 1

940

Assembler Language Programming for IBM z System Servers

Version 1.00

In the macro expansion in Figure 734 on page 941, you can see in statement 41 that the address
of the OutFile DCB is 4 bytes long.
000032
000034
000038
00003C
00003D
000040
000044
000046
000048

0700
4110 F03C
47F0 F044
8F
000000
000001A8
1801
1B11
0A13

0003C
00044

35
36+
37+
38+
39+
40+
41+
42+
43+
44+

OPEN
CNOP
LA
B
DC
DC
DC
LR
SR
SVC

(OutFile,(OUTPUT)),MODE=31
0,4
1,*+8
*+12
AL1(143)
AL3(0)
A(OutFile)
0,1
1,1
19

ALIGN LIST TO HALFWORD


LOAD R1 W/LIST ADR @V6PXJRU
BRANCH AROUND LIST @V6PXJRU
OPTION BYTE
RESERVED
DCB ADDRESS
POINT REG0 TO PLIST
CLEAR REGISTER 1
ISSUE OPEN SVC

Figure 734. Generated statements from a Standard-for macro with M O D E = 3 1


41.3.4. Mixed Case Macro Arguments

Be careful when using mixed-case characters in macro arguments. Some macros are fussy about
the case of their arguments, as the following examples show.
In general, symbols and keyword parameter names can be any mixture of upper and lower case;
positional and keyword arguments must often be in upper case only.
Compare Figure 735 to Figure 719 on page 938, where the positional argument OUTPUT was
written in upper case.
000000
000000 4110 C008
000004 47F0 C00C
** ASMA254I *** MNOTE ***

00008
0000C

5 OpenOutS OPEN (OutFile,Output)


6+
CNOP 0,4
ALIGN LIST TO FULLWORD
7+OpenOutS LA
1,+8
LOAD R1 W/LIST ADR
8+
B
*+8
BRANCH AROUND LIST
10+
12,*** IHB002 INVALID OPTION OPERAND SPECIFIED Output

Figure 735. Example of a mixed-case positional macro argument

In Figure 736, the two keyword arguments LV and A are accepted in lower case; the positional
argument R must however be in upper case.
000008 1804
00000A 4110 7000
00000E 0A0A

00000

13
14+
15+
16+

FREEMAIN R,lv=(4),a=(7)
LR
0,4
LA
1,0(0,7)
SVC 10

LOAD LENGTH
LOAD AREA ADDRESS
ISSUE FREEMAIN SVC

Figure 736. Example of mixed-case keyword macro arguments

In the two macro calls in Figure 737, the two macro-format (MF=) keyword arguments l and e are
in lower case, which the macro doesnt recognize:
** ASMA254I *** MNOTE ***
** ASMA254I *** MNOTE ***

19 OpenOutL OPEN (OutFile,OUTPUT),mf=l


21+
12,*** IHB002 INVALID MF OPERAND SPECIFIED-l
24 OpenOutE OPEN mf=(e,openoutl)
26+
12,*** IHB002 INVALID MF OPERAND SPECIFIED-(e,openoutl)

Figure 737. Example of mixed-case keyword macro arguments


41.3.5. The SYSSTATE Macro

On z/OS systems, the SYSSTATE macro can help many system service interface macros to generate correct statement sequences depending on the level of the a/OS operating system. Check the
documentation of the SYSSTATE macro to see which arguments and options will generate statements most applicable to your execution environment.

Exercises
41.3.1.(2) + Assemble the statements in Figure 728 on page 940 (being careful to generate the
OpenList also), and study the generated statements. Does it matter which of the List and
Execute forms of the OPEN macro is generated first?
41.3.2.(1) In Exercise 41.2.1, why is it important to generate OpenList also?

Chapter XII: System Services, Reenterability, and Recursion

941

41.4. Causing Abnormal Termination


Sometimes a program will find itself in a situation that should never occur, or when continuing
could cause more damage than stopping immediately. There are several ways to force termination,
including creating program interruptions such as executing an invalid operation code or branching
to an invalid address:
- - DC
H 0

Discovered an unrecoverable error!


Force program interruption

DC

X00nn

Where nn describes your situation

LA
BR

1,X BAD
1

Set odd address in GR1


Force program interruption

or
or

or
X C0F4wxyz0002

Simulate JL *+4; wxyz is your code

These will terminate the program unless some error recovery has been set up (see Sections 41.7
and 41.8 starting on page 957) that traps the program interruption. A more common, and more
flexible, way to terminate a program is to cause an abnormal end, or ABEND 284 with the
ABEND macro.
The ABEND macro supports several useful arguments, including:
a user code that you provide to indicate the specific termination condition;
keyword arguments that let you specify whether a memory dump should be provided (you
must provide a file where the dump can be written);
keyword arguments that let you specify whether the entire job step should be ended;
a reason code that you use to indicate greater detail about the condition causing the termination.
To terminate your program with user code 42, as in Figures 729 and 730 on page 940, you can
write
ABEND 42

End the program immediately

As a more complex example, suppose you want to terminate your program with user code 42 and
reason code X BADCODE , and request a memory dump:
StopHere ABEND 42,DUMP,REASON=X BADC0DE

Error in my code!

Figure 738. Sample ABEND macro

The macro expansion is shown in Figure 739:


000000
000000
000004
000004
000008
00000C
000010
000014
000018
00001A

4110 004F

0004F

47F0 F00C
0BADC0DE
58F0 F008
4100 0084
8900 0018
1610
0A0D

0000C
00008
00084
00018

3 StopHere
4+StopHere
6+
7+
8+
9+
10+
11+
12+
13+
14+

ABEND
DS
LA
CNOP
B
DC
L
LA
SLL
OR
SVC

42,DUMP,REASON=X BADC0DE
Error in my code!
0H
1,42
LOAD PARAMETER REG 1
0,4
ALIGN ON WORD BOUNDARY
*+8
BRANCH AROUND CONSTANTS
AL4(X BADC0DE )
REASON CODE
15,*-4
LOAD REG15 WITH REASON CODE
0,132(0,0)
DUMP/STEP/DUMPOPTS/REASON
0,24(0)
SHIFT TO HIGH ORDER
1,0
OR IN WITH COMPCODE
13
LINK TO ABEND ROUTINE

Figure 739. Generated statements from an ABEND macro

284

942

Uusually pronounced Ab-End, rather than A-Bend.


Assembler Language Programming for IBM z System Servers

Version 1.00

The user code is in the rightmost 12 bits of GR1, the reason code is in GR15, and the high-order
byte of GR1 contains bit flags that detail which options are specified and what should be done at
termination.
You can also use the DUMPOUT macro for simple memory dumps, without causing program
termination. It is described in Appendix B: Simple I/O Macros on page 1001.

Exercises
41.4.1.(1) + What kind of program interruption will be caused by branching to address X BAD ?
Why should you not try to branch to address X D1E ?
41.4.2(1) + What kind of program interruption will be caused if you first load GR1 using this
instruction?
LGFI 1,C BAD
BR
1

Force program interruption

What if the operand is C D1E instead?


41.4.3.(1) + Theres an intentional mistake in Figure 739 on page 942. What is it?

41.5. Storage Management


Many programs need to acquire additional working memory; and the two most commonly used
macros are GETMAIN and STORAGE. To release the acquired storage you can use the
FREEMAIN and STORAGE macros (with different operands for STORAGE) or simply terminate the program and let the operating system clean up for you. 285
GETMAIN and FREEMAIN were the original OS/360 storage-management macros, and like
STORAGE, are limited to memory below the 2GB bar. (Storage above the bar is managed
with the IARV64 macro.)
Take Care!
All three of GETMAIN, FREEMAIN, and STORAGE may use general
registers 0, 1, 14, and/or 15 as work registers for various combinations of
macro arguments.
41.5.1. The GETMAIN Macro

GETMAIN provides several ways to request storage:


Conditional (C)
If the requested storage is available, GETMAIN will put zero in GR15; otherwise a nonzero
value is in GR15.
Unconditional (U)
If the requested storage is not available, GETMAIN will terminate the program with an
ABEND.
Register (R)
A request for a single block of storage. Parameters are passed in registers; some of them may
have been constructed in storage and then loaded into registers.

285

But its much better that your program keep track of the storage it has acquired, and release it when its no longer
needed. There may be a time when your program is part of a larger suite of programs that could possibly exhaust the
available storage if all programs dont release what they acquire.
Chapter XII: System Services, Reenterability, and Recursion

943

Element (E)
A request for a single block of storage.
Variable (V)
A request for a single block of storage between a maximum and a minimum size.
List (L)
A request for several blocks of storage.
Some of these can be combined; for example, VRC means that you want to acquire storage
between two limits, the arguments will be passed in registers, and the system puts a return code in
GR15 to indicate the success or failure of the request.
The supported combinations that can be requested by the first (positional) operand of
GETMAIN are summarized in Table 427:

Type
Register, Single
Element
Single Element
List of Elements

Single
Conditional
Unconditional

Variable
Conditional
Unconditional

Where

RC

R, RU

VRC

VRU

<2GB

EC

EU

VC

VU

<16MB

LC

LU

<16MB

Table 427. GETMAIN request options

As shown in the last column of Table 427, storage acquired using any of the five Register forms
can be requested either below or above the 16MB line, and all addresses and lengths have
31-bit lengths. The storage is allocated in the same area of memory as the calling program (that is,
below or above the 16MB line). For all other forms, the storage is allocated below 16MB.
Acquired storage is always aligned on a doubleword boundary, with length that is a multiple of 8
bytes. Sometimes, you can request page alignment on a 4K boundary.
Several forms require that you provide one or more words in memory into which lengths and/or
addresses will be stored; be careful not to modify them during program execution, because they
can be used to release the acquired storage using the FREEMAIN macro.
Figure 740 shows an example of a typical GETMAIN request:
GETMAIN R,LV=72

Get storage for local save area

Figure 740. Sample R = t y p e G E T M A I N request

The expansion of this macro call is shown in Figure 741; note that the only value passed to SVC
10 is in GR0. (The BAL instruction sets the high-order bit of GR1 to 1; well see why this is
interesting when we discuss the FREEMAIN macro.)
000000 4100 07D0
000004 4510 C008
000008 0A0A

007D0
00008

5
6+
7+
8+

GETMAIN R,LV=72
LA
0,72(0,0)
BAL 1,*+4
SVC 10

Get storage for local save area


LOAD LENGTH
INDICATE GETMAIN
ISSUE GETMAIN SVC

Figure 741. Expansion of a sample R-type G E T M A I N request

For the Register forms, storage will be allocated by default in the area where the requesting
program is executing, either below or above the 16MB line.
Figure 742 on page 945 shows an example of a VRU request:

944

Assembler Language Programming for IBM z System Servers

Version 1.00

00003C
00003C
000040
000044
000048
000049
00004A
00004B
00004C
000050
000054

47F0 C04C
00000090
00000048
00
00
00
0A
9801 C040
58F0 C048
0A78

0004C

00040
00048

34
35+
36+
37+
38+
39+IHB0004F
40+
41+
42+
43+
44+
45+

GETMAIN VRU,LV=(144,72)
CNOP 0,4
B
*+16-4*0-4*0-2*0
DC
A(144)
DC
A(72)
DC
AL1(0)
DC
AL1(0)
DC
AL1(0)
DC
BL100001010
LM
0,1,*-12+2*0
L
15,IHB0004F
SVC 120

ALIGN DATA ON FULLWORD BDY


BRANCH PAST DATA
MAXIMUM LENGTH
MINIMUM LENGTH
RESERVED
RESERVED
SUBPOOL
MODE BYTE
LOAD MAX AND MIN LENGTHS
LOAD GETMAIN PARMS
ISSUE GETMAIN SVC

Figure 742. Expansion of a sample VRU-type G E T M A I N request

In this case, GR0, GR1, and GR15 all contain values used by SVC 120.
If you GETMAIN 8192 or more bytes, or a multiple of 4096 bytes on a page boundary, the
system will automatically clear the area to zeros.286
41.5.2. The FREEMAIN Macro

The FREEMAIN macro is used to release storage acquired by GETMAIN. For single elements,
the values passed to the SVC routine are the length and address of the area to be freed.
FREEMAIN supports forms like those of GETMAIN:
Conditional (C)
If the requested storage can be freed, FREEMAIN will put zero in GR15; otherwise a
nonzero value is in GR15.
Unconditional (U)
If the requested storage cant be freed, FREEMAIN will terminate the program with an
ABEND.
Register (R)
A request to return a single block of storage. Parameters are passed in registers; some of
them may be constructed in storage and then loaded into registers.
Element (E) and Variable (V)
A request to free a single block of storage. Because both E and V GETMAIN requests allocate a single area of storage, the equivalent FREEMAIN forms release a single fixed-length
area. (The GETMAIN and FREEMAIN argument lists are different.)
List (L)
A request to free one or more blocks of storage.
The supported combinations that can be requested by the first (positional) operand of
FREEMAIN are summarized in Table 428:
Type
Register, Single
Element

Conditional

Unconditional

Where

RC

R, RU

<2GB

Single Element

EC, VC

E, EU; V, VU

<16MB

List of Elements

LC

L, LU

<16MB

Table 428. FREEMAIN request options

As the last column of Table 428 indicates, the Register forms can free storage allocated either
above or below the 16MB line; all the other forms can free storage only below 16MB.
Figure 743 on page 946 shows a simple example of a typical FREEMAIN request:

286

With some rather specialized restrictions; see the reference manuals in the Bibliography.
Chapter XII: System Services, Reenterability, and Recursion

945

000072 4100 0048


000076 5810 C084
00007A 0A0A

00048
00084

60
61+
62+
63+

FREEMAIN R,LV=72,A=Z
LA
0,72(0,0)
L
1,Z
SVC 10

LOAD LENGTH
LOAD AREA ADDRESS
ISSUE FREEMAIN SVC

Figure 743. Example of an R-type F R E E M A I N macro

In this case, the length is loaded into GR0 and the address is put in GR1. Note that the same
SVC 10 is used as for GETMAIN; the key difference here is that the high-order bit of GR1 is
zero (because the address of the acquired storage is below 2GB), while it was 1 for GETMAIN. 287
41.5.3. The STORAGE Macro

The STORAGE macro combines the functions of acquiring and releasing storage in one macro,
using the positional arguments OBTAIN and RELEASE to select the operation. To specify conditional and unconditional operations, you must specify COND=YES or COND=NO, respectively; NO is
the default.
Figure 744 shows a simple request for 72 bytes using the STORAGE macro.
STORAGE OBTAIN,LENGTH=72

Request 72 bytes

Figure 744. Sample STORAGE OBTAIN request

The instructions generated from this request are shown in Figure 745. (Note that registers 0, 14,
and 15 are used; compare this expansion to the equivalent request using GETMAIN in
Figure 741 on page 944.)
000000
000000
000004
000008
000009
00000A
00000B
00000C
00000C
000010
000014
000018
00001C
000020

47F0 F00C
00000048
00
00
00
02

0000C

5800
58F0
58E0
58EE
58EE
B218

00004
00008
00010
00304
000A0

F004
F008
0010
0304
00A0
E000

00000

4
5+
6+
7+IHB0001L
8+IHB0001F
9+
10+
11+
12+IHB0001B
13+
14+
15+
16+
17+
18+

STORAGE OBTAIN,LENGTH=72
CNOP 0,4
B
IHB0001B
DC
A(72)
DC
BL100000000
DC
AL1(0*16)
DC
AL1(0)
DC
BL100000010
DS
0F
L
0,IHB0001L
L
15,IHB0001F
L
14,16(0,0)
L
14,772(14,0)
L
14,160(14,0)
PC
0(14)

Request 72 bytes
.BRANCH AROUND DATA
.STORAGE LENGTH
.KEY
.SUBPOOL
.FLAGS
.STORAGE LENGTH
.CONTROL INFORMATION
.CVT ADDRESS
.ADDR SYST LINKAGE TABLE
.OBTAIN LX/EX FOR OBTAIN
.PC TO STORAGE RTN

Figure 745. Example of a STORAGE OBTAIN macro expansion

If the request was successful, the address of the obtained storage is returned in GR1.
To return the 72 bytes requested previously, we assume that their address is now in GR1, as indicated by the ADDR=(1) operand.
STORAGE RELEASE,LENGTH=72,ADDR=(1) Return 72 bytes
Figure 746. Sample STORAGE RELEASE request

The instructions generated by this macro are shown in Figure 747 on page 947 (again, compare
this to the equivalent FREEMAIN in Figure 743).

287

946

The BAL instruction in Figure 741 on page 944 is doing something important!
Assembler Language Programming for IBM z System Servers

Version 1.00

000024
000024
000028
00002C
00002D
00002E
00002F
000030
000030
000034
000038
00003C
000040
000044

47F0 F030
00000048
00
00
00
03

00030

5800
58F0
58E0
58EE
58EE
B218

00028
0002C
00010
00304
000CC

F028
F02C
0010
0304
00CC
E000

00000

20
21+
22+
23+IHB0003L
24+IHB0003F
25+
26+
27+
28+IHB0003B
29+
30+
31+
32+
33+
34+

STORAGE RELEASE,LENGTH=72,ADDR=(1) Return 72 bytes


CNOP 0,4
B
IHB0003B
.BRANCH AROUND DATA
DC
A(72)
.STORAGE LENGTH
DC
BL100000000
DC
AL1(0*16)
.KEY
DC
AL1(0)
.SUBPOOL
DC
BL100000011
.FLAGS
DS
0F
L
0,IHB0003L
.STORAGE LENGTH
L
15,IHB0003F
.CONTROL INFORMATION
L
14,16(0,0)
.CVT ADDRESS
L
14,772(14,0)
.ADDR SYST LINKAGE TABLE
L
14,204(14,0)
.OBTAIN LX/EX FOR RELEASE
PC
0(14)
.PC TO STORAGE RTN

Figure 747. Example of a STORAGE RELEASE macro expansion

The STORAGE macro supports a greater variety of options compared to GETMAIN and
FREEMAIN. Note also that it generates a PC instruction rather than the SVCs used by
GETMAIN and FREEMAIN.
41.5.4. Subpools (*)

The three macros described above support subpools. A subpool is a way to group related
requests. For example, if your program is creating variable-sized binary trees, linked lists, and
tables, you may need to allocate additional storage for each as the need arises. By allocating each
type in a separate subpool, you can then release all the storage allocated for one of those functions at once, without having to keep track of each separately allocated segment.
Subpools (and their many types) are described in the references listed in the Bibliography on page
1041.

Exercises
41.5.1.(1) + Why does the BAL instruction in Figure 741 on page 944 always generate a highorder 1 bit in GR1, whether executed in 24-bit or 31-bit addressing mode?

41.6. Basic Input and Output


Input and Output (I/O for short) is a vast and complex subject, many aspects of which are well
beyond the scope of this text. We will introduce key features used by many application programs.
41.6.1. A Simple Scenario

Well start with a simple scenario in six basic steps, showing the key actions involved in your
programs reading records from a Data Set. The figures are expanded in detail at each step.
Simple Scenario, Step 1: The Data Set
The Data Set is on some external storage medium such as tape or disk. Almost all Data Sets
have some type of label describing the properties of the records in the Data Set. A part of the
label is the Data Set Name (DSName) that you can use to refer to the Data Set.

Label Data
Set

Figure 748. A Data Set with records you want to read

Chapter XII: System Services, Reenterability, and Recursion

947

You have written a program to read the records, and submit a job to the operating system to load
and execute the program.
Simple Scenario, Step 2: Submitting a job to execute the program
When you submit the job to read from the Data Set, you specify in the Job Control Language
(JCL) a Data Definition Name (DDName) that your program will need to access the data. The
operating system Supervisor creates a Job File Control Block (JFCB) from information in the JCL
statements you provided.

DDName JCL

JFCB


Label Data
Set

Figure 749. You submitted a job with a program to read the records

After the Supervisor processes the JCL statements, your program is ready to be loaded.
Simple Scenario, Step 3: Your program after loading and before execution
Your program has been loaded into memory. It contains the Data Control Block (DCB) you
wrote, with information about how your program will access the records, as well as your OPEN,
GET, and CLOSE macros, and a Record Buffer area where the records will be placed as theyre
read.
The OPEN macro, when executed, gives you access to your data.
The GET macro requests a data record be read.
The CLOSE macro terminates access to the Data Set.
The DCB contains the DDName that provides access to the Data Set whose DDName (now
saved in the JFCB) was specified in JCL statements.

948

Assembler Language Programming for IBM z System Servers

Version 1.00

......

OPEN

......

GET

DCB

......

CLOSE

......

Record Buffer

DDName JCL

JFCB


Label Data
Set

Figure 750. Your program, loaded into memory before execution

Your program is ready to start execution.


Simple Scenario, Step 4: OPENing the data set
After establishing addressability and initializing, your program executes the OPEN macro; many
things happen.
1. Information from the JFCB, the Data Set Label, and from the DCB is merged into the
DCB, as described in Section 41.6.5 on page 954.
2. Access Method routines appropriate to the type of device holding the Data Set, the type of
records, the type of buffering, etc., are loaded automatically. These routines provide device
independence to your program.

......

DDName JCL

OPEN

JFCB

......

GET
DCB

 Label Data

......

Set

CLOSE
 Access

......
Methods

Record Buffer

Figure 751. Your program after executing the OPEN macro

A lot can go wrong at this stage, typically causing an ABEND with system completion code x13,
where x is a hexadecimal digit.

Chapter XII: System Services, Reenterability, and Recursion

949

Simple Scenario, Step 5: GETting a record


The GET macro points to the DCB and to the Record Buffer, and calls the Access Method routines to read a record from the Data Set and place it in the Record Buffer. For example, you
might write
GET

MyDCB,RecBuf

Read a record from MyDCB into RecBuf

If you specified an end-of-data address (EODAD, described below) in the DCB, control goes
there when there are no more records in the Data Set.

......

DDName JCL

OPEN

......

JFCB


GET  DCB

 Label Data
......

Set


CLOSE
 Access
......
Methods

A Data Set Record 

Figure 752. Your program after executing the G E T macro

Simple Scenario, Step 6: CLOSEing the DCB


When youre finished, you execute a CLOSE macro: it specifies the name of the DCB you want
to close. Your DCB is restored to its initial status; the Data Set Label is updated if necessary (if
you wrote to the Data Set), and the updated JFCB is retained in case you want to re-OPEN the
Data Set.

950

Assembler Language Programming for IBM z System Servers

Version 1.00

......

OPEN

......

GET
DCB

......

CLOSE

......

Record Buffer

DDName JCL

Updated
JFCB


Label Data
Set

Figure 753. Your program after executing the CLOSE macro

Your program has been restored (almost) to its initial state, except for changes you may have
made to data fields and work areas. The program then tidies up, and returns to the system.
This brief scenario should help you follow the details to follow.
41.6.2. Access Techniques and Access Methods

There are many access techniques available for data. Data items can be written or read sequentially (one after the other); directly (put the item in a specific position in a data set, or read it from
that position, ignoring other items); by index (a field in the data is used to identify it), and so on.
Each of these can be very complex; we will examine only sequential access, and only in its simple
forms.
There are two main ways to read or write data sequentially:
Basic

You manage blocks of data, independent of any internal structure each block may have,
such as multiple records; you must organize the data items in each block. Each I/O
operation is initiated by a READ or WRITE macro, and synchronization of the I/O
operations with read or write completion is done with CHECK and WAIT macros.

Queued

You manage individual data records. The Supervisor does almost everything for you: it
handles I/O operations, synchronization of I/O activity and data availability, blocking
and deblocking records, etc. Reading and writing records is done with macros like GET
and PUT.

We will describe only the simplest form, queued access.


There are several ways to manage records using queued access; the simplest forms are called
BSAM (Basic Sequential Access Method) and QSAM (Queued Sequential Access
Method). 288 Depending on values in your DCB, the system will load appropriate access method
routines to support the various types of data movement.
With QSAM, you can choose one of the following modes (among others):

288

Pronounced Bee-Sam and Cue-Sam.


Chapter XII: System Services, Reenterability, and Recursion

951

Move mode
Your GET macro points to your buffer where the system should place your input record; or,
your PUT macro points to your buffer from which the output record should be written by
the system.
Locate mode
Your GET macro returns a pointer to where your input record can be found; your PUT
macro returns a pointer to where your output record should be placed.
In practice, QSAM is far easier to use than BSAM; Table 429 illustrates some differences.
QSAM
Supports all record formats
Your interface is logical records
Automatic blocking and deblocking
Automatic buffer management
Automatic I/O operation synchronization

BSAM
Supports all record formats
Your interface is physical blocks
Blocking and deblocking is your problem
Buffer management is your problem
Synchronizing I/O operations with use of
the data is your problem

Table 429. Comparing QSAM and BSAM


41.6.3. The Data Control Block (DCB)

The DCB macro is a complex structure, with nearly 100 parameters (almost all of which you
wont care about), some of which can have as many as 30 valid values (almost all of which you
wont care about). It is a part of your program. Some values in the DCB can come from other
sources, such as JCL DD statements, a data set label, and from your program during execution.
All fields must be completed by the end of the OPEN process, before I/O operations can begin.
The DCB contains 3-byte address fields such as the address of the access method routines and the
EODAD and EXLST addresses described below, so it must reside below the 16MB line.
You must specify the DSORG and MACRF arguments at assembly time; and if you intend to
provide a DCB OPEN exit to examine and/or modify the DCB during the OPEN process, you
must specify the EXLST argument. Values for other arguments can be supplied during OPEN by
the JCL DD statement, the data set label, and the OPEN exit.
DSORG

Must be coded in DCB macro; the most usual values are:


PS

PO

Physical Sequential: strictly sequential access. Both of the following are defined
when you specify PS:
BS

Basic Sequential: strictly sequential access.

QS

Queued Sequential: strictly sequential access.

Partitioned Organization, for libraries, which are collections of sequential data sets
identified by a member name thats contained in a directory. All members have
the same characteristics, and are accessed sequentially. The access technique for
members of a library is called BPAM289 (Basic Partitioned Access Method);
members are located with the FIND macro, and read and written with READ
and WRITE macros.

If you code more than one DSORG value, you can re-OPEN the DCB for a different
type of I/O after closing for the previous use.
MACRF

289
290

952

Must be coded in DCB macro; dont omit it. 290 These QSAM forms are the simplest to
use:

Pronounced Bee-Pam.
If you omit a MACRF value, the assembly will assign the default E (with severity 8), which means (if you proceed)
that you must write your own device-dependent channel programs and do everything yourself. Its quite difficult.
Assembler Language Programming for IBM z System Servers

Version 1.00

GM

Get Move: Logical record processing, move mode input. The access method routines reads blocks of records into internal buffers, unblocks your record for you,
and moves it to the work area you defined as the second operand of the GET
macro. Your work area must have the same length as the record!

PM

Put Move: Logical record processing, move mode output. You tell the PUT
macro where your record is; the system moves it to its internal buffer for output
when the buffer is full.

GL

Get Locate: Logical record processing, locate mode input. The access method
tells you where in its internal buffers the record is.

PL

Put Locate: Logical record processing, locate mode output. The access method
tells you where to put your record in its internal buffer.

These are some other arguments that can be supplied during initialization or execution.
DDNAME

Can be coded in the DCB macro, or supplied by the program before OPEN

RECFM

Figures 755-757 illustrate the following record formats.


F

Fixed length unblocked records (BLKSIZE=LRECL)

FB

Fixed length blocked records (BLKSIZE=nLRECL)

Variable length unblocked records

VB

Variable length blocked records

Undefined (None of the above)

xxA

Records have ANSI carriage-control characters in the first byte

LRECL

The length of each F record, or the maximum length for V records. Often omitted for
input data sets; it can be supplied from the data set label at OPEN time. The LRECL
field is updated after each read of a record or block.

BLKSIZE

The maximum length of a block; for FB, it must be a multiple of the LRECL value;
for VB, the maximum block length.

EODAD

For reads, the address to receive control on End of Data (EOD). The EOD routine
can either return to the address in GR14 on entry, or continue normal processing (this
is the most common way). If no EODAD address is provided at end of data, or if you
try to read after the end of data, the system will terminate your program with a 337
ABEND.
The 3-byte address of the EODAD routine means that it will be entered in 24-bit
addressing mode, so it must reside below the 16MB line. It can of course change
addressing modes so long as it changes back to 24-bit mode before returning to the
system.

EXLST

The exit list specifies special exit routines; the DCB OPEN exit is the most most usual,
for which you specify the name of a word-aligned list of the form
X 8 5 , AL3(OPEN-exit_routine). The DCB OPEN exit routine can modify or complete
a DCB before the data set is completely open.
When it receives control, the low-order 3 bytes of GR1 point to the DCB (remember
that the DCB and the OPEN exit must be in 24-bit storage). GR14 must be preserved
and used to return to finish OPEN processing. You must not use the address in GR13
for a save area, and you need not preserve the contents of GRs 2-13 (the system does
that).

A typical DCB statement might look like this:

Chapter XII: System Services, Reenterability, and Recursion

953

dcbname

DCB DDNAME=xxxxxxxx,
MACRF=xx,
DSORG=xx,
LRECL=nnn,
BLKSIZE=nnnnn,
RECFM=xx,
EODAD=xxxxxxx

To match up with the JCL DDName


Macro Format: how to process records
Data Set Organization
Logical Record Length
For blocked records
Record Format
End-of-data address for input
column 72

X
X
X
X
X
X

Figure 754. Example of typical DCB parameters


41.6.4. Important Record Formats

Fixed: all records have the same length, and may be grouped into blocks containing (usually)
a fixed number of records. Its best to have no truncated (partially filled) blocks except the
last.

Recfm F:

Recfm FB:


Record Record Record Record

Potentially very slow!


RecordRecordRecord RecordRecordRecord

 Block 
 Block 

Figure 755. Unblocked and blocked F-type record and block formats

Variable: each record is preceded by a 4-byte Record Descriptor Word (RDW) giving the
record length in the first two bytes; that length includes the 4-byte length of the RDW.
V-format records may be blocked; a block of records is preceded by a 4-byte Block Descriptor
Word (BDW) giving the length of the block (including its own length) in the first two bytes.
For both the BDW and RDW, the remaining two bytes must be zero.

Recfm V:

Recfm VB:


RDWRecd RDW Record RDWRecord RDW=Record Descriptor Word

BDWRDWRecdRDW Record RDWRecord

 Block 

BDW=Block Descriptor Word

Figure 756. Unblocked and blocked V-type record and block formats

Undefined: A single physical record; do any blocking/unblocking (if needed) yourself. You
must understand the internal structure of U-format blocks that you read or write.

Recfm U:

Block
Block
Block

Figure 757. U-type block formats


41.6.5. Opening the DCB

Figure 758 on page 955 and the following explanations outline the steps taken during initialization of a DCB by OPEN:

954

Assembler Language Programming for IBM z System Servers

Version 1.00

1

5

Original DCB  Working DCB  DCB Exit

4
6

2

JCL DD Stmt 
JFCB

3
7

Old Data
New Data
Set Label
Set Label

Figure 758. Completion of a DCB during OPEN processing

1

The settings of the original DCB are saved so they can be restored when the DCB is closed.

2

Data from the JCL DD statement was used to create the Job File Control Block (JFCB).

3

Fields in the JFCB not already completed are filled from the data set label.

4

Fields in the DCB not already completed are filled from the JFCB.

5

If a DCB OPEN exit exists, it is given control to make any desired modifications to the
DCB.

6

The merged and updated fields from the DCB are copied back into the JFCB.

7

If the data set has been opened for output, fields from the JFCB are used to create the new
data set label.

OPEN then chooses and loads access method routines according to your choices of DSORG,
buffering technique, access technique, and device type. If OPEN fails, you normally get a system
013 ABEND.
41.6.6. Closing the DCB

To close a DCB and terminate I/O to that DDName, simply write


CLOSE dcbname
For the QSAM macros weve seen, you should follow that with
FREEPOOL dcbname
so the access method routines will free the storage they acquired for internal buffers.
41.6.7. The DCBD Macro and the IHADCB Dummy Section

The DCBD macro generates symbolic names for all DCB fields, in the IHADCB Dummy Control
Section. You specify at most two arguments:
DCBD DSORG=xx,
DEVD=xx

Data Set Organization(s)


Device type(s)

Figure 759. DCBD operands

DSORG

Types of access for which your DCBs were written.

Chapter XII: System Services, Reenterability, and Recursion

955

DEVD

Specifies the types of devices to be included.

However, if you write


DCBD DSORG=(PS,PO)

Data Set Organization(s)

Figure 760. DCBD operands

then the presence of the PS argument means you can omit the DEVD argument entirely.
If you code multiple DSORG values, you can use IHADCB to refer to multiple DCBs.
Important fields defined in the IHADCB DSect are the DCBOFLGS byte, which contains the
DCBOFOPN bit you should test to verify that the DCB OPENed correctly, and the DCBLRECL field
that you must use when reading and writing V- and U-format records.
For example, you can use the IHADCB dummy section to map each DCB in your program, with
the help of Labeled Dependent USING statements:

Sysin

Sysou

OPEN
LA
USING
TM
JZ
LA
USING
TM
JZ

(SYSINDCB,INPUT,SYSOUDCB,OUTPUT)
11,SYSINDCB
Point to SYSINDCB
IHADCB,11
Map it with IHADCB
Sysin.DCBOFLGS,DCBOFOPN Test if OPEN was successful
BadSysin
Go take recovery action
11,SYSOUDCB
Point to SYSOUDCB
IHADCB,11
Map it with IHADCB
Sysou.DCBOFLGS,DCBOFOPN Test if OPEN was successful
BadSysou
Go take recovery action

Figure 761. Using IHADCB to map two different DCBs simultaneously


41.6.8. The DCBE Macro and 31-bit Address Mode

All the I/O examples weve seen were required to execute in 24-bit addressing mode, and therefore
reside below the 16MB line. There are other macros (like DCBE, the DCB Extension) that let
you put things like buffers and exit routines above the line. This can be important if available
storage below the line is limited. To learn more, see the Data Sets references in the Bibliography on page 1041.
41.6.9. I/O Summary

This has been a very simple overview of a vast and complex subject. z/OS supports the richest
variety of facilities among modern operating systems, while some other operating systems have
extremely simple I/O models. Most programs need only a small and useful subset of all the capabilities z/OS offers.
Why use BSAM? If you have large volumes of data in which records can be processed independently, you can assign parallel tasks to process the records in each block as it is read. This can give
higher rates of throughput than QSAM could support, because QSAM handles one record at a
time.
Another popular access method is the Virtual Storage Access Method (VSAM), which supports
sequential, direct, and indexed access. It requires different macros and control, and its flexibility
(and complexity) is beyond the scope of this text.
Some general guidelines:
Specify INPUT or OUTPUT (etc.) on the OPEN macro
Omit device-dependent parameters and macros when possible, to allow for varied devices,
record formats, etc. at execution time. Put device-dependent and data-set-specific information
on the DD statement.

956

Assembler Language Programming for IBM z System Servers

Version 1.00

Dont code more in the DCB than is required to ensure correct processing. Other parameters
can be completed during initialization or execution.291
Avoid unblocked records: there is a potential performance penalty in time and CPU costs. 292
A DCB can be used for multiple data sets so long as it is closed before opening for a different
data set. May need to modify fields if any differences in data set characteristics.
41.6.10. A Sample Program

This sample program uses the macros described above to write a printable record.
Sample
Sample
Sample

CSect ,
AMode 24
RMode 24
STM 14,12,12(13)
Save caller s registers
LR
12,15
Copy base register
Using Sample,12
Establish addressability
LR
2,13
Copy caller s save area address
LA
13,Save
Point to local save area
ST
2,Save+4
Store back chain
ST
13,8(,2)
Store forward chain
OPEN (PrintDCB,(OUTPUT))
Open the print DCB
PUT PrintDCB,Line
Output the message
CLOSE PrintDCB
Close the print DCB
FREEPOOL PrintDCB
Release buffers
L
13,Save+4
Restore caller s save area address
RETURN (14,12)
Restore registers
BR
14
Return
Line
DC
CL121 1 Greetings from a sample program
Print NoGen
PrintDCB DCB DSORG=PS,MACRF=PM,LRECL=121,BLKSIZE=121,RECFM=FA,
X
DDNAME=PRINT
Save
DC
9D 0
Local save area
End
Figure 762. A complete sample program

The output of this little program is:


1Greetings from a sample program

41.7. Handling Program Interruptions


Programs can handle their own exception conditions on two levels:
1. Program interruptions can be investigated using a Program Interruption Exit; in the
absence of an exit, the system will generate an ABEND using SVC 13, as illustrated in
Figure 739 on page 942.
2. Abnormal terminations (ABENDs) can be investigated using a Task Abnormal Termination
Exit that receives control on an ABEND. You can use an abnormal termination exit routine
to handle program interruptions, but the interface is more complex than for a program interruption exit (see Section 41.8 on page 961).

291

292

Some systems will assign an optimum BLKSIZE for output data sets depending on its physical properties, and for
input data sets based on its existing BLKSIZE.
I once saw a case where a program reading unblocked 80-byte records took nearly 10 minutes of elapsed clock time,
but completed in about 10 seconds when the input data set was adequately blocked. (It was an old, slow machine.)
Chapter XII: System Services, Reenterability, and Recursion

957

The basic mechanism used by the CPU for handling interruptions is illustrated in Figure 763 (also
shown in Figure 16 on page 58).

 FETCH  DECODE  EXECUTE



no
Any Interrupts?

yes


no
yes

Any other Load New PSWNote interruption cause, A


interrupts?
from Memory
save Old PSW, status info

Figure 763. Instruction cycle with interruptions

After determining at A that the interruption can be processed, the system analyzes the cause and
checks whether an exit routine has been established (by the interrupted program) for that type of
interruption.
41.7.1. Program Interruptions

If a program interruption exit has been established, the system saves relevant status information in
a work area called a Program Interruption Element or PIE, and the exit routine is given
control with a pointer to the work area.
Your program can receive control when any of the 15 program interruptions occurs if the exit
routine has requested control. The exit can take corrective action if it chooses.
You can also establish multiple exits: each supersedes the previous, and you can terminate them
as needed. Only one exit is active at a time.
41.7.2. Establishing a Program Interruption Exit

Use the ESPIE or SPIE 293 macro to establish a Program Interruption Exit. SPIE is for applications using only 24-bit addressing, while ESPIE is for 24- or 31-bit mode applications; well use
ESPIE for our examples.
The expansion of either macro creates a small Program Interruption Control Area, or PICA *
that defines a data structure with the address of the exit routine, a pointer to an argument list to
be passed to your exit, and mask bits indicating which of the 15 program interruption types
should cause the system to pass control to your exit.
For example, to request that your exit routine named ProgInt be given control for any of the 15
possible program interruption types, you can write
ESPIE SET,ProgInt,((1,15))
Figure 764. Establishing a program interruption exit

where the first operand SET establishes the exit, the second operand is the name of your exit
routine, and the third operand specifies interruption types 1 through 15. The expansion of this
macro is shown in Figure 765 on page 959, where the PICA is in statment numbers 16-20.

293
*

958

The macro names can be understood to mean (Extended) Set Program Interruption Exit.
This PICA is unrelated to typography or cravings for unnatural foods.
Assembler Language Programming for IBM z System Servers

Version 1.00

00000C
00000C 4D10 C020

00020
00010

000010
000014
000018
00001A
00001C
000020
000024
000028
00002A

00000038
00000000
7FFF
0000
00000000
4100 0004
41F0 001C
0A6D
5010 C09C

00004
0001C
0009C

11
12+*
13+
14+
15+IHB00002
16+
17+
18+
19+
20+
21+
22+
23+
24

ESPIE SET,ProgInt,((1,15))
MACDATE = 08/15/81
CNOP 0,4
BAS 1,*+20
EQU *
DC
A(ProgInt)
USER EXIT ROUTINE ADDRESS
DC
A(0)
USER PARAMETER LIST ADDRESS
DC
B0111111111111111 INTERRUPTION MASK
DC
B0000000000000000
DC
A(0)
RESERVED
LA
0,4
SET FUNCTION CODE
LA
15,28
SVC ROUTER CODE
SVC 109
ST
1,MyToken
Save token

Figure 765. Expansion of an ESPIE macro establishing a program interruption exit

The 2-byte bit string in statement 19 contains a 1-bit for each type of program interruption you
want to examine; in this case, all 15.
When the ESPIE macro is executed, the system first creates an Extended Program Interruption
Element (EPIE) that will hold data about an interruption when it occurs, and then returns a
4-byte token in GR1 for you to save.
Maskable Interruptions
If your program has set the Program Mask to disable any of the four
maskable interruptions (fixed-point overflow (8), decimal overflow (9),
HFP exponent underflow (13), or HFP lost significance (15) specifying
any of those exceptions in a SPIE or ESPIE macro will re-enable that
exception.
For more information about the maskable exceptions, see the initial description at 4.6.
Exceptions and Program Interruptions (*) on page 59 and the examples of the SPM instruction
at 16.9. Retrieving and Setting the Program Mask (*) on page 235.
41.7.3. Terminating a Program Interruption Exit

The token returned to you when you established an exit identifies the PICA generated by the
previous ESPIE macro (if any); you use it when you want to cancel the current program interruption exit and restore control to any previous exit.
You can consider program interruption exits as a stack of programs: the most recent is on top of
the stack. Then, if another module in your program establishes its own program interruption exit,
when that second exit is canceled, the most previously established exit resumes effect.
Note that if the active exit does not process a given type of program interruption, control is not
passed down the stack to an earlier exit; the program will be ABENDed by the system.
To terminate the current program interruption exit, issue an ESPIE macro with the RESET
operand, and the token that you received when you established the exit:
ESPIE RESET,MyToken

End current exit

Figure 766. Terminating a program interruption exit

The expansion of this macro is shown in Figure 767:

000052
000056
00005A
00005E

5810 C0AC
4100 0008
41F0 001C
0A6D

000AC
00008
0001C

770
771+*
772+
773+
774+
775+

ESPIE RESET,MyToken
MACDATE = 08/15/81
L
1,MyToken
LA
0,8
LA
15,28
SVC 109

GET TOKEN
RESET FUNCTION CODE
SVC ROUTER CODE

Figure 767. Expansion of an ESPIE macro terminating a program interruption exit

If you want to cancel all program interruption exits, specify a zero token:
ESPIE RESET,0

Cancel all exits


Chapter XII: System Services, Reenterability, and Recursion

959

41.7.4. Handling a Program Interruption

When a program interruption occurs and the currently active PICA requests control, the system
places information in the EPIE:
the general registers in effect at the point of interruption
the 8-byte ESA/390-mode old PSW (see Figure 768), containing

the address and addressing mode of the instruction following the interrupted instruction (IA
and A in Figure 768)

the condition code, program mask (see CC and PM in Figure 768) and the instruction length
code

the interruption code and Data Exception Code; if the DXC field is zero, the exception was
due to invalid decimal data; otherwise, see Section 34.4.1. on page 636 for a description of
possible floating-point exceptions

16
2 2 4
8
1
31
bit widths
//

ILCCC PM
0 A
Instruction Address

//
Figure 768. ESA/390-mode old PSW in EPIE

The most useful contents of the EPIE are sketched in Table 430. (The full EPIE is described in
the MVS Data Areas manual referenced in the Bibliography on page 1041.)
Offset
(dec)
0
4
8
72
74
76

Offset
(hex)
0
4
8
48
4A
4C

Length

Type

Description

4
4
64
8
1
4

CL4
A
XL64
XL8
BL1
A

51
53
57
99

1
1
1
1

BL1
XL1
BL1
BL1

A0
120
128

128
8
16

XL128
XL8
XL16

Control block identifier C EPIE


Parameter list address
32-bit GPRs at time of interruption
8-byte ESA/390 old PSW at time of interruption
Condition Code and Program Mask
AMODE bit and 31-bit address of next instruction to execute
Instruction Length code (bit positions X 0 6 )
Interruption code
Data Exception code (if Interruption code is 7)
Set bit X 4 0 to resume execution by restoring the
64-bit GPRs rather than the 32-bit GPRs
64-bit GPRs at time of interruption
Breaking Event Address
16-byte old PSW at time of interruption

81
83
87
153
160
288
296

Table 430. Partial contents of Extended Program Interruption Element (EPIE)

Using the information in the EPIE, your Program Interruption Exit can do many things, such as:
1. Examine the interruption condition and do nothing; simply return to the address in GR14 on
entry to the exit routine.
2. Print an error message and resume execution at the next instruction.
3. If the interruption was due to invalid data, analyze the instruction to determine where the
data is; then try correcting the data or the register pointing to it. Then use the ILC in the
EPIE to subtract the length of the interrupted instruction from the old PSW, and try again

960

Assembler Language Programming for IBM z System Servers

Version 1.00

(being sure to remember that this is a second try, so you dont create an interruption
loop!).294
4. Modify the old PSW address in the EPIE so that control will resume at a different place in
your program after your exit returns via the system.
5. If your exit determines that continuing execution is a bad idea, set bit 1 0 at offset 153
(X 9 9 ) and return to the system; it will automatically issue an ABEND. (Dont modify anything else in the EPIE.)
Many other possibilities will come to mind.
Be Careful!
1. The linkage from the system to your program interruption exit is not
standard: do not try to save any registers in the callers save area.
2. If you do I/O from your exit routine, you must establish a local save
area pointed to by GR13. Because they are used by I/O routines,
you must first preserve GR14, GR15, GR0, and GR1.
3. Your exit routine must return to the interrupted program via the
return address in GR14 when the exit was entered.

Exercises
41.7.1.(2)) + Write short examples of instruction sequences that will cause each of the 15 types
of program interruption. (You will want to use this information when you solve Programming
Problem 41.6.)

41.8. Abnormal Terminations of Any Kind


Note!
This topic is quite complicated; this section can at best give a brief
outline of its key components and actions. For a detailed overview, see
the topic Providing Recovery in the MVS Assembler Services Guide,
referenced in the Bibliography on page 1041.
As when you establish an exit to handle program interruptions with ESPIE, you can specify a
routine to be given control on any abnormal termination condition. That routine (called a
recovery routine) can capture information about the cause and location of the problem, maybe
take remedial action to repair or bypass the error and resume execution at a chosen point in your
program, or release any resources the program may have acquired and terminate a bit more
gracefully.
The overall flow of control can be visualized in simplified form in Figure 769 on page 962:

294

On a very early System/360 Model 67, one particular program interruption at an address at a specific offset from a
doubleword boundary would resume execution not at the next sequential instruction, but at the previous doubleword
boundary. If that was the address of the interrupted instruction, an interruption loop would occur.
Chapter XII: System Services, Reenterability, and Recursion

961

1
2
Application Normal
Program
End

3
4

Interruption System

Your ESTAE

Recovery

System
System Routine(s)




6

  5 

Percolate 
RTM
7

Retry Routine 

Figure 769. Sketch of interruption handling control flow

In this basic scenario, you are responsible for writing three routines: the Application Program 1,
the ESTAE recovery routine(s) (ESTAE exit(s)) 4, and the Retry Routine 7. These can be
separate programs, or parts of the Application Program.
Under normal conditions, you expect the Application Program to complete with a Normal End
2, and control passes to the Recovery/Termination Manager (RTM) to do any necessary final
actions. If an Interruption 3 occurs, or if your Application Program 1 issues an ABEND
macro, the System will give control to the most recent of your Recovery Routines 4, and
provide useful information in a System Diagnostic Work Area (SDWA). If no Recovery
Routine is available, control will pass directly to the Recovery/Termination Manager (RTM) 5,
which will do its best to clean up any resources held by your program and generate whatever
diagnostic information it can.
Assuming a Recovery Routine is available, you can make several choices:
1. You can decide that the problem cannot readily be fixed, generate as much diagnostic information as you can, and pass control to the RTM 5 to terminate execution (possibly with
additional diagnostic information such as a memory dump).
2. You can choose to do some repairs and pass control to the Recovery/Termination Manager
5, or you can decide that the problem may be identifiable by the next of the Recovery
Routines on the exit stack, and indicate to the System that recovery control should
percolate 6 to the next exit routine.
3. You can process the interruption condition so that it is partly or completely repaired, and
decide to pass control back to the application program by way of the Retry Routine 7; it
can complete fixing the problem, or completely bypass it.
Both percolation and retry require the SETRP macro, which well review on page 964.
The most general form of exception handling is provided by the STAE, ESTAE, and ESTAEX
macros, 295 all of which support Standard, List, and Execute forms.
STAE was the earliest form, and executes only in 24-bit addressing mode. ESTAE was introduced
next, and executes in both 24- and 31-bit modes. ESTAEX is the most general form, and can
execute in all three modes. (See the details in the Assembler Services Reference manual listed in
the Bibliography.) The following discussion will use ESTAE; ESTAEX is very similar.

295

962

The names are generally understood to mean (Extended) Specify Task Abnormal Exit.
Assembler Language Programming for IBM z System Servers

Version 1.00

41.8.1. The ESTAE Macro

Issuing ESTAE establishes an exit routine that will be given control on an abnormal termination
condition in your program. If you issue multiple ESTAEs, you can either replace the current exit
with a new one (like ESPIE), or (unlike ESPIE) you can form a chain or stack of exit routines, each of which can decide to take corrective action, or to pass the problem to the previous
exit routine. This passing of control is called percolation.
Because program interruptions can also cause an abnormal termination, an ESTAE exit can also
process program interruption conditions, but the interface is both more powerful and much more
complex than ESPIEs.
The ESTAE macro has this general form:
ESTAE two_positional_operands,multiple_keyword_operands
These are the most important operands for most programs; default values are underlined.
exitname

This is the first positional operand, giving the entry point name of the recovery
routine to be placed at the top of the exit stack.
If you specify 0 for this operand, the name of the current exit routine (at the top of
the stack) is removed.

CT|OV

This second positional argument is either CT or OV. Specifying OV means that the
current exit routine will be replaced (overlaid) by the new one provided in the
first operand. Specifying CT means that the new exit routine will be added
(concatenated) to the top of the stack of exit program names. It will be entered
first by the operating system when an interruption occurs, but it can percolate
control to the previous exit routine.

PARAM=

This keyword operand specifies the address of a parameter area created by the
Application Program that can provide useful information for the Recovery
Routine, and where that routine can place data that may be useful for the application.

PURGE=

This keyword operand specifies the actions you want to take with currently active
I/O operations.

ASYNCH=

SDWALOC31=

NONE

Dont do anything; let the operations continue. (This means that any
interruptions caused by the active I/O could cause re-entry to your exit
routine.)

QUIESCE

Save the status of pending I/O requests so they can be restarted if


desired. Currently active I/O operations will be purged.

HALT

Dont save pending requests. Currently active I/O operations will be


purged.

This keyword operand specifies whether certain types of interruption should be


allowed while your recovery routine is in control:
NO

No other interruptions should be allowed.

YES

Must be specified if your exit routine will request system services that
could generate interruptions, or if you specified PURGE=QUIESCE or
PURGE=NONE and interruptions are required to complete processing of
certain I/O activities.

You can specify whether the System Diagnostic Work Area (SDWA) created by
the System should be located in 24- or 31-bit addressable storage:
NO

The SDWA will be in 24-bit storage.

YES

YES is required if the application program is running in 31-bit addressing


mode, or if it is using 64-bit general registers.

The satisfactory-completion return codes (in GR15) from ESTAE are 0 and 4 (you specified OV
but there was no previous exit to overlay, so the System treated your request as though you had
specified CT). All other return codes indicate an error.
A simple example of an ESTAE macro is shown in Figure 770 on page 964:
Chapter XII: System Services, Reenterability, and Recursion

963

000000
000000 A715 000E
000004 16
000005
000008
00000C
000010
000011
000012
000014
000018
00001C
000020
000024

000000
00000084
00000000
00
01
0000
00000000
00000080
4100 0100
4110 1000
0A3C

0001C

00100
00000

4
7+
8+
9+
+
10+
11+
12+
13+
14+
15+
16+
17+
18+
19+
20+

ESTAE
CNOP
BRAS
DC

EXIT,PARAM=PLIST
0,4
1,*+28
AL1(22)

DC
DC
DC
DC
DC
DC
DC
DC
LA
LA
SVC

AL3(0)
A(PLIST)
A(0)
AL1(0)
AL1(1)
AL2(0)
A(0)
AL4(EXIT)
0,256(0,0)
1,0(0,1)
60

ESTAB. FULL WD. BOUND. ALIGN.


LIST ADDR IN REG1 SKIP LIST
FLAGS FOR TCB, PURGE,
X
ASYNCH AND CANCEL
FIELD NO LONGER USED
STAE EXIT PARM. LIST ADDR.
SPACE FOR TCB ADDR
FLAGS FOR TERM,RECORD,SDWALOC31
THIRD FLAG BYTE
RESERVED
SPACE FOR TOKEN
FOUR BYTE EXIT ADDR
CREATE & PARMLST EQ 0
MAKE REG1 POS. XCTL=NO
ISSUE STAE SVC

Figure 770. A simple ESTAE macro.

You can see the references to the exit and parameter-area addresses; the other fields are for arguments we havent discussed.
41.8.2. Interruption Processing

Your ESTAE exit receives control from the System in the addressing mode that was in effect
when the ESTAE macro was issued, not in the current mode. You should do several things first:
1. Save the return address in GR14, so you can return control to the System, and GR2 contains
the address of the parameter area that you specified on the PARAM= operand of the ESTAE
macro. (The parameter area address is also in the SDWA field SDWAPARM.)
2. Test GR0:
If c(GR0)=12 (X 0C ), no SDWA has been provided by the System, and GR13 does not
point to a save area. Your options are quite limited, and its best to terminate the
program.
If c(GR0) 12, GR1 holds the address of the SDWA, GR13 points to a standard save
area, and the address of the parameter area is also in the SDWAPARM field of the SDWA.
(The names of the SDWA fields are defined in the DSECT generated by the IHASDWA
macro, and described in the MVS Data Areas manual listed in the Bibliography.)

The completion code (also known as the ABEND code) is in the SDWAs SDWACMPC
field, and if the SDWARCF bit is 1, the SDWACRC contains the reason code (that you could
have provided on an ABEND macro).

Check the SDWAPERC bit: if its 0, this is the first recovery routine, and there has been no
previous percolation.

The information provided by the System in the SDWA to the exit routine is very rich, including
the contents of the general registers, the 8-byte PSW in effect at the time of the original ABEND,
and other useful data. The SDWA is described in the MVS Data Areas manual; see the Bibliography for details.
Your recovery routine may need to communicate with the application program. The best way to
do this is to use the parameter area you specified on the PARAM= operand of the ESTAE macro.
This area can contain addresses of parts of the application program and of acquired storage,
addresses that may need to be used to locate data or that may be needed by your retry routine.
41.8.3. Percolation and Retry

If your exit wants to percolate to another exit, or retry execution at a point in the application, it
must issue the SETRP (Set Return Parameters) macro, described in the Assembler Services Reference manual. Depending on the arguments on the SETRP macro when you have used it to return
control to the System, the System will percolate to the next exit routine on the exit stack, or
give control to your retry routine.
Note that if the SWDACLUP bit in the SDWA is 1, retry is not allowed.
The general form of the macro is:

964

Assembler Language Programming for IBM z System Servers

Version 1.00

SETRP keyword_arguments
You should use SETRP only if the System provided a SDWA to your exit routine. If there is no
SDWA, its best not to retry.
These are the most important operands for most programmers; default values are underlined.
RC=

0|4. This argument specifies whether you want to percolate (0) or retry (4).

REGS=

(reg1,reg2). The register or range of registers to be restored from the standard save
area addressed by GR13. Specify the register values as you would for a Load Multiple instruction: (reg1,reg2). The macro will generate a BR 14 instruction to
return control to the System. (If you omit this argument, you must create your own
branch instruction to return control to the System.)

The following arguments may be specified only if you specified RC=4 (retry).
RETADDR=

The address of your retry routine. It can be a separate routine; your exit routine can
request that the System resume execution of your program at whatever point you
choose.

FRESDWA=

NO|YES. This argument specifies whether (YES) or not (NO) you want the SDWA to
be freed before your retry routine receives control. If you specify NO, the retry
routine must free the SDWA, using length and subpool information in the SDWA.

There are many other macro operands not mentioned here; see the MVS Assembler Services Reference in the Bibliography for details.
Percolation: If you chose to percolate (RC=0) its best to repair as much of the problem as possible, such as releasing unneeded resources, depending on the type of interruption.
Before you issue the SETRP macro to return control to the System (and then to the next recovery
routine on the exit stack), check whether a SDWA was provided: if not, set c(GR15) to zero. If
yes, you could update the SDWA with data that might be useful if and when the program continues, or is terminated.
When the SERTP macro passes control to the system, the system removes the current ESTAE
exit from the top of the exit stack; if the stack is now empty, the system will abnormally terminate your program and control will pass directly to the RTM.
Retry: If you choose to retry (RC=4), you are passing control back to the Application Programs
retry routine (which can be an existing module or part of the application). The current ESTAE
exit on the top of the exit stack is not freed. If your retry routine creates another interruption,
control will pass to the same recovery routine that just gave control back to the application via
the retry routine. Be careful: you could cause an error-processing loop.
41.8.4. Summary

This topic is far more extensive than this overview can properly describe. The cited references
provide all the information you may need.
From your perspective (not the Systems!) you can think of your program as being in one of
several states:
1. Executing; it is doing what it was intended to do.
2. In your ESTAE-exit recovery routine, your program having created an interruption condition.
3. Abnormal end: no recovery routines, or your recovery routine(s) failed.
4. Terminated.
From the Systems perspective, your program can be in several states:
1. Executing; doing something.
2. Having executed an ESTAE macro, which creates an exit that can then be in one of four
states:

Chapter XII: System Services, Reenterability, and Recursion

965

a. Defined and activated: known to the System; you provided an exit name on ESTAE,
and available to receive control if an interruption occurs.
b. In control; the System has passed control to the exit.
c. No longer in control, because it has either percolated or retried.
d. Deactivated and undefined: the System will no longer pass control to it, and not known
to the System.
3. Terminating abnormally: you provided no exit routines, or your exit routines failed.
4. Terminating normally.

41.9. Summary

Instructions Discussed in this Section


The instruction mnemonics and opcodes are shown in the following table:
Mnemonic
PC

Opcode
B218

Mnemonic
SVC

Opcode
0A

The instruction opcodes and mnemonics are shown in the following table:
Opcode
0A

Mnemonic
SVC

Opcode
B218

Mnemonic
PC

Programming Problems
Programming Problem 41.1.(1) Revise the little program in Figure 33 on page 83 to use system
macros rather than PRINTOUT.
Programming Problem 41.2.(3) + Write a program to read 80-byte fixed length records, and
write them to a 121-byte print data set (with carriage-control characters), preceded by a
sequence number giving the number of the input record. Verify that each DCB opened correctly, and take appropriate actions to notify the user if not.
For sample input records, you can use the data from Programming Problems 24.13 or 24.14.
on page 401.
Programming Problem 41.3.(3) + Write a program with a program interruption exit that generates each the 15 possible interruption types in turn. For each interruption, generate a message
describing the interruption type and the address of the interrupted instruction. Then, return to
the mainline program to generate the next interruption.
Programming Problem 41.4.(1) + Write a program using ESPIE to establish a program interruption exit, and display the token returned in GR1. Then establish a second exit, and display
the token returned in GR1. Can you determine what it might refer to? Then, use the RESET
option of ESPIE to terminate both exits.
Programming Problem 41.5.(3) + Write a short program that issues an ESPIE macro that designates an exit routine in your program. Then, generate a program interruption that causes entry
to your ESPIE exit routine. The exit should display (print) information about the interruption:

966

Assembler Language Programming for IBM z System Servers

Version 1.00

the interruption code


the address of the failed instruction
the failed instruction
any relevant register contents
any relevant storage fields
anything else that might be helpful

Then, return to the main program following the failed instruction, to complete execution
normally.
Programming Problem 41.6.(4) + Using your solution to Programming Problem 41.5 as a
starting point, write a program to generate as many of the 15 program interruptions as you can,
displaying the same information as before, plus any additional information you believe may be
useful. (For example, for a decimal data interruption, show the invalid operands; this may
require calculating some Effective Addresses.) (Your solution to Exercise 41.7.1 will be useful.)
Programming Problem 41.7.(3) + Write a program with an ESTAE exit. Then, generate a
program interruption as in Programming Problems 41.5 or 41.6. Your recovery routine should
provide at least the same information as in Problem 41.5.
Programming Problem 41.8.(4) Write a program with an ESTAE exit, and generate an interruption condition other than a program interruption, and provide at least the same information
as in Problem 41.5.

Chapter XII: System Services, Reenterability, and Recursion

967

42. Reenterability and Recursion

444
4444
44 44
44 44
44 44
44444444444
444444444444
44
44
44
44
44

2222222222
222222222222
22
22
22
22
22
22
22
22
22
222222222222
222222222222

42.1. Reenterability
Well start by outlining what reenterability means technically, then what it implies in practice.
42.1.1. What it Means in General

There are many ways to understand reenterability:


1. A program does not modify itself.
2. A program does not modify itself and is loaded into memory-protected storage.
3. A program that produces correct results when multiple units of work execute it concurrently.
It can modify itself if none of the units of work rely on or can detect the modification. For
example:
L
ST

0,X
0,X

IC
STC

0,*
0,*-4

Such a program modifies itself, but the modification is not detectable unless the program has
been loaded into protected storage.
4. Many programmers use the term reentrant to describe a reenterable program. 296 Mathematically, reentrant describes a closed curve with at least one concave segment.
Sometimes people think reenterability also means recursion; theyre quite distinct. Well discuss
recursion in Section 42.2 on page 972.
42.1.2. What it Means in Practice

Before starting, you should evaluate where, how, and when the module will be used, to decide
whether or not it should be reenterable. But note that if you write all programs and subprograms

296

968

It has been claimed that reenterable was the original term, starting around 1964. Some years later someone apparently decided that word looked too complex, and substituted reentrant, without knowing its mathematical definition.
Assembler Language Programming for IBM z System Servers

Version 1.00

to be reenterable, you can use their components more easily in other applications, whether or not
the complete application is reenterable.
42.1.3. Assembly-Time Considerations

1. Specifying the RENT option asks the Assembler to check for obvious cases of selfmodification, but there are many ways for a program to modify itself that the Assembler
cannot detect. Specifying a RSECT control section does the same checking on a per-section
basis,297 but neither will detect d(b) references like this:
LA
STC

1,*
1,0(1)

Not detected by RENT or RSECT!

STC

2,*

Detected by RENT and RSECT!

2. Anything the routine may modify should be in acquired storage, or in a work area provided
by the caller.
3. These practices can make it easier to write a reenterable program (see Figure 771 on
page 970):
a. Define a DSECT for all local variables (but not constants). It should contain a local
save area for calls to other external routines.
b. On completion of entry linkage, allocate storage for the local variables, and assign a base
register for this storage area.
c. Initialize local variables as required.
d. Release the local storage as part of the exit linkage.
4. Use the List and Execute forms of most macros, unless you have verified that the Standard
form does not generate inline store instructions. See Figures 741, 743, 745, and 747 starting
on page 944 for examples of macros that can be used in reenterable programs without
needing to use the List and Execute forms.
42.1.4. At Linking Time

When you link a reenterable program using the z/OS Program Management Binder, you must
specify either the RENT or REFR option; these options describe your programs property (see
the Binder manuals shown in the Bibliography for details):
NONE

The module cannot be reused. A new copy must be brought into memory for each use.

SERIAL The module is serially reusable. It can only be executed by one task at a time; when
one task has finished executing it another task can begin. A serially reusable module
can modify its own code, but when it is re-executed it must initialize itself or restore
any instructions or data that have been altered. (Sometimes known as REUS.)
RENT

The module is reenterable. It can be executed by more than one task at a time. A task
can begin executing it before a previous task has completed execution. A reenterable
module cannot modify its own code. In some cases, the operating system may load a
reentrant program into an area of virtual storage that cannot be modified. Reenterable
modules are also serially reusable.

REFR

The module is refreshable. It can be replaced by a new copy during execution without
changing the sequence or results of processing. A refreshable module cannot be modified during execution. Refreshable modules are also reenterable and serially reusable.
A module can be refreshable only if all the control sections within it are refreshable.

The Binder (like the Assembler) trusts your claims about your programs reenterability, and does
not try to verify them.

297

Except for enabling checks for simple cases of self-modification within its section, RSECT is the same as CSECT.
Chapter XII: System Services, Reenterability, and Recursion

969

42.1.5. Techniques

This little example shows how you can write a reenterable program.
At the start of a reenterable program, you normally acquire storage for save areas, working data,
macro lists, and so on. A partial sketch of the entry and exit linkages is shown in Figure 771;
more will be added for a functioning program.
RentProg RSect ,
SAVE (14,12),,*
Save caller s registers
LR
12,15
Copy base register
Using RentProg,12
Establish addressability
GETMAIN R,LV=WorkLen
Get working storage
ST
13,4(,1)
Save back chain
ST
1,8(,13)
Store caller s forward chain
LR
13,1
Point R13 to the work area
Using WorkArea,13
Addressability for work area
XC
8(4,13),8(13)
Clear our forward chain
- - Do whatever needs doing
L
13,Save+4
Reload address of caller s area
LR
1,13
Put work area address in GR1
FREEMAIN R,A=(1),LV=WorkLen Free the acquired storage
RETURN (14,12)
Return to caller or system
WorkArea DSect ,
Save
DS
9D
Local save area
Buffer DS
CL80
OpenList OPEN (,,,),MF=L
List to OPEN two DCBs
CLoseLst CLOSE (,,,),MF=L
List to CLOSE two DCBs
- - DS
0D
Align to doubleword
WorkLen Equ *-WorkArea
Length of the work area
Figure 771. Skeleton form of a reenterable program

Figure 771 shows how to allocate working storage, set up a save area, then to free it and return.
Now, well add some working statements.
Suppose this little program reads records from INDCB, processes them, and writes them to
OUTDCB. In Figure 771 we omitted the DCB macros, so well add those and the GET and
PUT macros in Figure 772, assuming that the housekeeping instructions are unchanged. First,
because the DCBs are modified during execution, they must be copied to the work area.

GetRec

970

- - MVC
MVC
LA
LA
OPEN
GET
- - -

WDCB1(WDCB1L),INDCB
Copy INDCB to the work area
WDCB2(WDCB2L),OUTDCB
Copy OUTDCB to the work area
2,WDCB1
Point to working input DCB
3,WDCB1
Point to working output DCB
((2),INPUT,(3),OUTPUT),MF=(E,OpenList) Open both
(2),Buffer
Read a record
Process it

Assembler Language Programming for IBM z System Servers

Version 1.00

PUT
J
EndFile CLOSE
- - INDCB
DCB
OUTDCB

DCB
- - WorkArea DSect
- - WDCB1
DCB
WDCB1L Equ
WDCB2
DCB
WDCB2L Equ

(3),Buffer
GetRec
((2),,(3),)

Write it out
Close the DCBs

DDName=INFILE,LRECL=80,BLKSIZE=8000,MACRF=GM,DSORG=PS, X
EODAD=EndFile
DDName=OUTFILE,LRECL=80,BLKSIZE=8000,MACRF=PM,DSORG=PS
,
DSORG=PS,MACRF=GM,DDNAME=X
*-WDCB1
DSORG=PS,MACRF=GM,DDNAME=X
*-WDCB1

Working DCB1
Working DCB2

Figure 772 (Part 2 of 2). I/O macros in a reenterable program

The use of unusual (and identical) DDNames on the working DCBs doesnt matter because they
are overwritten after the DCB skeletons are moved to the work area. However, you should always
check your assembly listing to verify that the length of each DCB matches the length of the work
area to which its moved. (Here, they should both have length X 6 0 .)
The complete assembled program is shown in Figure 773.
000000
000000 47F0 F00E
000012 18CF

00000 00188
0000E
R:C 00000

000014
000022
000026
00002A

4510 C01C
50D0 1004
5010 D008
18D1

00002C
000032
000038
00003E
000042
000046
000070

D703
D25F
D25F
4120
4130
4110
1812

00007C
000088
00008C
0000AE
0000B2
0000B4
0000C2

1813
A7F4
4110
58D0
181D
47F0
98EC

0000C8
000128
000000
000000
000048
000098
0000A0

0000000000000000
0000000000000000
00000 00168
00
00

0001C
00004
00008

R:D 00000
D008 D008 00008 00008
D0A8 C0C8 000A8 000C8
D108 C128 00108 00128
D0A8
000A8
D108
00108
D098
00098

FFF4
D0A0
D004

00070
000A0
00004

C0BC
D00C

000BC
0000C

1
2
3
8
9
10
16
17
18
19
20
21
22
23
24
25
38
44
45
51
52
63
64
65
71
74
129
184
185
186
187
193

Print NoGen
RentProg RSect ,
SAVE (14,12),,*
Save caller s registers
LR
12,15
Copy base register
Using RentProg,12
Establish addressability
GETMAIN R,LV=WorkLen
Get working storage
ST
13,4(,1)
Save back chain
ST
1,8(,13)
Store caller s forward chain
LR
13,1
Point R13 to the work area
Using WorkArea,13
Addressability for work area
XC
8(4,13),8(13)
Clear our forward chain
MVC WDCB1(WDCB1L),INDCB
Copy INDCB to the work area
MVC WDCB2(WDCB2L),OUTDCB
Copy OUTDCB to the work area
LA
2,WDCB1
Point to working input DCB
LA
3,WDCB2
Point to working output DCB
OPEN ((2),INPUT,(3),OUTPUT),MF=(E,OpenList) Open both
GetRec GET (2),Buffer
Read a record
*
- - Process it
PUT (3),Buffer
Write it out
J
GetRec
EndFile CLOSE ((2),,(3),),MF=(E,CloseLst) Close both DCBs
L
13,Save+4
Reload address of caller s area
LR
1,13
Put work area address in GR1
FREEMAIN R,A=(1),LV=WorkLen Free the acquired storage
RETURN (14,12)
Return to caller or system
INDCB
DCB DDName=INFILE,LRECL=80,BLKSIZE=8000,MACRF=GM,DSORG=PS, X
EODAD=EndFile
OUTDCB DCB DDName=OUTFILE,LRECL=80,BLKSIZE=8000,MACRF=PM,DSORG=PS
WorkArea DSect ,
Save
DS
9D
Local save area
Buffer DS
CL80
OpenList OPEN (,,,),MF=L
List to OPEN two DCBs
CLoseLst CLOSE (,,,),MF=L
List to CLOSE two DCBs

Chapter XII: System Services, Reenterability, and Recursion

971

0000A8 0000000000000000
00060
000108 0000000000000000
00060
000168
00168

199
254
255
310
311
312
313

WDCB1
WDCB1L
WDCB2
WDCB2L

DCB
Equ
DCB
Equ
DS
WorkLen Equ
End

DSORG=PS,MACRF=GM,DDNAME=X
*-WDCB1
DSORG=PS,MACRF=GM,DDNAME=X
*-WDCB2
0D
Align to doubleword
*-WorkArea
Length of the work area

Figure 773 (Part 2 of 2). Assembly listing for a simple reenterable program

Exercises
42.1.1.(3) Note: This exercise is intended as a mental exercise in violating reenterability, not to
illustrate a useful or proper programming technique!
Write a program with a loop, in which a single instruction modifies itself on each iteration
through the loop, in such a way that the instruction is different each time. That is, an instruction like MVI *+1,0 does not change on each iteration. Display enough of the programs
behavior to convince yourself that your solution works.

42.2. Recursion
Recursion appears in varied forms in many programming languages. For example, the common
practice of grouping nested mathematical expressions in parentheses often implies the need for a
recursive routine to parse the complete expression. In Section 8.6 on page 105, the Assembler
Language defines an operand as formed from one to three expressions. Each expression is defined
as a factor or as factor or as factor factor; a factor is defined in turn as a primary
or as a primary*primary or as a primary/primary. Finally, a primary is defined as a term or
as a parenthesized expression, ( expression ). It is this last item that makes the definition of an
expression recursive; you could be scanning an expression and encounter an opening parenthesis
and find that you must (recursively) scan a new expression that is part of the expression you were
previously scanning.
As another example, suppose the Assembler Language supported some types of nested literals, as
in =A(=F 7 ) . 298 After recognizing the =A( portion of the outer literal, the Assembler would
normally parse an address-constant operand, but in this case the =F 7 operand will require a
recursive re-entry to the literal-operand scanner.
Mathematically, a recursive function is one that is defined in terms of itself. In programs, a recursive routine calls itself, either directly or indirectly. An example of a routine that can be implemented both with or without recursion is the familiar Factorial function; we saw iterative
solutions in Programming Problems 18.5, 33.2, and 36.4. Its recursive definition is
1. Factorial: for integers N 0.
Fact(N) = 1 if N = 0 or 1
Fact(N) = N Fact(N-1) otherwise
Some other functions having recursive definitions are:
2. Product: for integers M, N 1.299
Prod(N,M) = M if N = 1
Prod(N,M) = N if M = 1
Prod(N,M) = N + Prod(N,M-1) otherwise
3. Greatest Common Divisor: for integers M, N 1.300

298
299

972

At the time of this writing, HLASM doesnt support nested literals; but you can always ask.
Some very early computers evaluated products this way.
Assembler Language Programming for IBM z System Servers

Version 1.00

GCD(N,M) = N if M = 0
GCD(N,M) = GCD(M,mod(N,M)) otherwise
Note that GCD(M,N) = GCD(N,M). Also, the Largest Common Multiple function
L C M ( N , M ) = N M/GCD(N,M).
Another interesting GCD result is that GCD(n A 1,n B 1 ) = n GCD(A,B) 1.
4. Fibonacci numbers: for N 1.
FIBO(N) = 1 if N 2
FIBO(N) = FIBO(N-1) + FIBO(N-2) otherwise
Weve seen many iterative solutions to generating the Fibonacci series; for example, see Programming Problems 16.7-10 and 30.7-8.
5. Remainder: given three positive integers A, b, C, calculate the remainder of A b/C.
REMDR(Ab,C)
REMDR(Ab,C)
REMDR(Ab,C)
REMDR(Ab,C)

=
=
=
=

REMDR((A2)b/2 ,C) if A C and b 2 is even


mod(AREMDR((A2)(b-1)/2,C),C) if A < C and b 3 is odd
A if A < C and b = 1
REMDR((mod(A,C))b,C) if A C

6. Partitions: PART(N) = number of ways to write N as a sum of positive integers.


PART(N) = 1 if N = 0
PART(N) = 0 if N < 0
PART(N) = R(1) - R(2) + R(3) - R(4) + R(5) - ...
where R(k) = PART(N-(3k2-k)/2) + PART(N-(3k2+k)/2)
7. Partitions: PART2(N,M) = number of ways to write M as the sum of not more than N
positive integers. (Note that PART(N) = PART2(N,N).)
PART2(N,M) = 1 if (a) N = 1 and M 1, or (b) M = 0, or (c) M = 1
PART2(N,M) = 0 if M < 0
PART2(N,M) = PART2(N-1,M) + PART2(N,M-N)
8. Binomial Coefficients: BINCN,M = number of ways to select M objects from a set of N.
BINCN,M = 1 if M = 0 or M = N
BINCN,M = BINC N 1,M 1 + BINC N 1,M
9. Ackermanns Function: for X, Y 0.
ACK(X,Y) = Y + 1 if X = 0
ACK(X,Y) = ACK(X-1,1) if X > 0 and Y = 0
ACK(X,Y) = ACK(X-1,ACK(X,Y-1)) otherwise
Be careful with the Ackermann function! It grows extremely fast, faster than any exponential
function. For example, ACK(3,n) = 2( n + 3 ) 3, while ACK(4,2) = 265536 3 1019728 .
Note that 2 65536 = 2**(2**(2**(2**2))), an exponentiation stack or power tower of five
2s. ACK(4,N) is a power tower of (N + 3 2s) 3.
10. The Tower of Hanoi is a famous problem often involving a recursive solution. suppose
you have three pins P1, P2, and P3, and on P1 is a set of disks D1, D2, ... DN in increasing
size from top to bottom. For example, with four disks:

300

Also known as the Greatest Common Factor (GCF) or Highest Common Factor (HCF) function.
Chapter XII: System Services, Reenterability, and Recursion

973

P1
P2
P3

D1

D2

D3

D4

=====================================================================================

The problem is to move the disks from P1 to P2, subject to these rules:
a. Only one disk may be moved at a time.
b. A larger disk is never put on a smaller disk.
c. At each stage, all disks must be on P1, P2, or P3 (no disks may be held temporarily
elsewhere).
A recursive algorithm to accomplish the moves uses the function THMOVE(i,j,M), which
moves the topmost M disks from pin P i to pin P j, using pin P k if the topmost disks of pins
P k and P j are larger than the M-th disk from the top of pin Pi. The steps of the algorithm
are:
Step 1:

If M=1, move the topmost disk from P i to P j, and return.

Step 2:

Do THMOVE(i,k,M 1) where i j k.

Step 3:

Move the topmost disk from P i to P j.

Step 4:

Do THMOVE(k,j,M 1) where i j k.

Step 5:

Return.

In the figure above, you would start with THMOVE(1,2,4).


Well see some of these recursive activities again as Programming Problems.
It is a common belief that a recursive routine must also be reenterable, but this is not so. The
recursive routine can maintain its own internal stack; see Programming Problem 42.1 (which is
highly recommended).
A common feature of recursive routines is that they must allocate and initialize instances of local
variables on each entry, and free them on exit. Many implementations of recursive routines use a
stack for local variables, save areas, and so on.
Making a recursive routine also be reenterable can simplify managing local variables if the routine
can be loaded into protected storage; any attempt to store into the body of the routine will generate a memory protection error.
Here is an example of a reenterable, recursive routine to evaluate factorials and return the calculated value in GR0. (Remember that the largest argument that can be held in a fullword is 12;
trying to evaluate larger values can lead to a variety of unexpected errors.)
*
RFact

974

Reenterable, Recursive Factorial Routine


RSect ,
STM 14,3,12(13)
Save registers
LR
3,15
Copy base register
Using RFAct,3
Provide addressability
LR
2,1
Preserve arglist pointer

Assembler Language Programming for IBM z System Servers

Version 1.00

LHI 0,LWA
GETMAIN R,LV=(0)
ST
13,4(,1)
ST
1,8(,13)
LR
13,1
Using WA,13
L
2,0(,2)
L
1,0(,2)
CHI 1,2
JE
Ret
JNH Test
ST
1,Arg
BCTR 1,0
ST
1,NewArg
LA
1,NewArg
ST
1,ArgAddr
LA
1,ArgAddr
LARL 15,RFact
BASR 14,15
*
Value returned in GR0
Calc
L
1,Arg
MR
0,0
Ret
L
2,Save+4
Drop 13
ST
1,20(,2)
LHI 0,LWA
FREEMAIN R,LV=(0),A=(13)
Drop 3
LR
13,2
LM
14,3,12(2)
BR
14
Test
LTR 1,1
JM
SetZ
LHI 0,1
J
Ret
SetZ
XR
0,0
J
Ret
WA
DSect ,
Save
DS
5D
Arg
DS
F
NewArg DS
F
ArGAddr DS
A
DS
0D
LWA
Equ *-WA
End

Get length of work area


Get working storage
Store back chain
Store forward chain
Now have local save area
Map the work area
Get argument address
Get argument N
Is the argument 2?
Fact(2) = 2, no recursion
Go test for 0, 1, or < 0
Save N we re called with
Create N-1
Store argument for call
Create argument address
Store the address
Point to argument address
Get entry point address
Call ourselves recursively
Get the N we were called with
Form N*(N-1)
Get caller s save area address
No more reference to work area
Store product in R0 slot
Set work area length in GR0
Release our storage
No more based references here
Restore caller s R13
Restore registers
Return to whoever called
Is argument 0 or 1 or < 0
If < 0, return 0
If 0 or 1, return 1
And complete return sequence
Return 0 for N < 0
And return
Work area mapping
Local save area, GR14-GR3
Value we were called with
Argument for recursive call
Address of the argument
Round to doubleword
Length of work area

Figure 774 (Part 2 of 2). Example of a reenterable, recursive routine

The assembly listing is shown in Figure 775 on page 976:

Chapter XII: System Services, Reenterability, and Recursion

975

Loc Object Code

Addr1 Addr2 Stmt Source


1 *
000000
00000 00082
2 RFact
000000 90E3 D00C
0000C
3
000004 183F
4
R:3 00000
5
000006 1821
6
000008 A708 0038
00038
7
8
00000C 4510 3010
00010
9+
000010 0A0A
10+
000012 50D0 1004
00004
11
000016 5010 D008
00008
12
00001A 18D1
13
R:D 00000
14
00001C 5820 2000
00000
15
000020 5810 2000
00000
16
000024 A71E 0002
00002
17
000028 A784 0016
00054
18
00002C A7D4 0021
0006E
19
000030 5010 D028
00028
20
000034 0610
21
000036 5010 D02C
0002C
22
00003A 4110 D02C
0002C
23
00003E 5010 D030
00030
24
000042 4110 D030
00030
25
000046 C0F0 FFFF FFDD
00000
26
00004C 0DEF
27
28 *
00004E 5810 D028
00028
29 Calc
000052 1C00
30
000054 5820 D004
00004
31 Ret
32
000058 5010 2014
00014
33
00005C A708 0038
00038
34
35
000060 4110 D000
00000
36+
000064 0A0A
37+
38
000066 18D2
39
000068 98E3 200C
0000C
40
00006C 07FE
41
00006E 1211
42 Test
000070 A744 0006
0007C
43
000074 A708 0001
00001
44
000078 A7F4 FFEE
00054
45
00007C 1700
46 SetZ
00007E A7F4 FFEB
00054
47
000000
00000 00038
49 WA
000000
50 Save
000028
51 Arg
00002C
52 NewArg
000030
53 ArGAddr
000038
54
00038
55 LWA
56

Statement
Reenterable, Recursive Factorial Routine
RSect ,
STM 14,3,12(13)
Save registers
LR
3,15
Copy base register
Using RFAct,3
Provide addressability
LR
2,1
Preserve arglist pointer
LHI 0,LWA
Get length of work area
GETMAIN R,LV=(0)
Get working storage
BAL 1,*+4
INDICATE GETMAIN
SVC 10
ISSUE GETMAIN SVC
ST
13,4(,1)
Store back chain
ST
1,8(,13)
Store forward chain
LR
13,1
Now have local save area
Using WA,13
Map the work area
L
2,0(,2)
Get argument address
L
1,0(,2)
Get argument N
CHI 1,2
Is the argument 2?
JE
Ret
Fact(2) = 2, no recursion
JNH Test
Go test for 0, 1, or < 0
ST
1,Arg
Save N we re called with
BCTR 1,0
Create N-1
ST
1,NewArg
Store argument for call
LA
1,NewArg
Create argument address
ST
1,ArgAddr
Store the address
LA
1,ArgAddr
Point to argument address
LARL 15,RFact
Get entry point address
BASR 14,15
Call ourselves recursively
Value returned in GR0
L
1,Arg
Get the N we were called with
MR
0,0
Form N*(N-1)
L
2,Save+4
Get caller s save area address
Drop 13
No more reference to work area
ST
1,20(,2)
Store product in R0 slot
LHI 0,LWA
Set work area length in GR0
FREEMAIN R,LV=(0),A=(13) Release our storage
LA
1,0(0,13)
LOAD AREA ADDRESS
SVC 10
ISSUE FREEMAIN SVC
Drop 3
No more based references here
LR
13,2
Restore caller s R13
LM
14,3,12(2)
Restore registers
BR
14
Return to whoever called
LTR 1,1
Is argument 0 or 1 or < 0
JM
SetZ
If < 0, return 0
LHI 0,1
If 0 or 1, return 1
J
Ret
And complete return sequence
XR
0,0
Return 0 for N < 0
J
Ret
And return
DSect ,
Work area mapping
DS
5D
Local save area, GR14-GR3
DS
F
Value we were called with
DS
F
Argument for recursive call
DS
A
Address of the argument
DS
0D
Round to doubleword
Equ *-WA
Length of work area
End

Figure 775. Assembly listing of the reenterable recursive routine

Several items are worth noting:


1. The routine tries to use a minimum number of general registers, while maintaining standard
linkage and save area conventions. (This contributes nothing to efficient performance for this
particular problem; an iterative solution would be much more efficient.)
2. The local base register in GR3 is needed only because the expansion of the GETMAIN
macro must generate a BAL instruction, as we saw in Figure 741 on page 944. In some situations, the FREEMAIN macro may also generate instructions needing base-displacement
resolution.
3. Returning the function value in GR0 can be done by reloading the other registers; storing the
result into the callers GR0 slot in his save area is another method.

976

Assembler Language Programming for IBM z System Servers

Version 1.00

Exercises
42.2.1.(2) + In Figure 774 on page 974, give two reasons why we cant use BAS 14,RFACT to
cause recursion, rather than the LR and BASR instructions in the figure? Both will go to the
same place.
42.2.2.(2) If you call RFACT in Figure 774 on page 974 with argument 5, show (a) the
ordered recursive calls with their arguments, and (b) the steps followed on recursion returns to
evaluate the final result.
42.2.3.(3) + By studying Figure 775 on page 976, what is the earliest position to which you
can safely move the DROP 3 statement?

42.3. Summary
The general principles for writing reenterable programs are fairly simple:
All local work areas must either be in acquired storage, or in storage provided by the caller. If
acquired, the storage must be released on exit from your routine.
The program must not modify itself.
Note that some IBM macros make it difficult to write reenterable programs, because their
expansions generate in-line data areas into which the macro stores argument values.

Programming Problems
Problem 42.1(4) + Write a non-reenterable recursive subroutine with a single fullword argument
N that evaluates N factorial and returns its value in GR0. Then write a program to call it with
values from 12 to 1, and display the results to verify its execution.
Problem 42.2(2) + You may have noticed that the program in Figure 773 on page 971 omitted
any FREEPOOL macros. Rewrite, test, and run the program with the proper FREEPOOL
macros.
Problem 42.3(1) + Create your own version of the factorial routine in Figure 774 on page 974,
and then create a calling program to request values of N! for values of N from 1 to 12. What
happens on your system if you try calculating Factorial(13)?
Problem 42.4(2) + Write a program to calculate the seventh Fibonacci number recursively.
Include enough tracing output so you can see the great labors performed to achieve a simple
result. (That is, FIB(7) requires calculating FIB(6) and FIB(5); but FIB(6) requires FIB(5)
(again) and FIB(4), and FIB(5) requires FIB(4) (again) and FIB(3), etc. many values are
calculated repeatedly.)
Problem 42.5(2) + The binomial coefficients can be defined both iteratively and recursively; the
recursive definition is for 1 N M:
BINCO(N,M) = 1 if M = 0 or M = N
BINCO(N,M) = BINCO(N-1,M-1) + BINCO(N-1,M) otherwise
Write a program to evaluate the binomial coefficients up to M=10.
Problem 42.6(3) + The definition above of the remainder function REM may seem unnecessarily complex. To show why it can be a great simplification, write a recursive program to evaluate the remainder when (1) A=24, b=48, C=11 (that is, the remainder of 24 48/11), (2)
A=73, b=51, C=16 (that is, REM(73 51/16)).

Chapter XII: System Services, Reenterability, and Recursion

977

Problem 42.7(4) + The partition function P(N) requires evaluating the R expressions for each N
until successive values are zero. Write a recursive program to evaluate P(N) for N from 5 to 9.
Problem 42.8(3) + The partition function Q(N,M) is easier to evaluate than the P(N) in
Problem 42.7. Write a recursive Evaluate Q(N,M) for M from 5 to 9 and for N from 1 to M.
Compare your values of Q(N,N) to the values of P(N) you calculated in Problem 42.7.
Problem 42.9(3) + The Q(N,M) values of the partition function can be calculated iteratively
using this algorithm:
array Q(1:M,1:N)
for k=1 step 1 until M do
begin for j=1 step 1 until N do
Q(k,j) = if k=1 or j=1 then 1 else
if kj then 1+Q(k,j-1) else
Q(k,j-1) + Q(k-j,j)
Write a program to evaluate the Q array up to Q(9,9), and compare your results to the values
you calculated in Problem 42.8. (Note that no element of the Q array is calculated more than
once.)
Problem 42.10(3) + Write a recursive program using the formulae for evaluating REM(A b/C) to
read values for A, b, and C including at least these sets of three values:
A = 73, b = 23, C = 109
A = 73, b = 79, C = 127
A =143, b =204, C = 999
Problem 42.11(3) + Write a recursive program to evaluate Ackermanns function ACK(3,3).
Your answer should be 61. (Be careful about exploring larger arguments: the function grows
extremely rapidly!)
Problem 42.12(3) + Write a program to solve recursively the Tower of Hanoi problem
described above. If you can display or animate the steps of the algorithm, so much the better.
Problem 42.13(3) + Write a program to solve the Tower of Hanoi problem described above,
using this iterative method. 301
Number the disks from 1 to N, smallest to largest.
Order the posts so that moving clockwise and counterclockwise are meaningful.
Then:
Move odd-numbered disks only clockwise and even-numbered disks only counterclockwise.
Dont move the same disk twice in succession.
Dont put a larger disk on a smaller.

301

978

Due to Wm. Randolph Franklin, published in SIGPLAN Notices Aug. 1984, page 87.
Assembler Language Programming for IBM z System Servers

Version 1.00

Appendix A: Conversion and Reference Tables


CCCCCCCCCC
CCCCCCCCCCCC
CC
CC
CC
CC
CC
CC
CC
CC
CC
CC
CCCCCCCCCCCC
CCCCCCCCCC

RRRRRRRRRRR
RRRRRRRRRRRR
RR
RR
RR
RR
RR
RR
RRRRRRRRRRRR
RRRRRRRRRRR
RR
RR
RR
RR
RR
RR
RR
RR
RR
RR

TTTTTTTTTTTT
TTTTTTTTTTTT
TT
TT
TT
TT
TT
TT
TT
TT
TT
TT

This appendix contains the following tables:


1. Table 431 gives the correspondences between hexadecimal digits and their decimal and binary representations.
2. Tables 432 and 433 are hexadecimal addition and multiplication tables.
3. Tables 434 and 435 give powers of 2 from 1 to 64 and from 65 to 128, respectively.
4. Tables 436 and 437 provide multiples of powers of 16, up to 15 16 7
5. Table 438 shows the powers of 10 expressed in hexadecimal.
6. The tables in Hexadecimal and Decimal Integers on page 989 provide rapid conversions between
decimal and hexadecimal for integers between 0 and 4095.
7. The tables in Conversion Tables for Hexadecimal Fractions on page 997 provide conversions
between decimal and hexadecimal fractions.
8. EBCDIC Character Representation in Assembler Language Programs on page 998 shows the
encodings used by the Assembler for EBCDIC characters.
9. ASCII Character Representation in Assembler Language Programs on page 999 shows the
encodings used by the Assembler for ASCII characters.
10. DC Statement Types on page 1000 shows the types of constants supported by the DC and DS statements.

Hexadecimal Digits in Decimal and Binary


Table 431. Hexadecimal, decimal, and binary
Hex
0
1
2
3
4
Decimal
Binary

0
0000

1
0001

2
0010

3
0011

4
0100

5
5
0101

6
6
0110

7
7
0111

8
1000

9
1001

A
10
1010

B
11
1011

C
12
1100

D
13
1101

14
1110

15
1111

Appendix A: Conversion and Reference Tables

981

Hexadecimal Addition and Multiplication Tables


+
0
1
2
3
4
5
6
7
8
9
A
B
C
D
E
F

0
00
01
02
03
04
05
06
07
08
09
0A
0B
0C
0D
0E
0F

1
01
02
03
04
05
06
07
08
09
0A
0B
0C
0D
0E
0F
10

2
02
03
04
05
06
07
08
09
0A
0B
0C
0D
0E
0F
10
11

3
03
04
05
06
07
08
09
0A
0B
0C
0D
0E
0F
10
11
12

4
04
05
06
07
08
09
0A
0B
0C
0D
0E
0F
10
11
12
13

5
05
06
07
08
09
0A
0B
0C
0D
0E
0F
10
11
12
13
14

6
06
07
08
09
0A
0B
0C
0D
0E
0F
10
11
12
13
14
15

7
07
08
09
0A
0B
0C
0D
0E
0F
10
11
12
13
14
15
16

8
08
09
0A
0B
0C
0D
0E
0F
10
11
12
13
14
15
16
17

9
09
0A
0B
0C
0D
0E
0F
10
11
12
13
14
15
16
17
18

A
0A
0B
0C
0D
0E
0F
10
11
12
13
14
15
16
17
18
19

B
0B
0C
0D
0E
0F
10
11
12
13
14
15
16
17
18
19
1A

C
0C
0D
0E
0F
10
11
12
13
14
15
16
17
18
19
1A
1B

D
0D
0E
0F
10
11
12
13
14
15
16
17
18
19
1A
1B
1C

E
0E
0F
10
11
12
13
14
15
16
17
18
19
1A
1B
1C
1D

F
0F
10
11
12
13
14
15
16
17
18
19
1A
1B
1C
1D
1E

7
07
0E
15
1C
23
2A
31
38
3F
46
4D
54
5B
62
69

8
08
10
18
20
28
30
38
40
48
50
58
60
68
70
78

9
09
12
1B
24
2D
36
3F
48
51
5A
63
6C
75
7E
87

A
0A
14
1E
28
32
3C
46
50
5A
64
6E
78
82
8C
96

B
0B
16
21
2C
37
42
4D
58
63
6E
79
84
8F
9A
A5

C
0C
18
24
30
3C
48
54
60
6C
78
84
90
9C
A8
B4

D
0D
1A
27
34
41
4E
5B
68
75
82
8F
9C
A9
B6
C3

E
0E
1C
2A
38
46
54
62
70
7E
8C
9A
A8
B6
C4
D2

F
0F
1E
2D
3C
4B
5A
69
78
87
96
A5
B4
C3
D2
E1

Table 432. Hexadecimal Addition Table

1
2
3
4
5
6
7
8
9
A
B
C
D
E
F

0
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00

1
01
02
03
04
05
06
07
08
09
0A
0B
0C
0D
0E
0F

2
02
04
06
08
0A
0C
0E
10
12
14
16
18
1A
1C
1E

3
03
06
09
0C
0F
12
15
18
1B
1E
21
24
27
2A
2D

4
04
08
0C
10
14
18
1C
20
24
28
2C
30
34
38
3C

5
05
0A
0F
14
19
1E
23
28
2D
32
37
3C
41
46
4B

6
06
0C
12
18
1E
24
2A
30
36
3C
42
48
4E
54
5A

Table 433. Hexadecimal Multiplication Table

982

Assembler Language Programming for IBM z System Servers

Version 1.00

Powers of 2
Table 434. Integer powers of 2

Table 434. Integer powers of 2

K (kilo)

M (mega)

G (giga)

2N

2N

2
4

8,589,934,592

33

17,179,869,184

34

34,359,738,368

35

16

68,719,476,736

36

32

137,438,953,472

37

64

274,877,906,944

38

128

549,755,813,888

39

256

1,099,511,627,776

40

512

2,199,023,255,552

41

T (tera)

1,024

10

4,398,046,511,104

42

2,048

11

8,796,093,022,208

43

4,096

12

17,592,186,044,416

44

8,192

13

35,184,372,088,832

45

16,384

14

70,368,744,177,664

46

32,768

15

140,737,488,355,328

47

65,536

16

281,474,976,710,656

48

131,072

17

562,949,953,421,312

49

262,144

18

1,125,899,906,842,624

50

524,288

19

2,251,799,813,685,248

51

1,048,576

20

4,503,599,627,370,496

52

2,097,152

21

9,007,199,254,740,992

53

4,194,304

22

18,014,398,509,481,984

54

P (peta)

8,388,608

23

36,028,797,018,963,968

55

16,777,216

24

72,057,594,037,927,936

56

33,554,432

25

144,115,188,075,855,872

57

67,108,864

26

288,230,376,151,711,744

58

134,217,728

27

268,435,456

28

536,870,912

576,460,752,303,423,488

59

1,152,921,504,606,846,976

60

29

2,305,843,009,213,693,952

61

1,073,741,824

30

4,611,686,018,427,387,904

62

2,147,483,648

31

9,223,372,036,854,775,808

63

4,294,967,296

32

18,446,744,073,709,551,616

64

E (exa)

Appendix A: Conversion and Reference Tables

983

Table 435 (Page 1 of 2). Integer powers of 2

Z (zetta)

Y (yotta)

984

2N

36,893,488,147,419,103,232

65

73,786,976,294,838,206,464

66

147,573,952,589,676,412,928

67

295,147,905,179,352,825,856

68

590,295,810,358,705,651,712

69

1,180,591,620,717,411,303,424

70

2,361,183,241,434,822,606,848

71

4,722,366,482,869,645,213,696

72

9,444,732,965,739,290,427,392

73

18,889,465,931,478,580,854,784

74

37,778,931,862,957,161,709,568

75

75,557,863,725,914,323,419,136

76

151,115,727,451,828,646,838,272

77

302,231,454,903,657,293,676,544

78

604,462,909,807,314,587,353,088

79

1,208,925,819,614,629,174,706,176

80

2,417,851,639,229,258,349,412,352

81

4,835,703,278,458,516,698,824,704

82

9,671,406,556,917,033,397,649,408

83

19,342,813,113,834,066,795,298,816

84

38,685,626,227,668,133,590,597,632

85

77,371,252,455,336,267,181,195,264

86

154,742,504,910,672,534,362,390,528

87

309,485,009,821,345,068,724,781,056

88

618,970,019,642,690,137,449,562,112

89

1,237,940,039,285,380,274,899,124,224

90

2,475,880,078,570,760,549,798,248,448

91

4,951,760,157,141,521,099,596,496,896

92

9,903,520,314,283,042,199,192,993,792

93

19,807,040,628,566,084,398,385,987,584

94

39,614,081,257,132,168,796,771,975,168

95

79,228,162,514,264,337,593,543,950,336

96

Assembler Language Programming for IBM z System Servers

Version 1.00

Table 435 (Page 2 of 2). Integer powers of 2


2N

158,456,325,028,528,675,187,087,900,672

97

316,912,650,057,057,350,374,175,801,344

98

633,825,300,114,114,700,748,351,602,688

99

1,267,650,600,228,229,401,496,703,205,376

100

2,535,301,200,456,458,802,993,406,410,752

101

5,070,602,400,912,917,605,986,812,821,504

102

10,141,204,801,825,835,211,973,625,643,008

103

20,282,409,603,651,670,423,947,251,286,016

104

40,564,819,207,303,340,847,894,502,572,032

105

81,129,638,414,606,681,695,789,005,144,064

106

162,259,276,829,213,363,391,578,010,288,128

107

324,518,553,658,426,726,783,156,020,576,256

108

649,037,107,316,853,453,566,312,041,152,512

109

1,298,074,214,633,706,907,132,624,082,305,024

110

2,596,148,429,267,413,814,265,248,164,610,048

111

5,192,296,858,534,827,628,530,496,329,220,096

112

10,384,593,717,069,655,257,060,992,658,440,192

113

20,769,187,434,139,310,514,121,985,316,880,384

114

41,538,374,868,278,621,028,243,970,633,760,768

115

83,076,749,736,557,242,056,487,941,267,521,536

116

166,153,499,473,114,484,112,975,882,535,043,072

117

332,306,998,946,228,968,225,951,765,070,086,144

118

664,613,997,892,457,936,451,903,530,140,172,288

119

1,329,227,995,784,915,872,903,807,060,280,344,576

120

2,658,455,991,569,831,745,807,614,120,560,689,152

121

5,316,911,983,139,663,491,615,228,241,121,378,304

122

10,633,823,966,279,326,983,230,456,482,242,756,608

123

21,267,647,932,558,653,966,460,912,964,485,513,216

124

42,535,295,865,117,307,932,921,825,928,971,026,432

125

85,070,591,730,234,615,865,843,651,857,942,052,864

126

170,141,183,460,469,231,731,687,303,715,884,105,728

127

340,282,366,920,938,463,463,374,607,431,768,211,456

128

Appendix A: Conversion and Reference Tables

985

Multiples of Powers of Sixteen

Table 436. Multiples of powers of sixteen (part 1 of 2)


Hex Digit
16 0
16 1
16 2
1
1
16
256
2
2
32
512
3
3
48
768
4
4
64
1,024
5
5
80
1,280
6
6
96
1,536
7
7
112
1,792
8
8
128
2,048
9
9
144
2,304
A
10
160
2,560
B
11
176
2,816
C
12
192
3,072
D
13
208
3,328
E
14
224
3,584
F
15
240
3,840

Table 437. Multiples of powers of sixteen (part 2 of 2)


Hex Digit
16 5
16 6
1
1,048,576
16,777,216
2
2,097,152
33,554,432
3
3,145,728
50,331,648
4
4,194,304
67,108,864
5
5,242,880
83,886,080
6
6,291,456
100,663,296
7
7,340,032
117,440,512
8
8,388,608
134,217,728
9
9,437,184
150,994,944
A
10,485,760
167,772,160
B
11,534,336
184,549,376
C
12,582,912
201,326,592
D
13,631,488
218,103,808
E
14,680,064
234,881,024
F
15,728,640
251,658,240

986

Assembler Language Programming for IBM z System Servers

Version 1.00

16 3
4,096
8,192
12,288
16,384
20,480
24,576
28,672
32,768
36,864
40,960
45,056
49,152
53,248
57,344
61,440

16 4
65,536
131,072
196,608
262,144
327,680
393,216
458,752
524,288
589,824
655,360
720,896
786,432
851,968
917,504
983,040

16 7
268,435,456
536,870,912
805,306,368
1,073,741,824
1,342,177,280
1,610,612,736
1,879,048,192
2,147,483,648
2,415,919,104
2,684,354,560
2,952,790,016
3,221,225,472
3,489,660,928
3,758,096,384
4,026,531,840

Powers of 10 in Hexadecimal

10 N in hexadecimal
1
A
64
3E8
2710
186A0
F4240
989680
5F5E100
3B9ACA00
2540BE400
174876E800
E8D4A51000
9184E72A000
5AF3107A4000
38D7EA4C68000
2386F26FC10000
16345785D8A0000
DE0B6B3A7640000
8AC7230489E80000
56BC75E2D63100000
3635C9ADC5DEA00000
21E19E0C9BAB2400000
152D02C7E14AF6800000
D3C21BCECCEDA1000000
84595161401484A000000
52B7D2DCC80CD2E4000000
33B2E3C9FD0803CE8000000
204FCE5E3E25026110000000
1431E0FAE6D7217CAA0000000
C9F2C9CD04674EDEA40000000
7E37BE2022C0914B2680000000
4EE2D6D415B85ACEF8100000000
314DC6448D9338C15B0A00000000
1ED09BEAD87C0378D8E6400000000
13426172C74D822B878FE800000000
C097CE7BC90715B34B9F1000000000
785EE10D5DA46D900F436A000000000
4B3B4CA85A86C47A098A224000000000
2F050FE938943ACC45F65568000000000
1D6329F1C35CA4BFABB9F5610000000000
125DFA371A19E6F7CB54395CA0000000000
B7ABC627050305ADF14A3D9E40000000000
72CB5BD86321E38CB6CE6682E80000000000
47BF19673DF52E37F2410011D100000000000
2CD76FE086B93CE2F768A00B22A00000000000
1C06A5EC5433C60DDAA16406F5A400000000000
118427B3B4A05BC8A8A4DE845986800000000000
AF298D050E4395D69670B12B7F41000000000000
6D79F82328EA3DA61E066EBB2F88A000000000000
446C3B15F9926687D2C40534FDB564000000000000

N
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50

Appendix A: Conversion and Reference Tables

987

10 N in hexadecimal
2AC3A4EDBBFB8014E3BA83411E915E8000000000000
1ABA4714957D300D0E549208B31ADB10000000000000
10B46C6CDD6E3E0828F4DB456FF0C8EA0000000000000
A70C3C40A64E6C51999090B65F67D9240000000000000
6867A5A867F103B2FFFA5A71FBA0E7B680000000000000
4140C78940F6A24FDFFC78873D4490D2100000000000000
28C87CB5C89A2571EBFDCB54864ADA834A00000000000000
197D4DF19D605767337E9F14D3EEC8920E400000000000000
FEE50B7025C36A0802F236D04753D5B48E800000000000000
9F4F2726179A224501D762422C946590D91000000000000000
63917877CEC0556B21269D695BDCBF7A87AA000000000000000
3E3AEB4AE1383562F4B82261D969F7AC94CA4000000000000000
26E4D30ECCC3215DD8F3157D27E23ACBDCFE68000000000000000
184F03E93FF9F4DAA797ED6E38ED64BF6A1F010000000000000000
F316271C7FC3908A8BEF464E3945EF7A25360A0000000000000000
97EDD871CFDA3A5697758BF0E3CBB5AC5741C640000000000000000
5EF4A74721E864761EA977768E5F518BB6891BE80000000000000000
3B58E88C75313EC9D329EAAA18FB92F75215B17100000000000000000
25179157C93EC73E23FA32AA4F9D3BDA934D8EE6A00000000000000000
172EBAD6DDC73C86D67C5FAA71C245689C1079502400000000000000000
E7D34C64A9C85D4460DBBCA87196B61618A4BD216800000000000000000
90E40FBEEA1D3A4ABC8955E946FE31CDCF66F634E1000000000000000000
5A8E89D75252446EB5D5D5B1CC5EDF20A1A059E10CA000000000000000000
3899162693736AC531A5A58F1FBB4B746504382CA7E4000000000000000000
235FADD81C2822BB3F07877973D50F28BF22A31BE8EE8000000000000000000
161BCCA7119915B50764B4ABE86529797775A5F1719510000000000000000000
DD15FE86AFFAD91249EF0EB713F39EBEAA987B6E6FD2A0000000000000000000
8A2DBF142DFCC7AB6E3569326C7843372A9F4D2505E3A40000000000000000000
565C976C9CBDFCCB24E161BF83CB2A027AA3903723AE4680000000000000000000
35F9DEA3E1F6BDFEF70CDD17B25EFA418CA63A22764CEC100000000000000000000
21BC2B266D3A36BF5A680A2ECF7B5C68F7E7E45589F0138A00000000000000000000
15159AF8044462379881065D41AD19C19AF0EEB576360C36400000000000000000000
D2D80DB02AABD62BF50A3FA490C301900D6953169E1C7A1E800000000000000000000
83C7088E1AAB65DB792667C6DA79E0FA0861D3EE22D1CC531000000000000000000000
525C6558D0AB1FA92BB800DC488C2C9C453D2474D5C31FB3EA000000000000000000000
3379BF57826AF3C9BB530089AD579BE1AB4636C90599F3D0724000000000000000000000
202C1796B182D85E1513E0560C56C16D0B0BE23DA38038624768000000000000000000000
141B8EBE2EF1C73ACD2C6C35C7B638E426E76D668630233D6CA10000000000000000000000
C913936DD571C84C03BC3A19CD1E38E9850A46013DE160663E4A0000000000000000000000
7DAC3C24A5671D2F8255A4502032E391F3266BC0C6ACDC3FE6EE40000000000000000000000
4E8BA596E760723DB17586B2141FCE3B37F803587C2C09A7F054E80000000000000000000000
3117477E509C47668EE9742F4C93E0E502FB02174D9B8608F6351100000000000000000000000
1EAE8CAEF261ACA01951E89D8FDC6C8F21DCE14E908133C599E12AA00000000000000000000000
132D17ED577D0BE40FD3316279E9C3D9752A0CD11A50C05B802CBAA400000000000000000000000
BFC2EF456AE276E89E3FEDD8C321A67E93A4802B0727839301BF4A6800000000000000000000000
77D9D58B62CD8A5162E7F4A779F5080F1C46D01AE478B23BE1178E81000000000000000000000000
4AE825771DC07672DDD0F8E8AC39250971AC4210CECB6F656CAEB910A000000000000000000000000
2ED1176A72984A07CAA29B916BA3B725E70BA94A813F259F63ED33AA64000000000000000000000000
1D42AEA2879F2E44DEA5A13AE3465277B06749CE90C777839E74404A7E8000000000000000000000000
1249AD2594C37CEB0B2784C4CE0BF38ACE408E211A7CAAB24308A82E8F10000000000000000000000000

Table 438. Powers of 10 expressed in hexadecimal

988

Assembler Language Programming for IBM z System Servers

Version 1.00

N
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100

Hexadecimal and Decimal Integers


These tables convert integers between 0 and 4095 (X 000 and X F F F ). For example, to convert X 123
to decimal, find the first two digits (12) in the column headed 12*, and then find the row numbered 3. At
the intersection you will find the decimal value 291.

08*

09*

0A*

0B*

0C*

0D*

0E*

0F*

0
1
2
3

128
129
130
131

144
145
146
147

160
161
162
163

176
177
178
179

192
193
194
195

208
209
210
211

224
225
226
227

240
241
242
243

116
117
118
119

4
5
6
7

132
133
134
135

148
149
150
151

164
165
166
167

180
181
182
183

196
197
198
199

212
213
214
215

228
229
230
231

244
245
246
247

104
105
106
107

120
121
122
123

8
9
A
B

136
137
138
139

152
153
154
155

168
169
170
171

184
185
186
187

200
201
202
203

216
217
218
219

232
233
234
235

248
249
250
251

92
93
94
95

108
109
110
111

124
125
126
127

C
D
E
F

140
141
142
143

156
157
158
159

172
173
174
175

188
189
190
191

204
205
206
207

220
221
222
223

236
237
238
239

252
253
254
255

14*

15*

16*

17*

18*

19*

1A*

1B*

1C*

1D*

1E*

1F*

304
305
306
307

320
321
322
323

336
337
338
339

352
353
354
355

368
369
370
371

0
1
2
3

384
385
386
387

400
401
402
403

416
417
418
419

432
433
434
435

448
449
450
451

464
465
466
467

480
481
482
483

496
497
498
499

292
293
294
295

308
309
310
311

324
325
326
327

340
341
342
343

356
357
358
359

372
373
374
375

4
5
6
7

388
389
390
391

404
405
406
407

420
421
422
423

436
437
438
439

452
453
454
455

468
469
470
471

484
485
486
487

500
501
502
503

280
281
282
283

296
297
298
299

312
313
314
315

328
329
330
331

344
345
346
347

360
361
362
363

376
377
378
379

8
9
A
B

392
393
394
395

408
409
410
411

424
425
426
427

440
441
442
443

456
457
458
459

472
473
474
475

488
489
490
491

504
505
506
507

284
285
286
287

300
301
302
303

316
317
318
319

332
333
334
335

348
349
350
351

364
365
366
367

380
381
382
383

C
D
E
F

396
397
398
399

412
413
414
415

428
429
430
431

444
445
446
447

460
461
462
463

476
477
478
479

492
493
494
495

508
509
510
511

00*

01*

02*

03*

04*

05*

06*

07*

0
1
2
3

0
1
2
3

16
17
18
19

32
33
34
35

48
49
50
51

64
65
66
67

80
81
82
83

96
97
98
99

112
113
114
115

4
5
6
7

4
5
6
7

20
21
22
23

36
37
38
39

52
53
54
55

68
69
70
71

84
85
86
87

100
101
102
103

8
9
A
B

8
9
10
11

24
25
26
27

40
41
42
43

56
57
58
59

72
73
74
75

88
89
90
91

C
D
E
F

12
13
14
15

28
29
30
31

44
45
46
47

60
61
62
63

76
77
78
79

10*

11*

12*

13*

0
1
2
3

256
257
258
259

272
273
274
275

288
289
290
291

4
5
6
7

260
261
262
263

276
277
278
279

8
9
A
B

264
265
266
267

C
D
E
F

268
269
270
271

Appendix A: Conversion and Reference Tables

989

28*

29*

2A*

2B*

2C*

2D*

2E*

2F*

0
1
2
3

640
641
642
643

656
657
658
659

672
673
674
675

688
689
690
691

704
705
706
707

720
721
722
723

736
737
738
739

752
753
754
755

628
629
630
631

4
5
6
7

644
645
646
647

660
661
662
663

676
677
678
679

692
693
694
695

708
709
710
711

724
725
726
727

740
741
742
743

756
757
758
759

616
617
618
619

632
633
634
635

8
9
A
B

648
649
650
651

664
665
666
667

680
681
682
683

696
697
698
699

712
713
714
715

728
729
730
731

744
745
746
747

760
761
762
763

604
605
606
607

620
621
622
623

636
637
638
639

C
D
E
F

652
653
654
655

668
669
670
671

684
685
686
687

700
701
702
703

716
717
718
719

732
733
734
735

748
749
750
751

764
765
766
767

34*

35*

36*

37*

38*

39*

3A*

3B*

3C*

3D*

3E*

3F*

816
817
818
819

832
833
834
835

848
849
850
851

864
865
866
867

880
881
882
883

0
1
2
3

896
897
898
899

912
913
914
915

928
929
930
931

944
945
946
947

960
961
962
963

976
977
978
979

992
993
994
995

1008
1009
1010
1011

804
805
806
807

820
821
822
823

836
837
838
839

852
853
854
855

868
869
870
871

884
885
886
887

4
5
6
7

900
901
902
903

916
917
918
919

932
933
934
935

948
949
950
951

964
965
966
967

980
981
982
983

996
997
998
999

1012
1013
1014
1015

792
793
794
795

808
809
810
811

824
825
826
827

840
841
842
843

856
857
858
859

872
873
874
875

888
889
890
891

8
9
A
B

904
905
906
907

920
921
922
923

936
937
938
939

952
953
954
955

968
969
970
971

984
985
986
987

1000
1001
1002
1003

1016
1017
1018
1019

796
797
798
799

812
813
814
815

828
829
830
831

844
845
846
847

860
861
862
863

876
877
878
879

892
893
894
895

C
D
E
F

908
909
910
911

924
925
926
927

940
941
942
943

956
957
958
959

972
973
974
975

988
989
990
991

1004
1005
1006
1007

1020
1021
1022
1023

20*

21*

22*

23*

24*

25*

26*

27*

0
1
2
3

512
513
514
515

528
529
530
531

544
545
546
547

560
561
562
563

576
577
578
579

592
593
594
595

608
609
610
611

624
625
626
627

4
5
6
7

516
517
518
519

532
533
534
535

548
549
550
551

564
565
566
567

580
581
582
583

596
597
598
599

612
613
614
615

8
9
A
B

520
521
522
523

536
537
538
539

552
553
554
555

568
569
570
571

584
585
586
587

600
601
602
603

C
D
E
F

524
525
526
527

540
541
542
543

556
557
558
559

572
573
574
575

588
589
590
591

30*

31*

32*

33*

0
1
2
3

768
769
770
771

784
785
786
787

800
801
802
803

4
5
6
7

772
773
774
775

788
789
790
791

8
9
A
B

776
777
778
779

C
D
E
F

780
781
782
783

990

Assembler Language Programming for IBM z System Servers

Version 1.00

48*

49*

4A*

4B*

4C*

4D*

4E*

4F*

0
1
2
3

1152
1153
1154
1155

1168
1169
1170
1171

1184
1185
1186
1187

1200
1201
1202
1203

1216
1217
1218
1219

1232
1233
1234
1235

1248
1249
1250
1251

1264
1265
1266
1267

1140
1141
1142
1143

4
5
6
7

1156
1157
1158
1159

1172
1173
1174
1175

1188
1189
1190
1191

1204
1205
1206
1207

1220
1221
1222
1223

1236
1237
1238
1239

1252
1253
1254
1255

1268
1269
1270
1271

1128
1129
1130
1131

1144
1145
1146
1147

8
9
A
B

1160
1161
1162
1163

1176
1177
1178
1179

1192
1193
1194
1195

1208
1209
1210
1211

1224
1225
1226
1227

1240
1241
1242
1243

1256
1257
1258
1259

1272
1273
1274
1275

1116
1117
1118
1119

1132
1133
1134
1135

1148
1149
1150
1151

C
D
E
F

1164
1165
1166
1167

1180
1181
1182
1183

1196
1197
1198
1199

1212
1213
1214
1215

1228
1229
1230
1231

1244
1245
1246
1247

1260
1261
1262
1263

1276
1277
1278
1279

54*

55*

56*

57*

58*

59*

5A*

5B*

5C*

5D*

5E*

5F*

1328
1329
1330
1331

1344
1345
1346
1347

1360
1361
1362
1363

1376
1377
1378
1379

1392
1393
1394
1395

0
1
2
3

1408
1409
1410
1411

1424
1425
1426
1427

1440
1441
1442
1443

1456
1457
1458
1459

1472
1473
1474
1475

1488
1489
1490
1491

1504
1505
1506
1507

1520
1521
1522
1523

1316
1317
1318
1319

1332
1333
1334
1335

1348
1349
1350
1351

1364
1365
1366
1367

1380
1381
1382
1383

1396
1397
1398
1399

4
5
6
7

1412
1413
1414
1415

1428
1429
1430
1431

1444
1445
1446
1447

1460
1461
1462
1463

1476
1477
1478
1479

1492
1493
1494
1495

1508
1509
1510
1511

1524
1525
1526
1527

1304
1305
1306
1307

1320
1321
1322
1323

1336
1337
1338
1339

1352
1353
1354
1355

1368
1369
1370
1371

1384
1385
1386
1387

1400
1401
1402
1403

8
9
A
B

1416
1417
1418
1419

1432
1433
1434
1435

1448
1449
1450
1451

1464
1465
1466
1467

1480
1481
1482
1483

1496
1497
1498
1499

1512
1513
1514
1515

1528
1529
1530
1531

1308
1309
1310
1311

1324
1325
1326
1327

1340
1341
1342
1343

1356
1357
1358
1359

1372
1373
1374
1375

1388
1389
1390
1391

1404
1405
1406
1407

C
D
E
F

1420
1421
1422
1423

1436
1437
1438
1439

1452
1453
1454
1455

1468
1469
1470
1471

1484
1485
1486
1487

1500
1501
1502
1503

1516
1517
1518
1519

1532
1533
1534
1535

40*

41*

42*

43*

44*

45*

46*

47*

0
1
2
3

1024
1025
1026
1027

1040
1041
1042
1043

1056
1057
1058
1059

1072
1073
1074
1075

1088
1089
1090
1091

1104
1105
1106
1107

1120
1121
1122
1123

1136
1137
1138
1139

4
5
6
7

1028
1029
1030
1031

1044
1045
1046
1047

1060
1061
1062
1063

1076
1077
1078
1079

1092
1093
1094
1095

1108
1109
1110
1111

1124
1125
1126
1127

8
9
A
B

1032
1033
1034
1035

1048
1049
1050
1051

1064
1065
1066
1067

1080
1081
1082
1083

1096
1097
1098
1099

1112
1113
1114
1115

C
D
E
F

1036
1037
1038
1039

1052
1053
1054
1055

1068
1069
1070
1071

1084
1085
1086
1087

1100
1101
1102
1103

50*

51*

52*

53*

0
1
2
3

1280
1281
1282
1283

1296
1297
1298
1299

1312
1313
1314
1315

4
5
6
7

1284
1285
1286
1287

1300
1301
1302
1303

8
9
A
B

1288
1289
1290
1291

C
D
E
F

1292
1293
1294
1295

Appendix A: Conversion and Reference Tables

991

68*

69*

6A*

6B*

6C*

6D*

6E*

6F*

0
1
2
3

1664
1665
1666
1667

1680
1681
1682
1683

1696
1697
1698
1699

1712
1713
1714
1715

1728
1729
1730
1731

1744
1745
1746
1747

1760
1761
1762
1763

1776
1777
1778
1779

1652
1653
1654
1655

4
5
6
7

1668
1669
1670
1671

1684
1685
1686
1687

1700
1701
1702
1703

1716
1717
1718
1719

1732
1733
1734
1735

1748
1749
1750
1751

1764
1765
1766
1767

1780
1781
1782
1783

1640
1641
1642
1643

1656
1657
1658
1659

8
9
A
B

1672
1673
1674
1675

1688
1689
1690
1691

1704
1705
1706
1707

1720
1721
1722
1723

1736
1737
1738
1739

1752
1753
1754
1755

1768
1769
1770
1771

1784
1785
1786
1787

1628
1629
1630
1631

1644
1645
1646
1647

1660
1661
1662
1663

C
D
E
F

1676
1677
1678
1679

1692
1693
1694
1695

1708
1709
1710
1711

1724
1725
1726
1727

1740
1741
1742
1743

1756
1757
1758
1759

1772
1773
1774
1775

1788
1789
1790
1791

74*

75*

76*

77*

78*

79*

7A*

7B*

7C*

7D*

7E*

7F*

1840
1841
1842
1843

1856
1857
1858
1859

1872
1873
1874
1875

1888
1889
1890
1891

1904
1905
1906
1907

0
1
2
3

1920
1921
1922
1923

1936
1937
1938
1939

1952
1953
1954
1955

1968
1969
1970
1971

1984
1985
1986
1987

2000
2001
2002
2003

2016
2017
2018
2019

2032
2033
2034
2035

1828
1829
1830
1831

1844
1845
1846
1847

1860
1861
1862
1863

1876
1877
1878
1879

1892
1893
1894
1895

1908
1909
1910
1911

4
5
6
7

1924
1925
1926
1927

1940
1941
1942
1943

1956
1957
1958
1959

1972
1973
1974
1975

1988
1989
1990
1991

2004
2005
2006
2007

2020
2021
2022
2023

2036
2037
2038
2039

1816
1817
1818
1819

1832
1833
1834
1835

1848
1849
1850
1851

1864
1865
1866
1867

1880
1881
1882
1883

1896
1897
1898
1899

1912
1913
1914
1915

8
9
A
B

1928
1929
1930
1931

1944
1945
1946
1947

1960
1961
1962
1963

1976
1977
1978
1979

1992
1993
1994
1995

2008
2009
2010
2011

2024
2025
2026
2027

2040
2041
2042
2043

1820
1821
1822
1823

1836
1837
1838
1839

1852
1853
1854
1855

1868
1869
1870
1871

1884
1885
1886
1887

1900
1901
1902
1903

1916
1917
1918
1919

C
D
E
F

1932
1933
1934
1935

1948
1949
1950
1951

1964
1965
1966
1967

1980
1981
1982
1983

1996
1997
1998
1999

2012
2013
2014
2015

2028
2029
2030
2031

2044
2045
2046
2047

60*

61*

62*

63*

64*

65*

66*

67*

0
1
2
3

1536
1537
1538
1539

1552
1553
1554
1555

1568
1569
1570
1571

1584
1585
1586
1587

1600
1601
1602
1603

1616
1617
1618
1619

1632
1633
1634
1635

1648
1649
1650
1651

4
5
6
7

1540
1541
1542
1543

1556
1557
1558
1559

1572
1573
1574
1575

1588
1589
1590
1591

1604
1605
1606
1607

1620
1621
1622
1623

1636
1637
1638
1639

8
9
A
B

1544
1545
1546
1547

1560
1561
1562
1563

1576
1577
1578
1579

1592
1593
1594
1595

1608
1609
1610
1611

1624
1625
1626
1627

C
D
E
F

1548
1549
1550
1551

1564
1565
1566
1567

1580
1581
1582
1583

1596
1597
1598
1599

1612
1613
1614
1615

70*

71*

72*

73*

0
1
2
3

1792
1793
1794
1795

1808
1809
1810
1811

1824
1825
1826
1827

4
5
6
7

1796
1797
1798
1799

1812
1813
1814
1815

8
9
A
B

1800
1801
1802
1803

C
D
E
F

1804
1805
1806
1807

992

Assembler Language Programming for IBM z System Servers

Version 1.00

88*

89*

8A*

8B*

8C*

8D*

8E*

8F*

0
1
2
3

2176
2177
2178
2179

2192
2193
2194
2195

2208
2209
2210
2211

2224
2225
2226
2227

2240
2241
2242
2243

2256
2257
2258
2259

2272
2273
2274
2275

2288
2289
2290
2291

2164
2165
2166
2167

4
5
6
7

2180
2181
2182
2183

2196
2197
2198
2199

2212
2213
2214
2215

2228
2229
2230
2231

2244
2245
2246
2247

2260
2261
2262
2263

2276
2277
2278
2279

2292
2293
2294
2295

2152
2153
2154
2155

2168
2169
2170
2171

8
9
A
B

2184
2185
2186
2187

2200
2201
2202
2203

2216
2217
2218
2219

2232
2233
2234
2235

2248
2249
2250
2251

2264
2265
2266
2267

2280
2281
2282
2283

2296
2297
2298
2299

2140
2141
2142
2143

2156
2157
2158
2159

2172
2173
2174
2175

C
D
E
F

2188
2189
2190
2191

2204
2205
2206
2207

2220
2221
2222
2223

2236
2237
2238
2239

2252
2253
2254
2255

2268
2269
2270
2271

2284
2285
2286
2287

2300
2301
2302
2303

94*

95*

96*

97*

98*

99*

9A*

9B*

9C*

9D*

9E*

9F*

2352
2353
2354
2355

2368
2369
2370
2371

2384
2385
2386
2387

2400
2401
2402
2403

2416
2417
2418
2419

0
1
2
3

2432
2433
2434
2435

2448
2449
2450
2451

2464
2465
2466
2467

2480
2481
2482
2483

2496
2497
2498
2499

2512
2513
2514
2515

2528
2529
2530
2531

2544
2545
2546
2547

2340
2341
2342
2343

2356
2357
2358
2359

2372
2373
2374
2375

2388
2389
2390
2391

2404
2405
2406
2407

2420
2421
2422
2423

4
5
6
7

2436
2437
2438
2439

2452
2453
2454
2455

2468
2469
2470
2471

2484
2485
2486
2487

2500
2501
2502
2503

2516
2517
2518
2519

2532
2533
2534
2535

2548
2549
2550
2551

2328
2329
2330
2331

2344
2345
2346
2347

2360
2361
2362
2363

2376
2377
2378
2379

2392
2393
2394
2395

2408
2409
2410
2411

2424
2425
2426
2427

8
9
A
B

2440
2441
2442
2443

2456
2457
2458
2459

2472
2473
2474
2475

2488
2489
2490
2491

2504
2505
2506
2507

2520
2521
2522
2523

2536
2537
2538
2539

2552
2553
2554
2555

2332
2333
2334
2335

2348
2349
2350
2351

2364
2365
2366
2367

2380
2381
2382
2383

2396
2397
2398
2399

2412
2413
2414
2415

2428
2429
2430
2431

C
D
E
F

2444
2445
2446
2447

2460
2461
2462
2463

2476
2477
2478
2479

2492
2493
2494
2495

2508
2509
2510
2511

2524
2525
2526
2527

2540
2541
2542
2543

2556
2557
2558
2559

80*

81*

82*

83*

84*

85*

86*

87*

0
1
2
3

2048
2049
2050
2051

2064
2065
2066
2067

2080
2081
2082
2083

2096
2097
2098
2099

2112
2113
2114
2115

2128
2129
2130
2131

2144
2145
2146
2147

2160
2161
2162
2163

4
5
6
7

2052
2053
2054
2055

2068
2069
2070
2071

2084
2085
2086
2087

2100
2101
2102
2103

2116
2117
2118
2119

2132
2133
2134
2135

2148
2149
2150
2151

8
9
A
B

2056
2057
2058
2059

2072
2073
2074
2075

2088
2089
2090
2091

2104
2105
2106
2107

2120
2121
2122
2123

2136
2137
2138
2139

C
D
E
F

2060
2061
2062
2063

2076
2077
2078
2079

2092
2093
2094
2095

2108
2109
2110
2111

2124
2125
2126
2127

90*

91*

92*

93*

0
1
2
3

2304
2305
2306
2307

2320
2321
2322
2323

2336
2337
2338
2339

4
5
6
7

2308
2309
2310
2311

2324
2325
2326
2327

8
9
A
B

2312
2313
2314
2315

C
D
E
F

2316
2317
2318
2319

Appendix A: Conversion and Reference Tables

993

A8*

A9*

AA*

AB*

AC*

AD*

AE*

AF*

0
1
2
3

2688
2689
2690
2691

2704
2705
2706
2707

2720
2721
2722
2723

2736
2737
2738
2739

2752
2753
2754
2755

2768
2769
2770
2771

2784
2785
2786
2787

2800
2801
2802
2803

2676
2677
2678
2679

4
5
6
7

2692
2693
2694
2695

2708
2709
2710
2711

2724
2725
2726
2727

2740
2741
2742
2743

2756
2757
2758
2759

2772
2773
2774
2775

2788
2789
2790
2791

2804
2805
2806
2807

2664
2665
2666
2667

2680
2681
2682
2683

8
9
A
B

2696
2697
2698
2699

2712
2713
2714
2715

2728
2729
2730
2731

2744
2745
2746
2747

2760
2761
2762
2763

2776
2777
2778
2779

2792
2793
2794
2795

2808
2809
2810
2811

2652
2653
2654
2655

2668
2669
2670
2671

2684
2685
2686
2687

C
D
E
F

2700
2701
2702
2703

2716
2717
2718
2719

2732
2733
2734
2735

2748
2749
2750
2751

2764
2765
2766
2767

2780
2781
2782
2783

2796
2797
2798
2799

2812
2813
2814
2815

B4*

B5*

B6*

B7*

B8*

B9*

BA*

BB*

BC*

BD*

BE*

BF*

2864
2865
2866
2867

2880
2881
2882
2883

2896
2897
2898
2899

2912
2913
2914
2915

2928
2929
2930
2931

0
1
2
3

2944
2945
2946
2947

2960
2961
2962
2963

2976
2977
2978
2979

2992
2993
2994
2995

3008
3009
3010
3011

3024
3025
3026
3027

3040
3041
3042
3043

3056
3057
3058
3059

2852
2853
2854
2855

2868
2869
2870
2871

2884
2885
2886
2887

2900
2901
2902
2903

2916
2917
2918
2919

2932
2933
2934
2935

4
5
6
7

2948
2949
2950
2951

2964
2965
2966
2967

2980
2981
2982
2983

2996
2997
2998
2999

3012
3013
3014
3015

3028
3029
3030
3031

3044
3045
3046
3047

3060
3061
3062
3063

2840
2841
2842
2843

2856
2857
2858
2859

2872
2873
2874
2875

2888
2889
2890
2891

2904
2905
2906
2907

2920
2921
2922
2923

2936
2937
2938
2939

8
9
A
B

2952
2953
2954
2955

2968
2969
2970
2971

2984
2985
2986
2987

3000
3001
3002
3003

3016
3017
3018
3019

3032
3033
3034
3035

3048
3049
3050
3051

3064
3065
3066
3067

2844
2845
2846
2847

2860
2861
2862
2863

2876
2877
2878
2879

2892
2893
2894
2895

2908
2909
2910
2911

2924
2925
2926
2927

2940
2941
2942
2943

C
D
E
F

2956
2957
2958
2959

2972
2973
2974
2975

2988
2989
2990
2991

3004
3005
3006
3007

3020
3021
3022
3023

3036
3037
3038
3039

3052
3053
3054
3055

3068
3069
3070
3071

A0*

A1*

A2*

A3*

A4*

A5*

A6*

A7*

0
1
2
3

2560
2561
2562
2563

2576
2577
2578
2579

2592
2593
2594
2595

2608
2609
2610
2611

2624
2625
2626
2627

2640
2641
2642
2643

2656
2657
2658
2659

2672
2673
2674
2675

4
5
6
7

2564
2565
2566
2567

2580
2581
2582
2583

2596
2597
2598
2599

2612
2613
2614
2615

2628
2629
2630
2631

2644
2645
2646
2647

2660
2661
2662
2663

8
9
A
B

2568
2569
2570
2571

2584
2585
2586
2587

2600
2601
2602
2603

2616
2617
2618
2619

2632
2633
2634
2635

2648
2649
2650
2651

C
D
E
F

2572
2573
2574
2575

2588
2589
2590
2591

2604
2605
2606
2607

2620
2621
2622
2623

2636
2637
2638
2639

B0*

B1*

B2*

B3*

0
1
2
3

2816
2817
2818
2819

2832
2833
2834
2835

2848
2849
2850
2851

4
5
6
7

2820
2821
2822
2823

2836
2837
2838
2839

8
9
A
B

2824
2825
2826
2827

C
D
E
F

2828
2829
2830
2831

994

Assembler Language Programming for IBM z System Servers

Version 1.00

C8*

C9*

CA*

CB*

CC*

CD*

CE*

CF*

0
1
2
3

3200
3201
3202
3203

3216
3217
3218
3219

3232
3233
3234
3235

3248
3249
3250
3251

3264
3265
3266
3267

3280
3281
3282
3283

3296
3297
3298
3299

3312
3313
3314
3315

3188
3189
3190
3191

4
5
6
7

3204
3205
3206
3207

3220
3221
3222
3223

3236
3237
3238
3239

3252
3253
3254
3255

3268
3269
3270
3271

3284
3285
3286
3287

3300
3301
3302
3303

3316
3317
3318
3319

3176
3177
3178
3179

3192
3193
3194
3195

8
9
A
B

3208
3209
3210
3211

3224
3225
3226
3227

3240
3241
3242
3243

3256
3257
3258
3259

3272
3273
3274
3275

3288
3289
3290
3291

3304
3305
3306
3307

3320
3321
3322
3323

3164
3165
3166
3167

3180
3181
3182
3183

3196
3197
3198
3199

C
D
E
F

3212
3213
3214
3215

3228
3229
3230
3231

3244
3245
3246
3247

3260
3261
3262
3263

3276
3277
3278
3279

3292
3293
3294
3295

3308
3309
3310
3311

3324
3325
3326
3327

D4*

D5*

D6*

D7*

D8*

D9*

DA*

DB*

DC*

DD*

DE*

DF*

3376
3377
3378
3379

3392
3393
3394
3395

3408
3409
3410
3411

3424
3425
3426
3427

3440
3441
3442
3443

0
1
2
3

3456
3457
3458
3459

3472
3473
3474
3475

3488
3489
3490
3491

3504
3505
3506
3507

3520
3521
3522
3523

3536
3537
3538
3539

3552
3553
3554
3555

3568
3569
3570
3571

3364
3365
3366
3367

3380
3381
3382
3383

3396
3397
3398
3399

3412
3413
3414
3415

3428
3429
3430
3431

3444
3445
3446
3447

4
5
6
7

3460
3461
3462
3463

3476
3477
3478
3479

3492
3493
3494
3495

3508
3509
3510
3511

3524
3525
3526
3527

3540
3541
3542
3543

3556
3557
3558
3559

3572
3573
3574
3575

3352
3353
3354
3355

3368
3369
3370
3371

3384
3385
3386
3387

3400
3401
3402
3403

3416
3417
3418
3419

3432
3433
3434
3435

3448
3449
3450
3451

8
9
A
B

3464
3465
3466
3467

3480
3481
3482
3483

3496
3497
3498
3499

3512
3513
3514
3515

3528
3529
3530
3531

3544
3545
3546
3547

3560
3561
3562
3563

3576
3577
3578
3579

3356
3357
3358
3359

3372
3373
3374
3375

3388
3389
3390
3391

3404
3405
3406
3407

3420
3421
3422
3423

3436
3437
3438
3439

3452
3453
3454
3455

C
D
E
F

3468
3469
3470
3471

3484
3485
3486
3487

3500
3501
3502
3503

3516
3517
3518
3519

3532
3533
3534
3535

3548
3549
3550
3551

3564
3565
3566
3567

3580
3581
3582
3583

C0*

C1*

C2*

C3*

C4*

C5*

C6*

C7*

0
1
2
3

3072
3073
3074
3075

3088
3089
3090
3091

3104
3105
3106
3107

3120
3121
3122
3123

3136
3137
3138
3139

3152
3153
3154
3155

3168
3169
3170
3171

3184
3185
3186
3187

4
5
6
7

3076
3077
3078
3079

3092
3093
3094
3095

3108
3109
3110
3111

3124
3125
3126
3127

3140
3141
3142
3143

3156
3157
3158
3159

3172
3173
3174
3175

8
9
A
B

3080
3081
3082
3083

3096
3097
3098
3099

3112
3113
3114
3115

3128
3129
3130
3131

3144
3145
3146
3147

3160
3161
3162
3163

C
D
E
F

3084
3085
3086
3087

3100
3101
3102
3103

3116
3117
3118
3119

3132
3133
3134
3135

3148
3149
3150
3151

D0*

D1*

D2*

D3*

0
1
2
3

3328
3329
3330
3331

3344
3345
3346
3347

3360
3361
3362
3363

4
5
6
7

3332
3333
3334
3335

3348
3349
3350
3351

8
9
A
B

3336
3337
3338
3339

C
D
E
F

3340
3341
3342
3343

Appendix A: Conversion and Reference Tables

995

E8*

E9*

EA*

EB*

EC*

ED*

EE*

EF*

0
1
2
3

3712
3713
3714
3715

3728
3729
3730
3731

3744
3745
3746
3747

3760
3761
3762
3763

3776
3777
3778
3779

3792
3793
3794
3795

3808
3809
3810
3811

3824
3825
3826
3827

3700
3701
3702
3703

4
5
6
7

3716
3717
3718
3719

3732
3733
3734
3735

3748
3749
3750
3751

3764
3765
3766
3767

3780
3781
3782
3783

3796
3797
3798
3799

3812
3813
3814
3815

3828
3829
3830
3831

3688
3689
3690
3691

3704
3705
3706
3707

8
9
A
B

3720
3721
3722
3723

3736
3737
3738
3739

3752
3753
3754
3755

3768
3769
3770
3771

3784
3785
3786
3787

3800
3801
3802
3803

3816
3817
3818
3819

3832
3833
3834
3835

3676
3677
3678
3679

3692
3693
3694
3695

3708
3709
3710
3711

C
D
E
F

3724
3725
3726
3727

3740
3741
3742
3743

3756
3757
3758
3759

3772
3773
3774
3775

3788
3789
3790
3791

3804
3805
3806
3807

3820
3821
3822
3823

3836
3837
3838
3839

F4*

F5*

F6*

F7*

F8*

F9*

FA*

FB*

FC*

FD*

FE*

FF*

3888
3889
3890
3891

3904
3905
3906
3907

3920
3921
3922
3923

3936
3937
3938
3939

3952
3953
3954
3955

0
1
2
3

3968
3969
3970
3971

3984
3985
3986
3987

4000
4001
4002
4003

4016
4017
4018
4019

4032
4033
4034
4035

4048
4049
4050
4051

4064
4065
4066
4067

4080
4081
4082
4083

3876
3877
3878
3879

3892
3893
3894
3895

3908
3909
3910
3911

3924
3925
3926
3927

3940
3941
3942
3943

3956
3957
3958
3959

4
5
6
7

3972
3973
3974
3975

3988
3989
3990
3991

4004
4005
4006
4007

4020
4021
4022
4023

4036
4037
4038
4039

4052
4053
4054
4055

4068
4069
4070
4071

4084
4085
4086
4087

3864
3865
3866
3867

3880
3881
3882
3883

3896
3897
3898
3899

3912
3913
3914
3915

3928
3929
3930
3931

3944
3945
3946
3947

3960
3961
3962
3963

8
9
A
B

3976
3977
3978
3979

3992
3993
3994
3995

4008
4009
4010
4011

4024
4025
4026
4027

4040
4041
4042
4043

4056
4057
4058
4059

4072
4073
4074
4075

4088
4089
4090
4091

3868
3869
3870
3871

3884
3885
3886
3887

3900
3901
3902
3903

3916
3917
3918
3919

3932
3933
3934
3935

3948
3949
3950
3951

3964
3965
3966
3967

C
D
E
F

3980
3981
3982
3983

3996
3997
3998
3999

4012
4013
4014
4015

4028
4029
4030
4031

4044
4045
4046
4047

4060
4061
4062
4063

4076
4077
4078
4079

4092
4093
4094
4095

E0*

E1*

E2*

E3*

E4*

E5*

E6*

E7*

0
1
2
3

3584
3585
3586
3587

3600
3601
3602
3603

3616
3617
3618
3619

3632
3633
3634
3635

3648
3649
3650
3651

3664
3665
3666
3667

3680
3681
3682
3683

3696
3697
3698
3699

4
5
6
7

3588
3589
3590
3591

3604
3605
3606
3607

3620
3621
3622
3623

3636
3637
3638
3639

3652
3653
3654
3655

3668
3669
3670
3671

3684
3685
3686
3687

8
9
A
B

3592
3593
3594
3595

3608
3609
3610
3611

3624
3625
3626
3627

3640
3641
3642
3643

3656
3657
3658
3659

3672
3673
3674
3675

C
D
E
F

3596
3597
3598
3599

3612
3613
3614
3615

3628
3629
3630
3631

3644
3645
3646
3647

3660
3661
3662
3663

F0*

F1*

F2*

F3*

0
1
2
3

3840
3841
3842
3843

3856
3857
3858
3859

3872
3873
3874
3875

4
5
6
7

3844
3845
3846
3847

3860
3861
3862
3863

8
9
A
B

3848
3849
3850
3851

C
D
E
F

3852
3853
3854
3855

996

Assembler Language Programming for IBM z System Servers

Version 1.00

Conversion Tables for Hexadecimal Fractions


The six pairs of columns give respectively a hexadecimal fraction and its decimal equivalent. For example,
the decimal value of the hexadecimal fraction .FF is .9375+.05859375, or 0.99609375.
.1
.2
.3
.4
.5
.6
.7
.8
.9
.A
.B
.C
.D
.E
.F

.0625
.1250
.1875
.2500
.3125
.3750
.4375
.5000
.5625
.6250
.6875
.7500
.8125
.8750
.9375

.01
.02
.03
.04
.05
.06
.07
.08
.09
.0A
.0B
.0C
.0D
.0E
.0F

.00390625
.00781250
.01171875
.01562500
.01953125
.02343750
.02734375
.03125000
.03515625
.03906250
.04296875
.04687500
.05078125
.05468750
.05859375

.001
.002
.003
.004
.005
.006
.007
.008
.009
.00A
.00B
.00C
.00D
.00E
.00F

.000244140625
.000488281250
.000732421875
.000976562500
.001220703125
.001464843750
.001708984375
.001953125000
.002197265625
.002441406250
.002685546875
.002929687500
.003173828125
.003417968750
.003662109375

.
.0001
.0002
.0003
.0004
.0005
.0006
.0007
.0008
.0009
.000A
.000B
.000C
.000D
.000E
.000F

.0000152587890625
.0000305175781250
.0000457763671875
.0000610351562500
.0000762939453125
.0000915527343750
.0001068115234375
.0001220703125000
.0001373291015625
.0001525878906250
.0001678466796875
.0001831054687500
.0001983642578125
.0002136230468750
.0002288818359375
.000001
.000002
.000003
.000004
.000005
.000006
.000007
.000008
.000009
.00000A
.00000B
.00000C
.00000D
.00000E
.00000F

.00001
.00002
.00003
.00004
.00005
.00006
.00007
.00008
.00009
.0000A
.0000B
.0000C
.0000D
.0000E
.0000F

.00000095367431640625
.00000190734863281250
.00000286102294921875
.00000381469726562500
.00000476837158203125
.00000572204589843750
.00000667572021484375
.00000762939453125000
.00000858306884765625
.00000953674316406250
.00001049041748046875
.00001144409179687500
.00001239776611328125
.00001335144042968750
.00001430511474609375

.000000059604644775390625
.000000119209289550781250
.000000178813934326171875
.000000238418579101562500
.000000298023223876953125
.000000357627868652343750
.000000417232513427734375
.000000476837158203125000
.000000536441802978515625
.000000596046447753906250
.000000655651092529296875
.000000715255737304687500
.000000774860382080078125
.000000834465026855468750
.000000894069671630859375

Appendix A: Conversion and Reference Tables

997

EBCDIC Character Representation in Assembler Language Programs


This table uses IBM code page 037.

Table 439. Assembler Language EBCDIC character representation


Char
Blank
.
(
+
&
$
*
)
/
,
_
#
@

=
a
b
c
d

998

Hex
40
4B
4D
4E
50
5B
5C
5D
60
61
6B
6D
7B
7C
7D
7E
81
82
83
84

Char
e
f
g
h
i
j
k
l
m
n
o
p
q
r
s
t
u
v
w
x

Hex
85
86
87
88
89
91
92
93
94
95
96
97
98
99
A2
A3
A4
A5
A6
A7

Assembler Language Programming for IBM z System Servers

Char
y
z
A
B
C
D
E
F
G
H
I
J
K
L
M
N
O
P
Q
R

Version 1.00

Hex
A8
A9
C1
C2
C3
C4
C5
C6
C7
C8
C9
D1
D2
D3
D4
D5
D6
D7
D8
D9

Char
S
T
U
V
W
X
Y
Z
0
1
2
3
4
5
6
7
8
9

Hex
E2
E3
E4
E5
E6
E7
E8
E9
F0
F1
F2
F3
F4
F5
F6
F7
F8
F9

ASCII Character Representation in Assembler Language Programs


Char
Code
Char
Code
Char
blank
20
8
38
P
!
21
9
39
Q

22
:
3A
R
#
23
;
3B
S
$
24
<
3C
T
%
25
=
3D
U
&
26
>
3E
V

27
?
3F
W
(
28
@
40
X
)
29
A
41
Y
*
2A
B
42
Z
+
2B
C
43
[
,
2C
D
44
2D
E
45
]
.
2E
F
46
^
/
2F
G
47
_
0
30
H
48
`
1
31
I
49
a
2
32
J
4A
b
3
33
K
4B
c
4
34
L
4C
d
5
35
M
4D
4
6
36
N
4E
f
7
37
O
4F
g
Table 440. 7-bit ASCII character representation

Code
50
51
52
53
54
55
56
57
58
59
5A
5B
5C
5D
5E
5F
60
61
62
63
64
65
66
67

Char
h
i
j
k
l
m
n
o
p
q
r
s
t
u
v
w
x
y
z
{
|
}

(none)

Code
68
69
6A
6B
6C
6D
6E
6F
70
71
72
73
74
75
76
77
78
79
7A
7B
7C
7D
7E
7F

Appendix A: Conversion and Reference Tables

999

DC Statement Types
Table 441. High Level Assembler DC-Statement Constant Types
Type
A
B
C
C
C
C
D
D
D
D
E
E
E
E
F
G
H
J
L
L
L
L
P
Q
Q
R
S
S
V
Y
Z

1000

Subtype(s)
(D)

A
E
U
B
D
H
B
D
H
(D)
(D)
(D)
B
D
H
(D)
Y
(D)
Y
(D)

Default
Length(s)

Modifiers

Pad/
Truncate

4 (8)
Minimum
Minimum
Minimum
Minimum
Minimum
8
8
8
8
4
4
4
4
4 (8)
Minimum
2 (8)
4 (8)
16
16
16
16
Minimum
4 (8)
3
4 (8)
2
3
4 (8)
2
Minimum

L
L
L
L
L
L
L,S,E
L,E
E
L,S,E
L,S,E
L,E
E
L,S,E
L,S,E
L
L,S,E
L
L,S,E
L,E
E
L,S,E
L
L
L3
L
L2
L3
L
L
L

Left
Left
Right
Right
Right
Right
Right
Right
None
Right
Right
Right
None
Right
Left
Right
Left
Left
Right
Right
None
Right
Left
None
None
Left
None
None
None
Left
Left

Assembler Language Programming for IBM z System Servers

Constant
Absolute or relocatable expression
Binary
EBCDIC Characters
ASCII characters generated
EBCDIC characters generated
Unicode characters generated
Hexadecimal floating-point
Binary floating-point
Decimal floating-point
Hexadecimal floating-point (improved rounding)
Hexadecimal floating-point
Binary floating-point
Decimal floating-point
Hexadecimal floating-point (improved rounding)
Fixed-point binary
Graphic (usually Kanji)
Fixed-point binary
Class length
Hexadecimal floating-point
Binary floating-point
Decimal floating-point
Hexadecimal floating-point (improved rounding)
Packed decimal
DXD or Part offset
Long-displacement DXD or Part offset
PSECT address
12-bit-displacement base-displacement address
Long-displacement base-displacement address
External symbol
Absolute or relocatable expression
Zoned decimal

Version 1.00

Appendix B: Simple I/O Macros

IIIIIIIIII
//
IIIIIIIIII
//
II
//
II
//
II
//
II
//
II
//
II
//
II
//
II
//
II
//
IIIIIIIIII //
IIIIIIIIII //

OOOOOOOOOOOO
OOOOOOOOOOOO
OO
OO
OO
OO
OO
OO
OO
OO
OO
OO
OO
OO
OO
OO
OO
OO
OO
OO
OOOOOOOOOOOO
OOOOOOOOOOOO

The forms that I/O takes within and across z/Architecture operating systems is varied enough that it takes
many books to describe them. So that you wont need to understand the I/O rules associated with a particular Operating System, the simple needs of small programs like the Programming Problems here can be
satisfied by the following facilities:
1. An instruction (READCARD) to read 80-character records into a named area in your program, with provision for optionally transferring control to some out-of-line location if no further records are available.
2. An instruction (PRINTLIN) to print line images on a printer file, with carriage control characters and
optional specification of the length of the character string to be printed.
3. An instruction (PRINTOUT) to:

print the value of the contents of an area of memory, giving its name as well as the value of the
contents in an easily-readable format.

print the contents of the General Purpose and Floating-Point registers.

return control to the Supervisor when program execution has been successfully completed.

4. An instruction (CONVERTO) to convert the contents of a General Purpose register to a string of decimal
characters in memory.
5. An instruction (CONVERTI) to convert decimal characters in memory to a signed binary value in a
General Purpose register.
6. An instruction (DUMPOUT) to generate a formatted hexadecimal dump of specified areas of memory.
These macro instructions do not change the Condition Code.

Macro Facilities
These facilities are provided by the READCARD, PRINTLIN, CONVERTO, CONVERTI, DUMPOUT, and PRINTOUT
macro-instructions,
First, here is a summary of the abbreviations used in the descriptions.
<name>

any valid symbol naming an area of memory which is addressable from the point where
it is used in a macro-instruction.

<number>

any valid self-defining term; limits on the size of the term are described for each macroinstruction. In most cases, a predefined absolute symbol may be used.

<d(b)>

any valid operand providing an addressable displacement and base.

<nfs>

a valid (and optional) name-field symbol (label) naming the macro-instruction in whose
name field it appears.

[optional]

square brackets around a term means that it is optional.

...

an ellipsis means that the preceding item may be repeated any number of times.
Appendix B: Simple I/O Macros

1001

Examples of these macro-instructions are given below.


You may want to precede the first call to any of these macros with a
PRINT NOGEN
statement; otherwise your listing will include many generated statements that wont have much meaning to
you until youve had more experience with z System.

The READCARD Macro-Instruction


READCARD reads records into an 80-byte buffer in the program. This macro-instruction is written
<nfs>

READCARD

<name>[,<name>]

where either <name> operand may also be written as <d(b)>.


It reads a record from the input file into the 80-byte area beginning at the first operand address. If no
record is available, then (1) control is returned to the instruction specified by the second operand if it is
present, or (2) if no second operand is present, execution is terminated with the message
*** Execution terminated by Reader EOF
For example,
READCARD

MyRecord

will read the next record and place it as an 80-byte EBCDIC character string at the location named
MyRecord; if no record is present, execution will be terminated. The instruction
GetARec

READCARD

MyRecord,EndFile

does the same as the previous example, except that if no record is available, control will be transferred to
the instruction named EndFile.

The PRINTLIN Macro-Instruction


The PRINTLIN macro-instruction is written in the form
<nfs>

PRINTLIN

<name>[,<number>]

where the <name> and optional <number> operands may also be written as <d(b).
PRINTLIN causes the character string beginning at the location defined by the first operand to be printed;
the number of characters is specified by the second operand (which may be a predefined absolute symbol).
The print-line length is limited to 121 characters.
The first character of the string will be detached and used for spacing control. The ANSI Standard carriage control characters are:

an
an
an
an
an

EBCDIC
EBCDIC
EBCDIC
EBCDIC
EBCDIC


0
-
1
+

(blank) means single space,


(zero) means double space,
(minus) means triple space,
(one) means start at the top of a new page, and
(plus) means no spacing (the new line will be printed over the previous one).

If the second operand is omitted, the length of the character string is assumed to be 121 bytes, which means
that 120 characters will be printed after the first is detached. 302 If the second operand is present, it is taken
to be the length of the string; the number of characters specified will be placed at the left end of an internal
buffer, extended to 121 bytes with blanks if necessary, and then sent to the printer file. For example, we
could write
PrTtl
Title

PRINTLIN Title
- - DC
CL121 1 Title for top line of the page

to print the indicated title at the top of a new page. If we wrote


PRINTLIN

Title,1

then the printer would skip to the top of a new page and print a blank line there, because only the spacing
control character (the 1) is transmitted from the program to the print file.

302

See the discussion at Operating System Environment and Installation Considerations on page 1008 for information on setting the
default print-line length.

1002

Assembler Language Programming for IBM z System Servers

Version 1.00

The CONVERTO Macro-Instruction


The CONVERTO macro-instruction is written in the form
<nfs>

CONVERTO

<number>,<address>

where the <number> is the number of a general or floating-point register, and <address> points to a string of
bytes in storage where the converted result is stored. The <address> operand may also be written as
<d(b)>.
CONVERTO converts the contents of the designated register from binary to decimal characters (for general
registers) or to hexadecimal characters (for floating-point registers). The first character of the converted
result is always blank, so it may be printed immediately using the PRINTLIN macro.
Note that the length of the generated character string is always as specified below; be careful to allocate
enough space for the result so that you wont overwrite other data or instructions.
If the value of the <number> operand does not lie in the range 0 <number> 47, the macro call is
ignored.
32-bit general register
A <number> between 0 and 15 specifies the corresponding 32-bit general register. For example, if the
operand is 9, the contents of GR9 will be converted to a string of 12 characters. For example, if
c ( G R 9 ) = X 80000000 , the formatted string will be the 12 characters (where is our representation
for a blank character):
-2147483648
64-bit general register
A <number> between 16 and 31 (less 16) specifies the corresponding 64-bit general register. For
example, if the operand is 16, the contents of GGR0 will be converted to a string of 21 characters.
For example, if c(GG9)=X 80000000 00000000 , the formatted string will be the 21 characters
(where is our representation for a blank character):
-9223372036854775808
Execution on z/Architecture is required.
Floating-Point Register
A <number> between 32 and 47 (less 32) specifies the corresponding Floating-Point Register. For
example, if the operand is 36, the contents of FPR4 will be printed as a string of 20 characters (where
is our representation for a blank character):
X FEDCBA9876543210
Because there are three floating-point representations, and because accurate conversion from
hexadecimal and binary floating-point formats is quite difficult, only hexadecimal values are displayed.
Be Careful!
If your system does not support z/Architecture instructions or the full set of 16
Floating-Point registers, trying to display their contents may cause a program
interruption for an invalid operation code or a specification exception.

The CONVERTI Macro-Instruction


CONVERTI is generally used to scan a data record received by the READCARD macro instruction. It converts a
string of optionally signed decimal characters to binary into a specified 32-bit or 64-bit general register, and
sets GR1 to the address of the non-digit character at which scanning was stopped. This means that you can
convert multiple values from the same character string.
The CONVERTI macro-instruction is written in the form
<nfs>

CONVERTI

<number>,<address>[,ERR=<address>] [ ,STOP=<address>]

where <number> specifies a general register, and <address> is the starting address of a string of bytes in
storage of characters to be converted to binary. The <address> operand may also be written as <d(b)>.
The first non-blank character must be a plus sign, a minus sign, or a decimal digit; otherwise, GR1 is set to
the address of that character and the register specified by <number> is unchanged. (If you expect unusual
characters to be scanned, you should specify the STOP= operand on the CONVERTI statement.)

Appendix B: Simple I/O Macros

1003

Be Careful!
Dont specify either 1 or 17 for the <number> operand, because any converted
value in GR1 or GG1 will be replaced by the address of the stop character.
The optional keyword operands ERR= and STOP= specify locations in your program where the CONVERTI will
transfer control if certain conditions occur:
ERR=

If the value of the <number> operand is greater than 31, or if the value of the significant decimal
digits at the <address> operand is too large to be converted correctly to the general register specified by the <number> operand, control will be transferred to the <address> given by the ERR=
operand.

STOP=

If an invalid character is found in the string of characters starting at the <address> operand, GR1
is set to the address of that character and control will be transferred to the <address> given by the
STOP= operand. (See example 3 below.)

If either of these conditions occurs and the needed ERR= or STOP= <address> is not specified, CONVERTI will
print a message and terminate the program.
32-bit general register
A <number> between 0 and 15 specifies the corresponding 32-bit general register. The number to be
converted must have no more than 10 significant digits. Insignificant leading zero digits are ignored.
64-bit general register
A <number> between 16 and 31 (less 16) specifies the corresponding 64-bit general register. The
number to be converted must have no more than 19 significant digits. Insignificant leading zero digits
are ignored.
Execution on z/Architecture is required.
For example:
1. Convert the digits at D1 to binary in 32-bit GR3:

D1

CONVERTI
- - DC
C

3,D1
+019

The contents of GR3 will be X 00000013 and GR1 will contain the address of the blank character
following the digit 9.
2. Convert the digits at D2 to binary in 64-bit GG5:

D2

CONVERTI 21,D2
- - DC
C -9223372036854775808

The contents of GG5 will be X 8000000 00000000 and GR1 will contain the address of the blank
character following the final digit 8.
3. The character string at D3 contains several values to be stored at Table. The scan is terminated by the
character *.

CvtLoop

Check

D3

LA
3,Table
LA
2,D3
Start of string
CONVERTI 0,0(2),STOP=Check
Invalid character? Test at Check
ST
0,0(,3)
Store an entry at Table
LA
3,4(,3)
Point to next Table entry
B
CvtLoop
Resume converting
- - CLI
0(1),C *
Is the invalid character ours?
JNE
BadChar
No, a bad character appeared
- - DC
C +1 -2+3 -0000000000000004 *

and the four words starting at Table will contain the values 1, 2, 3, and 4.
Providing a known stop character lets you scan an input string for all the values provided. For
example, a record stored at InRec by the READCARD macro could be followed by a stop character:
InRec
DS
StopChar DC

1004

CL80
C *

Buffer area
Stop character

Assembler Language Programming for IBM z System Servers

Version 1.00

The PRINTOUT Macro-Instruction


The PRINTOUT macro-instruction lets you print the value of the contents of named areas of memory, the
contents of registers, and to terminate execution.
The operand field of the PRINTOUT macro-instruction may contain any number of <name>s or <number>s
separated by commas, with no intervening blanks. An operand consisting of a single asterisk will terminate
execution. The basic forms of the PRINTOUT macro-instruction are written
<nfs>

PRINTOUT

<name>[,<number>...]

<nfs>

PRINTOUT

where any combination of the <name> and <number> operands may be used in an operand list; either may
be written in the form <d(b)>. If the asterisk operand is used, it is treated as the last operand in the list.
For example,
AllDone

PRINTOUT

0,*

will display the contents of GR0 and then terminate execution.


A <number> operand with value between 0 and 47 causes the contents of a register to be printed in hex and
decimal; larger values are treated as addresses. The <number> may in most cases be a predefined absolute
symbol.
32-bit general register
a <number> between 0 and 15 specifies the corresponding 32-bit general register. For example, if the
operand is 12, the contents of GR12 will be printed:
GPR

12

= X FFFFFFF3 =

-13

64-bit general register


a <number> between 16 and 31 (less 16) specifies the corresponding 64-bit general register. For
example, if the operand is 16, the contents of GGR0 will be printed:
GGR

= X1234567890ABCDEF =

1311768467294899695

Execution on z/Architecture is required.


Floating-Point Register
a <number> between 32 and 47 (less 32) specifies the corresponding Floating-Point Register. For
example, if the operand is 36, the contents of FPR4 will be printed:
FPR

= X FEDCBA9876543210

Because there are three floating-point representations, and because accurate conversion from
hexadecimal and binary floating-point formats is quite difficult, only hexadecimal values are displayed.
Be Careful!
If your system does not support z/Architecture instructions or the full set of
16 Floating-Point registers, trying to display their contents may cause a
program interruption for an invalid operation code or a specification
exception.
To print the contents of the original four floating-point registers F0, F2, F4, and F6, we could write
FourFPRs PRINTOUT

32,34,36,38

Printing the contents of any other Floating-Point Register requires those registers to be installed and available on your machine.
To print the contents of R14 and then terminate execution, we could write
PRINTOUT

X E , *

To print the contents of memory areas named A, B, and C, we could write


PRINTOUT

A,B,C

The format of the output depends on the type attribute of the symbol naming the memory area:

Type attribute C (character) data is shown as strings of at most 100 characters.


Type attribute F or H data are shown as signed decimal numbers.
If you use forms like PRINTOUT d(b) and d has attributes C, F, or H, the result will be formatted as
above; otherwise, the data is displayed as 16 hexadecimal digits.
Other type attributes cause data to be displayed as 2 to 100 hexadecimal digits, depending on the length
attribute of the operand.

Appendix B: Simple I/O Macros

1005

Specifying PRINTOUT with no operand is useful for flow tracing; only a header line is printed. An example is
shown below.
PRINTOUT
If you want a comment field on the statement, put a single comma as the operand:
PRINTOUT

Your comments here

Finally, if you want to terminate execution with no message:


PRINTOUT

*,Header=NO

Terminate quietly

Any value other than No (in any mixture of upper and lower case) will be treated as yes.

The DUMPOUT Macro-Instruction


The DUMPOUT macro-instruction is written in the form
<nfs>

DUMPOUT

<name>[,<name>]

where either <name> operand can be written as <d(b)>.


DUMPOUT prints a formatted hexadecimal dump of the area of memory starting with the fullword containing the first operand, 32 bytes to a line. If the second operand is omitted, one line will be printed. If the
second operand is given, all of memory between the two addresses will be dumped. The dump starts from
the lower of the two addresses and proceeds toward the higher. The lower address is rounded down to a
fullword boundary, and 32 bytes are displayed on each line even if some bytes are at addresses greater than
the higher address. 303
No checks are made to avoid possible storage access violations. For example,
DumpA

DUMPOUT

will cause the 32-byte area of memory starting at (or very near) A to be dumped. Similarly,
DumpAB

DUMPOUT

A,B

would print a dump of the area of memory starting with a line containing the byte at A and ending with a
line which includes the byte named B.

PRINTOUT and DUMPOUT Header


Normally, the output produced by the PRINTOUT and DUMPOUT macros will be preceded by a header line:
*** PRINTOUT requested at Address xxxxxx, Statement sssss, CC=n
or
***

DUMPOUT requested at Address xxxxxx, Statement sssss, CC=n

where sssss is the statement number of the macro, and CC=n shows the current Condition Code setting.
To suppress this header line, you can specify an additional operand HEADER=NO on the PRINTOUT or DUMPOUT
macro. For example:
ABDMP

PRINTOUT
DUMPOUT

A,B,C,Header=No
A,B,header=no

The default is HEADER=YES.

Usage Notes
1. All five macros require residence in RMODE(24) storage below the 16MB line, and execute in
AMODE(24). The generated code is frequently self-modifying, and is not re-enterable.
2. Most operands of the form <name>, <d(b)>, and <number> are resolved in S-type address constants, so
addressability is required when all macros except $$GENIO are invoked.
3. When you execute a macro, be sure that the base register used at assembly time to resolve the S-type
constants has the correct address at execution time.
4. Be careful not to reference areas outside your program, as you may risk interruptions for memory
protection violations.

303

That is, the dump is from the smaller to the larger of (LowAddr/4)4 and ((HighAddr+31)/32)32.

1006

Assembler Language Programming for IBM z System Servers

Version 1.00

5. If you use PRINTOUT to display named areas of memory, it uses the names attributes for formatting
the result.
6. At most eight characters of the <name> and <d(b)> operands are displayed. If you write
PRINTOUT 00000000(3),00000000(7)
the eight bytes addressed by registers GR3 and GR7 will be displayed in hexadecimal, but both with
have the name 00000000.

Sample Program
Here is a small sample program that uses all of these macros. The assembly listing and its output are in the
following figures.
IOMacs

Print
CSect
Using
SR

Nogen
,
*,15
1,1

Suppress expansions
Sample Program
Local base register
Clear card counter
Next statement for flow tracing

*
Read

EOF

Out
CardOut
LineLen
OutData
Last

PrintOut
ReadCard CardOut,EOF
Read card until endfile
LA
1,1(0,1)
Increment card counter
PrintOut 1
Print the count register
PrintLin Out,Linelen
Print a line
ConvertI 0,CardOut
Convert a number
ConvertO 0,OutData
Put it in printable form
PrintLin OutData,L OutData Print the value
B
Read
Go back and read again
DumpOut IOMacs,Last
Dump everything
XGR
3,3
Set GGR3 to 0 (z/Architecture!)
BCTGR 3,0
Set GGR3 to -1 (z/Architecture!)
PrintOut 1,19,32,*
Print GR1, GG3, FPR0, terminate
DC
C 0 Input Record = First part of line
DC
CL80
Card image here
Equ
*-Out
Define line length
DS
CL12
Converted chars/binary/chars
Equ
*
Last byte of program
End

The program uses READCARD to read two card images, keeps a count in GR1 which is displayed with
PRINTOUT. The card image just read is shown with a prefix using PRINTLIN. Then, one number from each
record is converted to binary using CONVERTI, and then to printable format using CONVERTO. The result of
each conversion is printed using PRINTLIN.
When there are no more input records, DUMPOUT shows the entire program. Finally PRINTOUT * also displays
the contents of GR1, GG3, and FPR0 before terminating the program.
The two input records look like this:
+123456
-000034567890

* First record
* Second and last record

Here is a portion of the assembly listing, including the carriage control characters.
0
000000
R:F

00000 001E2
00000

000000 1B11
000002 90EF F00C
000024
00004A
00004E
00007C
00009C
0000BC
0000DC
0000FC
000100
000128
00012C

0700
4110
90EF
0700
0700
0700
0700
47F0
0700
B982
B946

0000C

1001
F058

00001
00058

F024

00024

0033
0030

1
2 IOMacs
3
4
5 *
6
17+
749 Read
760
761
773
781
789
797
805
806 EOF
817
818

Print
CSect
Using
SR

Nogen
,
*,15
1,1

Suppress expansions
Sample Program
Local base register
Clear card counter
Next statement for flow tracing

PrintOut
Print OFF
Suppress this stuff
ReadCard CardOut,EOF
Read card until endfile
LA
1,1(0,1)
Increment card counter
PrintOut 1
Print the count register
PrintLin Out,Linelen
Print a line
ConvertI 0,CardOut
Convert a number
ConvertO 0,OutData
Put it in printable form
PrintLin OutData,L OutData Print the value
B
Read
Go back and read again
DumpOut IOMacs,Last
Dump everything
XGR
3,3
Set GGR3 to 0 (z/Architecture!)
BCTGR 3,0
Set GGR3 to -1 (z/Architecture!)

02-$$GEN

Appendix B: Simple I/O Macros

1007

000130 0700
000176 F0C99597A4A340D9
000186 4040404040404040
00060
0001D6
001E2

819
835
836
837
838
839
840

Out
CardOut
LineLen
OutData
Last

PrintOut 1,19,32,*
Print GR1, GG3, FPR0, terminate
DC
C 0 Input Record = First part of line
DC
CL80
Card image here
Equ
*-Out
Define line length
DS
CL12
Converted chars/binary/chars
Equ
*
Last byte of program
End

The output from this sample program is shown below. The listing shows the carriage control characters.
*** PRINTOUT requested at Address 021002, Statement
6, CC=0
*** PRINTOUT requested at Address 02104E, Statement
761, CC=0
GPR
1 = X00000001 =
1
0Input Record =
+123456
* First record
123456
*** PRINTOUT requested at Address 02104E, Statement
761, CC=0
GPR
1 = X00021191 =
135569
0Input Record =
-000034567890
* Second and last record
-34567890
*** DUMPOUT requested at Address 021100, Statement
806, CC=0
021000 1B1190EF F00C58F0 F01405EF 00F126CA 00021000 00021204 F0021002
021020 98EFE000 070090EF F03058F0 F03805EF 00F126CA 00021000 8002122C
021040 F18698EF E00047F0 F1004110 100190EF F05858F0 F06005EF 00F126CA
021060 00021204 0002104E 000002F9 A0070001 F1404040 40404040 98EFE000
021080 F08858F0 F09005EF 00F126CA 00021000 000211F8 F1760060 98EFE000
0210A0 F0A858F0 F0B005EF 00F126CA 00021000 00021220 0000F186 98EFE000
0210C0 F0C858F0 F0D005EF 00F126CA 00021000 00021214 0000F1D6 98EFE000
0210E0 F0E858F0 F0F005EF 00F126CA 00021000 000211F8 F1D6000C 98EFE000
021100 070090EF F10C58F0 F11405EF 00F126CA 00021000 000211E8 00021100
021120 F000F1E2 98EFE000 B9820033 B9460030 070090EF F13C58F0 F14405EF
021140 00000000 00021204 00021130 00000333 20070001 F1404040 40404040
021160 F1F94040 40404040 20070020 F3F24040 40404040 0800F0C9 9597A4A3
021180 96998440 7E404040 4060F0F0 F0F0F3F4 F5F6F7F8 F9F04040 40404040
0211A0 4040405C 40E28583 96958440 81958440 9381A2A3 40998583 96998440
0211C0 40404040 40404040 40404040 40404040 40404040 40404040 4060F3F4
0211E0 F9F00000 00000000 900FF098 9201F13E 41C00008 A7F40020 900FF088
*** PRINTOUT requested at Address 021130, Statement
819, CC=0
GPR
1 = X00021196 =
135574
GGR
3 = X FFFFFFFFFFFFFFFF =
-1
FPR
0 = X0000000000000000
*** Execution terminated by PRINTOUT * at Address 021130

00000006
00021024
00021000
070090EF
070090EF
070090EF
070090EF
47F0F024
00000326
00000000
20070013
40D98583
40404040
40404040
F5F6F7F8
41C00004

*....0..00....1..........0.......*
*q.......0..00....1..............*
*1fq....01.......0..00-...1......*
*.......+...9....1
q.......*
*0h.00....1.........81..-q.......*
*0y.00....1............1fq.......*
*0H.00....1............1Oq.......*
*0Y.000...1.........81O..q....00.*
*....1..01....1.........Y........*
*0.1Sq....b..........1..01.......*
*....................1
....*
*19
....32
..0Input Rec*
*ord =
-000034567890
*
*
* Second and last record
*
*
-345678*
*90........0qk.1.....x4....0h....*

The Macro Instruction Definitions


The following macro definitions can be used to implement the READCARD, CINVERTO, CONVERTI,
PRINTLIN, PRINTOUT, and DUMPOUT macro-instructions. An important feature of these macroinstructions is that they may be used anywhere in a program: they make no changes to any register (except
for CONVERTI, which changes the GR1 and the result register), do not change the Condition Code, and
do not contain any USING or DROP instructions that could affect addressability in your program.
The last macro definition (for $$GENIO) generates the code to perform the functions requested by the other
macros. It does not require the user to do anything special about addressability, so the macros may be
used in any program.

Operating System Environment and Installation Considerations


First, place the macro definitions in a macro library accessible to the Assembler. The default print-line
length (121) can be changed in the PRINTLIN macro, and in the $$GENIO macro by modifying the variable
&$$PLL. The default DDnames are
Print
Read

MVS/CMS=SYSPRINT,
MVS/CMS=SYSIN,

VSE=SYSLST
VSE=SYSIPT

and can be changed by modifying the &$$ONAM and &$$INAM variable symbols in macro $$GENIO.
The $$GENIO macro is complex. It generates the $$IOSECT CSECT with six entry points. It can be used in
two ways:
1. The instructions in the $$IOSECT can be generated as part of the users program, if the variable symbol
&$$LIBIO is set to 0 in the first few lines of the $$GENIO macro. This is simpler, but causes an invisible
gap in the statement numbers of the listing. The hidden statements can be displayed by specifying the
Assembler option PCONTROL(GEN,ON) but the generated code will be confusing to all but advanced students.

1008

Assembler Language Programming for IBM z System Servers

Version 1.00

2. Alternatively, you can generate the $$IOSECT instructions into a separate module. (This has the advantage of hiding the complexities of the $$GENIO macro, but requires a little bit more initial setup.) First,
set the &$$LIBIO variable symbol to 0, and create and assemble this short program:
$$GENIO
End
Link the generated object module into a library accessible at program linking and loading time. Then,
change the $$LIBIO variable symbol to 1 to suppress subsequent inline generation, and store the macro
back in the macro library.
All symbols generated in the expansions of these macros begin with the two characters $$. If this conflicts
with your conventions (or desires), change each occurrence of $$ to whatever two other characters you
like. (The symbol cross-reference for any assembly using these macros will include many symbols starting
with those two characters.)
The macros have been extensively tested under MVS, CMS, and VSE, and are set up to run under MVS or
CMS as the default. To run them under VSE, change the &$$DOS SETB statement (near the front of the
$$GENIO macro definition) according to the instructions there. Similarly, to change the default file names or
print line length, modify the following SETC statements as indicated there.

Appendix B: Simple I/O Macros

1009

READCARD Macro
MACRO
&LABEL READCARD &DATA,&EOFADDR BOTH ARGS ADDRESSABLE
.***************************************************************
.* This macro reads a single 80-character card image into the *
.* buffer area provided by &DATA. If an end-of-file condition *
.* is sensed on the input file, and the end-file parameter
*
.* &EOFADDR is present, then control will be returned to that *
.* location. If no end-file parameter is present, the job
*
.* is terminated with an appropriate message.
*
.***************************************************************
LCLB &EOFFLG
1 IF THERE IS EOFADDR
LCLA &T
AIF (&LABEL EQ ) . AA SKIP LABEL DEFINITION
&LABEL DC
0H 0
DECLARE LABEL
.AA
AIF (&EOFADDR EQ ) . DECLAB TEST IF EOFADDR PRESENT
&EOFFLG SETB 1
EOFADDR PRESENT
.DECLAB AIF (&DATA NE ) . PARMOK SEE IF FIRST PARAM THERE
MNote 8, Missing data area parameter. READCARD ignored.
MEXIT
ERROR EXIT FROM MACRO
.PARMOK ANOP ,
$$RC&SYSNDX DC 0H 0
DECLARE INTERNAL LABEL
CNOP 2,4
ALIGNMENT
STM 14,15,*+10
SAVE REGS 14 & 15
L
15,*+14
ADDRESS READCARD ROUTINE
BALR 14,15
CALL ROUTINE
&T
SETA 128*&EOFFLG
DC
2F 0 , AL1(&T),VL3($$READCD),A($$RC&SYSNDX),S(&DATA)
LM
14,15,0(14)
RESTORE R14 & R15
AIF (NOT(&EOFFLG)).GENIO NO EOFFADDR, NO BC INSTR
BC
0,&EOFADDR
COND. JUMP TO EOFADDR
.GENIO $$GENIO
GENERATE I/O SECTION
MEND

PRINTLIN Macro
MACRO
&LABEL PRINTLIN &DATA,&LEN
.***************************************************************
.* This macro sends a line image to the printer. The first
*
.* character of the string starting at &DATA is assumed to be *
.* an ASA carriage control character. The default line length *
.* is 121 characters, but this value may be overridden by the *
.* value given in the optional second parameter, &LEN. If the *
.* value of &LEN is greater than 121, then 121 will be used. *
.***************************************************************
AIF (&LABEL EQ ) . AA SKIP LABEL DEFINITION
&LABEL DC
0H 0
DECLARE LABEL
.AA
AIF (&DATA NE ) . PARMOK ERR IF NO DATA AREA
MNOTE 8, Missing data area parameter. PRINTLIN ignored.
MEXIT
.PARMOK CNOP 2,4
ALIGNMENT
STM 14,15,*+10
SAVE R14 & R15
L
15,*+14
ADDR PRINTLIN ROUTINE
BALR 14,15
CALL
AIF (&LEN EQ ) . DEFLEN IF LEN OMIT. USE DEFAULT
DC
2F 0 , V($$PRTLIN),S(&DATA),S(&LEN)
AGO .LM
.DEFLEN DC
2F 0 , V($$PRTLIN),S(&DATA),S(121) DEFAULT LENGTH
.LM
LM
14,15,0(14)
RESTORE REGS.
$$GENIO
GENERATE I/O SECTION
MEND

1010

Assembler Language Programming for IBM z System Servers

Version 1.00

CONVERTO Macro
Macro
&L
CONVERTO &R,&A
.***************************************************************
.* This macro converts the value in the register operand to
*
.* a signed string of decimal characters, placing the result *
.* in the second operand field. If the register operand is
*
.* between 32 and 47, the floating point register is converted *
.* to hexadecimal characters.
*
.*
*
.* Generated parameter list:
*
.*
DC
2F 0
For caller s R14,R15
*
.*
DC
V($$CNVRTO)
*
.*
DC
S(register),S(memory_address)
*
.***************************************************************
AIF (N&SysList eq 2).CVT1
.BadArg MNote 8, Invalid CONVERTO argument list.
MExit ,
.CVT1
AIF (&L eq ) . CVT2
&L
DC
0H 0
.CVT2
CNop 2,4
STM 14,15,*+10
L
15,*+14
BALR 14,15
DC
2F 0 , V($$CNVRTO),S(&R),S(&A)
LM
14,15,0(14)
$$GENIO
MEnd

CONVERTI Macro
Macro
&L
CONVERTI &R,&A,&ERR=,&STOP=
.***************************************************************
.* This macro converts a character string starting at the
*
.* address to a binary integer in the register operand. If the *
.* register operand is greater than 31, and if the number being*
.* scanned is too large, the ERR= exit is taken, and R1 is set *
.* to the address of the next character to be scanned. If an *
.* invalid character is encountered, the STOP= exit is taken, *
.* and R1 is set to the address of that character.
*
.*
*
.* If either of these error occurs and no exit address is
*
.* provided, a message is issued and the program halts.
*
.*
*
.* Generated parameter list:
*
.*
DC
2F 0
For caller s R14,R15
*
.*
DC
AL1(Flag),VL3($$CNVRTI)
*
.*
DC
S(register),S(memory_address)
*
.*
BC
0,&ERR+0 if register or number is invalid
*
.*
BC
0,&STOP+0 if an invalid character is found
*
.* These two BCs are not generated if no keywords are present. *
.***************************************************************
LCLA &F
AIF (N&SysList eq 2).A
MNote 8, CONVERTI: 2 operands required
MExit ,
.A
ANop ,
&L
CNop 2,4
STM 14,15,*+10
L
15,*+14
BALR 14,15
AIF (&ERR eq ) . B
&F
SetA 1
.B
AIF (&STOP eq ) . GenData
&F
SetA &F+2
.GenData DC
2F 0 , AL1(&F),VL3($$CNVRTI),S(&R),S(&A)
LM
14,15,0(14)
AIF (NOT &F).GenIO
BC
0,&ERR+0
Error in register or number
BC
0,&STOP+0
Invalid character found in scan
.GenIO $$GENIO

Appendix B: Simple I/O Macros

1011

MEnd

DUMPOUT Macro
MACRO
&LABEL DUMPOUT &LOW,&HIGH,&HEADER=YES
.***************************************************************
.* This macro dumps out an area of memory between the addresses*
.* specified by &LOW and &HIGH. The dump is in standard form, *
.* with eight words per line along with their EBCDIC character *
.* format at the right end. The header, giving the location
*
.* from which the macro was called, is optional.
*
.***************************************************************
LCLA &HDR,&N
&HDR = 1 IF NO HEADER
LCLC &HDRC
HEADER
&N
SetA &SYSSTMT
Save statement number
AIF (&LABEL EQ ) . NL SKIP LABEL DEFINITION
&LABEL DC 0H 0
DEFINE MACRO NAME
.NL
AIF (&LOW NE ) . LOW FIRST PARM IS THERE
MNOTE 8, No starting address. DUMPOUT ignored.
MEXIT
.LOW
ANOP
$$DO&SYSNDX DC 0H 0
DECLARE INTERNAL LABEL
CNOP 2,4
ALIGNMENT
STM 14,15,*+10
SAVE R14 & R15
L
15,*+14
ADDR DUMPOUT ROUTINE
BALR 14,15
CALL
&HDRC
SetC Upper(&HEADER )
Force to upper case
AIF (&HDRC NE NO ) . NHDR SKIP IF A HEADER
&HDR
SETA 1
SET TO IGNORE HEADER
.NHDR
DC 2F 0 , V($$DMPOUT),AL1(&HDR),AL3($$DO&SYSNDX),A(&N-1)
AIF (&HIGH EQ ) . NOHIGH NO HIGH PARM
DC
S(&LOW),S(&HIGH) DUMPOUT ADDRESSES
AGO .FINIS
.NOHIGH DC
2S(&LOW)
DUMPOUT ADDRESS
.FINIS LM
14,15,0(14)
RESTORE REGISTERS
$$GENIO
GENERATE I/O SECTION
MEND

PRINTOUT Macro
MACRO
&LABEL PRINTOUT &HEADER=YES
.***************************************************************
.* This macro lets you print register contents, areas of
*
.* memory, and terminate execution. To print an area of memory,*
.* specify its symbolic name.
*
.*
*
.* Memory operands must be addressable
*
.*
by an S-type address constant to be printed *
.* by this macro -- all such arguments must be addressable.
*
.* There may be any number of arguments for each macro call. *
.* The printed output will contain the name of the item and
*
.* the value of the named item. The output for each call may *
.* be preceded by a header message, which will be omitted if *
.* HEADER=NO is coded (after the last operand, usually).
*
.*
*
.* To terminate execution of the program, code * as the last *
.* (or only) operand.
*
.***************************************************************
LCLA &CNT,&LPCNT,&TCODE,&LENGTH,&A,&N
LCLB &BADOP
Missing/Ignored operand
LCLC &HDRC
Uppercase HEADER operand
.* &CNT is number of parameters; &LPCNT is loop counter;
.* &TCODE is operand code,
&N
SetA &SYSSTMT
Calling statement number
LCLC &T
TYPE CODE OF PARAM.
&CNT
SETA N&SYSLIST
GET NO. OF ARGS.
$$PO&SYSNDX DC 0H 0
DECLARE INTERNAL LABEL
CNOP 2,4
ALIGNMENT
&LABEL STM 14,15,*+10
SAVE REGS.
L
15,*+14
ADDR PRINTOUT ROUTINE
BALR 14,15
CALL ROUTINE

1012

Assembler Language Programming for IBM z System Servers

Version 1.00

DC
2F 0 , V($$PRTOUT) SAVE AREA, ADDR PRINTOUT
SetC Upper(&HEADER )
Upper case
AIF (&HDRC NE NO ) . NHDR
&A
SETA 1
INDICATE NO HEADER
.NHDR
AIF (&CNT NE 0).SS1
&A
SETA &A+240
INDICATE NO PARMS
.SS1
DC
AL1(&A),AL3($$PO&SYSNDX),A(&N-1) PARAMETER FLAGS
AIF (&CNT EQ 0).ENDLOOP EXIT IF NO PARMS
.PARMLP AIF (&CNT LE &LPCNT).ENDLOOP TEST IF LOOP COMPLETE
&LPCNT SETA &LPCNT+1
INC. LOOP CNTR
&T
SETC T&SYSLIST(&LPCNT) TYPE CODE OF OPERAND
&TCODE SETA 32
HEX IS DEFAULT
&LENGTH SETA 8
DEFAULT LENGTH
AIF (&SYSLIST(&LPCNT) NE * ) . SS4 BRANCH IF NOT *
DC
X0800
PRINTOUT *
AGO .GENIO
GENERATE I/O SECTION
.SS4
AIF (&T EQ C ) . CHAR BRANCH IF OPER. CHAR.
AIF (&T EQ F OR &T EQ H ) . DEC PRINT AS DEC
AIF (&T EQ J OR &T EQ M ) . LOK DEFAULT ATTR.
AIF (&T EQ T OR &T EQ U ) . LOK DEFAULT ATTR.
AIF (&T EQ N ) . LOKN DEFAULT ATTRIBUTES
AIF (&T NE O ) . GETLEN GET LENGTH ATTRIB.
MNOTE *, Omitted argument &LPCNT ignored.
&BADOP SETB (1)
Indicate bad/missing operand
AGO .PARMLP
.LOKN
ANOP
&A
SETA &SYSLIST(&LPCNT) GET VALUE OF ARGUMENT
AIF (&A LT 48).LOK
BRANCH IF VALID
MNOTE *, Operand &LPCNT ignored: value (&A) too big.
&BADOP SETB (1)
Indicate bad operand
AGO .PARMLP
SKIP THIS ARGUMENT
.DEC
ANOP
F OR H CONSTANT
&TCODE SETA 64
PRINT AS DECIMAL HWORD
AIF (&T EQ H ) . GETLEN GET LENGTH ATTRIB HWORD
&TCODE SETA 65
PRINT AS DECIMAL FWORD
AGO .GETLEN
GET LENGTH ATTRIB.
.CHAR
ANOP
CHARACTER STRING
&TCODE SETA 16
TYPE IS CHARACTER
.GETLEN ANOP
&LENGTH SETA L&SYSLIST(&LPCNT) LENGTH ATTRIBUTE
.* Max length chosen so printed data will fit on one print line
AIF (&LENGTH LE 50).LOK IF LENGTH < 50 O.K.
AIF (&LENGTH LE 100 AND &T EQ C ) . LOK CHAR, 100 OK.
&LENGTH SETA 100
MAX LENGTH FOR CHAR STR
AIF (&T EQ C ) . LOK
&LENGTH SETA 50
MAX LENGTH FOR HEX STR
.LOK
ANOP
AIF (&LPCNT NE &CNT).TCODEOK CHECK IF LAST OPERAND
&TCODE SETA &TCODE+128
LAST OPERAND
.TCODEOK ANOP
&LENGTH SETA &LENGTH-1
USE LENGTH-1 AS PARM.
DC
AL1(&TCODE),AL1(&LENGTH),S(&SYSLIST(&LPCNT))
DC
CL8&SYSLIST(&LPCNT) 8 Characters of print name
&BADOP SETB (0)
Indicate OK operand
.* PARAMS TO PRINTOUT--TYPE,LENGTH-1,S(ADDRESS),PRINTNAME
.* Type code: X80 = last item
X40 = decimal conversion
.*
X20 = hexadecimal X10 = character
.*
X08 = Prtout *
X01 = decimal fullword
.*
All zero halfword means last operand was bad
AGO .PARMLP
GET NEXT OPERAND
.ENDLOOP AIF (NOT &BADOP).DOLM Check bad last operand
DC H 0
Indicate null last operand
.DOLM
LM 14,15,0(14)
RESTORE REGISTERS
.GENIO $$GENIO
GENERATE I/O SECT
MEND
&HDRC

Appendix B: Simple I/O Macros

1013

$$GENIO Macro
MACRO
$$GENIO
.* The following local set symbols determine various options
.* for the generated control section.
GBLB &$$IOFLG
1 IF IOSECT GENERATED
LCLA &$$PLL
PRINT LINE LEN, .GE. 121
LCLB &$$DOS
SET TO 1 IF SYSTEM=DOS
&$$DOS SETB 0
SYSTEM IS OS/360 et seq.
LCLB &$$LIBIO
1 IF IOSECT is in a library.
&$$LIBIO SetB 0
Generate IOSect inline if 0,
.*
else generated code is in a runtime library if 1
LCLC &$$INAM
INPUT DDNAME
LCLC &$$ONAM
OUTPUT DDNAME
LCLC &$$CSNam,&$$CSTyp Caller s CSect name and type
.*
AIF (&$$IOFLG).MExit Exit if not required
&$$CSNam SetC &SYSECT
Save caller s CSect name
&$$CSTyp SetC &SYSSTYP
Save caller s CSect type
&$$IOFLG SetB 1
Set expansion not needed flag
AIF (Not &$$LIBIO).Gen If not in library, gen
.MExit MExit
.***************************************************************
.* This macro generates the code which implements the READCARD,*
.* PRINTLIN, DUMPOUT, and PRINTOUT macros. the OS version was *
.* implemented by James R. Low, and modified for DOS by Paul M.*
.* Dantzig, students at Stanford University. Later additions *
.* by John Ehrman.
*
.***************************************************************
.* Register usage: R13 = local base
*
.* R14,R15,R0,R1 = scratch and OS linkage
*
.* R7 = local link register, R12 = call type
*
.* R11 = parm ptr, retaddr, R10 = parm ptr(original R14)
*
.* R9 = data length, R2,R3,R4,R8 = work registers
*
.***************************************************************
.Gen
Push Print
Save PRINT status
Print OFF
Suppress this stuff
&$$IOFLG SETB 1
Set flag for $$GENIO generated
.* SET OPTIONAL VALUES
&$$PLL SETA 121
LINE LENGTH = 121
.* If the line length defined above is changed from 121 to 133,
.* remember to make the corresponding changes in the PRINTLIN
.* macro definition.
AIF (&$$DOS).OSNAME
GO DO DOS FILENAMES
&$$INAM SETC SYSIN
INPUT DDNAME
&$$ONAM SETC SYSPRINT
OUTPUT DDNAME
AGO .CSECT
GO GENERATE CSECTNAME
.OSNAME ANOP
&$$ONAM SETC SYSLST
DOS DEFAULT OUTPUT FILE
&$$INAM SETC SYSIPT
DOS DEFAULT INPUT FILE
.CSECT ANOP
$$IOSECT CSECT
$$IOSECT AMode 24
$$IOSECT RMode 24
ENTRY $$READCD,$$PRTLIN,$$PRTOUT,$$DMPOUT
ENTRY $$CNVRTO,$$CNVRTI
.*
$$DMPOUT STM 0,15,$$REGS-*(15) SAVE REGS. R15 AS BASE
MVI $$FLGS-*+4(15),1 INDICATE DUMPOUT CALL
LA
12,8
CODE FOR DUMP/PRINTOUT
J
$$LOAD13
BRANCH TO COMMON CODE
.*
$$PRTLIN STM 0,15,$$REGS-*(15) SAVE REGS. R15 AS BASE
LA
12,4
CODE INDICATES PRINTLIN
J
$$LOAD13
BRANCH TO COMMON CODE
.*
$$PRTOUT STM 0,15,$$REGS-*(15) SAVE REGS.
MVI $$FLGS-*+4(15),0 INDICATE PRINTOUT
LA
12,8
CODE FOR DUMP/PRINTOUT
J
$$LOAD13
BRANCH TO COMMON CODE
.*
$$CNVRTO STM 0,15,$$REGS-*(15) SAVE REGS.
LA
12,12
CODE FOR CONVERTO

1014

Assembler Language Programming for IBM z System Servers

Version 1.00

J
$$LOAD13
BRANCH TO COMMON CODE
.*
$$CNVRTI STM 0,15,$$REGS-*(15) SAVE REGS.
LA
12,16
CODE FOR CONVERTI
J
$$LOAD13
BRANCH TO COMMON CODE
.*
$$READCD STM 0,15,$$REGS-*(15) SAVE REGS. R15 AS BASE
SR
12,12
CODE INDICATES READ
.*
* $$LOAD13 BALR 13,0
LOAD BASE REGISTER
.*
USING *,13
ADDRESSABILITY IMPLIED
CNOP 0,4
ALIGNMENT
$$LOAD13 JAS 13,$$MOVE
SET BASE REG, JUMP DATA
.* The following USING statement, although a comment, is implied
.* throughout the code generated here. By using absolute
.* displacements (calculated relative to $$, whose address is in
.* R13), we can avoid having to issue another using statement
.* anywhere in the code generated for the I/O package, and
.* therefore the user can call these macros with assurance that
.* there will be no adverse effects on his code, no matter how
.* tortured it may be. Note that we go to great lengths to
.* avoid the generation of literals, also.
*
USING $$,13
IS ASSUMED
.*
USING *,13
ADDRESSABILITY IMPLIED
$$
EQU *
SET BASE FOR R13
AIF (&$$DOS).REGS
NO SAVE AREA FOR DOS
DC
18F 0
OS SAVE AREA
.REGS
ANOP
$$REGS DC
16F 0
LOCAL SAVE AREA for user s regs
$$FFF
DC
A(X FFFFFF )
MASK USED FOR EFF ADDR
$$F000 DC
A(X F000 )
MASK TO GET BASE REG.
$$ACALL DC
F 0
Calling address
AIF (&$$DOS).NUMC
SKIP DCB EXIT IF DOS
.* DCB EXIT SETS BLKSIZE TO LRECL IF NOT SPECIFIED OTHERWISE
$$DCBXIT DC
X 8 5 , AL3(*+3)
DCB EXIT POINTER
OC
62(2,1),62(1)
CHECK DCBBLKSIZ
BCR 7,14
RETURN IF NOT ZERO
MVC 62(2,1),82(1)
ELSE SET TO LRECL
BR
14
COMPLETE OPEN
.NUMC
ANOP
$$15
DC
H 1 5
USED TO SEE IF GPR
$$31
DC
H 3 1
USED TO SEE IF GGR
$$47
DC
H 4 7
USED TO SEE IF FPR
$$CVIASt DS
F
Digit string start address
$$CVIAEn DS
F
Digit string end+1 address
$$RDATA DC
D 0
For reg conversion subroutines
$$SAVG0 DC
D 0
To save GGR0 temporarily
$$DWORD DC 2D 0
USED FOR CVD,FLPTR,UNPK,CVDG
DC
X 0
USED FOR UNPK INTO HEX
$$CVIM32 DC
P2147483648
Maximum 32-bit binary magnitude
$$CVIM64 DC
P9223372036854775808 Max 64-bit binary magnitude
$$XTemp DS
XL4
For packing high-order digits
$$FLG2 DC
X 0 0
Temp save for no-header bit
$$FLGS DC
X 0 0
PRINTOUT PARAM FLGS.
$$CVIFlg DC
X 0 0
80=signed; 40=+; 20=-, 01=ERR exit
.* ALSO USED TO INDICATE DUMPOUT/PRINTOUT CALL
$$CC
DC
C , CC=
FOR PRINTOUT HEADING
$$CCV
DC
C 0
CC VALUE
$$ST
DC
C , Statement
Statement number text
$$GPR
DC
C GPR
FOR REGISTER PRINTOUT
$$PC
DC
C *** PRINTOUT requested at Address MESSAGE
$$DC
DC
C DUMP
OVERLAY FOR ABOVE MSG
$$XQUOTE DC
C= X
FOR PRINTING HEX DATA
$$CVIMC DC
C CONVERTI: Invalid character encountered
$$CVIMN DC
C CONVERTI: Invalid register or number too large
$$EX
DC
C *** Execution terminated by TERMINATION MSG
$$REOF DC
C Reader EOF
READCARD EOF TERMINATION
$$PEND DC
C PRINTOUT *
PRINTOUT * TERMINATION
$$ATLOC DC
C at Address
Where it happened
$$LOCP Equ L $$EX+L $$PEND+3 Offset for AT LOCATION
DC
C
USED TO CLEAR LINE BUFF
$$OUTBUF DC
CL&$$PLL
LINE BUFFER
$$PAT1 DC
X40202120
PATTERN TO PRINT Reg #
$$PAT2 DC
X402020202020202020202120 PATTERN TO PRINT DEC.

Appendix B: Simple I/O Macros

1015

$$PAT3 DC
0XL21 0 , 2 X40,17X 2 0 , X2120 Pattern for GGR
$$PAT4 DC
X402020202120
Pattern for statement number
$$DUMPTB DC
64C . , C , 9 C . , C .<(+|&& , 1 0 C . , C $*);-/
DC
9C . , C,%_>?,10C . , C : # @ = . abcdefghi , 7 C .
DC
C jklmnopqr , 8 C . , C stuvwxyz , 2 3 C . , C ABCDEFGHI
DC
7C . , C JKLMNOPQR , 8 C . , C STUVWXYZ , 6 C .
DC
C0123456789,6C .
$$TRTAB DC
C0123456789ABCDEF Hex translation taboel
$$CVITbl DS
0XL256
Input conversion translate table
*
Codes: hex 4=Invalid, 8=blank, C=+, 10=-, 14=digit
DC
(C ) X 0 4
Invalid chars
DC
XL1 8
Blank
DC
(C + -C -1)X04 X 4 1 -X 4 D invalid
DC
XL1 C
+
DC
(C - -C + -1)X04 X 4 F -X 5 F invalid
DC
XL1 1 0
DC
(C 0 -C - -1)X04 X 6 1 -X EF invalid
DC
10X 1 4
Digits
DC
6X 4
Invalid
$$RCVT DC
XL(L $$PAT3) 0
$$FLGSIO DC
X 0 0
IOFLGS
.* BIT 0 OF $$FLGSIO ONE IF OUTPUT FILE OPENED.
.* BIT 1 OF $$FLGSIO ONE IF INPUT FILE OPENED.
.* BIT 2 OF $$FLGSIO ONE IF INPUT FILE EOF ENCOUNTERED.
AIF (&$$DOS).BUF
SKIP OS MACROS IF DOS
.* The List and Execute forms of the OPEN and CLOSE macros are
.* used because they do not require addressability, as do the
.* standard forms, which make regular use of implied addresses.
$$PROPEN OPEN ($$OUDCB,(OUTPUT)),MF=L OPEN LIST FOR SYSPRINT
$$RDOPEN OPEN ($$INDCB,(INPUT)),MF=L OPEN LIST FOR SYSIN
$$PRCLOS CLOSE ($$OUDCB),MF=L
CLOSE LIST FOR SYSPRINT
$$RDCLOS CLOSE ($$INDCB),MF=L
CLOSE LIST FOR SYSIN
.* Input and output DCBs. BLKSISE might be provided on DD statement.
$$OUDCB DCB MACRF=PM,DSORG=PS,RECFM=FBA,EXLST=$$DCBXIT,
LRECL=&$$PLL,DDNAME=&$$ONAM
$$INDCB DCB MACRF=GM,DSORG=PS,LRECL=80,RECFM=FB,
DDNAME=&$$INAM,EODAD=$$EOF,EXLST=$$DCBXIT
AGO .BLANK
.BUF
ANOP
DO DOS DEFINITIONS
$$ADDRI DC
A($$INDCB)
ADDRESS OF INPUT DTF
$$ADDRO DC
A($$OUDCB)
ADDRESS OF OUTPUT DTF
.* The use of X 5 b in the following two definitions is so that
.* one can change all occurrences of $$ to some other neutral
.* characters without violating the DOS naming conventions for
.* its open and close routines.
$$OPEN DC
2X 5 B , CL6 BOPEN DOS OPEN ROUTINE NAME
$$CLOSE DC
2X 5 B , CL6 BCLOSE DOS CLOSE ROUTINE NAME
$$ASA
DC
C CBA98765432+-10
VALID ASA CONTROL CHARS
$$OUDCB DTFPR CTLCHR=ASA,WORKA=YES,IOAREA1=$$IOAOU1,
IOAREA2=$$IOAOU2,DEVADDR=&$$ONAM,BLKSIZE=&$$PLL
$$INDCB DTFCD WORKA=YES,EOFADDR=$$EOF,IOAREA1=$$IOAIN1,
IOAREA2=$$IOAIN2,BLKSIZE=80,DEVADDR=&$$INAM
$$IOAIN1 DS
CL80
INPUT BUFFER 1
$$IOAIN2 DS
CL80
INPUT BUFFER 2
$$IOAOU1 DS
CL&$$PLL
OUTPUT BUFFER 1
$$IOAOU2 DS
CL&$$PLL
OUTPUT BUFFER 2
.BLANK ANOP
$$MOVE MVC $$REGS+56-$$(8,13),0(14) COPY USER S R14 & R15
.* At this point R14 points to parameter list. R12 contains a code
.* indicating which macro was called--0 means READCARD, 4 means
.* PRINTLIN, and 8 means DUMPOUT or PRINTOUT ($$FLGS set also).
.* R10 will contain a copy of R14, the first param address.
.* R11 will point to the next param in the list.
.* $$EFADDR calculates the effective address from the halfword
.* in the right half of R2 and returns it in R0 and R2.
LR
11,14
COPY FIRST PARAM ADDRESS
LR
10,11
COPY FIRST PARAM ADDRESS
.*
SAVE CALLER S CC VALUE
LR
0,10
COPY CALLER S BALR 14 REG
SLL 0,2
DROP ILC
SRL 0,30
KEEP ONLY CC
STC 0,$$CCV-$$(0,13) STORE IN CC= TEXT
OI
$$CCV-$$(13),X F0 MAKE A CHARACTER
MVC $$ACALL-$$(3,13),13(11) Save PO/DO/RC call address

1016

Assembler Language Programming for IBM z System Servers

Version 1.00

X
X

X
X

LTR 12,12
CHECK FOR READCARD
JZ
$$OPNRD
BRANCH IF READCARD to open input
JAS 7,$$OPNOUT
OPEN PRINTER
B
*-$$(12,13)
Branch to processing routine
J
$$LINP
PRINTLIN
J
$$PODO
PRINTOUT/DUMPOUT
J
$$CVTO
CONVERTO
.*
J
$$CVTI
CONVERTI (follows immediately!)
.*------------------------------------------------------------------.* CONVERTI -- convert to 32 or 64 bit signed integer in GR
.*------------------------------------------------------------------.*State 0: validate register operand
LH
2,14(,11)
Get memory addressing halfword
JAS 7,$$EFADDR
Convert to an address
LR
3,2
Pointer carried in R3
LH
2,12(,11)
Get register addressing halfword
JAS 7,$$EFADDR
Convert to an address
LA
11,16(,11)
Set return address
CH
2,$$31-$$(,13)
Test register value
JH
$$CVIER1
Value error if reg too big
LR
4,2
Carry register number in R4
MVI $$CVIFlg-$$(13),0 Initialize flags
TM
8(14),X 0 3
Are there any exits?
JZ
$$CVISt1
If no, nothing more to do
MVC $$CVIFlg-$$(13),8(14) Copy byte with exit flag bits
NI
21(14),X 0 F
Reset ERR= branch mask to zero
NI
25(14),X 0 F
Reset STOP= branch mask to zero
.*State 1: scan for non-blank: +, -, or digit
$$CVISt1 XR
2,2
Initial state
TRT 0(1,3),$$CVITbl-$$(13) Scan one character
LA
3,1(,3)
Step to next char
LA
2,*+2-$$(2,13)
Address-4 of first branch
BR
2
Branch per character type
J
$$CVIErC
Invalid character; error exit
J
$$CVISt1
Blank; repeat initial-state scan
J
$$CVIP
Plus
J
$$CVIM
Minus
J
$$CVIS1A
Digit
$$CVIP OI
$$CVIFlg-$$(13),X C0 Sign found, + value
ST
3,$$CVIASt-$$(,13) Save digit starting address
J
$$CVISt2
Now scan for digits
$$CVIM OI
$$CVIFlg-$$(13),X A0 Sign found, - value
ST
3,$$CVIASt-$$(,13) Save digit starting address
J
$$CVISt2
Now scan for digits
$$CVIS1A OI
$$CVIFlg-$$(13),X C0 Set default + sign
LR
2,3
Copy pointer for digit start
BCTR 2,0
Back up to digit start address
ST
2,$$CVIASt-$$(,13) Save digit starting address
J
$$CVISt3
Now scan for more digits
.*State 2: have a sign; scan for required digit; non-digit -> error
$$CVISt2 XR
2,2
Clear GR2 for TRT
TRT 0(1,3),$$CVITbl-$$(13) Scan one character
LA
3,1(,3)
Step to next char
LA
2,*+2-$$(2,13)
Address-4 of first branch
BR
2
Branch per character type
J
$$CVIEr2
Invalid character
J
$$CVIEr2
Blank = invalid char
J
$$CVIEr2
+
= invalid char
J
$$CVIEr2
= invalid char
CLI 0(3),C 0
Is next char less than C 0 ?
JL
$$CVIS4C
If yes, scan is ended
CLI 0(3),C 9
Is it greater than C 9 ?
JH
$$CVIS4C
If yes, scan ended, R3=A(stop char)
.*State 3: only digits allowed; everything else terminates scan
$$CVISt3 XR
2,2
Clear GR2 for TRT
TRT 0(1,3),$$CVITbl-$$(13) Scan one character
LA
3,1(,3)
Step to next char
LA
2,*+2-$$(2,13)
Address-4 of first branch
BR
2
Branch per character type
J
$$CVIErC
Invalid char ends scan
J
$$CVISt4
Blank = non-digit char
J
$$CVISt4
+
= non-digit char
J
$$CVISt4
= non-digit char
J
$$CVISt3
Digit = repeat state 3

Appendix B: Simple I/O Macros

1017

.*State 4: remove leading 0s; save end addr, new start addr
$$CVISt4 BCTR 3,0
Back up to stop character
$$CVIS4C ST
3,$$CVIAEn-$$(,13) Save stop address for user s R1
LR
0,3
Copy end address
BCTR 0,0
Back up to last digit
L
2,$$CVIASt-$$(,13) Get starting address
$$CVIS4A CLI 0(2),C 0
Check for leading zero
JNE $$CVIS4B
Exit loop if nonzero
CR
2,0
Is the number entirely zeros?
JNL $$CVIS4B
Yes, have start of valid number
LA
2,1(,2)
Step to next digit
J
$$CVIS4A
Repeat the scan
$$CVIS4B ST
2,$$CVIASt-$$(,13) Save significance start address
LR
1,2
Save start addr in GR1 for packing
SR
0,2
Last-first = (Number-1) of digits
LR
2,0
Save L-1 for packing and moving
.*State 5: check reg type vs. length of digit string
CHI 2,18
More than 19 digits?
JH
$$CVIEr1
Error if so
CH
4,$$15-$$(,13)
Check for 32- bs 64-bit register
JH
$$CVISt6
Go process data for 64-bit reg
CHI 2,9
Check length of 32-bit data
JH
$$CVIEr1
Digit string too long, >10 digits
AHI 2,X0070
Include length 8 for the doubleword
STC 2,*+5-$$(,13)
Store L1,L2 in Pack instruction
PACK $$DWORD-$$(8,13),0(*-*,1) Pack up to 10 digits
CP
$$DWORD-$$(,13),$$CVIM32-$$(,13) Check vs. max 32
JL
$$CVIS5A
If smaller, go ahead and convert
JH
$$CVIEr1
Error if too big
TM
$$CVIFlg-$$(13),X C0 Equals max; is sign positive?
JO
$$CVIEr1
Error if +max
LA
0,1
Create max negative result
SLL 0,31
Have -2**31 in R0
J
$$CVIV32
Go store and test 32-bit value
$$CVIS5A CVB 0,$$DWORD-$$(,13) Convert to binary
TM
$$CVIFlg-$$(13),X A0 Was there a minus sign?
JNO $$CVIV32
Skip if +
LCR 0,0
Make the result negative
$$CVIV32 SLL 4,2
Make a word index from reg value
ST
0,$$REGS-$$(4,13) Store result in user s register
J
$$CVIRet
And return to caller
.*State 5: Convert to 64-bit register
$$CVISt6 XC
$$DWORD-$$(13),$$DWORD-$$(13) Clear high-order 8 bytes
STG 0,$$SAVG0-$$(,13) Save user s GG0
CH
2,$$15-$$(,13)
Check for 16 or more digits
JNL $$CVIS6B
Go do 16 to 19 digits
AHI 2,X0070
Simple case; set L1,L2 for pack
STC 2,*+5-$$(,13)
Set length fields
PACK $$DWORD+8-$$(,13),0(*-*,1) Pack 1-15 digits
CVBG 0,$$DWORD-$$(,13) Convert to 64-bit binary
TM
$$CVIFlg-$$(13),X 2 0 Was there a minus sign?
JNO $$CVIV64
If not, prepare to deliver result
LCGR 0,0
J
$$CVIV64
Go store result
$$CVIS6B LR
0,2
Copy length-1 for long number
AHI 0,-15
Length in R4 now 0-3 (16-19 digits)
LR
2,0
Save difference
AHI 0,X0030
Add in length for pack
STC 0,*+5-$$(,13)
Store L1,L2 in pack instructin
PACK $$XTemp-$$(*-*,13),0(*-*,1) Pack 1 to 4 digits
SRP $$XTemp-$$(13),1,0 Shift left once to eliminate sign
LA
1,1(1,2)
Address of remaining 15 digits
PACK $$DWORD+8-$$(,13),0(15,1) Pack remaining 15 digits
MVC $$DWORD+5-$$(3,13),$$XTemp-$$(13) Copy 1-4 digits
CP
$$DWORD-$$(16,13),$$CVIM64-$$(13) Check digit magnitude
JH
$$CVIEr1
Error if too large
JL
$$CVIS6C
If smaller, go ahead and convert
TM
$$CVIFlg-$$(13),X C0 Max magnitude: was there a - sign?
JO
$$CVIEr1
No, number too large by 1 bit
LA
0,1
Set up max negative value
SLLG 0,0,63
Now only a high-order bit in G0
J
$$CVIV64
Go store result
$$CVIS6C CVBG 0,$$DWORD-$$(,13) Convert to 64-bit binary
TM
$$CVIFlg-$$(13),X A0 Was there a minus sign?

1018

Assembler Language Programming for IBM z System Servers

Version 1.00

JNO $$CVIV64
No, store result
LCGR 0,0
Complement it
J
$$CVIV64
Go store result
$$CVIV64 LTR 4,4
Is the user s reg zero?
JNZ $$CVI64L
Jump if no, simpler case
ST
0,$$REGS-$$(,13) Store low (GR0) half of GG0
J
$$CVIRet
No more to do; high half is set
$$CVI64L LR
0,4
Copy register number
SLL 4,4
Move reg number left 4 bits
OR
4,0
Now have X rr in R4
STC 4,*+5-$$(,13)
Store in LMH instruction
LMH *-*,*-*,$$DWORD-$$(13) Load high half of user s Greg
LR
1,0
User s reg number now in R1
SLL 1,2
Make a word index from it
L
0,$$DWORD+4-$$(,13) Get low half of 64-bit result
ST
0,$$Regs-$$(1,13) Store low half in user s register
LG
0,$$SAVG0-$$(,13) Restore GG0
J
$$CVIRet
Return to caller
.*
.* $$CVIErr BCTR 3,0
Invalid value, R3=A(stop char)
$$CVIEr1 ST
3,$$CVIAEn-$$(,13) Store stop char address
TM
$$CVIFlg-$$(13),X01 Is there an ERR= operand?
JZ
$$CVIErN
If not, don t set its branch mask
OI
21(10),X F0
Set ERR= return branch mask to F
J
$$CVIRet
Return to caller s ERR= address
$$CVIErN MVC $$OUTBUF+1-$$(L $$CVIMN,13),$$CVIMN-$$(13)
JAS 7,$$OPNOUT
Make sure printer is opened
JAS 7,$$PUTLIN
Print the line
J
$$TERM1
And terminate
.*
$$CVIEr2 BCTR 3,0
Invalid char
$$CVIErC BCTR 3,0
Invalid data, R3=A(stop char)
ST
3,$$CVIAEn-$$(,13) Store stop char address
TM
$$CVIFlg-$$(13),X02 Is there a STOP= operand?
JZ
$$CVIErX
If not, don t set its branch mask
OI
25(10),X F0
Set ERR= return branch mask to F
J
$$CVIRet
Return to caller s STOP= address
$$CVIRet L
0,$$CVIAEn-$$(,13) Get address of stop character
ST
0,$$REGS-$$+4(,13) Store in GR1 slot
J
$$RETURN
Return to caller
$$CVIErX MVC $$OUTBUF+1-$$(L $$CVIMC,13),$$CVIMC-$$(13)
JAS 7,$$OPNOUT
Make sure printer is opened
JAS 7,$$PUTLIN
Print the line
J
$$TERM1
And terminate
.*------------------------------------------------------------------.* CONVERTO -- convert 32 or 64 bit signed integer to characters
.*------------------------------------------------------------------$$CVTO LH
2,12(,11)
Get register operand
JAS 7,$$EFAddr
Convert to effective address
LR
9,2
Save
CHI 2,47
Check value
JH
$$CVTX
Exit if too big, ignore the call
LH
2,14(,11)
Get storage address operand
JAS 7,$$EFAddr
Convert to effective address
CHI 9,15
Want a 4-byte GPR?
JH
$$CVTOD
No, want either GGR or FPR
NILL 9,X000F
Mask off unwanted bits
SLL 9,2
Make index for load
L
0,$$Regs-$$(9,13) Get the user s register
ST
0,$$RData-$$(,13) Store for conversion
JAS 7,$$CVT4
Convert to a character string
MVC 0(L $$Pat2,2),$$RCVT-$$(13) Move to caller s area
J
$$CVTX
And return
*
$$CVTOD CHI 9,31
Want an 8-byte GPR?
JH
$$CVTOF
No, must be a FPR
NILL 9,X000F
Mask off unwanted bits
SLL 9,4
Make a register number
STC 9,*+5-$$(,13)
Store in STG
STG *-*,$$RData-$$(,13) Store high half of user s GGR
SRL 9,2
Make a word index
L
0,$$Regs-$$(9,13) Get low half of user s register
ST
0,$$RData+4-$$(,13) Store low half for conversion
JAS 7,$$CVT8
Convert to characters

Appendix B: Simple I/O Macros

1019

MVC
J

0(L $$Pat3,2),$$RCVT-$$(13) Move to caller s area


$$CVTX
And return

*
$$CVTOF MVC 0(3,2),$$XQUOTE+1-$$(13) Initialize first 3 chars
NILL 9,X000F
Mask off unwanted bits
SLL 9,4
Make a register number
STC 9,*+5-$$(,13)
Store in STD
STD *-*,$$RData-$$(,13) Store user s FPR
UNPK 3(16,2),$$RData-$$(9,13) Convert to spread hex
UNPK 18(2,2),$$RData+7-$$(2,13) Convert to spread hex
TR
3(16,2),$$TRTAB-240-$$(13) Translate to EBCDIC
MVI 19(2),C
Insert closing quote
*
$$CVTX LA
11,16(,11)
Set return address
J
$$RETURN
Return to caller
.*------------------------------------------------------------------.* PRINTOUT/DUMPOUT HEADER LINE
.*------------------------------------------------------------------$$PODO MVC $$FLG2-$$(1,13),12(11) Copy No-header bit
TM
12(11),1
TEST NO-HEADER BIT
JO
$$NOHDR
SKIP HEADER IF SET
MVC $$OUTBUF+1-$$(L $$PC,13),$$PC-$$(13) HEADER MSG
CLI $$FLGS-$$(13),0
CHECK FOR PRINTOUT
JE
*+10
BRANCH IF PRINTOUT
MVC $$OUTBUF+5-$$(5,13),$$DC-$$(13) OVERLAY WITH DUMP
MVC $$DWORD-$$(3,13),13(11) MOVE CALL ADDRESS
JAS 7,$$HEXCV
CONVERT TO HEX
MVC $$OUTBUF+L $$PC+2-$$(6,13),$$DWORD-$$(13) TO LINE
LA
1,$$OUTBUF+L $$PC+2+6-$$(,13) Do statement number
MVC 0(L $$ST,1),$$ST-$$(13) Move text
LA
1,L $$ST(,1)
Step output pointer
L
0,16(,11)
Get statement number
CVD 0,$$DWORD-$$(,13) Convert to packed
MVC 0(L $$PAT4,1),$$PAT4-$$(13) Move pattern to line
ED
0(L $$PAT4,1),$$DWORD+5-$$(13) Edit statement number
LA
1,L $$PAT4(,1)
Step output pointer
MVC 0(L $$CC+1,1),$$CC-$$(13) Move CC value
.*
MVC $$OUTBUF+L $$PC+8-$$(L $$CC+1,13),$$CC-$$(13) CC VALUE
JAS 7,$$PUTLIN
PRINT CALLFROM MESSAGE
$$NOHDR CLI $$FLGS-$$(13),1
CHECK FOR DUMPOUT
JE
$$DUMP
GO PROCESS DUMP
.*------------------------------------------------------------------.* PRINTOUT -- First, CHECK IF NULL PARAMETER LIST
.*------------------------------------------------------------------TM
12(11),X F0
FLAGS IF NO PARAMS
LA
11,20(0,11)
ADDR NEXT PARM OR RET.
JO
$$RETURN
IF NO PARMS, RETURN
$$OUTLP MVC $$FLGS-$$(1,13),0(11) COPY PARM FLAGS
OC
0(2,11),0(11)
Check for null-last indicator
JNZ $$STAR
Not null-last, check for *
LA
11,2(,11)
Step over indicator
J
$$RETURN
And return to caller
$$STAR TM
$$FLGS-$$(13),8
SEE IF PRINTOUT *
JNO $$GETADD
BRANCH IF NOT PRTO *
TM
$$FLG2-$$(13),1
PRINTOUT * and no header?
JO
$$TERM
Yes, just terminate
MVC $$OUTBUF+2+L $$EX-$$(L $$PEND,13),$$PEND-$$(13)
J
$$TERM
AND GO TERMINATE
$$GETADD LH
2,2(,11)
ADDR HWORD PARAM.
JAS 7,$$EFADDR
COMPUTE EFFECTIVE ADDR
MVC $$OUTBUF+1-$$(L $$GPR,13),$$GPR-$$(13) GPR MSG
MVC $$OUTBUF+10-$$(L $$XQUOTE,13),$$XQUOTE-$$(13)
LA
0,X F
Mask for register digit
NR
0,2
Mask off all but 4 bits
CVD 0,$$DWORD-$$(,13) CONVERT REG NO TO DEC
MVC $$OUTBUF+4-$$(L $$PAT1,13),$$PAT1-$$(13) SET UP
ED
$$OUTBUF+4-$$(L $$PAT1,13),$$DWORD+6-$$(13) REGNO
CH
2,$$15-$$(,13)
SEE IF GPR
JH
$$TSTGGR
IF NOT, TO NEXT TEST
.* KNOW WE ARE TO PRINT CONTENTS OF a 32-bit GPR
SLL 2,2
Form word index
LA
2,$$REGS-$$(2,13) ADDRESS USERS REGISTER
MVC $$RDATA-$$(4,13),0(2) Copy user s register contents
*
ST
0,$$RDATA-$$(,13) Save value

1020

Assembler Language Programming for IBM z System Servers

Version 1.00

LA
9,3
LENGTH-1 OF DATA
JAS 7,$$PHEX
PRINT HEX
MVI 2(3),C =
Put = sign in output line
JAS 7,$$CVT4
Convert it
MVC 3(L $$PAT2,3),$$RCVT-$$(13) Move result to output
J
$$PNPUT
Output the line
$$TSTGGR CH
2,$$31-$$(,13)
SEE IF 64-bit GPR
JH
$$TSTFLT
IF NOT, TO NEXT TEST
.* Print contents of 64-bit General Register
MVI $$OUTBUF+2-$$(13),C G
Set msg to GGR
LA
0,X F
Set mask
NR
2,0
Clear high-order bits
SLL 2,4
Shift register number left
STC 2,*+5-$$(,13)
Store in next instruction
STG *-*,$$RDATA-$$(,13) Store GGRn high half
SRL 2,2
Reposition register number
LA
2,$$REGS-$$(2,13) Point to user s low half
MVC $$RDATA+4-$$(4,13),0(2) Move user s low order half
LA
2,$$RDATA-$$(,13) Data to convert
LA
9,7
Length-1
JAS 7,$$PHEX
PRINT HEX
MVI 2(3),C =
Put = sign in output line
JAS 7,$$CVT8
MVC 4(L $$PAT3,3),$$RCVT-$$(13) Move to output
J
$$PNPUT
Output the data
$$TSTFLT CH
2,$$47-$$(,13)
SEE IF FLPTR
JH
$$ISSYM
IF NOT IS SYMBOL
.* KNOW IS FLOATING PT REG
MVI $$OUTBUF+1-$$(13),C F
SET MSG TO FPR
SLL 2,4
PREPARE FOR STD
STC 2,*+5-$$(,13)
SELECT FLPTR
STD *-*,$$DWORD-$$(0,13) GET CONTENTS FLPTR
LA
2,$$DWORD-$$(,13) ADDR CONTENTS FOR PHEX
LA
9,7
LENGTH-1 OF DATA
JAS 7,$$PHEX
PRINT HEX
J
$$PNPUT
Output the data
$$ISSYM MVC $$OUTBUF+1-$$(8,13),4(11) SYMBOL NAME TO BUFF.
TM
$$FLGS-$$(13),64 SEE IF DECIMAL
JO
$$DEC
BRANCH IF DECIMAL
SR
9,9
PREPARE FOR IC
IC
9,1(,11)
GET LENGTH-1
TM
$$FLGS-$$(13),32 TEST FOR HEX
JNO $$SYM2
BRANCH IF NOT HEX
JAS 7,$$PHEX
Convert the data
J
$$PNPUT
Output the data
$$SYM2 DC
0H
MVI $$OUTBUF+12-$$(13),C C
SET FOR CHARACTERS
STC 9,*+5-$$(,13)
STORE LENGTH INTO MVC
MVC $$OUTBUF+14-$$(*-*,13),0(2) MOVE CHARACTER DATA
LA
3,$$OUTBUF+15-$$(9,13) Address of trailing quote
MVI 0(3),C
Put trailing quote
J
$$PNPUT
Output the data
.* DECIMAL FULLWORD OR HALFWORD
$$DEC
CLI 1(11),7
Check for FD data type
JE
$$DECD
Branch if yes, do long conversion
LH
3,0(0,2)
GET HALFWORD
TM
$$FLGS-$$(13),1
SEE IF WANTED FULLWORD
JNO *+8
IF NOT DON T LOAD IT
L
3,0(,2)
REALLY WANTED FULLWORD
ST
3,$$RDATA-$$(,13) Store for conversion
JAS 7,$$CVT4
Convert to characters
MVC $$OutBuf+11-$$(L $$Pat2,13),$$RCVT-$$(13)
J
$$PNPUT
PRINT LINE
$$DECD MVC $$RDATA-$$(8,13),0(2) Get the doubleword
JAS 7,$$CVT8
Convert to characters
MVC $$OutBuf+12-$$(L $$Pat3,13),$$RCVT-$$(13)
$$PNPUT LA
11,12(,11)
POINT TO NEXT PARAMETER
$$PUT
JAS 7,$$PUTLIN
PRINT LINE
TM
$$FLGS-$$(13),128 SEE IF LAST PARAMETER
JNO $$OUTLP
LOOP IF NOT
$$RETURN STM 10,11,$$REGS+56-$$(13) STORE PARM,RETURN ADDRS.
SPM 10
RESET CALLER S COND CODE
LM
0,15,$$REGS-$$(13) RESTORE REGS
.* At this point all but R14 & R15 of user are restored;

Appendix B: Simple I/O Macros

1021

.* R14 contains addr of parm list following the BALR, and


.* R15 contains return addr.
BR
15
RETURN TO USER
.*------------------------------------------------------------------.* DUMPOUT
.*------------------------------------------------------------------$$DUMP LH
2,22(,11)
GET SECOND OPERAND
JAS 7,$$EFADDR
SECOND EFFECTIVE ADDRESS
LR
9,2
SAVE FOR A WHILE
LH
2,20(,11)
GET FIRST OPERAND
JAS 7,$$EFADDR
FIRST EFFECTIVE ADDRESS
LA
11,24(,11)
SET RETURN ADDRESS NOW
CR
2,9
COMPARE START TO END
JNH *+10
SKIP SWAP IF OKAY
LR
0,9
SWAP HIGH AND LOW BOUNDS
LR
9,2
2 HAS LOWER BOUND
LR
2,0
AND R9 HAS UPPER BOUND
LA
8,4
SET INCREMENT
LCR 1,8
COMPLEMENT FOR MASKING
NR
2,1
FORCE TO WORD BOUNDARY
$$DUMPA ST
2,$$DWORD-$$(,13) STORE LINE-START ADDRESS
JAS 7,$$HEXCV
CONVERT TO HEX
MVC $$OUTBUF+1-$$(6,13),$$DWORD+2-$$(13) TO LINE
LA
1,$$OUTBUF+9-$$(,13)
SET LINE POINTER
MVI $$OUTBUF+82-$$(13),C * SET LEFT ASTERISK
MVC $$OUTBUF+83-$$(32,13),0(2) MOVE EBCDIC CHARS
TR
$$OUTBUF+83-$$(32,13),$$DUMPTB-$$(13) XLATE
MVI $$OUTBUF+115-$$(13),C * SET RIGHT ASTERISK
LA
0,8
SET INNER LOOP COUNT
$$DUMPB MVC $$DWORD-$$(4,13),0(2) GET A WORD FROM CALLER
JAS 7,$$HEXCV
CONVERT TO HEX
MVC 0(8,1),$$DWORD-$$(13) TO PRINT LINE
AR
2,8
INCREMENT FETCH ADDRESS
LA
1,9(,1)
AND LINE POINTER
JCT 0,$$DUMPB
LOOP TILL LINE DONE
JAS 7,$$PUTLIN
PRINT THE LINE
CR
2,9
COMPARE LOWER TO UPPER
JNH $$DUMPA
GO WORK ON NEXT LINE
J
$$RETURN
.*------------------------------------------------------------------.* PRINTLIN
.*------------------------------------------------------------------$$LINP LH
2,14(0,11)
ADDR. HWORD USER BUFFER
JAS 7,$$EFADDR
CALC. LINE LENGTH
LA
4,&$$PLL
MAX LINE SIZE
LTR 3,0
SEE IF CALC LENGTH ZERO
JZ
*+10
IF ZERO USE LEN=MAX
CR
3,4
SEE IF LEN GT MAX
JNH *+6
IF NOT USE LEN
LR
3,4
USE LEN=MAX
LH
2,12(,11)
ADDR HWORD. USER BUFFER
JAS 7,$$EFADDR
CALC. EFFECT. ADDR.
BCTR 3,0
LENGTH -1 FOR MVC
STC 3,*+5-$$(,13)
STORE LENGTH INTO MVC
MVC $$OUTBUF-$$(0,13),0(2) MOVE USER LINE TO BUFF
MVI $$FLGS-$$(13),128 MARK AS LAST PARAM
LA
11,16(,11)
RETURN ADDR
AIF (NOT &$$DOS).GOPUT SKIP ASA CODE IF NOT DOS
LA
2,L $$ASA
GET LENGTH OF CHARACTERS
SR
0,0
USED FOR USER S CONTROL
SR
1,1
FOR VALID CHARACTERS
IC
0,$$OUTBUF-$$(,13) GET USER S CONTROL CHAR
IC
1,$$ASA-1-$$(2,13) GET A VALID ASA CHAR
CR
1,0
COMPARE IT TO USER S
JE
$$PUT
GO PRINT IF OKAY
JCT 2,*-10
INDEX DOWN BY 1 IF BAD
MVI $$OUTBUF-$$(13),C
FORCE BLANK IF BAD
.GOPUT J
$$PUT
PRINT LINE AND RETURN
.*------------------------------------------------------------------.* READCARD
.*------------------------------------------------------------------$$OPNRD TM
$$FLGSIO-$$(13),X 4 0
SEE IF INPUT FILE OPEN
JO
$$INOPN
IF SO DON T OPEN AGAIN
AIF (&$$DOS).OPENRD
GO TO DOS OPEN CODE

1022

Assembler Language Programming for IBM z System Servers

Version 1.00

OPEN ($$INDCB,(INPUT)) OPEN INPUT FILE


LA
1,$$RDOPEN-$$(,13) ADDR OF OPEN LIST
OPEN MF=(E,(1))
OPEN INPUT FILE
AGO .MARKRD
GO SET INPUT OPEN BIT
.OPENRD ANOP
*
OPEN $$INDCB
DOS OPEN MACRO
LA
1,$$OPEN-$$(,13) ADDR OF OPEN NAME
LA
0,$$ADDRI-$$(,13) ADDR OF INPUT DTF
SVC 2
DOS OPEN/CLOSE SVC
.MARKRD OI
$$FLGSIO-$$(13),X 4 0
INDICATE FILE OPENED
$$INOPN LA
11,18(,11)
DETERMINE RETURN ADDR.
TM
$$FLGSIO-$$(13),X 2 0
SEE IF EOF ENCOUNTERED
JO
$$EOFERR
IF SO ERROR
LH
2,16(,10)
ADDR. HWORD DATA AREA
JAS 7,$$EFADDR
CALC. EFFECTIVE ADDR.
*
GET $$INDCB,(0)
GET NEW CARD IMAGE
LA
1,$$INDCB-$$(,13) ADDRESS OF INPUT DCB
GET (1),(0)
GET NEW CARD IMAGE
J
$$RETURN
RETURN TO CALLER
$$EOF
TM
8(10),X 8 0
SEE IF CALLER EOF EXIT
JNO $$EOFERR
IF NONE, ERROR
OI
$$FLGSIO-$$(13),X 2 0
MARK EOF FLAG
OI
5(11),X F0
CH USER BC 0 TO BC 15
J
$$RETURN
RETURN TO CALLER
$$EOFERR MVC $$OUTBUF+2+L $$EX-$$(L $$REOF,13),$$REOF-$$(13)
.*------------------------------------------------------------------.* TERMINATE
.*------------------------------------------------------------------$$TERM TM
$$FLG2-$$(13),1
Check for no message
JO
$$TERM1
Branch if none
MVC $$OUTBUF+1-$$(L $$EX,13),$$EX-$$(13) FINIS MSG
MVC $$OUTBUF+$$LOCP-$$(L $$ATLOC,13),$$ATLOC-$$(13)
MVC $$DWORD-$$(3,13),$$ACALL-$$(13) Get call address
JAS 7,$$HEXCV
Convert to hex characters
MVC $$OUTBUF+1+$$LOCP+L $$ATLOC-$$(6,13),$$DWORD-$$(13)
JAS 7,$$PUTLIN
PRINT MESSAGE
AIF (&$$DOS).CLOSP
GO TO DOS CLOSE CODE
*
CLOSE ($$OUDCB)
CLOSE OUTPUT FILE
$$TERM1 LA
1,$$PRCLOS-$$(,13) ADDR OF CLOSE LIST
CLOSE MF=(E,(1))
CLOSE OUTPUT FILE
AGO .CHKCLSR
GO TEST INPUT CLOSE
.CLOSP ANOP
*
CLOSE $$OUDCB
CLOSE OUTPUT FILE
$$TERM1 LA
1,$$CLOSE-$$(,13) SET ADDR OF ROUTINE NAME
LA
0,$$ADDRO-$$(,13) ADDR OF OUTPUT DTF
SVC 2
DOS OPEN/CLOSE SVC
.CHKCLSR TM
$$FLGSIO-$$(13),X 4 0
CHECK IF INPUT FILE OPEN
JNO $$TERM2
IF NOT DON T CLOSE
AIF (&$$DOS).CLOSR
GO TO DOS CLOSE CODE
*
CLOSE ($$INDCB)
CLOSE INPUT FILE
LA
1,$$RDCLOS-$$(,13) ADDR OF CLOSE LIST
CLOSE MF=(E,(1))
CLOSE INPUT FILE
AGO .TERM
GO TO TERMINATE CODE
.CLOSR ANOP
*
CLOSE $$INDCB
DOS CLOSE MACRO
LA
1,$$CLOSE-$$(,13) ADDR OF CLOSE NAME
LA
0,$$ADDRI-$$(,13) ADDR OF INPUT DTF
SVC 2
DOS OPEN/CLOSE SVC
.TERM
ANOP
$$TERM2 MVI $$FLGSIO-$$(13),0 CLEAR IO FLAGS
AIF (&$$DOS).EOJ
SKIP TO DOS EXIT
SR
15,15
SET OS RETURN CODE TO 0
SVC 3
OS EXIT MACRO
AGO .PUTL
AND GO ON WITH CODE
.EOJ
EOJ
.PUTL
ANOP
.*------------------------------------------------------------------.* INTERNAL SUBROUTINES
.*------------------------------------------------------------------.* Length-1 is in R9, source address is in R2, target address in R3.
$$PHEX LA
3,$$OUTBUF+14-$$(,13) ADDRESS FOR HEX DIGIT
LA
8,1(0,9)
NUMBER OF BYTES
AR
9,8
NUMBER OF HEX DIGITS -1
UNPK 0(3,3),0(2,2)
SPREAD HEX DIGITS

Appendix B: Simple I/O Macros

1023

.*
$$CVT4

.*
$$CVT8

LA
LA
JCT
STC
TR
LA
MVI
BR

3,2(,3)
INC. LINE POINTER
2,1(,2)
INCREMENT SOURCE PTR
8,*-14
LOOP IF MORE BYTES
9,*+5-$$(,13)
STORE LENGTH INTO TR
$$OUTBUF+14-$$(*-*,13),$$TRTAB-240-$$(13)
3,$$OUTBUF+15-$$(9,13) ADDR. NEXT PRINT POS.
0(3),C
CLOSING QUOTE MARK
7
Return to caller

L
CVD
MVC
LA
EDMK
BNMR
BCTR
MVI
BR

0,$$RDATA-$$(,13) Get 32-bit binary integer


0,$$DWORD-$$(,13) Convert to packed decimal
$$RCVT-$$(L $$PAT2,13),$$PAT2-$$(13) move pattern
1,$$RCVT+L $$PAT2-1-$$(,13) Possible sign position
$$RCVT-$$(L $$PAT2,13),$$DWORD+2-$$(13) Edit it
7
Return if not 1,0
Back up
0(1),C -
Set - sign
7
Return

STG
LG
CVDG
LG
MVC
LA
EDMK
BNMR
BCTR
MVI
BR

0,$$SAVG0-$$(,13) Save GGR0 (changed by CVDG)


0,$$RDATA-$$(,13) Get 64-bit binary integer
0,$$DWORD-$$(,13) Convert to packed decimal
0,$$SAVG0-$$(,13) Restore user s GGR0 (used by CVDG)
$$RCVT-$$(L $$PAT3,13),$$PAT3-$$(13) move pattern
1,$$RCVT+L $$PAT3-1-$$(,13) Possible sign position
$$RCVT-$$(L $$PAT3,13),$$DWORD+6-$$(13) Edit it
7
Return if not 1,0
Back up
0(1),C -
Set - sign
7
Return

.*
$$EFADDR LA
0,X FFF
DISPLACEMENT MASK
NR
0,2
DISPLACEMENT IN R0
N
2,$$F000-$$(,13) CALC WHICH BASE REG.
JZ
*+16
RETURN IF BASE = 0
SRL 2,10
BASE REG NO. AS INDEX
AL
0,$$REGS-$$(2,13) FORM EFFECTIVE ADDR.
N
0,$$FFF-$$(,13)
MASK OFF HIGH-ORDER BYTE
LR
2,0
RESULT IN R2 ALSO
BR
7
RETURN
.*
$$OPNOUT TM
$$FLGSIO-$$(13),X 8 0
IS OUTPUT FILE OPEN
BCR 7,7
RETURN NOW IF YES
OI
$$FLGSIO-$$(13),X 8 0
OUTPUT FILE BEING OPENED
AIF (&$$DOS).OPENP
DIFFERENT CODE FOR DOS
*
OPEN ($$OUDCB,(OUTPUT)) OPEN OUTPUT FILE
LA
1,$$PROPEN-$$(,13) ADDR OF OPEN LIST
OPEN MF=(E,(1))
OPEN OUTPUT FILE
AGO .CLEAR
GO FINISH OPEN
.OPENP ANOP
*
OPEN $$OUDCB
DOS OPEN MACRO
LA
1,$$OPEN-$$(,13) ADDRESS OF ROUTINE NAME
LA
0,$$ADDRO-$$(,13) ADDRESS OF DTF POINTER
SVC 2
DOS OPEN/CLOSE SVC
.CLEAR BR
7
RETURN TO CALLER
.*
$$PUTLIN LA
1,$$OUDCB-$$(,13) ADDRESS OF OUTPUT DCB
LA
0,$$OUTBUF-$$(,13) ADDRESS OF OUTPUT BUFFER
PUT (1),(0)
PRINT THE LINE
MVC $$OUTBUF-$$(&$$PLL,13),$$OUTBUF-$$-1(13) CLEAR
BR
7
RETURN TO CALLER
$$HEXCV UNPK $$DWORD-$$(9,13),$$DWORD-$$(5,13) UNPACK 4 BYTES
TR
$$DWORD-$$(8,13),$$TRTAB-240-$$(13) TO EBCDIC
BR
7
RETURN TO CALLER
.*------------------------------------------------------------------AIF (&SYSSTYP eq ) . NoSect
&$$CSnam &$$CSTyp
RESTORE ORIGINAL SECTION
.NoSect Pop Print
Restore PRINT status
MEnd ,
End of $$GENIO macro

1024

Assembler Language Programming for IBM z System Servers

Version 1.00

Glossary of Terms and Abbreviations


GGGGGGGGGG
GGGGGGGGGGGG
GG
GG
GG
GG
GG
GG
GGGGG
GG
GGGGG
GG
GG
GG
GG
GGGGGGGGGGGG
GGGGGGGGGG

LL
LL
LL
LL
LL
LL
LL
LL
LL
LL
LLLLLLLLLLLL
LLLLLLLLLLLL
adcon
Abbreviation for address constant.

Special Characters

addend
see augend

(1) Multiplication operator (2) Location Counter


Reference.

addr(x)
Address of some operand x.

Addition operator.

Subtraction operator.

Division operator.

address
(1) (n) A number used by the processor at execution
time to locate and reference operands or instructions
in memory. Here, an address is what reference
manuals (such as the Principles of Operation) would
call a virtual address. Sometimes used (incorrectly)
to mean an assembly time location. (2) (v) To reference; to provide an address (sense no. 1) that may be
used to reference an item in storage.

( ) (1) Address constant delimiters.


(2) Expression grouping delimiters.
=

(1) Literal-constant indicator.


(2) Indicator of a keyword argument argument or
parameter in a macro.

Indicator of a blank space.

Apostrophe. (1) Character string delimiter.


(2) Attribute reference operator.

Alphabetic character in symbols.

Alphabetic character in symbols; not invariant


across all EBCDIC code pages.

Alphabetic character in symbols; not invariant


across all EBCDIC code pages.

Alphabetic character in symbols; not invariant


across all EBCDIC code pages.

&

Ampersand; indicates the start of a variable


symbol.

(1) Qualified-symbol separator between qualifier


and symbol. (2) Concatenation operator in conditional assembly SETC expressions.

A
absolute symbol
A symbol whose value behaves in expressions like a
self-defining term. Its value does not change if the
assumed origin of the program changes.
ACONTROL
Assembler instruction statement allowing dynamic
modification of some Assembler options.

address constant (adcon)


A field within a control section into which a value
(typically, an address) is placed during assembly,
program binding, relocation, and/or loading.
address resolution
The process whereby the Assembler converts implied
addresses into base-displacement form using information in its USING Table, or resolves offsets in
relative-immediate instructions.
address table
A table of addresses of individual rows or columns of
an array, allowing faster access to the elements of
that row or column.
address translation (Dynamic Address Translation,
DAT)
The procedure used by the CPU to convert virtual
addresses into real addresses.
addressable
(1) At assembly time an implied address is addressable if it can be validly resolved by the Assembler
into a base-displacement address, using information
contained in the USING Table at the time of the
resolution, or the Assembler can assign a valid offset
to a relative-immediate isntruction. (2) At execution
time an operand is addressable if it lies either in the
bytes starting at address zero, or is within the basedisplacement resolution range of one of general
purpose registers 1 through 15, or can be referenced
by a relative-immediate instruction.

Glossary of Terms and Abbreviations

1025

addressability
The ability of the Assembler to calculate a displacement and assign a base register to an implicit
addressing expression, using information in the
USING Table; or the ability of the Assembler to
assign a valid offset for a relative-immediate reference.
addressability error
(1) Inability of the Assembler to derive a valid
addressing field for an implicit operand. (2) An
execution-time interruption for attempting to reference a non-existent address.
addressing halfword
A halfword containing a base register specification
digit in the first 4 bits, and an unsigned displacement
in the remaining 12 bits. A key element of z System
addressing.
addressing mode
One of three modes supported by z System that
determines the length of an Effective Address and the
addressable areas of memory.
algorithm
A finite sequence of well-defined steps for solving a
problem. 304
AMode
An abbreviation for addressing mode.
anchor
(1) The base location or base register specified in the
second operand of a USING statement. (2) The base
location in a Dependent or Labeled Dependent
USING statement. (3) The starting point of a
chained list or queue.
AND operation
A logical (boolean) operation between two bits,
whose result is 1 only if both operand bits are 1.
architecture
A description of the attributes of a system as seen by
the programmer, i.e., the conceptual structure and
functional behavior, as distinct from the organization
of the data flow and controls, and the physical
implementation. 305
argument
A value supplied by a calling program.
arithmetic division
Division of two signed operands, generating a signed
quotient and signed remainder.
arithmetic multiplication
Multiplication of two signed operands, generating a
signed product.

array
A collection of data items of the same data types and
lengths, arranged in contiguous storage locations.
Usually accessed using one or more index variables
or subscripts. (See also table.)
ASCII
American Standard Code for Information Interchange.
ASCII numeric characters
ASCII characters with representations between X 30
and X 39 .
Assembler
A program that translates programs written in
Assembler Language to machine language
instructions and data, producing an object module.
Assembler Language
A lower-level language allowing programmers
maximum freedom in specifying processor
instructions, providing powerful macro-instruction
facilities supporting encapsulation and economy of
expression.
assembly time
The time when the Assembler is processing a programs statements, as distinct from the time when the
machine language instructions created from an
Assembler Language program are executed by the
processor.
attribute
A property of a symbol known to the assembler, typically the characteristics of the item named by the
symbol, such as its type, length, etc. A program may
request the assembler to provide values of symbol
attributes using attribute references.
A variable symbol may have one attribute specific to
the symbol itself (e.g. its number attribute), and many
attributes specific to the value of the variable symbol.
attribute reference
A notation used to request the value of a symbol
attribute from the assemblers symbol table, or of a
variable symbol or its value.
augend
When two numbers are added, the number being
augmented (the first operand) is the augend, to which
the addend (the second operand) is added.

arithmetic representation
A signed number representation.

B n , bn
Base register specification digit for machine instruction operand n.

arithmetic shift
A movement of bits in a general register to the left or
right, preserving the arithmetic sign of the operand.

B-tree
A tree whose nodes contain one or more data elements, and two or more links to successor nodes.

304

305

After al Khwarizmi, a nickname of the 9th century Persian astronomer and mathematician Abu Jafar Muhammad ibn Musa, who
authored many books on arithmetic and algebra. He worked in Baghdad and his nickname alludes to his place of origin, Khwarizm
(Khiva), in present-day Uzbekistan and Turkmenistan.
G.M. Amdahl, G.A. Blaauw, and F.P. Brooks, Jr. Architecture of the IBM System/360, IBM Journal of Research and Development Vol. 8 No. 2, 1964, reprinted in IBM Journal of Research and Development Vol. 44 No. 1/2, January/March 2000.

1026

Assembler Language Programming for IBM z System Servers

Version 1.00

base address
The address in one of general purpose registers 1 to
15 to which a displacement is added to obtain an
effective address. (2) The execution-time contents of
a base register.
base digit
See base register specification digit.
base-displacement addressing
A technique for addressing memory using a compact
base-displacement format for representing the derivation of storage addresses.
base location
(1) In base-displacement address resolution, the first
operand of a USING statement, from which displacements are to be calculated. For ordinary USING
statements, the base location is assumed to be at a
relative offset (displacement) of zero from the address
contained in the base register; for dependent USING
statements, the base location may be at a positive or
negative offset from the location specified in the base
register eventually used to resolve an implied address.
(2) Informally, this term is sometimes used to mean
(a) the origin of a control section, (b) a base address
in a register at execution time, and (c) whatever the
speaker likes.
base register
(1) The second (and subsequent) operand(s) of a
USING instruction. (2) A general register used at
execution time to form an Effective Address.
base register specification digit
The first 4 bits of a 16- or 20-bit addressing field.
BEAR
The Breaking Event Address Register.
bias
A fixed value added to the exponent of a floatingpoint number so that its exponent field always contains a nonnegative value, the characteristic.

boundary alignment
(1) The Assemblers action in incrementing the
Location Counter so that its value is adjusted to the
boundary required by an instruction or by a constant
operand. (2) The binders action in ensuring proper
alighment of the components of a load module or
program object. (3) The Program Loaders action in
ensuring that memory alignment of the components
of a loaded program are correct. (4) The alignment
of the starting address of storage acquired at execution time.
branch address
The address from which the next instruction will be
fetched if a branch condition is met.
branch condition
The CPUs decision whether to alter the normal
sequential execution of instructions by fetching
instructions at the branch address.
branch mask
A 4-bit field in a Branch on Condition instruction
used to test the value of the Condition Code. If a
1-bit in the branch mask matches the CC value, the
branch condition is met.
byte
A group of 8 bits; the basic addressable unit of
memory.

C
C(x)
Contents of something named x.
CC
Condition Code, a 2-bit field in the PSW used to indicate the status or result of executing certain
instructions.

binary floating-point
A floating-point representation having a binary
significand.

calling point identifier


A NOP instruction with a halfword identifying
number in place of its addressing halfword, of the
form X4700nnnn .

binary search
A technique for searching ordered arrays by probing
the midpoint of successively smaller portions of the
array.

characteristic
The true exponent of a floating-point number plus the
bias.

binary tree
A data structure in which each element contains links
to two other elements, a left subtree or left child,
and a right subtree or right child.
bind time
A time following assembly time during which one or
more object modules are combined to form an executable module, ready for loading into memory at
execution time. Also known as link time.

class
A cross-section of Program Object data with uniform
format, content, and behavioral attributes.
code
An informal term for groups of Assembler Language
statements.
code page
A collection of characters and their associated binary
encodings.

Binder
The z/OS program that can generate load modules
and program objects, as well as place a just-linked
program directly into memory.

cohort
In a given format, a set of decimal floating-point
numbers having the same numeric value but different
quanta.

bit

column order
A way to store arrays so that the elements of each
column follow one another in memory. For arrays of
two or more dimensions, subscripts cycle most
rapidly from left to right.

A binary digit, taking values 0 and 1.


blank
A nonempty, finite-width invisible character; a space.
In contexts where explicit blank spaces appear, we
sometimes use the character.

Glossary of Terms and Abbreviations

1027

column-major order
Same as column order.

External Sections (PseudoRegisters) in the complete


program.

COM
An assembler instruction statement declaring the start
or resumption of a common section.

common section
A control section having length and alignment attributes (but no text). Common sections receive special
treatment during program linking: space is allocated
for the greatest length received for all common
sections with a given name.
comparand
(1) A quantity whose value is being compared. (2) A
quantity to which the incremented index is compared
to determine whether a loop should be repeated.
complement decimal addition
The addition of packed decimal operands of unlike
sign.
complex relocatability
A property of a symbol or expression whose relocation attribute is neither absolute or simply relocatable.
conditional assembly
A form of assembly whose input is a mixture of conditional assembly language and ordinary assembly
language statements, and whose outputs are statements of the ordinary assembly language. Statements
of the ordinary assembly language are treated as character strings, and are not obeyed during conditional
assembly.
conditional no-operation
An Assembler CNOP instruction that may generate
NOP and NOPR instructions, causing the Location
Counter to be aligned on a specified even boundary.

D n , dn
Displacement specification for machine instruction
operand n.
Data Exception Code
A field in the FPCR indicating which of various
floating-point or packed decimal exceptions may have
occurred.
DBCS
Double Byte Character Set, in which characters are
represented by two bytes.
decimal exponent
A letter E attached at the end of a numeric constant,
followed by a positive or negative integer giving the
power of ten by which the preceding nominal value is
multiplied.
decimal data exception
An exception condition caused by invalid numeric or
sign digits in a packed decimal operand, or by invalid
operand lengths for a packed decimal product.
decimal divide exception
An exception condition caused by a packed decimal
quotient being too large for the available space in the
first operand field, or by division by zero.
decimal floating-point
A floating-point representation having a decimal
significand.

constant type
A letter specifying the desired internal data representation for a generated constant.

decimal overflow exception


An exception condition caused by a packed decimal
sum or difference being too large for the receiving
first operand field.

control section
An indivisible unit of instructions, data, or uninitialized space that is not further subdivided during
linking and loading.

decimal specification exception


An exception condition caused by a packed decimal
multiplication or division specifying incorrect lengths
for one or both operands.

The smallest independently relocatable unit of


instructions and/or data. All elements of a given
control section maintain the same fixed relative positions to one another at assembly time. These fixed
relative positions at assembly time are maintained by
the program after control sections are placed into
storage at execution time.
CPU
Central Processing Unit
CSECT
(1) An assembler instruction statement indicating the
start or continuation of a control section. (2) An
informal term for a control section
C-string
A string of zero or more bytes ending with a zero or
null byte.
Cx
Characteristic part of a floating-point number x
CXD-type address constant
A word holding the length (not the address) of the
virtual area created at link time from all the Dummy

1028

declet
A 10-bit encoding of three Binary Coded Decimal
(BCD) digits. Declets may have two forms: (1)
canonical: 1,000 preferred (and generated) values,
and (2) non-canonical: any of 24 non-preferred
encodings accepted as operands, but not generated by
any arithmetic operation.
decode
The CPU action of analyzing the contents of the
instruction register to determine the validity and type
of instruction.
defined symbol
A symbol is defined when the Assembler assigns
values to its value, relocation, and length attributes.
denormalization
A process of shifting the fraction of a floating-point
number to the right by enough digit positions so its
exponent will lie in a desired representable range.
denormalized number
(1) A floating-point number with denormalized
significand. (2) A nonzero binary floating-point value
with characteristic zero and a nonzero fraction.

Assembler Language Programming for IBM z System Servers

Version 1.00

dependent USING
A USING statement allowing implicit references to
symbols in areas mapped by more than one DSECT
to be resolved with a single base register, in which the
first operand is based or anchored at a relocatable
address. May also take the form of a labeled
dependent USING statement. See also anchor,
labeled USING, and ordinary USING.
destructive overlap
Destructive overlap occurs when any part of a target
operand field is used for a source after data has been
moved into it.
DH
In an instruction supporting signed 20-bit displacements, the 5th byte of the instruction containing the
signed High-order 8 bits of the displacement.
digit selector
One of two pattern characters: a Digit Selector (DS)
having representation X 20 , or a Digit Selector and
Significance Starter (SS) having representation X 21 .
diminished radix-complement representation
A signed representation where the complement of a
number is represented by subtracting each digit from
(the radix minus 1). (See twos complement representation.)
displacement
(1) The unsigned 12-bit integer field of an addressing
halfword, or a signed 20-bit integer field, both used in
generating Effective Addresses. (2) Sometimes used
to describe the offset (difference) between a given
storage address and a base address that might be
used to address it.
dividend
A number to be divided by a divisor; the first
operand; the numerator.
divisor
A number to be divided into a dividend; the second
operand; the denominator.
DL
In an instruction supporting signed 20-bit displacements, the unsigned low-order 12 bits of the displacement.
double-ended queue
Same as queue. Sometimes called a dequeue.
doubly-linked list
Same as queue. Sometimes called a doublethreaded list.
DPD
Densely Packed Decimal, a representation used for
encoding decimal floating-point significands.
DROP instruction
An assembler instruction telling the Assembler to
eliminate one or more entries from its USING Table.
DSECT
(1) An assembler instruction defining the start or continuation of a Dummy Control Section. (2) A
Dummy Control Section, a template used to map the
components of a data structure. (3) An informal
name for a Dummy Control Section.
duplication factor
The number of times a constant operand should be
assembled.

DXC
Data Exception Code, a field in the Floating-Point
Control Register (FPCR).
DXD
An assembler instruction statement defining an
External Dummy Section.

E
EAR (Effective Address Register)
A (conceptual) internal register used to calculate
Effective Addresses.
EBCDIC
Extended Binary Code Decimal Interchange Code,
used to assign numeric values to character representations. The many EBCDIC encodings assign different values to some characters, but all the
alphabetic, numeric, and other syntactic characters
used in the Assembler Language are invariant across
EBCDIC encodings, except for the characters $,
@, and #.
Effective Address
The address calculated at execution time from a 16or 20-bit addressing field of an instruction, possibly
with indexing, or the address calculated from a
relative-immediate offset and the address of its
instruction.
Encoded Length
The contents L n of a Length Specification Byte or
digit; one less than the value of the Length
Expression N n (unless the Length Expression is zero,
in which case the Encoded Length is also zero).
entry point
The first instruction to receive control when a routine
is invoked.
entry point identifier
A string of characters following the first instruction at
an entry point, providing descriptive information
about the entry.
EQU Extended Syntax
Additional operands on EQU instructions that
provide additional information about the attributes of
the symbol defined by the EQU statement.
ESD
External Symbol Dictionary.
Ex
Exponent part of a floating-point number x
exception condition
A condition indicating an unusual result. Some
exceptions can deliver a default result if an interruption has been masked off by appropriate settings,
while others always cause an interruption.
executable control section
A control section containing machine language
instructions or data, defined by CSECT, RSECT, or
START instructions.
execute
The CPUs action of performing the operation
requested by the instruction in the instruction register.

Glossary of Terms and Abbreviations

1029

execution time
The time when your program has been put in
memory by the Program Loader and given control.
This may happen long after assembly time.306
explicit address
An address in which you specify the base register
specification digit and the displacement as absolute
expressions.
explicit length
(1) A length value specified in a DC or DS statement.
(2) A length field that you specify explicitly, rather
than having the Assembler assign the length field
from the Length Attribute of an operand.
exponent
The power of the radix by which the significand of a
floating-point number must be multiplied to determine its value.
exponent modifier
A modifier specifying a positive or negative power of
ten to be multiplied by the nominal value of a constant.
exponent overflow
A condition arising when the exponent of a calculated
floating-point result is too large to be contained in its
representation.
exponent underflow
A condition arising when the exponent of a calculated
floating-point result is too small to be contained in its
representation.
expression
A combination of terms and operators to be evaluated by the Assembler.
expression evaluation
The procedure used by the Assembler to determine
the value of an expression.
extended mnemonic
An instruction mnemonic provided by the Assembler
allowing you to specify a branch mask or other
instruction fields implicitly.
External Dummy Section
An area having length and alignment defined at
assembly time in a DXD statement that will be
assigned at link/bind time to a PseudoRegister Vector
and for which memory is allocated at execution time.
external symbol
A symbol whose name (and possibly, value) are a
part of the object module text provided by the
Assembler. Such names include (1) control section
names, (2) strong external names declared in V-type
address constants or EXTRN statements, (3) weak
external names declared in WXTRN statements, (3)
names of common sections, (4) names of Pseudo Registers or external dummy sections, (5) referenced
names declared on ENTRY statements, (6) class
names, and (7) symbols and character strings
renamed through the use of the ALIAS statement.
Compare to internal symbol.

encoded in the ESD records of the generated object


module.
extreme exponent
A floating-point numbers exponent with maximum
positive or negative value.

F
fetch
The CPUs action of bringing halfwords from
memory into the conceptual Instruction Register to
be interpreted as an instruction.
field separator
An edit-pattern character (FS) indicating that a
packed decimal value from the second operand has
been edited, and editing should continue with the following packed decimal value.
fill character
The first byte of an edit pattern.
firmware
A popular term referring to microcode or millicode.
floating-point
A data representation with a sign, an exponent, and a
set of significant digits.
Floating-Point Control Register (FPCR)
A special register containing IEEE masks, status indicators, Data Exception Code, and rounding mode.
floating-point exception condition
One of five conditions defined by the IEEE FloatingPoint Standard: invalid operation, division by zero,
exponent overflow, exponent underflow, and inexact
result.
floating-point system FP(r,p)
A floating-point data representation with a specified
radix r and number of significant digits p, sometimes
denoted FPF(r,p) or FPI(r,p) depending on the type
of encoding.
floating-point system FPF(r,p)
A floating-point system with radix r and p digits of
precision, in which the significant digits are represented as fractions.
floating-point system FPI(r,p)
A floating-point system with radix r and p digits of
precision, in which the significant digits are represented as integers.
FPCR
Floating-Point Control Register
FPR
Floating-Point Register
FPRn, FR n
Floating-Point Register n
free storage list
A list containing unused and available elements.
Sometimes abbreviated FSL .

External Symbol Dictionary


The set of external symbols created by an assembly.
They are displayed in the Assemblers listing and are

306

Or, the time at which programmers whose programs consistently fail to execute correctly are themselves executed.

1030

Assembler Language Programming for IBM z System Servers

Version 1.00

Fx
Fraction part of a floating-point number x

G
GR
General Register, General Purpose Register
GR Rn
A notation referring to the rightmost 32 bits of the
general register specified by R n .
GR G n
A notation referring to the 64-bit general register
specified by G n .
GRn
A notation referring to the rightmost 32 bits of
general register n.

hash table
A table of data items (possibly including lists and
pointers to other data items) whose entries are
accessed using the results of a hash function.
hexadecimal
A base-16 representation, with digits 0, 1, 2, 3, 4, 5,
6, 7, 8, 9, A, B, C, D, E, F, in increasing numerical
order. 307
hex
See hexadecimal.
HLASM
An acronym for the High Level Assembler.
High Level Assembler
IBMs most modern and powerful symbolic assembler for the z System processors, running on the
z/OS, z/VM, z/VSE, and zLinux operating systems. 308
The Assembler we describe here.

GGn
A notation referring to 64-bit general register n.
General Purpose Registers
A set of 16 64-bit registers used in the z System
family of processors for addressing, arithmetic, logic,
shifting, and other general purposes. Compare to
other registers described in the z/Architecture Principles of Operation such as Access Registers, Control
Registers, and Floating Point Registers.
GPR
See General Purpose Register
generalized object file format (GOFF)
An extended form of object module produced by
High Level Assembler, providing numerous enhancements and extensions not supported by the traditional
card-image object module format (OBJ).
GOFF
See generalized object file format.
GOFF option
An option that causes High Level Assembler to generate an object module using the generalized object
file format.
gradual underflow
A technique allowing numbers to become denormalized when they are finite and smaller than the
smallest normalized magnitude.
graphic data type
A representation of characters using a 16-bit
encoding.
guard digit
An extra digit used to increase the accuracy of a calculated floating-point result.

H
hash function
A function that creates a randomized linear subscript
from a data element. Used to avoid lengthy table
searches for large or complex data items.

307
308

I
I
Single operand of SVC instruction.
I
Integer Attribute Reference to a symbol (as in I SYM)
or to a symbolic parameter in a macro (as in
I&PARAM)
In

Immediate value specification for machine instruction


operand n

IA
Instruction Address (z/Architecture PSW bits 64-127).
IC
Interruption Code, a value indicating the cause of an
interruption.
ILC
See Instruction Length Code.
immediate operand
An operand contained in a field of the instruction
itself.
implied address
An address to which you expect the Assembler to
assign a base register specification digit and a displacement, or a relative-immediate offset, to an
addressing field.
implied length
A length field completed by the Assembler based on
its analysis of an operand.
increment
A (normally) constant value used to update the value
of the index for each iteration of a loop.
index
(1) The contents of an index register. (2) A varying
quantity used to control each iteration of a loop.

The base 16 representation is properly called sexagesimal.


The name is not necessarily an oxymoron, as High Level Assembler can do much more than ordinary (low-level) assemblers.
Glossary of Terms and Abbreviations

1031

index register
One of general purpose registers 1 through 15 specified by the index register specification digit in an
RX-type instruction.

its second byte may be modified (if required) by an


Execute instruction prior to final decoding.

index register specification digit


4 bits of an RX-type instructions specifying a register
with a value to be added to the Effective Address calculated from a base-displacment address.

indexing
Computation of an Effective Address by adding a displacement to the contents of a base register and an
index register.
infix notation
The traditional form of writing arithmetic expressions,
where operators are placed between operands, as in
2*(3+4).

Job Control Language


The statements needed to tell an Operating System
how to process your program through the assembly,
linking, and execution phases. JCL for short.

K
K
Character count attribute reference to a conditional
assembly symbolic parameter or SETC symbol (as in
K&PARAM)

inorder tree traversal


A technique for traversing a binary tree, visiting first
the left subtree, then the parent node, and then the
right subtree.
insert
Place one or more bytes into a register without
changing other bytes.
Instruction Address (IA)
A 64-bit field in the PSW giving the address of the
next instruction to be executed.
Instruction Length Code
Instruction Length Code, a 2-bit field in the PSW
indicating the length in halfwords of the currently executing instruction.
Instruction Register (IR)
A conceptual internal register used by the CPU to
decode instructions.
internal symbol
A symbol naming an element of an Assembler Language program, which is assigned a single value by
the Assembler, and not part of the object module.
They may be retained in the SYSADATA file.
Compare to external symbol.
internal symbol dictionary
See symbol table.
interruptible
An instruction is interruptible if the CPU suspends its
operation, updates the registers involved in the operation and subtracts the instructions length from the
Instruction Address in the PSW, so that when the
program resumes execution, the instruction will start
from the point where it was interrupted.
interruption
A process taking control away from the currently
executing instruction stream, saving information
about the interrupted program, and giving control to
the Operating System Supervisor (which may in turn
pass control to a program-specified routine).
invariant EBCDIC character
Those 82 characters whose EBCDIC representations
do not change among EBCDIC code pages. The syntactic characters used by HLASM are defined on
IBM Code Page 640.
IR
(1) Instruction Register, a conceptual internal register
in the CPU into which fetched instructions are placed
and decoded during the fetch-decode-execute cycle.
(2) An internal register holding a target instruction so

1032

L
L
Length Attribute Reference to an ordinary symbol (as
in L SYMBOL). or conditional assembler symbolic
parameter (as in L&PARAM). See Length Attribute Reference.
Ln
Length specification digits for operands in instructions
that support variable-length operands (See also N n.)
label
(1) Colloquially, the name of an instruction or data
definition. This is more properly called a name field
symbol. (2) In High Level Assembler, the name field
symbol of a USING statement, designating that statement as a labeled USING. The symbol is then
defined as a qualifier.
Labeled Dependent USING
A USING statement allowing implicit references to
symbols in areas mapped by more than one DSECT
to be resolved with by a specific base register.
Labeled USING
A USING statement directing resolution of implicit
references to a specific base register, distinguished
from an ordinary USING statement by the presence
of a qualifier symbol in the name field. Symbolic
expressions resolved with respect to a labeled USING
must use a qualified symbol with the qualifier of that
labeled USING.
LC
Location Counter. See Location Counter.
Length Attribute Reference
A term whose value is the length attribute of a
symbol.
Length Expression
A length value (N) coded implicitly or explicitly in a
machine instruction statement for an SS-type instruction, from which the Assembler derives the Length
Specification Byte L or the Length Specification Digit
L n. In this text, often described by the terms N or Nn .
length modifier
A modifier specifying the exact length to be used for
a constant, rather than its default length.

Assembler Language Programming for IBM z System Servers

Version 1.00

Length Specification Byte


The second byte (L) of an SS-type instruction, one
less than the true length of its operand.
Length Specification Digit
A 4-bit hexadecimal digit (Ln) in The second byte of
an SS-type instruction, one less than the true length of
its operand.
linear subscript
For arrays of two or more dimensions, the evaluation
of a subscript that treats the array as having been
mapped into a one-dimensional array corresponding
to the CPUs linear arrangement of bytes in memory.
linkage convention
A set of rules for transferring control between a
calling and a called program, passing arguments and
receiving results, and preserving caller information
during the execution of the subroutine so it can be
restored on return to the caller.
linked list
Same as list. Sometimes called a single-threaded
list.
Linkage Editor
The predecessor to the z/OS Binder; its functions are
included in the Binder. A Linkage Editor is used on
z/VSE.
linking loader
Links and places modules directly into storage with
linking, immediately prior to program execution.
Linker
A program that converts and combines object
modules and load modules into an executable format
ready for quick loading into memory by the Program
Loader.

erate a relocatable MODULE. (2) On older OS/360


systems, a program that links object and load
modules into memory for execution; now called the
Batch Loader. (3) The Program Loader.
location
A position within the object code of an assembled
program, as determined by assigning values of the
Location Counter during assembly. An assembly time
value, sometimes confused with an execution time
address.
Location Counter (LC)
A counter used by the Assembler at assembly time to
construct its model of the relative positions of all
components of an assembled program.
logical division
Division of two unsigned operands, generating an
unsigned quotient and unsigned remainder.
logical multiplication
Multiplication of two unsigned operands, generating
an unsigned product.
logical shift
A movement of bits in a general register to the left or
right, inserting zero bits into any vacated bit positions.
logical representation
An unsigned number representation.
logical arithmetic
Binary arithmetic and comparison operations with
unsigned operands.

list
(1) A sequence of data elements each containing a
link to its successor. (2) Colloquially, a table.

M n, mn
Mask digit in machine instruction operand n.

literal
A special symbol with the side effect of defining a
constant referenced by that symbol.

machine language
The binary instructions and data interpreted and
manipulated by the processor when a program is executed. 309 Compare Assembler Language.

literal pool
A set of literal-generated constants grouped together
by the Assembler. A program may contain multiple
literal pools.
load module
(1) A generic name for the output of a Linker; a
mixture of machine language instructions and data
ready to be loaded directly into memory for execution. (2) The original form of System/360 executable, stored in a Partitioned Data Set (PDS) program
library. in record format.
load operation
Replace the contents of a register with a copy of data
from a memory address or from another register.
Other parts of the register may contain sign-extended
bits (for arithmetic loads), or zero-extended bits (for
logical loads). The original contents of the target register are not preserved.
Loader
(1) On z/VM systems, a program that can link object
modules directly into memory for execution, or gen-

309

machine length
An Encoded Length, one less than the Length
Expression coded in the instruction statement.
macro instruction
A powerful means to encapsulate groups of statements under a single name, and then generate them
(with possible programmer-determined modifications)
by using the macro-instruction name as an operation
field entry. Often abbreviated macro.
mantissa
A term sometimes used to describe the significand of
a floating-point number. Because it can be confused
with the mantissa (fractional part) of a logarithm,
avoid its use when describing floating-point representations.
mask
(1) A bit in an instruction controlling its behavior.
(2) A bit in the FPCR controlling the actions to be
taken when an exception condition occurs.

It is not meant to be intelligible to normal human beings.


Glossary of Terms and Abbreviations

1033

MaxReal
The largest representable floating-point magnitude,
also called Max.

nominal value
The value you write between delimiters or value separators to specify the assembled value of a constant.

MBCS
Multiple Byte Character Set, in which characters are
represented by one to four bytes.

no-operation instruction
An executable instruction having no effect other than
to occupy space.

message character
Any character in an edit pattern that is not a Digit
Selector (DS), a Field Separator (FS), or a Digit
Selector and Significance Starter (SS).

normalization
A process of ensuring that the most significant digit in
a fraction-based floating-point representation is
nonzero.

millicode
Internal instructions used by the CPU to perform
operations too complex to be done cost-effectively in
hardware. (Sometimes called microcode.)

null byte
A zero or X 0 0 byte, sometimes indicated by the
character n.

MinReal
The smallest representable floating-point magnitude.
If normalized, it is also called Min; if denormalized, it
is also called DMin.
minuend
see subtrahend
mnemonic
A character string representing an instruction name,
intended to be easier to remember than the operation
code of the instruction. A convenient shorthand for
the name of an instruction. For example, the
Branch and Save instruction has mnemonic
BAS.
modal instruction
An instruction that places or updates addresses in the
general registers, with results that depend on the
addressing mode.
modifier
A value following the constant type, specifying other
information about the constants Length, Scale, and
Exponent.
multiplicand
In a multiplication, the number that is to be multiplied (the first operand) by another, the multiplier
(the second operand)
multiplier
See multiplicand
multiply and add/subtract
An instruction in which a double-length product is
created internally to which a third operand is added
or subtracted before truncating or rounding the result
to the length of the original operands.

N
N, Nn
The Length Expression you specify in an SS-type
instruction, giving the true length of an operand. The
Assembler converts that value to the Length
Expression used by the CPU when executing the
instruction.
N
Number attribute reference to a conditional assembly
symbolic parameter or dimensioned SET symbol (as
in N&PARAM).
NaN
A floating-point Not-a-Number having no numeric
or mathematical meaning.

1034

numeric digit
The rightmost 4 bits of a byte.

O
object code
The machine language contents of an object module.
object module
Records created by the Assembler containing the
external symbols, machine language text, and relocation dictionary information required for program
linking.
offset
(1) The MVO instruction shifts or offsets the second
operand to the left by one hex digit before appending
it to the sign digit of the first operand. (2) A field in
a relative-immediate instruction giving the distance in
halfwords from the instruction.
ones complement representation
A signed binary representation where negative
numbers are represented by changing each 0 bit to a
1 bit and vice versa.
opcode
An abbreviation for operation code. Sometimes used
when the term mnemonic is meant.
operand
(1) Something operated on by an instruction. (2) A
field in a machine instruction statement.
operand order dependence
The results of many packed decimal arithmetic
instructions depend on the order of the operands. For
example (007 + ) + (7 + ) yields 014 + , but (7 + ) + (007 + )
causes a decimal overflow.
operation code
The z/Architecture definition of that portion of an
instruction specifying the actions to be performed by
the CPU when it executes the instruction. Often
abbreviated opcode, sometimes mistakenly used to
refer to a mnemonic.
operator
One of * (meaning multiplication), / (meaning division), + (meaning addition), or (meaning subtraction).
options
Directives to the Assembler specifying various
global controls over its behavior. Options are
specified by the user as a string of characters, usually
part of the command or statement that invokes the

Assembler Language Programming for IBM z System Servers

Version 1.00

assembler, or on *PROCESS statements. Some options


may be dynamically modified by ACONTROL statements.
OR operation
A logical (boolean) operation between two bits,
whose result is 1 if either operand bit is 1.
Ordinary USING
A USING statement directing resolution of unqualified implicit references to a specific base register.
ORG Statement Extended Syntax
Additional operands on ORG statements that allow
LC alignment to a specific power-of-two boundary,
and an offset from that position.
origin
A starting value assigned by you (or by the Assembler), used to calculate offsets and displacements in
your program. (Because most programs are relocated, its rarely necessary to specify an origin.)
overflow
The sum, difference, product, or quotient of two
numbers is too large to be correctly represented in the
number of digits or range of values available.

P
padding
Adding extra bits or bytes to a constant so that it will
fill the space allotted to it.
parameter
A place-holder in a called program, to be assigned a
value from an argument provided by a calling
program.
parameterization
A valuable technique for adding flexibility and generality to program definitions, typically by defining
assembly-time values in EQU statements.
pattern character
Any byte in an edit pattern.
payload
Diagnostic information contained in a the significand
of a NaN.
pipeline
A technique used in modern CPUs to speed instruction execution by dividing the fetch. decode, and
execute phases into smaller stages.
PM
See Program Mask..
postfix notation
A representation of expressions convenient for evaluation. The infix form 2*(3+4) is represented as
2 3 4 + *.
post-normalization
A process of normalizing a floating-point operand
after operating on it.
postorder tree traversal
A technique for traversing a binary tree, visiting first
the left subtree, then the right subtree, and then the
parent node.

of one of the operands or a value providing the


maximum number of significant digits.
preferred quantum
The quantum selected for the result of a decimal
floating-point operation that maximizes the number
of significant digits, including low-order zero digits.
Equivalent to preferred exponent.
preorder tree traversal
A technique for traversing a binary tree, visiting first
the parent node, then the left subtree, and then the
right subtree.
pre-normalization
A process of normalizing floating-point operands
before operating on them.
problem state
A state in which the CPU disallows the execution of
certain instructions.
program interruption
An interruption condition caused by an executing
program that can be handled by the interrupted
program.
Program Loader
The component of the Operating System that brings
load modules into memory, makes final relocations,
and transfers control to the program.
program length
A Length Expression, not necessarily the length of a
program.
Program Mask
A 4-bit field in the PSW used to control whether or
not certain types of exception condition should cause
an interruption or take a CPU-defined default action.
PseudoRegister (PR), External Dummy (XD)
A PseudoRegister or external data item having length
and alignment attributes. Space in the loaded module
is reserved for Common control sections; space for
external dummy sections must be obtained at execution time. (See External Dummy Section.)
PSW
Program Status Word, containing information about
the current state of a program.

Q
QNaN
A Quiet Not-a-Number that does not cause an exception condition in any arithmetic operation.
Q-type address constant
A field containing the offset (not the address) of a
Dummy External Symbol (or PseudoRegister) from
the start of a virtual area mapped at link time and
allocated at execution time.
qualified symbol
A symbol prefixed by a qualifier and separated from
it by a period, as in qualifier.symbol.
qualifier
A symbolic identifier defined in the name field of a
Labeled USING statement. It may be used only as a
qualifier, and not as an ordinary symbol.

preferred exponent
The exponent of the result of a decimal floating-point
numeric operation has a preferred value, either that
Glossary of Terms and Abbreviations

1035

quantum
The value of a unit in the low-order digit of a decimal
floating-point number.
queue
A sequence of data elements each containing links to
its successor and to its predecessor. Sometimes called
a doubly-linked list.
quotient
The primary result of a division operation.

R
Rn , rn
(1) Register specification digit for machine instruction
operand n. (2) The field of a machine instruction
designating the number of a general register.
Rrn
The GPR designated by register number R n.
R(r1+1)
The GPR whose number is found by adding 1 to the
even-numbered register specification digit r1.
R(r3|1)
The GPR whose number is found by forcing the loworder bit of the register specification digit r3 to be a
1-bit. Thus, R(6|1) means R7, and R(7|1) means R7.
radix
The base in which the significant digits of fixed-point
or floating-point numbers are represented.
radix-complement representation
A signed representation where the the complement of
a number is formed by complementing each digit with
respect to the radix minus 1, and then adding 1 to the
lowest-order digit. The numerically significant highorder digit usually contains sign information.
real address
The true address of a byte in memory.
real numbers
A powerful abstraction used by mathematicians;
numbers with unlimited range and precision.
realistic numbers
Numbers used for computation, having finite range,
precision, and accuracy.
reentrant
See reenterable.
reenterable
A program is reenterable if (1) Its execution can be
suspended, then executed by other processes, and
then resumed by the original process with correct
behavior for all processes; (2) It can be executed
simultaneously by multiple processes, with correct
behavior for all processes. (3) Capable of simultaneous execution by two or more asynchronously
executing processes or processors, with only a single
instance of the program image. Typically, reenterable
programs do not modify themselves, but this is
neither a necessary nor sufficient condition for
reenterability.
reference control section
A control section containing no machine language
instructions or data, defined by a DSECT, COM, or
DXD instruction.

1036

relative address
An Effective Address determined by an offset relative
to the location of an instruction containing a relativeimmediate operand.
relocatable
A property of a program allowing it to execute correctly no matter where it is placed in memory by the
Program Loader.
relocate
Assign actual-storage or module-origin-relative
addresses to address constants.
relocating loader
Places modules into storage and adjusts addresses to
their correct final value.
relocation
A procedure used by the Linker and the Program
Loader to ensure that addresses in a relocatable
loaded program are correct and refer to the intended
targets, no matter where it is loaded. This usually
requires assigning true execution-time addresses to
parts of a program.
remainder
The residual portion of a division left over when a
dividend cannot be evenly divided by a divisor.
Smaller in magnitude than the divisor.
RENT
An Assembler option requesting simple tests be made
for conditions of obvious self-modification of the
program being assembled. These tests are also done
for control sections declared by the RSECT statement.
return address
The address of an instruction to which control should
be passed when a routine completes its execution.
return code
A small integer value (usually a multiple of 4) placed
in GR15 prior to returning to a calling program.
rotating shift
A movement of bits in a general register to the left in
such a way that bits moved out of the high-order bit
position are inserted into the low-order bit position.
(Also called a circulating shift.)
rounding digit
An extra digit used to help correctly round a calculated floating-point result.
Rounding Mode
(1) A field in the FPCR indicating the rounding
action to be taken after a binary floating-point operation. (2) A field in an instruction specifying the
rounding to be performed by the instruction, independent of any rounding mode specified in the
FPCR.
rounding-mode suffix
A suffix with the letter R and a number appended to
the numeric value of a floating-point specifying the
rounding used when converting the nominal value to
hexadecimal or binary floating-point.
rounding modifier
A field in an instruction specifying the type of
rounding to be performed on the result of the
floating-point operation.
row order
A way to store arrays so that the elements of each
row follow one another in memory. For arrays of two

Assembler Language Programming for IBM z System Servers

Version 1.00

or more dimensions, subscripts cycle most rapidly


from right to left.
row-major order
Same as row order.
RSECT
A reenterable control section, distinguished from an
ordinary control section (CSECT) only by (a) the
presence of a flag in the External Symbol Dictionary
and (b) that High Level Assembler will perform
reenterability checking of instructions within the
RSECT.
run time
See execution time.

S
S
Scale attribute reference to a symbol (as in S ABC), or
a macro parameter (as in S&PARAM).
Sn

Implied address of machine instruction operand n.

significance indicator
An internal bit used by the CPU during ED and
EDMK instructions to control subsequent editing
operations.
significance starter
An edit-pattern character that sets the Significance
Indicator ON. Also known as a digit selector and
significance starter because it selects a digit if the
Significance Indicator is already on.
significand
The numerically significant digits of a floating-point
number, whether explicitly or implicitly represented.
sign-magnitude representation
The familiar signed representation of numbers with
prefixed or suffixed + or signs attached to the
numbers magnitude.
simple relocatability
A property of an assembly-time symbol or expression
whose value changes by the same amount as a
change to the programs assumed origin.
SNaN
A Signaling Not-a-Number that causes an exception
condition in an arithmetic operation.

SBCS
Single Byte Character Set in which characters are
represented by a single byte.

special value
A floating-point zero, a denormalized number, an
infinity, a QNaN, or an SNaN.

section
A generic term for control section, dummy section,
common section, etc.; a collection of items that must
be bound or relocated as an indivisible unit.

stack
A data structure with a single visible element, the
stack top. Sometimes called a Last In, First Out
(LIFO) list or queue.

self-defining term
One of binary, character, decimal, graphic, and
hexadecimal. Its value is inherent in the term, and
does not depend on the values of other items in the
program.

statement
The contents of the records read and processed by
the Assembler. There are four types: comment statements, machine instruction statements, assembler
instruction statements, and macro-instruction statements.

self-modification
A program modifies its instructions or constants.
Considered a very poor programming practice with
severe execution-time performance penalties, and
usually forbidden if the program must be
reenterable. 310
Shift-In
The single byte X 0 F indicating a change from
double-byte mode to single-byte mode. That is, shift
into single-byte mode.
Shift-Out
The single byte X 0 E indicating a change from singlebyte mode to double-byte mode. That is, shift out of
single-byte mode.
sign extension
The process of copying the sign bit of a shorter
binary operand and extending it to the left, to the
length of a target field.
significance exception
In hexadecimal floating-point, the result of an addition or subtraction yields a significand of all zero
digits. This exception can either cause a program
interruption with IC=15, or can be masked to
produce a true zero.

310

statement field
One of the four fields of an Assembler Language
statement (other than a comment statement): the
name, operation, operand, and remarks fields. Which
fields are required and/or optional depends on the
specific statement.
status flag
A bit in the FPCR indicating that an exception condition has occurred.
store operation
Place a copy of part or all of a registers contents into
memory.
subtrahend
When one number is subtracted from another, the
number being diminished (the first operand) is the
minuend, and the number being subtracted (the
second operand) is the subtrahend.
supervisor state
A state in which the CPU allows the execution of all
instructions.
symbol
A name known at assembly time, to which various
values are assigned. The values may be absolute,

Technically, a self-modifying program can be reenterable if every execution instance makes exactly the same modifications. This is
considered an even poorer practice.
Glossary of Terms and Abbreviations

1037

simply, or complexly relocatable, or determined at


link or execution time.
symbol attribute
Information about the properties of a symbol,
including value, relocation, length, type, scale, and
integer. (Only the first three attributes are important
for most uses.)
Symbol Attribute Reference
(1) A term whose value is that of a symbols attribute.
The types of Symbol Attribute Reference are length,
scale, integer, definition, type, and opcode. (2) Conditional assembly attribute references include the
above six, plus count, number, assembler type, and
program type.
Symbol Table
A table used by the Assembler to hold the names,
values, and attributes of all symbols in a program.

ulp
An abbreviation for unit in the last place, a
measure of the relative precision of a floating-point
number.
Unicode
A standard for representing characters in almost all
languages. Encodings vary from 1 to 4 bytes in
length.
Unicode numeric characters
Unicode characters with representations between
X 0030 and X 0039 .
unnormalized add/subtract
Hexadecimal floating-point addition and subtraction
in which the result is not normalized.
USING statement
A promise to the Assembler that addressing fields can
be derived correctly from the base location and base
address information provided in the statement.

USING Table
An internal table used by the Assembler to hold
information provided in USING instructions.

Type Attribute Reference to a conditional assembly


symbolic parameter (as in T&PARAM).

UTF
Unicode Transformation Format. Three encodings
(UTF-8, UTF-16, and UTF-32) that are easily converted (transformed) among one another.

table
A term often used to describe a one-dimensional
array whose columns contain a mixture of different
data types and lengths. (See array.)

target instruction
(1) The instruction to which a branch instruction
might transfer control. (2) An instruction addressed
by an Execute instruction.

virtual address
The address of a memory location that may physically reside at a different real address.

term
A symbol, self-defining term, Location Counter reference, literal, or symbol attribute reference.

virtual origin
The address of a (possibly nonexistent) array element
all of whose subscripts are zero.

text
The portions of an object module containing machine
language instructions and data.
true decimal addition
The addition of packed decimal operands of like sign.
truncation
Removing bits or bytes from a constant so that it will
fit in the space allotted to it.
twos complement
A method for negating a binary integer, by converting
each 1 to 0 and each 0 to 1, and then adding a loworder 1.
twos complement representation
A signed binary representation where the high-order
bit contains sign information, and has weight 2 n 1.
type extension
A second letter following the constant type, providing
additional information about the constants length or
representation.

U
UCS
Universal Character Set. UCS-2 was a predecessor of
Unicode that defined only 65,536 values. Sometimes
used as an alternative name for UTF.

1038

X
Xn, x n
Index register specification digit for machine instruction operand n.
XOR operation
A logical (boolean) exclusive-OR operation between
two bits, whose result is 1 if either operand bit is 1
while the other is zero. If the operand bits are identical, the result is zero.

Z
zero duplication factor
A duplication factor that causes LC alignment
without generating a constant. Skipped bytes are
zeroed for DC instructions if the immediately preceding byte contains object code.
zero extension
The process of adding zero bits to the left of a shorter
operand, to extend it to the length of a target field.
zone digit
The leftmost 4 bits of a byte.

Assembler Language Programming for IBM z System Servers

Version 1.00

zoned digit
An edited packed decimal numeric digit.

Glossary of Terms and Abbreviations

1039

1040

Assembler Language Programming for IBM z System Servers

Version 1.00

Bibliography

BBBBBBBBBBB
BBBBBBBBBBBB
BB
BB
BB
BB
BB
BB
BBBBBBBBBB
BBBBBBBBBB
BB
BB
BB
BB
BB
BB
BBBBBBBBBBBB
BBBBBBBBBBB

IIIIIIIIII
IIIIIIIIII
II
II
II
II
II
II
II
II
IIIIIIIIII
IIIIIIIIII

BBBBBBBBBBB
BBBBBBBBBBBB
BB
BB
BB
BB
BB
BB
BBBBBBBBBB
BBBBBBBBBB
BB
BB
BB
BB
BB
BB
BBBBBBBBBBBB
BBBBBBBBBBB

Basic References
These are useful references you may want to have available. They should be available at these web sites:
http://www.ibm.com/systems/z/os/zos/bkserv/
http://www.ibm.com/servers/eserver/zseries/zos/webqs.html
http://www-03.ibm.com/software/products/en/hlasm

z/Architecture Processor
z/Architecture Principles of Operation, SA22-7832
z/Architecture Reference Summary, SA22-7871

High Level Assembler


High Level Assembler Language Reference, SC26-4940
High Level Assembler Programmer s Guide, SC29-4941

z/OS System Services


z/OS MVS Programming: Assembler Services Guide, SA23-1368
z/OS MVS Programming: Assembler Services Reference, Volumes 1-2, SA23-1369 SA23-1370
z/OS MVS Programming: Extended Addressability Guide, SA22-7614
z/OS MVS System Codes, SA22-7626
z/OS MVS System Messages, Volumes 1-10, SA22-7631 SA22-7640

z/OS Data Areas and Control Blocks

z/OS Input/Output

z/OS MVS Data Areas, Volumes 1-6. GA32-0853 GA32-0858


z/OS DFSMS Using Data Sets, SC26-7410
z/OS DFSMS Macro Instructions for Data Sets, SC23-6852

z/OS Binder
z/OS MVS Program Management Users Guide and Reference SA22-7643
z/OS MVS Program Management Advanced Facilities SA22-7644

z/VM
z/VM CMS Application Development Guide for Assembler, SC24-6070

Bibliography

1041

z/VSE
z/VSE Guide to System Functions, SC33-8312
z/VSE Messages and Codes, Volumes 1-3, SC33-8306 SC33-8308

System/360 Architecture History

IBM System/360 Principles of Operation, Form A22-6821.

Architecture of the IBM System/360, by G. M. Amdahl, G. A. Blaauw, and F. P. Brooks. IBM Journal of Research
and Development, Volume 8, No. 2, April 1964. (Reprinted in IBM Journal of Research and Development Vol. 44
No. 1/2, January/March 2000.)

The Structure of System/360, a series of five articles in the IBM Systems Journal, Volume 3, Number 2, 1964.

Part
Part
Part
Part
Part

I - Outline of the Logical Structure, by G. A. Blaauw and F. P. Brooks, Jr.


II - System Implementations, by W. Y. Stevens.
III - Processing Unit Design Considerations, by G. M. Amdahl.
IV - Channel Design Considerations, by A. Padegs.
V - Multisystem Organization, by G. A. Blaauw.

D. W. Sweeney, An Analysis of Floating-Point Addition, IBM Systems Journal Vol. 4 No. 1 (1965)

The functional structure of OS/360 Part I: Introductory Survey. IBM Systems Journal Vol. 5 No. 1, 3-11 (1966)

The functional structure of OS/360 Part II: Job and Task Management. IBM Systems Journal Vol. 5 No. 1, 12-29
(1966)

The functional structure of OS/360 Part III: Data Management. IBM Systems Journal Vol. 5 No. 1, 30-51 (1966)

Microprogram Control for System/360, by S. G. Tucker. IBM Systems Journal, Volume 6, Number 4, 1967.

Lisa Heller and Mark Farrell, Millicode in an IBM zSeries processor, IBM Journal of Research and Development,
Volume 48, Number 3/4, May/July 2004.

Assembler Design and Implementation

IBM System/360 Operating System Assembler Language, Form C28-6514.

Macro Language Design for System/360, by D. N. Freeman. IBM Systems Journal, Volume 5, Number 2, 1966.

Proceedings of the IBM Macro Assembler Conference, May 1-3, 1967, Los Gatos, California. (This collection of nine
papers is an interesting source of inside information presented by assembler specialists in the computer industry.)

PL/360, A Programming Language for the 360 Computers, by Niklaus Wirth. Journal of the ACM, Volume 15,
January 1968.

Assembler-Language Macroprogramming: A Tutorial Oriented Toward the IBM 360, by William Kent. Computing
Surveys, Volume 1, Number 4, December 1969.

Assembler Design and its Effect on Language and Performance, by H. Joseph Myers. Proceedings of SHARE
XXXIV, March 1970, Denver, Colorado.

A Brief System z Assembler History, by John Ehrman. Proceedings of SHARE 120, Session 12235, San Francisco,
California, February 2013.

Other General References

Donald Knuth, The Art of Computer Programming, Addison-Wesley.

1042

Assembler Language Programming for IBM z System Servers

Version 1.00

Acknowledgments

AAAAAAAAAA
AAAAAAAAAAAA
AA
AA
AA
AA
AA
AA
AAAAAAAAAAAA
AAAAAAAAAAAA
AA
AA
AA
AA
AA
AA
AA
AA
AA
AA

CCCCCCCCCC
CCCCCCCCCCCC
CC
CC
CC
CC
CC
CC
CC
CC
CC
CC
CCCCCCCCCCCC
CCCCCCCCCC

KK
KK
KK
KK
KK
KK
KK
KK
KK
KK
KKKKKKK
KKKKKKK
KK
KK
KK
KK
KK
KK
KK
KK
KK
KK

Thanks to the following:


ASSEMBLER_LIST discussion group for many interesting suggestions and observations.
Bryan Childs for several helpful suggestions.
Richard Corak for thorough and helpful comments on many drafts.
John Dravnieks for helping me understand the High Level Assembler, and for being a valued colleague for many years.
John Ganci for permission to use several clever solutions to programming exercises, and for his sharp-eyed and
knowledgable reviews, and thoughtful suggestions.
Dan Greiner for many tutorials on the behavior of z System and its instructions, and for thorough and detailed reviews of
drafts.
Vicki Griffeth for helping me to see an early version of these notes through a readers eyes.
David Gross for thorough proofreading and many helpful suggestions.
John Kalinich for reviewing several chapters.
Melvyn Maltz for suggestions and very careful proof-reading.
Lisa Moore for helping me understand and clarify the description of character encodings, especially Unicode.
Ed Oddo, William Deason, and Ken Edwards for supporting my efforts to complete these notes.
Prof. Joshua Panar of Ryerson University for extensive thoughtful comments, and field testing in a university environment.
Wayne Rhoten for help clarifying many important points.
Michael Stack of Northern Illinois University for his inspiration as a teacher of Assembler Language and as the creator
of the SHARE Assembler Boot Camp.
Romney White for thorough and helpful comments on many drafts.
Stanford University students for their critiques of a very early version of these notes.

Acknowledgments

1043

1044

Assembler Language Programming for IBM z System Servers

Version 1.00

Notices
NN
NN
NNN
NN
NNNN
NN
NN NN
NN
NN NN
NN
NN
NN
NN
NN
NN NN
NN
NN NN
NN
NNNN
NN
NNN
NN
NN
NN
N

OOOOOOOOOOOO
OOOOOOOOOOOO
OO
OO
OO
OO
OO
OO
OO
OO
OO
OO
OO
OO
OO
OO
OO
OO
OOOOOOOOOOOO
OOOOOOOOOOOO

TTTTTTTTTTTT
TTTTTTTTTTTT
TT
TT
TT
TT
TT
TT
TT
TT
TT
TT

This information was developed for products and services offered in the U.S.A.
IBM may not offer the products, services, or features discussed in this document in other countries. Consult your local
IBM representative for information on the products and services currently available in your area. Any reference to an
IBM product, program, or service is not intended to state or imply that only that IBM product, program, or service may
be used. Any functionally equivalent product, program, or service that does not infringe any IBM intellectual property
right may be used instead. However, it is the users responsibility to evaluate and verify the operation of any non-IBM
product, program, or service.
IBM may have patents or pending patent applications covering subject matter described in this document. The furnishing
of this document does not give you any license to those patents. You can send license inquiries, in writing, to
IBM Director of Licensing
IBM Corporation
North Castle Drive
Armonk, NY 10504-1785
U.S.A.
The following paragraph does not apply to the United Kingdom or any other country where such provisions are inconsistent with local law. INTERNATIONAL BUSINESS MACHINES PROVIDES THIS PUBLICATION AS IS
WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, OR
FITNESS FOR A PARTICULAR PURPOSE. Some states do not allow disclaimer of express or implied warranties in
certain transactions, therefore, this statement may not apply to you.
This information could include technical inaccuracies or typographical errors. Changes are periodically made to the information herein; these changes will be incorporated in new editions of the publication. IBM may make improvements
and/or changes in the product(s) and/or the program(s) described in this publication at any time without notice.
Any references in this information to non-IBM Web sites are provided for convenience only and do not in any manner
serve as an endorsement of those Web sites. The materials at those Web sites are not part of the materials for this IBM
product and use of those Web sites is at your own risk.

Trademarks
The following are trademarks of International Business Machines Corporation in the United States, or other countries, or
both.
BookMaster
Enterprise Systems Architecture/390
ESA/390
MVS
OS/390
S/370
System/370
System z
z/Architecture
Z/VSE

Enterprise Systems Architecture/370


ESA/370
IBM
OS/360
S/360
System/360
System/390
VSE/ESA
Z/VM
zSeries

Notices

1045

ANSI is a registered trademark of the American National Standards Institute in the United States, other countries, or
both.
IEEE is a trademark of the Institute of Electrical and Electronic Engineers, Inc. in the United States, other countries, or
both.
Linux is a registered trademark of Linus Torvalds in the United States, other countries, or both.
Unicode is a registered trademark of Unicode, Incorporated in the United States, other countries, or both.
Unix is a registered trademark of The Open Group in the United States and other countries.
Other company product and service names may be trademarks or service marks of others.

1046

Assembler Language Programming for IBM z System Servers

Version 1.00

Suggested Solutions to Selected Exercises and Programming


Problems

Suggested Solutions to Selected Exercises and Programming Problems

1047

Section 1 Solutions
Section 1.2
1.2.1. The field is 8 digits wide.
Section 1.3
1.3.1. The reference is to GR9.

1048

Assembler Language Programming for IBM z System Servers

Version 1.00

Section 2 Solutions
Section 2.1
2.1.1. (a) 22, (b) 44, (c) 170, (d) 127.
2.1.2. 2 n .
2.1.3. Assuming the number is unsigned, 2 n 1. Later, when we discuss signed numbers in the twos complement
representation, the answer will be 1.
Section 2.2
2.2.1. (a) B1010, (b) B10 1101 , (c) B11 1110 1000 .
2.2.2.
Binary
Digits
0000
0001
0010
0011
0100
0101
0110
0111
1000
1001
1010
1011
1100
1101
1110
1111
10001

Decimal
Value
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

Hex
Digit
0
1
2
3
4
5
6
7
8
9
A
B
C
D
E
F
10

Octal
Digits
0
1
2
3
4
5
6
7
10
11
12
13
14
15
16
17
20

2.2.3. Groupings always begin at the radix point, which for integers lies to the right of the last digit. (Consider what
would happen to B111111 if you grouped the bits from the left: should the result be B1111 1100 = X FC , rather
than X 3 F ?)
2.2.4. These are the hexadecimal addition and multiplication tables.
+
0
1
2
3
4
5
6
7
8
9
A
B
C
D
E
F

0
00
01
02
03
04
05
06
07
08
09
0A
0B
0C
0D
0E
0F

1
01
02
03
04
05
06
07
08
09
0A
0B
0C
0D
0E
0F
10

2
02
03
04
05
06
07
08
09
0A
0B
0C
0D
0E
0F
10
11

3
03
04
05
06
07
08
09
0A
0B
0C
0D
0E
0F
10
11
12

4
04
05
06
07
08
09
0A
0B
0C
0D
0E
0F
10
11
12
13

5
05
06
07
08
09
0A
0B
0C
0D
0E
0F
10
11
12
13
14

6
06
07
08
09
0A
0B
0C
0D
0E
0F
10
11
12
13
14
15

7
07
08
09
0A
0B
0C
0D
0E
0F
10
11
12
13
14
15
16

8
08
09
0A
0B
0C
0D
0E
0F
10
11
12
13
14
15
16
17

9
09
0A
0B
0C
0D
0E
0F
10
11
12
13
14
15
16
17
18

A
0A
0B
0C
0D
0E
0F
10
11
12
13
14
15
16
17
18
19

B
0B
0C
0D
0E
0F
10
11
12
13
14
15
16
17
18
19
1A

C
0C
0D
0E
0F
10
11
12
13
14
15
16
17
18
19
1A
1B

D
0D
0E
0F
10
11
12
13
14
15
16
17
18
19
1A
1B
1C

E
0E
0F
10
11
12
13
14
15
16
17
18
19
1A
1B
1C
1D

F
0F
10
11
12
13
14
15
16
17
18
19
1A
1B
1C
1D
1E

Suggested Solutions to Selected Exercises and Programming Problems

1049


1
2
3
4
5
6
7
8
9
A
B
C
D
E
F

0
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00

1
01
02
03
04
05
06
07
08
09
0A
0B
0C
0D
0E
0F

2
02
04
06
08
0A
0C
0E
10
12
14
16
18
1A
1C
1E

3
03
06
09
0C
0F
12
15
18
1B
1E
21
24
27
2A
2D

4
04
08
0C
10
14
18
1C
20
24
28
2C
30
34
38
3C

5
05
0A
0F
14
19
1E
23
28
2D
32
37
3C
41
46
4B

6
06
0C
12
18
1E
24
2A
30
36
3C
42
48
4E
54
5A

7
07
0E
15
1C
23
2A
31
38
3F
46
4D
54
5B
62
69

8
08
10
18
20
28
30
38
40
48
50
58
60
68
70
78

9
09
12
1B
24
2D
36
3F
48
51
5A
63
6C
75
7E
87

A
0A
14
1E
28
32
3C
46
50
5A
64
6E
78
82
8C
96

B
0B
16
21
2C
37
42
4D
58
63
6E
79
84
8F
9A
A5

C
0C
18
24
30
3C
48
54
60
6C
78
84
90
9C
A8
B4

D
0D
1A
27
34
41
4E
5B
68
75
82
8F
9C
A9
B6
C3

E
0E
1C
2A
38
46
54
62
70
7E
8C
9A
A8
B6
C4
D2

F
0F
1E
2D
3C
4B
5A
69
78
87
96
A5
B4
C3
D2
E1

2.2.5.
1.
2.
3.
4.
5.

21474 (base 8) = X233C .


77777 (base 8) = 2 15 1 = X 7 FFF .
1750 (base 8) = X 3 E8 .
60341303 (base 8) = X C1C2C3 .
4631 (base 8) = X 9 9 9 .

Section 2.3
2.3.1.
1.
2.
3.
4.

26293 = X66B5 = B 110 0110 1011 0101 = 63265 (base 8) = 12122311 (base 4).
X 2 FACED = B 10 1111 1010 1100 1110 1101 = 3124461.
X BABEF00D = 27257570015 (base 8) = 3133075469.
X C0FFEE = B 1100 0000 1111 1111 1110 1110 = 12648430.

2.3.2.
1. 2147483647 (a useful number!)
2. 12698307
3. 1077952604
2.3.4.
1.
2.
3.
4.
5.

X 2 5 7
X 7 FFA
X8008
X E000
X FFFA

=
=
=
=
=

599
32762
32776
57344
65530

2.3.5. It is usually most convenient to do the arithmetic in base A (the original base) by expressing B in base A. Sometimes it is simpler to convert from base A to base 10, and from there to B using decimal arithmetic. (We cant do the
arithmetic in base B, since we would have to know the representation of the number to be converted in base B in order
to do the arithmetic!) The result does not depend on the base used for the conversion.
2.3.6. (a) 5061 (octal) = 2609 (decimal); (b) 111, (c) 192 is not a valid octal number (9 is not an octal digit!).
2.3.7. Referring to the tables of powers of 16, we find 9K = 589,284; 5M = 83,866,080; 2G = 2,147,483,648.
Section 2.4
2.4.1.
1. 31659 = 75653 (base 8) = 13232223 (base 4) = B111 1011 1010 1011.
2. 6917 = 210132 (base 5) = 31C1 (base 13) = X 1 B05 .
3. X EF2A = 61226 = 21B39 (base 13).
2.4.2. The hex values are 1, A, 64, 3E8, 2710, 186A0, F4240, 989680, 5F5E100, 3B9ACA00. Did you do many
tedious base-10 divisions by 16, rather than nine base-16 multiplications by X A ? Try it, its good practice in hex
arithmetic. (In this way, you can derive further values easily; the next three are 2540BE400, 174876E800, and
E804A51000.)
2.4.4. Your answer should be 1000 (decimal).

1050

Assembler Language Programming for IBM z System Servers

Version 1.00

2.4.5. 73294 = 58001 (base 11) = 374BA (base 12) = 27490 (base 13) = 1C9D4 (base 14) = 16AB4 (base 15). The
previously computed results are of little use in converting to each new base.
2.4.6. Here is a base-7 multiplication table:

1
2
3
4
5
6

1
1
2
3
4
5
6

2
2
4
6
11
13
15

3
3
6
12
15
21
24

4
4
11
15
22
26
33

5
5
13
21
26
34
42

6
6
15
24
33
42
51

(1) 526 (base 7) = 265 = X 1 0 9 . (2) 11010 (base 7) = 2751 = 5277 (base 8). (3) 61436 (base 7) = 35174 (base 8).
(4) 666 (base 7) = 342, since 666 in base 7 is the same as 7 3 1, or 343 1.
2.4.7. 757 (base 10), 531 (base 12).
2.4.8. (1) 2F3 (base 25) = 1628. (2) 61436 (base 8) = 25374. (3) X DEFACE = 14613198. (4) 999 = X 3 E7 .
2.4.9. Whatever base is convenient; base A is most natural; occasionally it is simpler to use decimal arithmetic.
2.4.10. (1) 526 = X10E . (2) B11010 = 42 (base 5). (3) 61436 (base 8) = 25374. (5) 666 = 1641 (base 7).
2.4.11. 10, 11, 12, 13, 20, 22, 1000, 00000000 (or eight marks of some sort; the only reason to write zeros is because
the numeric digit available in base 1 is zero).
2.4.12. One base must be a power of the other. (This doesnt necessarily mean it will be easy!)
2.4.13. The values are 11, 12, 13, 14, 15, 16, 17, 20, 22, 24, 31, 100, and 121. (You may have seen this sequence as a
puzzle question What is the next number in this series?)
2.4.14. 435 7 = 222 10 , and 64 7 = 4 6 10 . Their sum in base 7 is 532, or 268 in decimal. Their base-7 product is 41526,
or 10212 in decimal.
2.4.15. The base-3 * values are respectively 2, 20, 101, 121, 1001, 1112, 10200, and 10212.
Section 2.6
2.6.1.
1. X DEADBEEF = 3735928559
2. X FFFFFFFF = 4294967295
3. X DEC0DED1 = 3737181905
Section 2.7
2.7.1. The quotients and remainders for each division step are:
1.
2.
3.
4.
5.

X B675 , X 3 ;
X C29 , X E ;
X CF , X 8 ;
X D , X C ;
X 0 , X D .

The converted value of X AB0DE is DC8E3 (base 15).


2.7.2. (a) 0729, (b) 9271, (c) 9999, (d) 9999 (not valid), (e) 5000, (f) 5000 (not valid), (g) 0001 (not valid). Valid values
in the 4-digit tens-complement representation must lie between 5000 (the maximum negative number) and + 4999 (the
maximum positive number).
2.7.3. 211 + 1, or 2047.
2.7.4. 2(n 1) + 1.
2.7.5. The three values are

Mathematicians joke: There are three types of people: those who can count, and those who cant.
Suggested Solutions to Selected Exercises and Programming Problems

1051

1. X DEADBEEF = 559038737
2. X FFFFFFFF = 1
3. X DEC0DED1 = 557785391
Section 2.8
2.8.1. Because it was chosen that way. It would be awkward to use a representation in which the process of converting
a positive number to negative was different from the process for converting from negative to positive.
2.8.2. (See Exercise 2.4.4 also)
1.
2.
3.
4.
5.

X0257
X 7 FFA
X8008
X E000
X FFFA

=
=
=
=
=

599
32762
32760
8192
6

2.8.3. The twos complement of the binary representation of a number X is the twos complement binary representation
of the number X, unless X is the negative number of greatest representable magnitude.
2.8.4. In decimal, c(A) = + 32064, c(B) = 12288, c(C) = + 5538, c(D) = 32758.
2.8.5. The variables, their decimal values, and their 9-bit representations for both positive and negative values, are
shown below. N.R. means the value cannot be represented.
Z
A
B
C
D
E
F

0
1
9
62
101
255
256

Positive
B000000000
B000000001
B000001001
B000111110
B001100101
B011111111
N.R.

Negative
N.R.
B111111111
B111110111
B111000010
B110011011
B100000001
B100000000

2.8.6.
1.
2.
3.
4.
5.
6.
7.

+ 10 X0000000A , 1 0 = X FFFFFFF6
+ 729 = X000002D9 , 729 = X FFFFFD27
+ 10 6 = 1000000 = X000F4240 , 1000000 = X FFF0BDC0
+ 10 9 = 1000000000 = X 3 B9BCA00 , 1000000000 = X C4643600
+ 2147483648 = 2 31 is not representable, 231 = X80000000
+ 65535 = 2 16 1 = X0000FFFF , 65535 = X FFFF0001
+ 2147483647 = 2 31 1 = X 7 FFFFFFF , (231 1 ) = X80000001

2.8.7. The two processes give the same bit patterns. The only case where you might consider them different is in complementing the maximum negative number: our recipe would indicate an overflow in the second step (when we add a
low-order 1 bit), whereas the suggested method would indicate an overflow in the first (subtraction) step. If subtraction
plus complementation is thought of as a single operation, then the two procedures are the same.
2.8.8.
1. + 13055 = X32FF
2. 9582 = X DA92 (twos complement of X256E )
2.8.9.
1.
2.
3.
4.
5.
6.

+5
97
+ 65795
16777158
+ 16777219
78606

=
=
=
=
=
=

X00000005
X FFFFFF9F
X00010103
X FF00003A
X01000003
X FFFECCF2

2.8.10. The values are:


1.
2.
3.
4.

1052

X B00F
X FFF1
X 0 FFF
X F001

=
=
=
=

-20465
-15
+4095
-4095

Assembler Language Programming for IBM z System Servers

Version 1.00

Section 2.9
2.9.1.
1.
2.
3.
4.
5.

X00000257
X00007FFF
X FFFF8008
X FFFFE000
X FFFFFFFA

=
=
=
=
=

B0000
B0000
B1111
B1111
B1111

0000
0000
1111
1111
1111

0000
0000
1111
1111
1111

0000
0000
1111
1111
1111

0000
0111
1000
1110
1111

0010
1111
0000
0000
1111

0101
1111
0000
0000
1111

0111
1111
1000
0000
1010

Section 2.10
2.10.1. No. Overflow must be detected using binary arithmetic. Since the four high-order bits are B1111, their sum is
B 1 1110 , so the carries into and out of the high-order bit positions agree.
Section 2.11
2.11.1.
1.
2.
3.
4.
5.
6.

10 ( 10) = X0000000A X FFFFFFF6 = X00000014 (no overflow, no carry);


729 65535 = X000002D9 X0000FFFF = X FFFEFD28 (no overflow, carry);
2147483647 + 2 = X 7 FFFFFFF + X00000002 = X80000001 (overflow, no carry);
10 9 + ( (231 1)) = X 3 B9BCA00 + X80000001 = X BB9BCA01 (no overflow, no carry);
0 ( + 0 ) = X00000000 X00000000 = X00000000 (no overflow, carry);
( 10) + 1 0 = X FFFFFFF6 + X0000000A = X00000000 (no overflow, carry).

2.11.2. C(X) = X679E , no overflow; C(Y) = X500A , overflow; C(Z) = X FD4A , no overflow.
2.11.3. The procedure is correct. Consider these examples, using 4-bit signed binary numbers.
Number
0000
0001
0111
1111
1000

Step 1
1111
0000
0111
1111
1111

Step 2
1111
0000
0110
1110
0111

0 1
1 0
7 6
1 2
8 +7 (with overflow)

2.11.5.
1.
2.
3.
4.
5.
6.

X 7 D26F071 + X B40E99A4
X 7 D26F071 -X B40E99A4
X FFFFF39A + X FFFE4B06
X FFFFF39A -X FFFE4B06
X80000003+X0000007C
X80000003+X8000007C

=
=
=
=
=
=

X31358A15 ,
carry, no overflow
X C91856CD , no carry,
overflow
X FFFE3EA0 ,
carry, no overflow
X0001A894 ,
carry, no overflow
X8000007F , no carry, no overflow
X0000007F ,
carry,
overflow

Section 2.12
2.12.1. In a 9 bit hexadecimal representation,
(a) A + C = X001 + X 03E = X03F (no carry, no overflow);
(b) D E = X 0 6 5 X 0 FF = X 1 6 6 (no carry, no overflow);
(c) Z + ( F ) = X 0 0 0 +X 1 0 0 = X 1 0 0 (no carry, no overflow);
(d) ( E) C = X 1 0 1 X03E = X 0 C3 (carry, overflow);
(e) ( B) + A = X 1 F7 +X 0 0 1 = X 1 F8 (no carry, no overflow);
(f) C Z = X03E X 0 0 0 = X03E (carry, no overflow);
(g) A + ( A ) = X 0 0 1 +X 1 FF = X 0 0 0 (carry, no overflow).
Section 2.13
2.13.1. Consider subtracting X80000000 from zero. If we assume that the twos complement of X80000000 is added
to the first operand (zero), then no carries occur out of the two high-order bit positions, and no overflow condition is
detected. If we add the ones complement of the second operand and a low-order 1-bit to the first operand, the two
carries will differ and the overflow will be correctly detected. Any overflow that occurs in forming the twos complement of the second operand will be lost prior to adding if we believe the incorrect description. Similarly, suppose we
subtract zero from anything. If we add the twos complement of zero, no carry occurs, but if we add its ones comple-

Suggested Solutions to Selected Exercises and Programming Problems

1053

ment and a low-order 1-bit, a carry always occurs. Thus our rule describes both the carry and overflow cases
correctly.*
Section 2.14
2.14.1. The decimal values, and their corresponding logical and arithmetic representations (written as 11-bit
hexadecimal numbers), are as follows; N.R. means that no valid representation exists to the given accuracy.
(a)
200
(b) 1023
(c) -1000
(d) 2047
(e)
-1
(f) -1024
(g) -1023
(h) 1024
(i)
-0

Positive
X 0 C8
X 3 FF
N.R.
X 7 FF
N.R.
N.R.
N.R.
X400
N.R.

Negative
X 0 C8
X 3 FF
X 4 1 8
N.R.
X 7 FF
X 4 0 0
X 4 0 1
N.R.
N.R.

2.14.2. The following table shows the results, where the abbreviations C means Carry, NC means No Carry,
O means Overflow, and NO means No Overflow.
+
A

A
11110
C, NO

B
00001
C, NO
00100
NC, NO

C
01111
C, O
10010
NC, NO
00000
C, O

D
01110
C, NO
10001
NC, O
11111
NC, NO

11110
NC, O

2.14.3. Using the same abbreviations as in the previous exercise, the results will look like this (the values in the first row
are A A, B A, C A, D A):
A
B
C
D

A
00000
C, NO
11101
C, NO

B
00011
NC, NO
00000
C, NO

C
10001
NC, NO
01110
C, O

D
10000
NC, O
01101
C, NO

01111
C, NO
10000
C, NO

10010
NC, O
10011
NC, NO

00000
C, NO
00001
C, O

11111
NC, O
00000
C, NO

Section 2.15
2.15.1. (a) 0028, (b) 9951, (c) 0527, (d) 9667, (e) 8766, (f) 2469.
2.15.2.
(a) 0028
+9951
9979 = 21

(b) 0527
+9667
0194

(c) 8766
+2469
1235

These calculations were simpler because no intermediate complementations were required.


2.15.3. (a) 0028, (b) 9950, (c) 0527, (d) 9666, (e) 8765, (f) 2469.

The error wasnt corrected until the 8th edition!

1054

Assembler Language Programming for IBM z System Servers

Version 1.00

Section 3 Solutions
Section 3.1
3.1.1. Because X30A6 X 2 EC9 = X 1 DD , the area contains X 1 DE or 478 bytes. Because you must consider
boundary alignments for half-, full-, and doublewords, some bytes on either end cant be used. Thus, the area can
contain 238 halfwords, 118 words, and 58 doublewords. (Try the same exercise with the ending address at X30A7 ,
and note the differences.)
3.1.2. No. The smallest addressable entity in memory is a byte. The bits within a byte are not individually addressable.
3.1.3. The area contains X 1 7 = 23 complete bytes, plus 3 bits at X 1 A023 plus 2 bits at X 1 A03B , giving 8*23+3+2
= 189 bits in all.
3.1.4. (1) halfword; (2) none; (3) halfword, word, and doubleword; (4) halfword and word.
3.1.5. (1) 131,072; (2) 32,768; (3) 2,097,152.
3.1.6. 322 in octal, and D2 in hex.
3.1.7. Let x mean either a 0-bit or a 1-bit. Then these bit patterns of the rightmost hex digit mean the indicated
alignments:
0000
x000
xx00
xxx0
xxx1

quadword
doubleword
word
halfword
byte

Section 3.3
3.3.1. No (GR7 and GR8 are not part of an even-odd pair); no (for the same reason); yes.
3.3.2. Sixteen. Actually, depending on the instructions used to load data from memory into the general registers, the
number can vary from 1 to 16. (Prior to z System, each general register contained only four bytes, so a pair contained
eight.)
Section 3.4
3.4.1. Only one: the right half of the register is ignored for 32-bit operands.
3.4.2. Probably so that the Floating-Point Feature could be omitted if the customer didnt want it.* In many programs,
the amount of arithmetic involving exchanges of data between the general and Floating-Point registers is small, so that
little would be gained by using a single register set for both types of operands. For other more complex programs,
however, this capability is extremely valuable.
One useful aspect of such a shared-register arrangement is that the programmer can decide the most efficient use of the
registers by his program; he can allocate as many or as few to floating-point operands as he feels are needed.

Or, as one cynic put it, so IBM could charge more for a processor with a full instruction set.
Suggested Solutions to Selected Exercises and Programming Problems

1055

Section 4 Solutions
Section 4.1
4.1.1. You can do this if each instruction contains the address of its successor. This technique was used on the IBM
650, but it also meant that instructions had to be longer, to hold both the operand memory address and the successor
instruction address.
Section 4.2
4.2.1. No, only on a halfword boundary. It is possible to require a word alignment in memory for the operand referred
to by the instruction, but not for the instruction itself.
4.2.2. Two bytes.
4.2.3. Because (1) each instruction is an integral number of halfwords in length, and (2) can start on any halfword
boundary.
4.2.4. Yes. A word or doubleword boundary is also a halfword boundary.
4.2.5. Theres no way to tell the difference.
Section 4.3
4.3.1. No, because the first two bits of the operation code uniquely determine the length of the instruction.
4.3.2. Twenty-four (decimal) bytes. The instructions are 2, 4, 4, 4, 6, and 4 bytes long. (Types are RR, RX, RS, RX,
SS, RX.)
4.3.3. In binary, the values are 01, 10, 10, 10, 11, 10.
4.3.4. 2 ((sum of first two opcode bits)+1) bytes.
4.3.5. The table entries could look something like this:
00
01
10
11

RR
RX
RS,SI
SS

2
4
4
6

01
10
10
11

0
1
1
2

(But you could also study Table 10!)


4.3.6. There are seven instructions, of lengths 4, 2, 4, 6, 2, 4, and 2 bytes respectively. The types are RS, RR, RX, SS,
RR, RX, and RR.
4.3.7. In most cases, you can find the required address by subtracting twice the ILC (the number of halfwords in the
previous instruction) from the IA in the PSW.
4.3.8. The z System CPU will fetch whatever bytes are in the gaps, and try to decode them as instructions. There is no
escape.
(You can cheat by using a branch instruction to jump over each gap, but then your program would be much larger
than necessary. Some early computers handled this problem by having each instruction contain the address of its successor, but those programs were also bigger. See Exercise 4.1.1 above.)
Section 4.4
4.4.1. (1) the RR-type instruction has opcode X 0 5 . (2) the RX-type instruction has opcode X 5 8 . (3) the RS-type
instruction has opcode X 8 9 . (4) the RX-type instruction has opcode X 5 A . (5) the SS-type instruction has opcode
X D2 . (6) the RX-type instruction has opcode X 5 0 .
Section 4.6
4.6.1. The Instruction Address in the PSW is odd, which violates the requirement that all instructions begin at a
halfword boundary.
4.6.2. Because the New PSWs Instruction Address is odd, the attempt to fetch the first instruction at memory location
X A237 would cause another program interruption. The current PSW stored at the old PSW area would be the one
shown, overlaying the old PSW that described the original error. The CPU would then stay in a program interruption loop until the processor was reset (which other executing programs would consider very unfriendly).

1056

Assembler Language Programming for IBM z System Servers

Version 1.00

4.6.3. The causes of the Interruption Codes are:


1. 0001: an invalid instruction code that cant be executed by the CPU.
2. 0009: your program tried to divide two binary numbers; either the divisor is zero, or the quotient is too large to be
represented in a single general register.
3. 000C: the product of two hexadecimal floating-point numbers is too large to be correctly represented.

Suggested Solutions to Selected Exercises and Programming Problems

1057

Section 5 Solutions
(All answers are in hexadecimal unless otherwise indicated.)
Section 5.1
5.1.1. Yes, and dont forget it! (You can of course put an addressing halfword somewhere not on a halfword
boundary, but then it cant be part of an executable instruction.)
5.1.2. Sixteen and fifteen.
Section 5.2
5.2.1. (1) X 1 AAF10 , (2) X02AF0C , (3) X000FB0 .
5.2.2. (1) X02B00F , (2) X000FC8 , (3) X 1 ABD48 .
Section 5.3
5.3.2. If the instruction type is RX, then the fourth digit of the instruction is an index digit; if it is not zero, an indexing
cycle is needed.
5.3.3. For RR instructions, none; for RX, two (the base and index registers); for RS and SI, one; for SS, two (one for
each operand).
5.3.4. If the instruction is type RR, or if the CPU needs repair.
Section 5.4
5.4.1. Register zero is never used as a base or index register. In all other respects, however, GR0 is a perfectly normal
and well-behaved general register. (Later, well see instructions that use GR0 to hold addresses.)
5.4.2. (1) X 1 AAF10 , (2) X02AF0C , (3) X000323, (4) X 8 AADD2 , (5) X000166, (6) X000FB0 . It is important to
distinguish the RX and the RS-SI instructions.
5.4.3. (1) X0710FC (the carry is lost!), (2) X0903AA , (3) X000000, (4) X00006C , (5) X000044, (6) X090518, (7)
X071F49 .
5.4.4. X FF0503 (RX instruction with base=0 and index=4, and for this particular instruction the operand could be
misaligned); (2) X31C000 ; (3) X 2 B4FFE (RX instruction with base=7, index=15).
Section 5.5
5.5.1. (1) X 1 BAD , (2) X 3 A55 or X 0 A4D , (3) not addressable, (4) not addressable, (5) not addressable.
5.5.2. It is most important to remember that addressability depends on the contents of the general registers. The fact
that a byte has an address does not mean it is addressable; it is possible that it is inaccessible to the program. (1) not
addressable (R0 cant be used as a base register); (2) X F000 ; (3) not addressable; (4) not addressable (R1 would
require a displacement of 1002, and GR11 would require 1); (5) X C3FC ; (6) X 5 FC3 ; (7) not addressable; (8)
X8921 or X BFE6 (the Assembler has a problem deciding, too); (9) not addressable; (10) X5000.
5.5.3. (See the note in the solutions to Exercise 5.5.2 also.) We will write the index digit and addressing halfword as
five hex digits in the form xbddd. (1) 010A20 is not addressable; (2) FFFFFF is addressable by 0F000, F0000, FF001,
EF000, FE000; (3) 6A0054 is not addressable; (4) 31AB7E is addressable by FB000, BF000, 19FF2, 91FF2, 1C1CA,
C11CA; (5) 001234 is addressable by 0C3FC, C03FC, FC3FD, CF3FD, 9C3EC, C93EC, EC3FC, CE3FC; (6)
07D3C4 is addressable by 05F03, 50F03, E5F03, 5EF03, F5F04, 5FF04, 5C0CC, C50CC, 95EF3, 59EF3; (7) 00A004
is addressable by DD004; (8) 31BB65 is addressable by 08921, 80921, E8921, 8E921, 98911, 89911, 0BFE6, B0FE6,
BEFE6, EBFE6, 9BFD6, B9FD6, F8920, 8F920, FBFE7, BFFE7; (9) 9ABCDE is not addressable; (10) 07C401 is
addressable by 05000, 50000, E5000, 5E000, F5001, 5F001.
5.5.4. The possible hex values are 0EEB, 3EEC, 6FEB, 7EEB, 8EEB, ..., FEEB (12 solutions); (2) no solutions; (3)
2F04.
5.5.5. We write the index digit and addressing halfword in the form xbddd. Then (1) 02ABCD may be addressed by
01BAD, 10BAD, 31BB5, 13BB5; (2) 000A4D may be addressed by 00A4D, 03A55, 30A55, 33A5D; (3-5) all of
001139, 88888E, and 02A010 are not addressable.

1058

Assembler Language Programming for IBM z System Servers

Version 1.00

5.5.6. Even though the base register specification digit would be zero in each addressing halfword, GR0 would still not
be used (or usable) as a base register!
5.5.7. (1) X31C161 , X07CBC5; (2) X005CFF , X 2 B42A3; (3) X023B43 , X000050; (4) X000E4E , X000E4E .
Section 5.6
5.6.1. Because 15 registers are available for addressing purposes, there is considerably less need to use addresses in
memory to locate an operand; the added cost of accessing memory is also avoided. An additional bit would also be
required in all instructions for which indirection was allowed. In some processors allowing indirect addressing, it is
possible to put the CPU into a loop by having two instructions in an indirect-address chain refer to one another.

Suggested Solutions to Selected Exercises and Programming Problems

1059

Section 6 Solutions
Section 6.2
6.2.1. The default rule is that columns 1 to 15 must be blank. It is a common practice to group comments into blocks
of descriptive statements, all of which have an asterisk in column 1. If one of those statements has a nonblank character in column 72, the following record will not be blank in columns 1 to 15, as required.
Section 6.3
6.3.1. The statement will be read by the Assembler during assembly time, when it will be translated into a machine
language instruction in the object module. This will be linked into the load module; after the load module has been
placed in memory at the start of execution time, the CPU can fetch, decode, and execute the instruction.
6.3.2. The choice is up to you; any column at least one space past the operand field is acceptable.
6.3.3. Any column except 1. It should not extend into column 72!
6.3.4. The operation field is always required.
6.3.5. Comment statements have no operation field entry; some Assembler instructions (such as SPACE, EJECT,
START, ORG, CSECT, etc.) require no operand field entry; any statement may be written without a remarks field.
6.3.6. Because column 1 is blank, the operation field entry is LOAD; the operand field entry is therefore LR; the rest of
the statement is comments!
6.3.7. (a) Only comment statements; (b) All non-comment statements.
Section 6.5
6.5.2. The END statement is only an indication to the Assembler that the source module is complete, and it is not any
part of the executing program. If you understand the phrase control reaches the END statement to mean that the
CPU attempts to execute instructions outside the bounds of the program, an error is likely to cause the end (termination) of program execution. Theres no way to know how the CPU will interpret whatever bit patterns it may then
stumble into.
6.5.3. Lines 4 and 10 have name-field entries; all but line 6 have operation field entries, operand field entries, and
comment field entries.

Programming Problem 6.1.


Here is the Assemblers listing of my program:
Loc

Object Code

000000

Addr1 Addr2
00000 00038

000000 0DF0
R:F 00002
000002 90EF F00A
0000C
00002A D196889540D94B40
000000

Stmt

Source Statement

1 Test
2
3 *
4
5
6
436 MyName
437

Start 0
First line of program
Print NoGen
Sample Program
BASR 15,0
Establish a base register
Using *,15
Inform the assembler
PRINTOUT MyName,* Print name and stop
DC
C John R. Ehrman
Define constant with name
END
Test
Last statement

When the program was executed, it produced this printed output;


*** PRINTOUT REQUESTED AT LOCATION 021002, CC=1
MyName
= John R. Ehrman
*** EXECUTION TERMINATED BY PRINTOUT * AT LOCATION 021002

1060

Assembler Language Programming for IBM z System Servers

Version 1.00

Line
Line
Line
Line
Line
Line
Line
Line

4
5
6
7
8
9
10
11

Section 7 Solutions
Section 7.1
7.1.1. (1) 12345 = X3039; (2) X15555; (3) X B4DAD ; (4) too long (9 significant digits); (5) the + sign is not valid on a
self-defining term; (6) X 3 C3C3D ; (7) too long (33 significant bits).
Section 7.2
7.2.1. (1) X007B7C5B ; (2) incorrectly paired apostrophes; (3) X40C140C2 ;
(4) X00D9E4C4 ; (5) X0000F1F2 ; (6) too long (five characters).
7.2.2. The values are (1) X 5 0 (the ampersands are paired), (2) X F7F5 , (3) X 7 D (the apostrophes are paired), (4)
X C37D , (5) X F0 , (6) X E2C4E3 .
7.2.3. This table shows the ASCII encodings for the same characters shown in Table 13 on page 89. (Here, they are
not in order of increasing encoding values.)
Table 442. ASCII Character Representation. (((alntb7b)))
Char

Hex

Char

Hex

Char

Hex

Char

Hex

Blank
&
#
a
e
i
m
q
u
y
C
G
K
O
S
W
0
4
8

20
26
2D
23
61
65
69
6D
71
75
79
43
47
4B
4F
53
57
30
34
38

.
$
/
@
b
f
j
n
r
v
z
D
H
L
P
T
X
1
5
9

2E
24
2F
40
62
66
6A
6E
72
76
7A
44
48
4C
50
54
58
31
35
39

(
*
,

c
g
k
o
s
w
A
E
I
M
Q
U
Y
2
6

28
2A
2C
27
63
67
6B
6F
73
77
41
45
49
4D
51
55
59
32
36

+
)
_
=
d
h
l
p
t
x
B
F
J
N
R
V
Z
3
7

2B
29
5F
3D
64
68
6C
70
74
78
42
46
4A
4E
52
56
5A
33
37

7.2.4. (1) X 7 D7D7D , (2) X 3 E8 , (3) X 8 , (4) X507D50 , (5) X 6 B , (6) X C17EC2 .
7.2.5.
(1)
(2)
(3)
(4)
(5)
(6)

64 = X 4 0 = B01000000= C (in our notation, C)


245 = X F5 = B11110101= C 5
80 = X 5 0 = B01010000 = C &&
16476 = X405C . = B0100000001011100 = C * (in our notation, C*)
101058055 = X F9F9F9F9 = B11111001111110011111100111111001 = C 9999
12966353 = X C5D9D1 = B110001011101100111010001 = C ERJ

7.2.6. The bits 11010010 are the EBCDIC representation of the capital letter K.
7.2.7. The terms and their values are:
(a)
(b)
(c)
(d)

B110010110000010111010110
C A&&B
54721
X B00B00

=
=
=
=

X00CB05D6
X00C150C2
X0000D5C1
X00B00B00

Suggested Solutions to Selected Exercises and Programming Problems

1061

7.2.8. The respective values are:


1.
2.
3.
4.

X D1C5
53701
11835
C JE

7.2.9. The values are:


1. B110010111000010111011001 =
2. C R&&Z
=
3. 51401
=

X CB85D6
X D950E9
X C8C9

7.2.10. (a) B01110101100010 = X 1 D62 , (b) C + = X 7 D4E , (c) 10010 = X271A


Section 7.3
7.3.1. Symbols (1), (3), (4), and (9) are valid. The second is invalid if you think of it as a single symbol because the
blank is not allowed, but Captain and Major are valid symbols. The other invalid symbols are (5) (exclamation point is
not allowed, to say nothing of the language), (6) (starts with a digit), (7) (naturally), (8) (parentheses are not allowed).
7.3.2. Consider the symbol 1234567J. The Assemblers term-scanning routine might be well on its way into converting what appeared to be a decimal self-defining term when the letter J appeared. This would require either backing
up, or necessitate multiple scans wherever a symbol could appear.
Section 7.5
7.5.1. All the symbols (EX7_5_1, BEGIN, DUMMY, N, and ONE) are relocatable. The LC values (and therefore the values
of the symbols) are as shown.
LC
5000
5000
5002
5006
500A
500E
5024
5028

Stmt
EX7_5_1
BEGIN

DUMMY
N
ONE

START
BASR
L
A
ST
DS
DC
DC

X5000
6,0
2,N
2,ONE
2,N
XL22
F 8
F 1

Section 7.6
7.6.1. You shouldnt need to check this answer!
7.6.2. The symbol TEN is three characters long.

1062

Assembler Language Programming for IBM z System Servers

Version 1.00

Section 8 Solutions
Section 8.2
8.2.1. The results are A+B, A-B, and A-B.
8.2.2. The expression has value 19.
8.2.3.
a.
b.
c.
d.
e.

A+-+-B
A*--B
A-*-B
A---B
--A-++B

Valid
Valid
Invalid
Valid
Valid

A+(-(+(-B)))
A*(-(-B))
A-(*(-B))
A-(-(-B))
-(-A(-(+(+B))))

-->
-->

A+B
A*B

-->
..)

A-B
A-B

Section 8.3
8.3.1. If none of these expressions is further combined with other expressions, then A R is invalid because the only
relocatable term is preceded by a sign. (If it was combined with another expression such as in (A R) + (A + R) the
result would be valid and absolute. (Its important to look at the whole expression!)
R + R is invalid because the sum will be complexly relocatable; all the expressions involving multiplication or division
with a relocatable term are always invalid; the remaining expressions are always valid.
8.3.2. If you think so, you may still be uncertain about the difference between the Assemblers computation of
expression values at assembly time, and the programs computation of whatever it likes at execution time. A program
can compute remainders, as we will see when we discuss the Divide instructions.
8.3.3. The two symbols may have different relocatability attributes. (We will meet such symbols when we discuss
external symbols and control sections.)
Section 8.4
8.4.1. 75, 32, and 2400 respectively.
8.4.2. R6 is the only absolute symbol, and it has value X000009 (a poor practice). The other symbols are relocatable;
their values are A (X000466), B (X00046C ), C (X000470),
X (X000474). The expressions, their values, and their relocatability attributes, are:
B+X 1 C
C-A+X-2*(R6/2)
2*C - -C A+2
B-2
R6-2

X000488
X000476
X000001
X00046A
X000007

relocatable
relocatable
absolute
relocatable
absolute

8.4.3. Expressions 1 and 6 are relocatable; the rest are absolute. They have values X10A99 , X FFFFE884 , X 7 , X 3 ,
X 8 D , and X12098 respectively.
8.4.4. Item 4 is invalid; if you look at it long enough you will see why. Expressions 1, 3, 5, 6, and 7 are valid.
Expressions 3 and 5 are syntactically valid, but the value overflows a word. Only the rightmost 32 bits would be
retained.
8.4.5. (1) X000F08 , absolute; (2) X172BE9 , relocatable; (3) X001BD8 , absolute;
(4) X000180, absolute; (5) X173ACC , relocatable.
8.4.6. Expressions 1 and 5 are invalid, because they contain products involving a relocatable expression. Except for
expression 4, the other expressions are all absolute, and have the following values: (2) X00558F ; (3) X0020A9 (if you
got X0020A8 , you forgot to do the multiplication before the division); (4) X00142D0A (relocatable); (6) X FFFFFFFE
(2 in decimal).
8.4.7. If we allowed relocatable terms in multiplications and divisions, it would no longer be possible to preserve the
simple additive relationship between the location value of an assembly-time expression and its address value at execution time. Handling such constructions would require that we pass enough information about the expression to the
Program Loader so that it could compute the correct value when the true address referred to by the symbol is known.
8.4.8.

Suggested Solutions to Selected Exercises and Programming Problems

1063

1. B-A
2. A+C .

Value=X F08 , absolute


Value=X172BE9 , relocatable

Section 8.5
8.5.1. (1) second; (2) first; (3) second; (4) second; (5) first; (6) third; (7) third; (8) third,
(9) second. All the operands are valid!

Programming Problem 8.1.


Many of the Length Attribute References I tried were invalid. The reasons are explained among the lines of the Assemblers listing.
Loc

Object Code

Addr1 Addr2

000000

Stmt

00000 00024
00000
001A9
000000 0000 0000
00000
** ASMA147E Symbol too long, or first
R:F

Source Statement

1 P8_1
2
3 ABS425
4
character

Start
Using
Equ
LA
not a

0
*,15
425
0,L 2
letter - 2

The Length Attribute of a self-defining term is undefined; if it had been written X 2 , the Assembler would produce a
different error message.
000004 4100 0001
00001
5
LA
0,L ABS425
** ASMA019W Length of EQUated symbol ABS425 undefined; default=1
The Length Attribute of the absolute symbol is undefined, so the Assembler tells us that it has assigned a default length
attribute, 1.
000008 4100 0004

00004

LA

0,L *

The Length Attribute of a Location Counter Reference is valid. The instruction is 4 bytes long, so thats the value of the
Length Attribute Reference.
00000C 0000 0000
00000
** ASMA028E Invalid displacement

LA

0,L *-10

The expression L *-10 is not addressable, because while L * has value 4, L *-10 has value 6. The Assembler could not
create a valid addressing halfword.
000010 0000 0000
00000
8
LA
0,L ( *-10)
** ASMA147E Symbol too long, or first character not a letter - (*-10)
The Length Attribute of a parenthesized expression is undefined.
000014 4100 0004

00004

LA

0,L = F 1 0

The Length Attribute of a literal is well defined.


000018 0000 0000
00000
10
LA
0,L L *
** ASMA150E Symbol has non-alphanumeric character or invalid delimiter - L *
The Length Attribute of a Length Attribute Reference is not allowed.
11
12

000020 0000000A

End

P8_1
=F 1 0

Programming Problem 8.2.


Loc

Object Code

Addr1 Addr2

Stmt

Source Statement

00005
1 A
Equ
5
00003
2 B
Equ
3
00003
3 C1
Equ
L A*B
** ASMA019W Length of EQUated symbol A undefined; default=1
00005
4 C2
Equ
A*L B
** ASMA019W Length of EQUated symbol B undefined; default=1
The Length Attribute of the symbols A and B is undefined, so the Assembler tells us that it has assigned a default length
attribute, 1.

1064

Assembler Language Programming for IBM z System Servers

Version 1.00

5 C3
Equ
L ( A*B)
** ASMA147E Symbol too long, or first character not a letter - (A*B)
** ASMA158E Operand expression is defective; set to *
A Length Attribute Reference to an expression is undefined. In this case, the Assembler tells us that it has assigned a
default value, the Length Attribute of the current Location Counter.

Suggested Solutions to Selected Exercises and Programming Problems

1065

Section 9 Solutions
Section 9.2
9.2.1. The values of the expressions are (a) 0, (b) 13, (c) 17, (d) 15, and (e) 16. This means that (c) and (e) are invalid.
9.2.2. Only (a) is valid; (e) is even, but too large.
Section 9.5
9.5.1. The operand D 2(X 2,B2) is of the form expr(expr,expr); D2(,B2) is of the form expr(,expr); S2(X 2) is of the form
expr(expr); S2 is of the form expr.
9.5.2. (1) implied, no indexing; (2) implied, with indexing; (3) implied, with indexing; (4) explicit, with indexing; (5)
implied, with indexing; (6) explicit, no indexing.
9.5.3. (1) implied (invalid if A and B are both relocatable); (2) implied (invalid if both A and B are relocatable); (3)
implied, with indexing (but invalid, since C ) has value greater than 15); (4) implied, with indexing (but invalid, since
C , C exceeds 15); (5) implied; (6) explicit, with indexing (but invalid, since the X2 and B 2 expressions are both too
large); (7) explicit, with an index expression); (8) explicit, no indexing.
Section 9.7
9.7.1. The implied addresses are S1 and S 2.
(a)
(b)
(c)
(d)
(e)
(f)

Can
Can
Can
Can
Can
Can

be
be
be
be
be
be

only SI: 1=D 1, 2 = B 1, 3 = I 2.


only RS-1: 4=R 1, 5 = D 2, 6 = B 2.
only RS-2: 7=R 1, 8 = R 3, 9 = S 2.
either RS-1: 10=R 1, 11=S 2; or SI: 10=S 1, 1 1 = I 2.
only RS-1: 14=R 1, 1 5 = D 2, but 16 is not a valid value for B2.
only SI: 100=S 1, 101=I 2.

Section 9.9
9.9.1. In the following table, the headings SS-1 and SS-2 refer to the two SS-type instruction formats.
(a)
(b)
(c)
(d)
(e)
(f)

Operand
1(2)
4(5,6)
A(L B)
Line
Line(80)
XX(,5)

SS-1 Format
S1(N 1) or D 2(B2)
D 1(N 1,B1)
S1(N 1) or D 2(B2)
S1, S2
S1(N 1)
D 1(,B1)

Length
explicit
explicit
explicit
implicit
explicit
implicit

SS-2 Format
S1(N 1) or S2(N 2)
D 1(N 1,B1) or D 2(N 2,B2)
S1(N 1), D 2(B2), S2(N 2) or D 2(B2)
S1, S2
Invalid!
D 1(,B1) or D 2(,B2)

Length
explicit
explicit
explicit
implicit
implicit

Note:
(c) The form D(B) is valid only if A is absolute and L B is between 0 and 15; but it is very unlikely anyone would
specify B2 that way!
(e) 80 cannot be either a length or a base register for an SS-2-type instruction.
(f) The symbol XX must be absolute.

1066

Assembler Language Programming for IBM z System Servers

Version 1.00

Section 10 Solutions
Section 10.5
10.5.1. The two statements are in reversed order. The value of the LC before the BASR is encountered may be 2 (or
even 3) less than the value of the LC after the BASR has been assembled. Thus the value placed in the USING Table
by the Assembler will cause it to calculate displacements that are 2 (or 3) bytes too large. This will undoubtedly lead to
incorrect operand addresses when the program is executed.
Stated differently: the value of the USING base_location (at assembly time) relative to the start of the program will not
be the same as the base address (at execution time), relative to the start of the program.
Section 10.6
10.6.1. If by chance the contents of the word at N had been the decimal integer 20450=X 4 FE2 instead of 8, then the
Effective Address of the A instruction would be X 4 FE2 + X 2 6 = X5008, a perfectly acceptable memory address for a
word (and, besides, its somewhere inside our program!). The subsequent instructions would have proceeded blindly,
adding the contents of the word at memory location X5008 (portions of the A and ST instructions!) to the unknown
contents of register 2, and storing the result at location X5004.
Following execution of the ST instruction, the first portion of the program segment would then contain
0D60 5860 xxxx xxxx 6026 5020 6022 ...
where xxxx xxxx is whatever sum resulted in register 2. The constants named N and ONE would be unchanged.
Section 10.7
10.7.1. The object code should be
0DA0
41D0A12A
4110A172
450EA19E
500FA176
10.8.1. The object code should be
5830B064
4A30B060
1043
9034B058
4240B056
4770B02A
Section 10.10
10.10.1. The statements are syntactically valid. However, the DROP statement should refer to the number of a general
register, which must be between 0 and 15. The resulting diagnostic will likely say something about an invalid register
number.
10.10.2. Following the first USING, the USING Table contains

basereg base location RA

00004002
01

Following the second USING, the new entry in the USING Table will be

basereg base location RA

00004008
01

The DROP 9 eliminates the first entry, and the DROP 10 eliminates the second. The generated code is as follows:

Suggested Solutions to Selected Exercises and Programming Problems

1067

Loc

Stmt

4000
4002
4002
4006
4008
4008
400C
400C
4010
4010

BASR
USING
L
BASR
USING
L
DROP
L
DROP
L

Generated Code
9,0
*,9
4,*+54
10,0
*,10
3,*+52
9
2,*+48
10
1,10(,9)

0590
none
58409036
05A0
none
5830A034
none
5820A034
none
5810900A

(GPR 10 has a smaller displacement)

Because register 9 was unchanged when the last instruction was executed, it can still be used by the CPU to calculate
effective addresses. Thus, the word at X400C will be loaded into register 1; its contents will therefore be X5820A034 .
The result does not depend on where the instructions were loaded into memory.
Section 10.11
10.11.1. The symbol at B is not addressable by the L instruction, because a displacement 2 would be required. Execution would probably fail with a program interruption for an invalid operation code.
Section 10.12
10.12.1. This is generally desirable; an implied address such as X 356 in a statement should lead to an effective
address of the same value. If the Assembler did not automatically supply a zero base digit, we would have to write
machine instruction operands in the form X 356 (0,0) or XX 356 (0) which is less convenient, although it is more
explicit.

Programming Problem 10.1


Here is a source program:
P10_1

BEGIN

N
ONE

TITLE SOLUTION TO PROBLEM 10.1


START
X5000
BASR
6,0
USING
BEGIN,6
L
2,N
A
2,ONE
ST
2,N
DS
22X
DC
F 8
DC
F 1
END
P10_1

The assembly listing looks like this:


005000
005000 0D60

05000 0002C
R:6

005002
005006
00500A
00500E
005024
005028
005000

5820 6022
5A20 6026
5020 6022
00000008
00000001

05002
05024
05028
05024

2
3
4
5
6
7
8
9
10
11

P10_1

BEGIN

N
ONE

START
BASR
USING
L
A
ST
DS
DC
DC
END

X5000
6,0
BEGIN,6
2,N
2,ONE
2,N
22X
F 8
F 1
P10_1

The addressing halfwords of the instructions in statements 5, 6, and 7 are the same as those we calculated by hand.

1068

Assembler Language Programming for IBM z System Servers

Version 1.00

Section 11 Solutions
Section 11.1
11.1.1. Because z System supports a wide variety of data types, it would be difficult to know what conversion should be
used to convert 8 to the correct internal representation. (Some assemblers use a different instruction mnemonic to
indicate the desired type of internal representation.)
Section 11.4
11.4.1. The generated constants are
(1)
(2)
(3)
(4)

X 8 1
X0080
X FFFF9D000063
X 7 F

11.4.2. The alignments are halfword, word, and byte respectively.


Section 11.6
11.6.1. He defined four word constants, having values 1, 0, 0, and 0. (The four generated words contain the value 2 96
as a 128-bit binary constant, which might be useful to someone doing 128-bit binary arithmetic.)
He could either rewrite the constant without the commas (and learn to count carefully), or use blanks, as in
TEN_to_9 DC

F1 000 000 000

The resulting constant is X 3B9ACA00 .


11.6.2. The generated constant is X00000001 FFFFFFFF 00000001 FFFFFFFF (where spaces have been inserted for
readability).
Section 11.8.
11.8.1. The four values are
(1)
(2)
(3)
(4)

F20000
F50000
FL220000
FL4 8 0

or
or
or
or

F 2 E4
F 5 E4
FL2 2 E4
FL4 8 E1

X00004E20
X0000C350
X2710
X00000050

Aligned
Aligned
Not aligned
Not aligned

11.8.2. Consider these two constants:


Ten_to_9 DC
Ten_to_9 DC

F 1 E9
FE9 1

11.8.3. The object code is X 5820F036, 5A20F03A, 5B20F03E, 5020F042 . The four missing LC values are
X 000038, 00003C, 000040, 000044 .

Suggested Solutions to Selected Exercises and Programming Problems

1069

Section 12 Solutions
Section 12.1
12.1.1. Try F 1 E9 .
12.1.2. The first constant will generate X 00000001 ; all the others generate zero.
12.1.3. The Assembler rounds the fraction part the bits lost at the right of the radix pointso the generated constant is
X 0001 . (If you use a scale or exponent modifier, you can create fixed-point binary constants with fractional parts.
Well see some examples later.)
12.1.4. The generated constant will be X 80000000 , with an Assembler error message saying the value is too large.
The operand is treated as a signed value, and exceeds 231 1 by 1.
12.1.5. The two binary integer constant words (named N and ONE) must be on a word boundary, so their addresses will
increase by 4 (not 2!) to X 5028 and X 502C .
12.1.6. The values are:
DC
DC
DC

F -2147483620
H -32594
F+2147483260

X8000001C
X80AE
X 7 FFFFE7C

Section 12.2
12.2.1. The values are X 0000017C , X 00000564 , and X 00000012 .
Section 12.3
12.3.1. The values are X 00C1 , X 0B5E , and X 002D .
12.3.2. S-constants 1, 3, 4, and 5 are valid, but S(A(N)) is not, since the displacement A is not absolute. Constants 1
and 5 depend on USING information, but normally there will be no USING statement that would affect S(N). In
S(N(7)), N must have a value between 0 and 4095, and in S(7(N)), N must have a value between 0 and 15.
Section 12.4
12.4.1. 33, 7, and 5 bytes respectively. (Did you peek at Section 12.5?)
12.4.2. Youd really be doing it the hard way this way. Since the implied length is 100 bytes, you must write between
793 and 800 binary digits. Assuming you write 54 per record (using the usual continuation rules), you would need 15
records, which could exceed the allowable maximum for your Assembler. There may be a better way.
12.4.3. You cant; think about it again. (In a character constant, a comma is part of the nominal value, not a separator.)
12.4.4. Two possible interpretations, and their Assembler Language defining statements, are:
DC
DC

F1077952604
C *

Word binary integers


Characters (three blanks and an asterisk)

Other interpretations are possible, as well see later.


12.4.5. The value of four blank characters interpreted as an integer is 1,077,952,576.
12.4.6. The generated constants are:
(1) X F1
(2) X001F
(3) X00123456
12.4.7. The generated constants are
1. X C17DC250C3
2. X 7 DC150C27D7DC3
3. X C1C2C3C67D
12.4.8. Just write

1070

Assembler Language Programming for IBM z System Servers

Version 1.00

EBCHex

DC

C0123456789ABCDEF

12.4.9. The generated constants for each symbol, and the differences, are:
Symbol
A
B

Generated Constant
X0000000000
X0000000000

Differences
Both constants generate the same data,
A and B have different length attributes.

C
D

X0707070707
X0000000007

Different data is generated, and


C and D have different length attributes.

E
F

X4040404040
X4040404040

Both constants generate the same data,


E and F have different length attributes.

G
H

X 5 C5C5C5C5C
X 5 C40404040

Different data is generated, and


G and H have different length attributes.

12.4.11. X F3F4F540 .
Section 12.5
12.5.1. The DC operand CL2ABC is truncated on the right, so the generated constant will be X C1C2 . In the
address constant, the value of the expression is X 00C1C2C3 , which will be truncated on the left, giving X C2C3 for
the generated constant.
12.5.2. The constants and their alignments are
(1)
(2)
(3)
(4)
(5)
(6)
(7)

F1000
H1000
B1000
XL11000
CL11000
AL1(1000)
YL3(1000)

X000003E8
X03E8
X 0 8
X 0 0
X F1
X E8
Length error

Word
Halfword
Byte
Byte (truncated)
Byte (truncated)
Byte (the last 8 bits of the term)

The constant AL1(1000) does not generate an error message!


12.5.3. The values are:
(1)
(2)
(3)
(4)

X00F1
X01E2
X001234
X2345

12.5.4. The constants that cannot be fit into smaller fields are X56789 and Y(X 1 2 4 ) .
Section 12.6
12.6.1. The generated constant is X 000005000002 .
12.6.2. The generated constant is X C2D3C1D5D25040 .
12.6.4. If the constant named Message starts on a word boundary, it will end one byte past a word boundary, so that
three bytes must be skipped to align the A-type constant named MsgLen. If it starts at a location one byte before a word
boundary, zero bytes must be skipped. Thus, anywhere between zero and three bytes will be skipped.
Section 12.8
12.8.1. The generated values are
(1)
(2)
(3)
(4)

X 4 E20
X0000C350
X2710
X00000050

aligned
aligned
not aligned
not aligned

by
by
by
by

default
default
default
default

Suggested Solutions to Selected Exercises and Programming Problems

1071

Section 13 Solutions
Section 13.1
13.1.1. Nothing is generated, since they are all DS statements. The length attribute of each symbol is 4, with the length
of Y being implied. The values of the symbols are X 12345 , X 1234C (note alignment), and X 12350 respectively.
Section 13.2
13.2.2. The solutions are shown in this table:
Sym
J
K
L
P
Q
R
T
V
W

Value
X 346
X 34C
X 350
X 345
X 348
X 350
X 345
X 348
X 350

LA
2
1
4
3
3
4
2
2
4

13.2.3. The values and Length Attributes are:


1. A

DC

F 2

A has value X 3 4 8 , Length Attr. = 4

2.
A

DS
DC
DC

0H
C *
C Asterisk

Value=X 3 4 7 , Length=8

DC
DC

0F 1
0XL27 0

Value=X 3 4 8 , Length=27

4. A

DC

A(A)

Value=X 3 4 8 , Length=4

5.
A

DS
DC

19H
X12345

Value=X36C , Length=3

DC
DC

3CL4 ABCDE
C A&&B

Value=X 3 5 1 , Length=3

DS
DC

CL400
F 1 2 , 3 4 , 5 6

Value=X 4 E0 , Length=4

3.

6.
7.

Section 13.3
13.3.1. The length attribute of a symbol is determined from the length attribute of the first term in the first-operand
expression. In this case, that term is the symbol Table, which has length attribute 4.
13.3.2. The result will be incorrect only if the length attribute of the symbol HW8 is expected to be 2. This is considered
a poor programming practice. It runs the risk that someone might change the constant named FW8 to some other value
with another name, and then the symbol HW8 could be undefined!
13.3.3. The first two definitions are equivalent, and the last two are equivalent (the parentheses have no effect other
than improving readability). The first two definitions, however, are incorrect: if the value of TblSiz is odd, the value
assigned to MidTbl will be aligned on a halfword boundary between two word boundaries, and attempts to refer to the
word at MidTbl would be erroneous.
13.3.4. (See your solution to Exercise 11.7.1 also.) The symbols A3 and A5 behave in exactly the same way as the
symbols they are equated to. Symbol A4 will not have the expected value, because the Assembler does not allow
literals as operands of EQU statements. (What advantages would there be to allowing literals as EQU operands?)
13.3.6. The definitions are circular, so the Assembler cant determine what should be done.
13.3.7. Both pairs are valid. (For some very old assemblers, the second pair would cause the symbol BAKER to be
undefined because its operand was not yet defined.)
13.3.8. All symbols are relocatable. The symbols, their values, and their length attributes, are:

1072

Assembler Language Programming for IBM z System Servers

Version 1.00

Symbol
ST
W
X

Value
01DBC5
01DBC8
01DBD0

Length
8
4
4

P
Q
R
S

01DBC8
01DBC8
01DBC8
01DBCC

4
2
1
1

13.3.9. You will remember from Section 8.3 that the assembler evaluates division by zero in an expression as zero.
First, we show how to break the calculation into four steps, using four auxiliary symbols K1, K2, K3, and K4.
K1
K2
K3
K4
MaxOfA_B

Equ
Equ
Equ
Equ
EQU

A/B
B/A
K1/K2
K2/K1
A*K3*(1-K4)+B*K4

0 if A < B, >
0 if B < A, >
0 if A < B,
0 if B < A,
Final result

0
0
1
1

otherwise
otherwise
otherwise
otherwise

The factor (1-K4) is needed in case A and B are equal. Then, we can write the full expression as follows:
MaxOfA_B EQU

((A/B)/(A/B))*A+(1-((A/B)/(A/B)))*((B/A)/(B/A))*B

Its not very pretty, but it works!


13.3.10. The values and Length Attributes are:
1. Value = X2924, Length attribute = 4
2. Value = X291B, Length attribute = 3
3. Value = X0009, Length attribute = 2
13.3.11. The symbols and their value and Length Attributes are:
1. A
B
C

DS
DS
DS

F
2H
2CL2

Value=X12348, Length=4
Value=X1234C , Length=2
Value=X12350, Length=2

2. F
G
H

DC
DC
DC

A(F)
3AL3(F,G,H)
Y(*-F,275)

Value=X12348, Length=4
Value=X1234C , Length=3
Value=X12368, Length=2

3. P
Q
R

DC
DC
DS

2C3&&
2A(C3&&)
3XL3 FEDCBA93

Value=X12345, Length=2
Value=X1234C , Length=4
Value=X12354, Length=3

4. X
Y
Z

DC
DC
DC

0FL5 5 , 1 0 , 2 0
FL3 5 , 1 0 , 2 0
2C 5 , 1 0 , 2 0

Value=X12345, Length=5
Value=X12345, Length=3
Value=X1234E , Length=7

13.3.12. The symbols and their generated data are:

F
G
H
P
Q
Y

X00012348
X012348 01234C 012368 ( repeated 2 more times!)
X00200113
X F350F350
X0000F3500000F350
X00000500000A000014

13.3.13. The symbols and their values and Length Attributes are:
1. STR
W
X

DS
DS
DS

0CL8
2F
2F

Value=X 1 DBC5 ,
Value=X 1 DBC8 ,
Value=X 1 DBD0 ,

Length=8
Length=4
Length=4

2. P
Q
R
S

DS
DS
DC
EQU

0F
0H
4X 4 0
*-P

Value=X 1 DBC8 ,
Value=X 1 DBC8 ,
Value=X 1 DBC8 ,
Value=X00004,

Length=4
Length=2
Length=1
Length=1

13.3.14. The values of the symbols, the length attributes, the data locations, the final LC value, and the assembled data
are given in hex. Underlined zeros indicate padding bytes inserted by the Assembler.

Suggested Solutions to Selected Exercises and Programming Problems

1073

Symbol
1.

Value

L.Att DataLoc LCval data

A
B

128
12C

4
2

128
12C

12E

000000FFFFFFEF
0021

D
C

125
12A

4
2

125
12A

12C

00000011
00FFDF

E
F

125
130

8
4

125
130

134

C1C2C3C4C5C6C7C8
000000000003E8

G
H

126
12C

2
4

12C

130

0000129E

J
K
L
M
N

126
126
128
128
128

2
1
4
6
4

128

12C

FFFFFC18

P
Q

125
130

3
4

125
130

138

C17DC2C17DC2C17DC2
000000C17DC200C17DC2

R
S

128
2B8

4
50

8.

AB

128

128

134

00000000000384 0080000002 000001

9.

BC
CD

125
12C

2
2

125
12C

130

00070007000701
3FFFC001

DE
EF

128
13C

4
4

11.

T
V
W

125
127
12B

2
2
8

125
127
12B

13B

0CAB
015C015C
C3C1C24040404040C3C1C24040404040

12.

Y
X

126
128

2
2

128

12C

00020002

Z
ZZ

125
128

2
4

125
128

130

E9E9
00000000030000000300000003

2.
3.
4.
5.

6.
7.

10.

13.

308

13C

13.3.15.
REven
ROdd

Equ
Equ

((N+1)/2)*2
REven+1

In case N is odd!
Next higher odd number

13.3.16. In the last three cases (11-13) at least one expression depends on the value of a symbol being defined by the
same statement that is using it. For many early assemblers this required making more complex decisions than could be
justified at that time. All 13 cases are successfully resolved by the High Level Assembler.
Section 13.4
13.4.1. The length and value attributes are:
Symbol
Cost
Desc
Fill
LFill
Pfx
Prod
Result

Length
8
60
29
1
24
12
133

Value
X2024
X202C
X2068
X201D
X2000
X2018
X2000

Section 13.5
13.5.1. This technique will work correctly so long as nothing is ever stored at either FW8 or HW8. Another way to get the
same result is to write
FW8
HW8

1074

DC
Equ

F 8
FW8+2,2

Define halfword, length attribute 2

Assembler Language Programming for IBM z System Servers

Version 1.00

13.5.2. The asterisk in column 1 indicates a comment, not the value of the LC! The last statement should be replaced
by ORG Here.
13.5.3. (1) B has value X 9830 , and length attribute 2. (2) B has value X 9838 , and length attribute 8. (3) B has value
X 9860 , and length attribute 4.
13.5.4. (1) B is relocatable, has value X 9837 , and length attribute 5. (2) B is relocatable, has value X B942 , and
length attribute 1.
13.5.5. We could write
F1
X2
*
F3
SKIP3

DC
DC

F 1
X 2

DC
ORG
DS

F 3
X2+1
XL3

First constant
Second constant
Three zero (skipped) bytes here
Third constant
Name and length of skipped bytes

Using Extended EQU Syntax, we could replace the last two statements:
SKIP3

Equ

X2+1,3

Name and length of skipped bytes

13.5.6. The symbol SET will be the operand of the ORG instruction, which is undoubtedly not what was intended. If a
symbol SET has been defined somewhere in the program (which is just a matter of chance), the LC will be assigned its
value, but that is quite unlikely to be the highest LC value attained in the program. (Or what is wanted!)
13.5.7. The assigned and desired lengths are both 80 bytes.
For the Bonus question, you could write something like
DS

(80-StmtLen)XL(StmtLen-80+1)

If StmtLen has exactly the desired value 80, this statement becomes
DS

0XL1

but if its value is greater than 80 the duplication factor will be negative; and if its value is less than 80, the explicit
length will not be greater than zero. In both cases, the Assembler will issue an error message.
Section 13.6
13.6.1. The storage definitions are the same, but the length attributes of the symbol FGroup are different. (What are
their values?) One way to see the similarity of the definitions is to consider defining
NWords

Equ

Table has one word

Both definitions will allocate both Table and LastWord at the same location.
Section 13.7
13.7.1. The Assembler doesnt rescan LC-dependent expressions unless they appear as nominal values in A-type or
Y-type constants. The statements will generate ten copies of the first constant, X 00000001 . (It would be helpful if
the Assembler indicated that the operand has a modifier requiring re-scanning if a Location Counter Reference appears
in the expression.)
13.7.2. The solutions are shown in this table:
Sym
A

X12345

Value

LA
3

Generated constant

X12348

X00012348

X12346

X0089

X12345

X00020002

X12345

X C14D405D00000000000040

X12345

X 0000010003

X E450C9

The underscored bytes in the generated constant for E are zero bytes inserted for alignment in the middle of the constant. Whether or not the underscored bytes for F are generated depends on whether the immediately preceding field
contains just-generated bytes (in which case the padding byte is present).
13.7.3. The expression (*-Sqrs) increases by 2 each time a constant is generated; because the table starts at onesquared, we add 2. Then, because the product increases by 4 for each constant, we divide by 4.

Suggested Solutions to Selected Exercises and Programming Problems

1075

13.7.4. Your assembled table should look like this (use the Assemblers PRINT DATA statement to see all the generated
data):
0001010201020203
0102020302030304
0102020302030304
0203030403040405
0102020302030304
0203030403040405
0203030403040405
0304040504050506
0102020302030304
0203030403040405
0203030403040405
0304040504050506
0203030403040405
0304040504050506
0304040504050506
0405050605060607

0102020302030304
0203030403040405
0203030403040405
0304040504050506
0203030403040405
0304040504050506
0304040504050506
0405050605060607
0203030403040405
0304040504050506
0304040504050506
0405050605060607
0304040504050506
0405050605060607
0405050605060607
0506060706070708

<-- Note the 0 3 byte

To see how the DC statement works, consider the underscored byte at offset 19. The first term is *-T, or 19. The next
term subtracts (*-T)/2, or 9. The next term subtracts (*-T)/4, or 4. The fourth term subtracts (*-T)/8, or 2, and the
fifth term subtracts 19/16, or 1. All succeeding terms subtract zero. Thus the final value is 19-9-4-2-1, or 3. The binary
representation of 19 is B 10011 which has three 3 1-bits.

Programming Problem 13.2.


You can write your program this way:
P13_2

Chars
Ints

Start 0
Using *,15
Printout Chars,*
DS
0F
Align to fullword boundary
DS
0CL16
DC
F -1046306171,-1803381883,-1723823710,1082565781
End
P13_2

You should believe the printed result!


Chars

1076

= C Assembler is fun

Assembler Language Programming for IBM z System Servers

Version 1.00

Section 14 Solutions
Section 14.1
14.1.1. The first pair of instructions will load the word from memory at address X 00000008 into GR5 (and who
knows what that will be?) The second will load a word integer constant X 00000008 into GR5. The distinction here is
between the value of an addressing expression, and the value of the object in memory referenced by an addressing
expression.
Section 14.2
14.2.1. There is no difference in their actions. However, the ST instruction can be indexed, while STM cannot.
14.2.2. The first word of an area of memory occupied by successive words has displacement 0 from the start of the
area; thus the fourth word has displacement 12.
14.2.3. All sixteen registers can be modified by an appropriate LM instruction.
14.2.4. (1) c(X) replaces c(GR15); (2) c(GR0) replaces c(X); (3) c(X) replaces c(GR0). In each case, only one register
participates.
14.2.5. Let A be the R 1 register expression, and B be the R 3 register expression. Then NREGS is defined by
NREGS
EQU
(B-A)+17*(A/A)-((A-1)/(A+1))-16*((B/A)/(B/A))
The value is the sum of four expressions: the first parenthesized expression is simply the usual difference; the second is
added if A is nonzero; the third is nonzero only when A is zero; and the last expression is added when B is greater than
or equal to A. Try some actual examples to see how it works.
Section 14.3
14.3.1. This form of the STH instruction would produce a bit pattern with the correct sign and the 15 low-order bits of
the true 32-bit representation. For example:
X00010001
X0000FFFF
X FFFF0001

when stored would become


when stored would become
when stored would become

X0001
X 7 FFF
X8001

so there would be no improvement; use halfword data carefully! To be truly useful, such STH instructions should
indicate an overflow condition if the sign bit was not identical to the next 16 bits to its immediate right.
14.3.2. After the first execution, c(GR2)=X 00005678 After the second, c(GR2)=X FFFFBA98 .
14.3.3. It could be either. These three statements generate the same object code:
STH
DC
DC

4,X05C ( 0 , 4 )
C
*
F1077952604

3 spaces and an asterisk


4-byte binary integer

14.3.4. All the L opcodes end in 8, and all the ST opcodes end in 0. Similarly, the L/ST, LH/STH, and LM/STM
pairs each start with the same first hex digit.
Section 14.4
14.4.1. A useful solution is to construct a table of bytes, each containing the count of 1-bits in the difference between its
location and the location of the beginning of the table. Thus, we would define the constant
*
NBits

DC

0 1 2 3 4 5 6 7 8 9 ...
15 16 ...
AL1(0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4,1,...)

(value of byte at XX)


(number of 1-bits)

and use it as follows:


L
IC
IC
STC

1,=F 0
1,XX
0,NBits(1)
0,XX

Set GR1 to zero for IC instruction


Get byte at XX with bits to count
Use it as index into NBits table
Replace byte at XX by its bit count

Suggested Solutions to Selected Exercises and Programming Problems

1077

Section 14.5
14.5.1. These two instructions and a two-byte temporary memory area will do the job:

Temp

STCM 1,B 0 1 1 0 , Temp


ICM
1,B 0 1 1 0 , Temp
- - DS
XL2

Section 14.6
14.6.1. The Assembler could simply interpret
STR

R1,R2

LR

R2,R1

as

This can be done easily with a macro-instruction, and no changes to the Assembler would be needed.
14.6.2. For LR, LTR, and LNR, the CC will never be set to 3 for any operand in GR R 2. For LCR and LPR, the CC
will be set to 3 if the GR R 2 operand is the maximum negative number X 80000000 or 2147483648.
14.6.3. Suppose GR2 contains X xxxxFEDC , where the rightmost 4 digits are a valid halfword integer and the
xxxx are unwanted bits. Writing
LHR

2,2

will extend the sign, leaving X F F F F F E D C in GR2.


14.6.4. After the first execution, c(GR2)=X 00005678 After the second, c(GR2)=X FFFFBA98 .
Section 14.7
14.7.1. There is no STGH instruction because its function would be exactly the same as STH.
14.7.2. Here is a solution using Load and Store instructions:

DSave

STG
0,DSave
L
0,DSave
LMH
0,0,DSave+4
- - DS
D

Save all of GR0


Load high-order half into low-order 32 bits
Load low-order half into high-order 32 bits
Temporary storage

There are easier ways to do this, as well see when we examine the shift instructions.
Section 14.9
14.9.1. Indexing applies only to the RX- and RXY-type instructions L and LG, but the result is equivalent to using LT
and LTG, both of which can be indexed.
14.9.1. None.
Section 14.10
14.10.1. The third digit of the opcode is 0 for the RRE-type instructions that deal with all 64 bits of a general register,
and 1 for the equivalent instructions that extend 32-bit data to 64 bits.
14.10.2. Complementing before sign extension could produce incorrect overflow indications. Remember that all 32-bit
binary numbers can be complemented in a 64-bit representation without overflow. Thus, the source operand
X80000000 ( 231) would produce an overflow when complemented.
14.10.3. Complementing a 64-bit operand can cause overflow, but after extending a 32-bit operand to 64 bits,
complementation cannot cause overflow.
14.10.4. The contents of general register 0 and the CC settings are:
(1)
(2)
(3)
(4)

X . . . . . . . . 8 0 0 0 0 0 0 0 ,
X FFFFFFFF 80000000 ,
X00000000 80000000,
X FFFFFFFF 80000000 ,

CC=3 (overflow), high-order 32 bits unchanged


CC is unchanged
CC=2 (positive)
CC=1 (negative)

14.10.5. All 32-bit integer complements can be correctly represented in 64 bits.

1078

Assembler Language Programming for IBM z System Servers

Version 1.00

Section 14.11
14.11.1. Load zeros into the R 1 register, and then insert the desired byte using an IC instruction.
14.11.1. Load zeros into the R 1 register, and then load the desired word using a L instruction.

Suggested Solutions to Selected Exercises and Programming Problems

1079

Section 15 Solutions
Section 15.2
15.2.1. The value of the CC is exactly the offset of the tested bit in the M1 field of the instruction.
15.2.2. The CC must take one of the values 0, 1, 2, or 3, each of which corresponds to a 1-bit in the mask. The branch
condition is always met.
15.2.3. The next instruction to be fetched will come from memory address zero, which (very!) rarely contains your
programs instructions.
15.2.4. If n = 0, or the branch condition is not met, nothing happens. If n 0 the Effective Address is
n + c(GRn) + c(GRn). Then, if n is even and the branch condition is met, there could be an error if the Effective
Address is too large or is the address of a non-instruction. If n is odd, a specification error would occur because the
Effective Address is odd.
Section 15.4
15.4.1. The given code sequence correctly aligns the address constant on a word boundary immediately preceded by the
BASR. However, the DS 0F may have caused one, two, or three bytes to be skipped preceding the NOPR!
15.4.2. There are many possibilities; you only need 2-byte or 4-byte instructions that do not branch out of line or
change the CC. For example, in place of NOPR you could use LR 0,0; and in place of NOP you could use ICM 0,0,0
or LGR 0,0 or BC 15,*+4. (Operands like *+4 are considered poor programming practice.)
NOPR and NOP are preferred, because the CPU need not move data uselessly. For NOPR, the CPU can determine
from the zero branch mask that it need not consider alternative targets for the next instruction to be fetched, which it
must do for BC 15,*+4.311
15.4.3. No branch will occur, because the R2 digit is zero; this was described in Section 15.1. (Review the discussion in
Section 15.4 about possible side-effects of this instruction.)
15.4.4. The first BCR branches to address zero, where something undesirable is likely to happen; the second BCR
drains the instruction pipeline and then continues execution.
Section 15.5
15.5.1. The LC values are: (1) X 0246 (2) X 0248 (3) X 0246 (4) X 024A (5) X 0254 (6) X 0246
15.5.2. The length and value attributes are:
Sym
A
B

Len
3
4

Value
X000743
X000748

C
D

7
10

X000743
X00074C

E
F

4
1

X00074C
X000754

15.5.3. c(D) = X C440C4C340C37DC4C37D .


15.5.4. The values and Length Attributes are:
1. Value = X 3 4 6 , Length = 4
2. Value = X34A , Length = 4
15.5.5. Either zero, two, four, or six bytes of No-Ops, depending on the current value of the Location Counter.

311

Modern processors try to improve the performance of branch instructions by maintaining a Branch History Table containing the
address of recent branch instructions, whether or not they branched, and their branch addresses. This lets the CPU guess more
reliably whether an instruction will or wont branch, and whether it might need to begin pre-fetching instructions at the branch
address. Adding branch instructions like BC 15,* + 4 may force other useful entries out of the Branch History Table, possibly
slowing execution of your program.

1080

Assembler Language Programming for IBM z System Servers

Version 1.00

Section 15.6
15.6.1. Every branch condition specified by a set of mask bits has a complementary branch condition determined by
forming the ones complement of the mask bits. Thus, pairs of branches such as

Next

BNZ
Next
B
LOOP
- - -

should be replaced by BZ

LOOP.

15.6.2. If we think of the extended mnemonics as representing separate instructions, then this description is not misleading, but it implies that the opcode is 12 bits long. It is more accurate to say that the extended mnemonics provide
statements that simplify the many ways to write conditional branch instructions.
15.6.3. An example of an instruction sequence:
LT
BP
BM
B

0,VAL
POS
NEG
ZERO

Load and test, set CC


Branch if positive
Branch if negative
Branch if zero

The last instruction is B. Should it be BZ instead?


15.6.4. The operation code X 40 is the STH instruction, so that the instruction X 40404040 appears to be the
RX-type instruction
STH

4,X 0 4 0 ( 0 , 4 )

Store a halfword

Depending on the contents of GR4 (the apparent base register), its contents could be stored almost anywhere, 64 bytes
beyond the address in GR4. Because there are 132 space characters, the instruction could be repeated 33 times if it
does not cause a program interruption for a protection or addressing exception. The instruction executed after the
33rd STH will depend on what follows the constant named Target in memory at execution time.
Section 15.7
15.7.1. The EQU statement is actually a comment statement! If it was in exactly the right place, his solution might
work for a while, but if instructions between the BZ and the intended target were added or removed, the target location
*+18 would be incorrect. This is why using * in branch instructions is a poor programming practice.
Section 15.8
15.8.1. All instructions begin on a halfword, or even, boundary.
Section 15.9
15.9.1. Yes. Many first-generation computers used branch instructions tested the sign bit of an Accumulator register.
Later machines such as the IBM 7090 provided similar tests, and included comparison instructions that skipped none,
one, or two of the following instructions, depending on whether the result of the comparison determined that the Accumulators contents were less than, equal to, or greater than the memory operand.
Most later machines had status flags such as Accumulator Overflow that served some of the function of a condition
code.
15.9.2. Since the CC is a 2-bit unsigned integer, only a single value can be assigned in a single instruction execution.

Suggested Solutions to Selected Exercises and Programming Problems

1081

Section 16 Solutions
Section 16.2
16.2.1. The BNM instruction will branch to ST if overflow occurs, so the result in c(ANS) = c(X)+c(Y) will undoubtedly be incorrect.
16.2.2. This solution uses mathematical induction: if (1) you can show that an assumption holds for the number 1,
and (2) you can also show that if you assume it holds for a positive integer N then the assumption also holds for N + 1,
then (3) your assumption holds for all positive integers.
We assume that the sum of the first N odd integers is N 2.

Our assumption is true for 1, since 1=1 2.

Now we need to show that if the sum of the first N odd integers is N 2, it is true that the sum of the first N + 1
integers is (N + 1)2.

Now, the sum of the first N odd integers is


[1 + 3 + 5 + ... + 2 N-1]
and the sum of the first N + 1 odd integers is
[1 + 3 + 5 + ... + 2 N-1] + [2 (N+1)-1]
The last term is 2 N + 2 1 = 2 N + 1, so we can write
[1 + 3 + 5 + ... + 2 N-1] + [2 (N+1)-1] = [N2] + 2N + 1
which is the same as (N + 1)2.

So our assumption is true for all positive integers.


16.2.3. The following instructions test for the possibility that N may be 1, so that only a single odd number (1) is stored.

ADDUP

ST
NN
SUM

LH
3,NN
LM
6,9,=F 0 , 2 , 1 , 1
AR
6,8
SR
3,9
BZ
ST
AR
8,7
B
ADDUP
ST
6,SUM
- - DC
H 6
DS
F

Get the value of N from c(NN)


Load GR6-GR9 with 0,2,1,1
Add odd integer to sum in GR6
Decrease N by 1
If it was 1, exit the loop
Next odd integer in GR8
Branch back (N-1) times
Store result in GR6 at SUM
Number of odd numbers to add
Sum of the first c(NN) odd numbers

A useful exercise is to write a short program to test both forms of this instruction sequence: this one and the one in
Figure 82 on page 220.
16.2.4. The values at ONE are alternately 1 and 3; other references to ONE probably did strange things! This technique
is useful when you want to alternate between two values x and y: subtract x from x+y and save the difference for the
next subtraction.
16.2.5. There are many ways to count the number of 1-bits in a word. This solution uses a table of bytes, each of
which contains a number giving the number of 1-bits in the byte whose value is the offset of that byte from the first byte
in the table. For example, the byte at offset 241 = X F1 = B 11110001 contains 5, the number of 1-bits in
B 11110001 .

Byte1

Byte2

Byte3

1082

SR
SR
ICM
BZ
IC
AR
ICM
BZ
IC
AR
ICM
BZ
IC

0,0
1,1
1,1,Data
Byte2
1,T(1)
0,1
1,1,Data+1
Byte3
1,T(1)
0,1
1,1,Data+2
Byte4
1,T(1)

Answer value in GR0


Work register
Get 1st byte of Data
Skip if zero, no bits to count
Get the count of 1-bits in this byte
Add to answer
Get 2nd byte of Data
Skip if zero, no bits to count
Get the count of 1-bits in this byte
Add to answer
Get 3rd byte of Data
Skip if zero, no bits to count
Get the count of 1-bits in this byte

Assembler Language Programming for IBM z System Servers

Version 1.00

AR
ICM
BZ
IC
AR
STH

Byte4

Store

0,1
1,1,Data+3
Store
1,T(1)
0,1
0,NBits

Add to answer
Get 4th and last byte of Data
Skip if zero, no bits to count
Get the count of 1-bits in this byte
Add to answer
Store final bit count

This is the table with the bits-per-byte counts:


T

DC
DC
DC
DC
DC
DC
DC
DC
DC
DC
DC
DC
DC
DC
DC
DC

AL1(0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4)
AL1(1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5)
AL1(1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5)
AL1(2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6)
AL1(1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5)
AL1(2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6)
AL1(2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6)
AL1(3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7)
AL1(1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5)
AL1(2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6)
AL1(2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6)
AL1(3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7)
AL1(2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6)
AL1(3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7)
AL1(3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7)
AL1(4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8)

00-0F
10-1F
20-2F
30-3F
40-4F
50-5F
60-6F
70-7F
80-8F
90-9F
A0-AF
B0-BF
C0-CF
D0-DF
E0-EF
F0-FF

16.2.6. As in the previous solution, well use a table to simplify. Each byte in the table has a number corresponding to
the number of leading 0-bits in the byte whose numeric value gives its offset from the start of the table. For example,
the byte at offset 26=X 1A = B 00011010 contains 3, the number of leading 0-bits in B00011010.

Byte1

Byte1Z
Byte2

Byte3

Byte4
*
Finish
Store
*
T

LA
0,31
Answer in GR0; initialize to 31
SR
1,1
Work register in GR1
ICM
1,1,Data
Get 1st byte of Data
BP
Finish
Have found first nonzero bit; exit
BZ
Byte1Z
Skip if zero, test following byte
LCR
0,0
Negative argument; set error value
B
Store
And store the result
SH
0,=H 8
Subtract 8 from GR0; no 1-bits found
ICM
1,1,Data+1
Get 2nd byte of Data
BNZ
Finish
Have found first nonzero bit; exit
SH
0,=H 8
Subtract 8 from GR0; no 1-bits found
ICM
1,1,Data+2
Get 3rd byte of Data
BNZ
Finish
Have found first nonzero bit; exit
SH
0,=H 8
Subtract 8 from GR0; no 1-bits found
ICM
1,1,Data+3
Get 4rd byte of Data
BNZ
Finish
Have found first nonzero bit; exit
If zero, c(Data) is identically zero, so result will be -1
IC
1,T(1)
Get number of leading 0-bits in byte
SR
0,1
Deduct from running count for answer
STH
0,MaxPow
Store the result
DC
DC

AL1(8,7,6,6,5,5,5,5),8AL1(4)
16AL1(3),32AL1(2),64AL1(1),128AL1(0)

There are other, simpler, and better ways to do this!


16.2.7. Because the first two bytes of the constant at NN are zero, the program would have looped until it either ran out
of time, or was interrupted for a fixed-point overflow in GR6.
16.2.8. The assembled program looks like this:

Suggested Solutions to Selected Exercises and Programming Problems

1083

Loc

Object Code

5000
____
5002
5004
5008
500A
500E
5012
5016
501A
501C

0D40
1B22
4320 401D
1202
4780 4010
4000 401A
47F0 4010
E4878840
0000
FFFFFFF6

Assembler Language Statements


Ex16_2_8 Start X5000
BASR 4,0
Using *,4
SR
2,2
IC
2,XX+3
LTR
0,2
BZ
Looper
STH
0,XX
Looper
B
*
Loop forever here
YY
DC
CL4 Ugh
(Skipped bytes!)
XX
DC
F -10

16.2.9. The contents of the word at XX will be X 00F6FFF6 .


16.2.10. Yes. Consider either of these instruction sequences:
L
AH

0,=X 7 FFFFFFF
0,=H 1

L
SH

1,=X80000000
1,=H 1

In both cases the magnitude of the result will be too large to represent correctly in 32 bits.
16.2.11. The first two instructions clear the work registers (R0 and R1) so that the original contents of their low-order
bytes cant cause a carry into the high-order 24 bits.
SR
SR
ICM
ICM
AR
STCM
BO

0,0
1,1
0,B 1 1 1 0 , X
1,B 1 1 1 0 , Y
0,1
0,B 1 1 1 0 , W
Over

Clear GR0
Clear GR1
Get value at X
Get value at Y
Add the values
Store the result
Branch if the sum overflowed

16.2.12. The constant is X 74CBB1 .


16.2.13. The first pair of instructions sets GR1 to zero, and then branches to address zero (not a good idea!). The
second pair of sets GR0 to zero and then does not branch; BCR 15,0 is a no-operation instruction.
16.2.14. The assembled program looks like this:
Loc
8000
8000
8002
8002
8006
800A
800C
8010
8014
8016
8018
801C
8020
8024

Object Code
0D40
9812 4016
BE27 401E
1301
47A0 4012
4001 4022
07FE
0000
00000005
FFFFFFFA

Assembler Language Statements


Ex16_2_E Start X8000
BASR 4,0
Using *,4
LM
1,2,Value
STCM 2,B 1 1 1 , First
LCR
0,1
BC
10,*+8
STH
0,Last(1)
BCR
15,14
Followed by ...
Two padding bytes!
Value
DC
F 4
DC
F -6
First
DS
F
Last
DS
H -10
End
Ex16_2_E

16.2.15.
1. CC=3, c(GR2) = X13579BDE
2. CC=3, c(GR2) = X80000001
3. CC=2, c(GR2) = X00010147 (set by ICM)

1084

Assembler Language Programming for IBM z System Servers

Version 1.00

Section 16.3
16.3.1. Two possible instruction sequences are:
(1)

LH
AGFR

(2)

STG
0,DTemp
LGH
0,HW
AG
0,DTemp
- - DS
FD

DTemp

1,HW
0,1

Load and extend 16 bits to 32 in GR1


Extend 32-bit value to 64 and add
Save c(GG0) temporarily
Load and extend 16 bits to 64
Add original contents of GG0
Temporary storage for c(GG0)

Both sequences have disadvantages: (1) requires an additional register, and (2) requires two accesses to a doubleword
in memory.
16.3.2. Two possible instruction sequences are:
(1)

LH
SGFR

1,HW
0,1

Load and extend 16 bits to 32 in GR1


Extend 32-bit value to 64 and subtract

(2)

STG
LGH
LCGR
AG
- - DS

0,DTemp
0,HW
0,0
0,DTemp

Save c(GG0) temporarily


Load and extend 16 bits to 64
Complement the original halfword value
Add original contents of GG0

FD

Temporary storage for c(GG0)

DTemp

Both sequences have disadvantages: (1) requires an additional register, and (2) requires two memory accesses to a
doubleword in memory and two additional instructions. (1) is preferable unless all the other general registers contain
data or addresses that you dont want to have to save briefly in memory.
Section 16.4
16.4.1. Because a comparison does not produce an arithmetic result only a CC settingno overflow can occur.
16.4.2. If an overflow occurs, the difference must be nonzero; thus the sense of the comparison is either greaterthan or less-than. If for example you perform the internal arithmetic for comparing 0 to X 80000000 , you will see
that the CPU should reverse the sense, as implied by the sign of the internal difference. Practically speaking, if the
result of nonzero, the CPU need only invert the sign bit when overflow occurs, and then set the CC in its usual way.
16.4.3. Because the CH instruction compares c(GR1) (which is zero) to only the first two bytes of =F 5 , the CC setting
will be 0, implying that the operands are equal. (Its easy to make this type of programming error!)
16.4.4. The assembled program looks like this:
Loc

Object Code

4800
4802
4802
4806
480A
480E
4824
4828
482C
4854
4858
485C

0DA0
5800 A056
5A00 A056
5000 A052
<other ops>
5900 A05A
4740 A000
<other ops>
00000000
00000001
0000000A

Assembler Language Statements


Ex16_4_4 Start X4800
BASR 10,0
Using *,10
Loop
L
0,One
A
0,One
ST
0,Number
PrintOut Number
C
0,Ten
BL
Loop
PrintOut *
Number
DC
F 0
One
DC
F 1
Ten
DC
F 1 0
End
Ex16_4_4

Section 16.5
16.5.2. First, we write the original instruction sequences in Figures 90 and 91 in two columns:

Suggested Solutions to Selected Exercises and Programming Problems

1085

NoC

L
LR
SL
SL
AL
BC
AL
STM

0,=F -1
1,0
0,ARG
1,ARG+4
1,=F 1
B 1 1 0 0 , NoC
0,=F 1
0,1,ARG

XXX

LM
LCR
LCR
BZ
SL
STM

0,1,ARG
0,0
1,1
XXX
0,=F 1
0,1,ARG

The only operand that properly causes overflow is the 64-bit maximum negative number X 8000000000000000 . The
instructions in the first column use only logical addition and subtraction, so they cannot cause an overflow condition.
Both LCR instructions in the second column can potentially cause an overflow condition, so we would have to take
steps to suppress a Fixed-Point Overflow interruption. If we do this, then both instruction sequences could be followed
by these:

NoOver

LTR
BNZ
C
BE
- - -

1,1
Check low-order word for zero
NoOver
If it s nonzero, operand can t overflow
0,=A(X80000000) Check high-order word for max neg #
Overflow
64-bit complementation would indicate overflow

16.5.3. Consider the following instructions:

CProp
Carry

NoCarry
Okay

LM
AL
BC
A
BNO
A
BNO
B
A
STM
BO

0,1,A
1,B+4
12,NoCarry
0,=F 1
NoCarry
0,B
Overflow
Okay
0,B
0,1,C
Overflow

Get all 64 bits of 1st operand


Add low-order half of second operand
Branch if no carry, it s easy
Now add the carry
If no overflow, finish up normally
Now add high-order halves
If no oflo now, sum has overflowed
Sum is correct
Add high-order halves normally
64-bit sum stored at C
If overflow now, it s true

If an overflow occurs in propagating the low-order carry at the instruction named CProp, the original contents of GR0
(the first word of the first operand) must have been X 7 F F F F F F F . Thus, when adding the high-order words at the
instruction named Carry, if no overflow occurs, the contents of the fullword at B must have been nonnegative, implying
that the 64-bit sum must have overflowed.
This solution isnt obvious; try writing a program with some sample data to test it.
16.5.5. With the LCR instructions, theres no easy way to avoid the possibility of intermediate overflow conditions; and
there is no logical complement instruction to help. Thus, the sequence shown in Figure 90 on page 227 could be
used.
Well see in Section 16.9 the instructions that let us modify the bits in the Program Mask.
16.5.12. This figure shows how the CC bits are set:

CC bits
Second bit=0
Second bit=1

First bit=0 zero, no carry nonzero, no carry


First bit=1 zero, carry
nonzero, carry

16.5.13. Subtraction requires adding the ones complement of the second operand (which will be all 1-bits) and a loworder 1-bit to the first operand (which will force a carry along the complete length of the sum, and off the left end). The
CC value B 10 reflects the zero result, with a high-order carry.
Section 16.8
16.8.1. If the CC settings following SL or SLR are 1, 2, or 3, then the settings following CL or CLR (with the same
operands) will be 1, 0, or 2 respectively. Remember that the CC cannot be 0 following SL or SLR; see Exercise 16.4.1.
16.8.2. This is most easily done (now) with a CLM and CLMH instruction.

1086

Assembler Language Programming for IBM z System Servers

Version 1.00

CLMH
BL
BH
CLM
BL
BH
BE

0,B 0 0 1 1 , StgOp
RegLow
RegHigh
0,B 1 1 0 0 , StgOp+2
RegLow
RegHigh
RegEqual

Compare bytes 2 and 3 of GG0


c(GG0) is low
c(GG0) is high
Compare bytes 4/5 of GG0 (0/1 of GR0)
c(GG0) is low
c(GG0) is high
c(GG0) = selected bytes of StgOp

If a temporary register is available, the shift instructions well discuss in Section 17 can solve this problem more easily.
16.8.3. After executing the two instructions with the first pair of operands, the CC setting is 1 (c(GR0) < c(GR1)) for
CR and 2 (c(GR0) > c(GR1)) for CLR. After executing the two instructions with the second pair of operands, the CC
setting is 2 (c(GR0) > c(GR1)) for CR and 1 (c(GR0) < c(GR1)) for CLR.
This technique is often used in sorting, where many other types of data are compared logically. By inverting the sign bit
of binary integers, (formerly) negative numbers are now logically less than (formerly) positive numbers. After the comparisons are complete, the sign bits are inverted again to restore the original values of the numbers.
16.8.5. With arithmetic comparison, all non-negative values are greater than all negative values; with logical values, all
negative values are greater than all non-negative values. For example, compare + 1 = X 00000001 and
1 = X FFFFFFFF .
16.8.6. Consider this test program:
X16_8_6

CSect ,
Using *,15
L
0,Oldest
L
1,Later
L
2,Newest
LR
3,1
SLR
3,0
LTR
3,3
Printout 3
LR
3,2
SLR
3,1
LTR
3,3
Printout 3,*,Header=No

Copy Later value to GR3


Subtract Oldest value
Test result
Copy Newest value to GR3
Subtract Later value
Test result

*
Oldest
Later
Newest

DS
0F
DC
X FFFFFFFE
DC
X FFFFFFFF
DC
X00000001
EndX16_8_6

Align on fullword
Oldest value
A later value
Most recent value

The calculated values in GR3 are both positive, as expected.


16.9.3.
BALR
SLL
ICM
SRDL
SPM

1,0
1,4
0,B 1 0 0 0 , CCode
0,4
1

Program mask in GR1


Drop off ILC and CC bits
New CC value in GR0
Shift into GR1
Set new CC without changing pm

BALR
SLL
SRL
ST

0,0
0,2
0,30
0,CCode

ILC, CC, PM, and IA in GR0


Drop ILC bits
Shift to right end of GR0
Store Condition Code

BALR
STCM
NI

0,0
0,B 1 0 0 0 , PMask
PMask,B 1 1 1 1

ILC, CC, PM, and IA in GR0


Store that leftmost byte
Set all but Program Mask to zeros

16.9.4.

16.9.5.

Suggested Solutions to Selected Exercises and Programming Problems

1087

Programming Problem 16.1.


The key to solving this problem is to define all the terms in A-type address constants.
* Display 3 arithmetic expressions as a 12-byte character string.
* c(X) = B100000000000000 + X C7A98 - 231471192,
* c(Y) = X C0FFEE - C @#$ - 694895668, and
* c(Z) = 1073741824 + X F194F6 + X ABCD .
P16_1 Start 0
Print Nogen
Using *,15
B
Start
*
X1
DC
A(B100000000000000)
X2
DC
A(X C7A98 )
X3
DC
A(231471192)
*
Y1
DC
A(X C0FFEE )
Y2
DC
A(C @#$ )
Y3
DC
A(694895668)
*
Z1
DC
A(1073741823)
Z2
DC
A(X F194F6 )
Z3
DC
A(X ABCD )
*
XANS
DS
0XL12
ANS
DS
0CL12
X
DS
F
Y
DS
F
Z
DS
F
*
Start DC
0H
L
0,X1
A
0,X2
S
0,X3
ST
0,X
*
L
1,Y1
S
1,Y2
S
1,Y3
ST
1,Y
*
L
2,Z1
A
2,Z2
A
2,Z3
ST
2,Z
*
Printout XANS,ANS,*
End
Your printed output will look something like this:
XANS
ANS

1088

= X F240C240D6D9405F40F240C2
= 2 B OR 2 B

Assembler Language Programming for IBM z System Servers

Version 1.00

Programming Problem 16.2.


The key to solving this problem is to define all the terms with length attribute 4. This is different from Problem 16.1,
because the alignment and padding of the terms is different.
* Display 4 arithmetic expressions as a 16-byte character string.
*
c(W) = c(WA) + c(WB) - 929065920, where
*
c(WA) = B100000000000000,
*
c(WB) = X1230000.
*
c(X) = c(XA) + 50344169 + c(XB), where
*
c(XA) = X 5 CF17 ,
*
c(XB) = C 0 0 0 .
*
c(Y) = c(YA) + c(YB) + c(YC), where
*
c(YA) = B11111111,
*
c(YB) = X1261F02 ,
*
c(YC) = C ABCD .
*
c(Z) = c(ZA) + c(ZB) - c(ZC), where
*
c(ZA) = X CAF75A ,
*
c(ZB) = B1000011,
*
c(ZC) = 511686493.
P16_2 Start 0
Print Nogen
Using *,15
B
Start
*
CANS
DS
0CL16
XANS
DS
0XL16
W
DS
F
X
DS
F
Y
DS
F
Z
DS
F
Start DC
0H
L
0,=BL4100000000000000
A
0,=XL41230000
S
0,=F929065920
ST
0,W
*
L
1,=XL4 5 CF17
A
1,=F50344169
A
1,=CL4 0 0 0
ST
1,X
*
L
2,=BL411111111
A
2,=XL41261F02
A
2,=C ABCD
ST
2,Y
*
L
3,=XL4 CAF75A
A
3,=BL41000011
S
3,=F511686493
ST
3,Z
Printout CANS,XANS,*
End
Your printed output will look something like this:
CANS
XANS

= IBM 360 BYTES.


= X C9C2D440F3F6F040C2E8E3C5E24B4040

Suggested Solutions to Selected Exercises and Programming Problems

1089

Programming Problem 16.3.


*
c(W) = c(WA) + c(WB) - 759375551, where
*
c(WA) = B100000000000000,
*
c(WB) = X CBA98 .
*
c(X) = c(XA) - c(XB) + 1386388536, where
*
c(XA) = X C0FFEE ,
*
c(XB) = C @#$ .
*
c(Y) = c(YA) + c(YB) + c(YC), where
*
c(YA) = B11111111,
*
c(YB) = X 1 F7C05 ,
*
c(YC) = C ABCD .
*
c(Z) = c(ZA) + c(ZB) - 975583924, where
*
c(ZA) = X FFFF ,
*
c(ZB) = -65536.
P16_3 Start 0
Print Nogen
Using *,15
B
Start
*
CANS
DS
0CL16
XANS
DS
0XL16
W
DS
F
X
DS
F
Y
DS
F
Z
DS
F
*
Start DC
0H
L
0,=BL4100000000000000
A
0,=XL4 CBA98
S
0,=F759375551
ST
0,W
*
L
1,=XL4 C0FFEE
S
1,=CL4 @#$
A
1,=F1386388536
ST
1,X
*
L
2,=BL411111111
A
2,=XL4 1 F7C05
A
2,=C ABCD
ST
2,Y
*
L
3,=XL4 FFFF
A
3,=A(-65536)
S
3,=F975583924
ST
3,Z
*
Printout CANS,XANS,*
End
Your printed output will look something like this:
CANS
XANS

1090

= KILROY WAS HERE.


= X D2C9D3D9D6E840E6C1E240C8C5D9C54B

Assembler Language Programming for IBM z System Servers

Version 1.00

Programming Problem 16.4.


The three values starting at Consts define initial values that make it easier to start the sequence.

P16_4

LOOP

Consts
One
Count
Value

Title Solution to Problem 16.4


START 0
BASR 15,0
Execution-time base register
USING *,15
Establish addressability
LM
0,2,Consts
Initialize first 3 terms
L
3,Count
Set print counter
LR
4,0
Move oldest term
AR
4,1
Add middle term
AR
4,2
And youngest term
ST
4,Value
Store for printing
PRINTOUT Value
Print it next
LR
0,1
Move middle to oldest
LR
1,2
And previous new to middle
LR
2,4
And new one to youngest
S
3,One
Subtract 1 from term counter
BP
LOOP
Branch if still positive
PrintOut *
Stop here
DC
F -1,0
Previous 3 terms of sequence, with..
DC
F + 1
Constant +1, third starting term
DC
F 2 5
Number of terms
DS
F
Space for printed value
END
P16_4

This solution requires that the constant named One immediately follow the two constants named Consts. This is not a
good programming practice; suppose someone replaced references to One with the literal =F 1 ?
The 25th term is X 0011CB8C = 1166220.
This solution uses an array of values, adding three and storing the sum at the fourth. Halfword values cant be used
because the value of the 21st term exceeds 15 bits.

P16_4A

Loop

Table

Title Solution to Problem 16.4


START 0
BASR 15,0
Execution-time base register
USING *,15
Establish addressability
LH
0,=H 2 2
Count of new terms
LM
2,4,Table
Get first three values
PrintOut 2,3,4,Header=No Print the first 3 terms
SR
1,1
Initialize index
L
2,Table(1)
Get oldest value
A
2,Table+4(1)
Add second-oldest value
A
2,Table+8(1)
Add most recent value
ST
2,Table+12(1)
Store in new position in table
PrintOut 2,Header=No
Print the new value
AH
1,=Y(L Table)
Increment the index
SH
0,=H 1
Decrement count
BP
Loop
Repeat until count = 0
PrintOut *,Header=No
Stop
LtOrg ,
Place literals here
DC
F 0 , 1 , 2
Three initial values
DS
22F
Remaining values
END
P16_4A

Programming Problem 16.7.

Suggested Solutions to Selected Exercises and Programming Problems

1091

P16_7

Start 0
Using P16_7,15
* Set up initial values.
LA
2,0
LA
3,1
Loop
PrintOut 3
LR
4,2
AR
4,3
C
4,=F1000000
BNL
Done
LR
2,3
LR
3,4
B
Loop
Done
PrintOut *,Header=No
End
P16_7

Provide addressability
Previous value.
Current value.
Print a value
Get a copy of the previous value.
Compute the next value
Compare to one million
If sum overflowed, we re done
Copy current value to previous.
Copy next value to current.
Repeat the calculation
Terminate the program

The output will look something like this:


GPR
3 = X00000001 =
1
GPR
3 = X00000001 =
1
GPR
3 = X00000002 =
2
. . . . . . . . . . . . . . . . . .
GPR
3 = X00000003 =
3
GPR
3 = X0004D973 =
317811
GPR
3 = X0007D8B5 =
514229
GPR
3 = X000CB228 =
832040
You may want to revise your solution to use the CONVERTO macro instead of PRINTOUT. (See Programming
Problem 16.9.)

Programming Problem 16.8.


P16_8

Loop

Done

Start 0
Using P16_8,15
LA
2,0
LA
3,1
PrintOut 3
LR
4,2
AR
4,3
BO
Done
LR
2,3
LR
3,4
B
Loop
PrintOut *,Header=No
End
P16_8

Provide addressability
Previous value.
Current value.
Print a value
Get a copy of the previous value.
Compute the next value
If sum overflowed, we re done
Copy current value to previous.
Copy next value to current.
Repeat the calculation
Terminate the program

The printed output looks something like this:


GPR
3 = X00000001 =
1
GPR
3 = X00000001 =
1
GPR
3 = X00000002 =
2
GPR
3 = X00000003 =
3
. . . . . . . . . . . . . . . . . .
GPR
3 = X43A53F82 = 1134903170
GPR
3 = X 6 D73E55F = 1836311903
Its not always a good idea to test for overflow, as an interruption may have occurred. Here are three other ways to test
for the largest value:
1. Check for the largest number:
C
BE

r,=F1836311903
Done

r = register with current number

Not an honest method, because you have to know the last value!

2. Use a logical addition that doesnt cause overflow, and check for an arithmetically negative result:

1092

Assembler Language Programming for IBM z System Servers

Version 1.00

ALR
LTR
BNP

r,rprev
r,r
DONE

rprev = register with previous number


Test sign of r
If not +, previous number was last

3. After output, test the current value against maximum positive number:
L
SR
CR
BL

t,=F2147483647
t,r
t,rprev
DONE

Maximum positive integer in temp reg


Subtract current from max
Compare difference to previous value
If smaller, current number is last

If (max-current) < (previous), we know that previous+current will overflow.

Programming Problem 16.9.


Note that the DC statement labeled Title starts in column 15, so that the constant need not be continued (the terminal
apostrophe is in column 71).
P16_9

Start 0
Using P16_9,15
Provide addressability
* Set up initial values.
LA
2,0
Previous value.
LA
3,1
Current value.
PrintLin Title,TLen
Print a header line.
PrintLin OutRec,1
Print a blank line.
Loop
CONVERTO 3,OutRec
Convert the number to characters
PrintLin OutRec,OutLen Print the results.
LR
4,2
Get a copy of the previous value.
AR
4,3
Compute the next value
BO
Done
If sum overflowed, we re done
LR
2,3
Copy current value to previous.
LR
3,4
Copy next value to current.
B
Loop
Repeat the calculation
Done
PrintLin EndRec,EndLen Print an ending line
PrintOut *,Header=No
Terminate the program
OutRec
DC
CL12
Output from CONVERTO
OutLen
Equ
*-OutRec
Title
DC
C 1 Fibonacci Sequence to Maximum Positive Fullword Value
TLen
Equ
*-Title
EndRec
DC
C 0 Program ends.
EndLen
Equ
*-EndRec
End
P16_9
The output lines will look like this; note that the carriage control characters are shown.
1Fibonacci Sequence to Maximum Positive Fullword Value
1
1
2
3
. . . . . .
701408733
1134903170
1836311903
0Program ends.

Suggested Solutions to Selected Exercises and Programming Problems

1093

Programming Problem 16.10.


P16_10

Loop

Done
Byte1
OutRec
OutLen
Title
TLen
EndRec
EndLen

Start 0
USING P16_10,15
Establish addressability
SGR
2,2
Previous value in GG2; F(0)=0.
LGB
3,Byte1
Current value in GG3; F(1)=1.
PrintLin Title,TLen
Print a title line
PrintLin OutRec,1
Print a blank line
CONVERTO 19,OutRec
Convert integer in GG3 to characters
PrintLin OutRec,OutLen
Print the results.
LGR
4,2
Get a copy of the previous value.
AGR
4,3
Compute the next value.
BO
Done
Overflow means we re done.
LGR
2,3
Copy current value to previous.
LGR
3,4
Copy next value to current.
B
Loop
Repeat the loop
PrintLin EndRec,EndLen
Print an ending line.
PrintOut *,Header=No
Terminate the program
DC
FL1 1
Initial value for F(1)
DC
CL21
Carriage control for output.
Equ
*-OutRec
Length of record.
DC
C 1 Fibonacci Sequence to Maximum Doubleword Value
Equ
*-Title
DC
C 0 Program ends.
Equ
*-EndRec
End
P16_10

The output looks like this (with carriage control characters):


1Fibonacci Sequence to Maximum Doubleword Value
1
1
2
. . . . . . . . . .
2880067194370816120
4660046610375530309
7540113804746346429
0Program ends.

Programming Problem 16.11.


The assembled program looks like this:
000000
R:C
000000
000002
000006
000008
00000C
000010
000012
000016
000000

18CF
5AF0 C008
0DCF
00000012
00000004
07FE
58A0 C004
47FA C004

00000 0001A
00000
00008

00004
00004

1 P16_11
2
3
4
5
6 X
7
8 Exit
9
10
11

CSect
Using
LR
A
BASR
DC
DC
BR
L
B
End

,
*,12
12,15
15,X
12,15
F 1 8
F 4
14
10,X-4
X-4(10)
P16_11

The key to following its execution is to not study the source code, because the BASR instruction changes the contents of
GR12, the base register! You must calculate effective addresses carefully at each step.

1094

Assembler Language Programming for IBM z System Servers

Version 1.00

Section 17 Solutions
Section 17.1
17.1.1. (1) 7, (2) 56, (3) 33, (4) 45, (5) 63, (6) 1, (7) 0.
Section 17.2
17.2.1. To find the bit, its byte address is simply K divided by 8, and the remainder of the division gives the position of
the bit within that byte.
L
SRDL
SRL
IC
SLL
SLL
SR
SLDL

2,KK
2,3
3,29
1,BStrg(2)
1,24
1,0(3)
0,0
0,1

Get bit number K


Byte count in GR2
And bit number in GR3
Get desired byte in GR1
Position at left end of GR1
Shift off undesired bits
Now clear GR0
And move the bit into GR0 from GR1

17.2.2. First, we use a right shift:


L
L
SRL
STC

1,K
0,=A(X 8 0 )
0,0(1)
0,KthBit

Shift
Put a
Shift
Store

amount in GR1
1-bit in byte-position zero
correct number of places
result bit

Another solution, shifting left:


L
S
L
SLL
STC

1,=F 7
1,K
0,=F 1
0,0(1)
0,KthBit

Compute 7-K
1-bit in GR0, byte-position 7
Shift left 7-K places
Store the k-th bit

17.2.3. The table at BTbl contains 8 bytes with a 1-bit in a position corresponding to its offset from BTbl.

BTbl

L
1,K
Load bit counter into GR1
IC
1,BTbl(1)
Insert byte with indexing
STC
1,KthBit
Store result
- - DC
X8040201008040201
Bytes with bits 0-7

17.2.4. Even though the register is only 32 bits long, the shift amount is determined from the six (not five!) low-order
bits of the Effective Address. The shift will set all bits in GR0 to zero.
17.2.5. If you want to use the shift instructions, you could write:
IC
SLL
IC
SLL
IC
SLL
IC

1,DPG+3
1,8
1,DPG+2
1,8
1,DPG+1
1,8
1,DPG

c(GR1)=xxxxxx78
c(GR1)=xxxx7800
c(GR1)=xxxx7856
c(GR1)=xx785600
c(GR1)=xx786534
c(GR1)=78563400
c(GR1)=78563412

With ICM instructions, you could write:


ICM
ICM
ICM
ICM

1,B 0 0 0 1 , DPG+0
1,B 0 0 1 0 , DPG+1
1,B 0 1 0 0 , DPG+2
1,B 1 0 0 0 , DPG+3

c(GR1)=xxxxxx12
c(GR1)=xxxx3412
c(GR1)=xx563412
c(GR1)=78563412

17.2.6. These instructions do the job:

Suggested Solutions to Selected Exercises and Programming Problems

1095

SR
C
BNL
A
SLL
B
- - -

Test

Done

1,1
0,=A(X40000000)
Done
1,=F 1
0,1
Test

Set GR1 to zero


Test value in GR0
If c(GR0) not low, we re done
Increment shift count
Shift left 1 bit
Repeat test
Shift count in GR1

17.2.7. The representations of the data at X and Y are c(X)=X 12D687 and c(Y)=X 74CBB1 . These instructions
will do the job:
ICM
ICM
SLDL
AR
STCM
JO

0,B 0 1 1 1 , X
1,B 0 1 1 1 , Y
0,8
0,1
0,B 1 1 1 0 , W
OverFlo

Put X in right end of GR0


Put Y in right end of GR1
Shift both left 8 bits
Add the values arithmetically
Store result
Branch if the sum overflowed

The representation of c(W)=X 87A238 ; the sum overflows.


17.2.8. If n=0, nothing happens; if n 0, calculate n+c(GRn) (modulo 64: the rightmost 6 bits) and shift GRn that
amount.
17.2.9. Yes: for signed integers, the LH instruction propagates the sign bit; but if the number is unsigned and its leftmost bit is 1, LH treats that bit as a sign that is propagated when it should not be. (Details like this can be very
important!)
Section 17.3
17.3.1. Simulating SLDL in this case is fairly easy:
LH
L
SLL
ST
SR
ST

1,NShifts
0,DataWord
0,0(1)
0,DWord
0,0
0,DWord+4

Get shift amount N


Load the data word
Shift left N bits
Store high-order 32 bits
Set GR0 to zero
Store low-order 32 bits

17.3.2. Because we have assumed that the low-order word is zero, the solution to Exercise 17.3.1 will also work.
(Remember that if N > 32, all bits in GR0 will be lost, and c(DWord) will be zero.)
17.3.3. In this case, we must handle the portion of the high-order word that shifts into the low-order word of the
double-length result.
LH
L
SRL
ST
L
LCR
SLL
ST

1,NShifts
0,DataWord
0,0(1)
0,DWord
0,DataWord
1,1
0,32(1)
0,DWord+4

Load shift count N into GR1


Get high-order word into GR0
Shift off low-order bits
Store high-order half of result
Reload a copy of original data
Complement shift count, now -N
Drop off high-order (N-32) bits
Store low-order half of result

17.3.4. In this case, we check for N 32: if true, the high-order word of the resulting double-length logical right shift will
be zero.

Under32

1096

LH
L
CH
BL
SRL
ST
SR
ST
B
SRL
ST
L
LCR
SLL

1,NShifts
0,DataWord
1,=H 3 2
Under32
0,32(1)
0,DWord+4
0,0
0,DWord
Done
0,0(1)
0,DWord
0,DataWord
1,1
0,32(1)

Load shift count N into GR1


Get high-order word into GR0
Check shift count
Branch if less than 32 shifts
Shift N-32 bits (see note below)
Store low-order half of result
Set GR0 to zero
Store high-order half of result
... and finish
Shift off low-order bits
Store high-order half of result
Reload a copy of original data
Complement shift count, now -N
Drop off high-order (N-32) bits

Assembler Language Programming for IBM z System Servers

Version 1.00

Done

ST
0,DWord+4
- - -

Store low-order half of result

The shift amount of the instruction SRL 0,32(1) is 32+N (mod 64); but since N32, the result gives the same shift count
as N-32.
17.3.5. In this case, the initial data is 64 bits long, and is to be shifted left 0 to 31 bits. Some comment statements have
been inserted to clarify the operation of the instructions.

*
*
*

LH
1,NShifts
Get shift count N
LM
2,3,DWData
64-bit shifting data in (GR2,GR3)
GR2/GR3: HHHHH....HHHHHLLLLL....LLLLL High and low order bits
LR
0,3
Copy low-order word to GR0
SLL
0,0(1)
Shift N bits left
GR0:
LLLL0000...000
ST
0,DWord+4
Done with low-order half of result
LR
0,2
Copy high-order word to GR0
SLL
0,0(1)
Shift left; now done with HO data
GR0:
HHH...HHH...000
LCR
2,1
Put -N in GR2
SRL
3,32(2)
Shift low-order data right 32-N bits
GR3:
000...000...LLL
ALR
0,3
Merge the two pieces in GR0
GR0:
HHH...HHHLLLLLL
ST
0,DWord
Store high-order half of result
Result:
HHH...HHHLLLLL LLLL0000...000

17.3.6. This solution is similar to that of Exercise 17.3.5:


LH
LM
LR
SRL
ST
LR
SRL
LCR
SLL
ALR
ST

1,NShifts
2,3,DWData
0,2
0,0(1)
0,DWord
0,3
0,0(1)
3,1
2,32(3)
2,0
2,DWord+4

Get shift count N


Load 64 bits to be shifted right
Copy high-order half to GR0
Shift right N bits
Store high-order half of result
Copy low-order half to GR0
Shift; low bits of low result word
-N in GR3
Shift high-order half 32-N bits
Merge pieces of high/low halves
Store low-order half of result

17.3.9. The following sequence makes no checks for whether or not significant bits are lost in the rearrangement. The
word containing four integers in the old format is at OLD, and the four in their new format are to be stored at NEW.
L
SRDL
SRL
SRDL
SRL
SRDL
SRL
SRDL
ST

0,OLD
0,6
1,2
0,13
1,2
0,2
0,2
0,7
1,NEW

Fetch the word with 4 integers


Shift 6 bits of 4th integer into GR1
Extend to 8 bits
All 13 bits of 3rd integer into GR1
Extend to 15 bits
Shift 2 low-order 2nd integer bits
Drop 2 high-order bits of 2nd
Shift last 7 bits into GR1
Store final result

17.3.10. This first solution works so long as the number of bits allowed for the value of each integer is sufficient; the
integers may then be in either the logical or the arithmetic representation.
L
SRDL
L
SRDL
L
SRDL
L
SRDL
ST

0,Fourth
0,6
0,Third
0,13
0,Second
0,4
0,First
0,9
1,NEW

Get 4th integer


Shift into GR1
Get 3rd integer
shift into GR1 next to 4th
Get 2nd integer
Shift into GR1 next to 3rd and 4th
Get 1st integer
Fill up the new word
And store the result

A second solution using A instructions (to Add) also does the job economically, but only if the integers are unsigned.
(Explain why this is so.)

Suggested Solutions to Selected Exercises and Programming Problems

1097

L
SLL
A
SLL
A
SLL
A
ST

0,First
0,4
0,Second
0,13
0,Third
0,6
0,Fourth
0,NEW

Get 1st integer


Make room for second
Add 2nd integer
Make room for third
Add 3rd integer
Make room for last
Add 4th and last integer
Store result

17.3.11. This solution is almost identical to that for Exercise 17.3.10.


L
LH
SRDL
L
LH
SRDL

0,Fourth
2,L4
0,0(2)
0,Third
2,L3
0,0(2)

Get 4th integer


Get bit length for 4th integer
Shift by specified amount
Get 3rd integer
Etc...
Etc...

17.3.12. The solution to Exercise 17.3.11 also works for integers in the arithmetic representation, provided that enough
bits are allotted to correctly represent the given values.
17.3.13. In Figure 113 on page 249 the value zero would be stored. In Figure 114 on page 249 the program would
stay in an unending loop comprising the SRDL, LTR, and BNM instructions until the program was halted.
17.3.14. For nonnegative values of N, a solution might be:
L
LR
A
SRL
AR

1,NN
2,1
2,=F 1
2,1
1,2

Get N
Move a copy to GR2
Force a carry if low bit = 1
Now have Ceiling(N/2) in GR2
Ceiling(N+N/2) now in GR1

17.3.15. To set the flag bytes correctly, we must test each integer as it is packed into the result word.

OKFour

OKThree

LM
L
SRDL
STC
LTR
BZ
STC
L
SRDL
STC
LTR
BZ
STC
L
SRDL
- - -

2,3,=F 0 , 1
0,Fourth
0,9
2,FLAG4
0,0
OKFour
3,FLAG4
1,Third
0,13
2,FLAG3
0,0
OKThree
3,FLAG3
0,Second
0,4

For setting data-fit flags


Get 4th integer
Shift 9 bits into GR1
Set 4th-integer FLAG4 to fit value
Now test if it really did fit
Skip one instruction if it did
Set data-fit FLAG4 to no-fit value
Fetch 3rd integer
Shift 13 bits into GR1
Set 4th-integer FLAG3 to fit value
Now test if it really did fit
Skip one instruction if it did
Set data-fit FLAG3 to no-fit value
Get 2nd integer
Shift 4 bits into GR1
...similarly for the other integers

17.3.16. We will illustrate two solutions: the first moves the bits from GR0 to GR1, then to GR3 and to GR2. (A
sketch may help.)
Loop

L
SRDL
LR
SLDL
S
BP
LR

4,=F 3 2
0,1
3,1
2,1
4,=F 1
Loop
1,2

Set bit counter in GR4


Shift a bit off right end of GR0
Move the shifted bit to GR3
Move into GR2, going left
Count down by 1
If count is positive, repeat
Leave result in GR1

The second solution uses logical addition to test for 1-bits at the left end of R0. (Again, a sketch may help.)

1098

Assembler Language Programming for IBM z System Servers

Version 1.00

Loop

Count

SignBit

L
4,=F 3 2
SRL
1,1
ALR
0,0
BC
12,Count
AL
1,SignBit
S
4,=F 1
BP
Loop
- - DC
A(X80000000)

Set bit counter in GR4


Make room in GR1 for a bit
Force a bit off left end of GR0
If no carry out, it was a zero bit
If carry, put a 1-bit in sign of GR1
Count down by 1
Repeat if count is positive
Leftmost 1-bit in a fullword

17.3.19. It works correctly. Well see in Chapter VII that the UNPK and TR instructions let us do this type of conversion more easily.
Section 17.4
17.4.1. The final CC setting in this instruction sequence is a correct emulation of SLDA:
SR
ST
LH
L
SLA
ST

0,0
0,DWord+4
1,NShifts
0,DataWord
0,0(1)
0,DWord

Set GR0 to zero


Store low-order half of result
Get shift count
Get datum to be shifted
Shift left N places
Store high-order half of result

17.4.2. The instruction sequence shown for the solution to Exercise 17.4.1 above can still be used, because the loworder half of the source operand was assumed to be zero.
17.4.3. In this instruction sequence, the final CC setting will not be correct:
LH
L
LR
LCR
SLL
ST
SRA
ST

1,NShifts
0,DataWord
2,0
3,1
2,32(3)
2,DWord+4
0,0(1)
0,DWord

Get shift count N


Get data to be shifted
Copy to GR2 (for low-order bits shift)
Complement N in GR3
Shift 32-N bits left
Store low-order half of result
Now, shift high-order half
Store high-order half of result

The reason the CC setting is not reliable is that if the original operand was nonnegative, a nonzero bit may have been
shifted into the low-order half of the result, leaving the high-order half zero. The SLA instruction would indicate
CC=0, whereas SRDA would indicate CC=2 for a positive nonzero result.
17.4.4. Here, we must test for 32 or more shifts:

Under32

Done

L
LR
LH
CH
BL
SRA
ST
SRA
ST
B
LCR
SLL
ST
SRA
ST
- - -

0,DataWord
2,0
1,NShifts
1,=H 3 2
Under32
2,32(1)
2,DWord+4
0,32
0,DWord
Done
3,1
2,32(3)
2,DWord+4
0,0(1)
0,DWord

Get data to be shifted


Copy it to GR2
Get shift count N
Check its size
Branch if less than 32
Shift right N-32 bit positions
Store low-order half of result
Shift GR0 32 bits: only sign bits left
Store high-order half of result
...and exit
Put -N in GR3
Shift data 32-N places left
Store low-order half of result
Shift high-order half N bit positions
Store high-order half of result

The CC setting at Done will not be correct. The first SRA instruction shifts N-32 positions because N 32, and adding
32 is equivalent to subtracting 32 in the rightmost 6 bit positions of the Effective Address.
17.4.5. In this case, we must shift a 64-bit signed operand:

Suggested Solutions to Selected Exercises and Programming Problems

1099

LH
LM
LR
SLL
ST
LR
SLA
ST
LCR
SRL
AL
ST

1,NShifts
2,3,DWData
0,3
0,0(1)
0,DWord+4
0,2
0,0(1)
0,DWord
1,1
3,32(1)
3,DWord
3,DWord

Get shift count N


Put 64-bit operand in (GR2,GR3)
Copy low-order word to GR0
Shift left N bits
Store low-order half of result
Copy high-order word to GR0
Shift left N bit positions
Store temporarily
Complement to get -N in GR1
Shift low-order word right N-32 bits
Add in the high-order bits
Store high-order half of result

The CC setting is not correct, because its value will depend on the result of the AL instruction.
17.4.6. We must right-shift a 32-bit operand right N bits:
LH
LM
LR
SRL
ST
LR
SRA
ST
LCR
SLL
AL
ST

1,NShifts
2,3,DWData
0,3
0,0(1)
0,DWord+4
0,2
0,0(1)
0,DWord
1,1
2,32(1)
2,DWord+4
2,DWord+4

Get shift count


Put shift operand into (GR2,GR3)
Copy low-order half to GR0
Shift right N bits
Store low-order part temporarily
Copy high-order half to GR0
Shift right arithmetically N bits
Store high-order half of result
Complement N
Shift out unneeded bits of high half
Add back the low-order half s bits
Store low-order half of result

The CC setting is not correct.


17.4.10. Because two bits are to be removed from the high-order part of the first and second integers, sign extension is
required only for the third and fourth integers.
L
SRDL
SRA
SRDL
SRA
SRDL
SRL
SRDL
ST

0,OLD
0,6
1,2
0,13
1,2
0,2
0,2
0,7
1,NEW

Fetch the word with 4 integers


Shift 6 bits of 4th integer into GR1
Sign-extend to 8 bits
All 13 bits of 3rd integer into GR1
Sign-extend to 15 bits
Shift 2 low-order bits of integer 2
Drop 2 high-order bits of integer 2
Shift last 7 bits into GR1
Store final result

17.4.11. Since c(NUM) is positive and nonzero, we will count the number of arithmetic right shifts:

Test

DONE

L
L
SRA
BZ
SLL
B
- - -

1,NUM
0,=F 1
1,1
Done
0,1
Test

Get number to be checked


Place starting exponent in GR0
Shift number right once
Finished if now zero
Double the power of 2 in GR0
And try again
2**N now in GR0

Check your solution carefully to ensure that it handles cases near a boundary, such as an exact power of two or a
number very near a power of two.
17.4.12. Because c(NUM) could be the maximum negative number, we should (in that case) consider the result in
GR0 to be a number in the logical representation.

1100

Assembler Language Programming for IBM z System Servers

Version 1.00

ShiftR

Done

L
LPR
L
BO
SRL
BZ
L
SRA
BZ
SLL
B
- - -

0,NUM
1,0
0,=F 3 1
Done
0,5
Done
0,=F 1
1,1
STOP
0,1
ShiftR

Load number to be tested into GR0


Move its magnitude to GR1, set CC
Maybe exponent is 31?
If the LPR overflowed, we re done
Force c(GR0)=0 without CC setting
If CC=0, c(NUM) was zero
Put starting power of 2 in GR0
Shift right once
Stop if we lost most significant bit
Double the power of 2
And try again
C(GR0) = the positive power of 2

You may hve tried another approach: shift a power-of-two bit to the right, while shifting c(NUM) to the left and
testing for overflow. (If you didnt, try it!)
17.4.13. The modifications are simple:

Test

Done

L
SR
SRA
BZ
A
B
- - -

1,NUM
0,0
1,1
Done
0,=F 1
Test

Get number to be checked


Set exponent to 0
Shift right once
Exit if now zero
Add 1 to exponent
And try again
Exponent N now in GR0

17.4.14. It is always true for nonnegative register contents, and for negative values in which the rightmost N bits are
zero. Other positive values will be forced to the next lower integer. For negative integers where nonzero bits are lost,
we can see that the truncation is still downwards toward more negative values: consider a single right shift of
X F F F F F F F D , or 3. After the shift, the result is X F F F F F F F E , which has value 2.
17.4.15. Testing for the possibility of overflow is more difficult than in Exercise 17.3.15, because we cannot simply
examine the high-order bits remaining after shifting the desired part out of the register. Even if the bits to the left of the
shifted part are all 0 or all 1, the most significant bit of the shifted part might be different, which would imply that the
value was too large for the allotted field.

OKFour

OKThree

LM
L
LR
STC
SRDA
SLA
BNO
STC
L
LR
STC
SRDA
SLA
BNO
STC
- - -

2,3,=F 0 , 1
0,Fourth
4,0
2,FLAG4
0,9
4,32-9
OKFour
3,FLAG4
0,Third
4,0
2,FLAG3
0,13
4,32-13
OKThree
3,FLAG3

For setting data-fit flags


Get 4th integer
Save for overflow check
Set FLAG4 to fit value
Position into packed word in GR1
Test for fit
Skip if it fits correctly
Set FLAG4 to no-fit value
Get third integer
Save for check
Set FLAG3 assuming a fit
Position in packed word
Test for fit into 13 bits
Skip if it fits correctly
Set FLAG3 to no-fig value
...similarly for the other integers

We will see simpler ways to set indicator flags in Section 24.


17.4.16. Here is one way to do the bit count:

Loop

Store

SR
SR
IC
SR
SRDA
BZ
LTR
BZ
A
B
STC

0,0
2,2
0,XX
1,1
0,1
Store
1,1
Loop
2,=F 1
Loop
2,XX

Clear GR0 for byte to be counted


Clear GR2 for bit count
Pick up data byte
Clear GR1 for shifting a bit
Shift a bit into GR1, set CC
Exit loop if no 1-bits left
Check GR1 for a 1-bit
Loop if it was a 0
Increment bit count
Continue testing
Store bit-count back at XX

17.4.17. The values are


Suggested Solutions to Selected Exercises and Programming Problems

1101

(a)
(b)
(c)
(d)

X FFFFFFEDCBA98765 ,
X8765432100000000,
X FEDCBA9800001D95 ,
X00003FB72EA61D95 ,

CC=1
CC=3 (fixed-point overflow)
CC=2 (the high-order half of GG0 is unchanged)
CC is unchanged.

17.4.18. The results are:


1. SRA 0,20
2. LPR 0,0
3. SLA 0,28

c(GR0) = X FFFFF876 , C C = 1
c(GR0) = X789ABCDF , C C = 2
c(GR0) = X90000000, C C = 3

17.4.19. This is one of many ways to do this:

Loop

LA
LA
ICM
SR
SLDL
LA
STC
LA
SH
BP

0,8
1,Char
3,B 1 0 0 0 , Byte
2,2
2,1
2,X F0 ( 0 , 2 )
2,0(,1)
1,1(,1)
0,=H 1
Loop

Count bits in GR0


Address of output characters
Insert the byte to be formatted
Clear GR2
Shift a bit into GR2
Make an EBCDIC character
Store the formatted digit
Step to next output character
Reduce bit count
Repeat for all 8 bits

17.4.20. Well assume the shift count N in GR2 lies between 0 and 63; if not, we can first isolate the rightmost 6 bits of
GR2.
LTR
SRDL
BNM
L
C
BL
LR
SRDL
ALR
B
ShortShf SRDL
ALR
SetNegCC LTR
B
NonNeg
LTR
BP
LTR
Done
- - -

0,0
0,0(2)
NonNeg
4,=F -1
2,=F 3 2
ShortShf
0,4
4,32(2)
1,5
SetNegCC
4,0(2)
0,5
0,0
Done
0,0
Done
1,1

Check sign of c(GR0)


Shift original argument by N bits
Branch if original value nonnegative
Put 32 1-bits in GR4
Check shift N count < 32?
Branch if shift count N < 32
Put 32 1-bits in GR0
Shift N-32 bits into GR5
Insert leading sign bits in GR1
Finish by setting Condition Code
Shift N 1-bits into GR5
Insert leading sign bits in GR0
Set CC=1
Check for nonzero bits in GR0
CC=2 if c(GR0)>0
Otherwise CC=0 or 2
Shifted result in c(GR0,GR1)

17.4.21. The solution is to check whether a one bit was shifted out; if so, add 1 to the shifted operand.

OK

L
SR
SRDA
BNM
LTR
BZ
A
- - -

0,=F -5
1,1
0,1
OK
1,1
OK
0,=F 1

c(GR0) = X FFFFFFFB = -5
Clear GR1
C(GR0) = X FFFFFFFD = -3
OK if number was non-negative
Test shifted bits
Some bit is not 1
Add 1 to GR0, c(GR0) = -2

Note that if the original value is even, the shifted bit is always zero. What happens if you start with 1? (See Exercise
17.4.14 also.)
17.4.22. Use an arithmetic shift (in either direction) with a zero shift amount.
17.4.23. 0 and 1.

1102

Assembler Language Programming for IBM z System Servers

Version 1.00

Section 17.5
17.5.1. Heres a possible solution:
LH
SRDL
SR
SLDL
L
LR
SLL
LCR
SRL
ALR
ST

2,NN
2,5
2,2
2,5
0,DataWord
1,0
0,0(2)
2,2
2,32(2)
0,1
0,RotateWd

Get shift count


Shift 5 bits right
Now set GR2 to zero
Rotate count (modulo 32) in GR2
Get data to be rotated (abc...xyz)
Copy it to GR1
Shift left N (cd...xyz00)
-N in GR2
Shift right 32-N (00abc...x)
Merge the parts (cd...xyzab)
Store the rotated result

17.5.2. Here, we can use SLDL to help:


LH
SRDL
SR
SLDL
LM
CH
BL
*
Swap
LR
LR
LR
SH
Under32 LR
SLDL
STM
LCR
SRL
AL
ST
17.5.3. RLLG

2,NN
Get shift count
2,6
Shift 6 bits into GR3
2,2
Set GR2 to zero
2,6
Shift count (modulo 64) in GR2
0,1,DWData
Get operand to be rotated
2,=H 3 2
Rotating more than 32 bits?
Under32
Branch if yes
the halves, and then rotate N-32 bits
3,0
Copy high-order half to GR3
0,1
Move low-order half to GR0
1,3
And high-order half to GR1
2,=H 3 2
Reduce count by 32
3,0
Copy high-order half to GR3
0,0(2)
Shift both halves left N(mod 32) bits
0,1,RotatDWd
Store both parts of (temporary) answer
2,2
Complement N (now within (-31,0))
3,32(2)
Shift high-order part right 32-N bits
3,RotatDWd+4
Add low-order piece of result
3,RotatDWd+4
Store final low-order half of result

r,r,32

Section 17.6
17.6.1. The statement will be assembled as though we had written
SLL

9,0(2)

The contents of GR2 will depend on its position in the program, so the shift amount could vary with each assembly.
(Not a good idea!) Its possible that some USING statements specifying the same relocatable value as A and a higher
register number were available for resolving Addressing Halfwords, in which case that register would be used as the
base register for the shift. (An even worse idea!)
17.6.2. Assuming normal base register usage conventions, the shift amount might be any even number from 0 to 62. In
any given execution of the program, the number of shifts will be fixed, but it will depend on where the program was
placed in memory. (Again, not a good idea!)
17.6.3. The number of shifts is not 12! As in Exercise 17.7.2, the number of shifts will be found when the address of
AAA is evaluated; this could be any multiple of 4 between 0 and 60, because AAA is fullword aligned.
17.6.4. Be careful! If the original value in Rx is negative, SLDA and SRDA wont be able to set it to zero. Furthermore, if x is an odd-numbered register, none of the double-length shift instructions can be used. If x is even, SLDL and
SLDA clear register x+1 instead, and SRDL and SRDA effectively move c(GRx) to c(GRx+1). Thus, (4), (6), (7),
and (8) should be avoided.
17.6.5. Your table might look like this:

Suggested Solutions to Selected Exercises and Programming Problems

1103

Shift
S
S
S
S
S
S
S
S

Direction
L
L
L
L
R
R
R
R

Length
S
S
D
D
S
S
D
D

Type
L
A
L
A
L
A
L
A

Mnemonic
SLL
SLA
SLDL
SLDA
SRL
SRA
SRDL
SRDA

17.6.6. There is no reason to shift more than 31 positions in a single register; the result can be obtained either with a
shift of 31 or fewer positions, or with a different (and probably faster) instruction.
17.6.7. We will see later that the UNPK instruction provides a simpler solution to this problem.

ChTbl

SR
IC
SRDL
IC
SRL
IC
STC
STC
- - DC

2,2
2,DATA
2,4
2,ChTbl(2)
3,28
3,ChTbl(3)
2,CH
3,CH+1

Clear GR2 for data byte


Get 2 hex digits from data
Shift right digit into GR3
Get EBCDIC character for left digit
Position right digit for indexing
Get EBCDIC character for right digit
Store first character of result
And second character also

C0123456789ABCDEF

17.6.8. The values by which the Effective Address should be divisible are:
1.
2.
3.
4.
5.
6.
7.
8.

L 4
BC 2 (it must be!)
LH 2
ICM 1
LR Irrelevant: LR generates no Effective Address!
SRDA 1
STM 4
STC 1

17.6.9. The shift amount depends on the Effective Address, so it could be any multiple of 4 between 0 and 60
(assuming the Assembler has placed the literal on a word boundary).
Section 17.7
17.7.1. The three statements will generate the same bit patterns, but only the constant named A will always be aligned
on a word boundary.
17.7.2. The generated constant is X D864E26F . If the letter U is omitted, all four data items are too large for the
allotted fields.
17.7.3. The generated constant is X 8C4417E1 .
17.7.4. You could write the constants as
DS
UnsdVals DC
SgndVals DC

0F
FL.(LA) U432 , FL.(LB) U12 , FL.(LC) U5001 , FL.(LD) U47
FL.(LA) -232 , FL.(LB) -8 , FL.(LC) -4001 , FL.(LD) -31

17.7.5. Write the length modifier as L.(8*A+B)

Programming Problem 17.1.


This solution uses a logical left shift to move bits into the sign position, where they are tested with the LTR instruction.
Can you think of a way to use an SLA instruction and a test for overflow instead? Modify this solution to test for several
data values.

1104

Assembler Language Programming for IBM z System Servers

Version 1.00

*
P17_1

Loop

*
Finish

Data
Norm
Count
*
Error

Title
Count
Print
START
BASR
USING
L
SR
SLL
LTR
BZ
BM
A
B

Solution to Problem 17.1


the number of 1-bits in a word
NoGen
0
15,0
Set GR15 as base register
*,15
Inform the assembler
0,DATA
Get data from memory
1,1
Set shift counter to zero
0,1
Shift data left one bit
0,0
See if sign bit is a one
Error
Error if zero, no one-bits there
Finish
Branch if yes, all done
1,=F 1
Add one to shift count
Loop
And go shift the data again

STH
1,Count
Store the shift count
SRL
0,1
Move the data back once
ST
0,Norm
Store shifted result
PrintOut Data,Norm,Count,*,Header=NO Print answers and stop
DC
F7294
A number to be tested
DS
XL4
Space for shifted result
DS
H
Space for final shift count
PRINTOUT *
END
P17_1

Error stop for bad data

The output for this sample Data item is:


Data
Norm
Count

=
7294
= X71F80000
=
18

Programming Problem 17.3.


This solution uses the arithmetic shifts:
P17_3
*

Start 0
Unpack four signed integers packed in a word.
Print NoGen
Using *,15
LA
Equ
9
Bit length of integer A
LB
Equ
4
Length of B
LC
Equ
13
Length of C
LD
Equ
6
Length of D
L
0,SgndVals
Get data word into GR0
SRDA 0,LD
Shift 6 bits into GR1
SRA
1,32-LD
Sign-extend to right
ST
1,Fourth
Store fullword result D
SRDA 0,LC
Shift off 13 more bits into GR1
SRA
1,32-LC
Shift with sign extension
ST
1,Third
Store signed result of C
SRDA 0,LB
Shift off next 4 bits for B
SRA
1,32-LB
Sign-extend second integer
ST
1,Second
Store final result of B
ST
0,First
Store correct first integer A
PrintOut First,Second,Third,Fourth,*,Header=NO
First
DS
F
Second
DS
F
Third
DS
F
Fourth
DS
F
SgndVals DC
0F,FL.9 -232 , FL.4 -8 , FL.13 -4001 , FL.6 -31
End
The printed output shows the desired values:

Suggested Solutions to Selected Exercises and Programming Problems

1105

First
Second
Third
Fourth

1106

=
=
=
=

-232
-8
-4001
-31

Assembler Language Programming for IBM z System Servers

Version 1.00

Section 18 Solutions
Section 18.2
18.2.1. For 32-bit operands using signed multiplication, the product of two maximum negative integers yields the 64-bit
signed product + 262 = X 40000000 00000000 , or 4611686018427387904.
18.2.2. If the operands x and y are positive, the products XY and xy are identical. If x is negative and y is positive, the
logical product XY is actually (232+x)y; thus we need to add Y to the high-order half of the product xy as computed
by the M (or MR) instruction. Similarly, if both x and y are negative,
XY = (232+x)(232+y) = 232(x+y) + xy
The 2 64 term is ignored in our 64-bit product, so we simply add x and y to the high-order half of the product xy.

NotNeg1

NotNeg2

L
L
LTR
MR
BNM
ALR
LTR
BNM
ALR
STM

2,X
1,Y
3,1
0,2
NonNeg1
0,2
2,2
NotNeg2
0,3
0,1,LogProd

Get first logical operand


Get second logical operand
Save for addition, and set CC
Form arithmetic product
Branch if 2nd operand not negative
Add first operand to high-order half
Check sign of first operand
Branch if arithmetic rep. not minus
Add 2nd operand to high-order half
Store 64-bit logical product

Thus:

If X < 0, add Y 232


If Y < 0, add X 232

18.2.3. The largest signed 32-bit magnitude is ( 231), and the largest signed 16-bit magnitude is ( 215), so the largest
48-bit product is 246=70368744177664. The largest signed 64-bit magnitude is ( 263), so the largest 96-bit product is
294=19807040628566084398385987584.
18.2.4. Because the two operands are positive, the test is simple:
L
M
LTR
BNZ
LTR
BM

1,A
0,B
0,0
Overflow
1,1
Overflow

Get multiplier
Form product
Test high-order half
Error if not all zero
Test leftmost bit of low-order half
If a 1-bit, result is too large

18.2.5. In this case it is simplest to use SLDA for the test. Because the product must be left intact in (GR0,GR1), the
shift must be done in a different register pair.
L
M
LR
LR
SLDA
BO

1,A
0,B
2,0
3,1
2,32
Overflow

Load multiplier
Form product
Copy left and ...
Right halves to (GR2,GR3)
Now test for fit in one word
If overflow, product won t fit

L
M
LR
LR
SLDA
BNO
LTR
BM
B
- - -

1,A
0,B
2,0
3,1
2,32
Okay
0,0
OverNeg
OverPos

Load A into GR1


Multiply by B in (GR0,GR1)
Copy high-order word to GR2
Copy low-orer word to GR3
Test for any overflow
Branch if no overflow
Test sign of original result
Branch if negative result is too big
Branch if positive result is too big
Result is representable in a fullword

18.2.6.

Okay

18.2.7. This solution references each pair of halfwords using the addresses in GR11 and GR12, incrementing them by 2
each time. The accumulating sum is in (GR0,GR1):

Suggested Solutions to Selected Exercises and Programming Problems

1107

Loop

NoCarry

L
SR
LR
LH
MH
SRDA
ALR
BC
AL
ALR
AL
AL
S
BP
STM

2,=F 1 0
0,0
1,0
4,0(,11)
4,0(,12)
4,32
1,5
12,NoCarry
0,=F 1
0,4
11,=F 2
12,=F 2
2,=F 1
Loop
0,1,DwSum

Count items in GR2


Accumulate sum in (GR0,GR1)
Initialize sum to zero
Get an operand
Multiply by the other
Extend word product to 64 bits
Add low-order words
Skip carry add if none to add
Add a carry bit
Now add high-order words
Add 2 to address of first table
And to the address of second table
Count down items by 1
Repeat if not done
Store accumulated sum

18.2.8. Since x is always positive, we only need to test the sign of y:


L
LTR
M
BNM
AL
Y_NonNeg STM

2,Y
1,2
0,X
Y_NonNeg
0,X
0,1,LProd

Get (possibly negative) 2nd operand


Move to GR1 and set CC
Multiply to form arithmetic product
Now skip if y is nonnegative
Otherwise add correction term
Store 64-bit logical product

18.2.9. Because the CPU must eventually access the even-numbered register, its address is needed anyway. Furthermore, it is consistent to require all instructions referring to a register pair to do so with the even-numbered register.
18.2.10. Only one instruction is needed:
SLDA
BO

0,32
Overflow

Destroys original (GR0,GR1) contents


Branch if overflow is indicated

18.2.11. The largest positive 32-bit magnitude is (231 1), and the largest positive 16-bit magnitude is (215 1), so the
largest 48-bit product is 70366596661249. The largest positive 64-bit magnitude is (263 1), so the largest 96-bit
product is 19807040619342712359383728129.
18.2.12. This technique is used: form the 64-bit product of A and B; then, if an arithmetic test of B indicates that its
negative, add B 232 to the product.

Skip

L
L
LTR
MR
BNM
AL
DC

1,A
0,B
0,0
0,0
Skip
0,B
0H 0

A in GR1
B in GR0
Test sign of B
Form the product A*B
Skip adding if B is not negative
Complete the 64-bit product

18.2.13. His instructions are incomplete. Consider multiplying 75141 56789: the product X FE5808A9 is indeed 32
bits long but appears to be negative, 27785047. An additional test is needed:

X
Y

L
1,X
M
0,Y
LTR
0,0
BNZ
NotOK
LTR
1,1
BZ
ProdOK
- - DC
F75141
DC
F56789

Load first operand


Multiply by second operand
Check high-order 32 bits
If not zero, product is too big
Check high-order bit of GR1
Branch if high-order 33 bits are 0s
Not OK

x
18.2.14. In the following sketch, the characters L< and L mean Logically Less Than and Logically Greater
Than Or Equal, respectively

1108

Assembler Language Programming for IBM z System Servers

Version 1.00

N
+

N
P64  c(R0) = all 0bits?  SRDA 0,64  c(R0) = all 1bits?
 P64
Y
0
Y

N

Y

Y

Y
P64  c(R1) L< X80000000?  P32
 c(R1) L X80000000?  P64
Some instructions to determine which of the two possible product fields should be used could be like these:

Plus

P64
P32
Done

SRDA
BZ
BP
C
BNE
CL
BNL
B
LTR
BNE
CL
JL
STM
B
ST
- - -

0,0
P32
Plus
0,=F -1
P64
1,=X80000000
P32
P64
1,1
P64
1,=X80000000
P32
0,1,Prod64
Done
1,Prod32

Check sign and possible zero


Product is zero, store as 32 bits
Go handle positive product
Is high half all 1-bits?
No, must store 64-bit product
Is low half logically < 2**31?
Yes, can store 32-bit product
Otherwise, store 64-bit product
Is low half all 0-bits?
If not, must store 64-bit product
Is low half logically >= 2**31?
No, OK to store 32-bit product
Store 64-bit product
Store 32-bit product

The solution above illustrates the general idea that testing only the high-order half of the product is not sufficient. This
more elegant solution takes many fewer instructions:

Prod64
Done

LR
SRA
CR
JNE
ST
J
STM
- - -

2,1
2,31
2,0
Prod64
1,Prod32
Done
0,1,Prod64

Copy low-order half of product


Copy sign bit through R2
Compare to high-order half of prod
If not equal, it s a 64-bit product
Store the 32-bit product
Finish
Store the full 64-bit product

The key to this solution is that the SRA fills R2 with sign bits of the low-order half of the product, so R2 contains
either 0 or 1. If that compares unequal to c(R0), we know there are significant bits in R0; and if it compares equal,
we know that the sign bit of R1 is the same as the bits in R0 so the product has only 32 significant bits. Worth
studying!
18.2.15. X FFFFFFC0 = 64.
Section 18.3
18.3.1. For 32-bit operands using logical multiplication, the product of two 32-bit maximum unsigned integers (232 1,
X F F F F F F F F ) yields the 64-bit unsigned product X FFFFFFFE00000001 , or 18446744065119617025.
18.3.2. Using the same analysis as in Exercise 18.2.2, we form an arithmetic product using logical multiply instructions:

B1

B2

L
L
LTR
MLR
BNM
SLR
LTR
BZ
SL
STM

1,P
2,Q
1,1
0,Y
B1
0,2
2,2
B2
0,P
0,1,ArProd

Load P into GR1


Load Q into GR2
Set CC for P
Logical product of P and Q
Branch if P >= 0
Subtract Q, correct for negative P
Check sign of Q
Branch if Q >= 0
Subtract P, correct for negative Q
Store signed product

Suggested Solutions to Selected Exercises and Programming Problems

1109

Section 18.5
18.5.1. The range of QD values is 1 Q D ND, and the range of RD values is 1 R D DD. (The lower bound
of 1 is because zero is a one-digit number.)
Section 18.6
18.6.1. Because the quotient is represented as a signed twos complement number, its magnitude is less than or equal to
231 . We might say that room must be left for the quotients sign bit.
18.6.2. A specification error occurs if n is odd. If n is even, a divide-check interruption occurs only if the dividend is not
a negative number between 1 and (231 1) and the divisor is 1. Thus it is highly probable that an interruption will
occur. Heres a more detailed analysis:

If
If
If
If

c(GR n) is positive, the inequality in Figure 132 on page 277 is not satisfied.
c(GR n) is zero, an immediate interruption occurs.
c(GR n) is negative and not equal to 1, the inequality in Figure 132 on page 277 is not satisfied.
c(GR n) is negative and equal to 1, we must then consider the contents of c(GR n + 1):
If c(GR n + 1) is non-negative, the inequality in Figure 132 on page 277 is not satisfied.
If c(GR n + 1) is negative, and equal to the maximum negative number, ( 231 1) ( 1) fails because the quotient
would be + 231 .
Any other negative value is satisfactory.

18.6.3. A fixed-point divide interruption can occur only if the divisor is zero. The quotient may be too large to fit in a
halfword, but no error indication is given.
L
SRDA
LH
DR
STH
STH

0,WDividen
0,32
2,HDivisor
0,2
0,HRemaind
1,HQuotent

Fetch 32-bit dividend


Extend sign to 64 bits
Extend divisor to 32 bits
Divide
Store halfword remainder
And halfword quotient

18.6.4. A fixed-point divide exception is possible only if you divide the maximum negative number 231 by 1,
because the quotient + 231 cannot be represented correctly.
18.6.5. A fixed-point divide interruption cannot occur: the dividend must be less than 2 31 in magnitude, so division by 3
must yield a quotient whose magnitude is less than 2 30 .
18.6.6. Because c(NN) is positive, there is no need to worry about a carry: at worst, a carry could propagate into the
sign bit of the low-order half of the dividend. Since that bit is not a sign bit, no overflow need be signaled.
L
SR
AL
D
ST

7,NN
6,6
7,=F 5
6,=F 1 0
7,QQ

Get positive dividend


Set high-order half to zero
Add rounding factor logically
Compute rounded quotient
And store the result

18.6.7. As in the solution to Exercise 18.6.6, it can be shown that subtracting 5 from the low-order half of a dividend
cannot cause a borrow from the high-order register. Thus we could write the code sequence as follows:

Skip1

L
L
SRDA
BNM
LCR
ALR
D
ST

0,=F 5
6,NN
6,32
Skip1
0,0
7,0
6,=F 1 0
7,QQ

Set up rounding factor


Get signed dividend
Extend to 64 bits, and set CC
Branch if nonnegative
Complement the rounding factor
Add signed roundoff to right half
Divide by 10
Store signed rounded quotient

18.6.8. Simulating logical division using arithmetic divide instructions is more difficult than it might first appear. It can
be done, however. If you try, be sure to test your code sequence with many values representing boundary conditions.
18.6.9. This solution shows one way to do it:

Next

1110

SR
LTR
BNM
L
DR

0,0
1,1
Next
0,=F -1
0,2

Assume c(GR1) is nonnegative


Check sign of c(GR1)
Branch if not negative
Fill GR0 with sign bits
Do the division

Assembler Language Programming for IBM z System Servers

Version 1.00

This exercise was provided purely for its educational (and entertainment) value; the coding technique is clumsy and
unnecessary.
18.6.11. Because you cant represent 1/2 as an integer, you can revise the rounding formula like this:
(a)

quotient = ((2*dividend) + divisor) / (2*divisor)


or

(b)

quotient = (dividend + (divisor/2)) / divisor

Your choice of formulas might depend on the magnitudes of dividend and divisor, and whether the divisor is even.
Heres how you might code formula (a):
L
L
AR
AR
SRDA
AR
DR

0,Dividend
2,Divisor
0,0
0,2
0,32
2,2
0,2

Assume a 32-bit dividend


Assume a 32-bit divisor
2*dividend
(2*dividend+divisor)
Extend to 64 bits for division
2*dividend
Rounded quotient now in GR1

Weve assumed that magnitudes are small enough that no overflows will occur.
18.6.12. Its simpler to write
SRA

5,2

Divide c(GR5) by 2

Because c(GR5) is nonnegative, SRL could also be used.


18.6.13. Let N, D, Q, and R represent the numerator, divisor, quotient, and remainder respectively. Then we want to
calculate Q = (N/D) + (1/2). We can rewrite this as Q = ( N + D / 2 ) / D . After dividing, if 2 R D, we add 1 to Q.
For positive N and D, we can write these instructions:

NoRound

L
L
LR
SRA
AR
SRDA
DR
AR
CR
BL
A
- - -

2,N
4,D
3,4
3,1
2,3
2,32
2,4
2,2
2,4
NoRound
3,=F 1

Get numerator
Get divisor
Copy to GR3
Form D/2
Form modified numerator
Form 64-bit
Calculate tentative quotient in R3
Calculate 2*R
Compare to divisor
If less, no rounding
Round up the quotient

Now, you should revise these instructions to handle N and D with arbitrary signs.
Section 18.7
18.7.1. Simulating arithmetic division using logical division instructions is more complex than a related simulation of
arithmetic multiplication. This sequence of instructions handles most cases, but does not test for possible divide
exceptions and does not preserve the Condition Code.
LM
LTR
BNM
LCR
LCR
BZ
S
GetDivsr L
LTR
BNM
LCR
Divide
DLR
LTR
BNM
LCR
LTR
BNM
B
PosDvdnd LTR

0,1,NumL
3,0
GetDivsr
0,0
1,1
GetDivsr
0,=F 1
2,DenL
4,2
Divide
2,2
0,2
2,2
PosDvdnd
0,0
4,4
CompQuot
Store
4,4

Get signed dividend in (GR0,GR1)


Check dividend sign; save in GR3
Not negative, no need to complement
Complement high-order dividend
Complement low-order half
If low word zero, high word is OK
Complemented dividend now +
Divisor in GR2
Check divisor sign; save in GR4
If not negative, skip complement
Complement to make + divisor
Logical division, positive operands
Check dividend sign
Branch if nonnegative dividend
Must have negative remainder
- dividend; check sign of divisor
Mixed signs, complement quotient
Both -, store result
+ dividend; check divisor sign
Suggested Solutions to Selected Exercises and Programming Problems

1111

BNM
CompQuot LCR
Store
STM

Store
1,1
0,1,RemQuot

Both +, store result


Complement quotient
Store arithmetic remainder/quotient

You may want to test this code sequence with some sample data, and compare the results of normal and simulated
arithmetic division operations.
18.7.2. Both quotient and remainder are 2 32 2, and the divisor is 231 1. Thus, quotient divisor = 264 233 232 + 2;
adding the remainder gives 2 64 233, the dividend.
Section 18.8
18.8.1. Though ease of hardware implementation is important, the method you choose is up to you, and depends
mainly on your habits and intuitive expectations. Consider the following examples:
dividend / divisor
+8
+8
8
8

/
/
/
/

+3
3
+3
3

rem 0

z System
quot.
+2
2
2
+2

rem.
+2
+2
2
2

quot.
+2
2
3
+3

rem.
+2
+2
+1
+1

rounded
quot.
+3
3
3
+3

rem.
1
1
+1
+1

Table 443. Examples of different types of integer division


1. With the z System rules, you expect the integer division of 8 by 3 to give quotient 2 and remainder 2, except for
signs.
2. With a nonnegative remainder, the magnitudes of quotient and remainder behave less comfortably.
3. The quotient of 8/ 3 should be near 3, and the remainder will fix it up. The rounded rule might be
chosen if the processor architecture represented all integer quantities in floating-point format.
18.8.2. Errors might occur in each case:
1. A R n,n will generate a fixed-point overflow if the result is not representable and an interruption if it is not masked
off. This occurs if c(GRn) 230 or c(GRn)< 230 .
2. A specification error will occur if n is odd.
3. A specification error will occur if n is odd; if n is even, a fixed point divide exception always occurs either because
c ( G R n , G R n + 1 ) 232 c(GRn), or because c(GRn)=0.

Programming Problem 18.1.


We start with a value of x=F/2, and reduce x until a divisor is found.
*
P18_1

Outer

Inner

Store

1112

Title Solution to Problem 18.1


Find prime divisors of N**3-1
START 0
BASR 15,0
Set base register
USING *,15
L
1,N
Get n
MR
0,1
n*n
M
0,N
n*n*n
S
1,=F 1
F(n)
LR
0,1
Initial x = F/2
SRA
0,1
x in GR0
LR
3,1
Set up divide
SR
2,2
Extend dividend
DR
2,0
F(n)/x
LTR
2,2
Check remainder
BZ
Store
Branch if zero
S
0,=F 1
x=x-1
B
Inner
Loop for next trial
ST
0,X
Store x
PrintOut N,X
Print values
L
1,N
Pick up n again
A
1,=F 1
n=n+1
Assembler Language Programming for IBM z System Servers

Version 1.00

N
X

ST
1,N
C
1,=F 8
BNH
Outer
PrintOut *,Header=NO
DC
F 2
DS
F
END
P18_1

Restore
Test if
Loop if
Stop
Initial

n
done
not for next n
value of n

Programming Problem 18.2.


The only real difficulty in this problem is computing the numerator function. In subtracting the final term 14, a logical
subtract must be used to detect carry conditions correctly. The method used in this solution for computing the denominator avoids the possibility of the fixed-point overflow that will occur when computing 2*Xn-5 for the last time.
P18_2

Begin

Skip

Rem
Quot
XN

Title Solution to Problem 18.2


START 0
BASR 15,0
Set base register
USING *,15
LA
3,1
Xn in GR3
LA
10,11
n in GR10
SR
5,5
3*n in GR5
LR
4,3
Calculate denominator
S
4,=F 5
Xn-5
AR
4,3
Xn + (Xn-5)
LR
1,3
Now start on numerator
A
1,=F10727
Xn + 10727
SR
0,0
Clear GR0
SLDA 0,0(5)
Xn*(Xn + 10727) in (GR0,GR1)
SL
1,=F 1 4
-14
BC
3,Skip
Branch if a carry
S
0,=F 1
Else borrow one
DR
0,4
Quotient in GR1, remainder in GR0
STM
0,1,REM
Store both for print
ST
3,XN
Store Xn for print
PrintOut XN,Quot,Rem
print results
SLL
3,3
Form new Xn
A
5,=F 3
3*n
S
10,=F 1
Count down on number of tests
BP
Begin
Loop for next n value
PrintOut *,Header=NO
Terminate
DS
F
DS
F
DS
F
END
P18_2

Programming Problem 18.3.


By using an integer table containing values of length 1 byte, this solution can use the same numeric quantity to index
through the list of primes and to count for termination.
P18_3

LoopA

LoopB

Title
START
BALR
USING
LA
SR
IC
ST
LA
SLL
S
ST
LA
S
MR

Solution to Problem 18.3


0
12,0
*,12
11,10
Number of primes p to test
10,10
Carry p in GR10
10,Table-1(11)
Get a prime from table
10,P
Store p for printing
9,1
Compute 2**p; set GR9 = 1
9,0(10)
Shift left p places
9,=F 1
M(p) now in GR9
9,MP
Store M(p) for printing
7,4
Set up S1=4
10,=F 2
Set counter for p-2 calculations
6,7
Sn*Sn
Suggested Solutions to Selected Exercises and Programming Problems

1113

Carry

F2
Table
P
MP
Residue

SL
7,=F 2
Subtract two
BC
3,Carry
Jump if a carry, no borrow
S
6,=F 1
Otherwise borrow from GR6
DR
6,9
Compute remainder modulo M(p)
LR
7,6
Move back to GR7
S
10,=F 1
Count down number of multiplies
BP
LoopB
Loop if still positive
ST
7,Residue
Store final residue
PrintOut P,MP,Residue
Print results
S
11,=F 1
Count down number of primes by 1
BP
LoopA
Get next p
PrintOut *,Header=NO
Terminate
DC
F 2
.*
DC
FL131,29,23,19,18,13,11,7,5,3 One-byte primes
DS
F
DS
F
DS
F
END

P18_3

Programming Problem 18.4.


P18_4

*
Loop
*

*
Print

*
X
Rem
Quot
Max

1114

Solution to Problem 18.4


0
15,0
Set base register
*,15
Inform assembler
1,1
Initial value of X
Assume worst case (denominator = 0)
L
2,Max
Set remainder
LR
3,2
And quotient
Calculate denominator
LR
5,1
c(GR5) = X
SH
5,=H 2 1
Subtract 21
MR
4,1
X*(X-21)
AH
5,=H 1 3 1
Add 131
MR
4,1
X*(X*(X-21)+131)
SH
5,=H 2 3 1
Subtract 231
BZ
Print
Go print if zero
Calculate numerator
LR
7,1
Move X to GR7
MR
6,7
X squared in GR7
LR
3,7
Move X**2 to GR3
AH
3,=H 7
Add 7
MR
2,7
Multiply by X**2
LR
2,3
Move to GR2 for shift
SH
2,=H 1 1
Subtract 11
SRDA 2,32
Position for division
DR
2,5
Divide by denominator
Store for printing
STM
1,3,X
Store X, Rem, Quot
PrintOut X,Rem,Quot
Print results
AH
1,=H 1
Add 1 to X
CH
1,=H 1 2
Compare to 12
BNH
LOOP
Branch if less or =
PrintOut *,Header=NO
Terminate program
Data areas
DS
F
Value of argument X
DS
F
Calculated remainder
DS
F
Calculated quotient
DC
F -2147483648
END
P18_4
Title
START
BASR
USING
SR

Assembler Language Programming for IBM z System Servers

Version 1.00

Programming Problem 18.5.


The largest value printed is 12 factorial = 479001600
P18_5

Loop

Done
N
NFact

Print NoGen
Start 0
Using *,15
LA
1,1
L
3,NFact
ST
1,N
MR
2,1
ST
3,NFact
SLDA 2,32
JO
Done
PrintOut N,NFact
LA
1,1(,1)
J
Loop
PrintOut *,Header=No
DS
F
DC
F 1
End
P18_5

Start with 1!
Get current value
Store value of N
Form N!
Store new value
Check for overflow
If overflow, all done
Print values
Increment N
Repeat
Stop
Current value of N
0! = 1

Suggested Solutions to Selected Exercises and Programming Problems

1115

Programming Problem 18.6.


Note that all arithmetic is done in the general registers!
P18_6
*
* Step

* Step

* Step

* Step

* Step

* Step

* Step

* Step

* Step

1116

Title Solution to Problem 18.6


START 0
Calculate date of Easter for a specified year.
Using *,15
(1)
LHI
0,19
Step (1) divisor
L
2,Year
Get year
SRDA 2,32
Extend to 64 bits
LR
5,3
Copy to GR5
LR
4,2
Copy high-order zeros to GR4
DR
2,0
Calculate Y/19, A in GR2
(2)
LHI
0,100
Step (2) divisor
DR
4,0
B in GR5, C in GR4
(3)
LR
6,5
Copy B to GR6
SRDL 6,2
D in GR6
SRL
7,30
E in GR7
(4)
LHI
0,25
Step (4) divisor
LR
8,5
Copy B to GR8
SLA
8,3
8B in GR8
AHI
8,13
8B+13 in GR8
SRDL 8,32
Extend to 64 bits
DR
8,0
G in GR9
(5)
LHI
0,30
Step (5) divisor
LR
10,2
Copy A to GR10
MHI
10,19
19A
AR
10,5
19A+B
SR
10,6
19A+B-D
SR
10,9
19A+B-D-G
AHI
10,15
19A+B-D-G+15
SRDL 10,32
Extend to 64 bits
DR
10,0
H in GR10
(6)
LHI
0,319
Step (6) divisor
LR
3,10
Copy H to GR3
MHI
3,11
11H
AR
3,2
A+11H
SR
2,2
Clear GR2
DR
2,0
M in GR3
(7)
SRDL 4,2
Divide C by 4
SRL
5,30
J in GR4, K in GR5
(8)
LHI
0,7
Step (8) divisor
AR
7,7
2E in GR7
AR
7,4
2E+J
AR
7,4
2E+2J
SR
7,5
2E+2J-K
SR
7,10
2E+2J-K-H
AR
7,3
2E+2J-K-H+M
AHI
7,32
2E+2J-K-H+M+32
SR
6,6
Clear high-order 32 bits
DR
6,0
L in GR6
(9)
LHI
1,25
Step (9) divisor
LR
0,10
H in GR0
SR
0,3
H-M
Assembler Language Programming for IBM z System Servers

Version 1.00

AR
0,6
H-M+L
LR
5,0
H-M+L in GR5
AHI
5,90
H-M+L+90
SR
4,4
Clear high-order 32 bits
DR
4,1
N in GR5
ST
5,Month
* Step (10)
AR
0,5
H-M+L+N in GR0
AHI
0,19
H-M+L+N+19
SRDL 0,5
Divide by 32
SRL
1,27
P in GR1
ST
1,Day
Printout Year,Month,Day,*,Header=NO
Year
DC
F2010
Month
DS
F
Day
DS
F
END
P18_6

Programming Problem 18.7.


Title Problem 18.7: Create a hexadecimal addition table
Print Nogen
P18_7
Start 0
Using *,15
Establish addressability
PrintLin HeadLine,L HeadLine Print heading line
SR
0,0
Initialize row value in GR0
L
6,=A(X F )
Initialize digit mask
Col_Loop SR
1,1
Initialize column value in GR1
LR
2,1
Copy column value to GR2
IC
2,Chars(2)
Get its EBCDIC representation
STC
2,Line+1
Store in the print line
L
3,=A(Line+3)
Initialize product-value position
Row_Loop LR
5,1
Copy column value
AR
5,0
Multiply by row value
LR
4,5
Copy product to GR4
SRL
4,4
Move to rightmost 4 bits
NR
4,6
Leave high-order digit in GR4
NR
5,6
Leave low-order digit in GR5
IC
4,Chars(4)
Get EBCDIC char for high digit
IC
5,Chars(5)
And for low digit
STC
4,0(,3)
Store high digit in print line
STC
5,1(,3)
Store low digit in print line
A
3,=F 3
Step to next print-line position
A
1,=F 1
Increment column value
C
1,=F 1 6
Check for finished with this line
BL
Row_Loop
If not done, repeat for next column
PrintLin Line,L Line
Print a line of the table
A
0,=F 1
Step to next row
C
0,=F 1 6
Check if all rows done
BL
Col_Loop
If not done, repeat for next row
Printout *,Header=NO
Terminate the program
Chars
DC
C0123456789ABCDEF
EBCDIC characters
HeadLine DC
C 1
0 1 2 3 4 5 6 7 8 9 A B C D E F
Line
DC
CL(L Headline)
End
P18_7

Programming Problem 18.8.

Suggested Solutions to Selected Exercises and Programming Problems

1117

Title Problem 18.8: Create a hex multiplication table


Print Nogen
P18_8
Start 0
Using *,15
Establish addressability
PrintLin HeadLine,L HeadLine Print heading line
SR
0,0
Initialize row value in GR0
L
6,=A(X F )
Initialize digit mask
Col_Loop SR
1,1
Initialize column value in GR1
LR
2,1
Copy column value to GR2
IC
2,Chars(2)
Get its EBCDIC representation
STC
2,Line+1
Store in the print line
L
3,=A(Line+3)
Initialize product-value position
Row_Loop LR
5,1
Copy column value
MR
4,0
Multiply by row value
LR
4,5
Copy product to GR4
SRL
4,4
Move to rightmost 4 bits
NR
4,6
Leave high-order digit in GR4
NR
5,6
Leave low-order digit in GR5
IC
4,Chars(4)
Get EBCDIC char for high digit
IC
5,Chars(5)
And for low digit
STC
4,0(,3)
Store high digit in print line
STC
5,1(,3)
Store low digit in print line
A
3,=F 3
Step to next print-line position
A
1,=F 1
Increment column value
C
1,=F 1 6
Check for finished with this line
BL
Row_Loop
If not done, repeat for next column
PrintLin Line,L Line
Print a line of the table
A
0,=F 1
Step to next row
C
0,=F 1 6
Check if all rows done
BL
Col_Loop
If not done, repeat for next row
Printout *,Header=NO
Terminate the program
Chars
DC
C0123456789ABCDEF
EBCDIC characters
HeadLine DC
C 1
0 1 2 3 4 5 6 7 8 9 A B C D E F
Line
DC
CL(L Headline)
End
P18_8

Programming Problem 18.9. This solution uses a symbolic constant ND to define the number of terms in the
sequence, and the number of fraction digits to be printed. The suggested limit of 115 digits is simply because the result
displayed by the PrintLin macro is limited by the length of a print line to 121 bytes.
P18_9

ND

1118

CSect ,
Print NoGen
Using *,15
Equ
60
XR
1,1
LA
2,ND
XR
6,6
LA
3,ND-1
LA
4,1(,3)
XR
7,7
IC
7,N(3)
MHI
7,10
AR
7,6
XR
6,6
DR
6,4
STC
6,N(3)
LR
6,7
BCTR 4,0
JCT
3,B
LA
6,X F0 ( , 6 )
STC
6,D(1)
LA
1,1(,1)
JCT
2,A
PrintLin V,L V+ND

Calculate E to ND digits (ND < 115)

Output digit index


Counter for digit index
Q = 0
Count K
K
Inner loop to generate a digit
Get working fraction R(K)
10*R(K)
10*R(K)+Q(K+1)
Clear high-order dividend
Divide by K
Save new R(K)
Copy Q(K)
K=K-1
Repeat inner loop
Make a zoned digit
Store in output string
Step output-digit index
Repeat for next digits
Print the result

Assembler Language Programming for IBM z System Servers

Version 1.00

N
V
D

PrintOut *,Header=NO
DC
(ND)X 1
DC
C -E=2.
DC
(ND)C
End
P18_9

Initial fraction numerators


Digit string

The printed output is:


-E=2.718281828459045235360287471352662497757247093699959574966967
By choosing a larger size for each array element, you can make the number of terms greater; and by multiplying by a
larger power of 10 you can generate multiple fraction digits on each iteration. You might enjoy using (for example)
halfword terms and generating four fraction digits on each iteration. Youll have to work out how best to display the
result on multiple print lines.

Programming Problem 18.10. This solution is not a very efficient way to search for prime numbers: test divisors need not be larger than the largest number less than the square root of the tested value.
Print NoGen
CSect ,
Equ
99
Using *,15
LA
2,2
PrintOut Prime,Header=No
LA
2,3
STH
2,Prime
PrintOut Prime,Header=No
LoopA
LA
2,2(,2)
LA
3,3
LoopB
LR
4,2
SRDA 4,32
DR
4,3
LTR
4,4
BZ
NotPrime
LA
3,2(,3)
CR
3,2
BL
LoopB
STH
2,Prime
PrintOut Prime,Header=No
NotPrime C
2,=A(MaxTest)
BL
LoopA
PrintOut *,Header=No
Prime
DC
H 2
End
P18_10
P18_10
MaxTest

Largest Odd value to test

Print the only even prime

Print the smallest odd prime


Generate next test value
Initial test divisor
Copy test number to GR4
Position test number for division
Divide by test divisor
Test remainder
Zero remainder, not prime
Next test divisor
Test for enough tests done
Try again if test divisor not too big
Print the next odd prime
See if test value is too big
Repeat if not
Stop
Initial value

Suggested Solutions to Selected Exercises and Programming Problems

1119

Section 19 Solutions
Section 19.2.
19.2.1. I cant think of a good reason. Maybe they thought it wouldnt happen often enough?
Section 19.3.
19.3.1. This can be done using the instruction
N

8,=A(X01FFFFFF )

First seven mask bits are zero

We will see in Section 21 that newer instructions can eliminate the need for a mask operand in memory!
Section 19.4.
19.4.1. The only important feature of the solution is the logical AND instruction. Since we are shifting in a 64-bit
register pair, we must guard against the possibility that a shift amount greater than 31 is specified, since this would lead
to loss of bits when the SLDL is executed. Thus, we mask off all but the rightmost 5 bits of the shift amount. (A
circular shift of 32 bits produces the original argument.)
SR
L
L
N
SLDL
OR
ST

0,0
1,Data
2,NShifts
2,=A(X 1 F )
0,0(2)
1,0
1,Data

Clear high-order register, GR0


Get word to be shifted into GR1
Load shift count into GR2
Mask shift count to 5-bit value
Shift by required amount
Rotate high bits to bottom end
Store rotated data

19.4.2. A simple solution follows from the observation that a 32-bit circular right shift of N places is the same as a
circular left shift of 32 N places.

GoAhead

SR
L
L
LTR
BNM
LCR
A
N
SLDL
OR
ST

0,0
1,Data
2,NShifts
2,2
GoAhead
2,2
2,=F 3 2
2,=A(X 1 F )
0,0(2)
1,0
1,Data

Clear GR0
Get data to be shifted into GR1
Get the shift count in Gr2
Check sign of shift
Proceed if nonnegative
Form -N
And now 32-N
Mask shift amount to 5 bits
Shift by required amount
Rotate high bits to bottom end
Store rotated data

Alternatively, and maybe more obviously:

Go
Finish

- - LTR
BNM
SLDL
N
SRDL
B
N
SLDL
OR
ST

2,2
Go
0,32
2,=A(X 1 F )
0,0(2)
Finish
2,=A(X 1 F )
0,0(2)
1,0
1,Data

Initialize GR0, GR1, and GR2


Check sign of N
Proceed if not negative
Exchange GR0 and GR1
Mask shift amount to 5 bits
Shift right the specified amount
And go complete the result
Mask for left shift
Shift left the specified amount
Complete the circular shift
Store the rotated answer

19.4.3. The register contents are unchanged, and the CC setting indicates a zero or a nonzero result. The LTR instruction sets the CC for nonzero results depending on the sign, so the methods are not strictly equivalent, because NR and
OR will not set the CC to 2.
Section 19.5
19.5.1. Consider all four possible bit combinations:
Initially
c(GR1) = 1100
c(GR2) = 1010

1120

After XR 1,2
0110
1010

After XR 2,1
0110
1100

After XR 1,2
1010
1100

Assembler Language Programming for IBM z System Servers

Version 1.00

and the two bit patterns have been interchanged.


This cant be done in the same way between registers and memory, because there is no Exclusive OR instruction that
operates between operands in memory and in a register, and leaves the result in memory.
19.5.2. Useless and unintelligible junk.
19.5.3. Consider a 2-bit register (no pun intended), and the four possible values 00, 01, 10, and 11 for A and B. Make
a table with 16 rows corresponding to the combinations of values of A and B, and columns for A, B, A+B, A A N D
B, (A+B) (A AND B), A OR B, (A OR B) (A AND B), and A XOR B. It works!
19.5.4. XOR is commutative that is, (A XOR B) is always the same as (B XOR A). The order of the operands
doesnt affect the final result, which is B in each case.
19.5.5. It works! The reasoning is the same as in Exercise 19.5.4:
XR
XR

1,0
0,1

means Old XOR New


means Old XOR (Old XOR New)

so the final result is the same as New because (Old XOR Old) is zero!
19.5.6. The second use of =F 1 can be replaced by SL

8,=F -1 .

Now: if we replace the preceding AL by SL 9,=F -1 , do we need to worry about the following BC? If you recall that
the subtraction is performed by adding the ones complement of the second operand (that will be zero) and a low-order
1-bit to the first operand, we see that nothing need be changed in the other instructions.
19.5.7. This statement also eliminates the need for the DS 0F:
DC

A(X 7 FFC0 )

Section 19.6
19.6.10. These instructions need only as many iterations as there are numbers of 1-bits in c(GR0).
A

Done

SR
LTR
JZ
BCTR
NR
JCT
LCR

2,2
1,0
Done
1,0
0,1
2,A
2,2

Set count of 1-bits to zero


Test if any 1-bits of X are left
Finished if none are left
Form X-1
Eliminate a 1-bit
Count down and test for completion
Count of 1-bits now in GR2

19.6.11. Yes. Consider X=2 31 1X 7 FFFFFFF ; then X + 1 is X80000000. Try the same for X=2 32 1.
19.6.12. If X=-1, the mask is zero: (NOT X) is zero, and (X+1) is also zero, so their AND is necessarily zero.
19.6.13. If X=0, the mask is all 1-bits.
19.6.14. If X=0, the mask is all 1-bits: (X-1) is all 1-bits, and XORing that with zero produces all 1-bits.
Section 19.7
19.7.1. Start with A=B 1010 and B=B 1100 , and see what results from NOT(A), NOT(B), AND(A,B), OR(A,B),
and XOR(A,B). The tables below show some combinations; note that not all combinations appear to be possible.

Simulating AND(A,B):

OR and NOT
NOT((NOT A) OR (NOT B))

XOR and NOT

XOR and NOT


(A XOR B) XOR NOT(A XOR B)

XOR and AND


(A AND B) XOR (A XOR B)

Simulating OR(A,B):

AND and NOT


NOT((NOT A) AND (NOT B))

OR and XOR
(A OR B) XOR (A XOR B)

Simulating XOR(A,B):

Suggested Solutions to Selected Exercises and Programming Problems

1121

AND and OR
Not possible: (1 A N D 1) and (1 OR 1)
can never be 0.

AND and NOT


NOT(NOT((NOT A) AND B) AND
(NOT(A AND (NOT B))))

OR and NOT
(NOT(A OR (NOT B))) OR
(NOT((NOT A) OR B))

Simulating NOT(A): remember that (NOT 0) is always 1, but none of (0 A N D 0), (0 O R 0), and (0 XOR 0) can
ever return 1. Thus theres no way to simulate NOT using any two of the other logical operators.

Programming Problem 19.1. This solution does not calculate the CC value for an arithmetic sum.
P19_1
RCar
RAop
RA
RBop
RB
RCC
RSum
Rct
RT
*

Start

*
Inner

*
Data

1122

Print
Start
Equ
Equ
Equ
Equ
Equ
Equ
Equ
Equ
Equ

NoGen
0
10
4
5
6
7
12
8
11
0

Carries kept in GR10


A operand in GR4 (even)
A bit kept in GR5 (next odd)
B operand kept in GR6 (even)
B bit kept in GR7 (next odd)
Condition code formed in GR12
Sum developed in GR8
Count reg for number of bits
Temporary register

Using
LM
SR
LR
LR
L
L
LA
ST
ST

*,15
1,3,DataPtr
RCC,RCC
RCar,RCC
RSum,RCC
RAop,Data(1)
RBop,Data+4(1)
Rct,32
RAop,A
RBop,B

Set loop registers for cases


Initial CC set to 0
Initial carry = 0
Initial sum = 0
Initial A operand
Initial B operand
Initialize bit counter
Save A for printing
Same with B

SRDL RAop,1
Shift out the A bit
SRL
RA,31
Position at right end
SRDL RBop,1
Shift out B bit
SRL
RB,31
Position at right end
OR
RSum,RA
Insert the new a bit
XR
RSum,RB
Exclusive or with B bit
XR
RSum,RCar
And with old carry bit.
OR
RCC,RSum
Use sum for zero/nonzero CC
SRDL RSum,1
Move sum bit 1 place to right
LR
RT,RCar
Compute new carry bit
NR
RT,RA
(Old carry) and ( A bit)
NR
RA,RB
( A bit) and ( B bit)
NR
RCar,RB
( B bit) and (old carry)
OR
RCar,RA
OR
RCar,RT
New carry bit now complete
S
Rct,=F 1
Reduce count
BP
Inner
Process next bit
ALR
RCar,RCar
Double final carry bit
OR
RCC,RCar
Pack into condition code
STC
RCC,CCL
Store for printing
ST
RSum+1,Sum
Store sum for printing
PrintOut A,B,Sum,CCL,Header=No
Print results
AR
1,2
Increment data index
CR
1,3
Compare to last address
BNH
Start
Continue with next data pair
PrintOut *,Header=No
Terminat program
DS
DC
DC
DC

0D
Start of test cases
X FFFFFFFF,00000001 Sum
zero,
carry: LCC=2, ACC=3
X11111111,12345678 Sum nonzero, nocarry: LCC=1, ACC=2
X00000000,00000000 Sum
zero, nocarry: LCC=0, ACC=0

Assembler Language Programming for IBM z System Servers

Version 1.00

EnData
DataPtr
Sum
A
B
CCL

DC
Equ
DC
DS
DS
DS
DC
END

X FEDCBA98,12345678 Sum nonzero,


carry: LCC=3, ACC=1
*
A(0,8,EnData-Data-8)
XL4
Final sum
XL4
Initial A operand
XL4
Initial B operand
X FF
Logical-Add Condition Code
P19_1

Programming Problem 19.2.


In we first initialize S(0) to A and 2*C(0) to B, we are ready to enter the loop. The sum is accumulated in GR1, carries
are carried in GR3, and GR4 holds the working CC setting.

Loop

Done

StoreCC

SR
L
L
LR
XR
NR
ALR
BC
BC
L
BC
ST
LTR
BZ
A
ST

4,4
1,A
3,B
2,1
1,3
3,2
3,3
8,Done
4,Loop
4,=F 2
1,Loop
1,Sum
1,1
StoreCC
4,=F 1
4,CCodeL

Cet CC to zero, no carry condition


Initialize GR1 to S(0)
initialize GR3 to 2*C(0)
Move S(n) to temporary in GR2
Form S(n+1) in GR1
Form C(n+1)
Shift carries left by 1 position
If zero and no lost bit, we re done
If nonzero and no lost bit, repeat
A bit carried out: set partial CC
If more carries to do, repeat
Store final sum
Check for nonzero result
Jump if sum is zero, CC is okay
Set CC to indicate nonzero sum
Store final Condition Code

Determining the CC setting for arithmetic addition is left as an additional exercise for you.

Programming Problem 19.4.


The value NMax is defined so that the number of values tested is a multiple of 8; this allows proper packing of the results
in the bit string at PrimeBts.
P19_4
N
NMax
Mark

MarkLoop

Marking

FindNext

MarkDone
ByteLoop

Print
CSect
Equ
Equ
Equ
Using
LA
LA
LR
LA
CR
JNL
LA
MVI
AR
CR
JL
LA
CR
JNL
LA
CLI
JE
J
LA
LA
LA

NoGen
,
400
((N/8)*8)
0
*,15
0,NMax
1,2
2,1
3,0(2,2)
3,0
MarkDone
4,Table-1(3)
0(4),Mark
3,2
3,0
Marking
1,1(,1)
1,0
MarkDone
4,Table-1(1)
0(4),Mark
FindNext
MarkLoop
4,PrimeBts
1,Table
2,8

Maximum number to test


Round to a multiple of 8
Mark composites with zero
Maximum value to test
Starting value
Stepping increment
Starting index
Check for end of table
Done with marking if so
Address of a Table entry
Mark the entry as composite
Step to next
Test for past end of table
Repeat if not done
Increment starting value
Done all values?
Branch if yes
Point to next position in Table
Check for marked position
This one marked, look again
Try next values
Address of bit string
Address of marked table entries
Count bits packed in a byte

Suggested Solutions to Selected Exercises and Programming Problems

1123

SR
3,3
Bits packed in GR3
PackLoop SLL
3,1
Make room for next bit
CLI
0(1),Mark
Was this byte marked?
JE
NotPrime
Skip bit insertion if yes
LA
3,1(,3)
Insert a 1-bit for a prime
NotPrime LA
1,1(,1)
Point to next byte for mark test
S
2,=F 1
Count down bits in the byte
JP
PackLoop
Repeat for all 8 bits
STC
3,0(,4)
Store the packed byte in the string
LA
4,1(,4)
Step to next packed byte position
S
0,=F 8
Count down number of bytes tested
JP
ByteLoop
Repeat if more bytes to be packed
PrintOut PrimeBts,*,Header=No Show the results
Table
DC
(NMax)X 1
Initialize all to prime
PrimeBts DC
XL(NMax/8) 0
Prime bits
End
P19_4
The output is:
PrimeBts = X EA28A20A08A20828228220808A28800220A00A08220828028A00200228828020820A08A00800228800208028820208220809

Programming Problem 19.5.


The modifications to the solution to Problem 19.4 are simple; the output is:
PrimeBts = X F6D32D265948B6814C325261B0416984932C205A0486912522
The largest prime representable in a string of 2 30 bits would be less than 234..

1124

Assembler Language Programming for IBM z System Servers

Version 1.00

Section 20 Solutions
Section 20.1
20.1.1. The generated Effective Addresses are:
1.
2.
3.
4.

X 0174629A
X 01749816
X 0172629C
X 0174629E

20.1.2. The generated Effective Addresses are:


1.
2.
3.
4.

X 007B1EEE
X 007D68D2
X 00734EC4
X 007B1EF6

20.1.3. The generated Effective Addresses are:


1.
2.
3.
4.

X 9610C63C
X 9610D2FC
X 9610C640
X 9610A63A

20.1.4. The IA has already been incremented by the length of the current instruction, which could be either 4 or 6 bytes
long.
20.1.6. The respective Effective Addresss are:
(a) X27B9B4
(b) X27B976
(c) X2839CC
(d) X26B9AE
20.1.7. You cant. The address of an instruction is always even, and 2 I2 is also even.
20.1.8. This might better be called offset addressing. Its a risky technique, because something might be inserted
between the symbolic target A or * and whatever is at the offset from that location; finding and correcting such usage is
tedious and error-prone.
Section 20.2
20.2.1. The generated Effective Address in 24-bit mode is X 00360A , in 31-bit mode is X 0200360A , and in 64-bit
mode is X 000000008200360A .
20.2.2. The generated Effective Addresses are shown in the following table:
No.
1

24-bit mode
X10C63C

31-bit mode
X1610C63C

64-bit mode
X000000009610C63C

X10D2FC

X1610D2FC

X000000009610D2FC

X10C640

X1610C640

X000000009610C640

X10A63A

X1610A63A

X000000009610A63A

Section 20.3
20.3.1. LARL always adds its address to 2 I2, so the value in R1 depends on the address of the LARL itself!
20.3.2. If we write LA reg,0(0,reg) we get the same effect: in 24-bit addressing mode, the high-order byte is set to
zero. The value of reg cannot be zero for the LA (why?). It may make a difference in some cases that the N instruction sets the condition code, but LA leaves it unchanged.
20.3.3. No, because the second operand appears to be an implied indexed address:
and NoErr is relocatable and therefore invalid as an index register specification.

A may not be a defined symbol,

Suggested Solutions to Selected Exercises and Programming Problems

1125

20.3.4. No, because GR9 will contain the address of the literal, not the address of NoErr. Yes, if the LA is replaced by
L and the literal is addressable.
20.3.5. The differences depend on three factors: whether NoErr is addressable, whether the literal is addressable, and
the current addressing mode.
1. If both are indeed addressable, the results will be equivalent. This is true whether NoErr is absolute or relocatable.
LA is preferable if NoErr is addressable, since it saves the four bytes required for the literal and the extra
execution-time memory reference.
2. The second form is necessary if NoErr is not addressable. They are not equivalent if the literal is not addressable.
3. A-type constants dont depend on the addressing mode, while the LA and LAY instructions do. Normally this
wont be a concern.
20.3.6. The claim is true. You could also write this code sequence:
LA
SRL

8,X 1 0 1 ( , 5 )
8,0(8)

Its worth understanding how this works!


20.3.7. Using LA to increment general register contents is limited to
(1) values of number between 0 and 4095, and to
(2) nonzero values of GRx, and
(3) depends on the current addressing mode. For AMode 24, the sum cannot exceed 2 24 1, and for AMode 31, the
sum cannot exceed 2 31 1. There is no limit on the sum for AMode 64.
If number is defined in an EQU statement, the halfword literal cant be used. (But, you could then use =Y(number)
instead!)
In each case, its possible for the sum to exceed the given limit and wrap around to zero. Consider incrementing
c ( G R 1 ) = X 0 0 F F F F F F by 2 in 24-bit addressing mode: the Effective Address is 1!
In most cases, these three restrictions are satisfied. The CC setting is rarely interesting in such situations, so there is
little reason to use AH. Also, the two bytes for the literal and an execution-time memory reference are saved.
20.3.8. The object code from the assembled instructions looks like this:
E300 0120 7A71
E310 0EE0 8571

LAY
LAY

0,500000
1,-500000

In the second instruction, you will see that the high-order bit of DH is X 80 , indicating a negative long displacement.
If the addressing mode is 24- or 31-bit mode, the result of the second LAY instruction will be X 00F85EE0 or
X 7FF85EE0 , respectively: neither is 500000! You will get the intended negative value only if the addressing mode
is 64-bit mode.
20.3.9. In the first case, the initial c(GR6) is X 0 0 F F F F F F and the result will be + 1, because the generated Effective
Address X 01000001 retains only the low-order 24 bits. In the second case, the generated Effective Address will be
X 00FFFF02 .
20.3.10. Unless the LAY instruction is executed in 64-bit addressing mode, the Effective Address in GR3 will be
X 0 0 F F F F F F in 24-bit mode, and X 7 F F F F F F F in 31-bit mode.
20.3.11. The results depend on the contents of the two registers. If c(GRy) is a non-negative integer with value less
than 2 24, they are equivalent. Otherwise, the LA instruction will truncate significant high-order bits if the value is either
negative or greater than or equal to that value, for addressing modes 24 and 31. For addressing mode 64, they are
(almost) equivalent except that LA will change the high-order 32 bits of GGx.
20.3.12. You could use something like the following:

BList

LARL
AR
BR
- - J
J
J
J

0,BList
15,0
15

Address of branch list


Form address of selected branch
Branch to the correct one

A
B
C
D

None of the instructions requires a base register.


20.3.13. Remember: specifying register zero as a base or index register means no register!

1126

Assembler Language Programming for IBM z System Servers

Version 1.00

20.3.14. In 24-bit addressing mode, the results in GR10 are:


1. X00001234
2. X0000ABCD
and in 31-bit addressing mode, the results in GR10 are
1. X00001234
2. X007FABCD

(the same)

20.3.15. The Effective Addresses in 24-bit and 31-bit addressing modes are:
1. X0000FE ( 2 4 ) , X000000FE ( 3 1 )
2. X01831B ( 2 4 ) , X 1 B01831B ( 3 1 )
3. X000009(24), X01000009(31)
20.3.16. The resulting Effective Addresss are:
(a) No Effective Address can be generated, because the instruction cannot be addressed by the IA in the PSW! The
CPU will attempt to fetch an instruction at address X 003B6D0E .
(b) The Effective Address is X 543B6D0E .
(c) The Effective Address is X 00000000543B6D0E .

Suggested Solutions to Selected Exercises and Programming Problems

1127

Section 21 Solutions
Section 21.1
21.1.1. The operand 76543 is too large for a halfword operand, so the instruction cant be assembled without error.
You can use either of these instructions instead:
LGFI
IILF

0,76543
0,76543

...clears high-order half of GG0


Insert operand into GR0

In each case, the assembled I2 operand is X 00012AFF .


21.1.2. The difference is in notation: an I2 immediate operand is used in an arithmetic or logical operation, while an
R I 2 immediate operand is used in a relative-offset instruction such as a branch.
Section 21.2
21.2.1. The AFI instruction with a negative operand does what the SFI instruction would do with an operand of the
opposite sign. But: why is there a SLFI instruction?
21.2.2. This is the same solution as for Exercise 18.2.7, but with literal references replaced by immediate operands.

Loop

NoCarry

LHI
SR
LR
LH
MH
SRDA
ALR
BC
ALFI
ALR
AHI
AHI
AHI
BP
STM

2,10
0,0
1,0
4,0(,11)
4,0(,12)
4,32
1,5
12,NoCarry
0,1
0,4
11,2
12,2
2,-1
Loop
0,1,DwSum

* Count items in GR2


Accumulate sum in (GR0,GR1)
Initialize sum to zero
Get an operand
Multiply by the other
Extend word product to 64 bits
Add low-order words
Skip carry add if none to add
* Add a carry bit
Now add high-order words
* Add 2 to address of first table
* And to the address of second table
* Count down items by 1
Repeat if not done
Store accumulated sum

Section 21.3
21.3.1. Consider the (possible) XIHH instruction: its 16-bit operand would be XORed with the high-order 16 bits of
G G R 1, where X wxyz represents any arbitrary bit pattern.

HH

HL

LH

LL
GG R1

XIHH

X wxyz
XIHH Instruction

Because XORing a 0-bit to any other bit leaves it unchanged,


XIHH reg,X wxyz
XIHF reg,X wxyz0000

is equivalent to
... so XIHH is not needed.

21.3.2. Consider the NIHH instruction. Because ANDing a 1-bit to any other bit leaves that bit unchanged,
NIHH
NIHF

reg,X wxyz
reg,X wxyzFFFF

is equivalent to
... so NIHH is not needed.

So, why are NIHH/HL/LH/LL present? z System implemented 16-bit immediate operands much earlier than support
for 32-bit immediate operands, and RIL-type instructions like NIHF and NIHL appeared much later. But, the RI-type
instructions also save 2 bytes in the instruction stream, in case your program needs to be as small as possible.
21.3.3. Consider OIHH: ORing a 0-bit to any other bit leaves the other bit unchanged, so that

1128

Assembler Language Programming for IBM z System Servers

Version 1.00

OIHH
OIHF

reg,X wxyz
reg,X wxyz0000

is equivalent to
... so OIHH is not needed.

See the last paragraph of the previous solution for details.


21.3.4. Use NILH

1,X FF00

21.3.5. Use XIHF

7,X80000000

21.3.6. You can use these three instructions:


AHI
OILL
XILL

2,15
2,15
2,15

Force carry if not multiple of 16


Set low-order 4 bits to 1
Set low-order 4 bits to 0

21.3.7. The code will probably fail to give the intended result, because the NILL instruction operates only on the rightmost 16 bits of GR3. Thus, if GR3 had contained X F F F F F F F F , after the NILL instruction
c ( G R 3 ) = X F F F F 0 0 F 0 , which is smaller than X 00000070 Similarly, if GR3 had contained X 12345678 , its contents after the NILL instruction would be X 12340070 , and the branch to BitWas1 would be successful. These might
not be the intended results.
21.3.8. These are possible critiques of the three sequences:
1. A word is required in storage for the literal.
2. Two instructions are required.
3. Three instructions are required, and the contents of GR5 is destroyed.
A better solution is
NILF

4,X 3 F

Fullword immediate operand

21.3.9. This solution is almost correct (see the solution to Exercise 21.3.8). Because NILL uses a 16-bit immediate
operand, it fails if there are any nonzero bits in the high-order half of GR4. Suppose c(GR4)=X12345678: then
NILL

4,X003F

yields c(GR4) = X12340038

which is probably not a satisfactory result.

Programming Problem 21.1. This is another way to produce a hexadecimal addition table:
Title Create a hexadecimal addition table
Print Nogen
P21_1
Start 0
Using *,15
Establish addressability
PrintLin HeadLine,L HeadLine Print heading line
LHI
0,0
Initialize row value in GR0
LHI
6,X F
Initialize digit mask
Col_Loop LHI
1,0
Initialize column value in GR1
LR
2,0
Copy column value to GR2
IC
2,Chars(2)
Get its EBCDIC representation
STC
2,Line+1
Store in the print line
LA
3,Line+3
Initialize product-value position
Row_Loop LR
5,1
Copy column value
AR
5,0
Multiply by row value
LR
4,5
Copy product to GR4
SRL
4,4
Move to rightmost 4 bits
NR
4,6
Leave high-order digit in GR4
NR
5,6
Leave low-order digit in GR5
IC
4,Chars(4)
Get EBCDIC char for high digit
IC
5,Chars(5)
And for low digit
STC
4,0(,3)
Store high digit in print line
STC
5,1(,3)
Store low digit in print line
AHI
3,3
Step to next print-line position
AHI
1,1
Increment column value
CHI
1,16
Check for finished with this line
JL
Row_Loop
If not done, repeat for next column
PrintLin Line,L Line
Print a line of the table
AHI
0,1
Step to next row
CHI
0,16
Check if all rows done
Suggested Solutions to Selected Exercises and Programming Problems

1129

JL
Col_Loop
If not done, repeat for next row
Printout *,HEADER=NO
Terminate the program
Chars
DC
C0123456789ABCDEF
EBCDIC characters
HeadLine DC
C 1
0 1 2 3 4 5 6 7 8 9 A B C D E F
Line
DC
CL(L Headline)
End
P21_1

1130

Assembler Language Programming for IBM z System Servers

Version 1.00

Section 22 Solutions
Section 22.1
22.1.1. Unfortunately, the letter L is used in many mnemonics to mean Low as well as Long. The branch
relative on condition with a 16-bit I2 operand and mask 4 already uses the JL mnemonic, so the unconditional long
relative branch needed a different name.
22.1.2. If your program uses no program base registers for instructions, its possible that an instruction like
NOP

could require base-displacement resolution. Using JNOP and JLNOP means you wont need a base register to resolve
the operand address. (You could always write your NOP instruction using explicit base and displacement, but why do
the extra work?)
Sometimes the operands of NOPs are used to indicate a position in the program. For example, if you wanted to
mark a set of instructions that can be viewed by debuggers and other diagnostics, you could write
JNOP

137

Marker for item 137 s position

22.1.3. The generated machine instructions are:


(a)
(b)
(c)
(d)

A7F4
A7F4
A7F4
C0F4

FFFB
03FF
FFD8
0000 0001

Executing the last instruction will cause an operation exception, because it will branch into the second halfword of the
instruction that contains zeros.
Section 22.2
22.2.1. The result will be the same as if you had written
Str

DC

CL80 String to be Scanned For Special Characters

22.2.2. The only changes needed are to these three statements:


JNL
Okay
- - CHI
1,80
- - JL
GetChar

Branch if a letter or digit


Compare count to 80 (string length)
Loop if less than 80 done so far

Section 22.3
22.3.2. The indexed branch instruction labeled A2 cannot be changed, because relative branch instructions cannot be
indexed. However, you can fix this by rewriting it as
A2

LA
BR

1,BrTbl(1)
1

Form address of target instruction


Branch to it

If local addressability for the LA instruction is not available, you could use this approach:
A2

LARL
AR
BR

0,BrTbl
1,0
1

Address of start of branch table


Add to offset into the table
Branch to it

Section 22.4
22.4.1. Replace the two instructions
Loop

LA
2,0(1,1)
BCTR 2,0

(Count + Count) in GR2


(2 * Count) - 1

with the single instruction


Loop

LAY

2,-1(1,1)

(Count+Count) - 1 in GR2

22.4.2. Fixed-point overflows never occur in executing Branch on Count instructions.


22.4.4. A direct solution tests every bit, counting the one-bits, until the K-th bit is found. This solution uses some
arithmetic-immediate instructions.

Suggested Solutions to Selected Exercises and Programming Problems

1131

Outer

Inner

ZeroBit

Found

SR
L
LA
IC
SLL
LA
LTR
JNM
AHI
JZ
AHI
SLL
JCT
AHI
J
ST

0,0
1,KK
2,Str
3,0(,2)
3,24
4,8
3,3
ZeroBit
1,-1
Found
0,1
3,1
4,Inner
2,1
Outer
0,BitOff

Initialize bit offset


Initialize 1-bit count
Initialize byte pointer
Pick up a byte for testing
Position at left end
Initialize shift count
Is the bit a 1-bit?
Branch if not
Have a 1-bit, deduct 1 from K
Finished if it s the K-th one
Increment bit offset
Out with the old, in with the new
Count bits in this byte and loop
Increment byte pointer
... and go get a new byte
Store the desired bit offset

22.4.5. Probably, something strange. If c(GRb) is even (as an instruction address must be) before executing the BCT,
control will arrive at the branch location with an odd value (that address, minus 1) in GRb. If c(GRb) is + 1, no
branch occurs and the next instruction after the BCT will be executed. If c(GRb) is odd (and not + 1), the program will
try to branch to an odd address, but the number in GRb will then be even; a specification error will occur due to the
odd branch address, which will be hard to find because the contents of the register will now be even. Dont do this!
22.4.6. The only thing needing care here is to be sure we store the first value.

Loop

Store
Next

LA
LA
LA
L
J
L
C
JE
LA
ST
LA
JCT
S
SRL
ST

1,100
2,NewList-4
3,IntList
0,IntList
Store
0,0(,3)
0,0(,2)
Next
2,4(,2)
0,0(,2)
3,4(,3)
1,Loop
2,=A(NewList-4)
2,2
2,NumNews

Count list items in GR1


Output table addr in GR2 (delayed)
Input table addr in GR3
Pick up first item
And enter in output list
Get item from list
Compare to previous
Don t store if equal
Increment storage address
Store into NewList table
Increment IntList address
And repeat
Subtract start address
Divide by element length
Store number of new elements

22.4.7. It makes one extra iteration of the loop, and therefore calculates (N+1) 2.
22.4.8. The USING and BASR are reversed. At execution time, the implied addresses AA and Loop will actually refer
to AA+2 and LOOP+2 instead! The sum in GR2 is therefore 2+3+4+5 instead of 1+2+3+4. (It may be worth
reviewing Section 10.)
Heres the assembled program:
000000
000000
000002
000006
00000A
00000C
00000E
000012
000016
00001A
00001C
000000

0D80
4140 0004
4170 801C
1B22
0700
4A20 7000
4170 7002
4640 800C
0A03
0001000200030004

1 Ex22_4_8 START 0
2
USING *,8
Establish addressability
3
BASR 8,0
Set base register
4
LA
4,4
Initialize counter
5
LA
7,AA
Initialize address
6
SR
2,2
Set sum box to zero
7 Loop
NOPR 0
Let the CPU catch its breath
8
AH
2,0(,7)
Add a data item to the sum
9
LA
7,2(0,7)
Increment address by 2
10
BCT
4,Loop
Branch back if not done
11
SVC
3
Do something unforgettable
12 AA
DC
H 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9
Table of numbers
13
END
Ex22_4_8

22.4.10. This solution uses the techniques of Section 19:

1132

Assembler Language Programming for IBM z System Servers

Version 1.00

Done

XGR
LTGR
JZ
BCTGR
NGR
AHI
J
- - -

0,0
2,1
Done
2,0
1,2
0,1
X

Set count in GG0 to zero


See if all bits of GG1 are zero
If all zero, count is finished
Decrement GG2 by 1
Set rightmost bit of GG1 to zero
Increment count
Repeat until c(GG1) = 0
Count of 1-bits now in GG0

22.4.11. Consider these instructions:


Test

Done

XR
CLM
JNL
ALR
BCT
LCR

1,1
0,8,X 4 0
Done
0,0
1,Test
1,1

Set shift count to zero


Check for 1-bit in bit position 1
Branch if it s there
Shift c(GR0) left one bit
Count down and loop
Make shift count positive

22.4.12. This shows the generated object code:


Loc
0000

Object Code
0DC0

0002
0006

4130 0040
4170 C03A

000A
000E
0012
0016

5800
5A00
5800
4630

001A
003C
013C
023C

7000
7100
7200
C008

<something>

Assembler Language Statements


BASR 12,0
Using *,12
LA
3,64
LA
7,A
Using A,7
Loop
L
0,A
A
0,B
ST
0,C
BCT
3,Loop
Drop 7
PrintOut *
A
DS
64F
B
DS
64F
C
DS
64F

22.4.13. The program actually calculates C(1)=A(1) + B(1) 64 times! To make it work correctly, insert
LA

7,4(,7)

before the BCT instruction.


22.4.14. The errors are:
1. The SLL instruction should occur after testing the sign bit; otherwise only 31 bits will be tested.
2. The BZ instruction should be BNM; BZ will branch only if the entire contents of GR1 is zero.
3. An LA instruction cant be used to increment GR0.
The corrected code might look like this:

Loop

Next

SR
LA
LTR
BNM
A
SLL
BCT

0,0
2,32
1,1
Next
0,=F 1
1,1
2,Loop

Set count to zero


Count 32 bits
Test sign bit
Branch if sign bit is zero
Add 1 to count of 1-bits
Shift a bit into sign position
Repeat for all 32 bits

22.4.15. This solution uses the RLL (Rotate Left Logical) instruction:

Loop

Next

SR
LA
LTR
BNM
AHI
RLL
BCT

0,0
2,32
1,1
Next
0,1
1,1,1
2,Loop

Set count to zero


Count 32 bits
Test sign bit
Branch if sign bit is zero
Add 1 to count of 1-bits
Rotate a bit into sign position
Repeat for all 32 bits

Suggested Solutions to Selected Exercises and Programming Problems

1133

22.4.16. All five sequences yield the same result, the twos complement of the number in R0. The first two give the
same (arithmetically valid) CC setting. The third will indicate CC values of either 2 (the result is zero), or 1 (the result is
not zero). The fourth and fifth lead to CC settings of 0 (the result is zero) or 1 (the result is not zero).
22.4.17.
(1) The instructions add 1 arithmetically to c(GR0). If c(GR1)=X, the first LCR generates X. The BCTR generates X 1, and the final LCR generates ( X 1) = X + 1.
(2) They imitate the action of (a) AHI 0,1 or (b) A 0 , = F 1 (among other possibilities).
(3) The Condition Code settings are identical for the two instructions noted in (2). 312
Section 22.5
22.5.1. This solution uses indexed LH and STH instructions:

LOOP

LA
LH
AR
SR
LH
STH
AR
SR
JP

2,2
1,NN
1,1
3,3
0,HH-2(1)
0,RR(3)
3,2
1,2
LOOP

For incrementing/decrementing
Start at end of HH array
N*2 (for halfword indexing of HH)
Index at RR starts at 0
Get word from high end of HH
Store at low end of RR
Increment RR index
Decrement HH index
Repeat until index = 0

22.5.3. Do-Until.
Section 22.7
22.7.1. For BXLE, the branch will not be taken, and c(GR3) = 2. For BXH, the branch will be taken, and c(GR3)
= 2 again.
22.7.2. For BXLE, c(GR3) = 6, and no branch occurs. For BXH, c(GR3) = X C0000000 ! The BXH instruction was
executed 29 times.
22.7.3. The branch will occur only if the remainder was zero! If the remainder is greater than zero, the sum of
remainder and quotient will be greater than the quotient in GR7, and no branch will occur.
22.7.5. The claim is true. If the sum c(GRx) + c(GRy) is non-negative, it is also 231 1, so the claim holds. If the sum
is less than zero it has overflowed, and the BXLE instruction does not branch. Logically, the sum cannot exceed
2 231 1, so subtracting 2 31 1 gives the correct result modulo 231 1.
Another way to say this: if a,b are m, and if a + b > m, then a + b m = a + b (mod m). 313
22.7.6. Suppose the next-to-leftmost bit of the positive number is 1. Then the SLA will indicate an overflowed (not a
negative) result. Then (1) the JM should be be JO or JNP, and (2) GR0 should be initialized to contain 1, not 0. The
shift count in GR3 can be reduced to 31:
LA
LR
LA
SLA
JO
JXLE
- - -

0,1
2,0
3,31
1,1
Y
0,2,X

Initialize bit position


Increment of 1 in GR2
Comparand in GR3
Shift, test bit next to sign
Exit if it was 1
Count and loop if it was 0

22.7.9. The BXLE instruction is executed 6 times, and branches 5 times. The sequence of values in GR1 is 7, 24, 41,
58, 75, and 92.
22.7.10. (C A)/B + 1 times. (If the value of the expression is not positive, the body of the loop is executed only once.)

312
313

A performance expert (Dan Greiner) tested all possible 2 32 possible values to show their equivalence. The test took only a few
seconds.
The student was Donald Knuth.

1134

Assembler Language Programming for IBM z System Servers

Version 1.00

Section 22.8
22.8.1. The results are shown in this table:
c(GR1)
0, 1
positive,
2
negative

BXH
c(GR1)=0
(sum and comparand are 0)
Endless loop
(sum > comparand)
Set low-order bit of GR1 to 0
(sum , comparand + )

BXLE
Endless loop
(sum and comparand are 0)
Set low-order bit of GR1 to 0
(sum > comparand)
Endless loop
(sum , comparand + )

Section 22.9
22.9.1. c(GR2) will be 40. The instructions calculate the largest doubling of c(GR2) not exceeding c(GR3). But be
careful: If c(GR3)=X 7 F F F F F F F and c(GR2)=1, 2*c(GR2) will eventually overflow and become negative. At that
point, after at most 32 iterations, c(GR2) will become zero, and the BXLE instruction will then loop endlessly. (Dont
try it!)314
22.9.2. After the BXLE instruction has been executed once, c(GR5)=2. This is compared to the original value in GR5
(the comparand), which was 1. This is no longer less than or equal to the sum, so the final value in GR5 is 2.
For BXH, the sum is greater than the comparand each time BXH is executed, until the sum overflows after 31 iterations. c(GR5) then is negative, which when compared to the comparand X 40000000 is no longer greater, so the
final value in GR5 is X 80000000 .
22.9.3. The two leftmost bits of the positive number in GR1 can be either 00 or 01. If they are 00, then the first BXH
produces a larger but still positive number in GR1, and will branch to ZBit to increment the count. If the leftmost two
bits are 01, the sum (formed by the BXH) in GR1 will become negative, and the BXH at Loop will not branch.
If the number in GR1 was arbitrary, a test for zero would be needed to exit the entire code sequence; if the number
could be negative, LTR/JM instructions could indicate that bit number 0 was a 1-bit.
22.9.4. Consider the two high-order bits of GR1:
1. B 00 means that c(GR1) is positive, and the sum of the index and comparand will not overflow. The sum is
greater than the comparand (the original c(GR1)), so the instruction will branch.
2. B 01 means that c(GR1) is positive, but the sum of the index and comparand will overflow and appear negative.
The sum is then less than the comparand (the original c(GR1)), so the instruction will not branch.
3. B 10 means that c(GR1) is negative, but the sum of the index and comparand will overflow and appear positive.
The sum is then greater than the comparand (the original c(GR1)), so the instruction will branch.
4. B 11 means that c(GR1) is negative, and the sum of the index and comparand will not overflow. The sum is then
less than the comparand (the original c(GR1)), so the instruction will not branch.
22.9.5. Consider the two high-order bits of GR1:
1. B 00 means that c(GR1) is positive, and the sum of the index and comparand will not overflow. The sum is
greater than the comparand (the original c(GR1)), so the instruction will not branch.
2. B 01 means that c(GR1) is positive, but the sum of the index and comparand will overflow and appear negative.
The sum is then less than the comparand (the original c(GR1)), so the instruction will branch.
3. B 10 means that c(GR1) is negative, but the sum of the index and comparand will overflow and appear positive.
The sum is then greater than the comparand (the original c(GR1)), so the instruction will not branch.
4. B 11 means that c(GR1) is negative, and the sum of the index and comparand will not overflow. The sum is then
less than the comparand (the original c(GR1)), so the instruction will branch.
22.9.6. This exercise is most easily analyzed with a table:

314

I did, and thats why I know you shouldnt.


Suggested Solutions to Selected Exercises and Programming Problems

1135

c(GR0)
0
>0
0
>0
>0
>0
<0
<0
<0

c(GR1)
any
0
0
> 0, sum
> 0, sum
<0
< 0, sum
< 0, sum
>0

does not overflow


overflows
does not overflow
overflows

Branch?
No
Yes
No
Yes
No
Yes
No
Yes
No

You can sometimes make efficient use of BXH and BXLE if the operands in the index and increment/comparand
registers fit one of the patterns above.
22.9.7. The solution to this exercise uses the same table as in Exercise 22.9.6, except that each Yes and No is
reversed.
22.9.8. If the R1 operand is not equal to either the R 3 or R 3 |1 operands, this description is correct. And since most
uses of the branch on index instructions are used this way, little harm is usually done. However, consider these
instructions:
LHI
LHI
BXLE

6,2
7,2
7,6,XXX

c(GR6) = 2
c(GR7) = 2
Will it branch?

In our description, the sum of the index in GR7 (2) and the increment in GR6 (2) is greater than the comparand in
GR7 (2), so the branch will not occur.
In the incorrect description, the sum replaces the index before comparison: the sum (4) replaces the original index in
GR7, which then becomes the comparand. Since those values are equal, a programmer could be misled into believing
the branch will occur.
22.9.9. This is a form of what is known as the shift-and-square method for calculating integer powers. For example,
suppose you must evaluate X**5.

The first exponent bit tested is 1, so the code branches to OneBit, where the BXLE instruction finds that c(GR0) is
not zero, so X is squared in GR5; this result is called the work value.
Then the next exponent bit (0) is shifted into GR1; the BXLE finds that its zero, and branches to TestMore.
(Remember that the BXLE instruction also leaves zero in GR1.) Since there is still a 1-bit in GR0, the BXH
instruction branches to Square, where the work value is squared, leaving X**4 in GR5.
The last 1-bit of the exponent is shifted into GR1, and the BXLE test does not branch, so the work value is multiplied by c(GR3)=X, giving X**5.
The final test at TestMore finds that c(GR0) is now zero, and control passes to Finished, leaving X**5 in GR3.

Programming Problem 22.1.


We will show two solutions to this problem. Both use similar techniques to generate the table; the first solution assumes
fixed positions for all the data in the table.

1136

Assembler Language Programming for IBM z System Servers

Version 1.00

Title Solution to Problem 22.1


CSect ,
Print a hexadecimal multiplication table
Using *,15
Establish base register
Print NoGen
PrintLin Head,L Head
Print heading line
XR
0,0
Initialize row counter
Row_Loop DC
0H
LR
2,0
Get row value
IC
2,Chars(2)
Get character for this row
STC
2,Line+1
Store at left end of print line
XR
1,1
Initialize column counter
LA
4,Line+3
Point to first table position
Col_Loop DC
0H
LR
3,0
Put row value in GR3
MR
2,1
Multiply by column value
LR
2,3
Copy product to GR2
SRL
2,4
Position high-order product digit
NILL 3,X F
Low-order product digit in GR3
IC
2,Chars(2)
Get equivalent EBCDIC character
STC
2,0(,4)
Store high-order digit in print line
IC
3,Chars(3)
Get equivalent EBCDIC character
STC
3,1(,4)
Store low-order digit in print line
AHI
4,3
Step to next print line position
AHI
1,1
Increment column counter
CHI
1,16
See if this row is complete
JL
Col_Loop
Branch if not
PrintLin Line,L Line
Print this row
AHI
0,1
Increment row counter
CHI
0,16
See if all rows are complete
JL
Row_Loop
If not, do another row
PrintOut *,Header=NO
Terminate the program
Chars
DC
C0123456789ABCDEF
Head
DC
C 1
0 1 2 3 4 5 6 7 8 9 A B C D E F
Line
DC
CL(L Head)
Print line
End
P22_1

In this second solution, the symbols Margin and Space defined by EQU statements at the beginning of the program
control the position of the left margin and the spacing between columns of the table. Otherwise, the program is straightforward.
P22_1A
Margin
Space

TopRow

*
*
NextRow

*
NextCol

Title Alternate solution to Problem 22.1


START 0
Equ
15
Indentation from left edge
Equ
5
Space between columns
BASR 15,0
Establish run-time base
Using *,15
Let assembler know about assumption
PrintLin Title
Print title at the top of the page
LA
1,15
Set up 15 X values on the top line
SR
2,2
Initialize pickup index to zero,
LR
3,2
And the character storage index
IC
0,Char+1(2)
Pick up an EBCDIC character
STC
0,Line+Margin+Space+1(3) Store in line
LA
2,1(0,2)
Increment X value by 1
LA
3,Space(0,3)
Move store index over to next slot
JCT
1,TopRow
Do 15 digits in all
PrintLin Line
Print the top row of the table
c(GR1) = 0, c(GR2) = 15
LA
LA
SR
IC
STC
LA

4,1
1,1(0,1)
3,3
0,Char(1)
0,Line+Margin
0,15

Initial X value for each row


Increment Y value by 1
Reset line store index
Fetch left-column character
Store in line in left column
Set column count in GR0 for loop

LR
MR

7,1
6,4

Y value
* Y value
Suggested Solutions to Selected Exercises and Programming Problems

1137

SLDL 6,28
Place high-order digit in GR6
SRL
7,28
Move low-order digit to end of GR7
IC
6,Char(6)
Get appropriate ...
IC
7,Char(7)
...EBCDIC characters, and
STC
6,Line+Margin+Space(3)
...store first in line
STC
7,Line+Margin+Space+1(3) ...and second
LA
3,Space(0,3)
Increment line index
LA
4,1(0,4)
Increment X value
JCT
0,NextCol
Loop until line is complete
PrintLin Line
Print the line
JCT
2,NextRow
And loop until 15 rows are done
*
PrintLin Title,1
PrintOut *,Header=NO
*
Char
Title
Line

1138

DC
DC
DC
END

Skip a page to get a clean result


Stop

C0123456789ABCDEF Ebcdic form of hex digits


CL121 1 Hexadecimal Multiplication Table
CL121 0
Print line, with double spacing
P22_1A

Assembler Language Programming for IBM z System Servers

Version 1.00

Section 23 Solutions
Section 23.2
23.2.1. Only the first is valid; the I2 operands of the other two require more than 8 bits, so the Assembler will indicate
an error.
23.3.1. The table of EBCDIC character encodings in Table 13 on page 89 shows that Ca has representation X 81
and CA has representation X C1 . ORing the representation of C , or X 40 , into Ca produces X C1 .
Section 23.3
23.3.2. NI

Flags,B01111110

23.3.3. OI

Flags,B10000001

Section 23.4
23.4.1. Consider the following:

Loop

LA
LR
LA
CLI
JNE
SR

1,Data-1
0,1
1,1(0,1)
0(1),X FF
Loop
1,0

Set pointer to left of string


Save start address for later
Point to next byte
Check for all 1-bits
Branch if not all ones
Subtract start addr to get count

23.4.2. No, because SI-type instructions cant be indexed!


23.4.3. This solution scans characters from right to left.

Test

Store

LHI
LA
CLI
JNE
BCTR
JCT
ST
ST

0,80
1,Record+80-1
0(1),C
Store
1,0
0,Test
0,DataLen
1,LastChAd

Record length
Point GR1 to last character
Check for blank character
Branch if it s not a blank
Move pointer left by 1 byte
Count down and repeat
Store data length
Store address of last nonblank

If there no nonblank characters, the address stored at LastChAd will be A(Record-1).


the opcode for CLI is X 95 , which is less than X F F .*

23.4.4. Try CLI

*,X FF

23.4.5. Try CLI

*,0 the opcode for CLI is X 95 , which is greater than 0.*

23.4.6. He can write the test in either of two ways:


1.

CLI

Char,C f

2. LowerF

Equ
CLI

C f
Char,LowerF

23.4.7. Try CLI *+1,0 the CLI compares its immediate operand to itself. * A better instruction is CLR 0,0 which
makes no memory reference, but does refer to a register.
Section 23.5
23.5.1. This is essentially the definition of a 9-bit twos complement binary integer, which has values between 28 and
+ 2 8 1.
23.5.2. In step 1, if the I2 mask AND the first-operand byte is zero, all the tested bits were zero. In step 2, some or all
bits from the first step must have been ones. After XORing this field with the I2 mask again, if all the remaining bits
from step 1 were ones, the result is now zero, meaning all tested bits were ones. In step 3, if the result of the XOR is
not zero, the tested bits were mixed zeros and ones.

This may not be the best technique, because it mixes a reference to an instruction and data.
Suggested Solutions to Selected Exercises and Programming Problems

1139

23.5.3. Try TM *+1,AnyNonZeroValue because the I2 mask has at least one nonzero bit, each one-bit in the mask
will test itself, so all tested bits will be one.
23.5.4. TUM is not the mnemonic for Test Under Mask; the second operand is written as a decimal term (with value
X 50 ), and the branch mnemonic for a zero sign bit is BZ; BP would never branch, because TM doesnt set CC=2.
He should have written:
TM
BZ

BIN,X 8 0
POS

Test for zero sign bit


Branch if nonnegative

23.5.5. You can use TM *+1,0. (Is there any limitation on the first operand address?)
23.5.6. Yes, because BNM has mask B1011. But be careful! There are other TM-like instructions that dont behave
like TM!
Section 23.6
23.6.1. There are many ways to do this; this is a representative solution:

Repeat

LHI
LA
ICM
SR
SLDL
AHI
STC
AHI
JCT

0,8
1,BitChars
3,B 1 0 0 0 , BitData
2,2
2,1
2,C 0
2,0(,1)
1,1
0,Repeat

Initialize bit count


Point to output character string
Source byte in leftmost byte of GR3
Clear GR2 for shift
Move a bit into GR2
Form ECBDIC 0 or 1 character
Store character in output area
Increment output address
Repeat until 8 bits are done

23.6.2. No, because it doesnt correctly handle the mixed case.


Section 23.7
23.7.1. Yes. After the DS

B the Location Counter has been advanced by 1.

23.7.2. Consider these instructions:


(1)

NI

BitA,255-L BitA-L BitB

(2)

XI

BitB,L BitB

(3)

TM
JO

BitA,L BitA+L BitB Test both bits


Both
Branch if both are ones

(4)

LA
TM
JO
BCTR
JM
BCTR
- - -

0,2
BitA,L BitA+L BitB
Done
0,0
Done
0,0

Done

Set both bits to zero

Invert BitB

Assume both bits are ones


Test the two bits
Finished if both are ones
Reduce the ones-count by 1
Finished if only one is one
Both 0, reduce ones-count to zero

Why cant you use AHI 0,-1 instead of BCTR 0,0? Because AHI sets the Condition Code, and the JM instruction will
branch incorrectly.
Section 23.9
23.9.1. The number in GR6 is alternately 2 and 4, because the SLL instruction is alternately SLL and SRL. (To understand this, youll have to revisit the opcodes shown in Table 78 on page 242!) The values in GR4 are therefore the
odd numbers which are not multiples of 3. 315
23.9.2. The OI and XI have zeros in the right hex digit of the immediate operand, and the NI has all ones.
23.9.3. It saves allocating a byte for Flag! But it also makes the program self-modifying. (At the time HASP was
written, self-modifying programs werent unusual.)

315

An interesting bit of code from a prime-number generator by Valdo Androsciani.

1140

Assembler Language Programming for IBM z System Servers

Version 1.00

Section 24 Solutions
Section 24.2
24.2.1. None.
Section 24.3
24.3.1. (1) 2 (the length attribute of A is implicitly 2 bytes), X 0102 ; (2) 4 (the length attribute of B is explicitly 4),
C ABCD ; (3) 3 (the Length Expression is specified explicitly), X 000000 !
24.3.2. The possible operand formats are shown in this table:
Format

As first operand

As second operand

7(4)
24(6,12)

S(N)
D(N,B)
S(N) if B is absolute,
otherwise invalid

D(B)
Invalid
D(B) if A and B are absolute,
otherwise invalid

D(,B)

Invalid

A(B)
5(,1)

24.3.3. Suppose the comma is omitted, so that the operand looks like this:
MVC

D1(B1),S2

Because this first operand of the MVC instruction was intended to specify an explicit address, it should have the third
operand format described in Section 8.5. As written, the D1 expression will be interpreted as an implied address, and
the B1 expression will be interpreted as the Length Expression.
Section 24.4
24.4.1. No.
24.4.2. Yes and No. This may seem puzzling, because the assembler can derive an implied length attribute of an
operand expression. But consider these statements:
A
B
C
D
E
F

LA
LA
LA
LA
LA
LA

0,L *
0,L *+3
0,L3+*
0,L B
0,8+L B
0,L(8+L B)

c(GR0)
c(GR0)
Error,
c(GR0)
c(GR0)
Error,

= 4
= 7
L operand not a symbol
= 4
= 12
L operand not a symbol

The operand of a Length Attribute Reference must be either a valid symbol or a Location Counter Reference. In the
third and sixth examples, the expressions are 3+* and (8+L B). Since the Length Attribute of an expression is that of its
leftmost term, the Assembler issues an ASMA147E error message.
Section 24.6
24.6.1. The result would be C54345. You might want to experiment with the CPU you are using to see what happens
when you use MVCIN to move various strings onto themselves.
24.6.2.
MVC
Prefix,PText
Move prefix string
MVCIN Insert,IText+L Insert-1 Move insert string
MVC
Suffix,SText
Move suffix string
24.6.3. C DataData .
24.6.4. The result fields are:
Result2
Data2

DS
DC

C PQRS
C TUVWTUVW

From the first 4 bytes at Data2

24.6.5. The effective address of the STC is the same in both cases. However, suppose you needed later to insert an
instruction or two between the STC and the MVC: the *+5 operand would then refer to the wrong instruction. This
shows why references between instructions should use symbols, not expressions involving the Location Counter. (But
you should use an EX instruction, anyway!)

Suggested Solutions to Selected Exercises and Programming Problems

1141

24.6.6. Sketching the operations may help. The first MVCIN moves the last byte of the second operand, CG, to the
first byte of the first operand, etc. The final byte of the second operand, CA, is moved to the last byte of the first
operand, which is at the same address!
A similar analysis holds for the second MVCIN, except that the initial byte moved from the second operand is at the
same address as the first byte of the first operand. Thus, the one-byte overlap is harmless in both cases.
The result at X is CG F E D C BA, and the result at Q is C54321.
Section 24.7
24.7.1.

Temp

MVC
Temp,ZZ
NC
Temp,=X00780000
NC
XX,=X FF87FFFF
OC
XX,Temp
- - DS
XL4

Move to work area


Isolate second integer
Set new-integer position to zeros
Insert new second integer value
Temporary work area

24.7.3. The instructions work correctly. Just before executing the NC instruction, the eight bytes at BitChars will
contain
X9148241980040201
The NC instruction will change the bytes to
X0100000100000001
and the OC instruction inserts the high-order X F0 bits to form the eight EBCDIC characters C10010001.
Section 24.8
24.8.1. Consider 1 > 2. Because CLC does unsigned byte comparisons, X F F F F F F F F > X F F F F F F F E , and
the assertion is true.
24.8.2. Because negative binary integers have a 1 in the sign bit, a logical comparison will consider all negative
numbers to be greater than all non-negative numbers.
Now, suppose you invert the sign bits: now, a logical comparison will consider all non-negative values to be greater
than the originally negative values. For example:
arithmetically smallest

arithmetically largest

20=X FFFFFFEC
10=X FFFFFFF6
+ 10=X0000000A
+ 20=X00000014

becomes
becomes
becomes
becomes

X 7 FFFFFEC
X 7 FFFFFF6
X8000000A
X80000014

logically smallest

logically largest

So, these instructions will compare + 10 to 10 correctly:

M10
P10

XI
M10,X80
XI
P10,X80
CLC
P10,M10
JH
P10Big
JL
M10Big
J
Equal
- - DC
F -10
DC
F+10

Invert sign of -10


Invert sign of +10
Compare (modified) +10 to -10
Branch if +10 > -10
Branch if +10 < -10
Branch if they re equal

Comparisons using this technique should reset all inverted signs to their correct values.
24.8.3. It is not true for (3). The CC would be set to 0 if all the bytes were identical, whether or not they were zero.
24.8.4. Since only a single length is provided in the CLC instruction, there is no way to determine a shorter operand.
The maximum number of bytes compared is always the number specified; if an inequality occurs, the comparison stops
immediately. Also, there is no reference in the CLC instruction to blanks or padding. (Well see padding in
Section 25.)
24.8.5. This solution uses the one byte at a time property of the CLC instruction:

1142

Assembler Language Programming for IBM z System Servers

Version 1.00

CLI
JNE
CLC
JE
NotBlank - - -

Chars,C
NotBlank
Chars+1(71),Chars
AllBlank

Check first character for blank


If not blank, don t bother the rest
Compare the rest of the characters
Jump if all were blanks
Not all 72 characters are blanks

24.8.6. Because the length attribute of the literal =120C is 1, only a single byte will be compared.
24.8.7. The instruction will set CC=0 if all 8 bytes of the field addressed by GR4 are identical. (So the instruction is
very useful.)
Section 24.9
24.9.1. Here is an Assembler listing showing the generated data:
000000
000081
00008A
000091
00009A
0000A2
0000AA
0000C1
0000CA
0000D1
0000DA
0000E2
0000EA
0000F0
0000FA

4040404040404040
8182838485868788
40404040404040
9192939495969798
4040404040404040
A2A3A4A5A6A7A8A9
4040404040404040
C1C2C3C4C5C6C7C8
40404040404040
D1D2D3D4D5D6D7D8
4040404040404040
E2E3E4E5E6E7E8E9
404040404040
F0F1F2F3F4F5F6F7
404040404040

1 TRTAble
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

DC
DC
DC
DC
DC
DC
DC
DC
DC
DC
DC
DC
DC
DC
DC
End

(C a ) C
C abcdefghi
7C
C jklmnopqr
CL8
C stuvwxyz
23C
C ABCDEFGHI
7C
C JKLMNOPQR
CL8
C STUVWXYZ
6C
C0123456789
6C

Anything less than C a is blanked


Letters are unchanged
Non-printing characters are blanked
Print letters as is
More non-printing characters
Last of the lower-case letters
Blank anything between z and A
Letters are unchanged
Non-printing characters are blanked
Print letters as is
More non-printing characters
Last of the upper-case letters
Blank anything between Z and 0
Digits print okay
Tail-enders are blanked too

If you want to see all 256 bytes of generated data, add a


Print Data
assembler instruction statement at the start of your program.
24.9.2. Only a single TR instruction is needed. The translate table replaces each byte with its rotated equivalent; it
begins like this:
RotaTabl DC
* Argument:

X00800181028203830484058506860787088809...
000102030405060708090A0B0C0D0E0F101112...

24.9.3. This translation table uses no hand-counted duplication factors:


TRTable

DC
DC
DC
DC
DC
DC
DC
DC
DC
DC
DC
DC
DC
DC
DC

(C a ) C
Anything less than C a is blanked
C abcdefghi
Letters are unchanged
(C j -C i -1)C Non-printing characters are blanked
C jklmnopqr
Print letters as is
(C s -C r -1)C More non-printing characters
C stuvwxyz
Last of the lower-case letters
(C A -C z -1)C Blank anything between z and A
C ABCDEFGHI
Letters are unchanged
(C J -C I -1)C Non-printing characters are blanked
C JKLMNOPQR
Print letters as is
(C S -C R -1)C More non-printing characters
C STUVWXYZ
Last of the upper-case letters
(C 0 -C Z -1)C Non-printing characters are blanked
C0123456789
Digits print okay
(X 1 0 0 -C 9 -1)C Tail-enders are blanked too

24.9.4. First, define the following data areas and tables; their order is important:
Blank
InputRec
A1Format
Table

DC
DS
DS
DC
DC

C
Moved by 0 S in Table
CL80
Moved by 1-80 in Table
0F
80A((*+4-A1Format)/4)
320-byte string
3X 0 0
Three bytes of zeros

Note that the table at A1Format begins X 000000010000000200000003... . Then, the following instructions do the job:

Suggested Solutions to Selected Exercises and Programming Problems

1143

MVC
MVC
TR
TR

A1Format(240),A1Format+3
Shift Table left by 3 bytes
A1Format+240(80),A1Format+243
Shift rest of Table
A1Format(240),InputRec
Unpack 60 characters
A1Format+240(80),InputRec Unpack last 20 characters

The string at A1Format moved by the MVCs begins X 010000000200000003... .


24.9.5. The table must be 256 bytes long, because any bit combination is possible. The table is constructed so that the
function byte is the hex transpose of the argument byte that would access it. The table would start like this:
TRANS

DC
X00,10,20,30,40,50,60,70,80,90,A0,B0,C0,D0,E0,F0
DC
X 0 1 , 1 1 , 2 1 , 3 1 , . . . etc. ...
- - DC
X 0 F,1F, ...,
... DF,EF,FF

24.9.7. Using a TR instruction is simpler than the solution to Exercise 17.4.6. The bytes in the translate table contain
the bit counts:
BitNoTbl DC

AL1(0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4,1,...)

24.9.8. First, define the translate table:


Gather

DS
DC

0CL40
40AL1(4*(*-Gather))

40-byte string

Then the following instructions do the job.


MVC
MVC
TR
TR

OutRec(40),Gather
OutRec+40(40),Gather
OutRec(40),A1Format
OutRec+40(40),A1Format+160

The translation must be done in two steps, because we cannot define a full 80-byte table at Gather. (Why? Because
the values stored in the bytes would exceed 255.)
24.9.9. This can be done in several ways; this is one approach.
ASMTable DC
(X 1 0 0 ) C
ORG
ASMTable+C .
DC
C .
ORG
ASMTable+C (
DC
C (
ORG
ASMTable+C +
DC
C +
ORG
ASMTable+C&&
DC
C&&
ORG
ASMTable+C $
DC
C $
- - ORG
ASMTable+C =
DC
C =
ORG
ASMTable+C
DC
C
ORG
ASMTable+C a
DC
C abcdefghi
- - ORG
ASMTable+C A
DC
C ABCDEFGHI
- - ORG
ASMTable+C 0
DC
C0123456789
ORG
,
ASMTbEnd Equ
*

Initialize to 256 blanks


Position at .
Position at (
Position at +
Position at &
Position at $
Etc., for other special chars
Position at =
Position at
Position at a

Position at A

Position at 0
Set LC to end of table

24.9.10. This solution shows a complete program that does both the right and left shifts. As with many problems
involving TR and TRT, the important part of the solution is in the translate tables. The table named TLeft translates
every byte whose leftmost digit is X X into a byte X 0X (shifting the left digit right), and the table named Right
translates every byte whose rightmost digit is X Y into a byte X Y0 (shifting the right digit left). The OC instructions
then merge the translated strings.

1144

Assembler Language Programming for IBM z System Servers

Version 1.00

XShift

Old
New
Temp
Start

CSect ,
Print NoGen
Using *,15
J
Start
DC
X123456789ABCDEF0
DS
XL(L Old)
DS
XL(L Old)
MVC
Temp(L Old),Old
TR
Temp(L Old),TLeft
MVC
New,Temp
MVC
Temp(L Old),Old
TR
Temp(L Old),TRight
OC
New+1(L Old-1),Temp
PrintOut New

Jump over data definitions


Sample data to shift
Space for shifted result
Temporary working storage
Copy data to temp
Shift left digits to right
Move shifted left digits
Copy data to temp again
Shift right digits to left
OR right digits, with offset
Print right-shifted result

TLeft
TRight

MVC
Temp,Old
Copy data to temp
TR
Temp(L Old),TRight
Shift right digits to left
MVC
New,Temp
Move shifted right digits
MVC
Temp(L Old),Old
Copy data to temp again
TR
Temp(L Old),TLeft
Shift left digits right
OC
New(L Old-1),Temp+1
OR left digits, with offset
PrintOut New,*,Header=NO
Print left-shifted result
DC
16X 0 , 1 6 X 1 , 1 6 X 2 , 1 6 X 3 , 1 6 X 4 , 1 6 X 5 , 1 6 X 6 , 1 6 X 7
DC
16X 8 , 1 6 X 9 , 1 6 X A , 1 6 X B , 1 6 X C , 1 6 X D , 1 6 X E , 1 6 X F
DC
16AL1(0,16,32,48,64,80,96,112,128,144,160,176,192,208,22+
4,240)
End

24.9.12. The instruction at Q1 adds C0 to the hex digit; if it is numeric (between 0 and 9), this is its EBCDIC representation. The comparison at Q2 tests to see if it is as large as 250 (or C 0 + X A ); if so, the hex digit must have been A
through F. The AHI instruction at Q3 then corrects the representation; it might better have been written
Q3

AHI

8,C A -C 0 -X A

Map A-F back to correct values

24.9.14. The second byte can be translated with the table constructed in the solution to Exercise 24.9.5. The X F can
be inserted most easily with an OI instruction, but you could use another TR instruction and a new table if you were
feeling extravagant.
24.9.15. The result at OddTable will be X 00000202040404
24.9.16. The program does work. The precautions are:
1. Be sure that L InString truly represents the number of input bytes, and that it does not exceed 128. (What would
need to be done if is greater than 128?)
2. Be sure that the length attribute of OutStrng is twice the number of input bytes, by defining OutStrng as
OutStrng DS

CL(2*L InString)

3. Assuming that the previous two conditions have been satisfied, write the TR instruction as
TR

OutStrng(2*L InString),=C0123456789ABCDEF

so that all operations depend only on the length of InString.


24.9.17. The required translate table can be created in several ways. First, you can do each byte manually so that the
table starts like this:
RevBits

DC

X008040C020A060E0109050D030B070F00804...

but this is clearly a tedious and error-prone approach. A better approach is to let the Assembler do the work, but
constructing the operand is not obvious.
We start with the observation that a bit representing the N-th power of 2 can be extracted from a byte named X using
the expression
(X-((X/2( N + 1 ) )*2( N + 1 ) ))/2 N
To put this bit in the reversed position in the output byte, it must be multiplied by 2(7-N) . Using these expressions, we
can create the translate table this way:

Suggested Solutions to Selected Exercises and Programming Problems

1145

DC

256AL1((*-R)/128+2*(((*-R)-(((*-R)/128)*128))/64)+4*(((*X
-R)-(((*-R)/64)*64))/32)+8*(((*-R)-(((*-R)/32)*32))/16)+X
16*(((*-R)-(((*-R)/16)*16))/8)+32*(((*-R)-(((*-R)/8)*8))X
/4)+64*(((*-R)-(((*-R)/4)*4))/2)+128*((*-R)-(((*-R)/2)*2X
)))

Consider the second expression 2*(((*-R)-(((*-R)/128)*128))/64): this extracts the second bit of the offset from the
start of the table, corresponding to value 2 6, and multiplies it by 2 so it will be the second bit from the right in the
corresponding byte of the translate table.
24.9.19. After first time, the table will be X 00010203...7D7E7F 7F7E7D...03020100 each time after the first. The
original table is never recovered!
24.9.20. The table is unchanged every time the TR instruction is executed.
Section 24.10
24.10.2. You cant replace DC XL256 0 by DS because the other 254 bytes of the table wont be correctly initialized.
24.10.7. This complete program uses a translate-and-test table with nonzero entries for all nonblank characters.
X24_10_7 Csect ,
Using *,15
Print NoGen
RecLen
Equ
80
Record length
XR
1,1
Clear GR1
XR
3,3
c(GR3) = worst-case string length
LA
4,Record+Reclen-1 c(GR0) = A(last byte of Record)
MVCIN Temp,0(4)
Move Record to Temp in reverse order
TRT
Temp,FindNonB
Scan in reverse to find a nonblank
JZ
Store
Branch if record was all blanks
LA
3,Temp+Reclen
c(GR3) = 1 byte after Temp
SR
3,1
c(GR3) = length of string
LA
4,Record-1(3)
c(GR4) = A(last nonblank character)
Store
ST
3,DataLen
Store length of string
ST
4,LastChAd
Store address of last nonblank
Printout DataLen,LastChAd,*,Header=NO
Print results
DataLen DS
F
Significant length of string
LastChAd DS
A
Address of last nonblank char
Record
DC
CL(RecLen) This is a test to see what happens.
Temp
DS
CL(RecLen)
FindNonB DC
256X 1
Set all 256 bytes to X 1
Org
FindNonB+C
Position at offset X 4 0
DC
X 0
We won t stop on blanks
Org
,
Reset Location Counter
End
X24_10_7
24.10.8. Suppose the second TRT does not find a nonzero function byte. Then the LTR
function byte from the first TRT, probably giving incorrect results.

2,2 instruction would use the

24.10.9. The first operand generates 64 X 01 bytes, corresponding to offsets from X 00 to X 3F . The second
operand generates a single X 00 byte at offset X 40 . Finally, the third operand generates 256-C -1, or
256-64-1=191 bytes containing X 01 . Thus, a total of 256 bytes are generated.
24.10.11. The TRT scan stops at the X02 function byte of XX, with Condition Code 1 meaning the scan is incomplete, and c(GR2)=X 00000002 .
Section 24.11
24.11.1. The two sets of USING statements are distinct and independent. The EX reference to the target instruction is
resolved at the location of the EX instruction, while the operands of the target instruction are resolved with the
USINGs in effect at that location. Be careful!
24.11.2. If EX branched to the target instruction, he would expect GR1 to contain the address of whatever is named
There. Because EX does not branch, GR1 will actually contain the address of Here.
24.11.3. GR1 will contain the address of the LR instruction, not the address of the AR instruction! This is because the
BASR places the Instruction Address into R 1; the PSW still contains the address of the instruction following the EX.

1146

Assembler Language Programming for IBM z System Servers

Version 1.00

The target instruction (the BASR) does not modify the IA in the PSW, because its R2 digit is zero. The ILC will
contain B 10 (indicating a 4-byte instruction), because EX is an RX-type instruction.
24.11.5. In this solution, we must make two checks: (1) to verify that the number of bytes to move is positive, and (2)
test whether the number is greater than 256. If so, we move blocks of 256 bytes until the residual amount to move is
256 bytes.
LTR
JNP
Test
CHI
JNH
MVC
AHI
AHI
AHI
J
LastGrp BCTR
EX
Finished - - - - MoveLast MVC

3,3
Finished
3,256
LastGrp
0(256,2),0(1)
1,256
2,256
3,-256
Test
3,0
3,MoveLast

Check number of bytes to move


If not positive, we re done
Test if number to move is > 256
If not, go handle residual group
Move 256 bytes
Increment from address
Increment to address
Decrement count by 256
And see of any more blocks to move
Make an machine length
Move the residual byte count

0(*-*,2),0(1)

Executed MVC

Compare this to the instructions in Figure 220 on page 393, and explain the differences.
24.11.6. This solution handles pairing, but does not enforce the HLASM rule that character constants and self-defining
terms must always have paired ampersands and apostrophes.
LA
LA
LR
LHI
TestCh
CLI
JE
CLI
JE
CopyChar MVC
AHI
AHI
JCT
SLR
ST
J
HaveChar CHI
JE
CLC
JNE
BCTR
AHI
J
Done
- - - - DCData
DC
DCGen
DS
DCGenL
DS

1,DCData
4,DCGen
3,4
2,L DCData
0(1),C&&
HaveChar
0(1),C
HaveChar
0(1,4),0(1)
1,1
4,1
2,TestCh
4,3
4,DCGenL
Done
2,1
CopyChar
0(1,1),1(1)
CopyChar
2,0
1,1
TestCh

Initialize From pointer


Initialize To pointer
Save To start address for length
Get From string length
Check for ampersand
Branch to check for pair
Check for apostrophe
Branch to check for pair
Move From character to To
Step From pointer
Step To pointer
Test next character
Final To final addr - start addr
Store length of result
Was it the last character?
Branch if yes, include it
Does next character match?
Branch if not to keep it
Decrement count of remainder
Step over the paired character
And check for more characters

C This string contains && s and s


CL(L DCData)
Result string
F
Length of result

24.11.8. The easiest way to do this is to pre-pad the receiving field if N > M.

Suggested Solutions to Selected Exercises and Programming Problems

1147

LHI
LHI
CR
JE
JH
LR
J
Pad
MVI
LR
AHI
JNP
EX
Move
BCTR
EX
- - MoveData MVC
PadBlank MVC

2,M
3,N
2,3
Move
Pad
2,3
Move
DataPad,C
1,3
1,-2
Move
1,PadBlank
2,0
2,MoveData

Length of source field


Length of target field
See which is longer
If the same, just move
If N>M, must pad target field
N<M, move only N characters
And move them now
Initialize first pad byte
Copy N
Deduct for EX machine length
If not >0, only 1 pad byte
Otherwise complete the padding
Now have lesser of (N,M)-1
Move the source bytes to target

DataPad(*-*),Data
DataPad+1(*-*),DataPad

Move the data


Ripple blanks

24.11.9. Suppose the two operands are byte strings named A and B, and we want to compare A to B.

BLonger

APad

ALonger

BPad

Done

LHI
LHI
CR
JE
JH
CLC
JNE
LA
LA
CLC
JNE
LA
JCT
J
CLC
JNE
LA
LA
CLC
JNE
LA
JCT
- - -

2,L A
3,L B
2,3
Compare
ALonger
A,B
Done
1,L B-L A
2,L A+B
=C , 0 ( 2 )
Done
2,1(,2)
1,APad
Done
B,A
Done
1,L A-L B
2,L B+A
0(1,2),=C
Done
2,1(,2)
1,BPad

Length of A
Length of B
Compare lengths
Equal, do the compare directly
Branch if A is the longer string
A is shorter, compare to B
If an inequality, we re dond
Calculate length of A pad
Where to start padded compare
Compare tail of B to blank
If a mismatch, we re done
Step to next byte of B, CC unchanged
And compare again
Strings are equal, with padding
B is shorter, compare to A
If an inequality, we re dond
Calculate length of B pad
Where to start padded compare
Compare tail of A to blank
If a mismatch, we re done
Step to next byte of A, CC unchanged
And compare again
CC set correctly for all compares

While it is possible at assembly time to determine which of L A and L B is larger and then define a string of blanks
whose length is the absolute difference, the above approach seems simplest.
24.11.12. The key to this solution is the translation table, in which each function byte rotates the bits of the source byte
to the right by one bit position.

Rotate1
Done
RoTable

NILL
JZ
TR
JCT
- - - - DC
DC
- - DC
DC

1,B 1 1 1
Done
Rotator,RoTable
1,Rotate1

Use only 3 rightmost bits of GR1


Finished if shift count was zero
Rotate by 1 bit position
Repeat until N shifts are done

X00,80,01,81,02,82,03,83,04,84,05,85,06,86,07,87
X 0 8 , 8 8 , 0 9 , 8 9 , . . . etc. ...

etc.
X
... etc. ...
77,F7
X 7 8 , F8,79,F9,7A,FA,7B,FB,7C,FC,7D,FD,7E,FE,7F,FF

You could avoid looping by choosing one of seven different rotation translate tables, but the gain seems less than the
needed effort.

1148

Assembler Language Programming for IBM z System Servers

Version 1.00

You cant rotate by N bits using a single translate table, because the source byte could contain any of 256 bit combinations, and the function bytes for each of 7 possible rotations are at different offsets in the table.*
24.11.13. Suppose the rightmost 8 bits of GR9 are B 00000011 , indicating an odd number. Then, the executed TM
instruction is effectively
TM

OneBit,B00000011

But because only one of the tested bits at OneBit is one, the JO instruction would not branch to OddReg as required,
because the tested bits are mixed zero and one.
24.11.14. This can be done by testing the N rightmost bits one at a time in a loop; assume GR0 can be used as a
working register, and the number to be tested is in GR9.
LA
0,N
EX
9,TMTest
JNZ
NotPower
SRL
9,1
JCT
0,Test
- - NotPower - - - - TMTest
TM
OneBit,0
OneBit
DC
B00000001
Test

Number of bits to test


Test the rightmost bit
If 1, not a multiple of 2**N
Move to next significant bit
And try again

Test the rightmost bit


Low-order 1 bit

The limitations of this technique are:


1. GR0 cannot be the register tested.
2. If we arent allowed to shift the contents of the register, we cant test for powers greater than 8.
3. If we can shift, the original contents of the register is destroyed, and there is no way to check the lost bits.
To do this more general test, if N is known at assembly time we could write

PowerN

L
BCTR
NR
JNZ
- - DC

0,PowerN
0,0
0,9
NotPower

Get the test mask


Decrement to form N 1-bits
See if the bits of GR9 are zero
Branch if not

FS(N) 1

Generate 2**N

24.11.15. The main problem is that the rightmost 4 bits of GR1 will modify the operation code of the executed LHI
instruction! Thus, he should have written

LHIOp

SLL 1,4
EX
1,LHIOp
- - LHI 0,137

Position register number correctly


Load the constant into a GPR
Constant to be loaded somewhere

24.11.16. This solution uses EX and MVI instructions:

MVI
Byte
Char

LHI
LA
ICM
XR
SLDL
EX
AHI
JCT
- - MVI
DC
DS

0,8
1,Char
3,B 1 0 0 0 , Byte
2,2
2,1
2,MVI
1,1
0,A

Set bit counter to 8


Point GR1 to characters
Byte in high-order byte of GR3
Clear GR2
Shift a bit from GR3 into GR2
Let the MVI store the character
Increment the address by 1
Count down by 1 and loop

0(1),X F0
X CD
CL8

Store C 0 or C 1
Sample bit pattern

24.11.18. First, we create a translate table that can be used to reverse the order of a string of up to 256 bytes:
RevTbl

DC

256AL1(255-(*-RevTbl))

In other words, I couldnt figure out how to do it. Can you?


Suggested Solutions to Selected Exercises and Programming Problems

1149

This table contains 256 byte values starting at X F F and decreasing by 1 for each generated byte. Then, we can do
the inverse move by first computing the position of the last L bytes of the table, moving them to the Target field, and
then translate the source using these instructions:
LR
BCTR
LA
SR
EX
EX
- - Move2Tgt MVC
Tran2Tgt TR

1,0
1,0
2,RevTbl+256
2,0
1,Move2Tgt
1,Tran2Tgt

Copy L to GR1
Make effective length in GR1
Point to byte past end of table
Point to last L bytes of table
Move those last L bytes to Target
Translate from Source to Target

Target(*-*),0(2)
Moves L bytes to Target field
Target(*-*),Source Moves L bytes in inverse order

This technique was often used before MVCIN was available.


24.11.19. Since the rightmost byte of GR1 is ORed into the second byte of the EX target instruction now in the IR, that
second byte will be 9|5 for the first operand digit and 8|2 for the second operand digit, yielding SR 13,10 as the executed instruction.
24.11.20. EX is an RX-type instruction, so it can be indexed.

Programming Problem 24.2.


This solution uses three translate tables: one to do the shuffling, one to convert the hex digits to EBCDIC, and a third to
place all the EBCDIC characters (including the shuffle count) into two output lines. (Note that this is the Vertical hex
technique used in Problem 24.12!) The first output line has a blank carriage control character (single space), the shuffle
count, a space, and then a blank followed by the two hex digits of a shuffled value. The second output line has the same
format, except that the first four characters are blank.
Note that only the (even!) value of the symbol NC needs to be changed to modify the number of cards to shuffle.
Print Nogen,Data
CSECT ,
USING *,15
NC
Equ
52
Number of playing cards
MaxCount Equ
NC
Maximum number of shuffles?
*
Arbitrary upper limit
XR
1,1
Initialize shuffle counter
XR
2,2
Clear even work register
XR
3,3
Clear odd work register
NextOut DC
0H
Top of shuffling loop
STC
1,Count
Store shuffle count
LA
0,NC+1
Number of digits to format
LA
4,Count
Addr(start of digit string)
LA
5,Expand
Addr(start of expansion string)
ToHex
DC
0H
Top of expansion loop
IC
2,0(,4)
Get a byte
SRDL 2,4
Move low-order digit to GR3
STC
2,0(,5)
Store high-order digit
SRL
3,28
Position low-order digit
STC
3,1(,5)
Store in next output position
AHI
4,1
Increment input pointer
AHI
5,2
Increment output pointer
JCT
0,ToHex
Expand all the digits
TR
Expand,Hex2Char
Convert X 0 ? digits to EBCDIC
MVC
Out,Format
Move formatting translate table
TR
Out,Blank
Translate complete output lines
PrintLin Out,L Out/2
Print first set of shuffled values
PrintLin Out+L Out/2,L Out/2
Print second set
PrintLin Blank,1
Blank line
AHI
1,1
Increment count
C
1,=A(MaxCount)
Test for enough shuffles
JH
Finish
Exit if yes
MVC
Temp,Shuffle
Copy shuffle table
TR
Temp,Cards
Do the next shuffle
MVC
Cards,Temp
Put the shuffled cards back
P24_2

1150

Assembler Language Programming for IBM z System Servers

Version 1.00

J
NextOut
And go output the result
DC
0H
PrintOut *,Header=NO
Terminate the program
*
Note: Count must immediately precede Cards
Count
DC
X 0
Count of number of shuffles
Cards
DC
0XL(NC),(NC)AL1(*-Cards+1)
Starting card order
Temp
DS
XL(NC)
Shuffling area
*
Define the Shuffle table
Shuffle DC
(NC/2)AL1((*-Shuffle)/2,(*-Shuffle)/2+NC/2)
*
Note: Blank must immediately precede Expand, for output
Blank
DC
C
Single space for carriage control
Expand
DS
XL(2*(NC+1))
Digit-expansion area
Out
DS
XL(2*((NC/2)*3+4)) Two formatted print lines
Format
DS
0XL(L Out)
Length of formatting table
DC
AL1(0,1,2,0)
Blank, 2 count digits, blank
F1
DS
0AL1
Anchor for first line
DC
(NC/2)AL1(0,((*-F1)/3)*2+3,((*-F1)/3)*2+4)
DC
4AL1(0)
4 blanks for second line
F2
DS
0AL1
Anchor for second line
DC
(NC/2)AL1(0,((*-F2)/3)*2+NC+3,((*-F2)/3)*2+NC+4)
Hex2Char DC
C0123456789ABCDEF Hex-to-EBCDIC translation table
End
P24_2
Finish

The output from this program showing the original order of the cards and the results after the first shuffle:
00

01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 19 1A
1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34

01

01 1B 02 1C 03 1D 04 1E 05 1F 06 20 07 21 08 22 09 23 0A 24 0B 25 0C 26 0D 27
0E 28 0F 29 10 2A 11 2B 12 2C 13 2D 14 2E 15 2F 16 30 17 31 18 32 19 33 1A 34

Some sample results with other numbers of cards:


Cards
8
10
12
24
52
64

Shuffles
3
6
10
11
8
6

Programming Problem 24.3.


The key to this solution is the translate table, which has zero function bytes in the positions of a blank and the decimal
digits. There are better ways to create the (printable) column number!
P24_3
Read

Valid

Print NoGen
Start 0
Using *,15
Use caller s GR15 as base register
ReadCard Record,EndFile Read a record
LA
0,Record-1
LA
1,Record
TRT
0(L Record,1),Table
Scan the record
JZ
Valid
No invalid characters found
MVC
OutRec,Record
Move the record to the display line
Invalid character found
SR
1,0
Calculate column number
SR
0,0
Clear high-order register
D
0,=F 1 0
Divide by 10
MVC
InvalMsg,ErrorMsg Move error message text to line
STC
1,ErrorCol
Store tens digit of column number
STC
0,ErrorCol+1
Store low-order digit of column
OC
ErrorCol(2),=2C 0 Add numeric zones
PrintLin OutLine,OutLen Display the error message
MVC
OutLine+1(OutLen-1),OutLine
Clear the display line
J
Read
Repeat for another record
Suggested Solutions to Selected Exercises and Programming Problems

1151

EndFile
Table

BR
DC
DC
DC
TabLen
Equ
ErrorMsg DC
Record
DS
*
OutLine DC
OutRec
DC
DC
InvalMsg DC
DC
ErrorCol DC
OutLen
Equ
End

1152

14
Return to the caller
(C ) X 1 , X 0
Blank valid, lower characters not
(C 0 -C -1)X 1 , 1 0 X 0 Numeric digits valid, rest not
(255-C 9 ) X 1
Remaining characters invalid
*-Table
Must be 256 (X 1 0 0 )
C Invalid character, column
CL80
Input buffer for 80-byte records
C
CL(L Record)
C
CL(L ErrorMsg)
C
2C
*-OutLine
P24_3

Carriage control character


Space for the record
Space
Space for error message
Space
Space for column number
Length of the display line

Assembler Language Programming for IBM z System Servers

Version 1.00

Section 27 Solutions
Section 27.1
27.1.1. Both instructions in Figure 261 on page 455 use implied lengths, relying on the length attribute of the target
operand. Thus, they move 8 zones or digits. If the fields are defined as 8X 0 0 their length attribute is 1, and only one
zone or numeric will be moved. Thus, the results would be
c(Numerics) = X 0 E
c(Zones)
= X F0
27.1.2. The result will be the same as executing
MVC

Target,Source

except that it will take more time.


27.1.3. The key to this solution is the translate table, which is arranged like this:
0
9 A
F

Bad Sign
OK Signs
:
:
:
9

A
Bad Byte
Bad

Digit
:
:
:
F

*
ZDLast

XR
TRT
B
J
J
J
J
J
- - 4=Bad
DC
DC

2,2
ZTest+L ZTest-1(1),ZDLast
*(2)
BadSign
ZPlus
ZMinus
BadDigit
BadByte
Sign, 8=Plus, 12=Minus, 16=Bad Digit, 20=Bad Byte
10AL1(4,4,4,4,4,4,4,4,4,4,8,12,8,12,8,8)
6AL1(20,20,20,20,20,20,20,20,20,20,16,16,16,16,16,16)

You might try extending the translate table to detect value of 0 in the last byte, and branch to Plus0 and Minus0 as
appropriate. (The TP instruction described in Section 29.1 is much simpler!)
27.1.4. The translate table checks for zoned numerics:

ZDNums

TRT
ZTest(L ZTest-1),ZDNums
JNZ
BadZDig
Condition Code not zero
- - DC
240AL1(4)
X 0 0 -X EF invalid
DC
10AL1(0)
X F0 -X F9 valid
DC
6AL1(4)
X FA -X FF invalid

27.1.5. The printed characters will be E, N, C, and R.


27.1.6. For EBCDIC, the rows punched for the + character are 12-8-6, and for the character only row 11. For
BCD, the character is also row 11 only, and the + character is row 12 (the top row).
27.1.7. Since only the zone portion of the byte is being moved, any five-byte literal with X F zone digits would work.
27.1.8. The second form is incorrect because the duplication factor is not an absolute expression.

Suggested Solutions to Selected Exercises and Programming Problems

1153

Section 27.2
27.2.1. All of the constants are 5 bytes long, so the generated data for the last two constants will be different.
27.2.2. The values are (1) X D1 , (2) X C0 , (3) X F0F4D2 , (4) X F0C5 .
27.2.3. The values are (1) 09, (2) + 2, (3) + 007, (4) 0.
27.2.4. The generated values are (1) X F0F0F0F0F0F0F0F1F2F3F4F5F6F7F8C9 (7 leading zeros), (2) Length error (too
many digits), (3) X F5F4F3F2C1 (high-order digit truncated), (4) Error (length modifier greater than 16).
27.2.5. In the rightmost byte, 6 10=60; in any other byte, 10. In the rightmost byte, the 10 decimal digits can be
paired with any of ABCDEF for the sign digit; remember that negative zero is valid.
27.2.6. Because the constant is type C, only the first 5 characters will be present in the assembled constant! (Remember,
the commas are part of the nominal data.)
27.2.7. Both have Length Attribute 5.
Section 27.3
27.3.1. The integer part of (N + 2)/2, or (N/2) + 1.
27.3.2. In the rightmost byte, 6 10=60; in any other byte, 10 10=100.
27.3.3. The possible bit combinations in each byte of the packed decimal number at Pack need to be analyzed to
determine where they might occur. This diagram divides the possible byte values into four groups:
0-9

A-F

0
9

Box A

Box B

A
F

Box C

Box D

Box A contains bytes all of whose digits are 9 or less; Box B contains bytes whose first digit is 9 or less and whose
second digit is X A or greater. Box C contains bytes whose first digit is greater than X A and whose second digit is 9
or less. The remaining bit combinations are in Box D.
By examining the contents of each box, we can use the Condition Code setting after TRT to distinguish many cases:
Box
A

CC=0
All bytes contain only numeric
digits so the number has an
invalid sign.
Should not occur.

Should not occur.

Should not occur.

CC=1
A byte before the last contains a
second digit greater than 9, so it
has an invalid digit.
Sign digit before the last byte is
invalid.
An invalid digit appears in a
byte before the last.
A byte before the last contains
an invalid digit.

Now, we can construct and use the required translate table:

*
J0
*
P

*
M

1154

LA
XR
TRT
B

1,Pack+L Pack-1
2,2
Pack,PDTest
J0(2)

Point to last byte of Pack (for CC=0)


Set GR2 to zero
Test the packed data
Branch to check resulting CC

BadSign

All numerics, sign is invalid

Equ
JZ
JM
J

*-J0
Error
BadDigit
PPlus

Box B
CC=0:
CC=1:
CC=2:

Equ
JZ
JM

*-J0
Error
BadDigit

Box B Offset for - result


CC=0: something went wrong
CC=1: sign before last digit

Offset for + result


something went wrong
sign before last digit
+ sign on valid number

Assembler Language Programming for IBM z System Servers

Version 1.00

CC=2
The last byte has a valid
numeric digit but an invalid
sign.
Valid positive or negative data.
The last byte contains an invalid
digit and sign.
The last byte contains an invalid
digit.

*
C

*
D

*
PDTest
Row0_9
RowA_F

PMinus

CC=2: - sign on valid number

Equ
JZ
JM
JP

*-J0
Error
BadDigit
BadByte

Box C
CC=0:
CC=1:
CC=2:

Equ
JZ
J

*-J0
Error
BadDigit

Box D offset
CC=0: something went wrong
CC=1,2: bad digit

DC
DC
DC

0X
10AL1(0,0,0,0,0,0,0,0,0,0,P,M,P,M,P,P) 1st digit 0-9
6AL1(C,C,C,C,C,C,C,C,C,C,D,D,D,D,D,D) 1st digit A-F

offset
something went wrong
bad digit
bad sign and digit

27.3.4. One way to do this is with


NI

SomeVal+L SomeVal-1,X FE

Force last bit to 0

Any sign code with rightmost bit zero (A, C, E) indicates a plus sign.
27.3.6. It cant be done with a single instruction. (Compare this exercise to Exercise 27.3.4.) Sign codes X B and X D
indicate a negative value, but X F indicates a positive value. With two instructions, its easy. (Show how!)
Section 27.4
27.4.1.

c(Z1) = X X F2F1F4F7F4F8F3F6F4F8
c(Z2) = X X F1F4F7F4F8F3F6F4F7 (truncation of one digit)
c(P3) = X X99999999999D
c(P4) = X X123C456C789C (three separate constants);
The explicit length of 20 is illegal for both the packed and the zoned constants.
c(P6) = X X31415926535C (decimal point ignored)
c(P7) = X X 0 CF0 (both constants truncated)
c(Z8) = X X F1F2F0F4F0F0F8F0...F0

27.4.2.

L Z1
L Z2
L P3
L P4
L P6
L P7
L Z8

=
=
=
=
=
=
=

10
9
6
2 (!)
6
1
1

27.4.3. The generated constant, X000D , is truncated.


27.4.4. No. The Assembler complains only if the number of digits in the nominal value is greater than 31, even if
removing leading zero digits would leave fewer than 32 significant digits! (Do you think the Assembler should be less
or more fussy?)
27.4.5. Because signed packed decimal numbers always have an odd number of digits, the high-order zero digits in the
nominal values are the same as the (default) zero digits inserted by the Assembler to ensure an odd number of digits.
27.4.6. This can be done with an EX instruction:

ICM
T

XR
6,6
LA
1,L P
IC
1,T-1(1)
EX
1,ICM
- - ICM
6,*-*,P
DC
X 1 , 3 , 7 , F

Set GR6 to zero


Length of the packed operand
Insert appropriate mask bits
Insert bytes at right end of GR6
Executed to insert 1-4 bytes
Masks for ICM instruction

27.4.8. Four possible interpretations, and their Assembler Language defining statements, are:

Suggested Solutions to Selected Exercises and Programming Problems

1155

DC
DC
STH
DC

F1077952604
C *
4,X05C ( 0 , 4 )
P+4040405

Fullword binary integer


Characters (three blanks and an asterisk)
Store Halfword
Packed decimal

Further interpretations are possible, as well see later.


27.4.9. This solution is due to John Ganci:
Print Data
To verify all data is generated
DS
0D
DC
1000AL2((((*-S1)/2)/100)*16*16*16+(((*-S1)/2-(((*-S1)/2)/X
100)*100)/10)*16*16+(((*-S1)/2-(((*-S1)/2)/100)*100)-(((X
(*-S1)/2-(((*-S1)/2)/100)*100)/10)*10))*16+12)

S1

To describe this solution, he writes:


1. Let V = (*-S1)/2 = H*100 + T*10 + U (Hundreds, Tens, and Units)
2. H = V/100 = ((*-S1)/2)/100
3. Remove the Hundreds digit: TU = T*10+U = V-H*100 =
(*-S1)/2-(((*-S1)/2)/100)*100
4. T = TU/10 = ((*-S1)/2-(((*-S1)/2/100)/100)*100)/10
5. Remove the Tens digit: U = TU - T*10 = U - (TU/10)*10 =
(*-S1)/2-(((*-S1)/2)/100)*100-(((*-S1)/2-(((*-S1)/2/100)/100)*100)/10)*10
6. Then, generate the packed decimal constant X HTUC =
H*16*16*16+T*16*16+U*16+12
What will happen if you replace the constant type AL2 with Y? Try it!
27.4.10. Like the solution to Exercise 27.4.9, this is also due to John Ganci:
Print Data
To verify all data is generated
DS
0D
DC
1000AL3((((*-Z3)/3)/100)*16*16*16*16+(((*-Z3)/3-(((*-Z3)/X
3)/100)*100)/10)*16*16+(((*-Z3)/3-(((*-Z3)/3)/100)*100)-X
((((*-Z3)/3-(((*-Z3)/3)/100)*100)/10)*10))+X F0F0C0 )

Z3

The analysis of this exercise is similar to that in Exercise 27.4.9, but the generated data doesnt line up as neatly in the
listing.
27.4.11. The Scale Attribute values are:

S A=7, S B=3, S C=1, S D=4, S E=0.

27.4.12. The number of packed decimal digits is 2*L X 1, so the value of the Integer Attribute is I X = 2*L X 1 S X.
That is, the total number of digits minus the number of fraction digits.
27.4.13. The attributes of the symbols are:
L
5
5
5
4
6

Symbol
A
B
C
D
E

I
2
6
8
3
11

S
7
3
1
4
0

Section 27.5
27.5.1.
PACK
UNPK
PACK
PACK
UNPK
PACK

1156

AA(5),BB(5)
BB,AA
0(16,9),65(,2)
AA(0),BB(0)
BB-AA(,9),BB(L AA)
AA,BB+11(3)

F244
F3A1
F2F0
F200
F3A1
F212

------9000
---9002
----

------2041
----------

Assembler Language Programming for IBM z System Servers

Version 1.00

Section 27.6
27.6.1. NP = (NZ + 2)/2, or (NZ/2) + 1.
27.6.2. The results for the three operands are:
1. X0000000FFF7F
2. X336B066934A5
3. X CCFC07F2C412
27.6.4. The address of the rightmost byte of the first (target) operand must be greater than or equal to the address of
the rightmost byte of the second (source) operand. This is perhaps deceptive: it might seem that the first operands
rightmost byte address could be as much as 2 less than the second operands rightmost byte address, since the result
byte is stored immediately after fetching the necessary operand bytes. However, the fetched bytes are those for the
current result byte, not the next result byte!
27.6.5.

c(P1)
c(P2)
c(P3)
c(P4)
c(P5)

=
=
=
=
=

X468C
X02468C
X 6 C
X00000681357C
X002468135F

27.6.6. The result is correct for any length, so the maximum length is 16 and the minimum length is 1.
27.6.7. X000000013579BDFE .
27.6.8. Packing a string of blanks gives X 0 0 0 . . . 0 0 4 , which has an invalid sign code for arithmetic purposes. The
rightmost byte could be corrected with an OI instruction with mask X 0 C .
27.6.9. The result will be valid for any value of K satisfying 1 K N.
27.6.10. The length digit for PackData is in the L1 field, so it must be positioned correctly:
BCTR 2,0
Reduce count for EXecute
SLL
2,4
Position the count digit correctly
EX
2,PackOp
Do the Pack instruction
- - PackOp
Pack PackData(*-*),ZData
Executed instruction
27.6.11. The result will be X00BDFE .
27.6.12. The result will be X00BEFE .
27.6.13. The result will be X00BDFE .
27.6.14. There is no difference so long as there is at least one zoned decimal digit at the right end of the source
operand, because both zeros and blanks have numeric digit zero.
Section 27.7
27.7.1. c(PackOp) = X12345C ; c(ZonOp) = X F1F2F3F4C5 .
27.7.2. The results are:
1. X F0F0FFFFFFFFFFFF7F
2. X F9F6F9F9F9F3F8F4A5
3. X F6FFF7F2F6FCF6F412
27.7.3. X FFFFFCFFFCFCFDFE . (Were you surprised?)
27.7.5. If the length of either operand is 1 byte, there is no problem with overlap.
Now, assume neither operand is one byte long. Then, the address of the rightmost byte of the first (zoned) operand
must be greater or equal to than the address of the rightmost byte of the second (packed) operand plus the length of the
second operand, minus 2. That is, if Z L is the address of the last byte of the zoned operand, and P L for the second
operand, then
ZL PL + L P - 2

Suggested Solutions to Selected Exercises and Programming Problems

1157

where L P is the length of the packed second operand. This avoids the possibility that the byte pairs of the first
operand being stored before single bytes are fetched for the second operand.
27.7.6.

c(Z1) = X F1F2F3F4F5C6
c(Z2) = X F0F1F2F3F4F5C6
c(Z3) = X F5C6
c(Z4) = X F0F0F0F4F5C6
c(Z5) = X F1F2F354 .
The contents of Z6 is unknown, since the implied length (4) of PData means that unpacking will start with the byte
at PDATA+6. If we assume that the byte at PData+3 contains the two hex digits X xy , then c(Z6)=X FCyx .

27.7.7. The minimum length is of course 1; the maximum length is 3. (See the solution to Exercise 27.7.3 for an
illustration.)
27.7.8. NZ = 2 N P 1. They are different because we discarded the remainder in evaluating NP=(NZ/2) + 1.
27.7.11. The result is X FFFFFFFFFFFFFDEF
27.7.12. Use implied lengths for the second operand of PACK and UNPK.
27.7.14. The result will be X F0F1F2F3F465 .
27.7.15. The result will be X F0FFF2F3F465 .
27.7.16. The result will be X F0FFF5F6F565 .
27.7.17. The result at Answer will be X F0F0F7F6F5F4C3 .
Section 27.8
27.8.1. The result is 16 bytes long:
readability).

X00000000 12345678 90123456 789ABCDC (the spaces are inserted to improve

27.8.2. The result will be X 0 BDFBDFBDFBDFBDFBDFBDFBDFBDFBDFC .


27.8.3. The result will be X 0 DBFDBFDBFDBFDBFDBFDBFDBFDBFDBFC .
27.8.4. Because the required 16 bytes of the packed decimal operand would overlap the source operand, the results are
unpredictable. (Try it, and see what happens!)
27.8.5. Assuming that no test is made for all unpacked characters being zeros, CC1 should indicate a negative packed
operand, and CC2 should indicate a positive packed operand. If the test for zero characters was made, CC0 should be
set. (Question: should such a test for zeros check the entire packed operand, or only the digits actually unpacked?)
27.8.6. X0000 0000 0000 0000 0000 0009 8765 432C , where the spaces were inserted for readability.
27.8.7. The CC setting will be zero in both cases!
Section 27.9
27.9.1. Because all of the bytes being translated have values between X F0 and X FF , we must ensure that the first
byte of the translate table at TRTab is accessed if the source byte is X F0 .
27.9.2. X 0 F , from swapping the digits of the first byte of the translate table.
27.9.3. Be careful! It is tempting to start by writing
UNPK

String(17),DW(9)

only to discover that the length of 17 is invalid. The unpacking must be done in two steps, as in
UNPK
UNPK
TR

String(9),DW(5)
First 4 bytes
String+8(9),DW+4(5)
Last 4 bytes
String(16),=C0123456789ABCDEF -X F0

Translate

Does it matter in which order the above two UNPKs are executed? Try it, and then explain why or why not. *

The order does matter. If the UNPKs are reversed, the byte at String+8 will contain the swapped digits of the byte at DW+5.

1158

Assembler Language Programming for IBM z System Servers

Version 1.00

27.9.4. The second operand was exhausted before the first operand field was filled.
27.9.5. Suppose a (non-zero) register (say, 7) is free. Then rewrite the TR either as
L
TR

7,=A(TRTab-X F0 )
Char(8),0(7)

Point to offset from table


Use the same translate table

Of course, the literal must be addressable! If not, use LY instead of L. Or, write
LAY
TR

7,TRTab-X F0
Char(8),0(7)

Point to offset from table


Use the same translate table

If neither of these methods work, consider rewriting that part of your program.
27.9.6. This elegant technique is due to D. R. Page. ** The code is surprisingly simple:
UNPK
TR
UNPK
TR
UNPK
- - Byte
DC
DS
BinaryCh DS
TBL
DC

BinaryCh(3),Byte(2)
BinaryCh(2),TBL-X F0
BinaryCh(5),BinaryCh(3)
BinaryCh(4),TBL-X F0
BinaryCh(9),BinaryCh(5)
B10101101
Input Data
C
Work byte
CL8,C
Result string + work byte
X00010405101114154041444550515455

27.9.7. The solution is obtained by inverting the solution to Exercise 27.9.6. The translate table is different, however:
although only 16 bytes are used for the translation, an area 86 bytes long is required. (The gaps could be filled with
other data if you like; Q can represent any byte value, because those bytes of the table are not referenced.)
Q

Equ
PACK
TR
PACK
TR
PACK
MVC
- - BinaryCh DC
Byte
DS
Table
DC
DC
DC
DC
DC

**

0
Or any other value < 256
BinaryCh+4(5),BinaryCh(9)
BinaryCh+4(4),Table
BinaryCh+6(3),BinaryCh+4(5)
BinaryCh+6(2),Table
BinaryCh+7(2),BinaryCh+6(3)
Byte(1),BinaryCh+7 Move result byte
CL810101101,C Input data + work byte
X
Result byte
AL1(0,1,Q,Q,2,3),10AL1(Q)
AL1(4,5,Q,Q,6,7),10AL1(Q)
32AL1(Q)
AL1(8,9,Q,Q,10,11),10AL1(Q)
AL1(12,13,Q,Q,14,15)
(86 bytes in all!)

IBM Technical Disclosure Bulletin, Volume 18, January 1973, page 2617.
Suggested Solutions to Selected Exercises and Programming Problems

1159

Section 28 Solutions
Section 28.1
28.1.1. Even though the result is X0000000C , its unlikely any packed decimal operand would be generated this way.
(Suppose the second operand of the AHI instruction had been 2140: would you expect the result at PWord to be a
valid packed decimal number?) (Is it?) (If yes, what is its value?)
Section 28.2
28.2.1. Decimal operands may have differing lengths, whereas both operands in a binary addition or subtraction have
the same length (perhaps after internal sign extension). If the decimal operands have the same length, then no decimal
overflow will occur when adding numbers of unlike sign.
28.2.2. The results are:
(a)
(b)
(c)
(d)
(e)
(f)
(g)
(h)

X04294967295C , CC=2, no overflow.


X00001C , CC=3, overflow
X99997D , CC=1, no overflow
X 4 D , CC=3, overflow
X111C , CC=2, no overflow
X 0 C , CC=0, no overflow
X000D , CC=3, overflow
X 7 D , CC=3, overflow

28.2.3. The results are:


(a)
(b)
(c)
(d)
(e)
(f)

X12690C , CC=2, no overflow.


X000D , CC=3, overflow
X000C , CC=0, no overflow
X458C , CC=3, overflow
X040000000D , CC=1, no overflow
X00000C , CC=0, no overflow

Section 28.3
28.3.1. The subtraction would overflow, setting the Condition Code incorrectly to 3 instead of 2, and possibly also
causing an interruption for decimal overflow.
28.3.2. The CC will be set to 1, because the first operand (X 0 C ) is logically less than the second (X 0 D ). Remember
that the Assembler generates the preferred sign codes!
28.3.3. The CC settings are:
(a)
(b)
(c)
(d)
(e)
(f)
(g)
(h)

CC=1
CC=2
CC=1
CC=1
CC=2
CC=0
CC=1
CC=1

28.3.4. The CC settings are:


(a)
(b)
(c)
(d)
(e)
(f)

CC=2
CC=1
CC=0
CC=0
CC=1
CC=0

28.3.5. The operands may overlap only if their rightmost bytes coincide.

1160

Assembler Language Programming for IBM z System Servers

Version 1.00

Section 28.4
28.4.2. Let the first and second operands be N1 and N2 bytes long respectively. Then operand 2 (the multiplier) can
have at most 2 N2 1 nonzero digits, and operand 1 (the multiplicand) is required to have at most 2 (N1 N2) 1
nonzero digits. (Remember that N1 > N2.) The largest number of nonzero digits in the product is the sum of these, or
2 N1 2, but the product is 2 N1 1 digits long.
28.4.3. Because the product is at most 16 bytes long, the shorter operand must be at most 8 bytes long. Even though
multiplication is commutative (a*b is the same as b*a), the fact that operand 1 is to receive the product forces operand
2 to be the shorter operand.
28.4.4. The largest valid first and second operands are
Operand1 DC
Operand1 DC

PL16999999999999999
PL8999999999999999

(15 9 s)
(15 9 s)

so the largest product is X0999 9999 9999 9998 0000 0000 0000 001C . (Spaces added for readability.)
28.4.5. The products are shown in this table:

(a)
(b)
(c)
(d)
(e)
(f)

Original Pair
(9 + ) (9 )
(72 ) (7 + )
(44 + ) (44 + )
(15 ) (55 + )
(107 + ) (107 + )
(28 + ) (3 )

Product
X081D
X00504D
X0001936C
X0000825D
X0011449C
X00084D

Reversed Pair
(9 ) (9 + )
(7 + ) (72 )
(44 + ) (44 + )
(55 + ) (15 )
(107 + ) (107 + )
(3 ) (28 + )

Product
X081D
X00504D
X0001936C
X0000825D
X0011449C
X00084D

28.4.6. The result will not be 063 + . Even though the first operand field is long enough to hold the product, it does not
have as many leading zero bytes as the length of the second operand. This will lead to a Data exception, and the IC
will be set to 7.
Section 28.5
28.5.2.
(a) 113 + 055 +
(b) decimal divide interruption
(c) 67957045711 1 +
(d) 520322163 + 202 +
(e) 38460 018 +
28.5.3. In 08 35 the quotient sign digit is not in the low-order position of the second byte.
Section 28.7
28.7.4. It seems simplest to add positive and negative terms separately, and then add those two results. But if the list is
long, the number of digits needed to hold the intermediate sums increases, and the addition time for each term therefore increases also. The choice probably depends on operand sizes and the number of items in the list. (Theres no
simple answer, unfortunately.)

Suggested Solutions to Selected Exercises and Programming Problems

1161

Section 29 Solutions
Section 29.1
29.1.1. The CC settings are:
(a)
(b)
(c)
(d)
(e)
(f)

CC=3
CC=0
CC=1
CC=2: the operand is X00FF
The operand is invalid because it is more than 16 bytes long.
CC=0: the operand is X818283846F , or 818283846 +

29.1.2. Not really. You could start with the rightmost byte and step the starting address of the operand to the left one
byte at a time; but if any byte had two invalid digits, you couldnt tell which it was. You might get better results with a
TRT instruction and an appropriate translate table.
Also, stepping from right to left would also require remembering which byte had the most recent bad digit.
29.1.3. Because valid digits are in the range from 0 to 9, you could use this test:
CLI
JH
J

BadByte,X 9 F
BadLeft
BadRight

c(BadByte) > X 9 F
c(BadByte) < X 9 F

This test fails if the byte is actually valid. (Why?)


Section 29.2
29.2.1. The second bytes containing the two length digits for the 7 ZAP instructions are respectively X 1 0 , X 1 0 ,
X 1 2 , X 1 2 , X 1 1 , X 1 0 , and X 1 1 .
29.2.2. When (1) a preferred sign digit is desired, (2) when validity checking of sign and digits is desired, or (3) to set
the CC to reflect the sign of the operand.
29.2.3.
(1)
(2)
(3)
(4)
(5)
(6)

C(X)
C(X)
C(X)
C(X)
data
data

= X123D ,
= X405C ,
= X000C ,
= X753C ,
exception,
exception,

CC = 1;
CC = 2;
CC = 0;
CC = 2;
caused by invalid digit;
caused by invalid sign.

29.2.4. It might be tempting to try


XI

PackVal+L PackVal-1,1

However, this wont work if the sign code is E or F, both of which indicate + .) One way is to construct a translate table
which leaves the left half of the byte unchanged, and which changes the right half to a preferred sign code of the
opposite sense. One way is this:

Temp

ZAP
Temp,PackVal
ZAP
PackVal,=P 0
SP
PackVal,Temp
- - DS
PL(L PackVal)

Copy to a temporary
Clear the original field
Copy back with opposite sign
Temporary, same size as PackVal

An even simpler way to do this (courtesy of John Ganci) is:


ZAP
XI

PackVal,PackVal
PackVal+L PackVal-1,1

Make a preferred sign (C or D)


Invert the sign

29.2.5. These are two possible disadvantages; there may be others!

You must remember to check for operand fields of equal length. Because MVC has only a single length field, it
might be easy to change the length of one of the operands and forget that the MVC statement will not be correct
after the program is re-assembled.
MVC doesnt set the Condition Code, and does not check for invalid results.

29.2.6. The maximum value of the Length Expression in the MVC instruction is 256, so we must have

1162

Assembler Language Programming for IBM z System Servers

Version 1.00

NDec-1 = 256/L Dec


which (with L Dec equal to 3) gives NDec=86. (Why is there a 1 in the above expression?)*
29.2.7. These two instructions will do the job:
ZAP
NI

SomeVal,SomeVal
SomeVal+L SomeVal-1,X FE

Force preferred sign code


Set low-order bit to zero

The ZAP instruction will not change the value of the operand, but will ensure that the sign code is one of the preferred
values, X C or X D . The NI instruction sets the low-order bit of the sign code to zero, making the sign code + . Note
that
OI

SomeVal+L SomeVal-1,X 0 F

sets the sign to + , but X F isnt the preferred plus sign. (This can be important if youre using CLC to compare lots of
packed decimal data: two equal values like X 1 C and X 1 F could compare as unequal.)
Section 29.3
29.3.1. The results will be
at A: X005C
at B: X 3 F
at C: X F0F5FCF3

After adding X 3 F to X002F


The operation code for UNPK
The unpacked value (?!)

Revising the code is left as another exercise for you.


29.3.2. The overflow will occur on the 127th addition.
This result is not obvious. Consider the first several additions: the results will be 368 + , 376 + , 382 + , 384 + , 388 + , etc.
You can see that the low-order digit takes values 4, 8, 6, and 2 in cycles that increase the original value by 20. When
the value arrives at 984 + , we will have performed (984-364)/20 4=124 additions; the next two additions give 988 +
and 996 + , and the next addition will overflow, leaving 002 + as the result. Thus, there are 124 additions to get to 984 + ,
and 3 more additions cause the overflow.
Dont just calculate (1000-364)/4=159, assuming an increment of 4 each time!
29.3.3. XC may be useless if a valid sign is required.
29.3.4. The only change occurs after the first addition, which produces 370+ and a CC setting of 2. Further additions
cause no changes, because the rightmost byte at XX contains 0 + . (Dont try this in a program; it might loop indefinitely!)
29.3.5. Yes. Consider (9 ) (999 ): the result is 0 + , the Condition Code is 3, and a decimal overflow has occurred.
29.3.6. Suppose the length of the first operand XX is N bytes, and that we want to zero the rightmost D digits, where D
is an odd number. (Why an odd number?) Then the SP instruction of Figure 290 on page 494 can be written
SP

XX(N),XX+(N-1)-D/2((D+1)/2)

To do this with an NC instruction, we might write

Mask
N

NC
XX+(N-1)-D/2((D+1)/2),Mask
- - DC
(D/2)X 0 0 , X 0 F
Leaves sign intact
Equ
(an odd number satisfying 0 < D < 2*N)

29.3.7. The results are:


Case 1: Decimal Overflow, CC=3, c(A)=X5C.
Case 2: CC=2, c(B)=X075C
Note that the result in both cases has the preferred plus sign code.
29.3.8. A decimal overflow can only be caused by packed decimal instructions, all of which are 6 bytes long. Thus, the
Instruction Length code cannot be 1.
29.3.9. A 4-byte packed decimal number can hold 7 digits, while each element of the Dec array is at most 5 digits long.
Thus, adding 50 elements cant overflow.

Because the first element is already initialized before the MVC is executed.
Suggested Solutions to Selected Exercises and Programming Problems

1163

Section 29.4
29.4.1. To test for valid signs and digits, or to set the CC to zero.
29.4.2. The last.
29.4.3. With the CP instruction, the CC setting will be 0, because positive and negative zeros are equal. With the CLC
instruction, the CC will be 1 because X000C < X000D . A different choice of sign codes can change the results!
29.4.4. These instructions dont use a temporary variable; the address in GR2 points to the current maximum value.
NDec

Equ
50
LA
0,NDec-1
LA
2,Dec
LA
1,Dec+L Dec
Compare CP
0(L Dec,2),0(L Dec,1)
JH
Next
LR
2,1
Next
LA
1,L Dec(,1)
JCT
0,Compare
ST
2,BigItemA
- - BigItemA DS
A
Dec
DS
(NDec)PL3

Number of table entries


Initialize count to (#entries-1)
Current largest
Start compare with second entry
Compare current max to element
Branch if max is bigger
Save address of new max value
Step pointer to next element
Count and loop
Save address of max value
Address of largest element
Table of elements

How would you modify these instructions to set GR3 to the index of the largest element (for example, to 1 for the first
element, 2 for the second, etc.)?
29.4.5. Remember that the hex representation of the two literals: =P+10 is X010C , and =P -20 is X020D . The CP
instruction will set the CC to 2 (the first operand is greater), but the CLC instruction will set the CC to 1 (the first
operand is lower). This shows why you must know the data types when choosing instructions to compare operands.
Section 29.5
29.5.1. 2 N 1 16, 1 N 2 8, N1 > N 2. (That was easy, wasnt it!)
29.5.2. Eight, because it is used as the length of the multiplier in the MP instruction, and because 2*LD is used in the
length expression for several other operands.
29.5.4. An MP instruction with identical operands will create a specification exception, because L1 is equal to instead
of greater than L 2.
29.5.5. If the multiplier is a single digit, as in
007+

7+

and we assume that the multiplier digit 7 + is fetched once, then the result should be the expected 049 + . However, if the
multiplier is longer than one byte, as in
0000777+

077+

the result would be unpredictable, depending on the order in which multiplicand and multiplier bytes are fetched. In
general, its best to avoid overlapping operands in decimal multiplication.
29.5.6. X049C .
29.5.7. X0003969C .
29.5.8. X07151577489C .
Section 29.6
29.6.1.If we assume that the preferred sign codes (X C and X D ) are used, then the test for a zero element could be
written
Test

CP
JNE
TM
JO

0(ELen,1),=P 0
AddUp
ELen-1(1),X 0 1
Divide

Check for zero magnitude


Okay to add
Test rightmost sign bit
Finished (almost) if it s 1

If the other four sign codes are used, we must modify the tests to also check for a sign code of X F :

1164

Assembler Language Programming for IBM z System Servers

Version 1.00

Test

CP
JNE
TM
JZ
TM
JNO

0(ELen,1),=P 0
AddUp
ELen-1(1),X 0 1
Addup
ELen-1(1),X 0 F
Divide

Check for zero magnitude


Okay to add
Test rightmost sign bit
Not negative; OK to add
Check for + sign with X F
Branch if not +0 to divide

29.6.2. 2 N 1 16, 1 N 2 8, and N 1 > N 2


29.6.3. A DP instruction with identical operands will cause a specification error, because L1 is equal to L2 instead of
being greater.
29.6.4. You could do a decimal divide by 2 and test the remainder; or, you could use a TM instruction like this:

PData

TM
PData+L PData-1,X 1 0
JO
Even
- - DC
P1234567

Test rightmost decimal digit


Branch if it s even
Sample data

29.6.5. The condition code setting for a + 0 and a 0 is always zero, so you cant know what the sign is.
29.6.6. This is guaranteed to produce a specification exception, because L1 will necessarily be less than or equal to L2.
29.6.7. If the divisor is one digit long, as in
00000067+

7+

then the result might be the expected 00009 + 4 + . However, if the divisor is longer than a single digit, it is difficult to
predict the result. In general, its best not to use overlapping operands in decimal division.
29.6.8. X00009C4C (quotient 9, remainder 4).
29.6.9. X00001C000C . (quotient 1, remainder 0)
29.6.10. X00016C495C . (quotient 16, remainder 495)
29.6.11. There is no obvious reason why this should be the case; you can easily visualize dividing a 31-digit dividend by
a 25-digit divisor to give a 25-digit remainder and a 5-digit quotient. The answer may be that (a) limited CPU internal
space for long operands, since division by a 25-digit divisor could involve many repeated subtractions. By limiting the
divisor to 15 digits and sign, the internal circuits would not have to carry more than 8 bytes at a time.
29.6.12. Review the discussion at the end of Section 28.5.
29.6.14. The result is X82479C030C047C , with quotient 82479 and remainder 30. (The fact that the divisor is adjacent
to the dividend and divisor is only meant to make the problem a little more confusing.)
29.6.15. Number of quotient digits = 2 (dividend_length divisor_length) 1
Section 29.7
29.7.1. Both expressions result in an unsigned displacement X FFFFFFFE . This is then larger than 4095, the largest
possible value for the displacement D2. The statement should be written
SRP

A,64-2,0

Shift 2 digits to the right

She could also specify a USING statement like


USING 5,-2
but (as with all similar promises to the Assembler) would have to be sure that GR5 contains 2 when the SRP instruction is executed. (Try it, and see what the assembled instruction looks like!)
29.7.2. Because at least one high-order zero digit must have been introduced, any carry generated by the rounding
process cannot propagate past the end of the shifted operand.
29.7.3. If the rounding digit is added in binary, a carry might not propagate into the next higher-order decimal digit of
the first operand, or an invalid digit might be generated.
29.7.4. Both instructions will cause decimal data exceptions.
29.7.5. The results are
1. 998+ (no shift!)
Suggested Solutions to Selected Exercises and Programming Problems

1165

2. 950+
3. 010+
29.7.6. The shift amount is 1, a one-digit right shift, and the resulting data will be X00457D

= PL3 -457 .

29.7.7. The shift operand (63) is the same as 1, so a single right shift with rounding will be done. The result will be
X00457D , not X00456D , because the rounding digit is given the same sign as the shifted operand.
29.7.9. Feel free to stop when youve written 100 statements in your attempted solution. Congratulate yourself if you
can find a solution (including CC settings) less than 100 statements long. Now you know why SRP was invented!
29.7.10. Using a signed shift amount meant that only one shift instruction was needed, rather than two, one for left
shifts and one for right shifts. Also, the maximum length of a packed decimal operand is 31 digits, while binary shifts
can handle up to 63 bits.
29.7.12. Our programmer friend forgot that the rounding digit is (internally) given the same sign as the decimal
operand. The Assembler will complain that the rounding operand digit I 3 is not between 0 and 9.
29.7.13. The result is c(E)=X500C with decimal overflow causing CC3. Note the preferred plus sign.
29.7.16.
1. If the left shift causes no decimal overflow, and
2. shifting the operand does not cause a decimal divide exception, then
3. the method will give a rounded quotient.
29.7.17. Consider these: (1) add 5- to 5-; the (overflowed) result will be 0-. (2) multiply 0+ by 0-. (3) divide 000+ by
1-. (4) use SRP to shift all significant digits of (say) -5 off the right end of the field.
Section 29.8
29.8.2. The results are
X00000123456C
X000C1C2C3C4C
X0000001E240C
X23456789ABCC

1.
2.
3.
4.

29.8.3. The number of numeric digits moved is always odd.


29.8.4. The number of numeric digits truncated is always odd.
29.8.6. The possible movements for the digits, and an instruction that does the movement, are shown below:
1L
1R
1R
1L
1L
1L

2L
2R
2L
2L, 1R 2R
2R, 1R 2L
2R

MVZ
Byte2,Byte1
MVN
Byte2,Byte1
MVO
Byte2,Byte1
MVC
Byte2,Byte1
PACK Byte2,Byte1 (OR UNPK)
Let me know how you did it.

29.8.7. First, the operation of the instructions:

The two MVC instructions create an 8-byte field at Out with copies of the byte.
The NC instruction masks off all but the single bit at each of the bit offsets from zero to seven. For example, the
first four bytes will contain X80 40 00 10 .
The MVO instruction moves the first four bytes to the Work field, offset to the right by 4 bits (effectively rightshifting).
The following MVC moves the four right-shifted bytes back to their original positions at Out.
The TR instruction converts each bit value to an EBDCIC 0 or 1 character.

The literal must be nine characters long, because the possible offsets into the string (from the bit values at Out) can take
values from 0 to 8.
Section 29.9
29.9.1. The operand 0001234 + has only one byte of high-order zeros, but the operand 100 + is two bytes long.
29.9.2. The most important restriction is that the result operand must be 16 or fewer bytes long; this can be written

1166

Assembler Language Programming for IBM z System Servers

Version 1.00

L + N/2 < 16 .
Similarly, the original operand must be 15 or fewer bytes long, so L < 16 and N > 0. The required instruction
sequence then takes the form
MVN
MVO
NC

A+L+N/2(1),A+L-1
A(L+1),A(L)
A+L(N/2+1),=XL(N/2+1) F

29.9.3. We require L < 16, N > 1, and N < 2L-1. Then we can use the code sequence

A
B

MVN
MVO
NC
- - DC
DS

B+L-1(1),A+L-1
Move sign
B(L-N/2),A
Move digits
B+L-N/2-1(N/2+1),=XL(N/2+1) F
PL(L) initial value
PL(L)
Shifted result goes here

29.9.4. We require L 16 and 0 < N < 2L. The MVN instruction can then be written

B
A

MVN
A+L-N/2-1(1),A+L-1
- - DS
0PL(L-N/2)
Define length attribute of result
DS
PL(L)
Original L-byte operand

29.9.5. Suppose N = 2L 1, which means that all the digits of the operand are to be shifted off. Then the MVO
instruction
MVO

A,A(0)

might appear to do the job. However, as you remember from the discussion of the length digits in two-length SS-type
instructions, a zero in the Length Expression is assembled as a zero length digit in the instruction. This is equivalent to
MVO

A,A(1)

which performs a shift of N 2, or 2L 3, digits, rather than N as required.


29.9.6. The code sequence below illustrates a possible solution.

Okay

LA
CLI
JNH
SR
MVO
NI
LTR
BNZR

1,Over
A,X 0 9
Okay
1,1
A(L),A(L)
A+L-1,X F
1,1
1

Set address of overflow branch


Check for high-order zero digit
Skip if digit is zero
Reset branch address
Perform the single shift
Reset the low-order digit to zero
Now test the overflow switch
Branch to Over if an overflow

29.9.7. We require L 16 and 0 < N < 2L. The following instructions perform the required shift.

Mask

MVC
A(L-N/2),A+N/2
Shift left N digits
NC
A+L-N/2-1(N/2+1),Mask
Mask out vacated digits
- - DC
X F0 , ( N/2-1)X 0 , X 0 F

29.9.8. The test for lost significant digits might be written

BadNews

LA
OC
JNZ
SR
DC
- - LTR
BNZR

1,Over
A(N/2),A
BadNews
1,1
0H
1,1
1

Set branch address


Check n high-order digits
Branch if not all zeros, overflows
Set branch flag for no overflow
Shift as in previous solution
Check overflow flag
Branch if something was lost

29.9.9. Because the result must be 16 or fewer bytes long, we must have L+N/2 16; in addition, N > 0 and
0 < L 15. The instructions can then be written

Mask

MVC
A+L+N/2-1(1),A+L-1 Move sign
NC
A+L-1(N/2+1),Mask Zero intervening digits
- - DC
X F0 , ( N/2-1)X 0 , X 0 F

Suggested Solutions to Selected Exercises and Programming Problems

1167

29.9.10. Consider the following instructions:


MVC
A+L A-1+N/2(1),A+L A-1
NC
A+L A-1(N/2+1),Mask
- - DC
X F0 , ( N/2-1)X 0 , X 0 F
DC
PL(length) value
DS
PL(N/2)

Mask
A

The length of A, plus N/2, should be less than or equal to 16; otherwise the result will be too long to be used as a valid
packed decimal operand. The value of N must be even and greater than zero.
29.9.12. We require L 16 and N 2 (L 1).
Section 29.10
29.10.1. The values are:

A
B
Sum

(3,0)
(3,3)
(7,0)

Section 29.11
29.11.1. The values are:
1.
2.
3.
4.

P1024.2048
P -0.98765
P+2235058.4
P72.3456

I = 5 ,
I = 2 ,
I = 8 ,
I = 3 ,

S=4
S=5
S=1
S=4

Programming Problem 29.2.


This little program shows the result. The first two executable instructions set the decimal overflow bit in the Program
Mask to zero, to disable the interruption for decimal overflow.
P29_2

M5

CSect ,
Using *,15
Print NoGen
XR
1,1
SPM
1
AP
M5,M5
Printout M5,*,Header=No
DC
P -5
End
P29_2

Establish addressability
Don t generate the macro expansions
Set GR1 to zero
Set decimal overflow interrupt off
Add (5-) and (5-)
Print the result and stop
Single-byte 5-

Note that CC=3 is displayed on the Printout message, as expected.

Programming Problem 29.3.


This little program shows the result.
P29_3

M0
P2

1168

CSect ,
Using *,15
Print NoGen
MP
P2,M0
Printout P2,*,Header=NO
DC
P -0
DC
PL2 2
End
P28_3

Establish addressability
Don t generate the macro expansions
Multiply (2+) and (0-)
Print the result and stop
Single-byte 0Two-byte 002+

Assembler Language Programming for IBM z System Servers

Version 1.00

Section 30 Solutions
Section 30.1
30.1.1. Twelve. The largest 64-bit signed magnitude is 263 = 9,223,372,036,854,775,808 (19 digits), and the 16-byte
receiving field can handle 31 digits.
30.1.2. An 8-byte field holding a packed decimal number has room for 16 hex digits, of which 15 are numeric decimal
digits and the last is a sign code.
30.1.3. c(X) = X000002147483648D . (That should have been easy!)
30.1.4. The first character string printed would be Page 0002I, with a letter I where the 9 should be. This is caused
by the UNPK instruction leaving the sign code digit C as the zone of the low-order byte of the page number. When
the page number is 30, the field will print as Page 0003?, where the rightmost character position indicated by ? is an
unprintable character having representation X C0 . (What will actually appear on the printed page depends on the
behavior of your printers and your Operating System.) When the page number is 31, Page 0003A will be printed.
30.1.5. Heres one way to do it:

Blot

Finish

- - OI
ZonePn+NDigits-1,C 0
Set zone of final digit
LA
0,NDigits-1
Set digit count less 1
LTR
0,0
Test if only 1 digit wanted
JNP
Finish
Exit if so
LA
1,PageNo+L PageNo-NDigits
Address of first digit
CLI
0(1),C 0
Check for leading zero
JNE
Finish
Exit loop if nonzero
MVI
0(1),C
Set to blank
LA
1,1(,1)
Step to next digit position
JCT
0,Blot
Count down and loop
- - -

If we knew that the digit count specified by NDigits would always be greater than 1, we could omit the test for a single
digit. Note that we always leave one visible digit, even if the page number is zero.
30.1.6. The values are
1.
2.
3.
4.

X000000000000001D
X000002147483321C
X000002004318083C
X000001077952604C

30.1.7. The values are


1. X0000000000000000000000000000001D
2. X0000000000009223372036854775807C
3. X0000000000000826260414904981820C
(Be careful! the argument value has 17 hex digits, so the high-order digit was lost.)
4. X0000000000006717250228839017560D
Section 30.2
30.2.1. A fixed-point divide exception will occur, because the packed decimal operand is +2 31. The result in the first
operand register will be X80000000.
30.2.2. The instructions will execute correctly. GR0 will contain X0000007B , and the contents of DWork will be
X000000000000123C .
30.2.3. The Assembler will issue an error message for the PACK instruction, because the (implied) length of the second
operand exceeds 16 bytes!
30.2.4. Converting a blank data field is a common error in using CVB. After the PACK instruction is executed, the
contents of WorkArea will be X0000000000000004, which has an invalid sign code. Thus, the CVB instruction will
cause a program interruption for a data exception, and the IC will be set to 7.
30.2.5. Because log 2(1015) = 49.83, at least 50 binary digits would be needed to compute the magnitude correctly.
Since the high-order bits will be lost even if the result is complemented, 50 bits would be sufficient.

Suggested Solutions to Selected Exercises and Programming Problems

1169

One way to do the conversion is by successive multiplications and additions; no divisions need be done! If the partial
terms of the intermediate value are multiplied by 10 and the new low-order digit is added, only 32 bits need to be
carried, but overflows must be detected so that an invalid result can be indicated.316 It would be inadvisable to indicate
a fixed-point overflow condition, since the program mask can be set to ignore them, and the program would have to
check the CC for an overflow indication; but CVB doesnt set the CC!
30.2.7. The low-order 32 bits of the result might be useful if the remainder (mod 2 32) has some significance to the
program. But to use the result, the program would first have to handle the program interruption.
30.2.8. The resulting values are:
1. X0098967F
2. X D3A8C00E
3. X FFFFFFFF
(Note that the high-order digit of the DC statement operand was truncated!)
4. X000003E7
Section 30.3
30.3.1. The patterns are:
1. FC is a blank; the pattern is C dddddsd .
2. F C = C * ; the pattern is C *dddsd.ss . The only Message Character is the period before the last two Digit
Selectors.
3. F C = C * ; the pattern is C *dddsdfTotal=dddsd.dd . The Message Characters are the blanks before and after
the first set of selectors, the characters C Total= , and the period before the last two Digit Selectors.
4. FC is a blank; all other bytes are Message Characters.
30.3.2. The pattern is represented by C ( CR) ( . One problem with reading this pattern is that each interior
apostrophe represents a single byte, and they arent paired; however, if theyre paired, then its even harder to tell what
the pattern is!
Section 30.4
30.4.1. The result at LineX will be C123456789, because the final digit of the decimal number will not be accessed.
30.4.2. The Fill Character can be a digit selector; thus L 1 digits, and therefore as many as (L 1)/2 + 1 bytes, might be
taken from the second operand. If there are no digit selectors in the pattern, no bytes would be taken from the second
operand.
30.4.3. The results will be
1. C 729413 , where represents a blank space.
2. C **0000729413
3. C *****0729413
30.4.4. The results will be
1. C 7294 , where represents a blank space.
2. C **0000007294
3. C *****0007294
30.4.5. Because the SS character in the pattern immediately precedes the last DS of the pattern, eleven blanks followed
by a single zero digit will replace the pattern. The DS marks the position of the last leading zero to be suppressed.
30.4.6. Because there are at most 10 significant digits in the decimal representation of the value contained in a fullword,
the first digit of the 6-byte (11-digit) packed decimal number is always zero. Thus the first DS is always replaced by the
Fill Character.
30.4.7. Since no decimal digits will be sought at the second operand address, no exception condition due to the invalid
address will be recognized.

316

It is strange that an error in a multiplicative process can be indicated by a divide exception!

1170

Assembler Language Programming for IBM z System Servers

Version 1.00

Section 30.5
30.5.1. Be careful! Pattern characters may affect the Significance Indicator, but no Message Character affects the SI.
30.5.2. The SS character must appear one byte earlier, so the pattern becomes C dd,dsd.ddCREDIT :
Pat2

DC

C , X20206B2021204B2020 , C CREDIT

Pattern

If the amount was 0000002+, the edited result would be 0.02CREDIT.


30.5.3. There should be 2 P 1 d and s selectors.
30.5.4. A packed decimal operand P bytes long contains 2 P 1 digits. Also, to produce any useful results at all, we
must have D < P. For example, if D=P 1, only a single digit can be formatted.
1. Even if the desired number of digits N is even, there must be an odd number of selectors: 2 (P D) 1. The
leftmost digit of the packed decimal operand must be zero if an even number of digits is to be displayed correctly.
2. To display N digits requires B= [(N + 2)/2] bytes, where the square brackets mean that the quotient should be
rounded down to the next lower integer. Thus, the offset D is P B. (In mathematical notation, we should write
B=floor(N + 2)/2, where floor(X) is the largest integer less than or equal to X.)
30.5.5. If c(Num) = 0, only a single zero digit will be printed; all the preceding Message Characters are insignificant.
If c(Num) = 512, no commas will appear in the result because the SI is turned on by the first significant digit (5),
which follows the last comma.
Section 30.6
30.6.1. This code fragment shows one way this can be done:

DoSign
DoPlus
DoMinus
Print
SignBits
PackVal
Pattern
Display

MVC
Display,Pattern
Move pattern to print line
LA
1,Display+L Display-1
Point to possibly forced digit
EDMK Display,PackVal
Edit and mark up to 7 digits
JNZ
DoSign
If not zero, set sign
XR
2,2
Clear GR2
IC
2,PackVal+L PackVal-1
Insert rightmost byte
NILL 2,X000F
Clear all but sign digit
IC
2,SignBits-X A ( 2 ) Get sign indicator
LTR
2,2
Set CC (0 means -, 1 means +)
BCTR 1,0
Adjust to preceding byte
MVI
0(1),C +
Assume result was +
JP
Print
Branch if the guess was right
MVI
0(1),C -
Negative result, set - sign
PrintLin Display,L Display
Print result
- - DC
AL1(1,0,1,0,1,1)
Sign indicators +,-,+,-,+,+
DC
PL4 0
Packed decimal operand
DC
C , 5 X 2 0 , X2120
Pattern
DS
CL8

30.6.2. The CC setting will be zero, because all the digits of the result are zero. It is possibly misleading that the SI will
still be ON at the end of the operation, due to the sign code in the right half of the last source byte.
Section 30.7
30.7.1. If each of the second operand bytes contains a sign code in the right digit, N bytes will be taken from the
second operand. If none of the first N digits of the second operand is a sign code, as few as (N+1)/2 bytes might be
taken from the second operand. (Remember, the Field Selector FS doesnt cause any second operand access.)
30.7.2. The CPU retains the digit it has, and doesnt reset the second-operand digit fetcher to get a new left-hand
digit.
30.7.3. GR1 will point to a character in the last source field only if there are significant nonzero digits stored into that
field, and significance was not forced by a SS character in the pattern.
Section 30.8
30.8.1. The Significance Indicator is set OFF as follows:

at the start of the operation,


after a Field Separator (FS) pattern character, and
Suggested Solutions to Selected Exercises and Programming Problems

1171

after a source byte containing a + sign code in the right-hand digit.

The Significance Indicator is set ON as follows:

pattern
pattern
pattern
pattern

=
=
=
=

SS, source = any nonterminal digit;


DS, source = nonzero terminal digit;
SS, source = terminal digit with sign code;
DS, source = nonzero terminal digit with sign code.

Programming Problem 30.3.


This program scans for multiple data values on each input record.
P31_3

CSect ,
Print NoGen
Using *,15
PrintLin Title,L Title
LA
10,10

Problem 30.3
Don t show macro expansions
Establish addressability
Print a title line
Initialize multiplier

*
GetRec

ReadCard InBuff,EndFile
MVI
OutLine,C
MVC
OutLine+1(L Outline-1),OutLine Initialize output line
LA
2,InBuff
Point to start of record
LA
3,L InBuff-1
Set effective length of record
Scan
EX
3,ScanTRT
Scan over leading blanks
JZ
GetRec
No more data on this record
LR
7,1
Save pointer to initial digit
XR
5,5
Initialize accumulated value
GetDigit CLI
0(1),C
Check for terminating blank
JE
Display
Go display this result
IC
6,0(,1)
Insert a numeric character
N
6,=XL4 F
Mask all but numeric digit
MR
4,10
Multiply partial value by 10
ALR
5,6
Add new digit
BC
3,TooBig
Carry out means overflow
LR
8,4
Copy accumulated value
LR
9,5
...both halves
SLDA 8,32
Check for overflow
JO
TooBig
Value is too large
LA
1,1(,1)
Step to next character
J
GetDigit
And get additional digits
*
Display CVD
5,Work8
Convert value to packed decimal
MVC
OutVal,ValPatt
Move pattern to output area
ED
OutVal,Work8+2
Convert to edited characters
J
MovChars
Go move the input characters
*
TooBig
MVC
OutVal,=CL12 **OverFlow**
Insert overflow message
StepOver CLI
0(1),C
Check for end of digits
JE
MovChars
Reached the end, go move them
LA
1,1(,1)
Step to next character
J
StepOver
Continue looking
*
MovChars LR
8,1
Copy pointer to ending blank
SR
8,7
Subtract string start address
BCTR 8,0
Make an effective length
EX
8,OutMVC
Move the character string
PrintLin OutLine,L OutLine
Display the results
MVC
OutLine+1(L OutLine-1),OutLine
Clear the print line
*
LR
2,1
Point where rescan starts
LA
3,InBuff+L InBuff-1
Point to end of record
SR
3,2
Remaining length to scan
BCTR 3,0
Make it an effective length
J
Scan
Look for another digit string
EndFile PrintOut *,Header=NO
End the program

1172

Assembler Language Programming for IBM z System Servers

Version 1.00

*
ScanTRT
OutMVC
ValPatt
Title
OutLine
OutVal
OutChars
SkipBlnk
InBuff
Work8

TRT
MVC
DC
DC
DC
Equ
Equ
DC
DS
DS
End

0(*-*,2),SkipBlnk
Skip blanks
OutChars(*-*),0(7)
Move character string
C , 9 X 2 0 , X2120
Edit pattern
C Converted Value
Input characters
CL100
Output line
OutLine+4,12
Position/length of value
Outline+20
Position of input characters
(C ) X 1 , X 0 , ( 2 5 5 -C ) X 1
Translate table
CL80
Buffer for input records
CL8
CVD work area
P31_3

The sample data was in these records:


1
0002
0003
1234567890
9999999999

2147483647
000000000000000000000042

and the output was these records:


Converted Value
1
2
3
1234567890
2147483647
**OverFlow**
42

Input characters
1
0002
0003
1234567890
2147483647
9999999999
000000000000000000000042

Programming Problem 30.7. This solution uses a loop to eliminate leading zeros from the unpacked value.
(Compare it to your solution for Problem 17.4.)
P30_7

CSect ,
Using P30_7,15
Provide addressability.
* Set up initial values.
LA
2,0
Previous value F(0).
LA
3,1
Current value F(1).
PrintLin Title,L Title
PrintLin OutRec,1
*
Loop
CVD
3,WrkArea
Convert to packed decimal
UNPK Number,Wrkarea+2(6) Unpack to EBCDIC
OI
Number+L Number-1,X F0 Set correct zone on last digit
LA
5,Number
Start of output value
Check
CLI
0(5),C 0
Is it a leading zero?
BNE
PrintNum
If not, print the result
MVI
0(5),C
If yes, replace it with a blank
LA
5,1(5)
Step to next character
B
Check
And try the next digit
PrintNum PrintLin OutRec,OutLeng Print the result
LR
4,2
Get a copy of the previous value.
AR
4,3
Compute the next value.
BO
Done
Overflow means we re done.
LR
2,3
Copy current value to previous.
LR
3,4
Copy next value to current.
B
Loop
Play it again, Sam.
*
DONE
PrintLin EndRec,L EndRec Print an ending line.
BR
14
Return to caller.
*
WrkArea DS
D
OutRec
DC
C
Carriage control for output.
Number
DS
CL12
Output from conversion
OutLeng EQU
*-OUTREC
Length of record.
*

Suggested Solutions to Selected Exercises and Programming Problems

1173

Title
EndRec

C 1 Fibonacci Sequence to Maximum Positive Fullword Value


C 0 Program ends.
P30_7

DC
DC
END

The printed output looks like this:


1Fibonacci Sequence to Maximum Positive Fullword Value
1
1
2
3
..........
701408733
1134903170
1836311903
0Program ends.

Programming Problem 30.8. This solution uses the E D instruction to format the result with commas separating
each group of three digits. (Compare it to your solution for Problem 30.7.)
* Print a Fibonacci Sequence up to Maximum Fullword Value.
P30_8
CSect ,
Using P30_8,15
Provide addressability
*
* Set up initial values.
*
LA
2,0
Previous value F(0).
LA
3,1
Current value F(1).
PrintLin Title,L Title
PrintLin OutRec,1
*
Loop
CVD
3,WorkArea
Convert to packed decimal
UNPK Number,Workarea+2(6) Unpack to EBCDIC
MVC
OutRec(OutLeng),EdPat Move edit pattern to output area
ED
OutRec(OutLeng),WorkArea+2 Format the result
PrintLin OutRec,OutLeng Print the result
LR
4,2
Get a copy of the previous value.
AR
4,3
Compute the next value.
BO
Done
Overflow means we re done.
LR
2,3
Copy current value to previous.
LR
3,4
Copy next value to current.
B
Loop
Play it again, Sam.
*
Done
PrintLin EndRec,L EndRec Print an ending line.
BR
14
Return to caller.
*
WorkArea DS
D
EdPat
DC
C
Fill character
DC
X20206B2020206B2020206B202120 dd,ddd,ddd,dsd
OutRec
DC
C
Carriage control for output.
Number
DS
CL15
Output from ED
OutLeng EQU
*-OutRec
Length of record.
*
Title
DC
C 1 Fibonacci Sequence to Maximum Positive Fullword Value
EndRec
DC
C 0 Program ends.
END
P30_8
The printed output looks like this:

1174

Assembler Language Programming for IBM z System Servers

Version 1.00

1Fibonacci Sequence to Maximum Positive Fullword Value


1
1
2
.............
987
1,597
.............
3,524,578
.............
701,408,733
.............
1,134,903,170
1,836,311,903
0Program ends.

Suggested Solutions to Selected Exercises and Programming Problems

1175

Section 31 Solutions
Section 31.2
31.2.1.
1.
2.
3.
4.

0.1 (base 10) = .00011001 (base 2), X19 (base 16).


0.3142 (base 10) = 0.0221110011 (base 3) = 0.458244 (base 14).
X BBBBB... = 0.733333333... (base 10) = 0.AEEEEE... (base 15).
3.6 (base 8) = 3.75 (base 10) = X 3 C .

31.2.2.
1.
2.
3.
4.
5.

X 0 . DEFACE = 0.87101448
X 0 . 5 = 0.3125
X 0 . C2854 = 0.75984573
X0.333333 = 0.19999999
X 0 . BEEF = 0.74583435

31.2.3. These are the four hexadecimal fractions:


1.
2.
3.
4.

X0.10504816F...
X0.00068DB8BAC7...
X 0 . FCD38CDA...
X0.00003C53E2D6...

31.2.4. (1/3) base 2 = .0101010101...


31.2.5. The values are shown, where underscored groups of digits are repeated indefinitely.
0.110
0.210
0.310
0.410
0.510
0.610
0.710
0.810
0.910

=
=
=
=
=
=
=
=
=

0.06314
0.1463
0.23146
0.3146
0.4
0.4631
0.54631
0.6314
0.71463

Section 31.3
31.3.1. The values could be defined as follows:
Amount
Percent
Round
Correct

DC
DC
DC
DC

F1174949
F5147
F 0 . 5 E5
F 1 E5

Amount in cents (scaled by 10**2)


Percentage rate (scaled by 10**3)
Rounding factor
Correction factor

31.3.2. The generated constant is X 0 E8D4A51 .


31.3.3. The two constants will generate X1174949C (4 bytes) and X05147C (3 bytes) respectively. The product work
area must therefore be at least 7 bytes long.
31.3.4. The hexadecimal values are:
1. X 6 . 5 F5C28F5...
2. X 3 DB.9A5E353...
3. X13A.28C59E0...
31.3.5. With signed 32-bit words, you can create 32 different representations, and with unsigned words, 33. This may
seem surprising, but remember that the radix point can be placed to the left of the leftmost significant digit as well as to
the right of the rightmost digit.
31.3.6. You need 10 bits for the integer part (2 9 < 604 < 210). The fraction part isnt finite (or at least, appears not to be!).
31.3.7. The hexadecimal constant is X3243F6A9 .

1176

Assembler Language Programming for IBM z System Servers

Version 1.00

= 10**12 = X 1 D1A94A2
= 10**13 = X9184E72A

DC
DC

FS(-11)10E11
FS(-12) U10E12

DC
DC

FDS(-25) U10E25 = 10**26 = X295BE96E64066972


FDS(-26) U10E26 = 10**27 = X CECB8F27F4200F3A

31.3.9. This way of writing the constant seems natural, as it looks like Ten to the 12th power. But its actually 10
followed by 12 zeros, which is too large for a signed constant.
31.3.10. This solution is partially parameterized using the symbols SF and SD:
X31_3_10 CSect ,
Using *,15
SF
Equ
24
Binary Scale Factor
SD
Equ
5
Significant fraction digits
L
1,A
Get value to convert
LR
0,1
Copy to GR0
SRL
1,SF
Discard fraction digits
CVD
1,D
Convert integer portion
UNPK Int,D
Unpack to EBCDIC
OI
Int+L Int-1,X F0 Correct low-order zone digit
CLI
Int,C 0
Is hign-order digit zero?
JNE
DoFrac
If not, continue
MVI
Int,C
Set the zero to space
DoFrac
DC
0H
Now do the fraction part
L
1,A
Get value to convert
SLL
1,32-SF
Eliminate integer portion
SRL
1,32-SF
Reposition fraction digits
M
0,=FE(SD) 1
Multiply to 10**SD (significance)
SRDL 0,SF-1
Drop all but rounding bit
AHI
1,1
Add 1 to round
SRL
1,1
Drop off rounding bit
CVD
1,D
Convert to packed decimal
UNPK Frac,D
Unpack fraction digits
OI
Frac+L Frac-1,X F0
Set correct zone digit
Printout Result,*,Header=No
Print result
A
DC
FS(SF)98.234567 Value to convert
D
DS
D
CVD conversion area
Result
DS
0CL(3+1+SD)
Int
DC
CL3
Integer portion
DC
C .
Decimal point
Frac
DC
CL(SD)
Fraction digits
End
X31_3_10
Section 31.4
31.4.1. Avogadros Number is 6.022 10 + 23, and Plancks constant is 6.626 10 34 .
31.4.2. Avogadros Number is slightly less than 1024, and Plancks constant is slightly greater than 10 35, so you would
need enough bits to represent 10 59, or about 200 bits. (Now you can see why floating-point is useful for some types of
applications!)
Section 31.5
31.5.1. Zero will have representations with a zero fraction, and 19 possible exponent values from 9 to + 9, including
zero. Usually the preferred representation of zero will use a zero exponent, so that the other 18 are redundant.
31.5.2. There are six possible representations, three with the significant digits represented as fractions and three with the
significant digits represented as integers.
Fractions:
Integers:

.0047 e=+3
0047. e=-1

.0470 e=+2
0470. e=-2

.4700 e=+1
4700. e=-3

Section 31.7
31.7.1. The original implementation of floating-point registers on System/360 provided only registers 0, 2, 4, and 6, so it
was natural to pair them as (0,2) and (4,6). When the remaining 12 registers were added, it was important to retain the
original pairings (so that existing programs would continue to execute correctly); the other pairings were made to follow
the same pairing style.
Suggested Solutions to Selected Exercises and Programming Problems

1177

31.7.2. The CPU need only OR the given register digit with B0010.
Section 31.8
31.8.1. DD, EB, L or LH, LD.
Section 31.9
31.9.1. Here are three possibilities: the first requires two storage references and a doubleword in memory; the second
uses FPR6 as a temporary, and the third uses GGR1 as a temporary.

DTemp

STD
0,DTemp
LDR
0,4
LD
4,DTemp
- - DS
D

LDR
LDR
LDR

6,0
0,4
4,6

LGDR
LDR
LDGR

1,0
0,4
4,1

You can create other (more elaborate) ways to do this, such as


LDGR
LDGR
XGR
XGR
XGR
LGDR
LGDR

1,0
2,4
1,2
2,1
1,2
0,2
4,1

Copy FPR0 to GG1


Copy FPR4 to GG2
Do the
.. XOR
.. swap
Copy original contents of FPR4 to FPR0
Copy original contents of FPR0 to FPR4

but no reasonable programmer would do it this way. *


31.9.2. Use the floating-point registers as intermediate storage.
31.9.3. LXY and STXY for single load and store, and perhaps LMF and STMF (or LMFP and STMFP) for
muultiple load and store. The most important exception condition would be to check that the register operand is a
valid reference to an extended register pair.

Programming Problem 31.1.


This solution uses packed decimal arithmetic:
P32_1

PDAmt
PDTax
PDProd
PDPat
PDAns

CSect ,
Using *,15
Print NoGen
ZAP
PDProd,PDAmt
Copy amount to work area
MP
PDProd,PDTax
Multiply by tax rate
SRP
PDProd,64-5,5
Convert to cents and round
MVC
PDAns,PDPat
Move pattern to output area
LA
1,PBAns+7
Point just past possible $ sign
EDMK PDAns,PDProd+3
Edit the result
BCTR 1,0
Move pointer left 1 byte
MVI
0(1),C $
Insert dollar sign
PrintOut PDAns,*,Header=NO
Print result
DC
P11749.49
Amount to be taxed
DC
P.05147
Tax rate
DS
PL8
Work area for product
DC
C , X40202020202021204B2020 Formatting pattern
DC
CL12
Output area for result
End
P32_1

The printed result will look like this:


PDAns

$604.75

Some people think Assembler Language programmers are inherently unreasonable.

1178

Assembler Language Programming for IBM z System Servers

Version 1.00

Programming Problem 31.2.


This solution uses scaled fixed-point binary arithmetic:
P32_2

FBNoC

FBAmt
FBTax
FBRnd
FBConv
FBWork
FBPat
FBAns

CSect ,
Using *,15
Print NoGen
L
1,FBAmt
Put argument in GR1
M
0,FBTax
Multiply by tax rate
AL
1,FBRnd
Add rounding factor
JC
12,FBNoC
Skip if no carry
AHI
1,1
Propagate carry
D
0,FBConv
Correct to get result in cents
CVD
1,FBWork
Convert to decimal
MVC
FBAns,FBPat
Move pattern to output area
LA
1,FBAns+7
Point just past possible $ sign
EDMK FBAns,FBWork+3
Edit, mark first significant digit
BCTR 1,0
Move pointer left 1 byte
MVI
0(1),C $
Insert dollar sign
PrintOut FBAns,*,Header=NO
Print result
DC
F1174949
Rate in cents
DC
F5147
Tax rate per 100,000 cents
DC
F 0 . 5 E5
Round to nearest cent
DC
F 1 E5
Convert result to cents
DC
D 0
Integer part in packed decimal
DC
C , X40202020202021204B2020 Formatting pattern
DC
CL12
Output area for result
End
P32_2

The printed result will look like this:


FBAns

$604.75

Programming Problem 31.3.


This isnt an easy problem, but it shows the efforts that programmers made when only fixed-point binary arithmetic was
available.
P32_3

SF
FBLoop

CSect
Using
Print
Equ
L
SRDA
D
S
SRA
LPR
A
ST
LPR
CHI
JH
LR
SRDA
CVD
UNPK
OI
MVI
SRL
M
SRDL
AHI
SRDL
CVD

,
*,15
NoGen
28
0,FBA
0,32-SF
0,FBX
1,FBX
1,1
2,1
1,FBX
1,FBX
2,2
2,3
FBLoop
4,1
4,SF
4,DFBW
FBAns(1),DFBW+7(1)
FBAns,X F0
FBAns+1,C .
5,32-SF
4,FBConv
4,SF-1
5,1
4,1
5,DFBW

Scale factor
Put argument in GR0
Shift right, now scaled by 2**28
Divide by current scaled estimate
Subtract it to get the correction
Divide by 2
Copy magnitude for tolerance test
Add original estimate
Store new value
Take magnitude of correction
Check correction smaller than 3
Repeat if not converged yet
Copy for formatting
Split integer and fraction parts
Convert integer part to decimal
Move to answer string
Put correct zone
Place the decimal point
Reposition fraction part
Convert 9 fraction digits
Position as integer value
Add 1 for rounding
Final shift
Convert to integer
Suggested Solutions to Selected Exercises and Programming Problems

1179

FBA
FBX
FBConv
DFBW
FBAns

OI
DFBW+7,X 0 F
Set correct zone
UNPK FBAns+2(9),DFBW+3(5) Move fraction part to output area
PrintOut FBAns,*,Header=NO
DC
FS(SF) 2
Value whose root is to be found
DC
FS(SF) 1
Initial estimate
DC
F 1 E9
For converting fraction part
DC
D 0
Work area for CVD results
DC
CL12
Output area for result
End
P32_3

The printed result will look like this:


FBAns

1180

= 1.414213563

Assembler Language Programming for IBM z System Servers

Version 1.00

Section 32 Solutions
Section 32.1
32.1.1. The three values are:
1. 0.9450 10 3 (0.7654 0.1235=0.09452690)
2. 0.5859 10 4 (0.7655 0.7655=0.58599025)
3. 0.1000 10 1 (0.0333 0.0321=0.00106893)
Section 32.2
32.2.1. A nonzero operand can have at most p 1 leading zero digits, so at most p 1 shifts are required.
32.2.2. The two products are:
Not pre-normalized
0.100010 2
Zero!

Pre-normalized
0.102910 2
0.518310 1

Section 32.3
32.3.1. The (possibly unexpected) results are the following:
(a) .9995 for each iteration
(b) 1.001, 1.002, 1.003, 1.004
(a) 1.000 for each iteration
Section 32.4
32.4.1. Any operand of the form .xxxD with digit D 0. Its exponent doesnt matter.
32.4.2. The values are shown in this table:
Product
155165
452469
211117
127137

No guard, no round
.255010 5
.111110 6
.234010 5
.173010 5

Guard, no round
.255710 5
.111110 6
.234510 5
.173910 5

Guard and round


.255810 5
.111110 6
.234610 5
.174010 5

Guard, no round
.514010 5
.282410 6
.279910 6
.209610 6

Guard and round


.514110 5
.282510 6
.280010 6
.209610 6

32.4.3. The values are shown in this table:


Product
509101
509555
509150
407515

No guard, no round
.514010 5
.282410 6
.279010 6
.209010 6

32.4.4. With only a guard digit, the results are these:


1. 0.9452 10 3
2. 0.5859 10 4
3. 0.1068 10 1
With both guard and rounding digits, the results are these:
1. 0.9453 10 3
2. 0.5860 10 4
3. 0.1069 10 1

Suggested Solutions to Selected Exercises and Programming Problems

1181

Section 32.5
32.5.1. One advantage is that steps of the multiplication process can stop when the remaining multiplier or multiplicand
digits are known to be zero; it can also avoid the necessity of right-shifting the product digits if the product would be
longer with rightmost zeros.
For example, (1230. 10 0) (4500. 10 0) or 1230 4500 = 5535000 has 3 low-order zeros; in FPI(10,4) three corrective
right shifts would be needed. If internal arithmetic used only 4 digits, its possible some high-order digits could be lost,
or an error condition might be indicated.
Section 32.6
32.6.1. The shift requirements are shown in this table:
Operation
.1428 .7142
.6667 .6666
.1277 .3456
.3456 .1275
.9999 .9999

Quotient
.2000
1.00015
.3695
2.71059
1.0000

Shifts
0
1
0
1
1

Rounded quotient
.2000
.1000
.3695
.2711
.1000

If the dividend (numerator) fraction is greater than or equal to the divisor (denominator) fraction, the quotient will
be greater than 1, requiring a shift.
Section 32.7
32.7.1. The calculated results are shown in this table:
Operation
(.743510 3) (.962110 1)
(.743510 1) (.699410 1)
(.104310 5) (.952710 4)
(.100010 0) (.999210 2)

No guard, no
round
.733810 3
.441010 0
.900010 3
.900010 1

Guard, no
round
.733810 3
.441010 0
.903010 3
.900010 1

Guard and
round
.733910 3
.441010 0
.903010 3
.900110 1

32.7.2. If you subtract zero, the magnitude of the other operand doesnt decrease.
Section 32.8
32.8.1. The relative sizes of the largest ulps are these:
Representation
FPF(16,14)
FPF(2,24)
FPF(10,34)

Max relative ulp


16 13
2 23
10 33

Section 32.9
32.9.1. Consider these three pairs: 317
1. [ + 9 + .2000] [ 9 + .4000] generates [ + 18 + .5000]
2. [ 9 + .2000] [ + 9 + .4000] generates [ 18 + .5000]
3. [ 9 + .2000] [ + 2 + .4000] generates [ 11 + .5000],
which if denormalized becomes [ 9 + .0050],
32.9.2. These are the results:
1. [ + 9 + .1038] (Normal)
2. [ + 7 .4830] (Normal)

317

You could just provide the examples shown in Section 32.9 (with keys 1, 2, and 5) but that would be less interesting.

1182

Assembler Language Programming for IBM z System Servers

Version 1.00

Section 32.10
32.10.1. Max= [ + 63X FFFFFF ], which with bias=X 7 FFFFFFF ; and Min= [ 64X100000] which with
b i a s = X00100000.
32.10.2. Because Min is approximately 16 65, its reciprocal is about 16 + 65. Since Max is approximately 16 + 63, the
range asymmetry means that there are about p 16 2 more small values than large, where p is the precision of the
fraction.

Suggested Solutions to Selected Exercises and Programming Problems

1183

Section 33 Solutions
Section 33.1
33.1.1. Five possible interpretations, and their Assembler language defining statements, are shown in these statements:
DC
DC
STH
DC
DC

F1077952604
C *
4,X05C ( 0 , 4 )
P+4040405
E.250982046

Fullword binary integer


Characters (three blanks and an asterisk)
Store halfword
Packed decimal
Hexadecimal floating-point

Other interpretations are possible.


33.1.2. For short hexadecimal floating-point numbers, (a) 5, (b) 6, (c) 6, (d) 256. For long numbers, (a) 13, (b) 14, (c)
14, (d) 256. (The reason there are 256 redundant values for zero is that pseudo-zeros of either sign are included.)
33.1.3. The values are (1) Normalized, (2) Normalized, (3) Unnormalized, (4) Zero, (5) Normalized, (6) Pseudo-zero,
(7) Normalized.
33.1.4. The 14-bit characteristic would have a range from 213 to + 213 1, or approximately ( 8192, + 8191),
assuming the bias is chosen to provide range symmetry.
Section 33.2
33.2.1. The easiest way to tell is to assemble a long constant also:
DC
DC

E 1 E13
D 1 E13

generates X 4 B9184E7
generates X 4 B9184E72A000000

So the short constant does not contain all the significant bits. (You could also check the table of the hexadecimal
representation of powers of ten in the Appendix.)
33.2.2. This is one of many possibilities:
DC

E 1 , 1 e1,1e2,1e3,1e4,1e5,1e6,1e7,1e8,1e9,1e10

33.2.3. The tables in the Appendix showing the hexadecimal representations of powers of 10 are helpful!
1. Short: 10 9 = X 3 B9ACA00 (or X483B9AC in short H F P format) has six nonzero significant digits.
2. Long: 10 22 = X21E19E0C9BAB2400000 (or X5321E19E0C9BAB24 in long H F P format) has fourteen nonzero significant digits.
3. Extended: 10 46 = X 1 C06A5EC5433C60DDAA16406f5A400000000000 (or X671C06A5EC5433C6 590DDAA16406F5A4 in
extended HFP format), has 28 nonzero significant digits.
33.2.4. The nine values are:
401999999999999A
4033333333333333
404CCCCCCCCCCCCD
4066666666666666
4080000000000000
409999999999999A
40B3333333333333
40CCCCCCCCCCCCCD
40E6666666666666

DC
DC
DC
DC
DC
DC
DC
DC
DC

D 0 . 1
D 0 . 2
D 0 . 3
D 0 . 4
D 0 . 5
D 0 . 6
D 0 . 7
D 0 . 8
D 0 . 9

Section 33.3
33.3.1. For the constants named A and D, only a single byte is available to hold the sign and characteristic, leaving no
room for the fraction! So, the Assembler will complain about lost precision. For the other constants, the generated
data is
B
C
E

X401A
X433E
X433F

The fraction is rounded to 8 bits


999=X 3 E7 , and the 7 is truncated
1000=X 3 E8 , and the 8 causes rounding up

33.3.2. These are the values and their generated constants:

1184

Assembler Language Programming for IBM z System Servers

Version 1.00

3.710 3
1.01055
8.810 0
1.01018

W
X
Y
Z

X43E7400000000000
X 6 E6867A6
X418CCCCCCCCCCCCC 33CCCCCCCCCCCCCD
X503782DB

Section 33.4
33.4.2. With half-even rounding, the L-type constant generates X 1 E177FF880000000 1000000000000000 so you cant
tell whether the rounding digit (the last 8) should be rounded up (if there are any nonzero bits in the distance) or not
(that is, to the even final digit 8). So, the Assembler must calculate the value of the constant to more than 112 bits.
(Some nonzero bits do appear with additional precision, so the Assembler knows the value should be rounded up, as
shown.)
33.4.3. The rounding modifiers and the generated values are:
X 3 E4189374BC6A7F0
X 3 E4189374BC6A7F0
X 3 E4189374BC6A7EF

R1
R4
R5

Section 33.6
33.6.1. The result in FPR(0,2) will be
FPR0: X50123456789ABCDE
FPR2: X42DCBA9876543210

(unchanged)
(corrected characteristic and sign)

and the CC will be 2 indicating a positive result.


33.6.2. These are the CC settings and register contents:
(1)
(2)
(3)
(4)

CC=2,
CC=1,
CC=1,
CC=2,

c(FPR4) =
c(FPR2) =
c(FPR4,6)
c(FPR4) =

X 4 C428571
X CC42857196DBB933
= X 8 A123456789ABCDE FC42857196DBB933
X 4 C42857196DBB933

Section 33.7
33.7.1. The primary change is to use MER rather than MEER.

Loop

XX
Count
YY
ZZ

XR
XR
LZDR
LH
LE
LE
MER
MDR
STD
LA
LA
JCT
- - DC
DC
DC
DS

5,5
6,6
4,4
2,Count
0,XX(5)
4,YY(5)
0,0
0,4
0,ZZ(6)
5,L XX(,5)
6,L ZZ(,6)
2,Loop

GR5 contains index for XX and YY


GR6 contains index for ZZ
Set long FPR4 to zero
Counter in GR2
Load X(i) in FPR0 (short)
Load Y(i) in FPR4 (now, long)
Long X(i)*X(i) in FPR0
Multiply by Y(i)
Store long result Z(i)
Increment XX, YY index by 4
Increment XX index by 8
Count down and loop

E 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 1 0 Values of X(i)
Y((*-XX)/L XX)
Count of X(i) entries
5E3.14159,2.71828
Values of Y(i)
10D
Long results Z(i)

33.7.2. The resulting fraction has only 12 significant digits, and the two low-order fraction digits are always zero.
33.7.3. They could be different. ME generates an 8-byte product that needs no rounding, because the low-order byte of
the product is X 0 0 . MEE generates only a 4-byte product, for which a rounded result would depend on the leftmost
bit of the right half of the long product.
33.7.4. Heres one way to calculate the table of cubes:

Suggested Solutions to Selected Exercises and Programming Problems

1185

CubeIt

Cubes

LA
0,100
LE
2,=E 1
LER
6,2
LA
1,Cubes
LER
4,6
MER
4,4
MER
4,6
STE
4,0(,1)
LA
1,L Cubes(,1)
AER
6,2
JCT
0,CubeIt
- - DS
100E

Set count of results wanted


Constant 1 in FPR2
Initialize N
Set GR1 to start of table
Copy N to FPR4
Form N**2
Form N**3
Store in the table of cubes
Increment table address
Increment N by 1
Repeat for 100 values

33.7.5. c(FPR0)=X4112345699999999; the right half of FPR0 is unchanged.


33.7.6. This leads to the peculiar (and possibly disturbing) circumstance that for a large class of hexadecimal floatingpoint numbers (those with a nonzero low-order digit), multiplication by 1 would not yield the original operand!
33.7.7. Simply XOR X40 to the sum.
Section 33.8
33.8.1. The Assembler generates the rounded constant E 0 . 6 = X4099999A .
33.8.2. The results are X 3 F9ABCD8 and X 3 E9ABC80 respectively.
33.8.3.
1. c ( F P R 0 ) = X427D93482D335B9E .
2. c ( F P R 0 ) = X C53BA1816A7D80C7 .
33.8.4. An exponent underflow interruption will occur if the Program Mask bit is one, and c(FPR4)=x 7 F100000 . If
the Program Mask bit is zero, c(FPR4)=0, and no interruption occurs.
33.8.5. HER and HDR can be thought of as analogs of
SRA

x,1

SRDA

x,1

and
Section 33.9
33.9.1. The result is X5812345698765400.
33.9.2. The instruction will generate a specification exception, because both operands dont refer to the lower-numbered
register of a floating-point register pair. FPR2 will be unchanged.
33.9.3. The mnemonic for Add Unnormalized is AU, and the mnemonic for Add Double Unnormalized is AW,
or A Double U. *
33.9.4. The results are:
1.
2.
3.
4.

c(FPR0)=X40130000,
c(FPR0)=X15400000,
c(FPR0)=X45000000,
c(FPR0)=X C2831693 ,

CC=2
with an exponent overflow interruption
CC=0
CC unchanged

33.9.5. The results are:


1.
2.
3.
4.
5.
6.

c(FPR0)=X42FE00F0 ,
c(FPR0)=X41104F3D ,
c(FPR0)=X42800078,
c(FPR0)=X00222242,
c(FPR0)=X46384000,
c(FPR0)=X C117D861 ,

CC=2
CC=2
CC unchanged
with an exponent overflow interruption
with an exponent underflow interruption
CC=1

Engineers find humor wherever they can.

1186

Assembler Language Programming for IBM z System Servers

Version 1.00

33.9.6. The results are:


c(FPR0)=X C1200000 ,
c(FPR0)=X44002000,
c(FPR0)=X44000000,
c(FPR0)=X04000000,
c(FPR0)=X 0 B012335 ,
c(FPR0)=X4601579A ,

1.
2.
3.
4.
5.
6.

CC=1
CC=2
with an HFP lost-significance interruption
with an HFP lost-significance interruption
CC=2
CC=2

33.9.7. The AER instruction will cause an interruption for exponent overflow, and the result in FPR0 is X801FFFFF .
33.9.8. Consider this addition:
2,=X 7 FFFFFFF
2,=X 7 E0FFFFF

LE
AE

Because the characteristic difference is one, the second operand must be right-shifted one digit, so that the CPU adds
the fractions X FFFFFF and X00FFFF , giving the sum X 1 . 0 0 FFFFE , which after a normalizing right shift gives the
result characteristic X 1 0 0 , indicating an exponent overflow and a final characteristic of zero. Any smaller second
operand would produce a smaller sum.
33.9.9. This operation subtracts (1 16 6) from 1, so the expected result is + 16 6.
1. SE produces c(FPR0) = X 3 B100000 , or 16 6 as expected.
The result of the unnormalized subtraction may be surprising:
2. SU produces c(FPR0) = X41000000, with a significance exception. To see how this happens:
41100000(0)
-40FFFFFF(0)
3B100000(0)

becomes

41000000(0)
-410FFFFF(F)
40000000(1)

Remember, the guard digit does not participate in the test for a zero intermediate fraction.
33.9.10. None.
33.9.12. Because the first operand is 10 6 and the second is 10 6, their sum must be able to represent at least 12
decimal digits. This means that either long or extended hexadecimal floating-point operands and arithmetic must be
used.
33.9.13. The result is X57234569; the guard digit (the high-order digit 9 of the smaller operand) appears in the
result.
33.9.14. The results are:
(a)
(b)
(c)
(d)
(e)

X41110005
X4080004B
X40FFFFFF
X41100000
X40223456

Section 33.11
33.11.1. The result would have been X 3 FDCF140 , showing that an additional digit of precision is generated.
Section 33.12
33.12.1. The fraction of the X 3 B10wxyz operand must be shifted right five digits for operand alignment, giving the
internal subtraction
40000001(0)
-40000001(w)
40000000(?)
Because the guard digit is ignored for comparisons, the two operands appear to be equal, and the Condition Code is
set to zero. (Try it!)
33.12.2. These are the resulting Condition Code settings:
1.
2.
3.
4.

(1)
(2)
(3)
(4)

CC
CC
CC
CC

=
=
=
=

1
2
0
2
Suggested Solutions to Selected Exercises and Programming Problems

1187

Section 33.13
33.13.1. Since the carry that caused the overflow was the result of adding a low-order 1-bit, the result fraction must be
X . 1 0 0 0 . . . . Because the characteristic wraps around from 127 to 0, the result must be either X 0 0 1 0 0 . . . or
X 8 0 1 0 0 . . . .
33.13.2. The three results are:
1. c ( F P R 0 ) = X0010000087654321, rounded, with an interruption for exponent overflow.
2. c ( F P R 0 ) = X4000000187654321 (rounded).
3. c ( F P R 0 ) = X4000000012345678 (not rounded).
33.13.3. The sequence works. For example, if FPR2 is initialized to X4200000080000000, the rounded result stored at
Round3 is X42100001.
33.13.4. There will be no difference. The LDER instruction extends the short number from Variable with zero, so the
LEDR instruction cannot round the result in FPR0.
Section 33.14
33.14.2. The largest positive integer is X 7 FFFFFFFFFFFFF00 = + 9223372036854775552, and the result is
X50FFFFFFFFFFFFF . The largest negative value is X8000000000000000 = 9223372036854775808, and its result is
X D080000000000000 .
The magnitude of the negative number is 256 larger than the magnitude of the positive number because not all 63 bits
of the positive number can be held in the 14 hex digits of the long hexadecimal floating-point result.
33.14.3. No, because the largest 64-bit integer is less than 1019, well within the range of all three hexadecimal floatingpoint formats.
33.14.4. The first instruction changes the sign bit of the integer operand. Remember that the twos complement representation of a 32-bit binary integer X is (232 + X) (modulo 2 32). Thus, if the integer was originally positive,
(232 - X) - 231 = 231 - X
is stored. This quantity is placed in FPR0 and 2 31 is subtracted from it. The result is the normalized value of X.
33.14.8. All three can be generated as hexadecimal floating-point D-type constants, but the first causes an Assembler
error:
000008 4E00000000000000
DCon1 DC DS(14) 0 . 1
Error, lost significance
** ASMA073E Precision lost
000018 CE00000080000000
DCon2 DC DS(6) -2147483648
-2**31, unnormalized
000028 4F08000000000000
DCon3 DC DS(1)36028797018963968 +2**55, unnormalized
The obscurity of these constants shows why a hexadecimal constant can be simplest.
33.14.12. The statement is
Float

DC

DS62147483648

33.14.13. This is one way to do it:

OK
T
W

L
ST
LZDR
AD
STD
TM
JZ
XC
AD
STE
- - DC
DC

0,IntVal
0,T+4
6
6,T
6,W
W+4,X 8 0
OK
W+1(3),W+1
6,W
6,Result

Get the integer


Store in pseudo-zero
Set FPR6 to zero
Create the normalized HFP value
Store the result for testing
Is the lost bit 1?
If not, no rounding needed
Clear high-order 6 digits of result
Add the rounding bit
Store the rounded

0D,X 4 E , 7 X 0
D 0

Doubleword aligned pseudo-zero


Doubleword temporary

33.14.14. This is one way to do it:

1188

Assembler Language Programming for IBM z System Servers

Version 1.00

Round

OK
T
W

L
ST
LZDR
AD
STD
CLC
JNE
TM
JZ
TM
JZ
XC
AD
STE
- - DC
DC

0,IntVal
Get the integer
0,T+4
Store in pseudo-zero
6
Set FPR6 to zero
6,T
Create the normalized HFP value
6,W
Store the result for testing
W+4(4),=X80000000 Is it exactly halfway between?
Round
If not, do normal round up
W+3,X 1
Is the low-order bit zero?
OK
If so, result is even, don t round
W+4,X 8 0
Is the lost bit 1?
OK
If not, no rounding needed
W+1(3),W+1
Clear high-order 6 digits of result
6,W
Add the rounding bit
6,Result
Store the rounded
0D,X 4 E , 7 X 0
D 0

Doubleword aligned pseudo-zero


Doubleword temporary

33.14.15. The results are shown in this table:


HFP_Number
X46000000
X C7654321
X 7 FEDCB49
X ABCDEF74
X4974662B

c(GR3)
X00000000
X F9ABCDF0
X 7 FFFFFFF
X00000000
X 7 FFFFFFF

CC
0
1
3
1
3

c(GG3)
X0000000000000000
X FFFFFFFFF9ABCDF0
X 7 FFFFFFFFFFFFFFF
X0000000000000000
X000000074662B000

CC
0
1
3
1
2

33.14.16. The converted 32-bit value is X00010001. Unfortunately, the halfword value is then X0001!
33.14.17. Using the value at DFloat, the result stored at DTemp will be X 4 E00000001000003 , and the number at NF
will be X01000003.
Section 33.15
33.15.1. The results in FPR0 after each step are:

After
After
After
After

DE: X41140000 (1.25)


FIER: X41100000 (1.0)
ME: X42100000 (16.0)
AE: X41400000 (4.0)

33.15.2. The AU instruction causes the fraction part of c(FPR0) to be shifted off; the ME instruction will pre-normalize
the integer part in FPR0, so the results will be the same.
33.15.3. In this case, the addition could cause the guard digit to be part of the normalized result. In Exercise 33.15.2,
the guard digit is not shifted left because there is no post-normalization.
If the quotient of the DE instruction is greater than or equal to X46100000, no fraction digits will be shifted off.
33.15.4. This is one way to do it:

AModB
A
B

LD
DD
FIDR
MD
LCDR
AD
STD
- - DS
DC
DC

0,A
0,B
0,0
0,B
0,0
0,A
0,AModB

Load A into FPR0


Divide by B
Drop off the fraction part
Form product with integer part
Form -B*IntPart(A/B)
Add A to form remainder
Store result

D
D 2 0
D 1 6

Remainder
A value for A
And for B

33.15.5. The results in FPR0 are:

Suggested Solutions to Selected Exercises and Programming Problems

1189

(1)
(2)
(3)
(4)
(5)

X42120000
X C7FEDCA9 80000000
X00000000 00000000
X77654321
X C7FEDCA9

Section 33.16
33.16.1. Using short HFP arguments (the results would not change for long or extended arguments):

Sqrt(Max) = X60400000
Sqrt(Min) = X20400000
Sqrt(DMin) = X 1 E100000

33.16.2. If a carry occurred, the result fraction would have to be all one-bits, or (1 ulp). But this would mean that the
source operand would have to be (1 (ulp/2)), which cant happen.
33.16.3. First, remember that the argument and the result have the same length. Now, if the result were to lie exactly
half way between two representable target values, it would have to be finite in length. But that would mean that for
some exponent, its an integral value, and hence its square (the source operand) would also be integral. (A number
whose square root is an integer is itself an integer.) But square roots have about half as many digits as the source value;
and since source and target have the same number of digits, the square root must be shorter than the source, so it cant
lie exactly halfway between two representable values.
Section 33.19
33.19.1. This operation subtracts (1 16 6) from 16, so the expected result is 15 + 16 6. The actual results are:
(1)

SE produces c(FPR0) = X41F00001 or 15 + 16 5 with an error of 15/16 ulp.

(2)

SU produces c(FPR0) = X420F0000 , an unnormalized value of 15 with error 16 6 or 1/16 ulp.

So the unnormalized result is more accurate! This peculiarity is caused by unrounded hexadecimal floating-point arithmetic.
33.19.2. This table shows the approximate values:
Exponent
width

Fraction
digits

7 bits

4 bits

Exponent range
64 to + 63
1.6*10 58 to 7.8*1056
16 to + 15
3.6*10 15 to 3.5*1013

Fraction
accuracy
5*10 7
6*10 8

These choices also depend on the expected uses of the representation: if customer data needs only a limited exponent
range, a 4-bit characteristic might give more fraction accuracy.*
33.19.3.
XGR
ICMH
OIHL
LFGR
DE
STE

0,0
0,8,X
0,1
0,0
0,X
0,ULPX

Clear 64-bit general register


Get sign/characteristic of X
Set bit 31 to 1
Copy X cc000001 00000000 to FR0
Divide by X
Store short precision ulp(X)

XGR
ICMH
OILL
LFGR
DD
STD

0,0
0,8,X
0,1
0,0
0,X
0,ULPX

Clear 64-bit general register


Get sign/characteristic of X
Set bit 63 to 1
Copy X cc000000 00000001 to FR0
Divide by X
Store long precision ulp(X)

33.19.5.

If you are interested in the reasons the designers of System/360 chose hexadecimal instead of base-8 floating-point, you might
consult this article: An Analysis of Floating-Point Addition, by D. W. Sweeney, IBM Systems Journal, Volume 4, Number 1,
1965.

1190

Assembler Language Programming for IBM z System Servers

Version 1.00

33.19.7.
LD
LD
XGR
ICMH
LFGR
LGHI
LFGR
DXR
STD
STD

4,X
6,X+8
0,0
0,8,X
0,0
0,1
2,0
0,4
0,ULPX
2,ULPX+8

Put high half of X in FR4


Put low half of X in FR6
Clear 64-bit general register
Get sign/characteristic of X
Copy X cc000000 00000000 to FR0
Put 1 in GG0
Copy X00000000 00000001 to FR2
Divide by X
Store high half of ulp(X)
Store low half of ulp(X)

Programming Problem 33.1.


P33_1

Loop

Calc
StoreF

FX
X
Max

START 0
BASR 15,0
USING *,15
LE
4,=E 1
LE
6,=E -5
STE
6,X
LER
2,6
MER
2,2
SE
2,=E 3
MER
2,6
SE
2,=E 2
JNZ
Calc
LE
0,Max
J
StoreF
LER
0,4
DER
0,2
STE
0,FX
PrintOut X,FX
AER
6,4
CE
6,=E + 5
JNH
Loop
PrintOut *,Header=NO
DS
E
DS
E
DC
EH ( Max)
END
P33_1

Set base register


And inform the assembler
Carry 1.0 in FPR4
And X in FPR6
Store X value for printing
Set up denominator
Form X squared
Subtract 3.0
(X*X-3.0)*X
-2.0; now have denominator
Branch if nonzero to compute
Otherwise set max value
And go store result
Numerator = 1.0
Form F(X)
Store value of function
Print values
Increase X by 1.0
Compare to last value
Branch if not bigger to do next X
Terminate program
Value of F(X)
Value of X
Maximum hexadecimal floating-point value

The maximum hexadecimal floating-point value will be printed when X = 1 and X = + 2.

Programming Problem 33.2. This program displays the long hexadecimal floating-point values.
P33_2

FactIt

Facts

CSect ,
Print NoGen
Using *,15
LA
0,55
LD
0,=D 1
LDR
2,0
LDR
4,0
STD
0,Facts
LA
9,Facts+L Facts
MDR
0,2
STD
0,0(,9)
PrintOut 32,Header=NO
ADR
2,4
LA
9,L Facts(,9)
JCT
0,FactIt
PrintOut *,Header=NO
DS
56D
End
P33_2

Set count of largest factorial


Initialize factorial value in FPR0
Initialize N in FPR2
Set increment in FPR4
Store 0 factorial
Set GR9 to next entry in table
Form F*N to form N!
Store in table
Print contents of FPR0
Increment F
Increment table address
Repeat for remaining values
Terminate
Storage for the factorial values

Suggested Solutions to Selected Exercises and Programming Problems

1191

The largest precisely representable short hexadecimal floating-point value is easy to find by examining the long results to
see which has nonzero digits extending past the sixth fraction digit; the last precise value is 12 factorial (12!). Finding the
equivalent long value is more difficult, because the last nonzero digit of 22! (X 3 CEEA4C2B3E0D80000 ) is X 8 and the last
significant digit of 23! (X57970CD7E2933680000 ) is X 6 , so its not easy to know whether the three low-order zero bits of
22! might be enough to hold the low bits of 23!, without going to higher precision.
By evaluating those two numbers in extended precision (as the hex values show), we find that 23! has a single one-bit in
the 15th hex digit, so that 22! is the largest that can be stored without loss of precision in long hexadecimal floating-point
format.

Programming Problem 33.3.


This solution first checks the input value for zero; otherwise, it multiplies or divides by powers of ten until the result is a
fraction less than 1 but greater than 0.1, keeping track of the decimal exponent. This fraction is multiplied by 10 6, converted to integer form, and formatted for printing.
P33_3

CSect ,
Print NoGen
F0
Equ
0
BASR 12,0
USING *,12
Read
ReadCard InRec,Exit
OC
InRec(8),=8C
MVC
PHex,InRec
TR
Inrec(8),HexCh
PACK DWord(5),Inrec(9)
LDE
0,DWord
XR
1,1
MVI
ESign,C +
TM
DWord,X 8 0
JZ
PlusSign
MVI
ESign,C -
PlusSign LPER F0,F0
JZ
Zero
CD
F0,=D 1
JE
FractOne
JH
PosExp
NegExp
MD
F0,=D 1 . E10
AHI
1,-10
CD
F0,=D 1
JL
NegExp
JE
FractOne
PosExp
CD
F0,=D 1 . E10
JL
Reduce
MD
F0,=D 1 . E-10
AHI
1,10
J
PosExp
Reduce
CD
F0,=D 1
JE
FractOne
JL
Convert
MD
F0,=D . 1
AHI
1,1
J
Reduce
Convert MD
F0,=D 1 . E6
AD
F0,=D . 5
CD
F0,=D 1 . E6
JNL
FractOne
CFER 0,5,F0
CVD
0,DWord
OI
DWord+7,X 0 F
UNPK EDigits,DWord
DoExpon DS
0H
MVI
ExpSign,C +
LTR
1,1
JNM
DoExpon2

1192

Floating-point work register


Set base register
Provide addressability
Read a record
Make upper-case characters
Move to output line for display
Translate digits to 0-F
Pack into a 4-byte word
Load and extend to long format
Clear GR1 for decimal exponent
Assume positive result
Check sign of input value
Skip setting - sign, + is correct
Result is negative.
Force argument sign + in register
Fraction is zero, finish up easily
See if argument has +/- exponent
All done if exactly 1.0
Branch if positive exponent
Negative exponent; increase by tens
And count decimal exponent down
Where did that take us?
If it s still too small, go again
If exactly equal, that s nice.
Positive exponent; check size
If in range, reduce slowly
Multiply gives more accuracy.
Bump decimal exponent accordingly
And do another reduction cycle
Exponent in (+10,0); check for 10**0
Fraction now is 1
Ready to convert if now a fraction
Reduce by 10**1
Increment exponent accordingly
And go around again
Convert to integer in (1,10**6)
Round it properly
Did it round up to 1000000?
It did, use fraction .100000
Convert to binary integer in GR0
Convert to packed decimal
Set correct zone
Place digits into string
Convert exponent
Assume positive exponent
Check for correct assumption
Skip if it was right

Assembler Language Programming for IBM z System Servers

Version 1.00

MVI
ExpSign,C -
Set exponent sign DoExpon2 CVD
1,DWord
Convert to decimal
OI
DWord+7,X 0 F
Set correct (positive) zone
UNPK Exponent,DWord
Unpack to zoned decimal
PrintLin PLine,Exponent-PLine+2
Print result
J
Read
Repeat for more values
Zero
MVC
EDigits,=6C 0
Set fraction to zeros
J
DoExpon
And go do exponent
FractOne MVC
EDigits,=C100000 Set fraction digits to .100000
AHI
1,1
Compensate by upping exponent
J
DoExpon
And go do exponent
Exit
PrintOut *,Header=NO
Terminate
LtOrg ,
Insert literals
DWord
DC
D 0
Work area
PLine
DC
C X
Start of print line
PHex
DS
CL8
Input value
DC
C =
ESign
DS
C
Sign of fraction
DecPt
DC
C .
Decimal point
EDigits DS
CL6
Fraction digits
ExponE
DC
C E
Exponent indicator E
ExpSign DS
C
Exponent sign
Exponent DS
CL2
Decimal exponent
HexCh
DC
256AL1(*-HexCh)
Define no-effect table
Org
HexCh+C A
Set origin to offset of A
DC
X FAFBFCFDFEFF
Translate numeric digit to hex
Org
,
Reset location counter
InRec
DS
CL80
Input area for records
END
P33_3

Programming Problem 33.6.


P33_6
HFPLoop

HFPA
HFPX

Csect ,
Using *,15
LD
0,HFPA
Put argument in FPR0
DD
0,HFPX
Divide by current estimate
SD
0,HFPX
Subtract current estimate
HDR
0,0
Divide by 2
LPDR 2,0
Copy for convergence test
AD
0,HFPX
Add original estimate
STD
0,HFPX
Store updated estimate
CD
2,=D 1 E-10
See if correction is small enough
JH
HFPLoop
If not, iterate again
LDR
2,0
Save final result in FPR2
SDR
4,4
Set FPR4 to zero for renormalization
AW
0,HFPUnn
Unnormalize to extract integer part
STD
0,HFPDW
Store temporarily
ADR
0,4
Renormalize the integer part
SDR
2,0
Remove integer part in FPR2
L
0,HFPDW+4
Get low-order word
CVD
0,HFPDW
Convert integer part to decimal
OI
HFPDW+7,X 0 F
Set proper zone
UNPK HFPAns(1),HFPDW+7(1)
Unpack the integer part
MVI
HFPAns+1,C .
Place the decimal point
MD
2,HFPCon
Convert fraction digits to integer
AD
2,HFPRnd
Add rounding factor
AW
2,HFPUnn
Unnormalize to form fullword integer
STD
2,HFPDW
Store temporarily
L
0,HFPDW+4
Get low-order word
CVD
0,HFPDW
Convert integer part to decimal
OI
HFPDW+7,X 0 F
Set proper zone
UNPK HFPAns+2(9),HFPDW+3(5) Move fraction part to output
Printout HFPAns,*,Header=NO
DC
D 2
Argument
DC
D 1
Initial estimate
Suggested Solutions to Selected Exercises and Programming Problems

1193

HFPCon
HFPRnd
HFPUnn
HFPDW
HFPAns

DC
DC
DC
DC
DC
End

D 1 E9
D 0 . 5
X 4 E , 7 X 0
D 0
CL12
P33_6

Conversion constant for fraction


Constant for rounding
Unnormalizing constant
Work Area
Output area for result

The printed result is


HFPAns

1194

= C1.414213562

Assembler Language Programming for IBM z System Servers

Version 1.00

Section 34 Solutions
Section 34.1
34.1.1. The three values are:
M i n = 2 126
D M a x = 2 126 2 149
D M i n = 2 149

34.1.2. There are 23 fraction bits in a short binary floating-point number, of which we must exclude the case of all zero
bits. So there are 223 1 possible bit combinations. Allowing for either sign, there are 2 (223 1) or 16,777,214 denormalized numbers.
34.1.3. The three values are:

Short format: X 7 F800000


Long format: X 7 FF0000000000000
Extended format: X 7 FFF000000000000 0000000000000000
Section 34.2

34.2.1. The constants are shown in this table:


Format
Short
Long
Extended

2 Bytes
3DCD
3FBA
3FFC

3 Bytes
3DCCCD
3FB99A
3FFB9A

4 Bytes
3DCCCCCD
3FB9999A
3FFB999A

In the 2-byte extended format, there is no fraction, only the implied 1-bit!
34.2.2. Six possible interpretations and the corresponding Assembler language defining statements can be written this
way:
DC
DC
STH
DC
DC
DC

F1077952604
C *
4,X05C ( 0 , 4 )
P+4040405
E.250982046
EB3.0039281845

Fullword binary integer


Characters (three blanks and an asterisk)
Store halfword
Packed decimal
Hexadecimal floating-point
Binary floating-point

Other interpretations are possible, as well see later.


34.2.3. The types of the six values are:
1.
2.
3.
4.
5.
6.

X 7 FFFFFFF
X007FFFFF
X80000000
X00FFFFFF
X FF8000AB
X FF800000

QNaN
Denormalized
0
Normal
QNaN
infinity

34.2.4. You wont be happy with the results, because

Short generates X 3 FB9999A , which has value +1.4500000 as a short operand, not 0.1!
ShortOne generates X 3 FF00000 , which has value +1.875 as a short operand, not 1!

Long generates X 3 DCCCCCCCCCCCCCCD , which has value +5.238689482212067E-11 as a long operand, not even
close to 0.1!
LongOne generates X 3 F800000000000000 as a long operand, which has value +7.8125E-3, not 1!

This shows why you should be very careful when using BFP constants defined with length modifiers.

Suggested Solutions to Selected Exercises and Programming Problems

1195

Section 34.3
34.3.1. The resulting value is X007FFFFF , one ulp smaller than EB(Min).
Section 34.4
34.4.1. The exception conditions are o and u (overflow and underflow), and the rounding mode is set to Down
(round toward infinity).
34.4.2. The instructions will (a) set the invalid-operation mask bit to zero, and (b) reset all the status flags to zero.
34.4.3. You would get a program interruption with IC=X 0 1 , meaning the instruction is invalid.
Section 34.5
34.5.1. The tested data classes are:
(a)
(b)
(c)
(d)

infinity, any QNaN, and SNaN.


Any and all data classes, so it tells you nothing useful!
Any NaN operand with any sign.
A zero operand.

34.5.2. In each case, the type of the operand is inconsistent with the type of the instruction. You should analyze the
operands carefully to see what each instruction thinks it is testing.
34.5.3. The redundant instruction is at (b): it tests for all data classes, so it will always set CC=1.
Section 34.6
34.6.1. The result in FPR(0,2) will be
FPR0: X50123456789ABCDE
FPR2: X FEDCBA9876543210

(unchanged)
(unchanged)

and the CC will be 2 indicating a positive result. (Compare this to the result of Exercise 33.6.1!)
34.6.2. The four results and the CC settings are:
(1)
(2)
(3)
(4)

LPEBR
LTDBR
LCXBR
LCDBR

4,2
2,2
4,0
4,2

CC=2,
CC=2,
CC=1,
CC=1,

c(FPR4)=X4285719600000000
c(FPR2) is unchanged
c(FPR4,6)=X 8 A123456789ABCDE 42857196DBB93310
c(FPR4)=X C2857196DBB93310

34.6.3. The resulting settings are (a) CC=2, (b) CC=3.


34.6.4. The TCDB instruction at (d) tests for a zero operand, so it could be replaced by
LTDBR 0,0

Test c(FPR0) for zero

Section 34.7
34.7.2. Heres one way to calculate the table of cubes:

CubeIt

BCubes

LA
LE
LER
LA
LER
MEEBR
MEEBR
STE
LA
AEBR
JCT
- - DS

0,100
2,=EB 1
6,2
1,BCubes
4,6
4,4
4,6
4,0(,1)
1,L BCubes(,1)
6,2
0,CubeIt

Set count of results wanted


Constant 1 in FPR2
Initialize N
Set GR1 to start of table
Copy N to FPR4
Form N**2
Form N**3
Store in the table of cubes
Increment table address
Increment N by 1
Repeat for 100 values

100EB

Table of cube values

34.7.3. This solution relies on setting the mask bits and the rounding mode in the FPCR:

1196

Assembler Language Programming for IBM z System Servers

Version 1.00

LFPC

=X D0000003

No underflow or inexact,
round to -infinity
Maximum value
c(FPR0)=X 7 F7FFFFF , rounded down to (Max)

*
LE
0,=EB ( Max)
MEEBR 0,0
Section 34.8

34.8.1. As in the solution to Exercise 34.7.3, this solution relies on setting the mask bits and the rounding mode in the
FPCR:
LFPC

=X D0000003

LE
DEB

0,=EB 1
0,=EB ( DMin)

No underflow or inexact,
round to -infinity
c(FPR0)=X 3 F800000
Result rounds down to (Max)

34.8.2. The results are:


1. X 3 F800000 = 1
2. X80000000 = 0
3. X FF800000 =
34.8.3. The three values are
1. 0
2. + 0
3. 1.0
34.8.4. Divide the signed zero into + 1, and check the sign of the resulting , using a Load and Test of the appropriate operand length.
Section 34.9
34.9.1. The representation of each (DMin) is X 0 0 0 . . . 0 0 1 . When added to itself, the result is X 0 0 0 . . . 0 0 2 . The need
to mask off all exception conditions is explained in the z/Architecture Principles of Operation; if the underflow exception is enabled, an interruption occurs and the final exponent is scaled to be in a valid range.
34.9.2. Because the value of (Min) is a power of two, adding (Min) to itself in each representation will simply double its
value, by increasing the exponent by one. Thus, the results are

X01000000 (short precision)


X0020000000000000 (long precision)
X0002000000000000 0000000000000000 (extended precision)

34.9.3. (a) + , (b) invalid operation.


Section 34.10
34.10.1. The CC values resulting from the comparisons are shown in this table:

Operand 2
C

Operand 1

Table 444. Comparing five binary floating-point operands


34.10.2. No.
Section 34.11
34.11.1. Yes, but be careful. You could shorten a binary floating-point operand by truncating the low-order portion,
but then you cant use the truncated operand as a shorter-format operand, because the exponent field will be too long.
They can be considered truncating only if the rounding mode is B 0 1 (toward zero), which chops off the low-order
digits.
Suggested Solutions to Selected Exercises and Programming Problems

1197

34.11.2. The short format has 23 significand bits; when lengthened to long format only its leading 22 or 23 bits will
match those of the original long format. Thus the difference between the original and final values will be approximately
X*(2 22).
34.11.3. The long precision values will be:
1.
2.
3.
4.
5.
6.

X 3 F800000
X00800000
X00000001
X 7 FE00000
X 7 FA00000
X 7 F800000

00000000
00000000
00000000
00000000
00000000
00000000

+7.8125E-3
+2.848E-306
+2.121E-314
+8.988E+307
+5.618E+306
+1.404E+306

You must be careful to know the true length of each binary floating-point operand!
Section 34.12
34.12.2. No, because the largest 64-bit integer is less than 1019, well within the range of all three binary floating-point
formats.
Section 34.13
34.13.1. The results are:
1.
2.
3.
4.
5.

X40800000
X40800000
X40400000
X40800000
X40400000

=
=
=
=
=

4
4
3
4
3

34.13.2. The long precision value loaded into FPR0 is X40230000 00000000 . But the FIEBR instruction treats it as a
short precision operand, which has value 2.54685, so the rounded value in FPR2 is X40400000, with value + 3.
The fact that the original operand + 9.5 didnt round to + 10 shows why you must be careful to match operand lengths
expected by the instructions to the length of the data items.
Section 34.14
34.14.1. From Table 264 on page 625 we can see that
(Max) 3.4 10 + 3 8 so its square root is 1.84 10 + 1 9 .
(Min) 1.2 10 -38 so its square root is 1.08 10 -19.
(DMin) 1.4 10 + 4 5 so its square root is 3.74 10 -23.
34.14.2. Because the operand is long precision but the instruction extracts the square root of a short precision operand,
the result is not + 4.0, but +1.6583 instead.

Programming Problem 34.2. This solution illustrates a way to derive useful results with low overhead.
P35_2

CSect ,
Print NoGen
F0
Equ
0
BASR 12,0
USING *,12
Read
ReadCard InRec,Exit
OC
InRec(8),=8C
MVC
PHex,InRec
TR
Inrec(8),HexCh
PACK DWord(5),Inrec(9)
LE
F0,DWord
XR
1,1
MVI
ESign,C +
TM
DWord,X 8 0
JZ
PlusSign
MVI
ESign,C -
NI
DWord,X 7 F
PlusSign LPEBR F0,F0
JZ
Zero

1198

Floating-point work register


Set base register
Provide addressability
Read a record
Make upper-case characters
Move to output line for display
Translate digits to 0-F
Pack into a 4-byte word
Load to FPR0
Clear GR1 for decimal exponent
Assume positive result
Check sign of input value
Skip setting - sign, + is correct
Result is negative.
Set original sign to 0
Force argument sign + in register
Fraction is zero, finish up easily

Assembler Language Programming for IBM z System Servers

Version 1.00

CLI
DWord,X 7 F
Check possible Infinity or NaN
JL
Finite
Skip if value is finite
TM
DWord+1,X 8 0
Check next bit
JO
Special
If 1, it s a special value
Finite
CEB
F0,=EB 1
See if argument has +/- exponent
JE
FractOne
All done if exactly 1.0
JH
PosExp
Branch if positive exponent
NegExp
MEEB F0,=EB 1 . E8
Negative exponent; increase by 8
AHI
1,-8
And count decimal exponent down
CEB
F0,=EB 1
Where did that take us?
JL
NegExp
If it s still too small, go again
JE
FractOne
If exactly equal, that s nice.
PosExp
CEB
F0,=EB 1 . E8
Positive exponent; check size
JL
Reduce
If in range, reduce slowly
MEEB F0,=EB 1 . E-8
Multiply gives more accuracy.
AHI
1,8
Bump decimal exponent accordingly
J
PosExp
And do another reduction cycle
Reduce
CEB
F0,=EB 1
Exponent in (+10,0); check for 10**0
JE
FractOne
Fraction now is 1
JL
Convert
Ready to convert if now a fraction
MEEB F0,=EB . 1
Reduce by 10**1
AHI
1,1
Increment exponent accordingly
J
Reduce
And go around again
Convert MEEB F0,=EB 1 . E5
Convert to integer in (1,10**5)
AEB
F0,=EB . 5
Round it properly
CEB
F0,=EB 1 . E5
Did it round up to 100000?
JNL
FractOne
It did, use fraction .10000
CFEBR 0,5,F0
Convert to binary integer in GR0
CVD
0,DWord
Convert to packed decimal
OI
DWord+7,X 0 F
Set correct zone
UNPK EDigits,DWord
Place digits into string
DoExpon DS
0H
Convert exponent
MVI
ExpSign,C +
Assume positive exponent
LTR
1,1
Check for correct assumption
JNM
DoExpon2
Skip if it was right
MVI
ExpSign,C -
Set exponent sign DoExpon2 CVD
1,DWord
Convert to decimal
OI
DWord+7,X 0 F
Set correct (positive) zone
UNPK Exponent,DWord
Unpack to zoned decimal
MVI
DecPt,C .
Place the decimal point
MVI
ExponE,C E
And the exponent indicator
PrintIt PrintLin PLine,Exponent-PLine+2
Print result
J
Read
Repeat for more values
Zero
MVC
EDigits,=5C 0
Set fraction to zeros
J
DoExpon
And go do exponent
FractOne MVC
EDigits,=C10000 Set fraction digits to .100000
AHI
1,1
Compensate by upping exponent
J
DoExpon
And go do exponent
Special CLC
DWord(2),=X 7 F80 Check for infinity
JNE
ItsaNaN
Skip if not infinity
MVC
DecPt(10),=CL10 ( Infinity) Indicate special value
J
Printit
Print the result
ItsaNaN MVC
DecPt(10),=CL10 ( NaN)
Indicate special value
J
Printit
Print the result
Exit
PrintOut *,Header=NO
Terminate
LtOrg ,
Insert literals
DWord
DC
D 0
Work area
PLine
DC
C X
Start of print line
PHex
DS
CL8
Input value
DC
C =
ESign
DS
C
Sign of fraction
DecPt
DC
C .
Decimal point
EDigits DS
CL5
Fraction digits
ExponE
DC
C E
Exponent indicator E
ExpSign DS
C
Exponent sign

Suggested Solutions to Selected Exercises and Programming Problems

1199

Exponent DS
HexCh
DC
Org
DC
Org
InRec
DS
END

CL2
256AL1(*-HexCh)
HexCh+C A
X FAFBFCFDFEFF
,
CL80
P35_2

Decimal exponent
Define no-effect table
Set origin to offset of A
Translate numeric digit to hex
Reset location counter
Input area for records

Programming Problem 34.3. This solution displays the values in hexadecimal. You will see that many of the
squared square roots match the original integer value.
P35_3

Loop

FPInt
FPRoot
FPDiff

CSect ,
Print NoGen
USING *,15
Provide addressability
LFPC =F 0
Mask off exceptions
LA
0,20
Count number of values
LE
0,=EB 1
Constant 1 in FPR0
LER
2,0
Integer value to be incremented
STE
2,FPInt
Store for display
SQEBR 4,2
Calculate the square root
STE
4,FPRoot
Store for display
LER
6,4
Copy it to FPR6
MEEBR 6,6
Squared square root
SEBR 6,2
Calculate (squared root)-(integer)
STE
6,FPDiff
Store for display
PrintOut FPInt,FPRoot,FPDiff Display the results
AEBR 2,0
Increment the integer value
JCT
0,Loop
Repeat for next value
PrintOut *,Header=NO
Terminate
DS
0F
Align to fullword boundary
DS
XL4
DS
XL4
DS
XL4
END
P35_3

The only reason to mask off the exceptions is that the square roots of non-square integers are necessarily inexact.

Programming Problem 34.3. This is one way to calculate the list of square roots and display the requesed
values in hexadecimal:
P34_3

Loop

FPInt
FPRoot
FPDiff

1200

CSect ,
Print NoGen
Using *,15
Provide addressability
LFPC =F 0
Mask off floating-point exceptions
LA
0,20
Count number of values
LE
0,=EB 1
Constant 1 in FPR0
LER
2,0
Integer value to be incremented
STE
2,FPInt
Store for display
SQEBR 4,2
Calculate the square root
STE
4,FPRoot
Store for display
LER
6,4
Copy it to FPR6
MEEBR 6,6
Squared square root
SEBR 6,2
Calculate (squared root)-(integer)
STE
6,FPDiff
Store for display
PrintOut FPInt,FPRoot,FPDiff Display the results
AEBR 2,0
Increment the integer value
JCT
0,Loop
Repeat for next value
PrintOut *,Header=NO
Terminate
DS
0F
Align to fullword boundary
DS
XL4
DS
XL4
DS
XL4
End
P34_3

Assembler Language Programming for IBM z System Servers

Version 1.00

Programming Problem 34.4. You will find the claim to be true for these values:

Short binary floating-point: 41, 47, 55, 61, 82, 83, 94, 97
Long binary floating-point: 49, 98
Extended binary floating-point: 43, 86, 87, 97

Mathematically inclined readers may find it interesting to explain the discrepancies detected above, and determine why
only the value 99 is shared between representations.

Programming Problem 34.5.


P34_5
BFPLoop

BFPA
BFPX
BFPCon
BFPRnd
BFPDW
BFPAns

Csect ,
Using *,15
LD
0,BFPA
Put argument in FPR0
DDB
0,BFPX
Divide by current estimate
SDB
0,BFPX
Subtract current estimate
DDB
0,=DB 2
Divide by 2
LPDR 2,0
Copy for convergence test
ADB
0,BFPX
Add original estimate
STD
0,BFPX
Store updated estimate
CDB
2,=DB 1 E-10
See if correction is small enough
JH
BFPLoop
If not, iterate again
ADB
0,BFPRnd
Round to 9 siginificant digits
LDR
2,0
Copy answer to FPR2
CFDBR 0,0,0
Convert integer part to fixed
CVD
0,BFPDW
Convert that to packed decimal
OI
BFPDW+7,X 0 F
Set proper zone
UNPK BFPAns(1),BFPDW+7(1)
Unpack the integer part
MVI
BFPAns+1,C .
Place the decimal point
CDFBR 0,0
Convert integer part back to float
SDBR 2,0
Subtract integer part
MDB
2,BFPCon
Convert fraction digits to integer
CFDBR 0,0,2
Convert fraction part to fixed
CVD
0,BFPDW
Convert that to packed decimal
OI
BFPDW+7,X 0 F
Set proper zone
UNPK BFPAns+2(9),BFPDW+3(5) Move fraction part to output
Printout BFPAns,*,Header=NO
DC
DB 2
Argument
DC
DB 1
Initial estimate
DC
DB 1 E9
Conversion constant for fraction
DC
DB 0 . 5 E-9
Constant for rounding
DC
D 0
Work Area
DC
CL12
Output area for result
End
P34_5

The printed result is


BFPAns

= C1.414213563

Suggested Solutions to Selected Exercises and Programming Problems

1201

Section 35 Solutions
Section 35.0
35.0.1. I sometimes explain what I call Cartoon (four-finger) arithmetic by holding my hands against the edge of a
table, with the thumb and first three fingers (or the four fingers) on the surface and the little fingers (or the thumbs)
hidden below the edge. Then, I ask a child to count from one to ten, where ten is the last finger counted: 1, 2, 3, 4,
5, 6, 7, 10. Then, I ask them to add 5 and 5.
35.0.2. Clocks use base 12 or base 24 arithmetic for hours, and base 60 for minutes and seconds; circular measure uses
base 360; weekly calendars use base 7. You will enjoy browsing for others.
Section 35.1
35.1.1. Your representation could look like this:
1
7
24

s char
6 BCDdigit fraction

Because the characteristic is 7 bits wide, it can accommodate characteristic values from 0 to 127. To avoid the range
asymmetry of hexadecimal floating-point data, EMax should be + 64 and EMin should be 63. Then, the characteristic
bias is + 63. (See the footnote on page 668.)
35.1.2. The three quanta are 1 10 7, 1 10 6, and 1 10 3 respectively.
35.1.3. Yes. The quantum in each case is 10 exponent .
35.1.4. The number of significant digits is 5, 6, and 9 respectively.
35.1.5. The pictured representation has precision of 19 digits, and the given value has five nonzero digits between its
leftmost and rightmost nonzero digits, so the cohort has 15 members in each case.
35.1.6. p n + 1.
Section 35.2
35.2.1. The cohort members and their quanta are
1. [ 20743] and [ 37430], with quanta 1 10 2 and 1 10 3 respectively.
2. [ + 10009], [00090], [ 10900], and [ 29000], with quanta 1 10 1, 1 10 0, 1 10 1, and 1 10 2 respectively.
3. [ 33400], [ 20340], and [ 10034], with quanta 1 10 3, 1 10 2, and 1 10 1 respectively.
35.2.2. 2, 5, and 11. (That wasnt too hard, was it!)
35.2.3. Nine. A long-precision number supports 16 digits, so we can have from 0 to 8 high-order (or low-order) zeros.
35.2.4. Assuming all exponents are valid, you cant tell unless you know how many low-order zero digits are in the
significand. For example, if the significand is 10000000, its cohort has 16 members. Similarly, if the significand is
12345678, its cohort has 9 members.
35.2.5. The encoding is X38F .
35.2.6. The BCD digits are 945.
35.2.7. The values are:
1. X827C000000000000 = 0: first 5 CF bits = 00000, TSF=0 bits = 11111 1
2. X 7 EF00049826BA3B0 = + SNaN: first 5 CF bits = 11111, next bit = 1 bits = 11111 0
3. X FB7388215142D357 = QNaN: first 5 CF bits = 11111, next bit = 0
35.2.9. The two values are
Short DFP: X 2 DF306BB
Long DFP: X22200000003306BB

1202

Assembler Language Programming for IBM z System Servers

Version 1.00

35.2.10. Examine Table 313 on page 672: for decimal digits 0-7, the bit patterns in the rightmost encoded hexadecimal
digit are the same as those of the source digit. Decimal digits 8 and 9 may sometimes be encoded to X E and X F
respectively.
Section 35.3
35.3.1. Seven possible interpretations, and their Assembler Language defining statements, are:
DC
DC
STH
DC
DC
DC
DC

F1077952604
C *
4,X05C ( 0 , 4 )
P+4040405
E.250982046
EB3.0039282
ED1.0850E+35

Word binary integers


Characters (three blanks and an asterisk)
Store Halfword
Packed decimal
Hexadecimal floating-point
Binary floating-point
Decimal floating-point

The decimal floating-point value is a member of a cohort: members with the same value can have different representations:
DC
DC
DC

ED10850E31
ED1085E32
ED1.085E35

Representation X4040405C
Representation X4050044B
Representation X4050044B

The last two of these show that the presence of the low-order zero digit in the nominal value changes the generated
constant.
35.3.2. The three constants are
Short
Long
Extend

DC
DC
DC

ED.9999998E97
Generates X77F3FCFE
DD.999999999999998E385
LD.9999999999999999999999999999999998E6145

Its instructive to assemble these three constants together with the following three (specify the PRINT DATA statement!). Youll see that the results for the first three constants are identical to the Max values except that the low-order
bit is one less.
DC
DC
DC

ED ( Max)
DD ( Max)
LD ( Max)

Generates X77F3FCFF

35.3.3. The three constants are


Short
Long
Extend

DC
DC
DC

ED.9999999E97
DD.9999999999999999E385
LD.99999999999999999999999999999999999E6145

If you dont like writing it as a fraction, you could also write (for example)
Long

DC

DD9999999999999999E369

35.3.4. The sketches of the hexadecimal and binary floating-point representations in Figure 431 on page 668 imply
that those representations can safely be lengthened or shortened. However, decimal floating-point values depend on
maintaining the precise structure of the Combination Field and of the declets in the Trailing Significand Field. Truncating or padding a constant could produce a bit string unrecognizable as a decimal floating-point value.
35.3.5. Because short decimal floating-point exponents range from 95 to + 95, the cohort of + 0 has 192 members, not
191: remember that + 0 and 0 are different members of the cohort.
35.3.7. NMin = 1.E-95, and DMin = .000001E-95.
Section 35.4
35.4.1. The tested data classes are:
(a)
(b)
(c)
(d)

infinity, any QNaN, and SNaN (The Effective Address bit pattern is B11101)
Any and all data classes, so it tells you nothing useful!
Any NaN operand with any sign.
A zero operand.

Suggested Solutions to Selected Exercises and Programming Problems

1203

Section 35.5
35.5.1. Yes: if the result has fewer significant digits than the representation provides, the cohort member with smallest
quantum will have a nonzero leftmost digit.
35.5.2. A program interruption with IC=1 (operation exception) will occur.
Section 35.6
35.6.1. Both instruction sequences do the same, and both sequences require four bytes. Depending on the z System
model, the single instruction could be slightly faster than the two LDRs.
Section 35.7
35.7.1. The results are
(a)
(b)
(c)
(d)

X0000000000000000
X7800000000000000
X7800000000000000
X F800000000000000

=
=
=
=

+0
+infinity
+infinity
-infinity

Section 35.8
35.8.1. The CC settings are shown in this table:
Operand 1
Finite
Infinity
NaN

Finite
1 or 2
3
3

Operand 2
Infinity
3
0
3

NaN
3
3
0

Section 35.9
35.9.1. To avoid an invalid operation exception, the rounding masks must round the decimal floating-point value
toward zero.

For Mp, the mask values are 9, 11, 13, and 15 (and 0 if the Decimal Rounding Mask in the FPCR has values 1, 3,
5, or 7).
For Mn, the mask values are 8, 9, 10, 13, and 15 (and 0 if the Decimal Rounding Mask in the FPCR has values 1,
2, 5, or 7).

There is one more mask value for Mn because 263 is even, while + 263 1 is odd, and can round (up) to an even final
digit, making the result larger than the maximum positive integer.
Section 35.10
35.10.1. You could compare the decimal floating-point operand to a constant. Suppose a nonnegative long operand is
in FPR2:
LD
CDTR
JNL

0,=DD 1 E16
2,0
LostDigit

10**16 (16 significant digits)


Compare operand to constant
Branch if a digit will be lost

and similarly for extended precision, where the constant would be =DD 1 E32 .
Alternatively, you could use the Extract Significance instructions to determine the actual number of significant digits.
35.10.2. Because the result is unsigned, there is no need to choose a sign code.
35.10.3. Because the source operand in (GG8,GG9) has at most 31 packed decimal digits, but the extended decimal
floating-point operand supports 34 digits, the LMD must necessarily be zero.
35.10.5. Let ZD represent the numeric value of the zoned decimal digits of the result.

1204

Assembler Language Programming for IBM z System Servers

Version 1.00

S
0

Z
0

1
1
1

0
0

1
1

1
1

Resulting behavior
All zones are X F

0
1
0

0
0
1

All zones are X 3

Zones are F 3 or X F , and if |Z D |=0, sign code is C

0
1

0
0

Zones are F 3 and sign code is C


Zones are F 3 and sign code is F

All zones are X F , sign code is F or D


All zones are X F , sign code is C or D
Zones are F 3 or X F , and if |Z D |=0, sign code is F

Section 35.11
35.11.2. The value of 24 7 is 3.428571, where the underlined group of digits is repeated indefinitely.
35.11.3. Use these two instructions to load the complement of the extended operand in (FPR0,FPR2) to (FPR4,FPR6):
LCDR
LDR

4,0
6,2

Complement high-order half


Copy low-order half

35.11.4. If the operand is a SNaN, Load and Test will cause an invalid operation exception, but Test Data Class will
not.
Section 35.12
35.12.1. The results are:
(a)
(b)
(c)
(d)
(e)

SLDT
SLDT
SRDT
SLDT
SRDT

2,2,0
2,2,3
2,2,6
2,2,10
2,2,8

Significance
Significance
Significance
Significance
Significance

=
=
=
=
=

8
11
2
16
0

35.12.2. Remember that the significand of a DFP number is encoded in declets. Thus, the low-order 24 bits of the DFP
number are X2500000, representing a declet X 0 2 5 followed by two X 0 0 0 declets. Referring to Figure 464 on
page 721, their values are 025, 000, and 000, so there are 8 significant digits.
35.12.3. An advantage of using shifts might include simplicity. Some disadvantages include (a) lack of rounding choices
on right shifts and (b) lack of overflow detection on left shifts.
35.12.4. Consider
LD
0,=DD12789
LD
2,=DD12789E+07
QADTR 4,0,2,8

Source operand = X2238000000004BCF


Second operand = X2254000000004BCF
c(FPR4) = X2254000000000000

The result has zero significand and nonzero exponent.


35.12.5. The Assembler limits the length of P-type constants to 16 bytes.
Section 35.14
35.14.1. Consider the value X77FFFFFF Following the zero sign bit, the first two ab bits are 11, so the biased exponent is formed from all but the last CF bit (cdefghij), giving B10111111 = X BF = 1 9 1 . Subtracting the exponent bias
(101) means that the exponent is 90. The significands high-order bits are B1001 (8 + k) so the significand is
X 9 FFFFF =10485760. But the largest valid significand is 10 7 1 = X96967F =9999999, so the significand is too large.
The value is non-canonical, and will be treated as zero.
35.14.2. Using the values calculated in Exercise 35.14.1, we can easily construct the Max value: X7796967F .
35.14.3. X00000001. The biased exponent is zero, so the true exponent is 101, and the significand is 1. Thus its
value is 1 10 101 .
35.14.4. Starting with X 5 FFFFFFF , the ab bits are 10, so the biased exponent is formed from bits abcdefgh, giving
B10111111, or X BF =191 for the biased exponent. Subtracting the bias (101) means the exponent is 90. The first 3
bits (ijk) of the significand are 111, so the significand is X 7 FFFFF = 223 1=8388607, which is less than 9999999, so
this is a valid representation of 8388607 10 90 .

Suggested Solutions to Selected Exercises and Programming Problems

1205

Section 35.15
35.15.1. The M 4 mask is used in four different ways:
M4
1

Use and Meaning


Used by CSDTR, CSXTR to select the sign code of the packed decimal result.
For FIDTR and FIXTR; and for FIEBRA, FIDBRA, and FIXBRA; and for CEFBRA, CDFBRA, CXFBRA,
CEGBRA, CDGBRA, and CXGBRA; and for CFEBRA, CFDBRA, CFXBRA, CGEBRA, CGDBRA, and
CGXBRA; and for CELFBR, CDLFBR, CXLFBR, CELGBR, CDGBRA, and CXLGBR; and for CDLGTR,
CXLGTR, CDLFTR, and CXLFTR; and for CGDTRA, CGXTRA, CFDTR, and CXFTR; suppresses the inexact
exception.
For LDETR and LXDTR, to indicate an invalid operation exception; for LEDTR and LDXTR, to truncate the
payload.
Used by Add (ADTRA, AXTRA), Divide (DDTRA, DXTRA), Divide to Integer (DIEBR, DIDBR), Multiply
(MDTRA, MXTRA), Quantize (QADTR, QAXTR), Reround (RRDTR, RRXTR), and Subtract SDTRA,
SXTRA), instructions as a 4-bit rounding mask.

8
any

Programming Problem 35.2. The values of N that fail for both long and extended precision decimal floatingpoint arithmetic are 3, 9, 22, 28, 33, 34, 45, 48, 49, 55, 63, 65, 66, 74, 75, 84, 88, 90, 95, and 99.
The values of N that fail only for long precision decimal floating-point arithmetic are 31, 41, 43, 51, 59, 71, 73, 82, 85,
92, 93, and 98.
The values of N that fail only for extended precision decimal floating-point arithmetic are 47, 67, 83, 86, and 89.
The failing values share the property that they are divisible by a prime number other than 2 or 5.

Programming Problem 35.3. This solution uses a specialized interface between DPD2BCD and its caller: the
input and returned values are in the left and right halves of a word argument.
*
*
*
*
*
*

Title DPD2BCD: Convert a 10-bit declet to 3 BCD digits


Entry via R15, return via R14; R1=A(A(fullword)), where the
first 2 bytes of the fullword are the (right-justified)
declet, and the last 2 bytes are the 3 converted BCD digits,
also right-justified.
Declet format:
PQ RSTU VWXY
BCD digits:
ABCD EFGH IJKM

DPD2BCD
DPD2BCD
DPD2BCD

CSect
RMode
AMode
Using
STM
L
Using
LH
LR
XR
SRDL
SRL
SRDL
SRL
SRDL
SRL
LH

,
Any
31
*,15
14,4,12(13)
3,0(0,1)
Fullword,3
0,Declet
4,0
1,1
0,1
0,3
0,1
0,2
0,1
1,28
2,DHMBCD(1)

SLL

0,9

TML
JZ

4,VBit
Case_A

LA
TML

1,B1100000
4,WBit+XBit

*
*

1206

Save some regs


A(fullword)
Get the declet
Carry declet in R4
Clear R1
Isolate Y bit (=M)
Drop VWX bits
Isolate U bit (=H)
Drop ST bits
Isolate R bit (=D)
Now have 2*DHM bits
Carry BCD digits in R2
RUY=DHM bits now completed
PQ bits positioned 0PQ0 0000 0000
0PQ(R) bits for BCD1: ABC(D)
V = 0? (VWXST bits 0----)
Jump if yes
Know V=1
Prepare for cases B and D
WX=00? (100--)

Assembler Language Programming for IBM z System Servers

Version 1.00

JZ

Case_B

TML
JZ

4,WBit
Case_C

TML
JZ

4,XBit
Case_D

TML
JZ
JO

4,SBit+Tbit
Case_E
Case_H

TML
JZ
DC
OR
STH
OI
J
DC
OR
LA
NR
OR
STH
J
DC
OR
NR
OR
STH
OI
J
DC
OR

4,SBit
Case_F
0H
2,0
2,BCD
BCD+1,X80+X 0 8
Finis
0H
2,0
1,B1100110
4,1
2,4
2,BCD
Finis
0H
2,0
4,1
2,4
2,BCD
BCD+1,X 0 8
Finis
0H
2,0

SRL
LA
NR
OR
STH
OI
J
DC
SRL
OR
NR
OR
STH
OI
J
DC
SRL
OR
STH
OI
OI
J
DC

4,4
1,B 1 1 0
4,1
2,4
2,BCD
BCD+1,X 8 0
Finis
0H
0,8
2,0
4,1
2,4
2,BCD
BCD,X 0 8
Finis
0H
0,8
2,0
2,BCD
BCD+1,X 8 0
BCD,X 0 8
Finis
0H

SRL
OR
STH
J
DC
STH

0,4
2,0
2,BCD
Case_H_1
0H
2,BCD

Case_G

Case_A

Case_B

Case_C
*

Case_D

Case_E

Case_F
*

Case_H

Jump if yes
Know V=1,XW not 00
W=0? (10---)
Jump if yes
Know V=1, W=0
X=0? (110--)
Jump if yes
Know V=1, X=1, W=1
ST=00 or 11?
Jump if ST=00 (11100)
Jump if ST=11 (11111)
Know VXW=111, and ST mixed
S=0?
Know XVW=11, S=0, T=1
Do 0PQ(R), 100(U), 100(Y)
Complete the 0PQ(R) bits
Do 100U = 100H, 100Y = 100M
Return
Do 0PQ(R), 0ST(U), 0WX(Y)
Complete the 0PQ(R) bits
Extract ST and WX bits
Isolate ST and WX bits
Insert the ST and WX digits
Return
Do 0PQ(R), 0ST(U), 100(Y)
Complete the 0PQ(R) bits
Extract ST bits
Insert
Do 100Y = 100M
Return
Do 0PQ(R), 100(U), 0ST(Y)
Complete the 0PQ(R) bits
Do 0ST(Y) inline
Position for 3rd digit
Extraction bits for ST
Insert the ST digits
Do 100U = 100H
Return
Do 100(R), 0ST(U), 0PQ(Y)
Reposition PQ bits
Done with 0PQ(Y)
Extract ST bits
Insert
Do 100R = 100D
Return
Do 100(R), 100(U), 0PQ(Y)
Reposition PQ bits
Insert the bits
Do 100U = 100H
Do 100R = 100D
Return
Do 100(R), 0PQ(U), 100(Y)
Do 0PQ(U) inline
Position PQ bits for 2nd digit
Insert the PQ digits
Complete the rest
Do 100(R), 100(U), 100(Y)
Store DHM bits
Suggested Solutions to Selected Exercises and Programming Problems

1207

OI
Case_H_1 DC
OI
OI
J
Finis
DC
LM
BR
Drop
DHMBCD
DC

BCD+1,X 8 0
Do 100U = 100H
0H
BCD,X 0 8
Do 100R = 100D
BCD+1,X 0 8
Do 100Y = 100M
Finis
Return
0H
14,4,12(13)
14
15
XL2000,001,010,011,100,101,110,111

Fullword DSect ,
Declet
DS
0H
DS
X
DS
X
SBit
Equ
X 4 0
TBit
Equ
X 2 0
VBit
Equ
X 0 8
WBit
Equ
X 0 4
XBit
Equ
X 0 2
BCD
DS
H
End

0000 00PQ
RSTU VWXY

Digits: 0, BCD1, BCD2, BCD3

A sample program to print the table of all possible declet values and their converted results:
Prob35_3 CSect ,
Prob35_3 RMode 24
Prob35_3 AMode 24
Using *,15
STM
14,12,12(13)
LA
12,Savearea
ST
13,4(,12)
ST
12,8(,13)
LR
13,12
LR
12,15
Drop 15
Using D2B,12
NTry
Equ
1023
LHI
10,NTry
LHI
9,8
LA
8,Line
MVC
Line,Line-1
Loop
DC
0H
LHI
3,NTry
SR
3,10
STH
3,Input
LA
1,ArgAddr
L
15,SubAddr
BASR 14,15
*
CVD
3,DW
Using Out,8
UNPK N,DW+5(3)
OI
N+L N-1,X F0
CLI
N,C 0
JNE
DoD
MVI
N,C
CLI
N+1,C 0
JNE
DoD
MVI
N+1,C
CLI
N+2,C 0
JNE
DoD
MVI
N+2,C
DoD
UNPK DU,Input(3)
TR
D,HEX-C 0
MVI
D+L D,C

1208

Only needed to use Printlin and...


Printout macros.
Save registers
Point to save area
Chain caller s area to ours
Chain ours to caller s
R13 now points to ours
Set new base address

Do declet values from 0 to 1023


Set loop counter
Number of values per line
Point to the print line
Propagate blanks
Load maximum number to convert
Subtract current loop count
Store declet value in argument
Point to it
Get address of DPD2BCD
Call the subroutine
Convert declet value to packed
Map output group onto print line
Unpack the decimal value
Set correct zone on last digit
Blank leading zeros
Jump if none
Blank leading zero
Check next digit
Jump if not zero
Blank it
Check next digit
Jump if not zero
Blank it otherwise
Unpack the declet s three digits
Translate to hex
Blank the trailing swap byte

Assembler Language Programming for IBM z System Servers

Version 1.00

UNPK BU,Output(3)
TR
B,HEX-C 0
MVI
B+L B,C
LA
8,OutL(,8)
JCT
9,Next
Printlin Line
MVC
Line,Line-1
LHI
9,8
LA
8,Line

Unpack the declet s decimal value


Translate to hex
Blank the trailing swap byte
Step to next output-line field
Loop back for more if line not full
Output the print line
Clear the print line
Reset the number of values per line
Point to start of print line

*
Next

AHI
10,-1
Count number of conversions
JNM
Loop
If not negative yet, repeat
CHI
9,8
Did the last line yet?
JE
Done
If yes, we re done.
Printlin Line
Otherwise, output the last line
Done
Printout *,Header=NO
Terminate
SubAddr DC
V(DPD2BCD)
ArgAddr DC
A(Input)
Address of the argument to DPD2BCD
Input
DS
H
Input value in left halfword
Output
DS
XL2
Output value in right halfword
Savearea DS
18F
DW
DS
D
Work area for CVD
DC
C
Line
DC
CL121
HEX
DC
C0123456789ABCDEF
Out
DSect ,
Mapping of an output group
DS
C
N
DS
CL4,C
DU
DS
0CL4
D
DS
CL3,C
BU
DS
0CL4
B
DS
CL3,C
OutL
Equ
*-Out
End
Prob35_3
The last line of printed output looks like this:
1016 3F8 778

1017 3F9 779

1018 3FA 796

1019 3FB 797

1020 3FC 976

1021 3FD 977

1022 3FE 998

1023 3FF 999

Suggested Solutions to Selected Exercises and Programming Problems

1209

Section 36 Solutions
Section 36.1
36.1.1. When converting short-precision data from hex to binary, some magnitudes may be unrepresentable; when converting from binary to hex, from 1 to 3 bits of precision may be lost, and special values cannot be converted.
36.1.2. When converting long-precision data from hex to binary, 1 to 3 bits of precision may be lost; when converting
from binary to hex, some magnitudes may be unrepresentable, and special values cannot be converted.
36.1.3. When converting extended-precision data from hex to binary there are no problems, but when converting from
binary to hex there may be unrepresentable magnitudes, loss of 1 to 4 bits of precision, and unrepresentable special
values.
Section 36.2
36.2.1. The result is 3.00001 in both cases.
36.2.2. The result is 3.00000 in both cases.
Section 36.4
36.4.1. A usable hexadecimal floating-point value requires at least one hex digit in the fraction. Consider two other
constants:
E1
E15

DC
DC

EL.9 1
EL.9 1 5

The nominal value of each is one hexadecimal digit; but the only significant bit (B0001) in the fraction of the constant
named E1 is lost, so the assembler will flag this statement. Similarly, the constant named E15 is rounded up to appear
to have nominal value 16, which then has the same fraction digit as the first constant.
36.4.2. The binary constant interpreted as a hexadecimal constant would appear to have value + 1.953125E 4, and the
decimal constant would appear to have value + 1.880791E 37! This shows why you must be careful not to mix
floating-point data types.
36.4.3. The BFP value is + 2.4, and the DFP value is + 4613008E + 20.
36.4.4. The HFP value is + 2.2350989E 37, and the BFP value is + 2.818926E 18. (Neither seems very close to 1.)
36.4.5. The values of the four constants are:
Bit Pattern
(a) X 3 F800000
(b) X41100000
(c) X42640000
(d) X 7 FFFFFFF

HFP Value
0.03125
1.0
100.0
MaxReal

BFP Value
1.0
9.0
57.0
QNaN

DFP Value
7.000000E25
0
2.000000E70
SNaN

Be very careful when mixing data types; remember that most bit patterns are valid in FP instructions.
Section 36.5
36.5.1. All the constants are represented by X40100001.
36.5.2. The result is 0.625000596...E 1.
Section 36.6
36.6.1. Any finite unnormalized value A such as X00010000 with characteristic zero will fail. If exponent underflow
is masked off the result is X00000000, and if exponent underflow occurs the result is X 7 F100000 . Neither result
equals the original value of A.
36.6.2. If A is a QNaN or SNaN, the result will be Not any Number. (You might want to claim that the result is the
value you started with; but remember that the law stated in Table 389 applies only to numbers!)
36.6.3. Several unnormalized values of A show this behavior:

1210

Assembler Language Programming for IBM z System Servers

Version 1.00

A
X4100000F
X4100000C
X4100000A

A (1/A)
X40FFFFFF
X40FFFFFC
X40FFFFFA

ulp difference
16
16
16

36.6.4. HexMax = 16 + 63 ulp, and HexMin = 16 65 , so their product is approximately 16 2, or 1/64.


Section 36.7
36.7.1. There are 127 nonzero characteristic values and two sign values, so you can create 254 pseudo-zeros in each
representation.
36.7.2. Because the characteristics differ by 1, the first operand fraction will be shifted right by one digit position. That
digit will be shifted left from the guard digit position, so the result will be the same as the first operand.
Section 36.8
36.8.1. The formats would look like this:
1  23  8

s 2 s complement fraction expon.

Pr1me 550

1  11  48

s exponent unsigned integer

CDC 6600

1  15  48

s exponent unsigned fraction


Cray2

36.8.2. Consider adding a tiny unnormalized value to zero:


LZER
AE

0
0,=X00000003

Set FPR0 to zero


Add a tiny unnormalized value

If program interruptions are enabled the result is an exponent underflow, and the result in FPR0 is X 7 B300000 (not
exactly equal to X00000003!). If disabled, the result is zero.
36.8.3. Consider z=X44200000 and y=X47000200. These two values compare equal, so z = y. Now, if If
t = X42000010, we find that z t = X441FFFFF and y t = X47000200, so z t/y
= t.
36.8.4. The Burroughs 6700 used a 48-bit word; * its short floating-point representation had one unused high-order bit
followed by the significand sign bit S and the exponent sign bit s:
1 1 1  6  39

Ss expon.
unsigned integer
Burroughs 6700

36.8.5. The values are shown in this table:


Hex
X81818181
X A3A3A3A3
X F5F5F5F5
X FEFEFEFE

Char
C aaaa
C tttt
C5555
C

Integer
-2122219135
-1549556829
-168430091
-16843010

BFP
-4.7572945E-38
-1.774180E-17
-6.235846E+32
-1.694740E+38

HFP
-6.9902216E-77
-7.694278E-36
-6.323899E+63
-4.505390E+74

DFP
-6.0301E-73
-1.68723E+26
-9.873375E+64
-SNan

Words were actually 52 bits long: the four high-order bits were a parity bit and three reserved tag bits. Application programmers
saw only the 48 bits.
Suggested Solutions to Selected Exercises and Programming Problems

1211

Programming Problem 36.3.


Long BFP values have greater exponent range than long HFP values, and also support special values; these cases must
be detected. Because long BFP operands are 53 bits long while HFP operands are 56 bits long, no rounding is required.

1212

Assembler Language Programming for IBM z System Servers

Version 1.00

Section 37 Solutions
Section 37.1
37.1.1.
ShftRt

SRL
L
LTR
BNPR
SRL
BR

0,2
1,NN
1,1
14
0,0(1)
14

Preliminary shift by 2
Shift amount in GR1
Check sign of n
Return immediately if not +
Perform remaining shifts
And return

L
L
SRL
LTR
BNP
SRL
ST
BR

0,Logic
1,NN
0,2
1,1
Store
0,0(1)
0,Result
14

Get shift-able argument


And shift amount
Do fixed part of shift
Test variable part
Skip shift if not +
Shift by variable amount
Store the answer
And return to caller

37.1.2.

Store

37.1.3. You will remember from Section 24.11 that when a Branch and Save instruction is decoded, the IA still contains the address of the instruction following the EX. Thus, the IA from the PSW placed in R 1 will contain that
address, not the address of the instruction following the Branch and Save. The next instruction fetched will be at the
branch address, unless the executed instruction was BASR r,0.
37.1.4. You probably found the error immediately: BASR 2,0 doesnt branch, but BASR 2,2 branches to whatever
address was in GR2 before the instruction was executed. The error is caused by not understanding the selection of the
branch address before the Instruction Address is placed into GR2.
37.1.5. This is a cute way to execute blocks of code exactly twice, without looping. The first BASR 3,0 sets GR3 to
the address of the following instruction, and then the first block of code is executed. When the BASR 3,3 is executed,
control returns to the start of the first block of code, but GR3 now contains the address of the first instruction of the
second block of code. When control again reaches the first BASR 3,3, the branch address in GR3 is the address of
the next instruction, so the BASR 3,3 now acts like it was a BASR 3,0. The second block of code is executed
twice, in the same way.
37.1.6. If the Location Counter was on an odd halfword boundary when the BAS instruction is assembled, two empty
bytes will be skipped by the Assembler so that the address constants will be properly aligned on a word boundary. A
branch to 8(,14) will then arrive in the middle of the second address constant.
37.1.7. This exercise illustrates an extreme antisocial tendency on someones part. The calling program can re-establish
its own registers only if (1) it had saved all of them within an addressable distance from the return point, and (2) the
instruction at the return address is a BASR x,0 that establishes a temporary base register that can be used to reload the
registers. For example:
BASR
Using
LAY
Drop
LM

14,0
*,14
14,MySave
14
0,15,0(14)

Local temporary base register


Establish addressability
Hope our save area is addressable!
No local base register now
Restore the registers

Now you see why the callee should save and restore registers!
37.1.8. instructions BASR R 1,R 2 and BAS R 1,0(0,R 2) are identical only if R2 is not zero; the BAS instruction would
then branch to memory location zero. Otherwise, they are identical.
When we consider that BCR R 1,0 and BCTR R 1,0 behave similarly in not branching, we might say that the RR forms
of the three instructions arent needed unless we need an instruction to place the IA in a register, or a two-byte nooperation, or an instruction to reduce a registers contents by one. At the cost of destroying some of the symmetry of
the System/360 instruction set, BASR, BCTR, and BCR could be removed and replaced by a single RR-type instruction in which the R2 digit specified which of the three non-branching activities was intended.
37.1.9. The third instruction will be executed indefinitely. The first BASR instruction puts the address of the second
BASR in GR5, and then the second BASR will branch to its own address. GR4 will contain the address of whatever
follows the second BASR.

Suggested Solutions to Selected Exercises and Programming Problems

1213

37.1.10. Consider these instructions:


ShftRt4A STM
LM
L
L
LTR
JNM
SR
ShftOK
SRL
LM
BR
ShftJG1 DS

1,2,ShftJG1
1,2,0(1)
0,0(0,1)
1,0(0,2)
1,1
ShftOK
1,1
0,2(1)
1,2,ShftJG1
14
2F

Save GR1 through GR2


Get argument addresses
Get first argument in GR0
Get second argument in GR1
Test sign of shift amount
Branch if non-negative
Set shift amount to zero
Shift by required amount
Restore GR1-GR2
Return to caller
Save area for 2 registers

1,ShftJG2
1,0(0,1)
0,0(0,1)
1,ShftJG2
1,4(0,1)
1,0(0,1)
1,1
ShftOK
1,1
0,2(1)
1,ShftJG2
14
F

Save GR1
Get first argument address
Get first argument in GR0
Restore GR1
Get second argument address
Get second argument in GR1
Test sign of shift amount
Branch if nonnegative
Set shift amount to zero
Shift by required amount
Restore GR1
Return to caller
Save area for 1 register

37.1.11.
ShftRt4B ST
L
L
L
L
L
LTR
JNM
SR
ShftOK
SRL
L
BR
ShftJG2 DS

This solution is probably less efficient than that in Exercise 37.1.10 because (a) it has more instructions, and (b) it must
load GR1 from the save area twice.
Section 37.3
37.3.1.
ShftRt

STM
LM
L
L
LTR
JNM
SR
ShftOK
SRL
ST
LM
BR
SaveRegs DS

1,3,SaveRegs
1,3,0(1)
1,0(,1)
2,0(,2)
2,2
ShftOK
2,2
1,2(2)
1,0(,3)
1,3,SaveRegs
14
3F

Save working registers


Get all argument addresses
Get word to be shifted
Get shift count N
Check sign of shift count
Skip next instruction if nonnegative
Set count to zero if negative
Shift 2+max(N,0) places
Store result at specified place
Restore caller s registers
And return
Save area for registers GR1-GR3

37.3.2. If more than one element has the same maximum value, which will appear in GR0 on return?
AMax

Comp

Skip
Exit
Saver

STM
LM
L
L
CHI
JNH
C
JNL
L
LA
JCT
LM
BR
DS

1,2,Saver
1,2,0(1)
0,0(,1)
2,0(,2)
2,1
Exit
0,0(,1)
Skip
0,0(,1)
1,4(,1)
2,Comp
1,2,Saver
14
2F

Save GR1, GR2


Get array and length addresses
Load 1st element of array
Load length of array
See if array is short (1 element)
Return if 1 (or fewer) items
Compare current max to an element
Skip if max is still a max
Else element is the new max
Step to next element of array
And try again
Restore registers
And return
Save area for GR1, GR2

37.3.4. This solution counts the bits using logical addition.

1214

Assembler Language Programming for IBM z System Servers

Version 1.00

NBits

CSect
Using
STM
LM
XR
L
LTR
JNP
LR
Loop
ICM
Test
ALR
JZ
JM
LA
JO
Next
LA
JCT
Store
ST
LM
BR
LocalSav DS
End

,
*,15
0,4,LocalSav
1,3,0(1)
4,4
2,0(,2)
2,2
Store
0,4
0,B1000,0(1)
0,0
Next
Test
4,1(,4)
Test
1,1(,1)
2,Loop
4,0(,3)
0,4,LocalSav
14
5F

Count 1-bits in a byte string


Local base register
Save GR0-GR4 locally
Get argument addresses
Initialize bit count
Get string length
Check length
If not positive, return zero
Clear GR0 for byte insertion
Get a byte from the string
Add GR0 to itself, check for carry
If c(GR0)=0, no 1-bits in the byte
CC=1 means no carry, bit was zero
Increment the count
Repeat for next 1-bit
Step to next byte
Count down, get another byte if any
Store bit count
Restore registers
Return to caller
Save area for GR0-GR4

37.3.5. Suppose you wrote


ORG

*,8,-2

If the LC is already aligned on a doubleword boundary, it would remain at the same location; the offset operand -2
would then subtract 2 from the LC, meaning that the Y-con might overlay the last 2 bytes of whatever preceded the
doubleword boundary.
Section 37.4
37.4.1. The low-order bit of the character A is 1; but the back chain address of a standard save area points to a word
address, so its two low-order bits would be zeros.
37.4.2. If the caller had entered your routine in 64-bit addressing mode, he would have provided a Format-4 save area.
Because your routine was called in 24- or 31-bit addressing mode, the return address doesnt depend on the high half
of GG14.
Section 37.5
37.5.1. In the early days, only BALR and BAL were available; BASR and BAS were introduced later. The BALR
and BAL instructions put the right half of the PSW into the R 1 register. In 24-bit addressing mode, the leftmost byte of
the register always contains the Instruction Length Code (2 bits), the Condition Code (2 bits) and the Program Mask
(and may therefore be slower than BASR and BAS). The rightmost 6 bits of that byte could be all 1-bits, but because
BALR and BAL are respectively 2-byte and 4-byte instructions, the ILC will never be B 1 1 .
When 31-bit addressing mode was introduced, executing
MVI

12(13),X FF

would have destroyed the high-order 7 bits of the return address in the save area (after GR14 had been loaded from
the save area!), making it difficult to know where the call came from. This was solved by setting the low-order bit of the
return address to 1.
Be careful, though: you should set a return flag only if the calling and called routines both execute in 24- or 31-bit
addressing mode.
37.5.2. It does conform to standard linkage conventions: GR13 contains the address of a save area; GR14 contains the
return address; GR15 contains the entry point address of the subroutine; and GR1 contains the address of the argument list. Also, the calling-point identifier is at the return address.
This isnt standard coding practice, though.
37.5.3. The instructions could be revised like this:

Suggested Solutions to Selected Exercises and Programming Problems

1215

BASR
LTR
JM
CHI
JH
TMLL
JZ
AHI
NILF
J
Set12
LA
Proceed LARL
AR
BR
JList
J
J
J
J
- - -

14,15
15,15
Set12
15,12
Set12
15,X 3
Proceed
15,X 3
15,X FFFFFFFC
Proceed
15,12
14,JList
14,15
14
Ret000
Ret004
Ret008
Ret012

Link to subroutine as usual


Test sign of return code
If negative, set to 12
Compare to 12
If greater, set to 12
Test two low-order bits of retcode
If 0, multiple of 4; OK to proceed
Force carry to round to next value
Set 2 low-order bits of GR15 to zero
OK to branch to return code handler
Return code forced to 12
Address of branch list
Add return code to list address
One-hop branch to correct routine
Return code = 0
Return code = 4
Return code = 8
Return code = 12
etc...

All these instructions need no base register.


37.5.7. Assuming the identifier isnt a negative number, and you write the statement in the form
DC

X4700nnnn

Max value is X 7 FFF

then its maximum value is 2 15 1 = 32767. But if you write it in the form
NOP

X nnn

Max value is X FFF

then its maximum value is 2 12 1 = 4095.


37.5.8. It works correctly. The MVC instruction puts the return code in the callers save area where GR15 was originally saved.
37.5.9. Consider these instructions: they use a based branch B, but make no reference to a base-displacement
addressing halfword that was assigned by the Assembler.

JList

BASR
LARL
B
J
J
J
J

14,15
14,JList
0(14,15)
Ret000
Ret004
Ret008
Ret012

Link to subroutine as usual


Address of branch list
Retcode added to list address
Return code = 0
Return code = 4
Return code = 8
Return code = 12

LA
NR
JNZ

0,3
0,15
BadRC

Put B 1 1 in GR0
And with 2 low-order bits of RC
If nonzero, RC not a multiple of 4

37.5.10.

37.5.11. The claim is true. Suppose the value in GR15 has nonzero bits a and b in the rightmost two bit positions.
Then the ORed expression in the internal register (when the target instruction is built by the CPU) will be
CLI

*+1,B111111ab

where *+1 is the address of the unmodified instruction. Any nonzero value of bits a or b will cause an inequality.
While an ingenious use of CLI and EX, this technique should not be used because it makes a data reference to the
instruction stream. Its better to use
TML
JNZ

15,B 1 1
Error

Section 37.6
37.6.1. Once the true entry address of the called program is in GR15, we can use it to reference its entry-point ID.
This shows possible modifications to Figure 515 on page 771:

1216

Assembler Language Programming for IBM z System Servers

Version 1.00

Caller

STM
14,2,12(13)
- - L
15,0(,14)
XR
2,2
IC
2,5(,14)
LA
1,6(,14)
- - LM
0,2,20(13)
- - L
14,12(,13)
BR
15

Save GR14-GR2 in caller s area


Load true entry point address
Clear GR2 for EPID length
Get EPID length
Address of EPID string
Process the EPID somehow
Restore GR0-GR2
Construct subroutine entry address
Restore caller s return address
Branch to chosen subroutine

37.6.2. In this case, we must work back up the save area chain to the caller of this callers routine, retrieve its entry
point address, and use that to find this routines entry-point ID. This shows possible modifications to Figure 515 on
page 771:
STM
14,2,12(13)
L
14,4(,13)
L
14,16(,14)
XR
2,2
IC
2,5(,14)
LA
1,6(,14)
- - LM
0,2,20(13)
- - L
14,12(,13)
BR
15

Save GR14-GR2
Back link to our caller s save area
Entry address to this routine
Clear GR2 for EPID length
Get EPID length
Address of EPID string
Process the EPID somehow
Restore GR0-GR2
Construct subroutine entry address
Restore caller s return address
Branch to chosen subroutine

37.6.3. It wont matter, because the c(GR13) are unchanged; but it will waste a few CPU cycles.
37.6.4. You might modify the interface this way:

Caller

AdrTbl

BAS
14,Caller
NOP
ShftRt#
- - AH
15,2(0,14)
L
15,AdrTbl
BR
15
DC
A(ShftRt)
DC
A(Print)
- - -

Link to caller routine


Pass # of subroutine to be called
Add subroutine number to GR15
Address in GR15 was modified!
Enter the called routine
Actual address of ShftRt
Actual address of Print
Etc., for other assisted routines

When control is returned to the instruction addressed by GR14, the NOP will pass control to the following instruction.
You would normally write the linkage routine to provide much more in the way of optional tracing and diagnostic
information. The examples given here simply pass control directly to the (indirectly) called program.
37.6.5. The program using assisted linkage to call the ShftRt subroutine could use instructions like these:
LHI
0,Print#
BAS
14,Caller
- - -

Put subroutine number in GR0


Link to Caller routine
Return here from called routine

The Caller routine could be revised like this:


Caller

AdrTbl

LARL
ALR
L
BR
DC
DC
- - -

15,AdrTbl
15,0
15,0(0,15)
15
A(ShftRt)
A(Print)

Address of zero-th target routine


Add subroutine number to GR15
Load correct entry point address
Enter called routine
Address of ShftRt
Address of Print
...etc...

Section 37.7
37.7.1. Because GR14 and GR15 were not modified, and the the result is returned in GR0, we need to restore only
GR1-GR3:

Suggested Solutions to Selected Exercises and Programming Problems

1217

ShftRt5

Ret

STM
LM
L
L
SRL
LTR
JNP
SRL
LM
BR

14,3,12(13)
2,3,0(1)
0,0(0,2)
1,0(0,3)
0,2
1,1
Ret
0,0(1)
1,3,24(13)
14

Save registers in caller s save area


Get argument addresses in GR2, GR3
Get 1st (logical) argument in GR0
Get 2nd (integer) argument in GR1
Shift 2 places
Test second argument
Return if it s not positive
Otherwise shift N places
Restore modified registers
And return

37.7.2. This solution needs to save and restore only GR1; the initial value passed by the caller in GR0 is sometimes
called the seed of the random number sequence.
RanInt

A
P
SaveR1

CSect
Using
ST
LR
M
D
L
BR
DC
DC
DS
End

,
*,15
1,SaveR1
1,0
0,A
0,P
1,SaveR1
14
F16807
F2147483647
F
,

Establish addressability
Save GR1
Move XOld to GR1
Multiply by A
Divide Xold*16807 by P
Restore GR1
Return with XNew in GR0
Multiplier
Prime P = 2**31-1
Save area for GR1
It s a complete program

This is a simple example of a very large class of multiplicative congruential generators. It has some weaknesses and
shouldnt be used for serious simulations.

Programming Problem 37.1.


The internal subroutine is named Print. This (inefficient) solution first prints the even prime 2, and then tests each successive odd number by dividing it by increasing odd values and rejecting the test value if the remainder is zero. Otherwise,
the test divisor is squared and compared to the test number; if the square is larger, the test number is prime.
P37_1

Outer
Inner

Start
BASR
Using
LA
JAS
LA
LA
LA
LA
LR
MR
CR
JH
LR
SR
DR
LTR
JZ
AR
J
JAS

0
15,0
*,15
1,2
14,Print
11,999
10,2
1,3
2,3
5,2
4,5
5,1
Prime
5,1
4,4
4,2
4,4
NotPrime
2,10
Inner
14,Print

Prime
*
NotPrime JXLE 1,10,Outer
PrintOut *,Header=NO
*
Print
CVD
1,Space
MVC
Line,Pattern
ED
Line,Space+6
PrintLin Line,L Line
BR
14
Line
DC
CL5

1218

Establish a base register


Provide addressability
Starting even prime
Print the only even prime
Last value to test
Increment 2 for next odd number
Starting odd-number test value
Trial divisor starts at 3
Set up multiply
Square divisor
Compare to test number
Branch if the test number is a prime
Copy test number
Clear high order register GR4
Divide
Test remainder
Branch if zero
Increment trial divisor by 2
And try another test value
Print the prime value
Increment by 2, test, and loop
Stop
Convert to packed decimal
Maximum of 3 digits in result
Print the line
Return to caller
Output line

Assembler Language Programming for IBM z System Servers

Version 1.00

Pattern
Space

DC
DS
End

X4040202120
D
P37_1

Formatting pattern bbdsd


CVD result work area

The initial and final output lines look like this:


2
3
5
7
- - 983
991
997

Programming Problem 37.2.


This little subroutine will do the job very simply:
PD2CH
CSect ,
**********************************************************************
* Convert 6-byte packed decimal numbers to numeric characters.
* Calling sequence:
*
CALL PD2CH(packed,character)
* where
*
packed
is a 6-byte packed decimal value
*
character is a 12-byte area to hold the result characters
**********************************************************************
USING *,15
Local base register
STM
14,2,12(13)
Save R14-R2
LM
1,2,0(1)
Get argument addresses
MVC
0(12,2),Pattern
Move pattern to output area
ED
0(12,2),0(1)
Edit the input value
LM
1,2,24(13)
Restore R1,R2
BR
14
Pattern DC
X 4 0 , 9 X 2 0 , X2120 bdddddddddsd for 11 digits
END

Programming Problem 37.4.


This subroutine uses registers 0-4, and restores only registers 2-4.
GCD
CSect ,
***********************************************************************
* GCD, Greatest-Common-Divisor routine: returns the GCD of two 32-bit *
* positive integers in GR0 or in memory. Calling sequence, using
*
* standard linkage conventions:
*
* Call GCD(I,J) returns the result in GR0.
*
* Call GCD(I,J,K) returns the result at K.
*
***********************************************************************
STM
2,4,28(13)
Save working registers
LM
2,4,0(1)
Addresses of I, J, and K
L
0,0(,3)
Argument J in GR0
L
2,0(,2)
Argument I in GR2
GCDA
LR
1,2
Copy I to GR1 as first dividend
LR
2,0
Copy J to GR1 as first divisor
SR
0,0
Clear high-order register
DR
0,2
Divide I by J
CHI
0,1
Is remainder 1?
JH
GCDA
If greater than 1, try again
JE
GCDB
Branch if exactly 1
LR
0,2
If zero, last divisor is the GCD
GCDB
LTR
3,3
Check if J was the last argument
JM
GCDRet
If so, return with GCD in GR0
ST
0,0(,4)
Store GCD at K
GCDRet
LM
2,4,28(13)
Restore registers
Suggested Solutions to Selected Exercises and Programming Problems

1219

BR
End

1220

14
,

Return

Assembler Language Programming for IBM z System Servers

Version 1.00

Section 38 Solutions
Section 38.1
38.1.1. At the point where the Assembler encounters the USING statements, the value of * is 12 larger than the value
of BaseLoc. (Each LAY instruction is 6 bytes long.)
38.1.2. Because no instructions containing implied addresses appear between the BASR and the USINGs.
38.1.3. This might work if all instructions in the range of the USING statement use 20-bit signed displacements, for
which addressability would be available over most of the program. But if statements like
MVC
DS
DC

A
B

A,B
CL5
C Bytes

appeared anywhere in the first 500K bytes of the program, neither operand of the MVC instruction would be addressable.
38.1.4. The Assembler often places literals at the far end of the program, so they might not be addressable. But even if
the literal is addressable with a valid base register, theres still an error: the wrong base address is assumed. (See the
solution to Exercise 38.1.5.)
38.1.5. Now, at least, the literal is correctly addressable. Registers 3, 4, and 5 will therefore contain the addresses
BEGIN+2, BEGIN+4096, and BEGIN+8192. However, the USING promises that they contain BEGIN+2,
B E G I N + 4 0 9 8 , and BEGIN+8194. Thus, parts of the program will work (those using GR3 as a base register), and
other parts mysteriously wont.
38.1.6. This has the same difficulty as in Exercise 38.1.5. The programmer thought hed get rid of the problems in
Exercises 38.1.4 and 38.1.5 by getting rid of the literal.
38.1.7. For the LA 2,Origin statement to work correctly, the location named Origin must be addressable by some
other register. (And if it is, why did we need to use R2 as a base register in the first place?)
38.1.8. There would be no base register available to resolve the implied address Addrs in the LM instruction into
base-displacement form. The Assembler would indicate an addressability error for that statement. Even if Addrs is
addressable, all the values promised in the USING statement would then be incorrect.
38.1.9. The Location Counter may not be on an even boundary before the entry point:
BigProg

SubRtn

Start
Entry
- - DC
DC
Using
ST
- - -

0
SubRtn
F 9 , 3 3
C Trouble
*,15
2,SaveR2

Two aligned constants


Odd-length constant
Value of * is now odd!
An alignment byte precedes this!

The USING base address will be too small by 1.


38.1.10. The second USING specifies base addresses that are too large by 4, the length of the LM instruction.
38.1.11.

The second instruction is BAS, not BASR; it will branch to memory address zero!
The address promised by the USING statement for the contents of GR3 is First+4100 (the BAS is four bytes long)
so that even if the first error is corrected, the wrong address will be placed in GR3. The generated LA instruction is
41B0AFFC.

38.1.12. If the literal pool containing =H4096 lies at the end of the assembly (as is often the case), the literal may not
be addressable. Even if it is addressable, the Assembler will assume GR12 can be used as a base register for the AH
instruction, before GR12 (at execution time) contains the correct value. Judicious use of LTORG and USING will
avoid the difficulty.
38.1.13.

The USING statement makes no reference to GR10;


as written, the USING specifies an incorrect value for R11. Even if the USING statement is corrected to read
USING *,10,11 we have another error, because
Suggested Solutions to Selected Exercises and Programming Problems

1221

The USING statement promises that Prog+4098 will be in GR11, not Prog+4096.

38.1.14 Both LA instructions refer to the START statement; they would be assembled as LA 11,4094(,10) and LA
12,4094(,11) which could generate entertaining (or horrifying) results as the program was executed.
38.1.15. You cant define a relocatable symbol on a USING statement! The name-field symbol would be treated as a
qualifier on a Labeled USING statement. (There are several other errors that you might want to find, but this one is
enough to start with.)
38.1.16. The LA instruction would be assembled as LA 11,0(,11) because the USING statement promises that the
address of *+4096 is already in GR11 when the LA is encountered.
38.1.17. The address placed in GR10 by the BASR is Here+2, not Here. Thus all implied addresses will be incorrect
when the program is executed. Even if the USING statement is corrected to read USING Here+2,10,11 then the LA
instruction cannot be correct.
38.1.18. This is essentially the same as in Exercise 38.1.16, but with * changed to Here. GR10 will still contain an
undefined value.
38.1.19. By the time the Assembler arrives at the second USING, the LC has increased by 8, so we must write
USING *+4088,11 instead.
38.1.20. Theres nothing wrong. Base-displacement addresses with GR11 as base may look peculiar, having many odd
displacements. *
38.1.21. Yes, so long as HW4096 is (1) on a halfword boundary, as assumed, and (2) is less than 4094 bytes distant
from BaseLoc.
38.1.22. If the DC operand was H4000, the USING statement would have to be replaced by the three statements
Using
Using
Using

*,10
*+4000,11
*+8000,12

If the operand was H5000, a similar set of statements would be needed. However, there would be 904-byte portions of
the program that could not be addressed, since the end of the range of GR10s USING statement does not overlap the
start of GR11s, and similarly for GR11 and GR12.
38.1.23. First, AH 11,HW4096 is assembled to X 4 AB0B232 , and AH 12,HW4096 is assembled to
X 4 AC0B232 . Second, GR10 would contain X00020002, and GR11 and GR12 would contain whatever they contained on entry to PROG plus some unknown halfword retrieved from an offset X 2 3 2 beyond whatever address was
in GR11 (which might even have been odd).
When the constant at HW4096 has value X2234, the two AH instructions are assembled as X 4 AB0C232 and
X 4 AC0C232 . When executed, GR12 will be used as a base register to find the mystery halfword to be added to GR11
and GR12. If the symbol HW4096 has value X3234, it is not addressable at all! Thus, if the code in Figure 522 on
page 778 is to work, the value of symbol HW4096 must be X1000 or less. (Why not X FFE or less?)
38.1.24. Replace the two AH

reg,HW4096 instructions with AHI

reg,4096 instructions.

Section 38.2
38.2.1. The address in GR15 is the address of the entry point ShftRt, not the address of the instruction following it.
Remember that BASR sets the first operand register to contain the address of the instruction following the BASR!
38.2.2. Remember that the branch address is formed before the branch instruction is executed. Then, the address of the
instruction following the BASR (the ST 0,Result) is put in the IA portion of the PSW, so the next instruction is fetched
from the branch address. The address of the target instruction (at ShftRt) will initially be in GR14; after executing the
BASR, the next instruction fetched is at ShftRt; GR14 contains the return address of the ST instruction.
38.2.3. Because the value of * will be wrong: it will be the address of the instruction following the BASR, not the address
of the entry point! If the ShftRt subroutine in Figure 526 on page 784 contained any instructions with implied
addresses, they would not be resolved relative to the start of the subroutine!
The technique in Figure 526 applies only to subroutines without implied addresses, or that establish their own (local)
base registers.

To be fair, machine language looks peculiar anyway.

1222

Assembler Language Programming for IBM z System Servers

Version 1.00

38.2.4. LGFI will set all 64 bits of GG5, whereas L leaves the high-order 32 bits unchanged. Also, LGFI will be be
faster.
Section 38.4
38.4.1. Two instances of the literal =F 1 will be generated, both at the end of section AAA, the first control section. The
reference to the literal in section BBB will fail with an addressability error.
38.4.2. Two instances of the literal =F 1 will be generated, each following the LTORG instruction at the end of each
section.
38.4.3. The END statement ends the assembly, so a DROP isnt needed. But its always a good practice to insert the
DROP, because someone else may add more instructions or data to your program.
38.4.4. For this simple little ShftRt subroutine, no implied addresses are used (the JNM instruction is a relative
branch instruction), so no problems will (or should!) occur. But this technique isnt recommended in general.
38.4.5. Suppose someone decides to reorganize the program, and add some more instructions to the ShftRt subroutine
that require based addresses. Its worth retaining the USING statement in case someone later adds instructions to the
routine that will require base-displacement addressing.
38.4.6. The values of the symbols are
A
B
C
D
N

X001240
X001248
X00124C
X00125C
X000005

38.4.7. After the 5 (N) bytes at A are reserved, the LC value is X00004B Because the next statement defines a fullword
area of memory, the LC is rounded up to the next fullword boundary, or X00004C .
38.4.9. The values of the four symbols are:
A
B
C
D

X002000
X002008
X002004
X00200C

38.4.10. Consider the terms in the duplication factor expression:

(*-Prog) is the length of the current section.


((*-Prog)+4095): if the section length is not an exact multiple of 4096, this term will have a value exceeding a
multiple of 4096.
(((*-Prog)+4095)/4096*4096): gives the smallest number of 4096-byte blocks into which the current section will
fit.
-(*-Prog) subtracts the number of bytes already allocated in the section, leaving the number of bytes in the section
needed to extend the section to the next 4096-byte boundary.
The resulting duplication factor generates the desired number of X 0 0 bytes (any other constant value could be
used).

You should do the above arithmetic steps with LC values like Prog+1, Prog+4095, Prog+4096, and Prog+4097.
38.4.11. The constants will be at these locations:

CSect A: X 0 1 at location 0, X 0 6 at location 1.


CSect B: X 0 2 , 0 4 at locations X 8 -9 .
CSect C: X 0 3 , 0 5 , 0 7 at locations X10-12 .

38.4.12. The values of the symbols are:


A
B
C
D
E
F
H

X000003
X000005
X000001
X000004
X000006
X000002
X000000

38.4.13. The values of the symbols are given in the Loc column.

Suggested Solutions to Selected Exercises and Programming Problems

1223

Loc
000000
000000
000001
000001
000008
000008
00000C
00000C
000002
000002
00000D
00000D
000003
000003
00000E
00000E
000009
00000A

Source Statement
SectA
CSect ,
H
DS
X
ALoc
LOCTR ,
B
DS
X
SectB
CSect ,
A
DS
X
BLoc
LOCTR ,
C
DS
X
ALoc
LOCTR ,
D
DS
X
BLoc
LOCTR ,
E
DS
X
SectA
CSect ,
F
DS
X
BLoc
LOCTR ,
G
DS
X
SectB
LOCTR ,
N
DS
H

Initiate CSECT SectA


At location 000000
Start LOCTR group ALoc in SectA
At location 000001 in SectA
Initiate CSECT SectB
At location 000008 in SectB
Start LOCTR group BLoc in SectB
At location 00000C
Switch to LOCTR group ALoc in SectA
At location 000002
Switch to LOCTR group BLoc in SectB
At location 00000D
Resume LOCTR group ALoc in CSECT SectA
At location 000003
Switch to LOCTR group BLoc in SectB
At location 00000E
Resume LOCTR group BLoc in CSECT SectB
At location 00000A

38.4.14. When the Assembler processes your END statement, it inserts two invisible statements:
<first>

CSECT ,
LTORG

where <first> is the name of the first executable control statement.


Section 38.5
38.5.1. The program in Figure 566 on page 811 assembled with the NOTHREAD Assembler option produces this External
Symbol Dictionary listing. The only changes from Figure 567 on page 811 are that each control section after the first
has starting location zero, and the address of the ENTRY symbol ASECENT has been adjusted relative to its owning
sections zero start address.
External Symbol Dictionary
Symbol
MAIN
SOMESYM
ASECTION
ASECENT
RSECTION
COMSECT
ADUMMY

Type
SD
ER
SD
LD
SD
CM
XD

Id

Address

Length

00000001 00002400 000000C0


00000002
00000003 00000000 0000010C
00000089
00000004 00000000 00000095
00000005 00000000 00000320
00000006 00000000 0000002C

Owner Id Flags Alias-of


00
00
00000003
08
00

38.5.2. START, CSECT, and RSECT define executable control sections, and COM and DSECT define reference
control sections. Only DSECT does not declare space in the object program.
38.5.3. As noted in the statement of the exercise, this type of coding is strongly discouraged!
Shifter CSect
ENTRY
Using
ShftRt MVI
B
Using
ShfLft MVI
ShftAA LTR
JNM
SR
ShftOp SLL
BR
End

,
ShftRt,ShfLft
*,15
ShftOp,X 8 8
ShftAA
*,15
ShftOp,X 8 9
1,1
ShftOp
1,1
0,2(1)
14
,

Declare two entry points


Set by caller of ShrtRt
Set SRL opcode
Branch to entry code
Set by caller of ShfLft
Set SLL opcode
Check shift amount
Skip if not minus
Otherwise set to zero
*** Opcode modified to be SLL or SRL
Return

Note that the instructions starting with ShftAA do not need a base address, so it doesnt matter that the Shifter
program can be entered with two different addresses in GR15.

1224

Assembler Language Programming for IBM z System Servers

Version 1.00

38.5.4. First, some specialized instructions require that their operands be quadword aligned. Second, some instruction
sequences will operate more efficiently if their operands are aligned on boundaries that lie within cache lines.
38.5.5. They can be useful for small test programs. Otherwise they mainly exist to let the Assembler generate usable
object code in case someone forgot to start a program with a named control section.
38.5.6. Youll generate two unnamed control sections. What your linker does with them should be interesting,
depending on how and whether blank section names are also distinguished by type.
38.5.7. You can reference the blank control section by adding an ENTRY statement for the first byte, as in
CSect
Entry
BlankCS DS
- - -

,
BlankCS
XL23

Unnamed control section


Entry name

but you cant define an entry point in a common control section.


38.5.8. If we assume that the address of ShfLft is in GR15 on entry at ShfLft, the instruction named ShftRt is not
addressable. However, because there is only a single USING statement, the LA is equivalent to simply LA 15,0(,15).
Thus the program will attempt to execute with a value in GR15 that is 8 too large when called at ShfLft.
To correct the program, change LA 15,ShftRt to AHI 15,ShftRt-ShfLft.
38.5.9. Without the third USING statement, displacements will be calculated by the Assembler relative to the address of
ShfLft as a base, so calls to ShfLft will work correctly.
When ShftRt is called, only the first two instructions will be executed with the correct base register. Control will be
correctly transferred to ShftAA, and the LTR will be executed. Now, if the number in GR1 is not negative, the branch
condition will be met, and the BNM instruction will be executed. However, its addressing halfword is X F00C ; because
GR15 contains the address of ShftRt, the branch address is actually the address of ShftAA! Thus if c(GR1) 0, the
program loops on the two instructions at ShftAA.
If c(R1)<0, the BNM instruction is not executed, and control passes to ShftOK. The bit tested will actually be at
ShFlag-8, which is the first byte of the BR 14 instruction! This byte contains X 0 7 , so the tested bit will be one and
the branch condition for the following BZ will not be met. The operand will be shifted left instead of right!
This exercise shows why you must be careful in establishing correct USING statements in routines with multiple entry
points.
38.5.10.
BYTE

Loop

Next

ZChars

Start
Using
STM
LM
ICM
LA
MVC
LTR
JNM
OI
LA
ALR
JCT
LM
BR
DC
End

0
*,15
14,2,12(13)
1,2,0(1)
1,B1000,0(1)
0,8
0(8,2),ZChars
1,1
Next
0(2),X 0 1
2,1(,2)
1,1
0,Loop
0,2,20(13)
14
8C 0

Conversion subroutine
Caller provides GR15 base register
Save GR14-GR2
Load pointers to the two arguments
Insert the byte argument
Initialize bit counter
Move zero-characters to argument 2
Test sign bit of GR1
Branch if it s zero
Make the output character a 1
Increment output-character address
Shift the byte left by 1 bit
Repeat for all 8 bits
Restore GR0-GR2
Return to caller
Eight zero characters

38.5.11. Consider this subroutine: no implicit addresses are used, so theres no need for the normal Using *,15 statement.

Suggested Solutions to Selected Exercises and Programming Problems

1225

SIGNUM

Start
STM
SR
L
LT
L
BZR
BCTR
BMR
LCR
BR
End

0
14,1,12(13)
0,0
1,0(,1)
1,0(,1)
1,24(,13)
14
0,0
14
0,0
14

Start of SIGN control section


Save registers
Initialize result
Get address of the argument
Get the integer argument, set CC
Restore GR1 without changing CC
Return directly if argument = 0
Make c(GR0) = -1 (no change to CC)
And return
Make c(GR0) = +1
Return to caller

Note that the BCTR instruction cant be changed to AHI 0,-1 because AHI changes the condition code.
38.5.12. Because Data is an external symbol, and is not addressable.
38.5.13. This subroutine assumes that the MemDump subroutine uses a local register save area so that it wont modify the
contents of the callers save area (which may be in an area to be dumped).
MemDump

Start 0
Memory-dump subroutine
Using *,15
Establish addressability
STM
1,5,Save
Save modified registers
LM
1,2,0(14)
Load start and end addresses
MainLoop MVC
Line,CC
Set carriage control character
ST
1,Loc
Store starting address for this line
MVC
Loc+4(16),0(1)
Move 16 bytes for unpacking/formatting
LA
5,Loc
Initialize UNPK source address
LA
3,5
Format 5 words into printable hex
LA
4,Line
Initialize output line position
LineLoop UNPK 0(9,4),0(5,5)
Unpack a word
TR
0(8,4),TRTab
Translate to EBCDIC
MVI
8(4),C
Blank out the swap byte
LA
5,4(,5)
Increment input address by 4
LA
4,9(,4)
Increment output address by 9 (space!)
JCT
3,LineLoop
Finish one line of output
PrintLin CC,1+L Line
Print the line
LA
1,16(,1)
Increment starting address by 16
CR
1,2
Compare to end address
JNH
MainLoop
Repeat for another line
LM
1,5,Save
B
8(,14)
Return to caller
Save
DS
5F
Save area
Loc
DS
5F
Work area for address, dump words
CC
DC
C
Blank carriage control character
Line
DS
CL45
Output line
DS
X
Padding byte for UNPK byte swap
TRTab
DC
240C , C0123456789ABCDEF Translate table
End
38.5.15. This can be done in many ways; first, we illustrate a technique used before z/Architecture instructions were
available.
I2D

Const
Float

CSect
Using
ST
XI
LD
SD
BR
DC
DC

,
*,15
0,Float+4
Float+4,X 8 0
0,Float
0,Const
14
DS62147483648
X 4 E , 7 X 0

Word integer to long hex float


Assume standard entry-address reg
Store integer value
Invert sign bit only
Pick up integer and exponent
Subtract magic constant
Return
Scaled 2**31
Temporary with hex exponent 14

This solution uses z/Architecture instructions:

1226

Assembler Language Programming for IBM z System Servers

Version 1.00

I2D

Const

CSect
Using
LGFR
LDGR
LNDR
SD
BR
DC

,
*,15
0,0
0,0
0,0
0,Const
14
DS62147483648

Word integer to long hex float


Assume standard entry-address reg
Extend 32-bit operand to 64 bits
Copy GG0 to FPR0
Invert sign bit of FPR0
Subtract magic constant
Return
Scaled 2**31

38.5.18. The SUB operand of the BAS instruction cant be resolved at assembly time. However, changing BAS to BRAS
or BRASL will resolve correctly at assembly time; whether the external reference can be resolved at link time depends
on the availability of SUB to the linker, and on how widely separated are the calling and called routines.
38.5.19.
Section 38.6
38.6.2. Both generate an ER entry for X in the ESD record, but the V-type constant generates a different RLD entry
that lets the Linker assign an indirect resolution to X.
Section 38.7.
38.7.1. An ENTRY name always has the same owning ESDID as its containing control section, but does not have
an ESDID of its own. (Thats why the * is attached to the ESDID.)
38.7.2. This can be done by using the fact that the owner of a COM section can refer to its internal names as ordinary
symbols. Thus, the owner of the MyCom section can define an address constant pointing to the symbol YourData and
give the adcon a name like DataAddr declared in an ENTRY statement:
Owner

CSect
- - DataAddr DC
ENTRY
- - MyCom
COM
- - YourData DS
- - -

Owner of the MyCom common section

A(YourData)
DataAddr

Address of the data area


Define its name externally

The Owner s common section


Parts of the MyCom section
The data area you need to reference
Other parts of the MyCom section

XL(23456)

Then, in your program you can write


YourProg CSect
EXTRN
- - L
L
- - DataPtr DC

.
DataAddr

Program to reference YourData


Name of the YourData pointer

3,DataPtr
3,0(,3)

Get the Owner s YourData pointer


Get the YourData pointer
... and work with the data
Point to MyCom s YourData pointer

A(DataAddr)

38.7.3. Use the contents of the Address as both an addend and as a mask to round up the current offset to the required
boundary. Suppose the current offset is in register ROff::
L
ALR
NR

0,Addr
ROff,0
ROff,0

Get the XD item s Address field


Add to the current offset
Set low-order bits to zero

38.7.4. If there were more than 1024 PR items each having length 4, the offset in the QL2-con would have a nonzero
high-order digit. That digit would appear in the base-register digit position of the base-displacement field of the L
instruction.
Section 38.10
38.10.5. Since the four instructions all set bit 32 of the R2 operand register (the b bit) to 0 in 24-bit mode and to 1 in
31-bit mode, these are the settings that BSM uses to set the AMODE before branching. It will set the PSW AMODE
bits to the same value they had at the time of the call.
38.10.6. BSM: yes; BASSM: no, because the first operand register is always changed in ways that depend on the
current addressing mode.

Suggested Solutions to Selected Exercises and Programming Problems

1227

38.10.7. Remember that BAL is a 4-byte instruction that sets the ILC to B 1 0 , which means the high-order bit of the
R 1 register will be 1. If your program runs in 24-bit addressing mode and you try to return from the called routine with
BSM, it will set the addressing mode to 31, and any address with nonzero bits in positions 32-40 will try to address
something beyond the bounds of your program.
Executing in AMODE 31 is safe for calling another AMODE 31 program, because both BAL and BALR set the
high-order bit of the 32-bit return address to 1; returning with BSM doesnt change the addressing mode.
38.10.8. It would work, but youd have to set the appropriate bits in the R1 and R 2 registers, which isnt necessary for
the ordinary linkage instructions that dont change addressing mode.

Programming Problem 38.2.


The Zeller subroutine has three arguments, the year, month, and day of month. Note that this solution makes no local
storage references, and therefore has no USING statement!
Zeller
CSect ,
No base register needed!
* Zeller s Congruence for the day of the week (0=Saturday, 6=Friday).
* D_W = (D_M+Y+Y/4+6*(Y/100)+Y/400+((M+1)*26)/10) (mod 7).
*
All divisions truncate, and return floor(quotient)
STM
14,5,12(13)
Save registers
LM
1,3,0(1)
Addr(Year,Month,Day_of_Month)
L
5,0(,1)
Get Y (year)
L
1,0(,3)
Get D_M (day of month)
AR
1,5
D_M+Y
SRA
5,2
floor(Y/4)
AR
1,5
D_M+Y+floor(Y/4)
LA
3,25
Constant 25
XR
4,4
Clear high-order register
DR
4,3
floor(Y/100)
LR
4,5
Copy to GR4
SRA
4,2
floor(Y/400)
AR
1,4
D_M+Y+floor(Y/4)+floor(Y/400)
MHI
5,6
6*floor(Y/100)
AR
1,5
D_M+Y+fl(Y/4)+fl(Y/400)+6*fl(Y/100)
LA
3,5
Constant 5
L
5,0(,2)
Get M (month)
AHI
5,1
M+1
MHI
5,13
(M+1)*13
XR
4,4
Clear high-order register
DR
4,3
((M+1)*13)/5
AR
1,5
Add to sum
LA
4,7
Constant 7
XR
0,0
Clear high-order register
DR
0,4
Divide by 7, leave remainder in GR0
LM
1,5,24(13)
Restore all but GR0
BR
14
End
The calling program could be written like this:
P38_2

Save
EndSave
*
Read

1228

CSect
Print
STM
LR
CNOP
BRAS
Using
DC
ST
ST

,
NoGen
14,12,12(13)
2,13
0,4
13,EndSave
Save,13
18F 0
2,4(,13)
13,8(,2)

ReadCard Inrec,NoData
MVC
CYear,InRec+6
MVC
CDay,InRec+28
PACK DWork,Inrec(10)
CVB
0,DWork

Save registers
Copy address of caller s area
Align to 4-byte boundary
Set GR13 to address of our save area
Use GR13 as local base register
Local save area
Store back chain in our area
Put forward chain in caller s area
Read an input record
Move year characters for output
Move day characters for output
Convert Year to packed decimal
Convert to binary

Assembler Language Programming for IBM z System Servers

Version 1.00

ST
PACK
CVB
ST
PACK
CVB
ST
MVI
MVC

0,Year
Save the binary year value
DWork,Inrec+10(10) Convert Month to packed decimal
0,DWork
Convert to binary
0,Month
Save the binary month value
DWork,Inrec+20(10) Convert Day of month to packed dec
0,DWork
Convert to binary
0,DayofM
Save the binary day of month value
Line,C
Initialize output line to blanks
Line+1(L Line-1),Line
Ripple move

LA
L
BASR
ST

1,ArgList
15,AZeller
14,15
0,WeekDay

DoYear

NoData
MoveDay
*
AZeller
ArgList
WeekDay
DayofM
Month
Year
DWork
CYear
CDay
*
Days

DCh
DSat
DSun
DMon
DTue
DWed

LR
1,0
AR
1,1
LA
3,Line+1
XR
2,2
IC
2,Days+1(1)
IC
1,Days(1)
LA
1,DCh(1)
EX
2,MoveDay
LA
3,2(3,2)
L
1,Month
AR
1,1
IC
2,Months-1(1)
IC
1,Months-2(1)
LA
1,MCh(1)
EX
2,MoveDay
LA
3,2(2,3)
MVC
0(2,3),CDay
CLI
0(3),C
JNE
DoYear
MVC
0(1,3),CDay+1
BCTR 3,0
MVI
2(3),C ,
MVC
4(4,3),CYear
PrintLin Line,L Line
J
Read
PrintOut *,Header=NO
MVC
0(*-*,3),0(1)

Point to argument address list


Get address of Zeller routine
Call Mr. Zeller for his congruence
Store the result
Format the data
Copy to GR1
Double it for index
Point to initial character
Clear GR2 for EX lengths
Get effective length of day name
Get offset of day name
Point to day name
Move day name to output line
Step output address over day
Get month value (starts at 1)
Double for indexing
Get effective length of month name
Get offset of month name
Point to month name
Move month name to line
Step over month name
Move character form of day
Was leading character a blank?
Skip adjustment if yes
Move the single-digit day
Back up by 1 character
Insert comma
Insert year characters
Print the result
Read another input record
Move day character name to line

DC
DC
DS
DS
DS
DS
DS
DS
DS

V(Zeller)
Address of Zeller subroutine
A(Year,Month,DayofM)
Argument addresses
F
F
F
F
D
Doubleword work area
CL4
CL2

DC
DC
DC
DC
DC
DC
DC
DS
DC
DC
DC
DC
DC

AL1(DSat-DCh,L DSat-1)
AL1(DSun-DCh,L DSun-1)
AL1(DMon-DCh,L DMon-1)
AL1(DTue-DCh,L DTue-1)
AL1(DWed-DCh,L DWed-1)
AL1(DThu-DCh,L DThu-1)
AL1(DFri-DCh,L DFri-1)
0C
C Saturday
C Sunday
C Monday
C Tuesday
C Wednesday
Suggested Solutions to Selected Exercises and Programming Problems

1229

DThu
DFri
*
Months

MCh
MJan
MFeb
MMar
MApr
MMay
MJun
MJul
MAug
MSep
MOct
MNov
MDec
*
Line
InRec

DC
DC

C Thursday
C Friday

DC
DC
DC
DC
DC
DC
DC
DC
DC
DC
DC
DC
DS
DC
DC
DC
DC
DC
DC
DC
DC
DC
DC
DC
DC

AL1(MJan-MCh,L MJan-1)
AL1(MFeb-MCh,L MFeb-1)
AL1(MMar-MCh,L MMar-1)
AL1(MApr-MCh,L MApr-1)
AL1(MMay-MCh,L MMay-1)
AL1(MJun-MCh,L MJun-1)
AL1(MJul-MCh,L MJul-1)
AL1(MAug-MCh,L MAug-1)
AL1(MSep-MCh,L MSep-1)
AL1(MOct-MCh,L MOct-1)
AL1(MNov-MCh,L MNov-1)
AL1(MDec-MCh,L MDec-1)
0C
C January
C February
C March
C April
C May
C June
C July
C August
C September
C October
C November
C December

DC
DS
End

CL40
CL80
P38_2

Input record buffer

The printed output from the suggested test cases is:


Tuesday June 30, 2009
Friday January 1, 2000
Saturday January 1, 1900

Programming Problem 38.3. Note that this solution modifies none of the registers that must be restored on
return.
HexUlp
*
*
*
*
*
*
*
HxUlpE

*
HxUlpD

1230

CSect ,
Return ulp of hex float arguments
Calling sequences:
Call HxUlpE(X)
Calculate ulp(X) for short X
Call HxUlpD(X)
Calculate ulp(X) for long X
Call HxUlpL(X)
Calculate ulp(X) for extended X
ulp(x) is returned in FPR0 (for short and long X), and in
FPR0/2 for extended X.
ENTRY HxUlpE,HxUlpD,HxUlpL
L
XGR
OIHL
ICMH
LFGR
DE
BR

1,0(,1)
0,0
0,1
0,8,0(1)
0,0
0,0(,1)
14

Get address of argument X


Clear GG0
Set bit 31 to 1
Insert characteristic cc of X
Copy X cc000001 00000000 to FPR0
Divide by X
Return short ulp(X) to caller

L
XGR
OILL
ICMH
LFGR
DD

1,0(,1)
0,0
0,1
0,8,0(1)
0,0
0,0(,1)

Get address of argument X


Clear GG0
Set bit 63 to 1
Insert characteristic cc of X
Copy X cc000000 00000001 to FPR0
Divide by X

Assembler Language Programming for IBM z System Servers

Version 1.00

*
HxUlpL

BR

14

Return long ulp(X) to caller

L
XGR
LD
LD
ICMH
LFGR
LGHI
LFGR
DXR
BR
End

1,0(,1)
0,0
4,0(,1)
6,8(,1)
0,8,0(1)
0,0
0,1
2,0
0,4
14

Get address of argument X


Clear GG0
Put high half of X in FPR4
Put low half of X in FPR6
Insert characteristic cc of X
Copy X cc000000 00000000 to FPR0
Put X00000000 00000001 in GG0
Copy it to FPR2
Divide by X
Return extended ulp(X) to caller

Programming Problem 38.9. The changes of addressing mode in this little program are needed because the
PrintOut macro operates only in AMODE(24):
AM

CSect ,
Using *,15
LG
0,=FD -1
Preset GG0
LGR
1,0
Copy to GG1
SAM24 ,
Set addressing mode 24
BASSM 1,0
BASSM sets GG1
LGR
2,0
Copy GG0 to GG2
SAM31 ,
Set AM31
BASSM 2,0
BASSM sets GG2
LGR
3,0
Copy GG0 to GG3
SAM64 ,
Set AM64
BASSM 3,0
BASSM sets GG3
SAM24 ,
Reset to AM24 for PRINTOUT
PrintOut 16,17,18,19,Header=No
Display the results

*
LGR
4,0
Copy GG0 to GG4
SAM24 ,
Set addressing mode 24
BASR 4,0
BASR sets GR4
LGR
5,0
Copy GG0 to GG5
SAM31 ,
Set AM31
BASR 5,0
BASR sets GR5
LGR
6,0
Copy GG0 to GG6
SAM64 ,
Set AM64
BASR 6,0
BASR sets GG5
SAM24 ,
Reset to AM24 for PRINTOUT
PrintOut 20,21,22,*,Header=No
End
The results look like this (explanations added):
GGR

= X FFFFFFFFFFFFFFFF

(Initialization value)

GGR
GGR
GGR

1
2
3

= X FFFFFFFF0002100E
= X FFFFFFFF80021016
= X000000000002101F

(AM24: b bit 32 = 0)
(AM31: b bit 32 = 1)
(AM64: e bit 63 = 1)

GGR
GGR
GGR

4
5
6

= X FFFFFFFF0002107C
= X FFFFFFFF80021084
= X000000000002108C

(AM24: b bit 32 = 0)
(AM31: b bit 32 = 1)
(AM64: e bit 63 = 0)

so the first-operand mode-bit settings are the same in AM24 and AM31.

Programming Problem 38.10.

Suggested Solutions to Selected Exercises and Programming Problems

1231

HexExp

1232

CSect
L
XR
ICM
NILL
AHI
BR
End

,
1,0(,1)
0,0
0,1,0(1)
0,B01111111
0,-64
14

Return exponent of HFP argument


Get argument address
Clear GR0
Insert sign and characteristic
Eliminate sign bit
Remove bias
Return to caller

Assembler Language Programming for IBM z System Servers

Version 1.00

Section 39 Solutions
Section 39.1
39.1.1. The symbols and their values are:
Value
000000
000000
00000C
000010
000012
000018
000020

Symbol
D39_1_1
A
B
C
D
E
F

DSect
DS
DS
DS
DS
DS
Equ

,
CL9
F
X
H
D
*-D39_1_1

39.1.2. Using the same symbols as in Figure 57 on page 163, we can define the DSECT this way:
ALStmt
DSect ,
Statemnt DS
0CL80
Name
DS
0CL8
DS
CL9
Mnemonic DS
0CL5
Mnemopnd DS
0CL25
DS
CL6
Operand DS
0CL19
DS
CL20
Comment DS
CL36
Continue DS
C
Sequence DS
CL8
ALStmt_L Equ
*-ALStmt

Assembler Language statement


Define 80-column record area
Define name-field symbol
Reserve space for name-field symbol
Define 5-character mnemonic field
Define both mnemonic and operands
Reserve space for mnemonic
Define 19-character operand field
Reserve space for operand field
Allocate 36 columns for comments
Define continuation-indicator column
Define sequencing columns
Length of the DSECt

39.1.3. As defined in the solution to Exercise 39.1.2, the values and length attributes of all symbols are:
Symbol
Statement
Name
Mnemonic
MnemOpnd
Operand
Comment
Continue
Sequence
ALStmt_L

Value (Hex)
000000
000000
000009
000009
00000F
000023
000047
000048
000050

Length Attr.
80
8
5
25
19
36
1
8
1

Section 39.2
39.2.1. Following the Equ statement defining the value of the symbol RecLen, add these two statements:
RecBase

Org
DS

Record
XL(RecLen)

Position LC at start of DSECT


Define symbol with record length

39.2.2. You can do this with a single statement:


NewRec

DS

0D,XL(RecLen)

Section 39.3
39.3.1. We assumed in Figure 618 on page 860 that the offset of the symbol RecID in the Record DSECT is greater
than 4096. So that the displacement of the second operand will be less than 4096, we must subtract 4096 and assign the
base register (GR8) with contents 4096 greater than the contents of GR7. You should never program this way!
39.3.2. The generated instruction is X D204 000A 700A . The base register for the first operand is zero, so the target
address is at address X00000A , very probably causing a protection exception. (Note also that the Effective Length is 4,
meaning that the MVC is attempting to move 5 bytes.)
39.3.3. The generated instruction is X D203 500A 700A . Both the target address and the Effective Length are correct.
Suggested Solutions to Selected Exercises and Programming Problems

1233

39.3.4. The LAY instruction (assuming the USING 0+X F999 , 7 statement in the footnote on page 863) will generate
E320 7D07 0871, with G R 7 as base register. (Note that the base value X F999 plus the displacement X 8 D07 is
X186A0 =100000.)
Section 39.4
39.4.1. The instructions and their generated object code are:
LA
LA

1,ABC
2,Qual.ABC

4110 C008
4120 9004

39.4.2. The instructions and their generated object code are:


Qual

Using
Using
LA
LA

*,9
*,6
1,ABC
2,Qual.ABC

4110 6008
4120 9008

Even though both instructions have the same displacement, the first USING specifies the higher-numbered register, so it
cannot be used to resolve the unqualified implied address of the first LA instruction. The lower-numbered register,
GR6, is assigned as base.
39.4.3. The three instructions and their generated object code are:
4100 9028
4110 9028
4120 9028

LA
LA
LA

0,A+40
1,QQ.A+40
2,QQ.A+40

Ordinary USING
Labeled USING
Labeled USING

All three generate the same object code.


39.4.4. You might expect the generated object code to be X4130 7200 . However, the Assembler doesnt resolve qualified absolute symbols, so the statement generates a diagnostic.
Section 39.5
39.5.2. The three DSECTs as written are short enough that all three can be addressed with a single base register, so the
order of their mapping with the Dependent USING statements does not matter. However, if one of the DSECTs is very
long (for example, DSECT A is defined with a DS XL6000 statement), it might be best to map the three DSECTS with
the longest one last.
39.5.3. If the two CSECTs are not assembled together, none of the symbols in the MsgSkels CSECT would be known in
the Program CSECT.
39.5.4. Consider these DSECT definitions:
A
BLoc
CLoc

DSect
DS
DS
DS
DS

,
CL32
XL(Blen)
XL(Clen)
(256-(*-A))

B
B1
B2
BLen

DSect ,
DSD
DS
D
Equ
*-B

C
C1
C2
CLen

DSect
DS
DS
Equ

,
CL80
XL8
*-C

Section 39.6
39.6.2. Assuming that GR9 provides addressability to the Outer DSECT, you could write something like this:
Using
LA
Using
LA
Using

Outer,9
10,Out_Inr1
Inner,10
11,Out_Inr2
Inner,11

A(Out_Inr1) in
Addressability
A(Out_Inr1) in
Addressability

GR10
for first instance
GR11
for second instance

Three base registers are needed, rather than one.


39.6.3. The Top DSECT starts at location zero. The length of the Bot DSECT is 16 (X 1 0 ) bytes because it is rounded
to the next doubleword boundary. The Mid DSECT length is X C8 bytes. The Top is three times as long as Mid, or
X 2 5 8 bytes. Offsets of the other variables within their respective DSECTs are easy to determine. The offsets of the
four variables are:

M1B1.X1
Mid1.MidVar1
M3B2.X2
Mid3.MidVar4

1234

X 0 2 8
X 0 3 8
X 2 0 9
X 2 3 8

Assembler Language Programming for IBM z System Servers

Version 1.00

39.6.4. The generated instructions are:


Object Code
D204 7028 702D
D204 709D 7028
D204 7209 722D
D204 70F0 7209
D20F 71B8 7228
D20F 7098 70F0
D213 714C 7190
D2C7 7000 70C8

Instruction
MVC
M1B1.X1,M1B1.X2
MVC
M1B3.X2,M1B1.X1
MVC
M3B2.X2,M3B3.X2
MVC
M2B1.X1,M3B2.X2
MVC
Mid3.B1,Mid3.B3
MVC
Mid1.B3,Mid2.B1
MVC
Mid2.MidVar3,Mid3.MidVar1
MVC
M1,M2

Section 39.7
39.7.1. The DSECTs and their lengths are:
Date
Addr
Phone

X 0 0 8
X 0 5 0
X 0 1 0

=
=
=

8
80
16

39.7.2. The DSECTs and their lengths are:


Person
Employee

X 0 9 8
X 3 7 3

= 152
= 883

39.7.5. Yes.

Suggested Solutions to Selected Exercises and Programming Problems

1235

Section 40 Solutions
Section 40.1
40.1.1. The three statements should be written
LowerSub DC
A(LBound)
UpperSub DC
A(HBound)
- - XX
DC
(HBound-LBound+1)F12345
40.1.2. Yes, it is open to criticism on many grounds.318
1. Consider what happens if the addressing halfword of the L instruction named GetIt could address the start of the
table, but not the end.
2. Suppose the initial addressing halfword is X FFF0 : what happens when we want to fetch the fifth table element?
3. The method is quite inefficient, especially considering the availability of many instructions to do indexing automatically,
4. Modifying instructions is considered an extremely poor technique under any circumstance: you cant debug the
code by reading the source or the listing, and the code cannot be shared by more than one process.
5. Its terribly inefficient, because storing into the instruction stream makes the CPU stop pre-processing instructions
and start over.
40.1.3. You can make a good case for either view:

In favor of spacing by 8: Each element of the table is aligned on a halfword boundary, making the halfword integer
more likely to be aligned on correct boundaries; and calculating index offsets can use shift logical instructions
instead of multiplying by 7.

Not in favor of spacing by 8: In programs needing to conserve memory space, adding the extra byte to each entry
could cause addressability problems.

In general, speed of access and simplicity of indexing code are more important considerations.
40.1.4. Only the single element of XX whose index is found at LowerSub will be stored at XSum.
40.1.5. Consider writing the DSECT this way:
Elem
DSect ,
El_Int
DS
HL2
El_Chars DS
CL5
The reason for writing the operand of El_Int as HL2 rather than H is to remind the reader that the integer field may not
always be aligned on a halfword boundary.
Section 40.2
40.2.1. To answer the last two questions first:

The ordering of the array does not matter. Suppose the elements are stored in row order. Then
Addr(A(i,j)) = Addr(A) + L*[N*(i-1)+(j-1)]
Addr(A(j,i)) = Addr(A) + L*[N*(j-1)+(i-1)]

( from element)
( to element)

If the elements are stored in column order,


Addr(A(i,j)) = Addr(A) + L*[(i-1)+N*(j-1)]
Addr(A(j,i)) = Addr(A) + L*[(j-1)+N*(i-1)]

( from element)
( to element)

Since the array A is square, and we are simply exchanging elements, there is no difference between row and column
order.

We dont have to swap the N diagonal elements A(i,i), so the number of elements involved is N*N N, or
N*(N 1). The elements are swapped in pairs, so the number of swaps is N*(N 1)/2.

The code will need to do swaps only for subscripts j < i, for values of i from 2 to N and for values of j from 1 to i 1.
(The inner loop is indented to help readability.)

318

Fortunately, that programmer has been out of business for many years.

1236

Assembler Language Programming for IBM z System Servers

Version 1.00

RI
RiMax
RJ
RjMax

Outer

Inner

Array

Equ
Equ
Equ
Equ

2
3
4
5

LA
RiMax,N
LA
RI,2
LR
RjMax,RI
BCTR RjMax,0
LA
RJ,1
LR
8,RI
BCTR 8,0
LR
10,8
LR
9,RJ
BCTR 9,0
LR
11,9
MHI
9,N
SLDL 8,2
ALR
8,9
MHI
10,N
SLDL 10,2
ALR
10,11
L
0,Array(8)
L
1,Array(10)
ST
0,Array(10)
ST
1,Array(8)
AHI
RJ,1
CR
RJ,RjMax
JNH
Inner
AHI
RI,1
CR
RI,RiMax
JNH
Outer
- - DS
(N*N)F

Register
Register
Register
Register

for
for
for
for

i values
maximum i value
j values
maximum j value

Maximum value of i
Initial value of i
Copy current value of i
Maximum value of j = i-1
Initial value of j
Copy i
Form (i-1)
Copy (i-1) to GR10
Copy j
Form (j-1)
Copy (j-1) to GR11
Form N*(j-1)
Form L*(i-1) and L*N*(j-1)
For linear subscript for A(i,j)
Form N*(i-1)
Form L*N*(i-1) and L*(j-1)
For linear subscript for A(j,i)
Get Array(i,j) for swap
Get Array(j,i) for swap
Store Array(i,j) at old A(j,i)
Store Array(j,i) at old A(i,j)
Increase j by 1
See if we ve completed a j cycle
If not, repeat
Increment i by 1
Compare to upper limit for i
Repeat another cycle on i
N by N array

40.2.3. In a column-ordered array with R rows, we know that the address of an element A(i,j) is given by
addr(A(i,j)) = [addr(A(1,1))-(L*(R+1))]+[L*(i+R*j)].
We know the address of A(i,j); so after rearranging, we find
(i-1)+R*(j-1) = [addr(A(i,j))-addr(A(1,1))]/L
If we divide the right-hand expression by R, the remainder is (i-1) and the quotient is (j-1).
L
R

Equ
4
Equ
7
L
1,ElemAddr
S
1,BaseAddr
SRL
1,2
SR
0,0
D
0,=A(R)
AHI
0,1
ST
0,ISub
AHI
1,1
ST
1,JSub
- - ElemAddr DS
A
BaseAddr DS
A
ISub
DS
F
JSub
DS
F

Assume elements are 4 bytes long


Assume 7 rows
Address of A(i,j)
Subtract address of A(1,1)
Divide by L
Clear high-order register for divide
Divide by number of rows
Add 1 to remainder (i-1)
Store I subscript
Add 1 to quotient (j-1)
Store J subscript
Known address of A(i,j)
Known address of A(1,1)
Calculated i subscript
Calculated j subscript

Section 40.3
40.3.7. We simply exchange the corresponding elements of the IVal and JVal arrays. These instructions will transpose
the sparse matrix A:

Suggested Solutions to Selected Exercises and Programming Problems

1237

L
BCTR
SLA
JNP
LA
SR
L
L
ST
ST
JXLE
- - -

Next

Done

1,NbrEls
1,0
1,2
Done
0,4
0,0
3,IVal(2)
4,JVal(2)
3,JVal(2)
4,Ival(2)
2,0,Next

Get number of array elements


Decrement by 1
Make into a word index
Exit if no elements today
Set word increment
Initialize index
Get an I subscript
And a J subscript
Store I where J used to be
Store J where I used to be
Increment index, test, and loop
Transposition complete

Section 40.4
40.4.6. Heres one solution:
AddrTab

DC

(NRows)A(AA-L+L*(NRows*(*-AddrTab)/4))

Section 40.5
40.5.1. It will not matter, because you will be searching through the entire array.
40.5.2. Unless we were lucky enough to find the desired item on the first comparison, the search would end with the
element not found. For example, if the array elements were 5, 4, 3, 2, and 1 and we search for the value 2, the first
comparison (2 to 3) would show that we should move lower in the array. But all those elements are larger than 2, so
the search would never find the correct element.
40.5.5. You wont see much improvement, because the effort of comparing the sign of the search argument to the sign
of the current table probe element is about the same as just comparing the argument to the table entry.
40.5.7. The best estimate is N*(N-1)/2 comparisons.
Section 40.6
40.6.1. (c) will overwrite the element currently at the top of the stack, and then set the stack pointer to the address of an
empty stack position.
40.6.2. The LM/STM/LA instructions will do the initialization:
SP
StkSize
Stack

Equ
1
GR1 contains stack pointer
Equ
20
Number of elements for full stack
DS
(StkSize)F
Allocate space for the stack
DS
0F
Define name of stack area
- - LM
0,2,=F 6 , 2 , 9
STM
0,2,Stack-3*L STACK
Set values
LA
SP,Stack-3*L STACK
Initialize stack pointer

40.6.3. The main disadvantage of this method is that a check for stack overflow might be done after the push, which
might be too late. One (very) small advantage is that a CPU that overlaps the execution of several instructions need not
wait for the address of the stack top to be generated before it can use that address to store the new data item.
40.6.4. The values of the expressions are 210, 77, and 100.
a. A possible infix notation is 2*3*5*7
Operator
Operand
Stack

*
7

3
7

2
3
7

5
2
3
7

10
3
7

30
7

210

b. A possible infix notation is 7*((3*2)+5)


Operator
Operand
Stack

1238

*
7

3
7

2
3
7

+
6
7

5
6
7

*
11
7

77

Assembler Language Programming for IBM z System Servers

Version 1.00

c. A possible infix notation is (3+7)*(2*5)


Operator
Operand
Stack

+
7

3
7

*
10

2
10

5
2
10

*
10
10

100

40.6.5. The first 5 statements define some symbolic names for registers.
EP
SP
StkSize
WT
WV

Fetch

Push
Step

Equ
Equ
Equ
Equ
Equ

11
10
10
8
9

Expression scan pointer


Stack pointer
Stack size
Work reg for type codes
Work reg for values, operators

SR
LA
LH
LH
LTR
JM
JP
LR
AHI
ST
LA
J

SP,SP
EP,Expressn
WT,0(,EP)
WV,2(,EP)
WT,WT
Finis
Oprtr
1,WV
SP,-4
1,Stack(SP)
EP,4(,EP)
Fetch

Initialize SP to empty stack


Initialize expression scan pointer
Get expression item type code
Get operand or operator
Check type of expression item
Done if less than 0
Branch if an operator
Move to GR1 for storing
Push stack contents down once
Place new operand onto stack
Step pointer to next expression item
And get next item

*
Set up for operation on top two stack elements
Oprtr
L
1,Stack+4(SP)
Get next-to-top stack item
L
2,Stack(SP)
Top stack element in GR2
LA
SP,8(,SP)
Pop both elements off the stack
LTR
WV,WV
Now check the operator code
JZ
AddTwo
If zero, add operator
MR
0,2
Otherwise, multiply
J
Push
And push the result back on stack
AddTwo
AR
1,2
Add the operands
J
Push
Go push sum onto stack
Finis
PrintOut 1,*
Print result and stop
DS
(StkSize)F
Space for stack
Stack
DS
0F
Expressn DC
H 0 , 2 , 0 , 3 , 0 , 4 , 4 , 1 , 4 , 0 , -1
Expression 234*+
40.6.7. Suppose the top of the two stacks are represented by values Stk1T and Stk2T; the bottom of Stk1 is A(1) and
the bottom of Stk2 is A(N). Then we can represent the four functions with this pseudo-code:
Push1(X): Stk1T = Stk1T+1;
if Stk1T = Stk2T then Stk1 Overflow
A(Stk1T) = X
Push2(X): Stk2T = Stk2T-1;
if Stk2T = Stk1T then Stk2 Overflow
A(Stk2T) = X
Pop1(X):

if Stk1T < 1 then Stk1 Underflow


X = A(Stk1T)
Stk1T = Stk1T-1;

Pop2(X):

if Stk2T > N then Stk2 Underflow


X = A(Stk2T)
Stk2T = Stk2T+1;

You can now write the appropriate instructions without difficulty.


Section 40.7
40.7.1. You could write the DSECT this way:
Array_El DSECT
Integer DS
HL2
CharData DS
CL5

2-byte integer
5 bytes of character data
Suggested Solutions to Selected Exercises and Programming Problems

1239

Its useful to define the Integer field with an explicit length because you dont necessarily know whether each array
element will be aligned on a halfword boundary.
40.7.5. The list is empty when both the forward and backward link addresses are the address of the list anchor.
40.7.10. Well choose arbitrary values for the symbols DataLen and NLItms to show how the array can be allocated.
NLItms
DataLen
*
ArrStack
ElemLen

Equ
Equ

20
40

Assume a list of 20 elements


Assume data field length = 40

DS
Equ
DS

F,XL(DataLen)
Space for first list element
*-ArrStack
Length of each list element
(NLItms-1)XL(ElemLen)
Space for remaining elements

40.7.11. These instructions will initialize the list:


LHI
LHI
LA
InitLoop ST
AHI
AHI
JCT
ST
ST
LA
ST

0,NLItms-1
2,2
1,ArrStack
2,0(,1)
2,1
1,ElemLen
0,InitLoop
0,0(,1)
0,HeadNdx
0,1
0,FreeNdx

One less than all list elements


Initial link value
Point to first list element
Store a successor index
Increment the index
Add the length of each list element
Count down until last element
Last element has a null link
Initialize head of working list
Index of first free-list element
Initialize index of free-list head

40.7.12. The steps would be like these:


1.
2.
3.
4.

If the FreeNdx is zero, there are no more free elements; branch to NoneLeft
NewNdx FreeNdx [The index of the New element is taken from the head of the free list]
FreeNdx Link(FreeNdx) [The new head of the free list is the previous second element on the free list]
Link(NewNdx) 0 [Assume the new element might be the end of the list]

40.7.13. We have already added elements with indexes 1 and 2 to the list, and the first element of the free list has index
3. After taking this free element from the list, the list would look like this:
Links
Data

data 1

data 2

:
:
:

HeadNdx = 1
FreeNdx = 4

 end of the current list


 NewNdx, prior to insertion

Having acquired the New element, you can use steps like these to add it to the head of the list:
1. Data(NewNdx) NewData [Put the new data in the new element]
2. Link(NewNdx) HeadNdx [The link in the new element points to the previous head element]
3. HeadNdx NewNdx [Make the new element the head of the list]
After adding the new element to the head of the list, the list would look like this:

1240

Assembler Language Programming for IBM z System Servers

Version 1.00

Links
Data

data 1

data 1

New Data

:
:
:

HeadNdx = 3
FreeNdx = 4

40.7.15. As written each element in the FSL links into the data field of the next element. If the second DC statement is
corrected to read
DC

(Elem_Len/4)A(0),(NLstItms-1)A(*-Elem_Len,0,0,0,0,0)

there will be no difference in the way the two lists are used.
Section 40.8
40.8.1. Only two links need to be updated:
Q1
Q2
Q3

Using
Using
Using
MVC
MVC

Q_El,5
Q_El,9
Q-El,2
Q1.RLink,Q2.RLink
Q3.LLink,Q2.LLink

Address of Q1
Address of Q2
Address of Q3
Forward chain Q1 to Q3
Backward chain Q3 to Q1

Section 40.9
40.9.1. It will make no difference, so long as elements are entered into the tree using the same left-right convention as
when they are retrieved.
40.9.2. There are four other 3-node binary trees, for a total of five. Let the nodes be indicated by * characters:
*
/ \

/
*

*
\

/
*

40.9.3. These inorder configurations should help you understand how the order of traversal affects the trees:
B
/ \
A

/
C

B
/

C
\

/
B

Youll enjoy sketching these five trees for preorder and postorder traversal.
Section 40.10
40.10.1. You might use shift instructions this way:
HashEnts Equ
L
SRDL
SRL
XR
XR
D

73
0,DataItem
0,16
1,16
1,0
0,0
0,=A(HashEnts)

Number of hash table entries


Load data item into GR0
Last 2 bytes of data item in GR0
First 2 bytes of data item in GR1
XOR the halves into GR1
Clear GR0 for a division
Divide by hash table size

Not a significant savings, but one less memory reference may help.
40.10.2. If the high-order bit of one of the 2-byte fields is 1 (but not in both fields), a different but still valid hash index
will be generated.

Suggested Solutions to Selected Exercises and Programming Problems

1241

Programming Problem 40.1.


The main feature of this solution is that the size of the graph is defined by the two EQU statements at the beginning. All
other quantities that depend on the length and width of the graph are then defined in terms of those values.
P40_1
*
XLen
YLen
*

XLoop

Title Solution to Problem 40.1


Start 0
Graph-plotting problem
Equ
Equ

119
59

BASR 12,0
Using *,12
PrintLin,Page,L Page
LA
11,XLen
LR
10,11
SH
10,MiddlX
JNZ
NotYAxis
LA
2,Graph+(XLen+1)/2
LA
3,YLen

Number of X values
Number of Y values

Inform assembler
Print title line
Initial X position at XLen
Carry X value in GR10
Form true X value from index
If X not zero, no Y axis yet
Position of Y-axis
Number of lines

*
YLoop

MVI
0(2),C |
Put Y-axis marker in line
LA
2,XLen(0,2)
Increment by line length
JCT
3,YLoop
Do YLen times
NotYAxis LR
1,10
Set up for parabola calculation
MR
0,1
X squared
AHI
1,25
Add roundoff factor
D
0,F50
Divide by 50
AHI
1,-25
Subtract 25 giving -y
AH
1,HalfY
Add YLen/2 to get line index
JM
NotStar
If negative, off top of page
CH
1,HYLen
See how close to bottom
JNL
NotStar
If bigger than YLen, off low end
MH
1,HXLen
Otherwise multiply by line length
LA
2,Graph-1(11)
Address of X position in top line
AR
2,1
Add line index
MVI
0(2),C *
Store asterisk in graph
NotStar LCR
1,10
Set up for straight line
AHI
1,-12
Subtract 12
SRA
1,1
Divide by 2, giving -Y
AH
1,HalfY
Add YLen/2 to get line index
BM
NotX
If negative, off the top
CH
1,HYLen
See if off the bottom
JNL
NotX
Jump if so
MH
1,HXLen
Mult line index by line length
LA
2,Graph-1(11)
Construct X-position in top line
AR
2,1
Add line factor to get array loc
MVI
0(2),C X
Store X in the array
NotX
JCT
11,XLoop
Count down on X position
LA
4,YLen
Set up for printing Ylen lines
LA
3,Graph
Establish initial line address mover
Mover
MVC
Line+1(XLen),0(3) Move line to print position
PrintLin Line,L Line
Print line with space at left
LA
3,XLen(0,3)
Increment address
JCT
4,Mover
Loop until all lines are done
Printout *,Header=NO
Exit
*
Page
DC
C1 Solution to Problem 40.1
Heading line
DC
CL(XLen+1)
Space for lines to be printed
F50
DC
F 5 0
HXLen
DC
AL2(XLen)
HalfX
DC
AL2(XLen/2)
HYLen
DC
AL2(YLen)
HalfY
DC
AL2(YLen/2)

1242

Assembler Language Programming for IBM z System Servers

Version 1.00

MiddlX
Graph

DC
DC
DC
DC
End

AL2((XLen+1)/2)
(YLen/2)CL(XLen)
(XLen)C -
X-Axis of minus signs
(YLen/2)CL(XLen)
P40_1

Programming Problem 40.2.


*
*
*
*
*
*
P40_2
StkSiz

Formula
Record
Master

*
Stack
StkLim
Data
Incr
IncrX
Branch

M0
M1
MM
Quit
StkMsg
SynMsg
MsgList
M0P
M1P

Title Solution to Problem 40.2


As each character is read from the input record, it is
immediately converted to a numeric index which controls
all further operations. This master index selects the
operation, determines the stack increment, and chooses
the operands.
START
Equ
BASR
Using
J
DC
DC
DC
ORG
DC
ORG
DC
ORG
DC
ORG
DC
ORG
DC
ORG
DC
ORG
DC
ORG
DC
ORG

0
20
12,0
*,12
Begin
0CL82 , C 0
CL80 , C
256X 0
Master+C A
X 1
Master+C B
X 2
Master+C C
X 3
Master+C 0
X0405
Master+C N
X 6
Master+C&&
X 7
Master+C |
X 8
Master+C X
X 9
*

DC
DC
DC
DC
DC
DC
DC
DC
DC
DC
DC
DC
DC
DC
DC
DC
DC
DC
DC
DC
DC
DS
DC
DC

XL(StkSiz) 0
Stack
Y(StkSiz)
Size of stack, for checking
X F0CCAA00FFFF
Values for A,B,C,0,1,NOT
H 0 , 1 , 1 , 1 , 1 , 1 , 0 , -1,-1,-1 Stack ptr increments
AL1(0,2,4,6,8,10,12,14,16,18) Offsets into incr
AL1(EndForm-Operate) Offset for all other chars
AL1(OprndA-Operate) Offset for A
AL1(OprndB-Operate) Offset for B
AL1(OprndC-Operate) Offset for C
AL1(Oprnd0-Operate) Offset for 0
AL1(Oprnd1-Operate) Offset for 1
AL1(NOT-Operate)
Offset for N
AL1(AND-Operate)
Offset for &
AL1(OR-Operate)
Offset for |
AL1(XOR-Operate)
Offset for X
C Result is always False
C Result is always True
C Result is indeterminate
C 0 End of tests
C *** Stack Overflow
C *** Stack holds more than 1 item at end
0F
Start of message list
AL1(L M0),AL3(M0)
Result all zero
AL1(L M1),AL3(M1)
Result all ones

Size of stack
Use register 12 for base
Branch around data definitions
Define print line and carriage ctrl
Define record, 1 blank to force stop
Initialize table to all zeros
Variable A
Variable B
Variable C
Constants 0,1
NOT operation
AND operation
OR operation
XOR operation
Set LC to end of translate table

Suggested Solutions to Selected Exercises and Programming Problems

1243

MMP
*
*
*
*
*
*
*
*
*
*
Begin

Fetch

******
Operate
OprndA
OprndB
OprndC
Oprnd0
Oprnd1

AND
OR
NOT
XOR
EndOps
******

StkErr
SynErr
EndForm

PRINT

Stop

1244

DC

AL1(L MM),AL3(MM)

Result mixed bits

Register usage -- (all are set to 0 when record is read)


R0 = Result of operation
R1 = Master index and branch index
R2 = Stack index increment table index
R3 = Stack pointer
R4 = Old stack top value
R5 = Data value for variables and constants
R6 = Input record scan pointer and message index
ReadCard Record,Stop
Read a record, stop if no more
PrintLin Formula,L Formula
LM
0,6,=7F 0
Initialize all registers to 0
IC
1,Record(6)
Get a character from the record
IC
1,Master(1)
Replace it by its master index
IC
2,IncrX(1)
Get (stack index increment) index
AH
3,Incr(2)
Add increment to stack index
BNP
StkErr
Stack underflow if not positive
CH
3,StkLim
Compare to stack size
BH
StkErr
Stack overflow if exceeds StkSiz
IC
0,Stack-1(3)
Get new stack top
IC
4,Stack(3)
Get old stack top
IC
5,Data-1(1)
Get operand, if any
IC
1,Branch(1)
Now set up branch index
PrintOut 0,1,2,3,4,5,6,Stack
for debugging
B
Operate(1)
And go do the operation
Equ
*
Start of operation list
Equ
*
Character is a
Equ
*
Character is b
Equ
*
Character is c
Equ
*
Character is 0
Equ
*
Character is 1
LR
0,5
Move data to result register
B
EndOps
And go complete the operation
NR
0,4
Perform AND operation
B
EndOps
Go store the result
OR
0,4
Perform OR operation
B
EndOps
XR
0,5
Perform NOT operation
B
EndOps
XR
0,4
Perform XOR operation
STC
0,Stack-1(3)
Store result back on stack
PrintOut 0,1,2,3,4,5,6,Stack for debugging
LA
6,1(0,6)
Increment record scan pointer
B
Fetch
And go get next character
PrintLin StkMsg,L StkMsg Indicate stack error
B
Begin
And start with a new record
PrintLin SynMsg,L SynMsg Bad formula
B
Begin
Read next formula
CHI
3,1
Check final stack index
BNE
SynErr
Syntax error, stack holds too much
LA
6,M0P-MsgList
Set for result being all zeros
TM
Stack,X FF
Test all bits on first stack entry
BZ
PRINT
LA
6,MMP-MsgList
Assume now the bits are mixed
BM
PRINT
Branch if that s true
LA
6,M1P-MsgList
Otherwise they re all ones
L
1,MsgList(6)
Get pointer to message
IC
2,MsgList(6)
And message length
PrintLin 0(1),0(2)
Print result message
B
Begin
And start all over again
PrintLin Quit,L Quit
That s all, give up
BR
14
Return to supervisor
End
P40_2

Assembler Language Programming for IBM z System Servers

Version 1.00

Programming Problem 40.6.


This solution uses indentation to show the nesting of the three loops. The size of the matrices is defined by the EQU
statement defining N.
P40_6
N
*

CSect ,
Using *,15
Equ
5
LHI

*
LOuter
LMiddle

1,N

LHI
2,N
XR
0,0
LHI
3,N

*
LInner

LR
BCTR
MHI
ALR
BCTR
SLL
L
LR
BCTR
MHI
ALR
BCTR
SLL
M
AR
JCT

4,1
4,0
4,N
4,3
4,0
4,2
7,A(4)
5,3
5,0
5,N
5,2
5,0
5,2
6,B(5)
0,7
3,LInner

*
LR
BCTR
MHI
ALR
BCTR
SLL
ST
JCT

4,1
4,0
4,N
4,2
4,0
4,2
0,C(4)
2,LMiddle

*
JCT

1,LOuter

A
B
C

DumpOut C,C+4*(N*N)
PrintOut *,Header=NO
DC
(N)F 1 , 2 , 3 , 4 , 5
DC
(N)F 5 , 4 , 3 , 2 , 1
DS
(N*N)F
End
P40_6

Begin Outer loop


Initialize I in GR1
Begin Middle loop
Initialize J in GR2
Accumulated sum in GR0
Initialize K in GR3
Inner loop: calculate C(I,J)
I
I-1
(I-1)*N
(I-1)*N+K
(I-1)*N+K-1
4*((I-1)*N+K-1)
Get A(I,K)
K
K-1
(K-1)*N
(K-1)*N+J
(K-1)*N+J-1
4*((K-1)*N+J-1)
A(I,K) * B (K,J)
Accumulate sum
Iterate on K
End of Inner loop
I
I-1
(I-1)*N
(I-1)*N+J
(I-1)*N+J-1
4*(I*N+J)
Store C(I,J)
Iterate on J
End of Middle loop
Iterate on I
End of Outer loop
Display result in hex format

Programming Problem 40.8.


*
Solution to Bordered-Square Programming Problem 40.8.
* This program is heavily parameterized, so that you need only to
* change the value of N, the length of each row of the square.
* If N exceeds 58 or is less than 6, various assembly errors occur.
*
Print NoGen
P40_8
Start 0
Print a square
Using *,15
*
N
Equ
12
Length of one edge
SqSize
Equ
(N/2)*2
Ensure square size is an even value
NZeros
Equ
SqSize-2
Number of inner zeros to print
Suggested Solutions to Selected Exercises and Programming Problems

1245

Lines
TopRow
LineLen
LineCntr
OuterCh
InnerCh
LeftEdge
*

Skip3
NoSkip3

NoSkips

Equ
Equ
Equ
Equ
Equ
Equ
Equ

60
Assume 60 lines per page
(Lines-SqSize)/2-1 Line number of top of square
120
Length of the line
LineLen/2
Center position on a line
C 1
Character for outer border
C 0
Character for inner border
LineCntr-(SqSize/2)
Left edge of printed square

PrintLin TopLine,1
Start a new page
LA
1,TopRow
Calculate number of lines to skip
SR
0,0
Clear high-order word
D
0,=F 3
Divide by 3
LTR
1,1
Any lines to triple-space?
JZ
NoSkip3
PrintLin CCChars,1
Triple space
JCT
1,Skip3
Continue triple-spacing as needed
LTR
0,0
Any lines to single/double space?
JZ
NoSkips
If not, done with skipping lines
LA
1,CCChars
Point to CCChars
AR
1,0
Index to the needed CC character
PrintLin 0(1),1
Do the final skip
MVI
Square1+LeftEdge,OuterCh
Start outermost row
MVC
Square1+LeftEdge+1(SqSize-1),Square1+LeftEdge fill row
MVC
Square2,Square1
Copy the row
MVI
Square2+LeftEdge+1,InnerCh
Start second row
MVC
Square2+LeftEdge+2(NZeros-1),Square2+LeftEdge+1 fill row
MVC
Square3,Square2
Copy the second row
MVI
Square3+LeftEdge+2,C Blank first interior character
MVC
Square3+LeftEdge+3(SqSize-5),Square3+LeftEdge+2 fill

*
MVC
OutLine,Square1
PrintLin OutBuf,L OutBuf
MVC
OutLine,Square2
PrintLin OutBuf,L OutBuf
MVC
OutLine,Square3
LA
1,SqSize-4
PrtInner PrintLin OutBuf,L OutBuf
JCT
1,PrtInner
MVC
OutLine,Square2
PrintLin OutBuf,L OutBuf
MVC
OutLine,Square1
PrintLin OutBuf,L OutBuf
PrintOut *,Header=NO
*
OutBuf
DC
CL(LineLen+1)
OutLine Equ
OutBuf+1,LineLen
Square1 DC
CL(LineLen)
Square2 DC
CL(LineLen)
Square3 DC
CL(LineLen)
TopLine DC
C 1
CCChars DC
C - 0
End
P40_8

1246

Copy top row


Print the line
Copy second row
Print the line
Copy next row
Number of innermost rows
Print the line
Copy second row
Print the line
Copy top row
Print the line
Terminate the program
Initialize output buffer
Define buffer position of output
Top and bottom rows of square
Second and N-1th rows of square
Remaining rows of square
CC characters for 1/2 spaces

Assembler Language Programming for IBM z System Servers

Version 1.00

Section 41 Solutions
Section 41.2
41.2.2. The first argument R is positional; the other two arguments A= and LV= are keyword.
Section 41.3
41.3.2. Because the expansion of the OPEN macro refers to it, and you dont want the assembly to fail due to an
undefined symbol.
Section 41.4
41.4.1. The address X BAD is odd, so branching to it will cause a specification exception. The address X D1E is even
and will cause a branch into the low area of memory, with unpredictable results.
41.4.2. The address C BAD is even, so it will cause a branch into the low area of memory, with unpredictable results.
The address C D1E is odd and will cause a specification exception.
41.4.3. The displacement in the LA instruction at offset X000000 (statement 6) is X04F , but it should be X02A . +
Section 41.5
41.5.1. If executed in 24-bit addressing mode, the BAL instruction places the Instruction Length Code B 1 0 (BAL is 4
bytes long) in the two high-order bits of the R1 register. In 31-bit mode, the high-order bit of GR R 1 is set from the
Basic Addressing Mode bit of the PSW, which is 1 for 31-bit mode.
Section 41.7
41.7.1. Some possible but unverified instruction sequences are:
(01)
(02)
(03)
(04)
(05)
(06)
(07)
(08)
(09)
(0A)
A
(0B)
(0C)
(0D)
(0E)
(0F)

DC
LPSW
EX
MVI
LGHI
IC
DC
AP
LA
SLA
SRDL
DR
AP
DC
DP
LE
MER
LE
MER
LE
SU
LE
D

H 0
0,8(0,0)
0,*
0,0
1,-1
1,0(,1)
X 1 D11
*,*
1,1
1,33
0,63
0,0
A,A
P 6
A,=P 0
0,=E 1 E72
0,0
0,=E 1 E-72
0,0
0,=X41000001
0,=X41000001
0,=E 1
0,=E 0

Invalid operation
Privileged operation
Execute
Protection
Addressing
DR 1,1: Specification
Decimal Data
Fixed-point overflow
Fixed-point divide
Decimal overflow
Decimal divide
Exponent overflow
Exponent underflow
Significance
Floating-point divide

Programming Problem 41.2.


This program shows one way to read 80-byte records and display the results. It uses three conditional-assembly SETA
statements to set values of the input and output record lengths and the program name.

I revised an earlier version of the figure and decided to leave the old displacement in place for you. Now: What was the original
value of the ABEND code?
Suggested Solutions to Selected Exercises and Programming Problems

1247

**********************************************************************
* Read and list 80-character fixed-length records, with a sequence
*
* number preceding the record image in the listing.
*
**********************************************************************
&OutLen SetA 121
Length of print line
&InLen
SetA 80
Length of input records
&Name
SetC Prob41_2
Name of program
&Name
CSect ,
&Name
AMode 24
Set required addressing mode
&Name
RMode 24
Set required residence mode
Print NoGen
DCB, DCBD expansions are VERY long!
*
SAVE (14,12)
Save caller s registers
LR
12,15
Copy entry address
Using &Name,12
Establish base address
LR
11,13
Copy caller s save area address
LA
13,SaveArea
Point to local save area
ST
11,SaveArea+4
Store backward link in our area
ST
13,8(,11)
Store forward link in caller s area
OPEN (OutDCB,(OUTPUT)) Open output DCB
Out
Using IHADCB,OutDCB
Map the output DCB
TM
Out.DCBOFLGS,DCBOFOPN
Did the output DCB open OK?
JO
OpenIn
Yes, open the input DCB
ABEND 1,DUMP
No sense trying to go further
OpenIn
OPEN (InDCB,(INPUT))
Open input DCB
In
Using IHADCB,InDCB
Map the input DCB
TM
In.DCBOFLGS,DCBOFOPN
Did the input DCB open OK?
Drop Out,In
No more DCBD mappings needed
JO
Proceed
Yes, continue
PUT
OutDCB,OpenMsg
Tell the user the open failed
CLOSE OutDCB
Close the output DCB
J
Finish
Say Farewell
Proceed XR
2,2
Set record count to zero
GetaRec GET
InDCB,InRec
Read a record
AHI
2,1
Increment record count
CVD
2,DTemp
Convert to packed decimal.
MVC
RecNum,NumPat
Move edit pattern to line
ED
RecNum,DTemp+5
Edit 5 digits
PUT
OutDCB,OutLine
Print the output line
J
GetaRec
Go read another record
EOF
CLOSE (InDCB,,OutDCB)
Close both DCBs
FREEPOOL InDCB
Free input buffers
Finish
FREEPOOL OutDCB
Free output buffers
L
13,SaveArea+4
Point to caller s save area
LM
14,12,12(13)
Restore caller s registers
XR
15,15
Set return code to zero
BR
14
*
NumPat
DC
X402020202120
Up to 10**5-1 records
*
OutLine DS
0CL(&OutLen)
Start of output line
RecNum
DS
CL(L NumPat)
Record number + carriage control
DC
CL3
Spaces
InRec
DS
CL(&InLen)
Input record to be listed
DC
CL(&OutLen-(*-OutLine))
Blanks for rest of line
OpenMsg DC
CL(&OutLen) 1 Unable to open input DCB We can t print
*
InDCB
DCB
DDNAME=INPUT,LRECL=&InLen,RECFM=FB,DSORG=PS,MACRF=GM,
X
EODAD=EOF,BLKSIZE=&InLen*10
OutDCB
DCB
DDNAME=OUTPUT,LRECL=&OutLen,RECFM=FBA,DSORG=PS,MACRF=PM,X
BLKSIZE=&OutLen*10
*
SaveArea DC
9D 0
Local save area
DTemp
DS
D
Work area for CVD
DCBD DSORG=PS,DEVD=DA
Generate IHADCB DSect
End
&Name.

1248

Assembler Language Programming for IBM z System Servers

Version 1.00

Using the data in Programming Problem 24.14 on page 401, the output of this program was:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

Four score and seven years ago our fathers brought forth on this continent a ne
w nation, conceived in liberty, and dedicated to the proposition that all men a
re created equal. Now we are engaged in a great civil war, testing whether that
nation, or any nation, so conceived and so dedicated, can long endure. We are
met on a great battle-field of that war. We have come to dedicate a portion of
that field, as a final resting place for those who here gave their lives that t
hat nation might live. It is altogether fitting and proper that we should do th
is.
But, in a larger sense, we can not dedicate, we can not consecrate, we can not
hallow this ground. The brave men, living and dead, who struggled here, have co
nsecrated it, far above our poor power to add or detract. The world will little
note, nor long remember what we say here, but it can never forget what they di
d here. It is for us the living, rather, to be dedicated here to the unfinished
work which they who fought here have thus far so nobly advanced. It is rather
for us to be here dedicated to the great task remaining before us -- that from
these honored dead we take increased devotion to that cause for which they gave
the last full measure of devotion -- that we here highly resolve that these de
ad shall not have died in vain -- that this nation, under God, shall have a new
birth of freedom -- and that government of the people, by the people, for the
people, shall not perish from the earth.

Suggested Solutions to Selected Exercises and Programming Problems

1249

Section 42 Solutions
Section 42.1
42.1.1. Try XC

*,=X 0 1 . The XC instruction changes alternately into OC, XC, OC, ....

Similarly, XI *,1 alternates between OI, XI, OI, ....


What property of these two pairs of opcodes makes this possible?
You will of course remember that modifying instructions is a very poor practice that slows execution considerably, and
makes the program non-reenterable. +
Section 42.2
42.2.1. By convention, GR15 must contain the entry point address when entering a subprogram. The entry point
address is used as a base address for any instructions (particularly in the macro expansions) that must be resolved
using base-displacement addressing.
42.2.3. You can see that the GETMAIN macro generates a BAL instruction that requires base-displacement resolution.
The FREEMAIN macro generates a LA instruction with explicit operands. All the other instructions either address the
WA DSect using GR13 as a base register, or use relative addressing within the RSect. Thus, the earliest position for the
D E O P 3 statement is immediately following the GETMAIN instruction.

Programming Problem 42.1


This factorial program was written to manage its own internal stack and call itself recursively.
FactA
CSect ,
*******************************************************************
* Evaluate N! recursively. The largest valid N is 12.
*
*******************************************************************
Using *,15
ST
14,Temp
Save return address
L
1,0(,1)
Get parameter address
L
1,0(,1)
Get N
ST
1,Temp+4
Save current value of N
ST
2,Temp+8
Save current value of GR2
L
2,StackPtr
Get stack pointer
AHI
2,12
Increment stack pointer
MVC
0(12,2),Temp
Save return address, N, GR2
ST
2,StackPtr
Save new stack pointer
CHI
1,1
Compare N to 1
JH
Recur
If greater, call again
LA
0,1
1 Factorial = 1
J
Exit
Return
*******************************************************************
Recur
BCTR 1,0
N-1
*
ST
1,Data
Save for recursive call
*
LA
1,DataPtr
Point to argument address
*
BASR 14,15
Call ourselves recursively
*
*******************************************************************
L
2,StackPtr
Retrieve stack pointer
L
1,4(,2)
Get value of N from call
MR
0,0
Form N*Fact(N-1)
LR
0,1
Form return value
*
Exit
L
2,StackPtr
Retrieve stack pointer
L
14,0(,2)
Get proper return address
AHI
2,-12
Decrement stack pointer
ST
2,StackPtr
Save updated stack top pointer
L
2,20(,2)
Restore caller s GR2

Doing things like that could also endanger your job security.

1250

Assembler Language Programming for IBM z System Servers

Version 1.00

*
Temp
Data
DataPtr
StackPtr
Stack

BR

14

Return to caller

DS
DC
DC
DC
DC
End

2F
F 0
A(Data)
A(Stack-8)
(13*3)F 0

Word 1 = return addr, Word 2 = N


Value of N for call
Address of data item for call
Initial stack pointer
Fact(13) is too big, anyway

This is a calling program:


CallFac

Test

AF
AP
Value
LinePos
LineN
LineFac
LineLen
Line

CSect ,
Using *,12
LR
12,15
LA
5,12
ST
5,Value
ConvertO 5,LineN
LA
1,AP
L
15,AF
BASR 14,15
ConvertO 0,LineFac
PrintLin Line,Linelen
JCT
5,Test
Printout *,Header=No
DC
V(FactA)
DC
A(Value)
DS
F
DS
DC
DC
DC
Equ
Org
DS
Drop
End

0C
CL12
C factorial =
Cl12
(*-Line)
LinePos
0CL(LineLen)
12

Establish addressability
Copy base register
Max N that fits in a fullword = 12!
Store N for call
Convert N to characters
Point to argument list
Address of factorial routine
Call it
Convert result to characters
Print the result
Reduce N by 1 and repeat
Terminate caller
Address of factorial routine
Address of N
Argument N
Position of the output line
Carriage control, Value of N
Value of N factorial
Line Length
Step back to line position
Define symbolic output line length

The output from this program is:


12
11
10
9
8
7
6
5
4
3
2
1

factorial
factorial
factorial
factorial
factorial
factorial
factorial
factorial
factorial
factorial
factorial
factorial

=
=
=
=
=
=
=
=
=
=
=
=

479001600
39916800
3628800
362880
40320
5040
720
120
24
6
2
1

Programming Problem 42.3


Mine created a storage protection error for a very remote address.

Suggested Solutions to Selected Exercises and Programming Problems

1251

1252

Assembler Language Programming for IBM z System Servers

Version 1.00

Index
Special Characters

apostrophe
in attribute reference 106
in C-type constants 152
in self-defining terms 88
minus sign
in expressions 99
negation operator 14
unary 99
_ underscore
in symbols 91
/ slash, solidus
division operator 15
in expressions 99
( ) parentheses
address constant delimiters 149
in expressions 99
product sign
multiplication operation 15
@ at sign
in symbols 91
non-invariant character 431
bullet character
representation of blank
character 15
representation of space
character 15
$ dollar sign
$$GENIO macro instruction
definition 1014
description 1008
in symbols 91
non-invariant character 431
* asterisk
in expressions 99
location counter reference 99
multiplication operator 99
*PROCESS statement 1035
& ampersand
in C-type constants 152
in self-defining terms 88
# hash, sharp, (US) pound sign
in symbols 91
non-invariant character 431
+ plus sign
addition operator 14
in expressions 99
unary 99
= equal sign
literal indicator 156
| | vertical bars
absolute value operator 15
quotient sign
division operation 15

A
A machine instruction 218
A-type address constant
definition 853

ABEND macro instruction 942, 962


abnormal termination 957
ABEND macro instruction 942,
957
any kind 961
memory dump 942
ABS
absolute value operator 15
absolute implied address 133
absolute USING location 132
access exception 59
access register 50
ACONTROL assembler
instruction 1035
definition 1025
AD machine instruction 593
ADATA assembler option 91
ADB machine instruction 648
ADBR machine instruction 648
adcon
See also address constant
definition 1025
addend
definition 238, 1025
addition
binary floating-point 648
decimal floating-point 689
fixed-point binary 218
fixed-point binary integers 33
floating-point 565
hexadecimal floating-point 592,
598, 599
complement addition 601
process 598, 599
immediate 322
logical 225
packed decimal 478
packed decimal operand order
dependence 479
packed decimal process 484
register-immediate 322
with carry 229
address 94
assembly time 1025
definition 1025
execution time 94, 1025
location 1025
vs. location 94
address constant
definition 160, 851, 1025
delimited by parentheses 149
expression as nominal value 149
S-type 151
type A 149
type AD 159
type V 806
type Y 151
address generation 302
base-displacement addressing 64
execution time 118
relative-immediate 302, 304

address generation (continued)


signed 20-bit displacement 302
unsigned 12-bit displacement 64,
302
address resolution
addressable 128
addressing halfword 1025
base-displacement form 128
definition 1025
displacement 125
DSECT 858
explicit address 121
highest-numbered register 130
implied address 122, 128
implied addresses 1025
multiple 129
qualified symbol 866
relocation attribute 128
rules 134, 303
signed 20-bit displacement 303
smallest displacement 130
unsigned 12-bit displacement 64
valid displacement 128
address table 903
definition 930, 1025
address translation 69
D A T 69
definition 71, 1025
virtual address 69
address vs. location
execution vs. assembly time 94
addressability 68, 134
definition 71, 136, 1026
error 131
definition 136
addressable
assembly time 1025
base-displacement
resolution 1025
definition 1025
execution time 1025
resolution 1025
addressing
addressability 68
base address 64
base register 64
base-displacement addressing 64,
1027
base-displacement format 1027
Effective Address 64
Effective Address Register 64
in large programs 776
index 65
indexed Effective Address 66
internal subroutine 784
mode 306
not addressable 68
relative-immediate 304
with address constants 779
without local addressability 783
addressing halfword 55, 64

Index

1253

addressing halfword (continued)


base register specification digit 64
definition 71, 1026
signed 20-bit displacement 302
unsigned 12-bit displacement 64
addressing mode 306
24-bit 306
31-bit 306
64-bit 306
address generation 306
A M O D E 813
AMODE assembler
instruction 813
entry symbols 836
ADR machine instruction 593
ADTR machine instruction 687
ADTRA machine instruction 687
AE machine instruction 593
AEB machine instruction 648
AEBR machine instruction 648
AER machine instruction 593
AFI machine instruction 322
AG machine instruction 218
AGF machine instruction 231
AGFI machine instruction 322
AGFR machine instruction 231
AGHI machine instruction 322
AGR machine instruction 218
AH machine instruction 218
AHI machine instruction 322
AL machine instruction 225
ALC machine instruction 230
ALCG machine instruction 230
ALCGR machine instruction 230
ALCR machine instruction 230
ALFI machine instruction 322
ALG machine instruction 225
ALGF machine instruction 231
ALGFI machine instruction 322
ALGFR machine instruction 231
algorithm
definition 16, 1026
ALGR machine instruction 225
ALIAS assembler instruction
external symbol renaming 1030
alignment 46
automatic 142
by CNOP 210
by NOALIGN option 141
by ORG 169
by SECTALGN option 141
CNOP and SECTALGN 795
DC and SECTALGN 795
doubleword 46
DS and SECTALGN 795
fullword 46
halfword 46
implied length 142
instructions 52
ORG and SECTALGN 795
quadword 46
SECTALGN option 795
word 46
ALR machine instruction 225
AMODE

1254

A M O D E (continued)
definition 853
AMODE assembler instruction
See addressing mode
ampersand
in C-type constants 152
in self-defining terms 88
anchor
base location 1026
base register 1026
definition 1026
AND operation 289, 299, 1026
definition 299, 1026
OR operation
definition 299
register-immediate 324
register-register 290
storage-immediate 356
storage-storage 378
AP machine instruction 489, 493
apostrophe
in C-type constants 152
in self-defining terms 88
AR machine instruction 218
architecture
definition 16, 1026
argument 751
definition 774, 1026
argument address list 752
argument passing 745
arithmetic
binary addition 33
binary division 274
binary floating-point special
values 634
binary multiplication 265
binary subtraction 34
decimal floating-point 687
double-length shift 252
hexadecimal floating-point 578
packed decimal 477
packed decimal addition 484
packed decimal arithmetic
rules 477
packed decimal subtraction 486
real vs. realistic floating-point arithmetic 731
scaled packed decimal 513
general rules 513
shifts 252
single-length shift 252
arithmetic division
definition 284, 1026
process 280
arithmetic multiplication
definition 284, 1026
process 272
arithmetic representation 30
definition 41, 1026
arithmetic shift
definition 261, 1026
process 244
array 894
address table 903
as a list of items 894

Assembler Language Programming for IBM z System Servers

Version 1.00

array (continued)
as a table 900
binary search 906
column order 896
definition 930, 1026
general subscripts 899
multi-dimensional 899
non-homogeneous 900
one-dimensional 894
row order 896
search 905
subscripting function 897
two-dimensional 896
ASCII
C-type constant 153
CA-type constant 159
numeric character 456, 472
definition 1026
pack 472
representation 432
table 999
translation 433
unpack 473
Assembler
definition 16, 84, 1026
input record fixed length 77
assembler instruction
CSECT 82
E N D 82
ORG
extended syntax 170
START 82
assembler instruction statement 76
ACONTROL 1025
A M O D E 813
CNOP 210
COM 789
CSECT 789
CSECT and LOCTR 797
D C 139
D R O P 130, 867, 874, 890
DS 161
DSECT 789, 858
D X D 789
E N T R Y 807
EQU 95, 164
E X T R N 804
difference from WXTRN 806
LOCTR 796
LOCTR and CSECT 797
L T O R G 158
O R G 169
R M O D E 813
RSECT 789, 969
START 789
TITLE 80
USING 122, 128, 866, 869, 875
W X T R N 804
difference from EXTRN 806
Assembler Language
definition 16, 1026
assembler option 135
*PROCESS statement 1035
ACONTROL assembler
instruction 1035

assembler option (continued)


ADATA 91
C ODE PAG E 439
COMPAT(TRANSDT) 90, 433
DBCS 435
G O F F 795, 835, 840
NOALIGN 141
N O T H R E A D 796, 1224
R E N T 969
SECTALGN 141, 158, 795
TEST 91
TRANSLATE 90, 160, 433
USING(MAP) 135
assembly
External Symbol Dictionary 95
input records 77
invocation 74
location counter vs. instruction
address 94
object code 75
process 74
pass 1 125
pass 2 127
separate 788
statements 75
assembly time 76
definition 84, 1026
location 94
assisted linkage 770, 833
V-type address constant 806
attribute
assembler 168
definition 1026
integer 92
length 92, 145
program 140, 168
reference 92
relocation 92, 127
scale 92, 461
type 92
value 92, 127
attribute reference
definition 1026
integer 98
length 98, 157
scale 98
to literals 157
augend
definition 238, 1026
AXBR machine instruction 648
AXR machine instruction 593
AXTR machine instruction 687
AXTRA machine instruction 687

B
B extended mnemonic 212
B-tree 926
definition 931, 1026
BAS machine instruction 744
base address 119, 128
definition 71, 1027
displacement 1027
effective address 1027
general purpose register 1027

base digit 64
See also base register specification
digit
definition 1027
base location
base-displacement address resolution 1027
definition 1027
dependent USING
statement 1027
displacement 1027
in USING assembler
instruction 128
ordinary USING statement 1027
base register 64, 122
definition 71, 1027
base register specification digit 64,
111
definition 71, 1027
base register zero 133
base-displacement addressing 64
definition 1027
base_location 122
absolute 132
definition 136
base_register
definition 136
BASR machine instruction 118, 744
BASSM machine instruction 844
BC machine instruction 206, 207
BCD representation 429
BCR machine instruction 206, 207
BCT machine instruction 335
BCTG machine instruction 335
BCTGR machine instruction 335
BCTR machine instruction 335
BE extended mnemonic 213
BEAR 214
begin column 77
BER extended mnemonic 213
BH extended mnemonic 213
BHR extended mnemonic 213
bias 562, 571
definition 572, 1027
exponent 571
rounding 562
Big-Endian 448
binary
floating-point 625
integer addition 33
integer subtraction 34
overflow detection recipe 33
shift 242
subtraction recipe 37
two s complementation recipe 29
binary digit
See bit
binary floating-point
addition 648
characteristic 626
reserved values 627
compare and signal 650
comparison 649
constant 630, 631, 632
length modifier 632
modifiers 631, 632

binary floating-point (continued)


constant (continued)
rounding-mode suffix 630
special values 630
type DB 629
type EB 629
type LB 629
convert to decimal floating-point
and hexadecimal
floating-point 729
converting from integer 653
converting to integer 653
data classes
denormalized numbers 626
infinity 626
normal numbers 626
quiet NaN 626
signaling NaN 626
zero 626
Data Exception Code 637
data formats 625
decimal exponent 631
definition 1027
divide to integer 656
division 646
division by zero 636
exception handling 636
exponent field width 626
exponent modifier 631
exponent overflow 636
exponent underflow 636
floating-point integer 655
inexact result 636
infinity 628
invalid operation 635
lengthening instructions 651
multiplication 644
multiply and add/subtract 659
NaN (Not a Number) 626, 627
payload 631
quiet 628
signaling 628
overview 633
arithmetic with special
values 634
denormalized numbers 634
exceptions 635
rounding modes 633
remainder 655
representation 626
representation range 628
rounding instructions 651
set rounding mode 638
signed zero 735
significand 626
special values 626, 627
denormalized numbers 627
infinity 627
N a N 627
square root 658
subtraction 648
test data class 640
binary search 906
definition 930, 1027
binary tree 922

Index

1255

binary tree (continued)


definition 930, 1027
bind time
after assembly time 1027
before execution time 1027
definition 1027
Binder 835
definition 1027
bit 21
data 360
definition 41, 1027
invert 356
naming problems 361
reset 356
set 356
test 358
bit bucket 244
bit-length constant 259
BL extended mnemonic 213
blank
definition 17, 1027
in constants 149, 152
not in self-defining terms 149, 152
representation in examples 15
text representation 17, 1027
Blefuscu 448
block comments 78
blocked records 953
BLR extended mnemonic 213
BM extended mnemonic 213
BMR extended mnemonic 213
BNE extended mnemonic 213
BNER extended mnemonic 213
BNH extended mnemonic 212
BNHR extended mnemonic 212
BNL extended mnemonic 212
BNLR extended mnemonic 212
BNM extended mnemonic 212
BNMR extended mnemonic 212
BNO extended mnemonic 212
BNOR extended mnemonic 212
BNP extended mnemonic 212
BNPR extended mnemonic 212
BNZ extended mnemonic 213
BNZR extended mnemonic 213
BO extended mnemonic 213
Boolean operations 288
BOR extended mnemonic 213
boundary alignment
See also alignment
by CNOP instruction 210
by DC/DS instruction 141
by ORG instruction 170
definition 147, 1027
BP extended mnemonic 213
BPR extended mnemonic 213
BR extended mnemonic 212
branch address 206, 305
and execute instruction 390
definition 215, 1027
branch condition 206
definition 215, 1027
branch mask 207
definition 215, 1027
branch relative 330

1256

branch relative (continued)


and execute instruction 394
and save 744
extended mnemonics 331
in place of branch on
condition 331
on condition 330
on count 335
on index 342
BRAS machine instruction 744
BRASL machine instruction 744
BRC extended mnemonic 331
BRCT machine instruction 335
BRCTG machine instruction 335
BRE extended mnemonic 331
Breaking Event Address
Register 214
BREL extended mnemonic 331
BRH extended mnemonic 331
BRHL extended mnemonic 331
BRL extended mnemonic 331
BRLL extended mnemonic 331
BRM extended mnemonic 331
BRML extended mnemonic 331
BRNE extended mnemonic 331
BRNEL extended mnemonic 331
BRNH extended mnemonic 331
BRNHL extended mnemonic 331
BRNL extended mnemonic 331
BRNLL extended mnemonic 331
BRNM extended mnemonic 331
BRNML extended mnemonic 331
BRNO extended mnemonic 331
BRNOL extended mnemonic 331
BRNP extended mnemonic 331
BRNPL extended mnemonic 331
BRNZ extended mnemonic 331
BRNZL extended mnemonic 331
BRO extended mnemonic 331
BROL extended mnemonic 331
BRP extended mnemonic 331
BRPL extended mnemonic 331
BRU extended mnemonic 331
BRUL extended mnemonic 331
BRXH machine instruction 342
BRXHG machine instruction 342
BRXLE machine instruction 342
BRXLG machine instruction 342
BRZ extended mnemonic 331
BRZL extended mnemonic 331
BSM machine instruction 844
BXH machine instruction 342
BXHG machine instruction 342
BXLE machine instruction 342
BXLEG machine instruction 342
byte 45
bit numbering 45
definition 50, 1027
memory address 45
byte reversal 449
BZ extended mnemonic 213
BZR extended mnemonic 213

Assembler Language Programming for IBM z System Servers

Version 1.00

C
C machine instruction 223
C-string 415
calling point identifier 764
definition 774, 1027
CC
See Condition Code
CD machine instruction 602
CDB machine instruction 649
CDBR machine instruction 649
CDFBR machine instruction 653
CDFR machine instruction 606
CDGBR machine instruction 653
CDGR machine instruction 606
CDGTR machine instruction 693
CDGTRA machine instruction 693
CDR machine instruction 602
CDSTR machine instruction 696
CDTR machine instruction 691
CDUTR machine instruction 697
CDXT machine instruction 699
CDZT machine instruction 699
CE machine instruction 602
CEB machine instruction 649
CEBR machine instruction 649
CEDTR machine instruction 692
CEFBR machine instruction 653
CEFR machine instruction 606
CEGBR machine instruction 653
CEGR machine instruction 606
central processing unit (CPU) 44
access register 50
Condition Code 49
control register 50
definition 50, 1028
floating-point register 48
general register 47
general register pair 48
Instruction Address 49
Program Mask 49
Program Status Word 49
CER machine instruction 602
CEXTR machine instruction 692
CFDBR machine instruction 653
CFDR machine instruction 606
CFEBR machine instruction 653
CFER machine instruction 606
CFI machine instruction 323
CFXBR machine instruction 653
CFXR machine instruction 606
CG machine instruction 223
CGDBR machine instruction 653
CGDR machine instruction 606
CGDTR machine instruction 693
CGDTRA machine instruction 693
CGEBR machine instruction 653
CGER machine instruction 606
CGF machine instruction 231
CGFI machine instruction 323
CGFR machine instruction 231
CGHI machine instruction 323
CGR machine instruction 223
CGXBR machine instruction 653
CGXR machine instruction 606

CGXTR machine instruction 693


CGXTRA machine instruction 693
CH machine instruction 223
character
ASCII 432
BCD 429
C-string 415
decimal floating-point 674
double-byte EBCDIC 433
EBCDIC 430
glyph 438
not allowed in symbols 91
representation
ASCII 159, 999
EBCDIC 89, 998
Unicode 437
shift-in 433
shift-out 433
Unicode 437
characteristic
binary floating-point 626
decimal floating-point 674
definition 572, 1027
floating-point 571
hexadecimal floating-point 573
CHI machine instruction 323
CHY machine instruction 223
CL machine instruction 233
class
definition 851, 852, 1027
class name 1030
CLC machine instruction 367, 379
CLCL machine instruction 404, 408
CLCLE machine instruction 404,
414
CLCLU machine instruction 440,
442
CLFI machine instruction 323
CLG machine instruction 233
CLGF machine instruction 233
CLGFI machine instruction 323
CLGFR machine instruction 233
CLGR machine instruction 233
CLI machine instruction 356
CLIY machine instruction 356
CLM machine instruction 233
CLMH machine instruction 233
CLMY machine instruction 233
CLOSE macro instruction 955
CLR machine instruction 233
CLST machine instruction 416, 420
CNOP assembler instruction 210
definition 1028
CNOP instruction
definition 215
code
definition 86, 1027
CODEPAGE assembler option 439
coefficient 673
cohort 669
definition 723, 1027
column order 896
definition 930, 1027
column-major order
definition 1028

COM assembler instruction 789,


1028
combination field 673, 674
comment statement 76
common
definition 851, 1028
common section 789, 1030
COM assembler instruction 1028
definition 1028
comparison
binary floating-point 649, 650
decimal floating-point 691
decimal floating-point biased exponent 692
fixed-point arithmetic 223
fixed-point logical 233
hexadecimal floating-point 602
packed decimal 496
register-immediate 323
storage-immediate 356
storage-storage 379
COMPAT(TRANSDT) assembler
option 90, 433
complement addition
hexadecimal floating-point 600,
601
process 600
packed decimal 486
complementation
fixed-point overflow 30
complex relocatability 101
definition 101, 106
term
symbol attribute reference 106
complex relocatability attribute 135
COND= in macro operand 946
Condition Code 49, 235
definition 51
retrieve/set 235
conditional assembly
conditional assembly
language 1028
definition 1028
conditional no-operation 209
definition 215, 1028
constant
address constant 149
alignment 139
all types 1000
ASCII 432
translation 433
binary 152
binary floating-point
decimal exponent 631
exponent modifier 631
length modifier 632
rounding-mode suffix 630
type DB 629
type EB 629
type LB 629
binary floating-point symbolic
operand
(DMin) 630
(Inf) 630
(Max) 630
(Min) 630

constant (continued)
binary floating-point symbolic
operand (continued)
(NaN) 630
(QNaN) 630
(SNaN) 630
bit-length 259
boundary alignment 141
character 152
type C 159
type CA 159
type CE 159
type CU 159
DBCS 435
decimal exponent 145, 577, 631,
678
decimal floating-point 676
rounding-mode suffix 677
type DD 676
type ED 676
type LD 676
decimal floating-point symbolic
operand
(DMin) 676
(Inf) 676
(Max) 676
(Min) 676
(NaN) 676
(QNaN) 676
(SNaN) 676
duplication factor 143
embedded blanks 149, 152
exponent modifier 146, 580, 631,
678
fixed-point binary 148, 149
unsigned 149
floating-point
summary 728
hexadecimal 152
hexadecimal floating-point 577,
582
decimal exponent 578
exponent modifier 580
length modifier 579
padding 579
rounding mode suffix 582
scale modifier 579
truncation 579
type D 577
type DH 577
type E 577
type EH 577
type L 577
type LH 577
type LQ 581
hexadecimal floating-point symbolic operand
(DMin) 582
(Max) 582
(Min) 582
length 139
length attribute 145
length modifier 142
literal 156
location-counter dependent 174

Index

1257

constant (continued)
multiple values 144
nominal value 139
offset 825
Q-type 825
packed decimal 461
padding 154
program modifier 140
Q-type 825
rounding-mode suffix
summary 728
S-type 151
scaled fixed-point binary 545
truncation 154
type 139
type A 149
type AD 159
type B 152
type C 152
ASCII characters 159
EBCDIC characters 152
Unicode characters 159
type CA 159
type CE 159
type CU 159
type D 554
type DB 554
type DD 554
type DH 554, 581
type E 554
type EB 554
type ED 554
type EH 554, 581
type extension 159
type F 148
type FD 148, 159
type H 148
type HD 148
type L 554
type LB 554
type LD 554
type LH 554, 581
type LQ 581
type S 151
type V 806
type X 152
type Y 151
Unicode 439
unsigned binary 149
vs. self-defining term 152
zero duplication factor 162
zoned decimal 458
constant modifiers 140
constant type 140
definition 147, 1028
continue column 77
control register 50
control section 788
blank 812
COM 789
common control section 1028
CSECT 789, 1028
definition 1028
DSECT assembler
instruction 789

1258

control section (continued)


dummy control section 856
D X D 789
executable 789
literals 794
ordinary control section 1028
Private Code 812
reference 789
resuming 793
RSECT 789, 1028
START 789
conversion
among floating-point types 729
BCD to declet 672
between arbitrary bases 21
between binary and
hexadecimal 20
between decimal and binary 22
between packed and zoned
decimal 463
binary floating-point to
integer 653
decimal floating-point to
integer 694
decimal floating-point to signed
packed decimal 696
decimal floating-point to unsigned
packed decimal 697
declet to BCD 672
fractions between bases 541
hexadecimal floating-point to
integer 608
hexadecimal floating-point truncation 607
In-Out 729
integer to binary
floating-point 653
integer to decimal
floating-point 693
integer to hexadecimal floatingpoint 607
Out-In 730
signed packed decimal to decimal
floating-point 696
unsigned packed decimal to
decimal floating-point 697
CONVERTI macro instruction 1003
definition 1011
description 1003
CONVERTO macro
instruction 1003
definition 1011
description 1003
CP machine instruction 489, 496
CPSDR machine instruction 557,
686
CR machine instruction 223
CSDTR machine instruction 696
CSECT
definition 1028
CSECT assembler instruction 789
CSECT instruction 789
CSXTR machine instruction 696
CU12 machine instruction 447
CU14 machine instruction 447

Assembler Language Programming for IBM z System Servers

Version 1.00

CU21 machine instruction 447


CU24 machine instruction 447
CU41 machine instruction 447
CU42 machine instruction 447
CUDTR machine instruction 697
CUSE machine instruction 416, 424
CUTFU machine instruction 447
CUUTF machine instruction 447
CUXTR machine instruction 697
CVB machine instruction 522, 524
CVBG machine instruction 522, 524
CVBY machine instruction 522, 524
CVD machine instruction 522
CVDG machine instruction 522, 523
CVDY machine instruction 522
CXBR machine instruction 649
CXD-type address constant
definition 853, 1028
CXFBR machine instruction 653
CXFR machine instruction 606
CXGR machine instruction 606
CXGTR machine instruction 693
CXGTRA machine instruction 693
CXR machine instruction 602
CXSTR machine instruction 696
CXTR machine instruction 691
CXUTR machine instruction 697
CY machine instruction 223
CZDT machine instruction 699
CZXT machine instruction 699

D
D machine instruction 274, 275
D A T 69
See also address translation
Dynamic Address Translation 69
data
access method 949
access technique 951
BDW 954
BLKSIZE 953
block descriptor word 954
blocked records 953
BPAM 952
BSAM 951
Data Control Block 952
Data Definition Name 948
Data Set Name 947
DCB 952, 953
DCB macro 952
DCBD macro 955
DCBE macro 956
D D N a m e 948
direct access 956
DSName 947
D S O R G 952
E O D A D 953
EXLST 953
fixed length records 953
FREEPOOL macro 955
IHADCB dummy section 955
indexed access 956
JFCB 948
Job File Control Block 948

data (continued)
LRECL 953
M A C R F 952
Partitioned Organization 952
QSAM 951, 952
R D W 954
R E C F M 953
record descriptor word 954
record formats 954
sequential access 951, 956
undefined length records 953
variable length records 953
VSAM 956
Data Control Block 948
data exception 59
Data Exception Code 637
binary floating-point
divide by zero 637
inexact 637
invalid operation 637
underflow 637
decimal floating-point
divide by zero 685
inexact 685
instruction availability 685
invalid operation 685
quantum exception 685
underflow 685
data groups
decimal floating-point 712
data structure
array 894
B-tree 926
doubly-linked list 919
DSECT 859
free storage list 915
hash table 927
list 913
mapping identical structures 880
mapping with DSECT 859
queue 919
stack 908, 910
tree 922
tree search 926
DBCS 433
constant 435
continuation rules 436
self-defining term 435
shift-in character 433
shift-out character 433
ward 434
DBCS assembler option 435
DC assembler instruction 139
DC statement 140
alignment 148
operands 140
delimiters 140
duplication factor 140
modifiers 140
nominal value 140
type 140
DCB 948
DCB macro instruction 952
DCB
D S O R G 952
M A C R F 952

DCB macro instruction (continued)


Partitioned Organization
library member 952
DCBD macro instruction 955
IHADCB dummy section 955
DCBE macro instruction 956
DD machine instruction 590
DDB machine instruction 646
DDBR machine instruction 646
DDR machine instruction 590
DDTR machine instruction 687
DDTRA machine instruction 687
DE machine instruction 590
DEB machine instruction 646
DEBR machine instruction 646
decimal data exception 478
definition 1028
decimal divide exception 60, 483
definition 1028
decimal exponent 145
definition 147, 1028
fixed-point binary
type F 148
type FD 148
type H 148
type HD 148
in binary floating-point
constant 631
in decimal floating-point
constant 678
in fixed-point binary constant 145
in hexadecimal floating-point constant 578
decimal floating-point
addition/subtraction 689
binary-significand format 716
characteristic 674
coefficient 673
cohort 669
combination field 674
compare and signal 691
compare biased exponent 692
comparison 691
conceptual representation 669
constant 676
decimal exponent 678
exponent modifier 678
rounding-mode suffix 677
special values 676
type DD 676
type ED 676
type LD 676
convert BCD to declet 672
convert decimal floating-point to
integer 694
convert decimal floating-point to
signed packed decimal 696
convert decimal floating-point to
unsigned packed decimal 697
convert declet to BCD 672
convert integer to decimal floatingpoint 693
convert signed packed decimal to
decimal floating-point 696
convert to binary floating-point and
hexadecimal floating-point 729

decimal floating-point (continued)


convert unsigned packed decimal
to decimal floating-point 697
data classes
infinity 679
normal 679
QNaN 679
SNaN 679
subnormal 679
zero 679
data encoding 671
data formats 673
data groups 712
infinity or NaN 712
normal or subnormal, extreme
exponent 712
normal, non-extreme exponent,
nonzero leftmost digit 712
normal, non-extreme exponent,
zero leftmost digit 712
zero, extreme exponent 712
zero, non-extreme
exponent 712
declet 671
definition 1028
division 689
extract biased exponent 705
extract significance 706
floating-point integer 702
infinity 674
insert biased exponent 705
lengthening instructions 702
multiplication 688
NaN (Not a Number) 674
overview
exceptions 684
preferred encoding 672
preferred quantum 682
quantize 708
quantum 670
quantum exception 684
redundant representations 669
representation 673
options 668
properties 675
reround 710
rounding 681
rounding instructions 703
set rounding mode 704
shift significand 707
signed zero 735
significance of zero 735
test data class 679
test data group 712
ulp (unit in the last place) 670
zero 674
decimal overflow exception 60, 1028
definition 1028
decimal specification exception 481
definition 1028
declet 671
definition 724, 1028
defined symbol
definition 97, 1028
definition

Index

1259

definition (continued)
$$GENIO macro
instruction 1014
A-type address constant 853
absolute symbol 106, 1025
adcon 1025
addend 238, 1025
address constant 160, 851, 1025
address table 930, 1025
address translation 71, 1025
addressability 71, 136, 1026
addressability error 136, 1026
addressing halfword 71, 1026
addressing mode 315, 1026
algorithm 16, 1026
A M O D E 315, 853, 1026
AND operation 299, 1026
architecture 16, 1026
argument 774, 1026
arithmetic division 284, 1026
arithmetic multiplication 284,
1026
arithmetic representation 41,
1026
arithmetic shift 261, 1026
array 930, 1026
ASCII 1026
ASCII numeric character 1026
Assembler 16, 84, 1026
Assembler Language 16, 1026
assembly time 84, 1026
augend 238, 1026
B-tree 931, 1026
base 71, 1027
base address 71, 1027
base register 71, 1027
base register specification
digit 71, 1027
base_location 136
base_register 136
BEAR 1027
bias 572, 1027
binary floating-point 1027
binary search 930, 1027
binary tree 930, 1027
Binder 1027
bit 41, 1027
blank 17, 1027
boundary alignment 147, 1027
branch address 215, 1027
branch condition 215, 1027
branch mask 215, 1027
Breaking Event Address
Register 1027
byte 50, 1027
C-string 1028
calling point identifier 774, 1027
Central Processing Unit 50, 1028
characteristic 572, 1027
class 851, 852, 1027
CNOP assenbler instruction 1028
CNOP instruction 215
code 86, 1027
code page 1027
cohort 723, 1027

1260

definition (continued)
column order 930, 1027
column-major order 1028
common 851, 1028
comparand 351, 1028
complement decimal
addition 1028
complex relocatability 106
Condition Code 51
conditional no-operation 215,
1028
constant type 147, 1028
control section 1028
CONVERTI macro
instruction 1011
CONVERTO macro
instruction 1011
CSECT 1028
CXD-type address constant 853,
1028
Data Exception Code 665, 1028
DBCS 1028
decimal data exception 1028
decimal divide exception 1028
decimal exponent 147, 1028
decimal floating-point 1028
decimal overflow exception 1028
decimal specification
exception 1028
declet 724, 1028
defined symbol 97, 1028
denormalization 572, 1028
denormalized number 665, 1028
densely packed decimal 724,
1029
Dependent USING 891, 1029
destructive overlap 1029
DH displacement
component 315, 1029
digit selector 1029
digit selector and significance
starter 1037
diminished radix-complement representation 41, 1029
displacement 1029
20-bit 302
unsigned 12-bit 64
dividend 284, 1029
divisor 284, 1029
DL displacement component 315,
1029
Double-Byte Character Set 1028
double-ended queue 1029
doubly-linked list 930, 1029
D P D 724, 1029
DROP assembler instruction 135,
1029
DSECT assembler
instruction 891, 1029
DUMPOUT macro
instruction 1012
duplication factor 147, 1029
DXC (Data Exception
Code) 665, 1029
D X D 1029

Assembler Language Programming for IBM z System Servers

Version 1.00

definition (continued)
EBCDIC 97, 1029
Effective Address 71, 1029
Effective Address Register 71,
1029
element 852
Encoded Length 117, 1029
entry point 774, 1029
entry point identifier 774, 1029
EQU extended syntax 177, 1029
exception condition 62, 665,
1029, 1030
executable control section 852,
1029
execution time 85, 1030
explicit address 117, 1030
explicit length 117, 1030
exponent 559, 1030
exponent modifier 147, 1030
exponent overflow 572, 1030
exponent underflow 572, 1030
expression 106, 1030
expression evaluation 106, 1030
extended mnemonic 215, 1030
external dummy 852, 1035
External Dummy Section 1030
External Symbol Dictionary 851,
1030
extreme exponent 724, 1030
field separator 1030
fill character 1030
floating-point 559, 1030
Floating-Point Control
Register 664, 1030
Floating-Point Register 51, 1030
floating-point system FP(r,p) 559,
1030
floating-point system
FPF(r,p) 559, 1030
floating-point system
FPI(r,p) 559, 1030
free storage list 930, 1030
general register 51, 1031
G G n 204, 1031
G O F F 852
gradual underflow 665, 1031
graphic data type 1031
G R n 204, 1031
guard digit 572, 1031
hash function 931, 1031
hash table 931, 1031
hexadecimal 41, 1031
High Level Assembler 1031
HLASM 16, 1031
immediate operand 329, 1031
implied address 117, 1031
implied length 117, 1031
increment 351, 1031
index 71, 351, 1031
index register specification
digit 71, 1032
indexing 71, 1032
infix notation 931, 1032
inorder tree traversal 931, 1032
insert 204, 1032

definition (continued)
Instruction Address 1032
instruction decode 61, 1028
instruction execute 61
instruction fetch 61, 1030
Instruction Length Code 51, 1032
instruction register 61, 1032
interruptible 1032
interruption 62, 1032
invariant EBCDIC
character 1032
I R 1032
Job Control Language 86, 1032
Labeled Dependent USING 891,
1032
Labeled USING 891, 1032
LC 1033
length attribute reference 106,
1032
Length Expression 117, 1032
length modifier 147, 1032
Length Specification Digit 1033
linear subscript 930, 1033
linkage convention 774, 1033
linked list 930, 1033
Linker 85, 1033
linking loader 852, 1033
list 930, 1033
literal 160, 1033
literal pool 160, 1033
load module 85, 852, 1033
load operation 204, 1033
location counter (LC) 97, 1033
logical arithmetic 238, 1033
logical division 284, 1033
logical multiplication 284, 1033
logical representation 41, 1033
logical shift 261, 1033
machine language 62, 1033
machine length 117, 1033
macro instruction 85, 1033
mantissa 559, 1033
mask 664, 1033
mask digit 1033
MaxReal 572, 1034
MBCS 1034
message character 1034
millicode 51, 1034
MinReal 572, 1034
minuend 238, 1034
mnemonic 85, 117, 1034
modal instruction 315, 1034
modifier 147, 1034
Multiple-Byte Character Set 1034
multiplicand 284, 1034
multiplier 284, 1034
multiply and add/subtract 622,
1034
N (Number attribute
reference) 1034
N (Length Expression) 1034
NaN (Not a Number) 665, 1034
no-operation instruction 215,
1034
nominal value 147, 1034

definition (continued)
normalization 572, 1034
null byte 1034
numeric digit 1034
OBJ 852
object code 85, 1034
object module 85, 852, 1034
offset 1034
ones complement
representation 41, 1034
opcode 117, 1034
operand 85, 1034
operand order dependence 1034
operation code 62, 117, 1034
operator 17, 106, 1034
option 1035
OR operation 299, 1035
Ordinary USING 891, 1035
ORG extended syntax 177, 1035
origin 85, 1035
overflow 41, 1035
padding 160, 1035
parameter 774, 1035
parameterization 177, 1035
pattern character 1035
payload 724, 1035
pipeline 216, 1035
P M 1035
post-normalization 572, 1035
postfix notation 931, 1035
postorder tree traversal 931, 1035
pre-normalization 572, 1035
preferred exponent 724, 1035
preferred quantum 724, 1035
preorder tree traversal 931, 1035
PRINTLIN macro
instruction 1010
PRINTOUT macro
instruction 1012
problem state 51, 1035
program interruption 1035
program length 117, 1035
program linking 852
Program Loader 85, 1035
Program Mask 62, 1035
program object 852
Program Status Word 51, 1035
pseudoregister 852, 1035
Q-type address constant 853,
1035
QNaN 665, 1035
qualified symbol 891, 1035
qualifier 891, 1035
quantum 724, 1036
queue 930, 1036
quotient 284, 1036
R(r1 + 1) 1036
R(r3|1) 1036
radix 559, 1036
radix-complement
representation 41, 1036
READCARD macro
instruction 1010
real address 71, 1036
reference control section 852,
1036

definition (continued)
relative address 315, 1036
relocatable 97, 1036
relocate 852, 1036
relocating loader 852, 1036
relocation 85, 97, 852, 1036
relocation dictionary 851
remainder 284, 1036
return address 774, 1036
return code 774, 1036
R M O D E 853
rotating shift 261, 1036
rounding digit 572, 1036
rounding mode 665, 1036
rounding modifier 665, 1036
rounding-mode suffix 622, 1036
row order 930, 1037
row-major order 1037
RSECT 1037
SBCS 1037
section 852, 1037
segment 852
self-defining term 97, 1037
Shift-In 1037
Shift-Out 1037
sign extension 205, 1037
sign-magnitude representation 41,
1037
significance exception 622, 1037
significance indicator 1037
significance starter 1037
significand 559, 1037
simple relocatability 106, 1037
Single-Byte Character Set 1037
SNaN 665, 1037
space 17
special value 665, 1037
stack 930, 1037
statement 85, 1037
statement field 85, 1037
status flag 664, 1037
store operation 205, 1037
subtrahend 238, 1037
supervisor state 51, 1037
symbol 97, 1038
symbol attribute 97, 1038
symbol attribute reference 106,
1038
Symbol Table 136, 1038
table 930, 1038
target instruction 1038
term 106, 1038
text 852, 1038
true decimal addition 1038
truncation 160, 1038
two s complement 1038
two s complement
representation 41, 1038
type extension 160, 1038
UCS 1038
ulp (unit in the last place) 572,
1038
Unicode 1038
Unicode numeric character 1038
Unicode Transformation
Format 1038

Index

1261

definition (continued)
Universal Character Set 1038
unnormalized add/subtract 622,
1038
unsigned 12-bit displacement 71
USING assembler
instruction 135, 1038
USING Table 135, 1038
U T F 1038
V-type address constant 853
virtual address 71, 1038
virtual origin 930, 1038
XOR operation 299, 1038
zero duplication factor 177, 1038
zero extension 205, 1038
zone digit 1038, 1039
denormalization 634
definition 572, 1028
denormalized numbers 626
binary floating-point 634
densely packed decimal
definition 724, 1029
dependent USING 869, 889
anchor 1029
complex structures 869
definition 891, 1029
DROP assembler instruction 874
DER machine instruction 590
DIDBR machine instruction 656
DIEBR machine instruction 656
digit selector 526
definition 1029
digit selector and significance
starter 526
definition 1037
diminished radix-complement representation 26
definition 41, 1029
discontinuity
Location Counter 794
displacement 64
20-bit 302
addressing halfword 1029
definition 71, 1029
unsigned 12-bit 64
dividend
binary division
by shifting 253
definition 284, 1029
fixed-point binary division 274
packed decimal 483
division
arithmetic 275
binary floating-point 646
decimal floating-point 689
double-length 275
fixed-point 274
fixed-point binary process 280
Fixed-Point Divide
Exception 274
floating-point 564
hexadecimal floating-point 590
logical 279
packed decimal 483, 500
register pair 274

1262

division (continued)
single-length 278
divisor
definition 284, 1029
fixed-point binary division 274
packed decimal 483
DL machine instruction 274, 279
DLG machine instruction 274, 279
DLGR machine instruction 274, 279
DLR machine instruction 274, 279
double-byte EBCDIC 433
shift-in 433
shift-out 433
ward 434
double-ended queue
definition 1029
doubleword 46, 179
doubly-linked list 919
definition 930, 1029
DP machine instruction 489, 500
DPD
definition 724, 1029
DR machine instruction 274, 275
DROP assembler instruction 130,
867, 874, 890
definition 135, 1029
dependent USING 874, 890
labeled dependent USING 890
labeled USING 867, 890
ordinary USING 130, 890
summary 890
DS assembler instruction 161
DSECT assembler instruction 789,
856, 858
address resolution 858
as External Dummy Section 824
DCBD 955
definition 891, 1029
EPIE 960
Location Counter 857
multiple data structures 859
named in Q-type address
constant 824
relocation attribute 857
DSG machine instruction 274, 275
DSGF machine instruction 275
DSGFR machine instruction 275
DSGR machine instruction 274, 275
Dummy Control Section
See DSECT assembler instruction
dummy external section 1030
DUMPOUT macro instruction 1006
definition 1012
description 1006
duplicate definition 125
duplication factor 140
default 140
definition 147, 1029
DXBR machine instruction 646
DXC 636
DXD assembler instruction 789
DXR machine instruction 590
DXTR machine instruction 687
DXTRA machine instruction 687

Assembler Language Programming for IBM z System Servers

Version 1.00

E
EBCDIC 430, 433
C-type constants 152
code pages 430
definition 97, 1029
double-byte 433
in character self-defining terms 88
table 998
ED machine instruction 522, 528
editing 526
flow diagram 536
overview 526
pattern 526
process 529
zoned digit 536
EDMK machine instruction 522,
533
EEDTR machine instruction 705
EEXTR machine instruction 705
Effective Address 64
24-bit addressing mode 307
31-bit addressing mode 307
64-bit addressing mode 307
definition 71, 1029
relative-immediate 304
signed 20-bit displacement 302
unsigned 12-bit displacement 302
Effective Address Register 64
definition 71, 1029
EFPC machine instruction 638
element
definition 852
Encoded length 368
definition 117, 1029
Length Specification Byte 368
machine length 368
end column 77
END record in object module 818
ENTRY assembler instruction 807,
1030
entry point 751
definition 774, 1029
entry point identifier 763
definition 774, 1029
EPICA
See Program Interruption Control
Area
EPIE
See Program Interruption Element
EQU assembler instruction 95, 164
extended syntax 168, 1029
definition 177
ESD record in object module 817
CM symbol type 812
CQ symbol type 812
ER symbol type 812
LD symbol type 812
PC symbol type 812
PQ symbol type 812
SD symbol type 812
SQ symbol type 812
WX symbol type 812
XD symbol type 812
ESDID 804

ESDTR machine instruction 706


ESPIE macro instruction 958
program interruption exit 958
ESTAE macro
recovery routine 962
retry routine 962
ESTAE macro instruction 962, 963
ESTAEX macro instruction 962
ESXTR machine instruction 706
EX machine instruction 390
exception 59
binary floating-point 636
division by zero 635
exponent overflow 635
exponent underflow 635
inexact result 635
invalid operation 635
signaling NaN 628
decimal floating-point
divide by zero 685
inexact 685
instruction availability 685
invalid operation 685
quantum 684, 685
underflow 685
hexadecimal floating-point
division by zero 590
exponent overflow 589
exponent underflow 589
lost significance 594
exception action
binary floating-point
divide by zero 638
exponent overflow 639
exponent underflow 639
inexact result 639
invalid operation 638
exception condition 60
definition 62, 1029
interruption if enabled 60
executable control section 789
CSECT 789
definition 852, 1029
RSECT 789
START 789
execute exception 59
execute instructions 390
execution time 76
address 94
definition 85, 1030
explicit address 111, 112, 370
definition 117, 1030
explicit length 115, 370
definition 117, 1030
in constants 142
exponent
binary floating-point 626
decimal floating-point 674
definition 559, 1030
hexadecimal floating-point 573
exponent modifier 145
binary floating-point constant 631
decimal floating-point
constant 678
definition 147, 1030

exponent modifier (continued)


hexadecimal floating-point
constant 580
exponent overflow 569
binary floating-point 636
definition 572, 1030
hexadecimal floating-point 589
exponent underflow 569
binary floating-point 636
definition 572, 1030
hexadecimal floating-point 589
expression 99
absolute 101
complexly relocatable 101
definition 106, 1030
evaluation 100, 105
definition 106
factor 105
operator
99
/ 99
* 99
+ 99
unary 99
unary + 99
operator precedence 100
paired terms 101
parentheses 99
primary 105
products 100
quotients 100
relocatable terms 100
simply relocatable 101
term 106
unpaired term 101
EXRL machine instruction 390
extended mnemonic 212
B 212
BE 213
BER 213
BH 213
B H R 213
BL 213
BLR 213
BM 213
B M R 213
BNE 213
BNER 213
BNH 212
B N H R 212
BNL 212
BNLR 212
BNM 212
B N M R 212
BNO 212
BNOR 212
BNP 212
BNPR 212
BNZ 213
BNZR 213
BO 213
BOR 213
BP 213
BPR 213
BR 212

extended mnemonic (continued)


BRC 331
BRE 331
BREL 331
B R H 331
BRHL 331
BRL 331
BRLL 331
B R M 331
BRML 331
BRNE 331
BRNEL 331
B R N H 331
B R N H L 331
BRNL 331
BRNLL 331
B R N M 331
B R N M L 331
BRNO 331
BRNOL 331
BRNP 331
BRNPL 331
BRNZ 331
BRNZL 331
BRO 331
BROL 331
BRP 331
BRPL 331
BRU 331
BRUL 331
BRZ 331
BRZL 331
BZ 213
BZR 213
definition 215, 1030
J 331
JC 331
JCT 335
JCTG 335
JE 331
J H 331
JL 331
JLC 331
JLE 331
J L H 331
JLL 331
J L M 331
JLNE 331
J L N H 331
JLNL 331
J L N M 331
JLNO 331
JLNOP 331
JLNP 331
JLNZ 331
JLO 331
JLP 331
JLU 331
JLZ 331
J M 331
JNE 331
J N H 331
JNL 331
J N M 331
JNO 331

Index

1263

extended mnemonic (continued)


JNOP 331
JNP 331
JNZ 331
JO 331
JP 331
jump instructions 331
J X H 344
J X H G 344
JXLE 344
JXLEG 344
JZ 331
NOP 208, 213
N O P R 208, 213
extended save area conventions 759
external dummy section 789
definition 852, 1035
External Dummy Section.
definition 1030
external symbol 804, 1030
ALIAS assembler
instruction 1030
class name 1030
COM 804
common section 1030
control section name 1030
CSECT 804
definition 1030
DSECT
named in Q-type address constant 824
DSECT assembler
instruction 804
dummy external section 1030
D X D 1030
DXD assembler instruction 804
E N T R Y 804
ENTRY assembler
instruction 1030
E X T R N 804
EXTRN statement 1030
pseudo register 1030
renaming via ALIAS
statement 1030
RSECT 804
START 804
W X T R N 804
WXTRN statement 1030
External Symbol Dictionary 95
definition 851, 1030
ESDID 804
Owning ID 804
relocation attribute 811
extreme exponent
binary floating-point 635
decimal floating-point 685
definition 724, 1030
hexadecimal floating-point 589
EXTRN assembler instruction 804,
806
difference from WXTRN 806
EXTRN statement 1030

1264

F
F-format records 953
FIDBR machine instruction 655
FIDR machine instruction 612
FIDTR machine instruction 702
FIEBR machine instruction 655
field separator 526
definition 1030
FIER machine instruction 612
fill character 527
definition 1030
FIXBR machine instruction 655
fixed length records 953, 954
fixed-point binary
arithmetic division 275
compare instructions 233
comparison 223
divide exception 60
division 274
double-length division 275
double-length multiplication 265
logical division 279
logical multiplication 270
mixed integer-fraction representation 544
multiplication 264
shifting 252
signed multiplication 265
single-length division 278
single-length multiplication 267
fixed-point overflow 30
binary complementation 30
two s complement 33
fixed-point overflow exception 59
FIXR machine instruction 612
FIXTR machine instruction 702
flag bit
Floating-Point Control
Register 636
floating-point
as rational numbers 550
binary 1027
constant
type D 554
type DB 554
type DD 554
type DH 581, 554
type E 554
type EB 554
type ED 554
type EH 581, 554
type L 554
type LB 554
type LD 554
type LH 581, 554
type LQ 581
constants summary 728
convert among types 729
decimal 1028
definition 559, 1030
exceptions summary 727
GPR-FPR copying
instructions 557
load zero instructions 556

Assembler Language Programming for IBM z System Servers

Version 1.00

floating-point (continued)
MaxReal 569
MinReal 569
overview 548, 730
addition/subtraction 565
base 548
bias 571
characteristic 571
division 564
exponent 548
exponent overflow 569
exponent representation 549
exponent sign 549
exponent underflow 569
exponent width 548
FP(r,p) 730
FPF(r,p) 550
FPI(r,p) 550
guard digit 562
multiplication 560
normalization 560
post-normalization 560
pre-normalization 561
radix 548
representation 548
rounding 550
rounding digit 562
significand 548
properties summary 727
real vs. realistic arithmetic 731
representation examples 736
representation summary 725
representation-independent
instructions 555, 686
rounding-mode suffix
summary 728
sign-copying instructions 557
summary 725
ulp (unit in the last place) 568
z System
base 10 551
base 16 551
base 2 551
floating-point register
pairs 552
floating-point registers 551
zero behavior 734
Floating-Point Control Register 636
binary floating-point 636
binary rounding mode 637
decimal floating-point 687, 704
decimal rounding mode 705
DXC 636
instructions 637
floating-point register 48, 551
floating-point summary
constant rounding-mode
suffix 728
constants 728
exceptions 727
properties 727
representations 725
floating-point system FP(r,p) 550
definition 559, 1030
floating-point system FPF(r,p) 550

floating-point system FPF(r,p) (continued)


definition 559, 1030
floating-point system FPI(r,p) 550
definition 559, 1030
FPCR
definition 1030
FPR
See also floating-point register
definition 51, 1030
fraction conversion
between bases 541
free storage list 915
definition 930, 1030
FREEMAIN macro instruction 943,
945, 947
FREEPOOL macro instruction 955
fullword 46

G
general purpose register
definition 1031
general register
definition 51, 1031
pair 48
register halves 180
generalized object file format
definition 1031
object module 1031
GET macro instruction 950
GETMAIN macro instruction 943,
947
G G n 193
definition 204, 1031
GOFF
See generalized object file format
GOFF object module
definition 852
GOFF option
definition 1031
GPR
See general purpose register
See general register
gradual underflow 634
graphic data type
See also DBCS
definition 1031
G R n 181, 193
definition 204, 1031
guard digit 562
definition 572, 1031

H
halfword 46, 179
halfword operands 184
halve instructions
hexadecimal floating-point 591
hash function 927
definition 931, 1031
hash table 927, 928
definition 931, 1031
HDR machine instruction 591

HER machine instruction 591


hex 21
See also hexadecimal
abbreviation for hexadecimal 21
hexadecimal
definition 41, 1031
digits 20
hexadecimal floating-point 573
addition/subtraction 593
no pre-normalization 593
characteristic 573
comparison 602
constant 577
conversion instructions
to/from fixed binary 606
convert to binary floating-point and
decimal floating-point 729
data representation 573
division 590
exponent 573
exponent overflow 589
exponent underflow 589, 599
halve 591
history 616
integer values 611
lengthening instructions 605
lost significance exception 594
more precise rounding 582
multiplication 586
multiply and add/subtract 614
normalized addition 592
normalized subtraction 592
post-normalization 586, 590
pre-normalization 586, 590
pseudo-zero 734
remainder 611
rounding instructions 603
square root 613
subtype H 582
symbolic operand
(DMin) 582
(Max) 582
(Min) 582
truncation in conversion 607
unnormalized addition 595
unnormalized representation 575
unnormalized subtraction 595
hexadecimal floating-point divide 60
hexadecimal floating-point exponent
overflow 60
hexadecimal floating-point exponent
underflow 60
hexadecimal floating-point lost significance 60
High Level Assembler
definition 1031
HLASM
definition 16, 1031

I
IA
See Instruction Address
IARV64 macro instruction 943
IC machine instruction 186

ICM machine instruction 187


ICMH machine instruction 192
IEDTR machine instruction 705
IEXTR machine instruction 705
IHADCB dummy section 955
IHADCB macro instruction 955
IHAEPIE dummy section 960
IHAEPIE macro instruction 960
IIHF machine instruction 319
IIHH machine instruction 319
IIHL machine instruction 319
IILF machine instruction 319
IILH machine instruction 319
IILL machine instruction 319
ILC
See also Instruction Length Code
definition 1031
immediate operand
add 322
arithmetic load 319
compare 323
logical AND 324, 356
logical insert 319
logical load 319, 322
logical OR 324, 356
logical XOR 325, 356
move 355
multiply 323
subtract 322
test 358
implied address 111, 112
absolute 133
base register zero 133
definition 117, 1031
implied length 115, 370
definition 117, 1031
in constants 142
in SS-type instructions 370
index 65
definition 71, 1031
index register
definition 1032
general purpose register 1032
index register specification
digit 1032
index register specification digit 65
definition 71, 1032
indexed Effective Address 66
indexing 65
definition 71, 1032
operations 334
inexact result
binary floating-point 636
decimal floating-point 684
infinity
binary floating-point 628
decimal floating-point 674
infix notation 909
definition 931, 1032
inorder tree traversal 926
definition 931, 1032
input/output
access technique
direct 951
indexed 951
sequential 951

Index

1265

input/output (continued)
CLOSE macro 955
F R E E P O O L macro 955
G E T macro 950
OPEN macro 954
P U T macro 952
QSAM
locate mode 952
move mode 952
sequential access
basic 951
BSAM 951
QSAM 951
queued 951
VSAM 956
insert 186
character 186
definition 204, 1032
logical-immediate 319
insert under mask
under mask 187
instruction
addressing halfword 55
basic types
R R 53
RS 53
R X 53
SI 53
SS 53
cycle 52
halfword alignment 52
Instruction Address 52
Instruction Length Code 55
instruction register 52
length 52
modal 308
operand address 55
operation code 54
operation code examples 56
partial completion 404
pipeline 209
Instruction Address 49, 52
definition 1032
updated 52
vs. location counter 94
instruction cycle
decode 53
definition 61
execute 53
definition 61
fetch 52
definition 61
with interruptions 58
instruction format
BRC 330
BRCL 330
RI-type 318
RIL-type 318
RRE-type 194, 416
RRF-type 443
RS-type 183, 188
RS-type shift 243
RSY-type 192, 412
RX-type 181
RXY-type 192

1266

instruction format (continued)


SI-type 354
SIY-type 354
SS-type, single-length 368
SS-type, two-length 463
Instruction Length Code 49, 55
definition 51, 62, 1032
instruction operation
CLCL 408
CLCLE 414
CLST 420
EX 390
EXRL 390
MVC 374
MVCL 406
MVCLE 412
MVST 418
SRST 417
T R 380
T R T 385
T R T R 388
instruction register 52
definition 61, 1032
integer conversion
between bases 21
internal symbol
Assembler Language 1032
definition 1032
SYSADATA file 1032
internal symbol dictionary
See also symbol table
definition 1032
interruptible
definition 1032
interruptible instruction 404
interruption 57
asynchronous 58
binary floating-point division by
zero 635
binary floating-point exponent
overflow 635
binary floating-point exponent
underflow 635
binary floating-point inexact
result 635
binary floating-point invalid operation 635
binary floating-point rounding
instructions 651
classes 58
code 58
data exception 478
decimal divide 60, 483
decimal floating-point division by
zero 684
decimal floating-point exponent
overflow 684
decimal floating-point exponent
underflow 684
decimal floating-point inexact
result 684
decimal floating-point invalid operation 684
decimal floating-point quantum
exception 684

Assembler Language Programming for IBM z System Servers

Version 1.00

interruption (continued)
decimal floating-pointquantum
exception 684
decimal overflow 60, 478
definition 62, 1032
disabled 58
enabled 58
ESPIE macro 958
exception 60
execute 390
execute exception 59
fixed-point divide 60
fixed-point overflow 59
hexadecimal floating-point
divide 60, 590
hexadecimal floating-point exponent overflow 60, 589, 603
hexadecimal floating-point exponent underflow 60, 589
hexadecimal floating-point lost significance 60, 594
hexadecimal floating-point square
root 613
invalid operation 59
involuntary 58
maskable 959
packed decimal division 483
packed decimal
multiplication 481
PIE 958
privileged operation 59
program 59, 959
program interruption exit 958
Program Mask 60
specification exception 481, 483
SPIE macro 958
SVC 936
synchronous 59
voluntary 59
interruption code 58
1 (invalid operation) 59
10 (decimal overflow) 60, 478
11 (decimal divide) 60, 483
12 (hexadecimal floating-point
exponent overflow) 589, 60, 603
13 (hexadecimal floating-point
exponent underflow) 589, 60
14 (hexadecimal floating-point lost
significance) 60, 594
15 (hexadecimal floating-point
divide) 60, 590
2 (privileged operation) 59
29 (hexadecimal floating-point
square root) 613
3 (execute exception) 59, 390
4 (access exception) 59
5 (addressing) 59
6 (specification) 59, 481, 483
7 (binary floating-point
exception) 637
7 (data exception) 59, 478
7 (decimal floating-point
exception) 685
8 (fixed-point overflow) 59
9 (fixed-point divide) 60, 274

interruption code (continued)


definition 62, 1031
invalid operation exception 59
invariant EBCDIC character
definition 1032
IPM machine instruction 235
IR
See also Instruction Register
definition 1032

J
J extended mnemonic 331
JC extended mnemonic 331
JCL 948
JCT extended mnemonic 335
JCTG extended mnemonic 335
JE extended mnemonic 331
JFCB 948
JH extended mnemonic 331
JL extended mnemonic 331
JLC extended mnemonic 331
JLE extended mnemonic 331
JLH extended mnemonic 331
JLL extended mnemonic 331
JLM extended mnemonic 331
JLNE extended mnemonic 331
JLNH extended mnemonic 331
JLNL extended mnemonic 331
JLNM extended mnemonic 331
JLNO extended mnemonic 331
JLNOP extended mnemonic 331
JLNP extended mnemonic 331
JLNZ extended mnemonic 331
JLO extended mnemonic 331
JLP extended mnemonic 331
JLU extended mnemonic 331
JLZ extended mnemonic 331
JM extended mnemonic 331
JNE extended mnemonic 331
JNH extended mnemonic 331
JNL extended mnemonic 331
JNM extended mnemonic 331
JNO extended mnemonic 331
JNOP extended mnemonic 331
JNP extended mnemonic 331
JNZ extended mnemonic 331
JO extended mnemonic 331
Job Control Language 83, 948
definition 86, 1032
Job File Control Block 948
JP extended mnemonic 331
jump extended mnemonic 331
jump instructions 331
JXH extended mnemonic 344
JXHG extended mnemonic 344
JXLE extended mnemonic 344
JXLEG extended mnemonic 344
JZ extended mnemonic 331

K
KDB machine instruction 650
KDBR machine instruction 650

KDTR machine instruction 692


KEB machine instruction 650
KEBR machine instruction 650
KXBR machine instruction 650
KXTR machine instruction 692

L
L machine instruction 181
LA machine instruction 309
label
definition 1032
labeled USING statement 1032
name field symbol 1032
qualifier 1032
labeled dependent USING 875, 889
complex data structures 875
definition 891, 1032
identical data structures 880
labeled USING 866, 889
address resolution 866
definition 891, 1032
DROP assembler instruction 867
large programs 776
address constants 779
addressability 776
uniform addressability 776
LARL machine instruction 309
LAY machine instruction 309
LB machine instruction 198
LBR machine instruction 198
LC
definition 1033
LCDBR machine instruction 642
LCDFR machine instruction 556
LCDR machine instruction 584
LCDTR machine instruction 701
LCEBR machine instruction 642
LCER machine instruction 584
LCGFR machine instruction 196
LCGR machine instruction 195
LCR machine instruction 189
LCXBR machine instruction 642
LCXR machine instruction 584
LD machine instruction 555
LDE machine instruction 605
LDEB machine instruction 651
LDEBR machine instruction 651
LDER machine instruction 605
LDETR machine instruction 702
LDGR machine instruction 557, 686
LDR machine instruction 556, 686
LDXBR machine instruction 651
LDXR machine instruction 603
LDXTR machine instruction 703
LDY machine instruction 555
LE machine instruction 555
LEDBR machine instruction 651
LEDR machine instruction 603
LEDTR machine instruction 703
length attribute 92
length attribute reference 372
definition 106, 1032
Length Expression 369, 370
definition 117, 1032

Length Expression (continued)


explicit 369
implied 369
length field 115, 463
explicit 115, 463
implied 115, 463
single-length instruction 115
two-length instruction 116
length modifier 141, 259
binary floating-point constant 632
bit 259
byte 142, 259
decimal floating-point
constant 678
definition 147, 1032
fixed-point binary 142
hexadecimal floating-point
constant 579
packed decimal constant 461
zoned decimal constant 458
Length Specification Byte 368, 373
definition 1033
relation to Length Expression 373
Length Specification Digit
definition 1033
lengthening instructions
binary floating-point 651
decimal floating-point 702
hexadecimal floating-point 605
LER machine instruction 556, 686
LEXBR machine instruction 651
LEXR machine instruction 603
LEY machine instruction 555
LFAS machine instruction 638
LFPC machine instruction 638
LG machine instruction 192
LGB machine instruction 198
LGBR machine instruction 198
LGDR machine instruction 557, 686
LGF machine instruction 196
LGFI machine instruction 320
LGFR machine instruction 196
LGH machine instruction 192
LGHI machine instruction 320
LGR machine instruction 195
LH machine instruction 184
LHI machine instruction 320
LHR machine instruction 189
library
load module 832
PDS 831
Lilliput 448
linear subscript 897
definition 930, 1033
linkage 743
linkage convention 751
argument 751
argument address list 752
argument passing
32-bit addresses 752
assisted linkage 770, 833
calling point identifier 764
definition 774, 1033
entry point 751
entry point identifier 763

Index

1267

linkage convention (continued)


parameter 751
return address 751
return code 765
return flag 764
RETURN macro-instruction 767
save area 756
SAVE macro-instruction 763
subroutine 751
V-type address constant 806
variable-length argument list 753
linked list 913
See also list
definition 930, 1033
linker 75
Binder 835
boundary alignment 141, 795
common sections 822
Composite External Symbol Dictionary 821
control sections 788
definition 85, 1033
library search 806
load module 831
options 969
linking
See program linking
linking loader
definition 852, 1033
list 913
as an array 894
definition 930, 1033
deletion 914
doubly-linked 919
insertion 913
literal 156
as a term 98
definition 160, 1033
in multiple control sections 794,
840
in Private Code section 812
rules 156
special symbol 156
literal pool 158
definition 160, 1033
Little-Endian 448
LLC machine instruction 198
LLCR machine instruction 198
LLGC machine instruction 198
LLGCR machine instruction 198
LLGF machine instruction 198
LLGFR machine instruction 198
LLGH machine instruction 198
LLGHR machine instruction 198
LLGT machine instruction 198, 849
LLGTR machine instruction 198,
849
LLH machine instruction 198
LLHR machine instruction 198
LLIHF machine instruction 320
LLIHH machine instruction 320
LLIHL machine instruction 320
LLILF machine instruction 320
LLILH machine instruction 320
LLILL machine instruction 320

1268

LM machine instruction 182


LMG machine instruction 192
LMH machine instruction 192
LNDBR machine instruction 642
LNDFR machine instruction 556
LNDR machine instruction 584
LNDTR machine instruction 701
LNEBR machine instruction 642
LNER machine instruction 584
LNGFR machine instruction 196
LNGR machine instruction 195
LNR machine instruction 189
LNXBR machine instruction 642
LNXR machine instruction 584
load immediate
arithmetic 319
logical 319
with IILF 319
load module 75
CESD record 832
creation 75
CTL/RLD record 832
definition 85, 852, 1033
EOM record 832
IDR record 832
loaded into memory 75
Partitioned Data Set 832
PDS 832
RLD record 832
SYM record 832
TEXT record 832
load operation 181
definition 204, 1033
location 94
assembly time 94, 1033
base location 1027
definition 1033
execution time address 1033
location counter 1033
vs. address 94
location counter 94
definition 97, 1033
discontinuity 794
Location Counter values and
LOCTR 796
reference 123
symbol definition 125
threading 795
vs. Instruction Address 94
location counter reference 99, 123
location vs. address 94
assembly vs. execution time 94
LOCTR group
logical
AND operation 289, 290
definition 299
Boolean 288
differences vs. arithmetic 39
operations 288
OR operation 289, 291
definition 299
XOR operation 289, 292
definition 299
logical arithmetic 225
definition 238, 1033

Assembler Language Programming for IBM z System Servers

Version 1.00

logical division 279


definition 284, 1033
logical multiplication 270
definition 284, 1033
logical representation 39
definition 41, 1033
logical shift 243
definition 261, 1033
double-length 248
process 243
single-length 245
LPDBR machine instruction 642
LPDFR machine instruction 556
LPDR machine instruction 584
LPDTR machine instruction 701
LPEBR machine instruction 642
LPER machine instruction 584
LPGFR machine instruction 196
LPGR machine instruction 195
LPR machine instruction 189
LPXBR machine instruction 642
LPXR machine instruction 584
LR machine instruction 189
LRDR machine instruction 603
LRER machine instruction 603
LRV machine instruction 449
LRVG machine instruction 449
LRVGR machine instruction 449
LRVH machine instruction 449
LRVR machine instruction 449
LT machine instruction 195
LTDBR machine instruction 642
LTDR machine instruction 584
LTDTR machine instruction 701
LTEBR machine instruction 642
LTER machine instruction 584
LTG machine instruction 195
LTGFR machine instruction 196
LTGR machine instruction 195
LTORG
in multiple control sections 794
LTORG assembler instruction 158
LTR machine instruction 189
LTXBR machine instruction 642
LTXR machine instruction 584
LXD machine instruction 605
LXDB machine instruction 651
LXDBR machine instruction 651
LXDR machine instruction 605
LXDTR machine instruction 701,
702
LXE machine instruction 605
LXEB machine instruction 651
LXEBR machine instruction 651
LXER machine instruction 605
LXR machine instruction 556, 686
LZDR machine instruction 556
LZER machine instruction 556
LZXR machine instruction 556

M
M machine instruction
machine instruction
A 218

264, 265

machine instruction (continued)


A D 593
ADB 648
ADBR 648
A D R 593
A D T R 687
A D T R A 687
AE 593
AEB 648
AEBR 648
AE R 593
AFI 322
A G 218
A G F 231
A G F I 322
A G F R 231
A G H I 322
A G R 218
A H 218
AHI 322
AL 225
ALC 230
ALCG 230
A L C G R 230
ALCR 230
ALFI 322
A L G 225
A L G F 231
A L G F I 322
A L G F R 231
A L G R 225
AL R 225
AP 489, 493
A R 218
AXBR 648
AXR 593
AXTR 687
AXTRA 687
BAS 744
BASR 744
BASSM 844
BC 206, 207
BCR 206, 207
BCT 335
BCTG 335
BCTGR 335
BCTR 335
BRAS 744
BRASL 744
BRCT 335
BRCTG 335
BRXH 342
B R X H G 342
BRXLE 342
BRXLG 342
BSM 844
BXH 342
B X H G 342
BXLE 342
BXLEG 342
C 223
C D 602
CDB 649
CDBR 649
C D F B R 653

machine instruction (continued)


C D F R 606
C D G B R 653
C D G R 606
C D G T R 693
C D G T R A 693
C D R 602
CDSTR 696
C D T R 691
C D U T R 697
CDXT 699
CDZT 699
CE 602
CEB 649
CEBR 649
C E D T R 692
CEFBR 653
C E F R 606
CEGBR 653
C E G R 606
CER 602
CEXTR 692
C F D B R 653
C F D R 606
CFEBR 653
C F E R 606
CFI 323
CFXBR 653
C F X R 606
C G 223
C G D B R 653
C G D R 606
C G D T R 693
C G D T R A 693
CGEBR 653
C G E R 606
C G F 231
C G F I 323
C G F R 231
C G H I 323
C G R 223
CGXBR 653
C G X R 606
C G X T R 693
CGXTRA 693
C H 223
CHI 323
CHY 223
CL 233
CLC 367, 379
CLCL 404, 408
CLCLE 404, 414
CLCLU 440, 442
CLFI 323
C LG 233
C L G F 233
C L G F I 323
C L G F R 233
C L G R 233
CLI 356
CLIY 356
CLM 233
C L M H 233
CLMY 233
CLR 233

machine instruction (continued)


CLST 416, 420
CP 489, 496
CPSDR 557, 686
CR 223
CSDTR 696
CSXTR 696
CU12 447
CU14 447
CU21 447
CU24 447
CU41 447
CU42 447
C U D T R 697
CUSE 416, 424
C U T F U 447
C U U T F 447
CUXTR 697
CVB 522, 524
CVBG 522, 524
CVBY 522, 524
CVD 522
CVDG 522, 523
CVDY 522
CXBR 649
CXFBR 653
C X F R 606
C X G R 606
C X G T R 693
CXGTRA 693
CXR 602
CXSTR 696
CXTR 691
CXUTR 697
CY 223
CZDT 699
CZXT 699
D 274, 275
D D 590
D D B 646
D D B R 646
D D R 590
D D T R 687
D D T R A 687
D E 590
DEB 646
DEBR 646
D E R 590
D I D B R 656
DIEBR 656
D L 274, 279
D L G 274, 279
D L G R 274, 279
D L R 274, 279
D P 489, 500
D R 274, 275
DSG 274, 275
D S G F 275
D S G F R 275
D S G R 274, 275
DXBR 646
D X R 590
D X T R 687
D X T R A 687
E D 522, 528

Index

1269

machine instruction (continued)


E D M K 522, 533
E E D T R 705
EEXTR 705
E F P C 638
ESDTR 706
ESXTR 706
EX 390
EXRL 390
F I D B R 655
F I D R 612
F I D T R 702
FIEBR 655
F I E R 612
FIXBR 655
F I X R 612
F I X T R 702
H D R 591
H E R 591
IC 186
ICM 187
I C M H 192
I E D T R 705
IEXTR 705
I I H F 319
I I H H 319
IIHL 319
IILF 319
IILH 319
IILL 319
I P M 235
KDB 650
K D B R 650
K D T R 692
KEB 650
KEBR 650
KXBR 650
K X T R 692
L 181
LA 309
LARL 309
LAY 309
LB 198
LBR 198
LCDBR 642
L C D F R 556
L C D R 584
L C D T R 701
LCEBR 642
LCER 584
L C G F R 196
L C G R 195
LCR 189
LCXBR 642
LCXR 584
L D 555
L D E 605
LDEB 651
LDEBR 651
L D E R 605
L D E T R 702
L D G R 557, 686
L D R 556, 686
LDXBR 651
L D X R 603

1270

machine instruction (continued)


L D X T R 703
L D Y 555
LE 555
LEDBR 651
L E D R 603
L E D T R 703
L E R 556, 686
LEXBR 651
LEXR 603
LEY 555
LFAS 638
L F P C 638
L G 192
LGB 198
LGBR 198
L G D R 557, 686
L G F 196
L G F I 320
L G F R 196
L G H 192
L G H I 320
L G R 195
L H 184
L H I 320
L H R 189
LLC 198
LLCR 198
LLGC 198
L L G C R 198
L L G F 198
L L G F R 198
L L G H 198
L L G H R 198
L L G T 198, 849
L L G T R 198, 849
L L H 198
L L H R 198
L L I H F 320
L L I H H 320
LLIHL 320
LLILF 320
LLILH 320
LLILL 320
L M 182
L M G 192
L M H 192
L N D B R 642
L N D F R 556
L N D R 584
L N D T R 701
LNEBR 642
L N E R 584
L N G F R 196
L N G R 195
L N R 189
LNXBR 642
L N X R 584
L P D B R 642
L P D F R 556
L P D R 584
L P D T R 701
LPEBR 642
L P E R 584
L P G F R 196

Assembler Language Programming for IBM z System Servers

Version 1.00

machine instruction (continued)


L P G R 195
L P R 189
LPXBR 642
L P X R 584
L R 189
L R D R 603
L R E R 603
LRV 449
LRVG 449
L R V G R 449
LRVH 449
LRVR 449
LT 195
LTDBR 642
L T D R 584
L T D T R 701
LTEBR 642
LTER 584
L T G 195
L T G F R 196
L T G R 195
L T R 189
LTXBR 642
LTXR 584
L X D 605
LXDB 651
LXDBR 651
L X D R 605
L X D T R 701, 702
LXE 605
LXEB 651
LXEBR 651
LXER 605
LXR 556, 686
L Z D R 556
LZER 556
LZXR 556
M 264, 265
M A D 614
M A D B 659
M A D B R 659
M A D R 614
M A E 614
MAEB 659
MAEBR 659
M A E R 614
M D B 644
M D B R 644
M D E 586
M D E B 644
M D E B R 644
M D E R 586
M D R 586
M D T R 687
M D T R A 687
M E 586
M E E 586
MEEB 644
MEEBR 644
M E E R 586
M E R 586
M G H I 323
M H 264, 268
M H I 323

machine instruction (continued)


M L 264, 270
M L G 264, 270
M L G R 264, 270
M L R 264, 270
M P 489, 497
M R 264, 265
MS 264, 268
MSD 614
MSDB 659
MSDBR 659
M S D R 614
MSE 614
MSEB 659
MSEBR 659
MSER 614
MSG 264, 268
M S G F 264, 268
M S G F R 264, 268
M S G R 264, 268
MSR 264, 268
MSY 264, 268
MVC 367, 374
MVCIN 367, 375
MVCL 404, 406
MVCLE 404, 412
MVCLU 440, 441
MVCOS 367
MVI 355
MVIY 355
MVN 454
MVO 489, 507
MVST 416, 418
MVZ 454
MXBR 644
M X D 586
MXDB 644
M X D B R 644
M X D R 586
M X R 586
M X T R 687
M X T R A 687
N 288
NC 367, 378
N G 288
N G R 288
NI 355
N I H F 324
N I H H 324
N I H L 324
N I L F 324
N I L H 324
NILL 324
NIY 355
N R 288
O 288
OC 367, 378
O G 288
O G R 288
OI 355
O I H F 325
O I H H 325
OIHL 325
OILF 325
OILH 325

machine instruction (continued)


OILL 325
OIY 355
operand formats 104
operands 98
O R 288
PACK 454, 465
PC 936
P F P O 731
P KA 454, 472
P K U 454, 472
Q A D T R 708
QAXTR 708
R L L 242
R L L G 242
RR-type 109
R R D T R 710
R R X T R 710
RS-type 113
RX-type 110
S 218
SAM24 844
SAM31 844
SAM64 844
SBRM 638
SD 593
SDB 648
SDBR 648
SDR 593
SDTR 687
SDTRA 687
SE 593
SEB 648
SEBR 648
SER 593
SFASR 638
SFPC 638
SG 218
SGF 231
S G F R 231
SGR 218
SH 218
SI-type 114
SL 225
SLA 242
SLAG 242
SLB 230
SLBG 230
SLBGR 230
SLBR 230
SLDA 242
SLDL 242
SLDT 707
SLFI 322
SLG 225
SLGF 231
SLGFI 322
S L G F R 231
SLGR 225
SLL 242
SLLG 242
SLR 225
SLXT 707
SP 489, 493
SPM 235

machine instruction (continued)


SQD 613
SQDB 658
SQDBR 658
SQDR 613
SQE 613
SQEB 658
SQEBR 658
SQER 613
SQXBR 658
SQXR 613
SR 218
SRA 242
SRAG 242
SRDA 242
SRDL 242
SRDT 707
SRL 242
SRLG 242
SRNMT 704
SRP 489, 502
SRST 416
SRSTU 440
SRXT 707
SS-type 115
SS-type length fields 115
ST 181
STC 186
STCM 187
STCMH 192
STD 555
STDY 555
STE 555
STEY 555
STFPC 638
STG 192
STH 184
STM 182
STMG 192
STMH 192
STRV 449
STRVG 449
STRVH 449
SVC 936
SXBR 648
SXR 593
SXTR 687
SXTRA 687
T A M 844
TCDB 641
TCEB 641
TCXB 641
T D C D T 680
TDCET 680
TDCXT 680
T D G D T 712
T D G E T 712
T D G X T 712
T M 358
T M Y 358
TP 489
T R 367, 380
T R E 422
TROO 443
TROT 443

Index

1271

machine instruction (continued)


T R T 367, 385
TRTO 443
T R T R 367, 388
T R T T 443
U N P K 454, 468
U N P K A 454, 473
U N P K U 454, 473
X 288
XC 367, 378
XCGBR 653
X G 288
X G R 288
XI 355
X I H F 325
XILF 325
XIY 355
X R 288
ZAP 489, 491
machine instruction statement 76
machine language 75
definition 62, 1033
machine length 368
definition 117, 1033
macro argument 937
macro instruction
ABEND 942, 962
arguments 937
call 937
CLOSE 955
COND= argument 946
CONVERTI 84, 1003
CONVERTO 84, 1003
DCB 952
DCBD 955
DCBE 956
definition 85, 1033
D U M P O U T 84, 1006
ESPIE 958
ESTAE 962, 963
ESTAEX 962
execute form 938
F R E E M A I N 943, 945, 947
F R E E P O O L 955
G E T 950
G E T M A I N 943, 947
IARV64 943
IHADCB 955
invocation 937
list form 938
MODE= argument 940
OPEN 954
PRINTLIN 84, 1002
PRINTOUT 84, 1005
P U T 952
R-form 940
R E A D C A R D 84, 1002
register arguments 940
R E T U R N 767
SAVE 763
SETRP 962
SPIE 958
STAE 962
standard form 938
STORAGE 943, 946, 947

1272

macro instruction (continued)


SYSSTATE 941
system services 937
macro-instruction statement 76
MAD machine instruction 614
MADB machine instruction 659
MADBR machine instruction 659
MADR machine instruction 614
MAE machine instruction 614
MAEB machine instruction 659
MAEBR machine instruction 659
MAER machine instruction 614
mantissa
definition 559, 1033
mask bit
Floating-Point Control
Register 636
Program Mask 235, 60
mask byte 358
mask digit 188, 194, 207
and execute instruction 364
branch 207, 331
MaxReal 569
definition 572, 1034
MDB machine instruction 644
MDBR machine instruction 644
MDE machine instruction 586
MDEB machine instruction 644
MDEBR machine instruction 644
MDER machine instruction 586
MDR machine instruction 586
MDTR machine instruction 687
MDTRA machine instruction 687
ME machine instruction 586
MEE machine instruction 586
MEEB machine instruction 644
MEEBR machine instruction 644
MEER machine instruction 586
memory address 45
alignment 46
memory dump
ABEND macro instruction 942
DUMPOUT macro
instruction 943
MER machine instruction 586
message character 526
definition 1034
MGHI machine instruction 323
MH machine instruction 264, 268
MHI machine instruction 323
millicode 50
definition 51, 1034
MinReal 569
definition 572, 1034
minuend
definition 238, 1034
ML machine instruction 264, 270
MLG machine instruction 264, 270
MLGR machine instruction 264,
270
MLR machine instruction 264, 270
mnemonic 84, 135
as abbreviation 108
definition 85, 117, 1034
extended 212

Assembler Language Programming for IBM z System Servers

Version 1.00

mnemonic (continued)
instruction name 84, 85, 135,
1034
modal instruction 308
modifier
bit length 259
byte length 259
definition 147, 1034
explicit length 142
exponent 140
length 140
scale 140
MP machine instruction 489, 497
MR machine instruction 264, 265
MS machine instruction 264, 268
MSD machine instruction 614
MSDB machine instruction 659
MSDBR machine instruction 659
MSDR machine instruction 614
MSE machine instruction 614
MSEB machine instruction 659
MSEBR machine instruction 659
MSER machine instruction 614
MSG machine instruction 264, 268
MSGF machine instruction 264, 268
MSGFR machine instruction 264,
268
MSGR machine instruction 264, 268
MSR machine instruction 264, 268
MSY machine instruction 264, 268
multiplicand
definition 284, 1034
multiplication
binary floating-point 644
decimal floating-point 688
fixed-point binary 264
process 272
fixed-point binary double-length
product 265
fixed-point binary single-length
product 267
floating-point 560
hexadecimal floating-point 586
logical 270
packed decimal 497
packed decimal operand order
dependence 482
register-immediate 323
signed 265
multiplier
definition 284, 1034
multiply and add/subtract
binary floating-point 659
hexadecimal floating-point 614
multiply-defined symbols 125
MVC machine instruction 367, 374
MVCIN machine instruction 367,
375
MVCL machine instruction 404, 406
MVCLE machine instruction 404,
412
MVCLU machine instruction 440,
441
MVCOS machine instruction 367
MVI machine instruction 355

MVIY machine instruction 355


MVN machine instruction 454
MVO machine instruction 489, 507
MVST machine instruction 416, 418
MVZ machine instruction 454
MXBR machine instruction 644
MXD machine instruction 586
MXDB machine instruction 644
MXDBR machine instruction 644
MXDR machine instruction 586
MXR machine instruction 586
MXTR machine instruction 687
MXTRA machine instruction 687

N
N machine instruction 288
NaN (Not a Number)
binary floating-point 626
decimal floating-point 674
NC machine instruction 367, 378
NG machine instruction 288
NGR machine instruction 288
NI machine instruction 355
NIHF machine instruction 324
NIHH machine instruction 324
NIHL machine instruction 324
NILF machine instruction 324
NILH machine instruction 324
NILL machine instruction 324
NIY machine instruction 355
no-operation instruction 208
conditional 209
definition 215, 1034
NOALIGN assembler option 141
nominal value 140
definition 147, 1034
type of constant 140
non-modal instruction 308
NOP extended mnemonic 208, 213
NOPR extended mnemonic 208, 213
normalization 560
definition 572, 1034
notation
binary 19
blank representation in
examples 15
data fields 14
hexadecimal 20
instruction components 15
positional 18
space representation in
examples 15
subscripts 14
NOTHREAD assembler option 796
NR machine instruction 288
null-terminated string 415
numeric digit 454
definition 1034
in packed decimal 454

O
O machine instruction

288

OBJ object module


definition 852
object code 75
creation 75
definition 85, 1034
pass 2 generation 127
object module 817
creation 75
definition 85, 852, 1034
END record 818
ESD record 817
RLD record 817
SYM record 817
TXT record 817
OC machine instruction 367, 378
offset
by ORG instruction 170
CUSE instruction 424
definition 1034
during relocation 841
in Q-type constant 818
MVO instruction 507
with dependent USING 871
OG machine instruction 288
OGR machine instruction 288
OI machine instruction 355
OIHF machine instruction 325
OIHH machine instruction 325
OIHL machine instruction 325
OILF machine instruction 325
OILH machine instruction 325
OILL machine instruction 325
OIY machine instruction 355
ones complement representation
definition 41, 1034
opcode
See also operation code
definition 117, 1034
OPEN macro instruction 954
operand 46
address 55
assembly-time 109
definition 85, 1034
execution-time 109
halfword 184
immediate 114, 318
in an instruction description 15
in an instruction statement 15
machine instruction 46
optional 442
subject of an operation 15
operand order dependence 479, 482
definition 1034
operation code
and instruction length 55
definition 62, 117, 1034
examples 56
operator
17, 99
/ 17, 99
17
* 17, 99
+ 17, 99
17
definition 17, 106, 1034

operator (continued)
unary 99
unary + 99
option
*PROCESS statement 1035
ACONTROL assembler
instruction 1035
definition 1035
G O F F 795, 835, 840
OR machine instruction 288
OR operation 289, 299, 1035
definition 299, 1035
register-immediate 324
register-register 291
storage-immediate 356
storage-storage 378
XOR operation
definition 299
ordinary control section
See also control section
common control section 1028
CSECT 1028
offsets fixed at assembly
time 1028
positions at execution time 1028
relocation at later times 1028
RSECT 1028
ordinary symbol 91, 1032
external 91
internal 91
ordinary USING 122
definition 891, 1035
shortcomings 860, 865
ORG assembler instruction 169
extended syntax 170, 1035
definition 177, 1035
origin 82
definition 85, 1035
initial location 82
overflow
binary floating-point 635
binary floating-point
rounding 651
definition 41, 1035
fixed-point binary 30, 33
hexadecimal floating-point 589
hexadecimal floating-point
rounding 603
packed decimal 478
two s complement 33
overlay 833

P
PACK machine instruction 454, 465
packed decimal
addition process 484
addition rules 478
arithmetic rules 477
comparison 496
comparison rules 480
constant 461
convert to/from decimal floatingpoint 696
data exception 478

Index

1273

packed decimal (continued)


divide exception 483
division 500
division rules 483
editing overview 526
mixed integer-fraction representation 543
move with offset 507
multiplication 497
multiplication data exception 481
multiplication rules 481
operand order dependence 479,
482, 1034
overflow 478
representation 459
scale attribute 461
scaled arithmetic 513
general rules 513
shifting 502
sign-magnitude
representation 460
specification exception 481, 483
subtraction process 486
subtraction rules 478
padding 154
by compare and move long 404
character 404
definition 160, 1035
hexadecimal floating-point
constant 579
in constants 154
with blanks 155
with sign bits 155
with zeros 461
parameter 751
definition 774, 1035
parameterization 171
definition 177, 1035
partial-completion instruction 404
Partitioned Data Set Extended 835
pattern 526
character 526
definition 1035
digit selector 526
digit selector and significance
starter 526
editing 526
field separator 526
fill character 527
message character 526
payload
definition 724, 1035
PC machine instruction 936
PDSE 835
percolate 962, 965
PFPO machine instruction 731
PICA
See also Program Interruption
Control Area
maskable program
interruptions 959
PIE
See Program Interruption Element
pipeline 209
definition 216, 1035

1274

PKA machine instruction 454, 472


PKU machine instruction 454, 472
PM
See Program Mask
post-normalization
definition 572, 1035
hexadecimal floating-point
division 590
hexadecimal floating-point multiplication 586
postfix notation 909
definition 931, 1035
postorder tree traversal 926
definition 931, 1035
pre-normalization
definition 572, 1035
hexadecimal floating-point
division 590
hexadecimal floating-point multiplication 586
preferred exponent 684
definition 724, 1035
preferred quantum 684
definition 724, 1035
preorder tree traversal 926
definition 931, 1035
PRINTLIN macro instruction 1002
definition 1010
description 1002
PRINTOUT macro instruction 1005
definition 1012
description 1005
Private Code section 812
privileged operation 50
privileged operation exception 59
problem state 50
definition 51, 1035
process
binary division 280
binary multiplication 272
hexadecimal floating-point
addition 598
hexadecimal floating-point complement addition 600
hexadecimal floating-point subtraction 599
packed decimal addition 484
packed decimal subtraction 486
program interruption 59
access exception 59
addressing 59
data 59
decimal divide 60
decimal overflow 60
definition 1035
ESPIE macro 958
identifying token 958
execute exception 59
fixed-point divide 60
fixed-point overflow 59
hexadecimal floating-point
divide 60
hexadecimal floating-point exponent overflow 60
hexadecimal floating-point exponent underflow 60

Assembler Language Programming for IBM z System Servers

Version 1.00

program interruption (continued)


hexadecimal floating-point lost significance 60
invalid operation 59
PIE 958
privileged operation 59
Program Mask control
decimal overflow 60
fixed-point overflow 60
hexadecimal floating-point
exponent underflow 60
hexadecimal floating-point lost
significance 60
specification 59
SPIE macro 958
Program Interruption Control
Area 958
Program Interruption Element 960
contents 960
DSECT EPIE 960
mapping macro IHAEPIE 960
Program Interruption Exit 960
program length
definition 117, 1035
program linking 819
combining object modules 819
Composite External Symbol Dictionary 821
definition 852
load modules 831
overview 75
Program Loader 75, 118, 795
boundary alignment 141, 795
definition 85
load modules 842
relocation 75
program loading
boundary alignment 795
Program Loader 75
Program Mask 49, 235, 589, 594
decimal overflow 60
definition 62, 1035
fixed-point overflow 60
hexadecimal floating-point exponent underflow 60, 589
hexadecimal floating-point lost significance 60, 594
mask bits 235
retrieve/set 235
program object 834
definition 852
Partitioned Data Set
Extended 835
PDSE 835
program object class 835
program objects
Program Status Word 49
basic addressing mode 308
Condition Code 49, 206
definition 51, 1035
extended addressing mode 308
Instruction Address 49, 52
instruction address vs. location
counter 94
Instruction Length Code 49

Program Status Word (continued)


interruptions 57
new 58
old 58
Program Mask 49
switching 57
pseudo register 1030
pseudoregister
definition 852, 1035
PSW
See Program Status Word
PUT macro instruction 952

Q
Q-type address constant
definition 853, 1035
QADTR machine instruction 708
QAXTR machine instruction 708
quadword 46, 179
qualified symbol 866
definition 891, 1035
qualifier 866
definition 891, 1035
quantum 670
decimal floating-point
quantize 708
definition 724, 1036
preferred 682, 684
quantum exception
decimal floating-point 684
queue 919
definition 930, 1036
quotient
definition 284, 1036
fixed-point binary division 274
packed decimal 483

R
radix 548
definition 559, 1036
radix point 543
radix-complement representation 26
definition 41, 1036
READCARD macro
instruction 1002, 1002
definition 1010
description 1002
real address 69
address translation 69
D A T 69
definition 71, 1036
real numbers 731
realistic numbers 731
recipe
binary overflow detection 33
binary subtraction 37
two s complementation 29
recovery routine 962
recovery/termination manager 962
percolate 962
retry routine 962
R T M 962

recursion 972
reenterability 968, 969
assembly time 969
linking time 969
RSECT 1036
reentrant
See also reenterability
definition 1036
reference control section 789
COM 789
definition 852, 1036
DSECT 789
D X D 789
reference table
ASCII representation 999
DC statement types 1000
EBCDIC representation 998
fractions in hexadecimal and
decimal 997
hexadecimal addition 982
hexadecimal digits 981
hexadecimal multiplication 982
integers in hexadecimal and
decimal 989
powers of 10 in hexadecimal 987
powers of 16 986
powers of 2 983
register
access 50
control 50
floating-point register 47, 551
floating-point register pair 552
general register 47
general register pair 242, 274
relative-immediate 304
address generation 304
relocatability
complex 1028
relocatability attribute 135
complex 135
relocatable 93, 121
absolute 106, 1025
complex 106, 1028
definition 97, 1036
location counter reference 99
simple 106, 1037
relocatable program 128
relocate
definition 852, 1036
relocating loader
definition 852, 1036
relocation 75, 94
by Program Loader 841
definition 85, 97, 852, 1036
load module creation 841
of A-type constant 823
of V-type constant 823
relocation attribute 92
complex 793
definition 811
dummy control section 857
ESDID 804
in expression evaluation 100
in External Symbol Dictionary 95
relocation dictionary

relocation dictionary (continued)


definition 851
remainder
binary floating-point 655
definition 284, 1036
fixed-point binary division 274
hexadecimal floating-point 611
in shift instructions 248
packed decimal 483
RENT assembler option 969
representation 626, 628
arithmetic vs. logical 39
ASCII 432, 999
BCD 429
binary floating-point 626, 628
binary numbers 26
blanks in examples 15
decimal floating-point 673
decimal floating-point
(conceptual) 669
decimal floating-point
encoding 671
diminished radix-complement 26
EBCDIC 89, 430, 998
hexadecimal 20
hexadecimal floating-point 573
logical 27
packed decimal 459
radix-complement 26
redundant decimal
floating-point 669
sign extension 32
sign-magnitude 26, 460
spaces in examples 15
Unicode 437
zoned decimal 454
residence mode
R M O D E 813
RMODE assembler
instruction 813
retry 965
retry routine 962
return address 751
definition 774, 1036
return code 765
definition 774, 1036
return flag 764
RETURN macro instruction 767
RETURN macro-instruction 767
returned values 748
RLD record in object module 817
A-type constant 817
Cumulative External Dummy 818
Q-type constant 818
V-type constant 817
RLL machine instruction 242
RLLG machine instruction 242
RMODE
definition 853
rotating shift 257
definition 261, 1036
rounding
binary floating-point 633
decimal floating-point 681
decimal floating-point
reround 710

Index

1275

rounding digit 562


definition 572, 1036
rounding instructions
binary floating-point 651
decimal floating-point 703
hexadecimal floating-point 603
packed decimal 502
rounding mode
binary floating-point 637
decimal floating-point 704
rounding-mode suffix 582, 630
binary floating-point
constants 630
decimal floating-point
constants 677
hexadecimal floating-point constants 582
row order 896
definition 930, 1037
row-major order
definition 1037
RR-type machine instruction 109
RRDTR machine instruction 710
RRXTR machine instruction 710
RS-type machine instruction 113
RSECT
control section 1037
definition 1037
External Symbol Dictionary 1037
reenterable 1037
RSECT assembler instruction 789,
969
R T M 962
run time
See also execution time
definition 1037
RX-type machine instruction 110

S
S machine instruction 218
S-type address constant 151
S-type constant 151
SAM24 machine instruction 844
SAM31 machine instruction 844
SAM64 machine instruction 844
save area
32-bit registers 756
chaining 758
doubly-linked list 757
extended conventions 759
standard 18-word 756
SAVE macro instruction 763
SAVE macro-instruction 763
SBCS 433
definition 1037
SBRM machine instruction 638
scale modifier
fixed-point binary constant 545
hexadecimal floating-point
constant 579
SD machine instruction 593
SDB machine instruction 648
SDBR machine instruction 648
SDR machine instruction 593

1276

SDTR machine instruction 687


SDTRA machine instruction 687
SDWA 962
SE machine instruction 593
SEB machine instruction 648
SEBR machine instruction 648
SECTALGN assembler option 141,
158, 795
section
See also control section
alignment 795
common 789
control 788
definition 852, 1037
dummy 789
entry point 804
external dummy 789
linking 819
literals 794
private code 812
program object section 835
resuming 793
types 788
segment 70
definition 852
self-defining term
assembly-time constants 87
binary 87
character 88
ampersand 88
apostrophe 88
translation 90, 433
DBCS 435
decimal 87
definition 97, 1037
hexadecimal 87
no embedded blanks 88
vs. C-type constant 152
sequence symbol 91
SER machine instruction 593
set rounding mode
binary floating-point 638
decimal floating-point 704
SETRP macro instruction 962
sexadecimal representation 20
SFASR machine instruction 638
SFPC machine instruction 638
SG machine instruction 218
SGF machine instruction 231
SGFR machine instruction 231
SGR machine instruction 218
SH machine instruction 218
shift
bit bucket 244
decimal floating-point
significand 707
double-length arithmetic 252
double-length logical 248
general register pair 242
packed decimal 502
process 243
rotating 257
single-length arithmetic 252
single-length logical 245
unit 243

Assembler Language Programming for IBM z System Servers

Version 1.00

shift-in character 433


shift-out character 433
SI-type machine instruction 114
sign extension 32, 185
definition 205, 1037
signed 20-bit displacement 303
sign-magnitude representation 26
definition 41, 1037
packed decimal 460
significance indicator 527
definition 1037
significance starter 526
definition 1037
significand
binary floating-point 626
decimal floating-point 674
definition 559, 1037
hexadecimal floating-point 548
simple I/O macros
$$GENIO 1008
CONVERTI 1003
CONVERTO 1003
D U M P O U T 1006
installation 1008
PRINTLIN 1002
PRINTOUT 1005
R E A D C A R D 1002
usage notes 1006
SL machine instruction 225
SLA machine instruction 242
SLAG machine instruction 242
SLB machine instruction 230
SLBG machine instruction 230
SLBGR machine instruction 230
SLBR machine instruction 230
SLDA machine instruction 242
SLDL machine instruction 242
SLDT machine instruction 707
SLFI machine instruction 322
SLG machine instruction 225
SLGF machine instruction 231
SLGFI machine instruction 322
SLGFR machine instruction 231
SLGR machine instruction 225
SLL machine instruction 242
SLLG machine instruction 242
SLR machine instruction 225
SLXT machine instruction 707
SP machine instruction 489, 493
space
ASCII representation 433
EBCDIC representation 90
representation in examples 15
text representation 17
specification exception 59
packed decimal 481
SPIE macro instruction 958
program interruption exit 958
SPM machine instruction 235
SQD machine instruction 613
SQDB machine instruction 658
SQDBR machine instruction 658
SQDR machine instruction 613
SQE machine instruction 613
SQEB machine instruction 658

SQEBR machine instruction 658


SQER machine instruction 613
square root
binary floating-point 658
hexadecimal floating-point 613
hexadecimal floating-point interruption 613
SQXBR machine instruction 658
SQXR machine instruction 613
SR machine instruction 218
SRA machine instruction 242
SRAG machine instruction 242
SRDA machine instruction 242
SRDL machine instruction 242
SRDT machine instruction 707
SRL machine instruction 242
SRLG machine instruction 242
SRNMT machine instruction 704
SRP machine instruction 489, 502
SRST machine instruction 416
SRSTU machine instruction 440
SRXT machine instruction 707
SS-type machine instruction 115
ST machine instruction 181
stack 908
definition 930, 1037
pop 910
push 910
STAE macro instruction 962
START assembler instruction 789
statement 75
*PROCESS statement 1035
ACONTROL assembler
instruction 1035
column positions
begin column 77
continue column 77
end column 77
CSECT 82
D C 139
definition 85, 1037
dependent USING 869
DROP assembler instruction 130
DS 161
E N D 82
EQU 95
EQU assembler instruction 164
free-field 79
job control 83
labeled dependent USING 875
labeled USING 866
LOCTR assembler
instruction 796
L T O R G 158
O R G 169
ORG extended syntax 1035
RSECT 1037
START 82
USING 128
statement field
comment 78
definition 85, 1037
name 78
operand 78
operation 78

statement field (continued)


remarks 78
statement type
Assembler 76
comment 76
machine instruction 76
macro-instruction 76
status preservation 749
STC machine instruction 186
STCM machine instruction 187
STCMH machine instruction 192
STD machine instruction 555
STDY machine instruction 555
STE machine instruction 555
STEY machine instruction 555
STFPC machine instruction 638
STG machine instruction 192
STH machine instruction 184
STM machine instruction 182
STMG machine instruction 192
STMH machine instruction 192
STORAGE macro instruction 943,
946, 947
subpool 947
store operation 181
definition 205, 1037
STRV machine instruction 449
STRVG machine instruction 449
STRVH machine instruction 449
subpool 947
F R E E M A I N 947
G E T M A I N 947
STORAGE 947
subroutine 742
argument 751
argument passing 745, 752
32-bit addresses 752
entry point 751
internal 784
linkage 743
linkage convention 751
lowest level 772
parameter 751
return address 751
returned values 748
status preservation 749
without addressability 783
subtraction
binary floating-point 648
binary integer 34
decimal floating-point 689
fixed-point binary 218
floating-point 565
hexadecimal floating-point 592
logical 225
packed decimal 478
packed decimal operand order
dependence 479
packed decimal process 486
register-immediate 322
with borrow 229
subtrahend
definition 238, 1037
supervisor state 50
definition 51, 1037

SVC machine instruction 936


SXBR machine instruction 648
SXR machine instruction 593
SXTR machine instruction 687
SXTRA machine instruction 687
SYM record in object module 817
symbol
absolute 92
attribute 97, 1026, 1038
assembler 168
definition 97
integer 92
length 92, 145
program 168
relocation 92, 127
scale 92
type 92
value 92, 127
complexly relocatable 101
defined 92
definition 97, 1038
duplicate 125
external 91, 804
external symbol 1030
internal 91, 93
internal symbol 1032
multiply defined 125
ordinary 91
external 91
internal 91
ordinary symbol 1032
qualified symbol 866
qualifier 866
relocatable 92
sequence 91
undefined 125
value vs. variable 96
variable 91
symbol attribute reference
definition 106, 1038
integer 98
length 98
scale 98
Symbol Table 125
definition 136, 1038
External Symbol Dictionary 95
external symbol table 91
ordinary symbols 125
symbolic operand
binary floating-point (DMin) 631
binary floating-point (Inf) 631
binary floating-point (Max) 631
binary floating-point (Min) 631
binary floating-point (NaN) 631
binary floating-point (QNaN) 631
binary floating-point (SNaN) 631
decimal floating-point
(DMin) 676
decimal floating-point (Inf) 676
decimal floating-point (Max) 676
decimal floating-point (Min) 676
decimal floating-point (NaN) 676
decimal floating-point
(QNaN) 676
decimal floating-point
(SNaN) 676

Index

1277

symbolic operand (continued)


hexadecimal floating-point symbolic operand (DMin) 582
hexadecimal floating-point symbolic operand (MAX) 582
hexadecimal floating-point symbolic operand (Min) 582
SYSSTATE macro instruction 941
System Diagnostic Work Area 962

T
table 900
definition 930, 1038
TAM machine instruction 844
TCDB machine instruction 641
TCEB machine instruction 641
TCXB machine instruction 641
TDCDT machine instruction 680
TDCET machine instruction 680
TDCXT machine instruction 680
TDGDT machine instruction 712
TDGET machine instruction 712
TDGXT machine instruction 712
term
definition 106, 1038
illustration 106
literal 98
location counter reference 98
self-defining 98
symbol 98
symbol attribute reference
integer 98
length 98
scale 98
TEST assembler option 91
text 817
definition 852, 1038
in load module 832
machine language 817
threading
Location Counter values 795
time 1037
assembly 76, 1027
binding 1027
execution 76, 1027
linking 1027
run time
See execution time
TITLE assembler instruction 80
TM machine instruction 358
TMY machine instruction 358
TP machine instruction 489
TR machine instruction 367, 380
trailing significand field 673
transformation format
(Unicode) 437
TRANSLATE assembler option 90,
160, 433
translate table 380, 385, 388
TRE machine instruction 422
tree
B-tree 926
binary 922
tree search

1278

tree search (continued)


inorder traversal 926
postorder traversal 926
preorder traversal 926
TROO machine instruction 443
TROT machine instruction 443
TRT machine instruction 367, 385
TRTO machine instruction 443
TRTR machine instruction 367, 388
TRTT machine instruction 443
true decimal addition
definition 1028, 1038
refid=ixdefn.complex
relocatability 1028
truncation 154
definition 160, 1038
hexadecimal floating-point
constant 579
in constants 154
twos complement overflow 33
twos complement representation
definition 41, 1038
recipe 29
TXT record in object module 817
type extension 159
all types 1000
definition 160, 1038
type AD 159
type CA 159
type CE 159
type CU 159
type DB 554, 629
type DD 554
type DH 554
type EB 629
type EH 554
type FD 159
type LB 554, 629
type LD 554
type LH 554
type LQ 581

U
U-format records 953
ulp (unit in the last place) 568
definition 572, 1038
relative precision 568
undefined length records 953, 954
undefined symbol 125
underflow
binary floating-point 635
hexadecimal floating-point 589
Unicode
Basic Multilingual Plane 438
C-type constant 153
constant 439
CU-type constant 159
glyph 438
numeric character 456, 472
definition 1038
pack 472
transformation format 445
translate instructions 443
unpack 473

Assembler Language Programming for IBM z System Servers

Version 1.00

Unicode numeric character


definition 1038
unit shift 243
unnormalized addition
hexadecimal floating-point 595
unnormalized hexadecimal floatingpoint representation 575
unnormalized subtraction
hexadecimal floating-point 595
UNPK machine instruction 454, 468
UNPKA machine instruction 454,
473
UNPKU machine instruction 454,
473
USING assembler instruction 122,
128, 866, 869, 875
absolute USING location 133
base location 122, 128
base register 122
definition 135, 1038
dependent 1027, 1029
dependent USING 869
labeled 866, 1032
labeled dependent 875, 1029
ordinary 122, 866
qualified symbol 1032
USING Map 135
USING Table 127, 130, 135
definition 135, 1038
USING Map 135
USING(MAP) option 135
UTF-16 445
UTF-32 445
UTF-8 445

V
V-format records 953
V-type address constant 806, 853
definition 853
variable
vs. symbol value 96
variable length records 953, 954
variable symbol 91
variable symbols
attribute 1026
symbol itself 1026
symbols value 1026
variable-length argument list 753
virtual address 69
address translation 69
D A T 69
definition 71, 1038
virtual origin 898
definition 930, 1038
of array 898
VSAM 956

W
ward in double-byte EBCDIC
widget 517, 519, 714
word 46, 179
workstation data 449

434

WXTRN assembler instruction 804,


806
difference from EXTRN 806
WXTRN statement 1030

X
X machine instruction 288
XC machine instruction 367, 378
XCGBR machine instruction 653
XG machine instruction 288
XGR machine instruction 288
XI machine instruction 355
XIHF machine instruction 325
XILF machine instruction 325
XIY machine instruction 355
XOR operation 289, 299, 1038
definition 299, 1038
register-immediate 325
register-register 292
storage-immediate 356
storage-storage 378
XR machine instruction 288

Z
ZAP machine instruction 489, 491
zero
unexpected floating-point
behavior 734
zero duplication factor 162
definition 177, 1038
zero extension 198
definition 205, 1038
zone digit 454
ASCII characters 456
definition 1038
Unicode characters 456
zoned decimal
constant 458
numeric digit 454
preferred sign 456
representation 454
sign digit 454
zone digit 454
zoned digit 536
definition 1039
in edited data 536

Index

1279

You might also like