Assembler Language Programming For IBM Z System Servers
Assembler Language Programming For IBM Z System Servers
for
IBM z System Servers
Version 1.00
John R. Ehrman
ii
Version 1.00
Contents
Figures
Tables
xxviii
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Foreword
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
.
.
.
.
.
.
.
Index
xvi
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
. .
. .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
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
. . . . . . . . . . . . . . . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
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
Version 1.00
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
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
. . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
. .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
Contents
16.
17.
18.
19.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
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
. . .
. . .
. .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
vi
Version 1.00
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
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
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
Contents
vii
viii
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
.
.
.
.
.
.
.
.
.
.
.
.
. . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
. . . . . . . . . . . .
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 . . . . . . . . . . . . . . . . . . . . . .
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
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
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 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
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
.
.
.
.
.
.
.
.
.
. . . . . . . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
xii
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
Version 1.00
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
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.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
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
. . . . . . . . . . . . .
.
.
.
.
.
.
.
. . . . . .
.
.
.
.
.
.
.
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
.
.
.
.
.
.
.
.
.
. .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
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 . . . . . . . . . . . . . . . . . . . . . . . . . .
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
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
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
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.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
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
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.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
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
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
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.
. .
.
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
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
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.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
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
. . . . . . . . . . . . . . . . . . . . . .
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.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
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.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
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
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
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.
. . .
. . .
. .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
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
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
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.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
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
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.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
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
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
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.
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
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.)
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.
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
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.
Transition and testing require system stability, which implies possible lost business opportunity.
Version 1.00
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
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
Version 1.00
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.
13
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.
Field1 Field2
0
3 4
7
Field widths
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
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?
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:
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.
Exercises
1.2.1.(1) If R 1 has value 9, what register is referenced by GR R 1?
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
17
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.
18
Version 1.00
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?
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 ,
1 = B1 = X 1 ,
10 = B1010 = X A ,
B1000 = 8 = X 8 ,
(hexadecimal to binary),
(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
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
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.
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
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
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
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.
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?
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
12
7)89
84
5=e1
1
7)12
7
5=e2
0
7)1
0
1=e3
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
Version 1.00
2
20)43
40
3=e1
0
20)2
0
2=e2
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
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
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
27
Now, consider negative numbers. The twos complement representation of a negative integer Y
satisfying the inequalities
231 Y 1
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
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
Version 1.00
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.
29
0000 0010
1111 1101
+
1
1111 1110
0100 1011
1011 0100
+
1
1011 0101
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
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
=
=
=
=
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
+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
and
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
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
Version 1.00
Representation of 1
X FF
X FFFF
X FFFFFFFF
X FFFFFFFFFFFFFFFF
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.
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?
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
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
36
Version 1.00
Bit n of
Operand A
Bit n of
Bit n of
sum A+B
Operand B
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):
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.
37
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
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
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
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.
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.)
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?
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.
41
42
Version 1.00
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.
43
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
Unit
Data
Data
Data
Memory
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
Version 1.00
Control
Central Processing
Inputoutput
Unit
Unit
Data
Data
Memory
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.
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
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?
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
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?
48
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?
Pro
Instruction
gram
Address
Mask
(IA)
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.
21
22
50
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.
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.
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
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)?
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
Registers
RR
RX,
Instruction
RS
SI
SS
Memory
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
register
specification
addressing halfword
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
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
operation
code
addressing halfword
addressing halfword
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?
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
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:
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
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?
56
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
Exercises
4.4.1.(2) Examine the operation codes given in Exercise 4.3.2, and determine their general
instruction classifications from Table 11.
57
no
Any Interrupts?
yes
no
yes
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.
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.
Interruption:
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
IC=3
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
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.
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
IC=D
IC=E
IC=F
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
Version 1.00
1. 0001
2. 0009
3. 000C
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
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
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
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
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?
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.
65
8 bits
4 bits 4 bits
16 bits
opcode
operand index
registerregister
addressing halfword
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
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
Version 1.00
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 .
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 .
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
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.
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.
70
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
Version 1.00
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.
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.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
74
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
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.
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
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.
76
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).
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
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.
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
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
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
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?
81
START 0
progname
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
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.
82
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
READCARD
PRINTLIN
DUMPOUT
CONVERTI
CONVERTO
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.
84
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.
85
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
Version 1.00
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.
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
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
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
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
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
&
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
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?
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.
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
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
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?
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.
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
97
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.
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
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
A+-B,
A*+B,
A+*B,
A/*B,
A-+B
A*-B
A-*B
A//B
Some syntactically valid expressions might not be evaluatable if either or both terms is relocatable
(to be described shortly).
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
100
Version 1.00
is
absolute
simply relocatable
R+R, A-R
complexly relocatable
forbidden
R-R
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.
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
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
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
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
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
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)
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 .
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
X 6D ( POINTER)
P(*-*)
(A-ST)(2+ST)
8(,3)
X(Y-8,Z/2)
(A-B)(A-B,(A-B))
104
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) )
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.
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
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)
107
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.
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
108
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.
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
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
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?
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
R1
X2
B2
D2
110
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.
IC
IC
IC
0,1128(10,7)
0,1128(0,7)
0,1128(7,0)
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)
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
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
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
is translated into the hexadecimal digits 43007468, as in Figure 34. Then if the index register is
GR10, the instruction
IC
0,BYTE(10)
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
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
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.
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
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
Some instructions (like Shift Double) require a register operand to be an even number.
R1
R3
B2
D2
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,S2
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 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
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
Version 1.00
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
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.
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
S1(N 1),S2
Implied Length
D 1(,B1),D 2(B2)
S1,S2
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
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
S1(N 1),S2(N 2)
Implied Lengths
D 1(,B1),D 2(,B2)
S1,S2
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
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)
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.
117
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.
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
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.
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
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
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
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
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.
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.
base_location,base_register
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.
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?
123
6,N
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
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
Version 1.00
125
Read statement
and save it
yes
END ? to Pass 2
no
yes
comment?
no
Instruction symbol in is it in
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
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
10,0
*,10
13,SAVE
1,PARM
14,SUB
0,TBL(15)
18F
A(TBL)
10F
14,12,12(13)
Version 1.00
Read, Print
statement
yes
comment?
no
yes
no
yes
no
yes
return to Supervisor
no
yes yes
machine
implied
compute
instruction?
address?
value
no
no
yes
constant?
data a valid displacement
no
OK
none
note error
addressability
error
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.
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
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
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)
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
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
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.
3.
If more than one base register provides the same smallest displacement, choose the corresponding highest-numbered register.
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
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.
130
Version 1.00
basereg base_location RA
empty
7
00000006 01
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?
131
basereg base_location RA
empty
empty
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
is always present. You can think of the USING Table appearing like this:
132
Version 1.00
basereg base_location RA
0
00000000 00 Assembler s hidden USING-Table entry
etc.
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
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)
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.
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
- - -
How would the assemblers treatment of the Symbol Table be changed? What would happen if
any symbol could be redefined?
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
Version 1.00
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.
137
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
64
138
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.
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
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 ?
F12345678
DC
or
Well see more examples as we investigate various data types.
65
66
140
Version 1.00
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
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
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
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
3F 8
Duplication factor 3
and
Three8s DC
(5/2+1)F 8
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
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.
Three8s DC
This is equivalent to
Three8s DC
3F 8
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
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
144
2F 1 , -1
Version 1.00
LR
R7,R3
2,N
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
DC
F 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 1 0
F 2 , FL2 -2
Equ
has Length Attribute 1. (The EQU assembler instruction is described further in Section 13.3
on page 164.)
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
145
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
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
147
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.
FL1 -10
FL8 -10
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
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
148
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
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
DC
H 5 E-1
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
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
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
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?
151
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
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
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
Version 1.00
ManyChar DC
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
1. DC
2. DC
3. DC
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.
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
CL4345
X00000345
X00000159
X F3F4F540
X00F3F4F5
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
154
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.
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
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
1,2,=F 1 , = F 2
1,=H 1 , = H 2
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
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
Version 1.00
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 )
0,=F1+3
DC
Generates X00000011
which is equivalent to
Message DC
MsgLen DC
C This is a message
A(L Message)
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)
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
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
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
81
160
Version 1.00
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.
DS
F 8
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
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
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?
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
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
Version 1.00
0CL80
0CL8
CL9
0CL5
0CL25
CL6
0CL19
CL20
CL36
C
CL8
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
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.
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
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
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
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
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
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?
Equ
expression1,expression2,expression3,expression4,keyword
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
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
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
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
169
ORG
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
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
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)
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
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
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)
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))
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
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
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
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
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)
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
A(MyData)
Address of MyData
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
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.
that will eventually contain some data. At assembly time, we give the area a name,
area of program
name of area
FDATA
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
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
X 1 A22
DS
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
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.
177
178
Version 1.00
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
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
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.
Mnem
L
Type Instruction
R X Load
Op
50
Mnem
ST
Type Instruction
R X Store
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
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
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
?
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
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)
R1
R3
B2
D2
182
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
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
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.
Mnem
LH
Type Instruction
R X Load Halfword
Op
40
Mnem
STH
Type Instruction
R X Store Halfword
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
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
0,=H 1
LH
0,=H -1
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
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!
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.
Mnem
IC
Type Instruction
RS
Insert Character
Op
42
Mnem
STC
Type Instruction
RS
Store Character
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
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
Becomes C BA
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
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.)
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.
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
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
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
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
188
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
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
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.
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
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.
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
0,1
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
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.
*
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
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
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
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?
0
63
Figure 70. 64-bit general register
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)
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
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
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
Save0123+0
c(GG0)
Save0123+8
c(GG1)
Save0123+16
c(GG2)
Save0123+24
c(GG3)
0,3,Save0123
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
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.
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
XL2
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.
unused
R1
R2
194
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
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)
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
0,1
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.
*
If we compare Figures 72 and 68, we see that these equivalent instructions behave similarly and
produce identical CC settings.
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)
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?
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)
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
0,1
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
196
Version 1.00
signextended s
GG R1
0
63
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
1,=F 0
1,Byte
SR
IC
1,1
1,Byte
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.)
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
B994 LLCR
E390
LLGC
E395
LLH
B995 L L H R
E391
LLGH
E317
LLGT
E316
LLGF
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.
LGB LB s
GG R1
0
(unchanged by LB)
31 32
63
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
198
Version 1.00
(zeroed by LLGC, LLGCR)
zeros
GG R1
0
(unchanged by LLC, LLCR)
63
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.
0
(unchanged by LLH, LLHR)
63
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.
zeros
GG R1
0
63
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.
199
zeros
0bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb GG R1
0
63
0
31
Figure 78. Operation of Load Logical Thirty One Bits instructions
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?
5,8
R5,R8
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
94
200
an R followed by a number
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).
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
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
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.
204
Version 1.00
Rn
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.
205
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.
206
Version 1.00
M1
R2
47
M1
X2
B2
D2
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
Instruction bit
position
8
9
10
11
Mask bit
position
Mask bit
value
0
1
2
3
8
4
2
1
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.)
207
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
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.
208
15,0
M1 is B1111
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)
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
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
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
Version 1.00
CNOP 2,4
BASR 8,11
DC
A(AnyWhere)
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.
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
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.
XX
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
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)
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
XX
Exercises
15.6.1.(2) + Programmers sometime write programs that contain instruction sequences like this:
Loop
Finish
- - - - BNZ Finish
B
Loop
- - -
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:
213
B
Target
- - DC
CL132
Target
He meant to go elsewhere...
132 bytes containing X 4 0
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 *
Can he now be sure his BZ instruction will branch to the intended target?
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
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
Version 1.00
217
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.
Mnem
A
S
AH
Type
RX
RX
RX
Instruction
Add (32)
Subtract (32)
Add Halfword (3216)
E308
E309
AG
SG
Op
1A
1B
4B
Mnem
AR
SR
SH
B308 A G R
B309 SGR
218
Version 1.00
Type
RR
RR
RX
Instruction
Add Register (32)
Subtract Register (32)
Subtract Halfword (3216)
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
Computed answer
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.
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
H 6
F
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
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??
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___________
_____________
_____________
_____________
_____________
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
_____________
_____________
_____________
_____________
_____________
_____________
_____________
_____________
_____________
_____________
_____________
_____________
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
Computed result
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
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
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.
Mnem
CH
C
CY
Type
RX
RX
RXY
Instruction
Compare Halfword (3216)
Compare (32)
Compare (32)
E320
CG
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)
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
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
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
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 )
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
_____________
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
B90A ALGR
B90B SLGR
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)
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.
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
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
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
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
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
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
FD
FD234567898765432
FD123456787654321
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
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
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?
0
No carry
Zero result
1
Carry
Nonzero result
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
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
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
Diff
A
B
LM
SL
SLB
STM
- DS
DC
DC
0,1,A
1,B+4
0,B
0,1,Diff
FD
FD234567898765432
FD123456787654321
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
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?
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)
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
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
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
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
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
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
Version 1.00
SR
0,0
SGR
0,0
and
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
Mnem
CLR
CLGR
CLGFR
EB20 C L M H
Type
RR
RRE
RRE
Instruction
Compare Logical (32)
Compare Logical (64)
Compare Logical (6432)
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
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
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
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
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
234
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
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.
Mnem
IPM
Type Instruction
R R E Insert Program Mask
Op
04
Mnem
SPM
Type Instruction
R R Set Program Mask
R1
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:
235
Bit
36 (F)
37 (D)
38 (U)
39 (S)
Int. Code
8
A
D
E
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
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
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
AR
SR
AGFR
SGFR
AGR
SGR
AL
SL
ALC
SLB
ALGF
SLGF
ALG
SLG
ALCG
SLBG
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 Compare
(to memory)
Arithmetic Compare
(to register)
2 bytes
AH
SH
8 bytes
CH
4 bytes
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
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
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)
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)
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.
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)
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
Version 1.00
241
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
EB0D
EB0B
SLLG
SLAG
EB1D
RLL
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
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)
R1
R3
B2
DL 2
DH2
opcode
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.
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.
243
b c d e x y z 0 0
a
bit bucket
After
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
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
8,1(0)
Suppose GR8 again contains X87654321 and GR3 contains X82F3A2B5 , executing the logical
right-shift instruction
SRL
8,16(3)
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.
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
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
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)
246
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.
(explicit address)
(implied address)
0,=A(X12345678)
0,9
c(GR0) initialized
c(GR0) = X68ACF000
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.
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.
SR
SRDL
LTR
BZ
A
SLL
7,7
6,3
7,7
A
6,=F 1
6,3
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
Version 1.00
ShiftL
L
L
SLDL
LTR
BNZ
ST
5,N
4,=F 0
4,1
5,5
ShiftL
4,N
L
SRDL
LTR
BNM
SLDL
ST
4,N
4,1
5,5
ShiftR
4,1
4,N
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
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
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
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
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
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.
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.
252
Version 1.00
Operation
Left shift
Right shift
Result is zero
Result is < zero
Result is > zero
Result has overflowed
Result is zero
Result is < zero
Result is > zero
Cannot occur
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
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
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
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
Version 1.00
0,=A(X87654321)
0,9
c(GR0) initialized
c(GR0) = X FFC3B2A1
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:
255
[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
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?
After
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
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.
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.
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)
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
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
258
Version 1.00
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
7,=F 1 5
FL3 8
FL3 8
FL.24 8
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
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
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
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
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
32
64
SLAG
SRAG
SLLG
SRLG
RLLG
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
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
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
262
Version 1.00
263
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:
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
B90C
MSGR
B91C
B996
B986
264
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.
Mnem
M
Type Instruction
R X Multiply (32 + 323232)
Op
1C
Mnem
MR
Type Instruction
R R Multiply Register
(32 + 323232)
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(GR1) * c(GR1)
c(GR9) * c(GR8)
c(GR5) * c(XX)
= c(GR13) * 932
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
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 (??)
266
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
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
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
E351
MSY
E30C
MSG
Multiply Single
(323232)
RXY Multiply Single
(323232)
RXY Multiply Single
(646464)
B90C
MSGR
E31C
MSGF
B91C
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
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
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
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
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?
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 . . .
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
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)
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
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
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.
271
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
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
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
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)
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
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)
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
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.
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)
The Divide Single instructions (DSG, DSGR, DSGF, and DSGFR) have only a single-length
dividend; well examine them shortly.
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
8,13
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
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
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
276
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
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
Because 236 is not less than 10231, a fixed-point divide interruption will occur.
277
////////////////////
Dividend
Divisor
R2 or D2(X2,B2)
(in register or memory)
Figure 134. Operands of single-length division before division
Remainder
Quotient
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
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
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)
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
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
0,=X FFFFFFF8
1,0
0,=X FFFFFFFF
Initialize GR0
And GR1, with the same bits
Divide by 2**32-1
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.
280
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
1 628 430
- 762
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.
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)
00111 01100
00001 01101
00010 11010
00101 10100
01011 01000
00101 01001
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)
(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
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
The divide instructions discussed in this section are shown in Table 91.
Function
32 + 32
32
Arithmetic
D
DR
Logical
DL
DLR
64
64 + 64
64
64
64
64
32
64
DSG
DSGR
DSGF
DSGFR
DLG
DLGR
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:
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
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
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.
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
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
Version 1.00
287
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)
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
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
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.
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:
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
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?
0,DataWord
0,6
0,13
1,19
1,Third
0,DataWord
0,13
0,19
0,Third
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
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
MaskC
L
0,DataWord
N
0,MaskC
L
1,NewThird
SLL 1,6
OR
0,1
ST
0,DataWord
- - DS
0F
DC
X FFF8003F
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.
1,1
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
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
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
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
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.
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
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
0,DataWord
1,NewThird
1,6
1,0
1,Mask3
0,1
0,DataWord
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.)
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
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
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.
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
6.
0,=F 1 2
1,0
1,0
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
8.
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
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?
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
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
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
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?
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
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
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
Version 1.00
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.
301
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
R1
X2
B2
DL 2
DH2
opcode
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
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
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 .
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
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.
R1
Op
RI 2
Opcode
R1
Op
RI 2
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
Version 1.00
RI2
signextended sbbbbbbbbbbbbb0
Add to
Effective Address
RItype instruction
Shift left 1 bit
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
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
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?
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
00000
.....
00000
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
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
0
31 32
63 64
127
Figure 150. z System PSW showing addressing-mode bits
B
0
1
0
1
Addressing mode
24-bit mode
31-bit mode
Invalid combination
64-bit mode
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
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.
Mnem
LA
LARL
Type Instruction
R X Load Address
RIL Load Address Relative Long
Op
Mnem
E371 LAY
Type Instruction
RXY Load Address
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
309
LA
r,n(0,0)
requiring 8 bytes (4 for the instruction and 4 for the constant generated by the literal), or
2,=H 1
LH
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!)
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
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
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
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.
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) ?
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)
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)
6,=A(X FFFFFF00 )
3,-1
312
Version 1.00
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)
region index
segment page
byte
index
index
index
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
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.
AMode = 64
Effective Address in
bits 0-63.
314
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.
315
316
Version 1.00
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
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
In RIL-type instructions, the immediate operand I2 occupies a word, the last 32 bits of the 48-bit
instruction.
opcode
R1
Op
I2
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
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
Version 1.00
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
A51
IIHL
RI
A52
IILH
RI
A53
IILL
RI
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
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
except that IILH avoids a memory reference. Similarly, these two are equivalent:
ICMH 3,B1111,=F -3
IIHF 3,-3
You can think of the IILF instruction as though its a Load Immediate instruction: 130
***
IILF 11,123456789
L
11,=F123456789
LI
11,123456789
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.
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
C0E
LLIHF
RIL
C0F
LLILF
RIL
A5C
LLIHH
RI
A5D LLIHL
RI
A5F
RI
A5E
LLILH
RI
LLILL
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
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
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
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
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
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
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
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
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?
Mnem
AHI
Op
A7B
Mnem
AGHI
AFI
Type Instruction
RI
Add Halfword Immediate
(3216)
RIL Add Immediate (32)
C29
C28
AGFI
C2B
ALFI
RIL
C2A ALGFI
RIL
C25
SLFI
RIL
C24
RIL
SLGFI
Type Instruction
RIL Add Halfword Immediate
(6416)
RIL Add Immediate (6432)
Add Logical Immediate
(6432)
Subtract Logical Immediate
(6432)
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
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
Version 1.00
Mnem
CHI
Type Instruction
RI
Compare Halfword Immediate (3216)
Op
A7F
Mnem
CGHI
Type Instruction
RI
Compare Halfword Immediate (6416)
C2D
CFI
RIL
C2C
CGFI
RIL
Compare Immediate
(6432)
C2F
CLFI
RIL
C2E
CLGFI
RIL
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
CH
2,NN
CHI 2,NN
- - DC
H 4 2
Mnem
MHI
Type Instruction
RI
Multiply Halfword Immediate (3216)
Op
Mnem
A7D M G H I
Type Instruction
RI
Multiply Halfword Immediate (6416)
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
and if the product and operands are larger, you can use IILF:
L
1,Operand2
IILF 15,629036721
MR 0,15
131
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.
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)
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
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
324
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
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
Mnem
XIHF
Type Instruction
RIL XOR Immediate (high)
(6432)
Op
C07
Mnem
XILF
Type Instruction
RIL XOR Immediate (low)
(6432)
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
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
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.
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
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
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
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
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
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.
328
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.
329
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.
M1
RI 2
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
For RIL-type branch instructions the value of the RI 2 operand lies in the range
231 RI2 2311, or
2147483648 RI2 2147483647
330
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
3,12
8,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
3,12
*+10
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
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
332
Version 1.00
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
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
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
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
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.
Mnem
BCT
Type Instruction
R X Branch on Count (32)
E346
BCTG
A76
BRCT
RI
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)
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
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.
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
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
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
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
Version 1.00
LM
LCR
LCR
JZ
BCTR
STM
XXX
6,7,Arg
6,6
7,7
XXX
6,0
6,7,Arg
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
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
Version 1.00
Loc
____
____
____
____
____
____
____
____
____
____
____
____
____
____
Object Code
_____________
_____________
_____________
_____________
_____________
_____________
_____________
_____________
_____________
_____________
_<32 bytes>__
_____________
_____________
_____________
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
(2) X
A
0,=F -1
0,=F 1
(5) S
X
0,=F 1
0,=F -1
(3) X 0,=F -1
AL 0,=F 1
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
Initialize index,
loop
add increment
compare to
done
increment, comparand body to index
comparand
not done
Figure 173. Sketch of a Do-Until loop
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,
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?
341
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)
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
BXHG and BXLEG are RSY-type instructions that also require R 1 and R 3 operands:
opcode
R1
R3
B2
DL 2
DH2
opcode
The relative-immediate forms of the branch on index instructions use two different instruction
formats, RSI and RIE:
opcode
R1
R3
RI 2
opcode
R1
R3
RI 2
opcode
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
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
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
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
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.
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
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
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
(NCubes)F
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
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
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)
SR
LA
LA
SLA
JM
JXLE
- - -
0,0
2,1
3,32
1,1
Y
0,2,X
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)
3,=F -2147483647
(-231+1)
346
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?
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
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.
347
will branch to XXX only if the contents of GR4 is less than or equal to zero. Similarly,
BXH
4,9,YYY
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
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
348
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
1,1,Yes
0,1,Yes
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
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.
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)
Register Length
32 bits
64 bits
BCTR
BCTGR
BCT
BCTG
BRCT
BRCTG
Branch on Index
BXH
BXLE
BXHG
BXLEG
BRXH
BRXLE
BRXHG
BRXLG
Operation
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
350
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
Version 1.00
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.
353
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.
I2
B1
D1
opcode
I2
B1
DL
DH
opcode
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
Version 1.00
Operation
Move
Mnemonic
MVI, MVIY
Action
CC set?
No
Operand 1 I2
AND
NI, NIY
Yes
OR
OI, OIY
Operand 1 Operand 1 OR I2
Yes
XOR
XI, XIY
Yes
CLI, CLIY
TM, TMY
Operand 1 Compared to I 2
Test Selected Bits of Operand 1
Yes
Yes
Compare
Test Under Mask
Mnem
MVI
Type Instruction
SI
Move Immediate
Op
Mnem
EB52 MVIY
Type Instruction
SIY Move Immediate
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
at X to zero
at X to all 1-bits
character Y at X
blank at X
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
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
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
355
The CC settings after NI, OI, and XI are shown in Table 133:
Operation
AND
OR
XOR
CC setting
0:
1:
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
Sometimes it is better to use other types of self-defining term for the second operand; example (2)
could be written
NI
X,B11111101
OI
OI
X,255
X,B00000010
(5)
LowerA
OI
DC
LowerA,C
C a
c(LowerA) now is C A
Lower case letter a
XI
X,B0000010
Inverts bit 6 at X
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.
Mnem
CLI
Type Instruction
SI
Compare Immediate
Op
Mnem
EB55 CLIY
Type Instruction
SIY Compare Immediate
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
Version 1.00
CC
0
1
2
Indication
Operand 1 = I 2
Operand 1 < I 2
Operand 1 > I 2
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
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
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.
Mnem
TM
Type Instruction
SI
Test Under Mask
Op
Mnem
EB51 TMY
Type Instruction
SIY Test Under Mask
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
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
Num+L Num-1,1
Even
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
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
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
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
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.
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
B10000000
Define the young-person bit
Status,X FF -Under25
He s getting older now
B00010000
Status,Married
Bigamy
Status,Married
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
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
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?
DS
Equ
DS
Equ
X
X 8 0
X
X 4 0
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
Flag1,Bit1
MoreCode
TM
JZ
Flag2,Bit0
WhatCode
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
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
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
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.
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
363
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
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
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
Figure 195. Adding alternate list elements twice, without program modification
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
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.
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
TM
TMY
I2
Function
Operand 2
I2
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
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
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.
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
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
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
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)
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
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
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)
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?
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
0,=F 6
0,X D4 ( 0 , 7 )
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
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
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
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
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
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
(while clumsy) is valid; its better to define a constant named by a symbol, and then use the
length attribute of the symbol:
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
Version 1.00
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
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).
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
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
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
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
Temp
A
B
MVC Temp,A
MVC A,B
MVC B,Temp
- - DS
XL2
DS
H
DS
H
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.
Chars
CRev
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
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.
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
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
Version 1.00
Data
Result
MVC Result,Data
- - DC
C Data
DS
CL8
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)
DC
DS
DS
C987654ABCDE
CL4
CL(L D-L E)
377
Line(120),Line
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
NC
JZ
Lump(4),Lump
Yes
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
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
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
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
Does this work? What will be found at BitChars? Explain your answer.
Line(120),=CL120
AllBlank
CLC
JE
=CL120 , Line
AllBlank
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
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
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.
379
Test
LA
LA
CLC
JE
LA
JCT
J
1,List
2,100
0(60,1),WhoIsIt
Found
1,60(,1)
2,Test
NotFound
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)
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
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
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
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
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
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.
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))
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?
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
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.
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
C abc123def
C *abcdef*
C AB7
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.
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
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
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
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
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
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
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
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
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
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.
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.
Mnem
EX
Type Instruction
RX
Execute
Op
C60
Mnem
EXRL
Type Instruction
RIL Execute Relative Long
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
Version 1.00
1,1
2,4
3,12
0,Inst(1)
1,2,Execute
0,A
0,0
0
0,B
0,CCC
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
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.
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
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.
Move
BCTR 9,0
EX
9,Move
- - MVC Line(*-*),0(8)
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
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
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
392
Version 1.00
NotMet
BCInst
L
1,Mask
SLL 1,4
EX
1,BCInst
- - - - BC
0,CondMet
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
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.
0,*
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
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.
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
This is not generally recommended, because the CPU must process the MVC instruction twice.
394
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
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
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-
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
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
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
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)
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?
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
398
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
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
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
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
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:
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 ...
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
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 .
403
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.
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
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
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
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
Version 1.00
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
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
No Execute instruction (or STC, to store a length byte into an MVC) was needed to supply the
Length Specification Byte for the move.
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
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
Version 1.00
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
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
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
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
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
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
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.
R1
R3
B2
DL 2
DH2
opcode
411
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
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
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
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
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
As another example, suppose we use MVCLE to initialize a large area of storage starting at Work
to zeros:
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
32000
20000
A(BlockLen*NBlocks)
Large area
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
Meaning
All bytes compared, operands equal, or both zero length
First operand low
First operand high
Some bytes compared without finding an inequality
414
Version 1.00
2,Line
3,120
0,0
1,1
2,0,C
AllBlank
Compare
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.
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
R1
R2
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.
string to be searched
416
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
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?
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
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.
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.
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
A1=A1+1
A2=A2+1
No
Yes
Enough
Done; Set CC3
for now?
418
Version 1.00
Move
Old
New
XR
LA
LA
MVST
JO
- - DC
DS
0,0
1,Old
2,New
2,1
Move
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
C LIST,OBJECT,XREF,ADATA,
String of tokens
CL20
Reserve space for longest token
H
Length of current token
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.
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.
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
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
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
=
/=
Yes
No
A1=A1+1
A2=A2+1
Set CC1
Done
No
Yes
Enough
Done: Set CC3
for now?
Comp
XR
LA
LA
CLST
JO
JE
JH
J
0,0
7,A
5,B
7,5
Comp
Equal
A_High
A_Low
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
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.
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
422
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
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
,
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?
423
Mnem
CUSE
Type Instruction
R R E Compare Until Substring Equal
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
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
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
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
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
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.)
427
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
428
Version 1.00
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.
157
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
,
(
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?
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
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
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 @#$|{[]}
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
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
sbsbSOdbdbdbdbdbdbSIsbsbSOdbdbdbdbSIsbsb
3 DB characters
2 DB chars
Figure 242. Mixed single- and double-byte EBCDIC characters
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)
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
434
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 .
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<>
Constants and terms are padded on the right with DBCS blanks:
DC
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<>
Both G-type and C-type constants are padded on the right with EBCDIC blanks:
DC
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
Equ
Equ
G < . A>
C < . A>
Has value
Has value
X000042C1 ( no shifts)
X 0 E42C10F ( with shifts)
436
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
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.
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
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.
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
CU 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
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
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
440
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
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.
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
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
A(BlockLen*NBlocks)
Length of work area
32000
...containing 32000 blocks,
20000
...each 20000 bytes long
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
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
Warning!
Comparing and sorting character data in EBCDIC and Unicode can give
very different results, because the character encodings are quite different.
R1
R2
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
442
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
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:
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 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.
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.
444
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
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.
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
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
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
B9B3 CU42
B9B2
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.
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
Repeat
LA
LA
LA
LA
TROT
JO
1,PH
2,Target
3,L Source
4,Source
2,4,1
Repeat
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.
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
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
When your program manipulates multi-byte data, youll want to know where it originated.
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)
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.
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
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.
unchanged
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
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
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
Function
1 byte
1 byte
TROO
2 bytes
TRTO
2 bytes
1 byte
TROT
2 bytes
TRTT
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
Operand1
Operand2
4 bytes
2 bytes
LRVH
4 bytes
LRV
8 bytes
8 bytes
LRVG
STRVH
LRVR
STRV
LRVGR
STRVG
452
Version 1.00
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.
453
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
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.
Z n Z n Z n Z n Z n
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
Version 1.00
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
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.
A
+
C
+
E
+
F
+
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
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
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
Version 1.00
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
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
DC
DC
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
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
DC
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
(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
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
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
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
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
Version 1.00
DC
DC
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
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
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.
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
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.
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
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)
463
A,B
A(7),B
24(,9),B
24(7,9),B
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
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
Version 1.00
F 1 F 2 F 3 F 4 C 5
1 2 3 4 5 C
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
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
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
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
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
Version 1.00
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
PACK P,P
- - DC
X ABCDEF
Q
P
PACK
- - DS
ORG
DC
Q,P
XL3
Q+1
X ABCDEF
Result field
Source field starts at Q+1
Source field
467
Q
P
PACK
- - DS
ORG
DC
Q,P
XL3
Q-1
X ABCDEF
Result field
Source field starts at Q-1
Source field
d d d d d S Packed operand
Z d Z d Z d Z d S d Zoned operand
Figure 277 shows how to convert the packed value +12345 to zoned form.
ZonOp
PackOp
UNPK ZonOp,PackOp
- - DS
ZL5
DC
P12345
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
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
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
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
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
P
UNPK
- - DC
Org
DC
U,P
Unpack P operand to U
XL6 0
U+3
X123456
U
P
UNPK
- - DC
Org
DC
U,P
Unpack P operand to U
XL6 0
U+4
X123456
Answer
Start
UNPK Answer,Start
- - DS
ZL7
DC
P76543
471
B1
D1
B2
D2
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
Version 1.00
B1
D1
B2
D2
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
PL1698765432
CL12
CL24
PDec
AChar2
UChar2
UNPKA
UNPKU
- - DC
DS
DS
AChar2,PDec
UChar2,PDec
PL1698765432
CL7
CL14
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.
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
A
PA
PKA PA,A(30)
- - DC
10X ABCDEF
DS
PL16
Zoned operand
Packed operand
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
Version 1.00
Chars
Data
UNPK Chars(8),Data(4)
- - DS
CL8
DC
X1234ABCD
Chars
Data
UNPK
- - DS
DC
DS
Chars(9),Data(5)
CL8,C
X1234ABCD
X
Char
Data
TRTab
UNPK
TR
- - DS
DC
DC
Char(9),Data(5)
Char(8),TRTab-X F0
CL8,CL1
F -5026
C0123456789ABCDEF
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 ?
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
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
476
Version 1.00
Zoned Unicode
PKU
UNPKU
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 .
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.
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
478
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
(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)
172
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 + )
Meaning
Operand 1 = Operand 2
Operand 1 < Operand 2
Operand 1 > Operand 2
480
99999+
2-
(1st operand)
(2nd operand)
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
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+
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
Version 1.00
(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 .
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
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
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
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)
485
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:
+
486
first operand
2 s complement of second operand
uncorrected sum, high-order carry
carries
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
uncorrected sum
add correction, no propagation
final true sum
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
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
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:
+
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
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:
487
+
68A
+ AAA
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
Version 1.00
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
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).
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)
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
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
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.
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
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.
Indication
Result is zero.
Result is less than zero.
Result is greater than zero.
Decimal overflow.
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
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
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
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
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
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!)
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
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
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
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.
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
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
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
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
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
1 N 2 8,
N1 > N 2
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
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)
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
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
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
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
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
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
MP
B,B+3(1)
- - DC
PL4567
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
Dvnd
ZAP Dvnd,=P162843
DP
Dvnd,=P762
- - DS
PL4
Initialize dividend
Divide by 762+
Space for quotient and remainder
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
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
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 ?
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
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
DP
B,B+3(2)
- - DC
PL5567
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?
179
502
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
Table 208 shows the assembled machine instruction. format of the SRP instruction:
F0
L1
I3
B1
D1
B2
D2
A,64-2,0
A,64+2,0
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.
503
SRP A,3,0
- - DC
P12345
SRP A,64-2,0
- - DC
P12345
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
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
In Section 29.9 we will see examples showing why SRP is such a useful decimal instruction.
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
29.7.5.(2) What will be the result at X1, X2, and X3 after executing these SRP instructions?
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
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
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.
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
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.
507
MVO A,B
MVO C,D
- - DC
P678
DC
PL4 -5
B
A
*
- - DC
P987654321
DC
PL3555
D
C
*
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
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.
MVO A,A(1)
- - DC
P12345
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)
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.
509
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
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
This technique can of course be used for single left shifts, but the method of Figure 312 is
simpler. (See Exercise 29.9.3.)
510
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.
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+
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
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
This NC instruction does the same zeroing as the two NI instructions in Figure 315.
B
A
MVN A+1(1),A+2
- - DS
0PL2
DC
PL312345
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.)
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
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
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.
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
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
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.
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
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
515
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
516
Version 1.00
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.
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
(3.2)
(3.0)
(0.3)
(1.4)
(1.2)
(7.2)
(7.2)
Next, the wholesaler uses this data and the work areas to calculate the retailers bill:
ZAP
*
MP
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
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
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
X0024000C
X000000000492467C
X000000000392467C
X000392467C
(5.2)
(13.2)
(13.2)
(7.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.
518
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
(5.2)
(3.0)
(5.2)
(1.2)
(1.4)
(3,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
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
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%.
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.
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
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)
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)
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
Version 1.00
29.12. Summary
Some properties of the instructions discussed in this section are summarized in Table 209.
Mnemonic
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
521
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.
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
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)
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
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
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.
524
Version 1.00
For CVB and CVBY, the low-order 32 bits of the twos complement binary result are
placed into register R1.
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
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?
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
B1
D1
B2
D2
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.
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
Version 1.00
by
C dddsdCRfdsd
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
527
PgNo
TtlP
TtlPgN
UNPK
OI
- - DC
DC
DS
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
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
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.
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
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
Version 1.00
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
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
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
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.
PayAmt
PayPat
Line
LPat
MVC
EDMK
AHI
MVI
- - DC
DC
DC
DS
LPat,PayPat
LPat,PayAmt
1,-1
0(1),C $
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
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 $
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:
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)
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 ?
534
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
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?
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
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
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
Version 1.00
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
537
538
Version 1.00
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.
539
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.
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
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
Version 1.00
word size
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.
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
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
PDAmt
PDTax
PDProd
ZAP PDProd,PDAmt
MP
PDProd,PDTax
SRP PDProd,64-5,5
- - DC
P11749.49
DC
P.05147
DS
PL8
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 . . .
544
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.
DC
DC
FS(28) 2
FS(28) 1
2, scaled by 2**28
1, scaled by 2**28
X20000000
X10000000
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
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
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
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
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.
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
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.
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.
sign exponent
significant
s
e
digits
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
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
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 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
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
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
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
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?
4 bytes
Short
8 bytes
Long
16 bytes
Extended
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.
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
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
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:
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?
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
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)
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.
193
555
Op
38
Mnem
LER
Type Instruction
RR
Load FPR from FPR
(Short)
B365
LXR
B373
B370
Op
28
Mnem
LDR
Type Instruction
RR
Load FPR from FPR
(Long)
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.
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)
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
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)
As the instruction names indicate, these two instructions move 64-bit operands. For example:
LDGR 4,13
LGDR 1,6
Mnem
CPSDR
Type
RRF
Instruction
Copy Sign (Long)
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?
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
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
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
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
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
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.
560
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)
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)
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.
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.
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.
7 3 0 0.
k = -2
X = 73
0 7 3 0.
k = -1
X = 73
0 0 7 3.
k = 0
X = 73
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?
564
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
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
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
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.
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
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
569
Representable Values
Exponent Values
2Emax
Products, Quotients
MaxReal 6
0
Normal Range
MinReal 7
Emin
Underflow Threshold
Products, Quotients
2Emin
Unrepresentably Small 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
Version 1.00
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.
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.
572
Version 1.00
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.
573
S char 6 digit fraction
Short: 4 bytes
FPF(16,6)
0
8
31
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
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
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 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
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
e
.000000000001
Fraction-exponent
representation
0.1100
.314159...10 + 1
.271828...10 + 1
.110 11
99999999
A8885A30
1628AED2
812DEA11
32999999
338D3131
33A6ABF7
29197F27
9999999A
98A2E037
158809CF
F0F6E886
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?
[dup_factor]type[modifiers] value[dec_exponent]
Like many other numeric constants, you can provide several value[dec_exponent] values separated by commas.
where
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.
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
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.
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
The previous rules for using literals also apply to hexadecimal floating-point literals.
578
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.
Generated Constant
X412B83B0
EL32.71965
X412B84
EL22.71965
X412C
EL12.71965
X 4 1
(Error!)
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.
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.
EE21,20,3E3,4E22
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
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
DC
DC
DC
DC
DE5 3 . 7 E-2
EE-25 1 . 0 E80
LE2 8 . 8 E-2
EE9 4 E9
Doubleword aligned
Quadword aligned
Align to quadword boundary
Quadword-aligned character string
To be sure your constants and data are correctly aligned on quadword boundaries when your
program is loaded into memory for execution,
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 )
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
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
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
EH ( DMin)
DH ( DMin)
LH ( DMin)
X00000001
X00000000 00000001
X00000000 00000000 72000000 00000001
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
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?
583
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
B363 LCXR
B360 L P X R
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.
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
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
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
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
*
*
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
585
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.)
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
586
Version 1.00
FPR2 Before
//////// ////////
41500000 ////////
Operation
LE
2,W
MEE
2,Y
FPR2 After
41500000 ////////
42230000 ////////
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
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)
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
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.
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
Exact product
Exact product
MEE, MEER
6 digits;
FPR R 1
14 digits
28 digits
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
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
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
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.
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)
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
590
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
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
Mnem
HER
Type Instruction
R R Halve (Short)
Op
24
Mnem
HDR
Type Instruction
R R Halve (Long)
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.
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)
0,=EH ( Min)
0,0
c(FPR0) = X00100000
Result = X 7 F800000 with 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
0,0
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.
592
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
2E
AWR
RR
6F
SW
RX
2F
SWR
RR
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
58123456(0)
+58000000(9)
58123456
Because the sum need not be normalized, the guard digit is lost.
Subtraction can be different; consider the same two operands:
58123456(0)
-52987654
58123456(0)
-58000000(9)
58123455
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
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
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
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
0,=X 7 FFE7654
0,=X 7 EFEDCBA
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
Const
L
1,=F12345
ST
1,Const+4
LD
0,=D 0
AD
0,Const
- - DC
0D,X 4E , 7 X 0
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
Exercises
596
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
=
=
=
=
=
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
=
=
=
=
=
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.
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
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.
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
600
42
.000DCF1
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
42
42
.1111110
.FEEEEEF
(1).0FFFFFF
Example 10:
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.
Example 11:
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
601
40
40
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
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)
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
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
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.
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
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.
603
LRER 0,2
STE 0,Rounded
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
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
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
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
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
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
E
E
Rounded result
These examples only show how rounding works; its far simpler to use the CPUs rounding
instructions, not these.
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)
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:
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.
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
606
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
c(FPR4)=X44D43100
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)
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
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
607
M3
R1
R2
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
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.
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
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
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.
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
610
Version 1.00
(a)
LE
0,HFP_Number
CFER 3,0,0
(b)
LE
0,HFP_Number
CGER 3,0,0
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
Pseudo-zero, exponent=14
Long HFP source data
Integer result
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)
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
Hex 33.5678
c(FPR2) = X4234000
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
E
E 2 0
E 1 6
Remainder
A value for A
And for B
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
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.
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)
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
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?
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)
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
R3
X2
B2
D2
R1
614
Version 1.00
opcode
MAE R1,R3,D2(X2,B2)
MAE R1,R3,S2
MAER R1,R3,R2
Explicit address
Implied address
4,=E 2 5
2,=E123
2,4,=E 4
Operand_3 in FPR4
Operand_1 in FPR2
Operand_2 = 4.0
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
4,=X60987654
4,=X60234567
4,=X FFFFFFFF
Operand_3
Operand_2 in memory
Operand_1
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.
615
0,=D 0 . 0
SWR
0,0
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.
616
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
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
4 bytes
DER
Operand Length
8 bytes
16 bytes
DDR
DXR
DE
DD
HER
HDR
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
Source Length
Result Length
8 bytes
4 bytes
LRER
LEDR
Round
16 bytes
4 bytes
LEXR
16 bytes
8 bytes
LRDR
LDXR
Function
8 bytes
LDER
LDE
4 bytes
16 bytes
LXER
LXE
8 bytes
16 bytes
LXDR
LXD
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
The instructions for converting binary integer operands to hexadecimal floating-point are summarized in Table 260.
Function
Source Length
Target Length
32 bits
4 bytes
8 bytes
CEFR
CDFR
64 bits
16
bytes
CXFR
4 bytes
8 bytes
CEGR
CDGR
16
bytes
CXGR
The instructions for removing the fraction part of hexadecimal floating-point operands (that is,
extracting the integer portion) are summarized in Table 261.
618
Version 1.00
Function
Operand Length
Form floating-point integer
4 bytes
FIER
8 bytes
FIDR
16 bytes
FIXR
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
Operand Length
4 bytes
8 bytes
MAER
MADR
MAE
MAD
MSER
MSDR
MSE
MSD
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
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
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.
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
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.
623
624
Version 1.00
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
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
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.
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
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.
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
The first number has characteristic value 127 and zero fraction, so its value is
(1.0)2127 127 = 1.0.
S
0
Char.
00000000
Fraction
00...011000010
Representation
X000116C2
Largest Denorm
00000000
111........111
X007FFFFF
Smallest Denorm
00000000
000........001
X00000001
627
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.
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
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
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
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.
DB
LB
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
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... .
629
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
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
R4
R5
R6
R7
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
The Assembler also supports nominal-value operands for special values, as shown in Table 268.
630
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
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
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
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.
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.
Short
Long
Extended
Normal values
Special values
9
11
11
14
16
18
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
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
632
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?
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 +
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)
Round toward +
Round toward
Most of the conversion instructions between binary floating-point and binary integers provide a
local rounding mask.
212
633
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
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
Version 1.00
Fn =
| | + | | =
Fn =
Fn = 0
Fn 0 =
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.
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
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
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
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)
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
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
B 1 0
Up (toward + )
B 1 1
Down (toward )
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
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
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
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
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.
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.
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
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.
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.
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.
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.
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.
639
Data length
Short
Long
Extended
Scale Factor
192
1536
24576
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.
640
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)
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
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
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
LA
9,B110000
TCEB 2,0(,9)
JNZ AnInfin
or
Exercises
34.5.1.(2) Given a binary floating-point operand in FPR0, which data classes will these
instructions detect?
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
Mnem
LTEBR
Type
RRE
Instruction
Load and Test (Short)
Op
B303
Mnem
LCEBR
Type
RRE
B301
LNEBR
RRE
B300
LPEBR
RRE
B312
LTDBR
RRE
B313
LCDBR
RRE
B311
LNDBR
RRE
B310
LPDBR
RRE
B342
LTXBR
RRE
B343
LCXBR
RRE
B341
LNXBR
RRE
B340
LPXBR
RRE
Instruction
Load Complement
(Short)
Load Positive (Short)
Load Complement
(Long)
Load Positive (Long)
Load Complement
(Extended)
Load Positive
(Extended)
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
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
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
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?
643
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.)
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
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
Version 1.00
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)
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
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
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.
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)
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
LD
DDB
0,=DB987654321
0,=DB 3
The quotient is rounded according to the current rounding mode in the Floating-Point Control
Register.
646
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
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
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?
647
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)
Meaning
Result is zero
Result is < zero
Result is > zero
Result is a NaN
For example:
LE
AEB
2,=EB 2 . 5 5
2,=EB -2.77
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
648
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) (+ ) (+ )?
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)
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
+ 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.
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.)
Remember that Condition Code 3 does not occur for hexadecimal floating-point comparisons.
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)
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
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
Version 1.00
Mnem
LEDBR
Type
RRE
Instruction
Load Rounded
(ShortLong)
B345
LDXBR
RRE
Load Rounded
(LongExtended)
Op
B346
Mnem
LEXBR
Type
RRE
Instruction
Load Rounded
(ShortExtended)
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
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.
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)
651
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
LE
0,=EB ( SNaN)
LDEBR 2,0
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.
=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
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)
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
Because the value in register GG1 is small enough, the result in FPR6 needed no rounding.
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)
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
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
+
+
+
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
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)
Meaning
Source was zero
Source was less than zero
Source was greater than zero
Special case
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.
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?
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)
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:
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)
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.
Mnem
DIEBR
Type
RRF
Instruction
Divide to Integer (Short)
Op
Mnem
B35B DIDBR
Type
RRF
Instruction
Divide to Integer (Long)
R3
M4
R1
R2
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
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)
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
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
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:
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
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.
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)
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)
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!
Mnem
MAEB
Type
RXF
Instruction
Multiply and Add (Short)
Op
Mnem
B30E MAEBR
Type
RRF
ED1E
MADB
RXF
B31E M A D B R
RRF
ED0F
MSEB
RXF
B30F MSEBR
RRF
ED1F
MSDB
RXF
B31F MSDBR
RRF
Instruction
Multiply and
(Short)
Multiply and
(Long)
Multiply and
(Short)
Multiply and
(Long)
Add
Add
Subtract
Subtract
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:
659
LE
2,Operand2
LE
6,Operand1
MAEBR 6,2,2
LE
2,Operand2
MEEBR 2,2
AEB 2,Operand1
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
Operand Length
8 bytes
16 bytes
ADBR
AXBR
SDBR
SXBR
ADB
SDB
CDBR
CXBR
CDB
Version 1.00
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
Source Length
Result Length
Round
8 bytes
4 bytes
LEDBR
16 bytes
4 bytes
LEXBR
16 bytes
8 bytes
LDXBR
Function
4 bytes
8 bytes
16 bytes
LDEBR
LXEBR
LDEB
LXEB
8 bytes
16 bytes
LXDBR
LXDB
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
The instructions for converting binary integer operands to binary floating-point are summarized in
Table 310.
Function
Source Length
Target Length
32 bits
4 bytes
8 bytes
CEFBR
CDFBR
64 bits
16
bytes
CXFBR
4 bytes
8 bytes
CEGBR
CDGBR
16
bytes
CXGBR
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 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.
662
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:
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
664
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.
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
Version 1.00
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.
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 d d d d d d d d d d d d d d d d d d Decimal
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
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
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
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
Version 1.00
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.)
220
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
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
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
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.
s Combination
Trailing Significand Field
Field (CF)
(TSF) or (T)
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
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.
Meaning
NaN
Infinity
Finite numbers
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
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
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)
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
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?
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?
DD
DC ED123.4567
LD
7 digits
DC DD12345678.90123456
16 digits
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
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
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
Unlike hexadecimal and binary floating-point zeros, decimal floating-point zeros can have a wide
variety of representations.
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
677
DC ED123.4567
DC ED123.45678R10
DC ED123.45678R14
Default rounding
Rounded to +infinity
Rounded away from zero
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
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
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
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)
+ sign
sign
52
54
56
58
60
62
53
55
57
59
61
63
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
Table 323 shows another way to visualize the left-to-right order of the test bits and the tested
classes:
680
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
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.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
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.
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
-DMin is selected for for rounding toward or for rounding away from zero
Otherwise, 0 is selected.
+DMin is selected for for rounding toward + or for rounding away from zero
Otherwise, 0 is selected.
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
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.
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
Version 1.00
123.45
+ 6.228
129.678
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
If the result is inexact, a different rule is needed. Using 7-digit precision, suppose we add:
123.45
+ 6.22801
129.67801
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
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
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
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...
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...
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
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.
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
Version 1.00
8
8
8
8
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
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.
Mask bit = 0
The result is the cohort member with
quantum closest to the preferred quantum.
The q flag bit is set to 1.
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.
Extended
9216
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?
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?
Mnem
CPSDR
Type
RRF
Instruction
Copy Sign (Long)
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)
6,3
0,2
Mnem
LER
B365
LXR
Type Instruction
RR
Load FPR from FPR
(Short)
R R E Load FPR from FPR
(Extended)
Op
28
Mnem
LDR
For example:
686
Version 1.00
Type Instruction
RR
Load FPR from FPR
(Long)
LER
LDR
LXR
5,8
4,2
1,12
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
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)
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
687
opcode
R3
M4
R1
R2
Effect
Mask
Effect
B1000
B1001
Round toward 0
B1010
Round toward +
B1011
Round toward
B1100
B0101
Round toward 0
B1101
B0110
Round toward +
B1110
B0111
Round toward
B1111
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
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
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.
Quantum = .001
Quantum = .00001
Quantum = .00001
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
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
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
690
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
Meaning
Operands are
First operand
First operand
Operands are
equal
is low
is high
unordered
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)
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
=
=
=
=
+Infinity
+QNaN
+2
+SNaN
Mnem
KDTR
Type
RRE
Instruction
Compare and Signal
(Long)
Op
Mnem
B3E8 K X T R
Type
RRE
Instruction
Compare and Signal
(Extended)
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
=
=
=
=
+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.
Mnem
CEDTR
Type
RRE
Instruction
Compare Biased Exponent
(Long)
Op
Mnem
B3FC C E X T R
Type
RRE
Instruction
Compare Biased Exponent (Extended)
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
692
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
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.
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)
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
but because 2 63 1 is 19 digits long, the decimal floating-point result was rounded to 16 decimal
digits.
M3
R1
R2
M3
M4
R1
R2
694
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
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
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
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
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
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
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
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
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.
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
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
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.
698
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
L2
B2
D2
R1
M3
Opcode
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.
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
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
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
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
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.
Load
Load
Load
Load
and Test, plus Load Complement, Load Negative, and Load Positive
Floating-Point Integer
Lengthened
Rounded
Mnem
LTDTR
Type
RRE
Instruction
Load and Test (Long)
Op
Mnem
B3DE L T X T R
Type
RRE
Instruction
Load and Test
(Extended)
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
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)
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
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)
The instructions have two mask fields, M3 and M 4, shown in Table 356:
opcode
M3
M4
R1
R2
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
LD
6,=DD 7 . 2
FIDTR 2,B1000,6,0
Mnem
LDETR
Type
RRF
Instruction
Load Lengthened
(Short to Long)
Op
Mnem
B3DC L X D T R
702
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
LE
2,=ED ( QNaN)
LDETR 4,2,0
LE
2,=ED123.4567
LDETR 4,2,0
LD
1,=DD7654.321
Long operand X222C0000007D51A1
LXDTR 5,1,0
Extended format
c(FPR5,FPR7)= X2207400000000000 00000000007D51A1
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)
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
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?
Mnem
SRNMT
Type
S
Instruction
Set Decimal Rounding
Mode
Op
Mnem
Type
Instruction
704
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.
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
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)
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
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
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
SNaN
QNaN
Finite
Infinity
QNaN
SNaN
QNaN
Mnem
ESDTR
Type
RRE
Instruction
Extract Significance
(Long)
Op
Mnem
B3EF ESXTR
Type
RRE
Instruction
Extract Significance
(Extended)
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
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
Special values return zero (for zeros), 1 for infinities, 2 for QNaNs, and 3 for SNaNs.
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)
R3
X2
B2
D2
R1
opcode
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
*+2,8,-2
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)
R3
M4
R1
R2
708
DC
DC
DD12789
DD12789E-3
Generates X2238000000004BCF
Generates X222C000000004BCF
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
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
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.
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
DD923.85
DD1.0825
DD
Item price
Tax rate + 1 for price
Calculated item cost
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
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
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)
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
Version 1.00
4,=DD1783
5,2
6,4,5,B1110
6,6,2
2
4,=DD1783333
5,4
5,-Final0s
6,4,5,B1110
0,6,Final0s
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.
711
DC
DC
DC
DD12345678901234564R8
DD12345678901234565R8
DD12345678901234566R8
Generates X263D34B9C1E28E56
Generates X263D34B9C1E28E56
Generates X263D34B9C1E28E57
DC
DC
DC
DC
DC
DC
DD12345678901234574R8
DD12345678901234575R8
DD12345678901234576R8
DC
DC
DC
Generates X263D34B9C1E28E57
Generates X263D34B9C1E28E58
Generates X263D34B9C1E28E58
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)
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
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:
c(FPR0)=X2209400000000000
c(FPR2)=X0000000008000000
Form extended product
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
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
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?
713
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
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.
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.
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.
sabcdefghijklmnopq
T=binary significand
sabcdefghijk
T=binary significand
716
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.
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 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 375 lists the decimal floating-point rounding and lengthening instructions.
Function
Long to Short
Short to Long
Extended to Long
Long to Extended
718
Round
LEDTR
Lengthen
LDETR
LDXTR
LXDTR
Version 1.00
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 377 lists instructions that move data among the floating-point registers.
Function
Copy FPR to GPR
Copy GPR to FPR
Instruction
LGDR
LDGR
Table 378 lists the instruction that sets the decimal rounding model.
Function
Set Decimal Rounding Mode
Instruction
SRNMT
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
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
720
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)
721
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
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.
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
Version 1.00
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.
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
6, 14, 28
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
725
Property
Hexadecimal
Maximum normalized
value
7.210 + 75
Minimum normalized
value
7.210 79
5.110 85
1.210 94
1.710 111
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
Yes
No
Yes
Yes
Yes
None
4 modes
8 modes
No
Yes
Yes
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
Version 1.00
Binary
.8000000715...
.8000000119...
Hexadecimal
.8000000119...
.8000000119...
Decimal
.8000000
.8000000
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?
Maskable
No
Yes
No
Yes
Masked result
True zero
True zero
Interrupt action/result
Scaled exponent
Scaled exponent
Dividend operand unchanged
Pseudo-zero
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
727
Differences to consider
Both hexadecimal and IEEE BFP/DFP results can differ significantly
between masked and unmasked actions.
Default Length
4
4
4
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 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
728
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
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
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.
Binary Digits
Short
24
Hexadecimal
Digits
6
Long
53
14
Extended
28
113
Decimal Digits
9
17
18
35
36
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
Version 1.00
Mnem
PFPO
Type
E
Instruction
Perform Floating-Point
Operation
Op
Mnem
Type
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
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?
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
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)
Multiplicative
Inverse
Zero Divisor
Cancellation
Division
229
732
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
Version 1.00
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
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.
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.
A representative pseudo-zero
X41000000
X41000000 00000000
X41000000 00000000 33000000 00000000
4,=E123.456
0,4
0,=X45000000
0,4
0,=X46000000
0,4
0,=X47000000
0,4
0,=X48000000
0,4
0,=X49000000
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
Version 1.00
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
735
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
Significand
Representation
Twos complement
Sign-magnitude
Sign-magnitude
Sign-magnitude
Sign-magnitude
Sign-magnitude
Sign-magnitude
Sign-magnitude
Sign-magnitude
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
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
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
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
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.
739
740
Version 1.00
XX
XX
XX
XX
XX
XX
XX
XX
XX XX
XXXX
XXXX
XX XX
XX
XX
XX
XX
XX
XX
XX
XX
Techniques for managing addressability in large programs (and how the powerful LOCTR
instruction can help).
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.
741
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
742
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
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
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
C05
BRASL
RIL
RI
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
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
FLAG,0
14
Subroutine
Returns to caller
15,ZSet
14,15
2,Noodle
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
A(ZSet)
FLAG,0
14
15,AdrZSet
14,15
2,Noodle
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
SRL
LTR
BNPR
SRL
BR
0,2
1,1
14
0,0(1)
14
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
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
Version 1.00
*
ShftRt
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
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
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:
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
F
F
F
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)
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.
748
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.
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
- - -
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)
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)
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
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?
0,X
0,Y
0,Z
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.
751
GR1
A(arg 1)
first argument
A(arg 2)
second argument
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
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
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
A(ArgA1,ArgA2+X80000000)
A(ArgB1,ArgB2,ArgB3+X80000000)
Two arguments
Three arguments
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
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:
753
GR1
0
A(argument 1)
0
A(argument 2)
:
:
:
:
1
A(argument n)
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.
GR1 or GG1
AD(argument 1)
:
:
AD(argument n)
X FFFFFFFFFFFFFFFFF
754
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.)
755
14,12,12(13)
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
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
Version 1.00
4 bytes
Offset 0 Reserved
+4 Back chain
Caller A s Save Area
+8 Forward chain
Callee C s Save Area
:
:
:
:
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
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
*
*
LR
LA
2,13
13,BSave
ST
13,8(0,2)
- - BSave DC
18F 0
*
*
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
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
Version 1.00
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
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)
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
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
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)
+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
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
0D
F
C F5SA
13D
D
D
8D
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
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?
762
Version 1.00
Using
B
DC
DC
STM
- - -
*,15
Saver
AL1(L EPID)
C Sample
14,2,12(13)
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),,*
SAVE (14,2),,*
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.
763
15,=A(Dummy)
1,List1
14,15
1
15,=A(Dummy)
1,List2
14,15
2
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.
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
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.
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
L
MVC
LM
BR
13,4(,13)
16(4,13),Retcode
14,12,12(13)
14
or
Figure 504 shows how the calling program can test the return code to validate the result:
765
ArgLst
L
LA
BASR
LTR
JNZ
ST
- - DC
15,=A(Sub)
1,ArgLst
14,15
15,15
Error
0,Result
A(DataItem)
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
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
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
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
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
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
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)
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.
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
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.
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
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
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
13,4(,13)
16(4,13),RetCode
14,12,12(13)
14
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
769
L
BR
AdrTbl DC
ShftRt# Equ
DC
Print# Equ
DC
- - -
15,AdrTbl(15)
15
0A(0)
*-AdrTbl
A(ShftRt)
*-AdrTbl
A(Print)
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
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
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#)
- - -
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)
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.
*,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
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
Version 1.00
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.
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.
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
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.
775
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
776
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
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)
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
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)
Start
BASR
BaseLoc LAY
LAY
Using
0
10,0
11,4096(0,10)
12,8192(0,10)
BaseLoc,10,11,12
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.
Start
BASR
Using
LR
AH
LR
AH
0
10,0
*,10,11,12
11,10
11,HW4096
12,11
12,HW4096
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
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
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
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...
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)
Exec
Start
BASR
Using
LM
B
LTORG
EQU
0
3,0
*,3,4,5
4,5,=A(Begin+4096,Begin+8192)
Exec
*
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
BaseLoc,10,11,12
780
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
- - -
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
Start
BASR
Using
LR
AH
0
10,0
*,10,11
11,10
11,=H4096
Start
BASR
Using
LA
0
10,0
*,11
11,Prog+4096
Start
BASR
Using
LA
LA
0
10,0
*,10,11,12
11,Prog+4096
12,Prog+8192
Start
BASR
Using
LA
LA
LA
0
2,0
*,2,3,4,5
3,Here+4096
4,Here+8192
5,Here+12288
781
Start
BASR
Using
LA
0
10,0
*,10,11
11,*+4096
Start
BASR
Using
LA
0
10,0
Here,10,11
11,Here+4096
Here
Start
BASR
Using
LA
0
10,0
Here,10,11
11,Here+4096
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)
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
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.
ShftOK
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
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)
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.
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)
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
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
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.
After
J
JZ
JC
JAS
Next
ZeroVal
12,NoCarry
14,Sub
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:
785
Before
EX
2,MoveData
After
EXRL 2,MoveData
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
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.
*,12
2,X
2,Y
2,Z
Positive
F123456789
F7654321
F
Some sum
O,PlusCode
F+12
A small number
786
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
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
JZ
NoArglist
CP
Packed,=P 0
JE
NoPacked
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.
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?
788
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
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 ,
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 ,
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
DXD
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
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
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.
15
00000000 01
12 Loc of MySub 02
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
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
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:
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
- - - - -
Figure 540. Main program, subroutine, and common section in one assembly
CSECT
DC
DC
CSECT
DC
DC
CSECT
DC
CSECT
DC
,
F101
F103
,
F -107
F -109
,
F113
,
F -127
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
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
0,Logic
1,Shift
15,AdShf
14,15
12
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
F
F
F
A(ShftRt)
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.
793
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.
Statement
A
DS
B
DS
C
DS
D
DS
N
Equ
XL(N)
F
CL(3*N)
F
5
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
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.
CSECT
- - LtOrg
*
Round
DC
ProgLen Equ
End
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.
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
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
2. This example resumes the LOCTR of control section A after the ALoc LOCTR was defined.
797
A
ALoc
A
CSect
LOCTR
DC
LOCTR
DC
End
,
,
X 0 1
,
X 0 0
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
A
ALoc
A
ALoc
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
Positive
,
F something
F something_else
F
,
Some sum
Resume LOCTR group for instructions
0,Plus Code
,
F some number
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
1,Msg1L
,
,
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
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.
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 ,
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
A
B
A
B
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
A
ALoc
A? Note!
!
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
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
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?
801
AAA
BBB
CSect
- - L
- - LTORG
CSect
- - S
- - End
,
3,=F 1
,
8,=F 1
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
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
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?
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
Logic
Shift
Result
AdShft
EXTRN
- - L
L
L
BASR
ST
- - DS
DS
DS
DC
ShftRt
0,Logic
1,Shift
15,AdShft
14,15
0,Result
F
F
F
A(ShftRt)
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
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
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
15,ASub1
CallSub2
14,15
15,ASub2
14,15
A(Sub1)
A(Sub2)
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
806
Version 1.00
Logic
Shift
Result
AdShft
EXTRN
- - L
L
L
BASR
ST
- - DS
DS
DS
DC
ShftRt
0,Logic
1,Shift
15,AdShft
14,15
0,Result
F
F
F
V(ShftRt)
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.
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
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
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
808
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
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)
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:
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
,
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
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.
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
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
00
00
08 RSECT flag
00
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
MAIN
Type
Id
Address Length
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
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
If you specify the SECTALGN(16) option, three different Type identifiers are used for quadwordaligned control sections:
SQ
CQ
PQ
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
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)
The forms of ESD data in an object module, and how each is processed, will be discussed starting
in Section 38.6.
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,
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.)
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.
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
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
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
,
31
31
,
31
64
The ESD listing from assembling this little fragment is shown in Figure 571 on page 815:
814
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
0
33
63
0
63
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.
815
ShftRt
ShfLft
SHFTAA
Using
MVI
B
LA
MVI
LTR
*,15
SHFLAG,0
SHFTAA
15,ShftRt
SHFLAG,1
1,1
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)
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)
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
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
Using the information in Table 400 on page 814, determine all valid values of the Flags field.
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
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.
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)
,
,
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
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
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
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)
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
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:
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
820
Version 1.00
ESD SD ID=1 SUB Addr=000 Len=800
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
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
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:
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
The symbol SUB appears twice in the Composite ESD because it is both a section definition and
an external reference.
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
822
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
...
...
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!
823
A
D
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
Q(FILE1CB)
Q(RANDOM)
Q(TreeHead)
The Assemblers External Symbol Dictionary entries for these three symbols are shown in this
excerpt:
Symbol Type Id
Address Length
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
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
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:
825
EDSLen
L
0,EDSLen
GetMain R,LV=(0)
LR 11,1
- - CXD ,
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
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)
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
Version 1.00
Link-time
behavior
COMMON
Space allocated in the load
module
Storage
Allocation
Initialization
Copies
External
names
Internal
names
References
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.
LD, SD,
LD, SD,
LD, SD,
LD, SD,
P R Only
CM
CM
CM
CM
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:
827
1. Make an entry in the ESDID Translation Table, unless the symbol is type LD (its ESDID is
that of its owning section).
ESDID
17
Newly assigned CESDID value for
ESDID
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.
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.
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.
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.
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.
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.
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
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?
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
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
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
CTL/RLD
Control records, for reading and relocating text records, and including Relocation Dictionary information.
EOM
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)
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.
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:
833
MAIN
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
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.
255
256
834
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
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)
Key parts of the External Symbol Dictionary listing from this assembly look like this:
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
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
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
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
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.
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!
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
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
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!
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
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.
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.
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
An element in a given section and class may contain several Parts; you can visualize them like
this:
:
:
Part T
Part P1
Part P2
:
:
839
CSect
DC
CATTR
DC
ENTRY
AMODE
EXTRN
AMODE
,
C 1
,
C 2
XA
31
XB
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.
840
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
Same, plus ED
Any data; Binder Programming
Interfaces for access
Open-ended architecture
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.
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.
:
:
:
:
:
:
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!
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
CLASS_X
CLASS_Y
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
0
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.
843
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
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
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
0
31 32
63 64
127
Figure 606. z System PSW showing addressing-mode bits
B
0
1
0
1
Addressing mode
24-bit mode
31-bit mode
Invalid combination
64-bit mode
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
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.
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
0
32
63
0
62 63
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.
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
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.
846
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 )
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
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)
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
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
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
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
:
:
2**64 bytes
2**32 bytes
2**31 bytes (the bar)
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
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 )
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
CL10
C A Message!
Target field
Source field
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)
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
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.
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
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
Version 1.00
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
Version 1.00
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.
855
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.
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
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
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
7,WorkA
DummyS,7
3,A
3,B
C,0(12)
ElseWhere
0,1,D
0D,XL84
Work area
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
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
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
The Length Attribute of a symbol naming a DSECT is 1, and not the total length of the DSECT
itself.
858
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?
14,Read_Old_Master
14,Copy_Record
14,Do_Old_Date
14,Write_Archive_Record
14,Update_New_Record
14,Write_New_Master
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
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.
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
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. - - -
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.
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
264
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
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,
265
862
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
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
RecID,RecID-Record(7)
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)
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
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
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
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
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:
864
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
+OldRec
+OldType
+OldID
+
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
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
865
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.
Qualifier A
Qualifier Left
Qualifier Record1
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
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
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.
867
Using
Using
- - LA
LA
Drop
LA
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
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
*
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
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
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?
DSect
DS
DS
DS
DS
DS
DS
DS
Equ
,
CL8
CL22
CL4
CL20
CL2
CL8
CL2
*-Addr
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
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.
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
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.
Dependent USINGs let you address multiple DSECTs with a single base register.
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
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.
871
R:F 00000
1 F 020 00000 00020
00058 4100 F028
00008
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
LA
*
0,B2
*
USING C,B+16
LA
*
*
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
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
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
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:
*
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.
Message skeletons
Message 1
Modified field: To name
Additional message characters
Modified field: From name
Length of message 1
Other messages follow
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:
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
Addressee name
Sender name
Address of Messages CSECT
Address of OutMsg area
CL121
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.
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.
874
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.
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
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
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.
DSect
DS
DS
Equ
,
XL5
XL7
*-Znner
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
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.
In1
In2
Using
LA
Using
LA
Using
Outer,10
11,Out_Inr1
Inner,11
12,Out_Inr2
Inner,12
Inner
of Inner
Inner
of Inner
The implied addresses in both LA instructions will be resolved with register 10 as the base register.
876
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.
Using Outer,10
Using Inner,Out_Inr1
Using Inner,Out_Inr2
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
Figure 644. Data in nested DSECTs addressed with Labeled Dependent USINGs
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
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
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
DSect
DS
DS
DS
DS
,
XL(L_Mid)
XL(L_Mid)
XL(L_Mid)
0D
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
|
|
|
|
|
B1
B2
B3
B1
B2
B3
B1
B2
B3
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.
879
Move
MVC
MVC
MVC
MVC
DSECT M1B1
DSECTs in M1
DSECTs in M3
DSECTs in M2, M3
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!
DSect
DS
DS
DS
Equ
,
CL8
F
A
*-Struc
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
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
Version 1.00
InDCB
OutDCB
Using
- - LA
LA
Using
MVC
- - DCB
DCB
- - DCBD
*,12
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.
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
IHADCB,InDCB
IHADCB,OutDCB
Input DCB
Output DCB
Generate IHADCB DSECT
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.
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
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
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
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 ,
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 ,
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 ,
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
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
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
885
CLC PGname,Input_Name
- - MVC PhExt,=CL(L PhExt)
- - CLC AZip,=C95141
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
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.
PE.PDoB,PS.PDoB
1
2
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
Version 1.00
CLC
EHD.DateF,DD1.DateF
3
5
DROP EHD,DD1
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.
887
DROP PD2
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
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.
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
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)
890
Version 1.00
891
892
Version 1.00
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
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
894
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
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
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.
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.
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.
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
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
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
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
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
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
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.
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.
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
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
900
Version 1.00
ID_Name DSECT ,
IDNumber DS
F
Name
DS
CL36
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
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
F
CL36
*-ID_Name
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:
15
00000002 01
Figure 673. USING Table with two entries, one for a DSECT
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
Version 1.00
Contents
addr(A(1,1))
ColAddr+4
addr(A(1,2))
ColAddr+8
addr(A(1,3))
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
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
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)
2,II
3,JJ
2,2
3,AddrTab-4(3)
0,0(2,3)
0,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
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
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.
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
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
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
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.
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.
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.
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
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)
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
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)
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
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)
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
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)
7 3 2 5 * * *
7 3 2 * 5 + *
7 3 + 2 5 * *
912
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
data
data
data
data
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.
E1 E3
E2
before
patiently awaiting insertion
E1
E3 after
E2
Equ
L
ST
ST
0
0,Link(,1)
0,Link(,2)
2,Link(,1)
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
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
This is much simpler (and clearer) than similar statements based on Ordinary USING statements.
E1 E2 E3
E1 E2
E3
before
after
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)
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
914
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.
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 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
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.
DSect
DC
DC
DC
,
A(0)
A(0)
A(0)
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)
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
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
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
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
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
A queue element contains links to its predecessor and successor elements (sometimes called
forward and backward links), as sketched in Figure 701.
919
data field
data field
data field
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)
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
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
920
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)
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
2
3
1
4
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)
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.
921
RNew
Left
Right
New
Equ
Using
Using
Using
- - MVC
ST
MVC
ST
5
Q_El,2
Q_El,3
Q_El,RNew
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
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
data field
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)
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.
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
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
924
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.
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
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
926
Version 1.00
number of data items here
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?
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)
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
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)
(NE)F
(NE)F
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.
930
Version 1.00
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):
931
*****
XX
*** *** XX
**
XX
**
XX **
*
XX
*
*
XX
*
*
XX
*
*XX*
*
XX
* XX
* XX
*XX
*
XX
*
XX*
Infix notation
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
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
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
Version 1.00
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
Simple forms of storage management: how to acquire and release blocks of memory.
Section 42 describes:
935
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
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.
Mnem Type
SVC
I
Instruction
Supervisor Call
Op
B218
Mnem
PC
Type
S
Instruction
Program Call
The SVC instruction has the form shown in Table 425 invokes the operating system Supervisor
by causing a Supervisor-Call interruption.
0A
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
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
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.
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:
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
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.
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
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)
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
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
000080
000080 80
000081 000000
OPEN
DC
DC
DC
(,),MF=L
0F 0
AL1(128)
AL3(0)
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
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
0002A
3
4+
6+
7+
ABEND
DS
LA
SVC
42
0H
1,42
13
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
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
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
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
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
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 ***
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?
941
DC
X00nn
LA
BR
1,X BAD
1
or
or
or
X C0F4wxyz0002
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
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!
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
284
942
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
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
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
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
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
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
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
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
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
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
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
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+
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?
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
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
Version 1.00
......
OPEN
......
GET
DCB
......
CLOSE
......
Record Buffer
DDName JCL
JFCB
Label Data
Set
......
DDName JCL
OPEN
JFCB
......
GET
DCB
Label Data
......
Set
CLOSE
Access
......
Methods
Record Buffer
A lot can go wrong at this stage, typically causing an ABEND with system completion code x13,
where x is a hexadecimal digit.
949
MyDCB,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
950
Version 1.00
......
OPEN
......
GET
DCB
......
CLOSE
......
Record Buffer
DDName JCL
Updated
JFCB
Label Data
Set
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.
288
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
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
PO
Physical Sequential: strictly sequential access. Both of the following are defined
when you specify PS:
BS
QS
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
FB
VB
xxA
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).
953
dcbname
DCB DDNAME=xxxxxxxx,
MACRF=xx,
DSORG=xx,
LRECL=nnn,
BLKSIZE=nnnnn,
RECFM=xx,
EODAD=xxxxxxx
X
X
X
X
X
X
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
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
Block
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 758 on page 955 and the following explanations outline the steps taken during initialization of a DCB by OPEN:
954
Version 1.00
1
5
4
6
2
JCL DD Stmt
JFCB
3
7
Old Data
New Data
Set Label
Set Label
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
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
DSORG
955
DEVD
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
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
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
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).
no
Any Interrupts?
yes
no
yes
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
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
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
If you want to cancel all program interruption exits, specify a zero token:
ESPIE RESET,0
959
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
81
83
87
153
160
288
296
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
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.)
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
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
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
HALT
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
YES
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
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
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:
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
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
Version 1.00
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.
967
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
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)
STC
2,*
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
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
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
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)
=
=
=
=
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:
Step 2:
Do THMOVE(i,k,M 1) where i j k.
Step 3:
Step 4:
Do THMOVE(k,j,M 1) where i j k.
Step 5:
Return.
974
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
975
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
976
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)).
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
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
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
981
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
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
982
Version 1.00
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)
983
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
Version 1.00
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
985
986
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
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
988
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
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
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
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
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
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
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
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
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
Version 1.00
.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
997
=
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
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
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
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
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
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.
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)>
<nfs>
a valid (and optional) name-field symbol (label) naming the macro-instruction in whose
name field it appears.
[optional]
...
an ellipsis means that the preceding item may be repeated any number of times.
Appendix B: Simple I/O Macros
1001
READCARD
<name>[,<name>]
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.
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
+
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
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
Version 1.00
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.
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.)
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
Version 1.00
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,*
12
= X FFFFFFF3 =
-13
= X1234567890ABCDEF =
1311768467294899695
= 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 , *
A,B,C
The format of the output depends on the type attribute of the symbol naming the memory area:
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
*,Header=NO
Terminate quietly
Any value other than No (in any mixture of upper and lower case) will be treated as yes.
DUMPOUT
<name>[,<name>]
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.
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
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
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
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....*
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
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.
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
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
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
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
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
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.
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
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
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
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
1019
MVC
J
*
$$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
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;
1021
1022
Version 1.00
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
STG
LG
CVDG
LG
MVC
LA
EDMK
BNMR
BCTR
MVI
BR
.*
$$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
Version 1.00
LL
LL
LL
LL
LL
LL
LL
LL
LL
LL
LLLLLLLLLLLL
LLLLLLLLLLLL
adcon
Abbreviation for address constant.
Special Characters
addend
see augend
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.
&
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.
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
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.
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.
1027
column-major order
Same as column order.
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.
control section
An indivisible unit of instructions, data, or uninitialized space that is not further subdivided during
linking and loading.
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.
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.
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.
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 .
306
Or, the time at which programmers whose programs consistently fail to execute correctly are themselves executed.
1030
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
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.
1031
index register
One of general purpose registers 1 through 15 specified by the index register specification digit in an
RX-type instruction.
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).
K
K
Character count attribute reference to a conditional
assembly symbolic parameter or SETC symbol (as in
K&PARAM)
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.
Version 1.00
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.
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
Version 1.00
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.
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
Version 1.00
S
S
Scale attribute reference to a symbol (as in S ABC), or
a macro parameter (as in S&PARAM).
Sn
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
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.
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.
Version 1.00
zoned digit
An edited packed decimal numeric digit.
1039
1040
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
z/OS Input/Output
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
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
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.
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.
1042
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
Acknowledgments
1043
1044
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
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
Version 1.00
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
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
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.
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
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 .
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
1052
X B00F
X FFF1
X 0 FFF
X F001
=
=
=
=
-20465
-15
+4095
-4095
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.
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-
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
1054
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
1056
Version 1.00
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
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.
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.
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
1060
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)
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
1061
X D1C5
53701
11835
C JE
X CB85D6
X D950E9
X C8C9
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
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.
1063
1. B-A
2. A+C .
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!
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
000020 0000000A
End
P8_1
=F 1 0
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
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.
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
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
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
00004002
01
Following the second USING, the new entry in the USING Table will be
00004008
01
The DROP 9 eliminates the first entry, and the DROP 10 eliminates the second. The generated code is as follows:
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
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.
BEGIN
N
ONE
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
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
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
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 .
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 *
1070
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
E
F
X4040404040
X4040404040
G
H
X 5 C5C5C5C5C
X 5 C40404040
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)
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
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
DC
F 2
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
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
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
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.
1073
Symbol
1.
Value
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
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
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
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
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.
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
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.
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
1076
= C Assembler is fun
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
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
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,...)
1,=F 0
1,XX
0,NBits(1)
0,XX
1077
Section 14.5
14.5.1. These two instructions and a two-byte temporary memory area will do the job:
Temp
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
DSave
STG
0,DSave
L
0,DSave
LMH
0,0,DSave+4
- - DS
D
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 ,
1078
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.
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
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
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
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.
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.
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.
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
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)
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
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)
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
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
Object Code
0D40
9812 4016
BE27 401E
1301
47A0 4012
4001 4022
07FE
0000
00000005
FFFFFFFA
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
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
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
(2)
STG
LGH
LCGR
AG
- - DS
0,DTemp
0,HW
0,0
0,DTemp
FD
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
Section 16.5
16.5.2. First, we write the original instruction sequences in Figures 90 and 91 in two columns:
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
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
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
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
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
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
*
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
1,0
1,4
0,B 1 0 0 0 , CCode
0,4
1
BALR
SLL
SRL
ST
0,0
0,2
0,30
0,CCode
BALR
STCM
NI
0,0
0,B 1 0 0 0 , PMask
PMask,B 1 1 1 1
16.9.4.
16.9.5.
1087
1088
= X F240C240D6D9405F40F240C2
= 2 B OR 2 B
Version 1.00
1089
1090
Version 1.00
P16_4
LOOP
Consts
One
Count
Value
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
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
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
r,=F1836311903
Done
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
Version 1.00
ALR
LTR
BNP
r,rprev
r,r
DONE
3. After output, test the current value against maximum positive number:
L
SR
CR
BL
t,=F2147483647
t,r
t,rprev
DONE
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.
1093
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
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
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
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
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
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
1095
SR
C
BNL
A
SLL
B
- - -
Test
Done
1,1
0,=A(X40000000)
Done
1,=F 1
0,1
Test
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
1,NShifts
0,DataWord
0,0(1)
0,DWord
0,0
0,DWord+4
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
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)
Version 1.00
Done
ST
0,DWord+4
- - -
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
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
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
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
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.)
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
0,Fourth
2,L4
0,0(2)
0,Third
2,L3
0,0(2)
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
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
The second solution uses logical addition to test for 1-bits at the left end of R0. (Again, a sketch may help.)
1098
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)
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
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
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
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:
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
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
0,OLD
0,6
1,2
0,13
1,2
0,2
0,2
0,7
1,NEW
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
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
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
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
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
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
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.
c(GR0) = X FFFFF876 , C C = 1
c(GR0) = X789ABCDF , C C = 2
c(GR0) = X90000000, C C = 3
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
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
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
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
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:
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
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
1104
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
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
=
7294
= X71F80000
=
18
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:
1105
First
Second
Third
Fourth
1106
=
=
=
=
-232
-8
-4001
-31
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
Thus:
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
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):
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
2,Y
1,2
0,X
Y_NonNeg
0,X
0,1,LProd
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
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
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
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
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
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
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
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
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
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
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)
(b)
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
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
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
1111
BNM
CompQuot LCR
Store
STM
Store
1,1
0,1,RemQuot
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
Outer
Inner
Store
1112
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
Begin
Skip
Rem
Quot
XN
LoopA
LoopB
Title
START
BALR
USING
LA
SR
IC
ST
LA
SLL
S
ST
LA
S
MR
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
*
Loop
*
*
Print
*
X
Rem
Quot
Max
1114
Version 1.00
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
1115
* Step
* Step
* Step
* Step
* Step
* Step
* Step
* Step
1116
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
1117
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
Version 1.00
N
V
D
PrintOut *,Header=NO
DC
(ND)X 1
DC
C -E=2.
DC
(ND)C
End
P18_9
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
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 )
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
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
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
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
Version 1.00
1,0
0,1
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
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))
Simulating OR(A,B):
OR and XOR
(A OR B) XOR (A XOR B)
Simulating XOR(A,B):
1121
AND and OR
Not possible: (1 A N D 1) and (1 OR 1)
can never be 0.
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
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
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
Version 1.00
EnData
DataPtr
Sum
A
B
CCL
DC
Equ
DC
DS
DS
DS
DC
END
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
Determining the CC setting for arithmetic addition is left as an additional exercise for you.
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
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
1124
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
X 007B1EEE
X 007D68D2
X 00734EC4
X 007B1EF6
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.
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)
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
A
B
C
D
1126
Version 1.00
(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 .
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
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
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
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
Version 1.00
OIHH
OIHF
reg,X wxyz
reg,X wxyz0000
is equivalent to
... so OIHH is not needed.
1,X FF00
7,X80000000
2,15
2,15
2,15
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
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
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
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
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
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
If local addressability for the LA instruction is not available, you could use this approach:
A2
LARL
AR
BR
0,BrTbl
1,0
1
Section 22.4
22.4.1. Replace the two instructions
Loop
LA
2,0(1,1)
BCTR 2,0
LAY
2,-1(1,1)
(Count+Count) - 1 in GR2
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
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
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
1132
Version 1.00
Done
XGR
LTGR
JZ
BCTGR
NGR
AHI
J
- - -
0,0
2,1
Done
2,0
1,2
0,1
X
Done
XR
CLM
JNL
ALR
BCT
LCR
1,1
0,8,X 4 0
Done
0,0
1,Test
1,1
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>
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)
Loop
Next
SR
LA
LTR
BNM
A
SLL
BCT
0,0
2,32
1,1
Next
0,=F 1
1,1
2,Loop
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
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
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
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
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
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.
1136
Version 1.00
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
4,1
1,1(0,1)
3,3
0,Char(1)
0,Line+Margin
0,15
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
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
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
*,X FF
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
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
NI
(2)
XI
BitB,L BitB
(3)
TM
JO
(4)
LA
TM
JO
BCTR
JM
BCTR
- - -
0,2
BitA,L BitA+L BitB
Done
0,0
Done
0,0
Done
Invert BitB
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
1140
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
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!)
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
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
M10
P10
XI
M10,X80
XI
P10,X80
CLC
P10,M10
JH
P10Big
JL
M10Big
J
Equal
- - DC
F -10
DC
F+10
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
Version 1.00
CLI
JNE
CLC
JE
NotBlank - - -
Chars,C
NotBlank
Chars+1(71),Chars
AllBlank
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
X00800181028203830484058506860787088809...
000102030405060708090A0B0C0D0E0F101112...
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:
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
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,...)
DS
DC
0CL40
40AL1(4*(*-Gather))
40-byte string
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
*
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
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
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
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
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:
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.
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
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
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
24.11.8. The easiest way to do this is to pre-pad the receiving field if N > M.
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
DataPad(*-*),Data
DataPad+1(*-*),DataPad
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
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
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
PowerN
L
BCTR
NR
JNZ
- - DC
0,PowerN
0,0
0,9
NotPower
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
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
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))
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
1150
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
Shuffles
3
6
10
11
8
6
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
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
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
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.
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.
*
J0
*
P
*
M
1154
LA
XR
TRT
B
1,Pack+L Pack-1
2,2
Pack,PDTest
J0(2)
BadSign
Equ
JZ
JM
J
*-J0
Error
BadDigit
PPlus
Box B
CC=0:
CC=1:
CC=2:
Equ
JZ
JM
*-J0
Error
BadDigit
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
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
SomeVal+L SomeVal-1,X FE
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
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
27.4.8. Four possible interpretations, and their Assembler Language defining statements, are:
1155
DC
DC
STH
DC
F1077952604
C *
4,X05C ( 0 , 4 )
P+4040405
S1
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:
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
----------
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
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).
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
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)
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)
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)
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
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
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.)
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
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.
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
PackVal,PackVal
PackVal+L PackVal-1,1
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
Version 1.00
SomeVal,SomeVal
SomeVal+L SomeVal-1,X FE
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
XX(N),XX+(N-1)-D/2((D+1)/2)
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)
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
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
If the other four sign codes are used, we must modify the tests to also check for a sign code of X F :
1164
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
PData
TM
PData+L PData-1,X 1 0
JO
Even
- - DC
P1234567
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
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.
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.
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
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)
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
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
BadNews
LA
OC
JNZ
SR
DC
- - LTR
BNZR
1,Over
A(N/2),A
BadNews
1,1
0H
1,1
1
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
1167
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
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-
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+
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
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
1170
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
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:
1171
pattern
pattern
pattern
pattern
=
=
=
=
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
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
2147483647
000000000000000000000042
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.
*
1173
Title
EndRec
DC
DC
END
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
Version 1.00
1175
Section 31 Solutions
Section 31.2
31.2.1.
1.
2.
3.
4.
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
X0.10504816F...
X0.00068DB8BAC7...
X 0 . FCD38CDA...
X0.00003C53E2D6...
=
=
=
=
=
=
=
=
=
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
1176
Version 1.00
= 10**12 = X 1 D1A94A2
= 10**13 = X9184E72A
DC
DC
FS(-11)10E11
FS(-12) U10E12
DC
DC
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
1,0
2,4
1,2
2,1
1,2
0,2
4,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
$604.75
1178
Version 1.00
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
$604.75
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
1180
= 1.414213563
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, no round
.514010 5
.282410 6
.279910 6
.209610 6
No guard, no round
.514010 5
.282410 6
.279010 6
.209010 6
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)
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
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.
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
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
1184
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)
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
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:
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
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
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
1186
Version 1.00
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
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
0D,X 4 E , 7 X 0
D 0
1188
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
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
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
D
D 2 0
D 1 6
Remainder
A value for A
And for B
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)
(2)
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
XGR
ICMH
OILL
LFGR
DD
STD
0,0
0,8,X
0,1
0,0
0,X
0,ULPX
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
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
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
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
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.
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
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
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
1194
= C1.414213562
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:
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
X 7 FFFFFFF
X007FFFFF
X80000000
X00FFFFFF
X FF8000AB
X FF800000
QNaN
Denormalized
0
Normal
QNaN
infinity
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.
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)
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
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
100EB
34.7.3. This solution relies on setting the mask bits and the rounding mode in the FPCR:
1196
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)
Operand 2
C
Operand 1
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
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
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
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.
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
= C1.414213563
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
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
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
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.
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
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
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
0
1
0
0
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
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
1205
Section 35.15
35.15.1. The M 4 mask is used in four different ways:
M4
1
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.
*
*
*
*
*
*
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
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
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
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
*
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
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
Version 1.00
A
X4100000F
X4100000C
X4100000A
A (1/A)
X40FFFFFF
X40FFFFFC
X40FFFFFA
ulp difference
16
16
16
Pr1me 550
1 11 48
CDC 6600
1 15 48
0
0,=X00000003
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
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
1212
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
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)
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.
1213
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
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
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
1214
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
*,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:
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
X4700nnnn
then its maximum value is 2 15 1 = 32767. But if you write it in the form
NOP
X nnn
JList
BASR
LARL
B
J
J
J
J
14,15
14,JList
0(14,15)
Ret000
Ret004
Ret008
Ret012
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
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
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)
- - -
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
- - -
AdrTbl
LARL
ALR
L
BR
DC
DC
- - -
15,AdrTbl
15,0
15,0(0,15)
15
A(ShftRt)
A(Print)
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:
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
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.
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
Version 1.00
Pattern
Space
DC
DS
End
X4040202120
D
P37_1
1219
BR
End
1220
14
,
Return
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
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.
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,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.
1222
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
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:
X000003
X000005
X000001
X000004
X000006
X000002
X000000
38.4.13. The values of the symbols are given in the Loc column.
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
38.4.14. When the Assembler processes your END statement, it inserts two invisible statements:
<first>
CSECT ,
LTORG
Type
SD
ER
SD
LD
SD
CM
XD
Id
Address
Length
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
,
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
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
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.
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
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
1226
Version 1.00
I2D
Const
CSect
Using
LGFR
LDGR
LNDR
SD
BR
DC
,
*,15
0,0
0,0
0,0
0,Const
14
DS62147483648
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
- - -
A(YourData)
DataAddr
XL(23456)
.
DataAddr
3,DataPtr
3,0(,3)
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
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.
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.
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
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)
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
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
L
XGR
OILL
ICMH
LFGR
DD
1,0(,1)
0,0
0,1
0,8,0(1)
0,0
0,0(,1)
Version 1.00
*
HxUlpL
BR
14
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
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.
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
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
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)
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
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
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
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
Version 1.00
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
X 0 9 8
X 3 7 3
= 152
= 883
39.7.5. Yes.
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)
( 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
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
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:
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
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
1238
*
7
3
7
2
3
7
+
6
7
5
6
7
*
11
7
77
Version 1.00
+
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
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
*
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):
Pop2(X):
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
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
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
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
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
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)
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.
1241
XLoop
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
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
Formula
Record
Master
*
Stack
StkLim
Data
Incr
IncrX
Branch
M0
M1
MM
Quit
StkMsg
SynMsg
MsgList
M0P
M1P
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
1243
MMP
*
*
*
*
*
*
*
*
*
*
Begin
Fetch
******
Operate
OprndA
OprndB
OprndC
Oprnd0
Oprnd1
AND
OR
NOT
XOR
EndOps
******
StkErr
SynErr
EndForm
Stop
1244
DC
AL1(L MM),AL3(MM)
Version 1.00
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
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
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
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
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.
1249
Section 42 Solutions
Section 42.1
42.1.1. Try XC
*,=X 0 1 . The XC instruction changes alternately into OC, XC, OC, ....
Doing things like that could also endanger your job security.
1250
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
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
factorial
factorial
factorial
factorial
factorial
factorial
factorial
factorial
factorial
factorial
factorial
factorial
=
=
=
=
=
=
=
=
=
=
=
=
479001600
39916800
3628800
362880
40320
5040
720
120
24
6
2
1
1251
1252
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
Index
1253
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
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
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
Index
1255
1256
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
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
Version 1.00
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
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
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
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
Index
1263
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
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
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
I
IA
See Instruction Address
IARV64 macro instruction 943
IC machine instruction 186
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
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
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
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
Index
1267
1268
Version 1.00
M
M machine instruction
machine instruction
A 218
264, 265
Index
1269
1270
Version 1.00
Index
1271
1272
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
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
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
1274
Version 1.00
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
Index
1275
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
Version 1.00
Index
1277
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
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
Version 1.00
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
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