Assembler.V2.Alntext V2.00
Assembler.V2.Alntext V2.00
for
IBM System zβ’ Servers
Version 2.00
John R. Ehrman
Tables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxix
Foreword . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
Outline and Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
Programming Environments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
Levels of Difficulty (*) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
Exercises and Programming Problems . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
Some Personal Observations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
Von Neumann Architecture . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
Why Program in Assembler Language (and Why Not)? . . . . . . . . . . . . . . . . . . . 5
Assembler Language Misconceptions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
Contents iii
5.2. Examples of Effective Addresses . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
5.3. Indexing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
5.4. Examples of Indexing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65
5.5. Addressing Problems (*) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66
5.6. Address Translation and Virtual Memory (*) . . . . . . . . . . . . . . . . . . . . 67
5.7. Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
Contents v
15.8. A Design Oversight and a Modern βCorrectionβ (*) . . . . . . . . . . . . . . . 212
15.9. Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 213
16. Fixed-Point Binary Addition, Subtraction, and Comparison . . . . . . . . . . . . . 216
16.1. Signed-Arithmetic Add and Subtract Instructions . . . . . . . . . . . . . . . . 216
16.2. Signed-Arithmetic Operations Using 32-Bit Registers . . . . . . . . . . . . . . 217
16.2.1. Condition Code Settings After Arithmetic . . . . . . . . . . . . . . . . . . 218
16.3. Signed-Arithmetic Operations Using 64-Bit Registers . . . . . . . . . . . . . . 221
16.4. Signed-Arithmetic Compare Instructions . . . . . . . . . . . . . . . . . . . . . 222
16.5. Logical-Arithmetic Add and Subtract Instructions . . . . . . . . . . . . . . . . 224
16.6. Add With Carry, Subtract With Borrow (*) . . . . . . . . . . . . . . . . . . . 228
16.7. Operations With Mixed 64-Bit and 32-Bit Operands . . . . . . . . . . . . . . 229
16.8. Logical-Arithmetic Compare Instructions . . . . . . . . . . . . . . . . . . . . . 232
16.9. Retrieving and Setting the Program Mask (*) . . . . . . . . . . . . . . . . . . 234
16.10. Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 235
17. Binary Shifting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 242
17.1. Unit Shifts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 243
17.2. Single-Length Logical Shifts . . . . . . . . . . . . . . . . . . . . . . . . . . . . 245
17.2.1. Three-Operand Shift Instructions . . . . . . . . . . . . . . . . . . . . . . . 247
17.3. Double-Length Logical Shifts . . . . . . . . . . . . . . . . . . . . . . . . . . . . 248
17.4. Arithmetic Shift Instructions . . . . . . . . . . . . . . . . . . . . . . . . . . . . 252
17.5. Rotating Shifts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 257
17.6. Calculated Shift Amounts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 257
17.7. Bit-Length Constants (*) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 259
17.8. Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 260
18. Binary Multiplication and Division . . . . . . . . . . . . . . . . . . . . . . . . . . . . 264
18.1. Overview of Multiplication Instructions . . . . . . . . . . . . . . . . . . . . . . 264
18.2. Arithmetic (Signed) Multiplication Instructions . . . . . . . . . . . . . . . . . 265
18.2.1. Double-Length Arithmetic Products . . . . . . . . . . . . . . . . . . . . . 265
18.2.2. Single-Length Arithmetic Products . . . . . . . . . . . . . . . . . . . . . . 267
18.3. Logical (Unsigned) Multiplication Instructions . . . . . . . . . . . . . . . . . . 270
18.4. How Multiplication Is Done (*) . . . . . . . . . . . . . . . . . . . . . . . . . . 272
18.5. Division Instructions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 274
18.6. Arithmetic (Signed) Division Instructions . . . . . . . . . . . . . . . . . . . . . 275
18.6.1. Double-Length Division . . . . . . . . . . . . . . . . . . . . . . . . . . . . 275
18.6.2. Single-Length Division . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 278
18.7. Logical (Unsigned) Division Instructions . . . . . . . . . . . . . . . . . . . . . 279
18.8. How Division Is Done (*) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 280
18.9. Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 283
19. Logical Operations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 288
19.1. Logical Operations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 289
19.2. Register-Based Logical Instructions . . . . . . . . . . . . . . . . . . . . . . . . 289
19.3. Logical AND . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 290
19.4. Logical OR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 291
19.5. Logical Exclusive OR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 292
19.6. Interesting Uses of Logical Instructions (*) . . . . . . . . . . . . . . . . . . . . 295
19.7. Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 297
Contents vii
25.4. Search String Instruction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 415
25.5. Move String Instruction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 417
25.6. Compare Logical String Instruction . . . . . . . . . . . . . . . . . . . . . . . . 419
25.7. Translate Extended Instruction . . . . . . . . . . . . . . . . . . . . . . . . . . . 421
25.8. Compare Until Substring Equal Instruction (*) . . . . . . . . . . . . . . . . . 423
25.9. Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 425
26. Other Types of Character Data (*) . . . . . . . . . . . . . . . . . . . . . . . . . . . . 428
26.1. Character Representations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 428
26.1.0. An Early Character Encoding . . . . . . . . . . . . . . . . . . . . . . . . . 428
26.1.1. BCD characters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 429
26.2. EBCDIC Representations and Code Pages . . . . . . . . . . . . . . . . . . . . 430
26.3. ASCII . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 432
26.4. Double-Byte EBCDIC Data (*) . . . . . . . . . . . . . . . . . . . . . . . . . . 434
26.4.1. The DBCS Option (*) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 436
26.4.2. G-Type DBCS Constants and Self-Defining Terms (*) . . . . . . . . . . 436
26.4.3. Continuation Rules for DBCS Data (*) . . . . . . . . . . . . . . . . . . . 437
26.5. Unicode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 438
26.5.1. The Unicode Representation . . . . . . . . . . . . . . . . . . . . . . . . . 438
26.5.2. Glyphs and Characters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 439
26.5.3. Unicode Character Constants . . . . . . . . . . . . . . . . . . . . . . . . . 439
26.6. Unicode Instructions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 441
26.6.1. String Search, Move, and Compare . . . . . . . . . . . . . . . . . . . . . 441
26.6.2. Optional Operands (*) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 443
26.6.3. Translation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 444
26.6.4. Conversion Among Transformation Formats (*) . . . . . . . . . . . . . . 447
26.7. Translate and Test Extended . . . . . . . . . . . . . . . . . . . . . . . . . . . . 450
26.8. Byte Reversal and Workstation Data . . . . . . . . . . . . . . . . . . . . . . . 453
26.8.1. Byte-Reversing Instructions . . . . . . . . . . . . . . . . . . . . . . . . . . 453
26.9. Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 456
Chapter VIII: Zoned and Packed Decimal Data and Operations . . . . . . . . . . . . 459
27. Zoned and Packed Decimal Representations . . . . . . . . . . . . . . . . . . . . . . 460
27.1. Zoned Decimal Representation . . . . . . . . . . . . . . . . . . . . . . . . . . . 460
27.1.1. Why Zoned Decimal Is The Way It Is (*) . . . . . . . . . . . . . . . . . 463
27.2. Zoned Decimal Constants . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 464
27.3. Packed Decimal Representation . . . . . . . . . . . . . . . . . . . . . . . . . . 465
27.4. Packed Decimal Constants . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 467
27.4.1. Scale Attributes and Packed Decimal Constants (*) . . . . . . . . . . . . 467
27.5. Converting Between Packed and Zoned . . . . . . . . . . . . . . . . . . . . . . 469
27.6. The PACK Instruction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 471
27.7. The UNPK Instruction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 474
27.8. Packing and Unpacking ASCII and Unicode Data (*) . . . . . . . . . . . . . 478
27.8.1. Packing ASCII and Unicode Data . . . . . . . . . . . . . . . . . . . . . . 478
27.8.2. Unpacking ASCII and Unicode Data . . . . . . . . . . . . . . . . . . . . 479
27.9. Printing Hexadecimal Values . . . . . . . . . . . . . . . . . . . . . . . . . . . . 481
27.10. Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 483
28. Packed Decimal Arithmetic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 484
28.1. General Rules . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 484
28.1.1. Precision and Accuracy . . . . . . . . . . . . . . . . . . . . . . . . . . . . 485
28.2. Decimal Addition and Subtraction . . . . . . . . . . . . . . . . . . . . . . . . . 485
28.3. Decimal Comparison . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 487
28.4. Decimal Multiplication . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 489
28.5. Decimal Division . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 490
28.6. True Decimal Addition (*) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 492
28.7. Complement Decimal Addition (*) . . . . . . . . . . . . . . . . . . . . . . . . 493
29. Packed Decimal Instructions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 497
29.1. TP Instruction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 498
29.2. ZAP Instruction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 499
29.3. AP and SP Instructions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 501
29.4. CP Instruction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 503
29.5. MP Instruction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 506
29.6. DP Instruction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 509
viii Assembler Language Programming for IBM System zβ’ Servers Version 2.00
29.7. SRP Instruction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 511
29.7.1. Biased and Unbiased Rounding with SRP (*) . . . . . . . . . . . . . . . 513
29.8. MVO Instruction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 516
29.9. Decimal Shifting Using MVO (*) . . . . . . . . . . . . . . . . . . . . . . . . . 518
29.9.1. Shift Right an Odd Number of Digits . . . . . . . . . . . . . . . . . . . . 518
29.9.2. Shift Left an Odd Number of Digits . . . . . . . . . . . . . . . . . . . . . 519
29.9.3. Shifting an Even Number of Digits . . . . . . . . . . . . . . . . . . . . . . 519
29.9.4. Shifting Left an Even Number of Digits . . . . . . . . . . . . . . . . . . . 520
29.9.5. Shifting Right an Even Number of Digits . . . . . . . . . . . . . . . . . . 520
29.10. Scaled Packed Decimal Computations: General Rules . . . . . . . . . . . . . 522
29.10.1. Precision and Scale . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 522
29.10.2. General Rules: Addition and Subtraction . . . . . . . . . . . . . . . . . 523
29.10.3. General Rules: Multiplication . . . . . . . . . . . . . . . . . . . . . . . . 523
29.10.4. General Rules: Division (*) . . . . . . . . . . . . . . . . . . . . . . . . . 524
29.10.5. COBOL and PL/I Notations (*) . . . . . . . . . . . . . . . . . . . . . . 525
29.11. Example of a Packed Decimal βBusinessβ Computation . . . . . . . . . . . 526
29.11.1. The Wholesaler's Calculation . . . . . . . . . . . . . . . . . . . . . . . . 526
29.11.2. The Retailer's Calculation . . . . . . . . . . . . . . . . . . . . . . . . . . 527
29.11.3. Comments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 529
29.11.4. Using Integer and Scale Attributes (*) . . . . . . . . . . . . . . . . . . . 529
29.12. Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 530
30. Converting and Formatting Packed Decimal Data . . . . . . . . . . . . . . . . . . . 532
30.1. CVD, CVDY, and CVDG Instructions . . . . . . . . . . . . . . . . . . . . . . 532
30.2. CVB, CVBY, and CVBG Instructions . . . . . . . . . . . . . . . . . . . . . . 534
30.3. Editing Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 536
30.4. Simple Examples of Editing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 538
30.5. Single-Field Editing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 541
30.5.1. Editing Negative Values . . . . . . . . . . . . . . . . . . . . . . . . . . . . 541
30.5.2. Protecting High-Order Fields . . . . . . . . . . . . . . . . . . . . . . . . . 542
30.6. The EDMK Instruction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 543
30.7. Editing Multiple Fields (*) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 545
30.8. Summary Comments on Editing (*) . . . . . . . . . . . . . . . . . . . . . . . . 546
Contents ix
32.5. Integer-Based Representations (*) . . . . . . . . . . . . . . . . . . . . . . . . . 577
32.6. Floating-Point Division . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 578
32.7. Floating-Point Addition and Subtraction . . . . . . . . . . . . . . . . . . . . . 578
32.8. Floating-Point Precision . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 580
32.9. Floating-Point Range . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 582
32.10. Exponents and Characteristics . . . . . . . . . . . . . . . . . . . . . . . . . . . 584
32.11. Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 585
33. Hexadecimal Floating-Point Data and Operations . . . . . . . . . . . . . . . . . . . 586
33.1. Hexadecimal Floating-Point Data . . . . . . . . . . . . . . . . . . . . . . . . . 586
33.2. Writing Hexadecimal Floating-Point Constants . . . . . . . . . . . . . . . . . 590
33.2.1. Decimal Exponents . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 591
33.3. Modifiers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 592
33.3.1. Length Modifiers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 592
33.3.2. Scale Modifiers (*) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 592
33.3.3. Exponent Modifiers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 593
33.4. Subtypes Q and H (*) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 594
33.4.1. LQ-Type Constants . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 594
33.4.2. Subtype H . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 595
33.4.3. Difficult Numbers (*) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 596
33.5. Basic Hexadecimal Floating-Point Instructions . . . . . . . . . . . . . . . . . . 597
33.6. Hexadecimal Floating-Point RR-Type Data-Movement Instructions . . . . . 597
33.7. Hexadecimal Floating-Point Multiplication . . . . . . . . . . . . . . . . . . . . 599
33.7.1. Exponent Overflow and Underflow. . . . . . . . . . . . . . . . . . . . . . 602
33.8. Hexadecimal Floating-Point Division . . . . . . . . . . . . . . . . . . . . . . . 603
33.8.1. The Halve Instructions (*) . . . . . . . . . . . . . . . . . . . . . . . . . . 604
33.9. Hexadecimal Floating-Point Addition and Subtraction . . . . . . . . . . . . . 606
33.9.1. Unnormalized Addition and Subtraction . . . . . . . . . . . . . . . . . . 609
33.9.2. Older Uses of Unnormalized Addition (*) . . . . . . . . . . . . . . . . . . 609
33.10. Adding Operands of Like Sign (*) . . . . . . . . . . . . . . . . . . . . . . . . 612
33.11. Adding Operands of Unlike Sign (*) . . . . . . . . . . . . . . . . . . . . . . . 612
33.11.1. Hexadecimal Floating-Point Complement Addition (*) . . . . . . . . . 613
33.11.2. Implementing Hexadecimal Floating-Point Complement Addition (*) . 614
33.12. Hexadecimal Floating-Point Comparison . . . . . . . . . . . . . . . . . . . . 615
33.13. Rounding and Lengthening Instructions . . . . . . . . . . . . . . . . . . . . . 616
33.13.1. Rounding Instructions . . . . . . . . . . . . . . . . . . . . . . . . . . . . 616
33.13.2. Lengthening Instructions . . . . . . . . . . . . . . . . . . . . . . . . . . . 618
33.14. Converting Between Binary Integers and HFP . . . . . . . . . . . . . . . . . 620
33.14.1. Converting Binary Integers to Hexadecimal Floating-Point . . . . . . . 620
33.14.2. Converting Hexadecimal Floating-Point to Binary Integers . . . . . . . 621
33.15. Hexadecimal Floating-Point Integers and Remainders (*) . . . . . . . . . . . 625
33.16. Square Root Instructions (*) . . . . . . . . . . . . . . . . . . . . . . . . . . . 626
33.17. Multiply and Add/Subtract Instructions (*) . . . . . . . . . . . . . . . . . . . 627
33.18. Some Hexadecimal Floating-Point History (*) . . . . . . . . . . . . . . . . . 629
33.18.1. Zeroing Floating-Point Registers . . . . . . . . . . . . . . . . . . . . . . 629
33.18.2. Hexadecimal Floating-Point to Binary Conversion Comments (*) . . . 629
33.18.3. Initial System/360 Oversights . . . . . . . . . . . . . . . . . . . . . . . . 630
33.19. Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 630
34. Binary Floating-Point Data and Operations . . . . . . . . . . . . . . . . . . . . . . . 638
34.1. Binary Floating-Point Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 638
34.1.1. Data Representations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 639
34.1.2. Normal Numbers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 640
34.1.3. Special Values . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 640
34.1.4. Range of the Representation . . . . . . . . . . . . . . . . . . . . . . . . . 641
34.2. Writing Binary Floating-Point Constants . . . . . . . . . . . . . . . . . . . . . 642
34.2.1. Decimal Exponents and Exponent Modifiers . . . . . . . . . . . . . . . . 644
34.2.2. Length Modifiers (*) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 645
34.3. Binary Floating-Point Arithmetic in General . . . . . . . . . . . . . . . . . . . 646
34.3.1. Rounding Modes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 646
34.3.2. Denormalized Numbers . . . . . . . . . . . . . . . . . . . . . . . . . . . . 647
34.3.3. Arithmetic with Zero, Infinity, and NaNs . . . . . . . . . . . . . . . . . . 648
34.4. Binary Floating-Point Exceptions, Interruptions, and Controls . . . . . . . . 649
34.4.1. Binary Floating-Point Exceptions (*) . . . . . . . . . . . . . . . . . . . . 649
Contents xi
35.12. Decimal Floating-Point Miscellaneous Operations (*) . . . . . . . . . . . . . 718
35.12.1. Set Decimal Rounding Mode . . . . . . . . . . . . . . . . . . . . . . . . 718
35.12.2. Extract and Insert Biased Exponent . . . . . . . . . . . . . . . . . . . . 719
35.12.3. Extract Significance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 720
35.12.4. Shift Significand Left/Right . . . . . . . . . . . . . . . . . . . . . . . . . 720
35.12.5. Quantize . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 722
35.12.6. Reround . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 724
35.12.7. Decimal Floating-Point Data Groups (*) . . . . . . . . . . . . . . . . . 726
35.13. Example of a Decimal Floating-Point βBusinessβ Computation . . . . . . . 728
35.13.1. The Wholesaler's Calculation . . . . . . . . . . . . . . . . . . . . . . . . 728
35.13.2. The Retailer's Calculation . . . . . . . . . . . . . . . . . . . . . . . . . . 729
35.13.3. Comparing Packed and Floating Decimal . . . . . . . . . . . . . . . . . 729
35.14. Decimal Floating-Point Binary-Significand Format (*) . . . . . . . . . . . . 730
35.15. Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 731
36. Floating-Point Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 739
36.1. Floating-Point Data Representations . . . . . . . . . . . . . . . . . . . . . . . 739
36.2. Floating-Point Properties . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 741
36.3. Floating-Point Exceptions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 741
36.4. Defining Floating-Point Constants . . . . . . . . . . . . . . . . . . . . . . . . . 742
36.5. Converting Among Decimal, Hexadecimal and Binary Representations . . . 743
36.5.1. In-Out Conversions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 743
36.5.2. Out-In Conversions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 744
36.5.3. The PFPO Instruction (*) . . . . . . . . . . . . . . . . . . . . . . . . . . . 745
36.6. βRealβ and βRealisticβ (Floating-Point) Arithmetic . . . . . . . . . . . . . . . 745
36.7. When Does Zero Not Behave Like Zero? (*) . . . . . . . . . . . . . . . . . . . 747
36.7.1. Hexadecimal Floating-Point . . . . . . . . . . . . . . . . . . . . . . . . . . 748
36.7.2. Binary Floating-Point . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 748
36.7.3. Decimal Floating-Point . . . . . . . . . . . . . . . . . . . . . . . . . . . . 749
36.8. Examples of Former Floating-Point Representations and Behaviors (*) . . . 749
36.9. Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 751
xii Assembler Language Programming for IBM System zβ’ Servers Version 2.00
38.2.1. Internal Subroutines Without Local Addressability . . . . . . . . . . . . 797
38.2.2. Internal Subroutines With Local Addressability . . . . . . . . . . . . . . 798
38.2.3. Minimizing the Number of Base Registers . . . . . . . . . . . . . . . . . 799
38.2.4. Relative Branches, Immediate Operands, and Long Displacements . . . 800
38.2.5. Separating Instructions and Data . . . . . . . . . . . . . . . . . . . . . . . 800
38.3. Separate Assemblies . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 802
38.4. Control Sections . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 803
38.4.1. Resuming Control Sections . . . . . . . . . . . . . . . . . . . . . . . . . . 806
38.4.2. Literals in Multi-Section Assemblies (*) . . . . . . . . . . . . . . . . . . . 808
38.4.3. Location Counter Discontinuities (*) . . . . . . . . . . . . . . . . . . . . 808
38.4.4. Section Alignment (*) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 809
38.4.5. Threaded Location Counters (*) . . . . . . . . . . . . . . . . . . . . . . . 809
38.4.6. The βLocation Counterβ Instruction LOCTR (*) . . . . . . . . . . . . . 810
38.5. External Symbols . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 818
38.5.1. EXTRN and WXTRN Statements . . . . . . . . . . . . . . . . . . . . . 819
38.5.2. V-Type Address Constants . . . . . . . . . . . . . . . . . . . . . . . . . . 820
38.5.3 E N T R Y Statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 821
38.5.4. The External Symbol Dictionary Listing . . . . . . . . . . . . . . . . . . 824
38.5.5. External Symbol Addressing and Residence Modes . . . . . . . . . . . . 827
38.6. Object Modules . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 831
38.6.1. Relocation Dictionary and External Symbol Dictionary . . . . . . . . . . 832
38.7. Program Linking: Combining Object Modules . . . . . . . . . . . . . . . . . . 833
38.7.1. Assigning COMMON Sections . . . . . . . . . . . . . . . . . . . . . . . . 836
38.7.2. Relocating Address Constants . . . . . . . . . . . . . . . . . . . . . . . . 836
38.7.3. External Dummy Sections (*) . . . . . . . . . . . . . . . . . . . . . . . . . 838
38.7.4. Loading Object Modules (*) . . . . . . . . . . . . . . . . . . . . . . . . . 841
38.8. Load Modules and Program Objects . . . . . . . . . . . . . . . . . . . . . . . 845
38.8.1. External Subroutines and Assisted Linkage: Overlay (*) . . . . . . . . . . 847
38.8.2. Program Objects (*) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 848
38.8.3. The βClass Attributeβ Instruction CATTR . . . . . . . . . . . . . . . . . 851
38.8.4. Programming for Program Objects . . . . . . . . . . . . . . . . . . . . . . 854
38.8.5. Comparing Load Modules and Program Objects . . . . . . . . . . . . . . 854
38.9. Loading Saved Modules into Storage . . . . . . . . . . . . . . . . . . . . . . . 855
38.9.1. Loading Load Modules . . . . . . . . . . . . . . . . . . . . . . . . . . . . 855
38.9.2. Loading Program Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . 856
38.10. Changing Addressing Modes . . . . . . . . . . . . . . . . . . . . . . . . . . . 858
38.10.1. The BASSM Instruction . . . . . . . . . . . . . . . . . . . . . . . . . . . 859
38.10.2. The BSM Instruction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 860
38.10.3. Branch and Return With Addressing Mode Change . . . . . . . . . . . 861
38.10.4. Load Logical Thirty-One Bits Instructions . . . . . . . . . . . . . . . . 863
38.11. Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 866
Chapter XI: Dummy Sections, Enhanced USINGs, and Data Structures . . . . . . . 871
39. Dummy Control Sections and Enhanced USING Statements . . . . . . . . . . . . . 872
39.1. Dummy Control Sections . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 872
39.2. Multiple Data Structures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 875
39.3. Shortcomings of Ordinary USING Statements . . . . . . . . . . . . . . . . . . 876
39.3.1. Ordinary USINGs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 877
39.4. Labeled USING Statements and Qualified Symbols . . . . . . . . . . . . . . . 882
39.4.1. Qualified Symbols . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 882
39.4.2. Dropping a Labeled USING Statement . . . . . . . . . . . . . . . . . . . 883
39.4.3. Labeled USING Statement Summary . . . . . . . . . . . . . . . . . . . . 883
39.5. Dependent USING Statements . . . . . . . . . . . . . . . . . . . . . . . . . . . 885
39.5.1. Definition of Dependent USING Statements . . . . . . . . . . . . . . . . 886
39.5.2. Examples of Dependent USING Statements . . . . . . . . . . . . . . . . 886
39.5.3. Mapping a CSECT as a DSECT . . . . . . . . . . . . . . . . . . . . . . . 889
39.5.4. Dropping Dependent USINGs . . . . . . . . . . . . . . . . . . . . . . . . 890
39.5.5. Dependent USING Statement Summary . . . . . . . . . . . . . . . . . . 890
39.6. Labeled Dependent USING Statements . . . . . . . . . . . . . . . . . . . . . . 891
39.6.1. Nesting Structures Addressed with Ordinary USINGs . . . . . . . . . . . 892
39.6.2. Nesting Structures Addressed with Labeled USINGs . . . . . . . . . . . 892
39.6.3. Nested Structures Addressed with Labeled Dependent USINGs . . . . . 892
Contents xiii
39.6.4. Multiple Nesting of Identical Structures . . . . . . . . . . . . . . . . . . . 893
39.6.5. Mapping an Array of Identical Data Structures . . . . . . . . . . . . . . . 895
39.6.6. Two MVS Data Control Blocks (DCBs) in a Program . . . . . . . . . . 896
39.7. Example of a Large βPersonnel-Fileβ Record (*) . . . . . . . . . . . . . . . . 897
39.7.1. Personnel-File Record Example: Comparing Birth Dates . . . . . . . . . 902
39.7.2. Personnel-File Record Example: Comparing Different Dates . . . . . . . 902
39.7.3. Personnel-File Record Example: Copying Addresses . . . . . . . . . . . 903
39.8. Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 904
39.8.1. USING Statement Summary . . . . . . . . . . . . . . . . . . . . . . . . . 904
39.8.2. DROP Statement Summary . . . . . . . . . . . . . . . . . . . . . . . . . . 905
40. Basic Data Structures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 907
40.1. One-Dimensional Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 908
40.2. Two-Dimensional Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 910
40.3. General Array Subscripts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 913
40.3.1. Multi-Dimensional Arrays (*) . . . . . . . . . . . . . . . . . . . . . . . . . 913
40.3.2. Non-Homogeneous Arrays (Tables) . . . . . . . . . . . . . . . . . . . . . 914
40.4. Address Tables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 917
40.5. Searching an Ordered Array . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 919
40.6. Stacks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 923
40.6.1. An Example Using a Stack . . . . . . . . . . . . . . . . . . . . . . . . . . 923
40.6.2. An Example Implementing a Stack . . . . . . . . . . . . . . . . . . . . . 924
40.7. Lists . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 927
40.7.1. List Insertion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 927
40.7.3. List Deletion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 929
40.7.4. Free Storage Lists . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 929
40.8. Queues . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 934
40.9. Trees . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 937
40.10. Hash Tables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 941
40.11. Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 944
xiv Assembler Language Programming for IBM System zβ’ Servers Version 2.00
41.7.4. Handling a Program Interruption . . . . . . . . . . . . . . . . . . . . . . . 975
41.8. Abnormal Terminations of Any Kind . . . . . . . . . . . . . . . . . . . . . . . 976
41.8.1. The ESTAE Macro . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 978
41.8.2. Interruption Processing . . . . . . . . . . . . . . . . . . . . . . . . . . . . 979
41.8.3. Percolation and Retry . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 979
41.8.4. Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 980
41.9. Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 981
42. Reenterability and Recursion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 983
42.1. Reenterability . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 983
42.1.1. What it Means in General . . . . . . . . . . . . . . . . . . . . . . . . . . . 983
42.1.2. What it Means in Practice . . . . . . . . . . . . . . . . . . . . . . . . . . . 984
42.1.3. Assembly-Time Considerations . . . . . . . . . . . . . . . . . . . . . . . . 984
42.1.4. At Linking Time . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 984
42.1.5. Techniques . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 985
42.2. Recursion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 987
42.3. Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 992
Bibliography . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1057
Basic References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1057
System/360 Architecture History . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1058
Assembler Design and Implementation . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1058
Other General References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1058
Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1059
Notices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1061
Contents xv
Trademarks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1061
Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1281
Figures
1. Example of numbering and notation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
2. One stage of a binary adder . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
3. βCircularβ representation of two's complement representation . . . . . . . . . . . . . . . 36
4. Conceptual structure of a typical computer . . . . . . . . . . . . . . . . . . . . . . . . . . 42
5. Conceptual structure of System z . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
6. A byte containing 8 binary digits . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
7. A portion of memory, with addresses shown above each byte . . . . . . . . . . . . . . . 43
8. A portion of memory . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
xvi Assembler Language Programming for IBM System zβ’ Servers Version 2.00
9. A single 64-bit general register . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
10. All sixteen general registers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
11. Four Floating-Point Registers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
12. Sketch of a Program Status Word . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
13. Basic instruction cycle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
14. Instruction formats and data interactions . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
15. Opcode bit patterns for typical instruction types . . . . . . . . . . . . . . . . . . . . . . . 53
16. Instruction cycle with interruptions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
17. Typical instruction format for old computers . . . . . . . . . . . . . . . . . . . . . . . . 61
18. Structure of an addressing halfword . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
19. Sketch of Effective Address calculation . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
20. RX-type instruction, showing index register specification digit . . . . . . . . . . . . . . . 64
21. Sketch of Effective Address calculation with indexing . . . . . . . . . . . . . . . . . . . . 64
22. 31-bit Virtual Address . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
23. Simple view of Assembler processing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72
24. Simple view of program linking . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73
25. Simple view of program loading and execution . . . . . . . . . . . . . . . . . . . . . . . 74
26. Assembler Language statement columns . . . . . . . . . . . . . . . . . . . . . . . . . . . 75
27. Comment statement examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76
28. Block comments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76
29. Statement fields for machine, assembler, and macro-instruction statements . . . . . . . 77
30. A machine instruction statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78
31. An assembler instruction statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78
32. The macro-instruction statement RETURN . . . . . . . . . . . . . . . . . . . . . . . . . 78
33. A complete Assembler Language program . . . . . . . . . . . . . . . . . . . . . . . . . . 81
34. RX Instruction with explicit operands . . . . . . . . . . . . . . . . . . . . . . . . . . . 109
35. A simple program segment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117
36. Simple program segment with assembled contents . . . . . . . . . . . . . . . . . . . . . 118
37. Same program segment, at different memory addresses . . . . . . . . . . . . . . . . . . 118
38. Same program segment, with assembled contents . . . . . . . . . . . . . . . . . . . . . 118
39. Program segment with pre-calculated explicit base and displacements . . . . . . . . . 119
40. Program segment with explicit base and Assembler-calculated displacements . . . . . 119
41. Program Segment with USING Instruction . . . . . . . . . . . . . . . . . . . . . . . . 120
42. Sample program segment with erroneous statement . . . . . . . . . . . . . . . . . . . . 122
43. Sketch of pass one of an assembly . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 124
44. Sketch of pass two of an assembly . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125
45. USING Table with one entry . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126
46. Program segment with second USING statement . . . . . . . . . . . . . . . . . . . . . 127
47. USING Table with multiple entries . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127
48. Assembled contents when two USINGs are active . . . . . . . . . . . . . . . . . . . . 128
49. USING Table after DROP statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129
50. USING Table after second DROP statement . . . . . . . . . . . . . . . . . . . . . . . 130
51. Implied and explicit length specifications . . . . . . . . . . . . . . . . . . . . . . . . . . 140
52. Multiple constants . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142
53. F-type constant with decimal exponent . . . . . . . . . . . . . . . . . . . . . . . . . . . 146
54. Character, hexadecimal, and binary constants . . . . . . . . . . . . . . . . . . . . . . . 150
55. Length attribute reference to two constants, one a literal . . . . . . . . . . . . . . . . . 155
56. Describing fields of a (U.S.) telephone number . . . . . . . . . . . . . . . . . . . . . . 160
57. Describing fields of an Assembler Language statement . . . . . . . . . . . . . . . . . . 161
58. Define a group of words . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 161
59. Describing fields of an Assembler Language statement using ORG instructions . . . . 167
60. Describing an Assembler symbol cross-reference listing line . . . . . . . . . . . . . . . 171
61. 32-bit portion of a 64-bit general register . . . . . . . . . . . . . . . . . . . . . . . . . . 178
62. Sign extension by LH instruction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 183
63. Loss of significant digits using STH/LH . . . . . . . . . . . . . . . . . . . . . . . . . . 183
64. Loss of significant digits using STH/LH . . . . . . . . . . . . . . . . . . . . . . . . . . 183
65. Action of IC and STC instructions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 185
66. Interchanging two bytes with IC and STC . . . . . . . . . . . . . . . . . . . . . . . . . 185
67. Inserting a small number into a register . . . . . . . . . . . . . . . . . . . . . . . . . . . 185
68. Examples of some RR-type instructions . . . . . . . . . . . . . . . . . . . . . . . . . . 188
69. 64-bit general register . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 189
70. Sign extension by LGH instruction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 191
Figures xvii
71. Examples of some RR-type instructions for 64-bit operands . . . . . . . . . . . . . . . 192
72. Sign extension by LHR instruction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 193
73. Sign extension for instructions with mixed 32- and 64-bit signed operands . . . . . . . 195
74. Sign extension by Load Byte instructions . . . . . . . . . . . . . . . . . . . . . . . . . . 196
75. Zero extension by Load Logical Character instructions . . . . . . . . . . . . . . . . . . 197
76. Operation of Load Logical Halfword instructions . . . . . . . . . . . . . . . . . . . . . 197
77. Operation of Load Logical word instructions . . . . . . . . . . . . . . . . . . . . . . . 197
78. Operation of Load Logical Thirty One Bits instructions . . . . . . . . . . . . . . . . . 198
79. Examples of conditional branch instructions . . . . . . . . . . . . . . . . . . . . . . . . 205
80. CNOP alignments and operands . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 209
81. Calculate a sum with an intermediate test . . . . . . . . . . . . . . . . . . . . . . . . . 217
82. Calculate the sum of the first N odd integers . . . . . . . . . . . . . . . . . . . . . . . . 218
83. Example of arithmetic addition and subtraction . . . . . . . . . . . . . . . . . . . . . . 218
84. Testing the result of arithmetic instructions . . . . . . . . . . . . . . . . . . . . . . . . 218
85. Calculate a 64-bit sum with an intermediate test . . . . . . . . . . . . . . . . . . . . . . 221
86. Adding two 64-bit numbers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 221
87. Examples of arithmetic comparisons . . . . . . . . . . . . . . . . . . . . . . . . . . . . 222
88. Calculate the sum of N odd integers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 223
89. Adding two 64-bit numbers logically . . . . . . . . . . . . . . . . . . . . . . . . . . . . 225
90. Double-length complementation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 225
91. Double-length complementation, a simpler way . . . . . . . . . . . . . . . . . . . . . . 226
92. Double-length addition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 226
93. Double-length subtraction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 226
94. Example of logical addition and subtraction . . . . . . . . . . . . . . . . . . . . . . . . 227
95. Double-length addition with carry . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 229
96. Double-length subtraction with borrow . . . . . . . . . . . . . . . . . . . . . . . . . . . 229
97. Sign extension for instructions with mixed 32- and 64-bit signed operands . . . . . . . 230
98. Calculate a 64-bit sum with an intermediate test . . . . . . . . . . . . . . . . . . . . . . 230
99. Calculate a 64-bit sum with an intermediate test . . . . . . . . . . . . . . . . . . . . . . 230
100. Sign extension for instructions with mixed 32- and 64-bit unsigned operands . . . . . 231
101. Examples of logical comparisons . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 232
102. Comparing logically ordered values . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 233
103. Bit positions used by IPM and SPM instructions (System/360 PSW sketch) . . . . . 234
104. Register contents before shifting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 243
105. Logical unit shift left . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 244
106. Logical unit shift right . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 244
107. Arithmetic unit shift right . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 244
108. Arithmetic unit shift left . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 244
109. Rounding an integer to the next higher multiple of 8 . . . . . . . . . . . . . . . . . . . 246
110. A 6-byte data entry . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 246
111. Storage definitions for a 6-byte data entry . . . . . . . . . . . . . . . . . . . . . . . . . 246
112. Using shift instructions for a 6-byte data item . . . . . . . . . . . . . . . . . . . . . . . 246
113. Shifting to make the low-order bit one (1) . . . . . . . . . . . . . . . . . . . . . . . . . 248
114. Shifting to make the low-order bit one (2) . . . . . . . . . . . . . . . . . . . . . . . . . 249
115. Four integers packed in a 32-bit word . . . . . . . . . . . . . . . . . . . . . . . . . . . . 249
116. Extracting one packed integer from a 32-bit word . . . . . . . . . . . . . . . . . . . . . 249
117. Unpacking four unsigned integers using right shifts . . . . . . . . . . . . . . . . . . . . 250
118. Unpacking four unsigned integers using left shifts . . . . . . . . . . . . . . . . . . . . . 250
119. Unpacking four signed integers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 254
120. Logical rotate unit shift . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 257
121. Packing four unsigned bit-length constants in a 32-bit word . . . . . . . . . . . . . . . 260
122. Packing four signed bit-length constants in a 32-bit word . . . . . . . . . . . . . . . . 260
123. General layout of multiplication operands . . . . . . . . . . . . . . . . . . . . . . . . . 265
124. Double-length product of multiply operations . . . . . . . . . . . . . . . . . . . . . . . 266
125. Calculate the sum of the first 10 cubed integers . . . . . . . . . . . . . . . . . . . . . . 267
126. Illustration of binary multiplication . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 273
127. General result of divide operation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 274
128. Operands of double-length division . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 275
129. Example of division by 3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 276
130. Example of rounded integer division . . . . . . . . . . . . . . . . . . . . . . . . . . . . 276
131. Example of rounded integer division with signed dividend . . . . . . . . . . . . . . . . 277
132. Ensuring a valid arithmetic division . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 277
xviii Assembler Language Programming for IBM System zβ’ Servers Version 2.00
133. Causing a fixed-point divide interruption . . . . . . . . . . . . . . . . . . . . . . . . . . 277
134. Operands of single-length division before division . . . . . . . . . . . . . . . . . . . . . 278
135. Operands of single-length division after division . . . . . . . . . . . . . . . . . . . . . . 278
136. Example of logical division . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 280
137. Illustration of binary division . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 282
138. Logical operations AND, OR, and XOR . . . . . . . . . . . . . . . . . . . . . . . . . . 289
139. Examples of logical operations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 290
140. Inserting a new integer value using AND and OR . . . . . . . . . . . . . . . . . . . . . 291
141. Data masking using Exclusive OR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 292
142. Rounding to the next multiple of 8 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 293
143. Rounding to the next multiple of 8 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 293
144. Complementing a double-length integer . . . . . . . . . . . . . . . . . . . . . . . . . . 293
145. Effective Address generation for long-displacement instructions . . . . . . . . . . . . . 303
146. Addressability range with 12-bit displacements . . . . . . . . . . . . . . . . . . . . . . . 304
147. Addressability range with 20-bit displacements . . . . . . . . . . . . . . . . . . . . . . . 304
148. Effective Address formation for relative-immediate instructions . . . . . . . . . . . . . 305
149. Areas of memory addressed by three AMODEs . . . . . . . . . . . . . . . . . . . . . . 308
150. System z PSW showing addressing-mode bits . . . . . . . . . . . . . . . . . . . . . . . 308
151. Loading integer constants with the LAY instruction . . . . . . . . . . . . . . . . . . . 310
152. Counting number of shifts to make rightmost bit a 1-bit . . . . . . . . . . . . . . . . . 311
153. Using LA to set a branch address . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 311
154. 64-bit Virtual Address . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 314
155. 64-bit Virtual Address with Region Indexes . . . . . . . . . . . . . . . . . . . . . . . . 314
156. Instruction classes, including RI, RIL . . . . . . . . . . . . . . . . . . . . . . . . . . . . 316
157. Four halfwords in a 64-bit general register . . . . . . . . . . . . . . . . . . . . . . . . . 317
158. Operation of six Insert Immediate instructions . . . . . . . . . . . . . . . . . . . . . . . 318
159. Operation of LHI instruction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 319
160. Operation of LGHI instruction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 319
161. Examples of load-immediate instructions . . . . . . . . . . . . . . . . . . . . . . . . . . 320
162. Operation of six logical load instructions . . . . . . . . . . . . . . . . . . . . . . . . . . 320
163. Extracting an unsigned integer value using AND Immediate . . . . . . . . . . . . . . . 323
164. Inserting a new integer value using AND Immediate . . . . . . . . . . . . . . . . . . . 323
165. Data masking using immediate operands . . . . . . . . . . . . . . . . . . . . . . . . . . 324
166. Data masking using a symbolically defined immediate operand . . . . . . . . . . . . . 324
167. A simple loop to scan and replace characters . . . . . . . . . . . . . . . . . . . . . . . . 332
168. A simple loop, using indexing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 333
169. Indexing into a branch table . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 333
170. A backward loop to scan and replace characters . . . . . . . . . . . . . . . . . . . . . . 334
171. Calculate the sum of the first N odd integers . . . . . . . . . . . . . . . . . . . . . . . . 335
172. Store the cubes of the first 10 integers . . . . . . . . . . . . . . . . . . . . . . . . . . . . 336
173. Sketch of a Do-Until loop . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 339
174. Sketch of a Do-While loop . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 339
175. Store the cubes of the first 10 integers in a different way . . . . . . . . . . . . . . . . . 340
176. Operation of BXH and BXLE instructions . . . . . . . . . . . . . . . . . . . . . . . . . 342
177. Operation of BXH and BXLE instructions . . . . . . . . . . . . . . . . . . . . . . . . . 342
178. Replacing special characters with blanks, using BXLE . . . . . . . . . . . . . . . . . . 343
179. Creating a table of cubed integers using BXLE . . . . . . . . . . . . . . . . . . . . . . 344
180. Creating a table of cubed integers using BXLE . . . . . . . . . . . . . . . . . . . . . . 344
181. Creating a table of cubed integers with addresses as controls . . . . . . . . . . . . . . . 344
182. Creating a table of cubed integers using BXH . . . . . . . . . . . . . . . . . . . . . . . 346
183. Creating a table of cubed integers, using BXH in a special way . . . . . . . . . . . . . 346
184. Examples of the MVI instruction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 353
185. Examples of the NI instruction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 354
186. Examples of the OI instruction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 354
187. Example of the XI instruction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 354
188. A simpler loop to scan and replace characters . . . . . . . . . . . . . . . . . . . . . . . 355
189. Setting an overflow-indication flag bit . . . . . . . . . . . . . . . . . . . . . . . . . . . . 357
190. Adding alternate list elements twice . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 357
191. Defining bit names safely . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 360
192. Using safely-defined bit names . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 360
193. Converting a binary integer to characters . . . . . . . . . . . . . . . . . . . . . . . . . . 361
194. Adding alternate list elements twice, with program modification . . . . . . . . . . . . . 362
Figures xix
195. Adding alternate list elements twice, without program modification . . . . . . . . . . . 363
196. Assembler Language syntax of basic SS-type instructions . . . . . . . . . . . . . . . . 366
197. Examples of SS-type instruction operands . . . . . . . . . . . . . . . . . . . . . . . . . 367
198. SS-type instruction using a Length Attribute reference . . . . . . . . . . . . . . . . . . 369
199. Examples of Length Specification Bytes . . . . . . . . . . . . . . . . . . . . . . . . . . 372
200. Emulated operation of MVC instruction . . . . . . . . . . . . . . . . . . . . . . . . . . 372
201. Example of Move Inverse instruction . . . . . . . . . . . . . . . . . . . . . . . . . . . . 373
202. Emulated operation of MVCIN instruction . . . . . . . . . . . . . . . . . . . . . . . . 374
203. Example of MVCOS instruction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 375
204. Inserting bits in a word using logical SS-type instructions . . . . . . . . . . . . . . . . 377
205. Emulating the TR instruction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 380
206. TR instruction to change special characters to blanks . . . . . . . . . . . . . . . . . . . 380
207. Translating hex digits to EBCDIC characters (1) . . . . . . . . . . . . . . . . . . . . . 381
208. Translating hex digits to EBCDIC characters (2) . . . . . . . . . . . . . . . . . . . . . 381
209. Searching for punctuation characters using CLI . . . . . . . . . . . . . . . . . . . . . . 385
210. Searching for punctuation characters using TRT . . . . . . . . . . . . . . . . . . . . . 385
211. Using TRT to validate numeric characters . . . . . . . . . . . . . . . . . . . . . . . . . 385
212. Using TRT to scan for embedded quotations . . . . . . . . . . . . . . . . . . . . . . . 386
213. Using TRT to scan a string of names and build an occurrence list . . . . . . . . . . . 387
214. Using TRTR to validate numeric characters . . . . . . . . . . . . . . . . . . . . . . . . 387
215. Scanning a string backward using CLI . . . . . . . . . . . . . . . . . . . . . . . . . . . 388
216. Scanning a string backward using TRTR . . . . . . . . . . . . . . . . . . . . . . . . . . 388
217. Executing a list of instructions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 390
218. Executing a list of instructions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 390
219. Constructing an executed instruction . . . . . . . . . . . . . . . . . . . . . . . . . . . . 391
220. Moving a string of bytes of unknown length . . . . . . . . . . . . . . . . . . . . . . . . 392
221. Register use by CLCL and MVCL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 404
222. Conceptual execution of the MVCL instruction . . . . . . . . . . . . . . . . . . . . . . 406
223. Using MVCL to set a field to blanks . . . . . . . . . . . . . . . . . . . . . . . . . . . . 406
224. Moving a message with padding and length checking . . . . . . . . . . . . . . . . . . . 406
225. Conceptual execution of the CLCL instruction . . . . . . . . . . . . . . . . . . . . . . 408
226. Using CLCL to test for blanks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 408
227. Comparing two records without padding . . . . . . . . . . . . . . . . . . . . . . . . . . 409
228. Register use by MVCLE and CLCLE . . . . . . . . . . . . . . . . . . . . . . . . . . . 411
229. Conceptual execution of the MVCLE instruction . . . . . . . . . . . . . . . . . . . . . 412
230. Using MVCLE to set a field to blanks . . . . . . . . . . . . . . . . . . . . . . . . . . . 413
231. Using MVCLE to initialize an area to zero . . . . . . . . . . . . . . . . . . . . . . . . . 413
232. Conceptual execution of the CLCLE instruction . . . . . . . . . . . . . . . . . . . . . 413
233. Using CLCLE to test for all blanks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 414
234. Registers bounding the SRST search string . . . . . . . . . . . . . . . . . . . . . . . . . 416
235. Conceptual execution of the SRST instruction . . . . . . . . . . . . . . . . . . . . . . 416
236. Conceptual execution of the MVST instruction . . . . . . . . . . . . . . . . . . . . . . 418
237. Moving a null-terminated string . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 418
238. Using MVST to isolate comma-separated tokens . . . . . . . . . . . . . . . . . . . . . 418
239. Conceptual execution of the CLST instruction . . . . . . . . . . . . . . . . . . . . . . 420
240. Translating characters to upper case with TRE . . . . . . . . . . . . . . . . . . . . . . 422
241. Examples using the CUSE instruction . . . . . . . . . . . . . . . . . . . . . . . . . . . 424
242. Fragment of an Institute-machine punched paper tape . . . . . . . . . . . . . . . . . . 428
243. Mixed single- and double-byte EBCDIC characters . . . . . . . . . . . . . . . . . . . . 434
244. Examples of DBCS data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 435
245. Extended continuation for DBCS data . . . . . . . . . . . . . . . . . . . . . . . . . . . 437
246. CU-type constant generating Unicode characters . . . . . . . . . . . . . . . . . . . . . 440
247. Using MVCLU to initialize an area to Unicode spaces . . . . . . . . . . . . . . . . . . 442
248. Using CLCLU to test for Unicode spaces . . . . . . . . . . . . . . . . . . . . . . . . . 443
249. Assembler instruction statement for RRF-type instructions with an optional operand 444
250. Using TRTT to translate from DBCS to Unicode . . . . . . . . . . . . . . . . . . . . 446
251. Translating a long string with TR and MVC, and with TROO . . . . . . . . . . . . . 446
252. Bits of a UTF-16 Unicode character . . . . . . . . . . . . . . . . . . . . . . . . . . . . 447
253. Bits of a UTF-16 Unicode surrogate pair . . . . . . . . . . . . . . . . . . . . . . . . . . 447
254. Bits of a UTF-32 Unicode character from a UTF-16 surrogate pair . . . . . . . . . . 448
255. Example of using TRTE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 451
256. Big-Endian storage representation of X'87654321' . . . . . . . . . . . . . . . . . . . . 453
Figures xxi
319. Shifting a decimal operand left an even number of digits . . . . . . . . . . . . . . . . . 520
320. Shifting a decimal operand right an even number of digits . . . . . . . . . . . . . . . . 520
321. Shifting a decimal operand right an even number of digits . . . . . . . . . . . . . . . . 521
322. Ensuring decimal point alignment for packed decimal addition . . . . . . . . . . . . . 523
323. A business calculation in packed decimal, part 1 . . . . . . . . . . . . . . . . . . . . . . 527
324. A business calculation in packed decimal, part 2 . . . . . . . . . . . . . . . . . . . . . . 527
325. A business calculation in packed decimal, part 3 . . . . . . . . . . . . . . . . . . . . . . 528
326. A business calculation in packed decimal, part 4 . . . . . . . . . . . . . . . . . . . . . . 528
327. Integer and Scale Attributes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 529
328. Using Scale Attributes in a SRP instruction . . . . . . . . . . . . . . . . . . . . . . . . 529
329. Converting a 64-bit binary integer to packed decimal . . . . . . . . . . . . . . . . . . . 533
330. Using CVD to format page numbers . . . . . . . . . . . . . . . . . . . . . . . . . . . . 533
331. Converting decimal characters to binary . . . . . . . . . . . . . . . . . . . . . . . . . . 535
332. Sketch of an editing operation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 536
333. Representation of an editing pattern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 537
334. Convert a packed decimal integer to characters using UNPK . . . . . . . . . . . . . . 538
335. Convert a packed decimal integer to characters using ED . . . . . . . . . . . . . . . . 538
336. Converting a 32-bit binary integer to characters . . . . . . . . . . . . . . . . . . . . . . 540
337. Editing a binary integer with separating commas . . . . . . . . . . . . . . . . . . . . . 541
338. Editing a signed number . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 542
339. Using field protection with ED . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 542
340. Edited result with a floating currency symbol . . . . . . . . . . . . . . . . . . . . . . . 543
341. Edited result with a properly placed floating currency symbol . . . . . . . . . . . . . . 544
342. Integer value with optional sign and separating commas . . . . . . . . . . . . . . . . . 544
343. Editing two packed decimal numbers into a single field . . . . . . . . . . . . . . . . . . 545
344. Editing multiple values . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 545
345. Logical-operation description of the editing process . . . . . . . . . . . . . . . . . . . . 547
346. ED and EDMK operation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 548
347. A data item containing an integer value . . . . . . . . . . . . . . . . . . . . . . . . . . . 552
348. A data item containing integer and fraction parts . . . . . . . . . . . . . . . . . . . . . 552
349. Values with radix point outside the digits . . . . . . . . . . . . . . . . . . . . . . . . . . 553
350. Calculating a tax amount in scaled fixed decimal arithmetic . . . . . . . . . . . . . . . 553
351. Calculating a tax amount in scaled fixed binary arithmetic . . . . . . . . . . . . . . . . 554
352. Two binary constants scaled by 2**28 . . . . . . . . . . . . . . . . . . . . . . . . . . . 555
353. Defining a scaled binary constant 10**12 . . . . . . . . . . . . . . . . . . . . . . . . . . 555
354. Multiplying two scaled binary numbers . . . . . . . . . . . . . . . . . . . . . . . . . . . 556
355. Examples of data with widely ranging values . . . . . . . . . . . . . . . . . . . . . . . . 559
356. A typical floating-point representation . . . . . . . . . . . . . . . . . . . . . . . . . . . 560
357. An example of a floating-point representation using 4 decimal digits . . . . . . . . . . 561
358. Another example of a floating-point representation using 4 decimal digits . . . . . . . 561
359. A floating-point representation showing left normalized and unnormalized values . . 561
360. A floating-point representation showing right normalized and unnormalized values . 562
361. A floating-point representation showing values without normalization . . . . . . . . . 562
362. Floating-point numbers with signed exponent . . . . . . . . . . . . . . . . . . . . . . . 563
363. Examples of approximate floating-point representations . . . . . . . . . . . . . . . . . 563
364. Three floating-point data lengths . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 564
365. Four floating-point registers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 564
366. All sixteen floating-point registers, showing register pairings . . . . . . . . . . . . . . . 566
367. Integer-based representation of 73 in FPI(10,4) . . . . . . . . . . . . . . . . . . . . . . 577
368. Illustrating floating-point division corrective right shift . . . . . . . . . . . . . . . . . . 578
369. Exponent range of representable and computable values . . . . . . . . . . . . . . . . . 583
370. Hexadecimal floating-point number representations . . . . . . . . . . . . . . . . . . . . 587
371. Quadword aligned constants and data . . . . . . . . . . . . . . . . . . . . . . . . . . . . 594
372. Hexadecimal floating-point constants with rounding suffixes . . . . . . . . . . . . . . . 595
373. Examples of hexadecimal floating-point instructions . . . . . . . . . . . . . . . . . . . 598
374. Example of LTXR instruction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 598
375. Examples of extended-precision hexadecimal RR instructions . . . . . . . . . . . . . . 598
376. Short hexadecimal floating-point multiplication . . . . . . . . . . . . . . . . . . . . . . 599
377. Floating-point registers used for hexadecimal floating-point multiplication . . . . . . . 600
378. Calculating a table of short hexadecimal floating-point products . . . . . . . . . . . . 600
379. Calculating a table of long hexadecimal floating-point products . . . . . . . . . . . . . 600
380. Floating-point registers used for hexadecimal floating-point multiplication . . . . . . . 601
xxii Assembler Language Programming for IBM System zβ’ Servers Version 2.00
381. Example of hexadecimal floating-point divide instructions . . . . . . . . . . . . . . . . 604
382. Example of hexadecimal floating-point divide instructions . . . . . . . . . . . . . . . . 604
383. Example of a hexadecimal floating-point halve instruction . . . . . . . . . . . . . . . . 605
384. Hexadecimal halve instruction causing underflow . . . . . . . . . . . . . . . . . . . . . 605
385. Example of hexadecimal floating-point addition . . . . . . . . . . . . . . . . . . . . . . 606
386. Evaluating a hexadecimal floating-point expression . . . . . . . . . . . . . . . . . . . . 607
387. Evaluating a hexadecimal floating-point inner product . . . . . . . . . . . . . . . . . . 608
388. Evaluating a polynomial with hexadecimal floating-point arithmetic . . . . . . . . . . 608
389. Evaluating a quadratic polynomial . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 608
390. Converting a binary integer to hexadecimal floating-point . . . . . . . . . . . . . . . . 609
391. Converting a hexadecimal floating-point number to a binary integer . . . . . . . . . . 610
392. Rounding a long hexadecimal floating-point number to short . . . . . . . . . . . . . . 617
393. Rounded inner product of long HFP numbers . . . . . . . . . . . . . . . . . . . . . . . 617
394. Manually rounding long to short (1) . . . . . . . . . . . . . . . . . . . . . . . . . . . . 618
395. Manually rounding long to short (2) . . . . . . . . . . . . . . . . . . . . . . . . . . . . 618
396. Manually rounding long to short (3) . . . . . . . . . . . . . . . . . . . . . . . . . . . . 618
397. Converting a 32-bit integer to short hexadecimal floating-point . . . . . . . . . . . . . 620
398. Converting a 64-bit integer to three hexadecimal floating-point values . . . . . . . . . 620
399. Early conversion of integer to hexadecimal floating-point . . . . . . . . . . . . . . . . 621
400. Format of a machine instruction statement for converting HFP to binary . . . . . . . 621
401. Calculating a HFP remainder . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 625
402. Evaluating a hexadecimal floating-point remainder . . . . . . . . . . . . . . . . . . . . 626
403. Examples of HFP square root instructions . . . . . . . . . . . . . . . . . . . . . . . . . 627
404. Three binary floating-point data representations . . . . . . . . . . . . . . . . . . . . . . 639
405. Range of the binary floating-point representation . . . . . . . . . . . . . . . . . . . . . 641
406. A view of the binary floating-point representation . . . . . . . . . . . . . . . . . . . . . 642
407. Examples of short binary floating-point constants . . . . . . . . . . . . . . . . . . . . . 642
408. Examples of long and extended binary floating-point constants . . . . . . . . . . . . . 643
409. Rounding indicators for binary floating-point constants . . . . . . . . . . . . . . . . . 643
410. Examples of parameterized binary floating-point NaNs . . . . . . . . . . . . . . . . . . 644
411. Binary floating-point constants with decimal exponents and modifiers . . . . . . . . . 645
412. Values representable with gradual underflow . . . . . . . . . . . . . . . . . . . . . . . . 647
413. Floating-Point Control (FPC) register . . . . . . . . . . . . . . . . . . . . . . . . . . . 649
414. Examples of binary floating-point data movement instructions . . . . . . . . . . . . . 656
415. Example of binary floating-point multiply instructions . . . . . . . . . . . . . . . . . . 657
416. Examples of binary floating-point multiplication overflow and underflow . . . . . . . 658
417. Examples of binary floating-point multiply instructions . . . . . . . . . . . . . . . . . 658
418. Example of binary floating-point denormalized product . . . . . . . . . . . . . . . . . 658
419. Example of binary floating-point extended-precision operands . . . . . . . . . . . . . . 658
420. Examples of binary floating-point division . . . . . . . . . . . . . . . . . . . . . . . . . 659
421. Examples of binary floating-point division overflow and underflow . . . . . . . . . . . 660
422. Examples of binary floating-point addition and subtraction . . . . . . . . . . . . . . . 661
423. Examples of binary floating-point comparison . . . . . . . . . . . . . . . . . . . . . . . 663
424. Examples of binary floating-point compare and signal instructions . . . . . . . . . . . 663
425. Examples of binary floating-point rounding instructions . . . . . . . . . . . . . . . . . 664
426. Examples of BFP load lengthened instructions . . . . . . . . . . . . . . . . . . . . . . 665
427. Examples of BFP load lengthened instructions with NaNs . . . . . . . . . . . . . . . . 665
428. Examples of binary integer to binary floating-point instructions . . . . . . . . . . . . . 666
429. Examples of converting binary floating-point fractions to integers with rounding . . . 667
430. Examples of Convert to Fixed instructions . . . . . . . . . . . . . . . . . . . . . . . . . 667
431. Examples of load FP integer instructions . . . . . . . . . . . . . . . . . . . . . . . . . . 669
432. Examples of divide to integer instructions . . . . . . . . . . . . . . . . . . . . . . . . . 670
433. Example of iterative divide to integer . . . . . . . . . . . . . . . . . . . . . . . . . . . . 670
434. Iterative execution of a divide to integer instruction . . . . . . . . . . . . . . . . . . . . 671
435. Examples of binary floating-point square root instructions . . . . . . . . . . . . . . . . 672
436. Example of binary floating-point multiply and add instructions . . . . . . . . . . . . . 673
437. Hexadecimal and binary floating-point representations . . . . . . . . . . . . . . . . . . 681
438. Conceptual decimal floating-point representation . . . . . . . . . . . . . . . . . . . . . 682
439. Three decimal floating-point representations of the same value . . . . . . . . . . . . . 683
440. Decimal floating-point data representation . . . . . . . . . . . . . . . . . . . . . . . . . 686
441. System z decimal floating-point representations . . . . . . . . . . . . . . . . . . . . . . 687
442. DFP constants with exponent modifiers and decimal exponents . . . . . . . . . . . . . 692
Figures xxiii
443. Examples of decimal floating-point Test Data Class instructions . . . . . . . . . . . . 694
444. Illustration of decimal floating-point rounding candidates . . . . . . . . . . . . . . . . 695
445. Illustration of decimal floating-point rounding candidates near zero . . . . . . . . . . . 695
446. Floating-Point Control (FPC) register . . . . . . . . . . . . . . . . . . . . . . . . . . . 698
447. Examples of converting decimal floating-point to fixed binary . . . . . . . . . . . . . . 708
448. Examples of converting decimal floating-point to binary integer . . . . . . . . . . . . . 709
449. Converting signed packed decimal to decimal floating-point . . . . . . . . . . . . . . . 710
450. Converting decimal floating-point to signed packed decimal . . . . . . . . . . . . . . . 710
451. Converting decimal floating-point to signed packed decimal . . . . . . . . . . . . . . . 710
452. Converting unsigned packed decimal to decimal floating-point . . . . . . . . . . . . . 711
453. Converting decimal floating-point to unsigned packed decimal . . . . . . . . . . . . . 711
454. Effect of the mask operand on Convert from Zoned results . . . . . . . . . . . . . . . 713
455. Examples of converting decimal floating-point to zoned . . . . . . . . . . . . . . . . . 714
456. DFP arithmetic with short operands . . . . . . . . . . . . . . . . . . . . . . . . . . . . 717
457. Floating-Point Control Register showing Decimal Rounding Mode bits . . . . . . . . 718
458. Example of extracting DFP biased exponent . . . . . . . . . . . . . . . . . . . . . . . . 719
459. Example of inserting a biased DFP exponent . . . . . . . . . . . . . . . . . . . . . . . 720
460. Examples of DFP Extract Significance instructions . . . . . . . . . . . . . . . . . . . . 720
461. Converting an extended decimal floating-point value to packed decimal . . . . . . . . 722
462. Calculate price plus tax . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 724
463. Correctly rounding a cost to two decimal digits . . . . . . . . . . . . . . . . . . . . . . 724
464. Example of a reround instruction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 725
465. Example of rerounding arbitrary amounts . . . . . . . . . . . . . . . . . . . . . . . . . 725
466. Examples of assembled DFP constants using rounding for reround . . . . . . . . . . . 726
467. Example of DFP binary-significand format . . . . . . . . . . . . . . . . . . . . . . . . . 730
468. Sketch of short binary-significand format . . . . . . . . . . . . . . . . . . . . . . . . . . 730
469. BCD-to-DPD encodings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 734
470. DPD-to-BCD translation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 735
471. Degraded precision in adding hexadecimal floating-point pseudo-zeros . . . . . . . . . 748
472. Trivial example of a subroutine (1) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 757
473. Trivial example of a subroutine (2) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 757
474. Subroutine linkage using a BAS instruction . . . . . . . . . . . . . . . . . . . . . . . . 758
475. Subroutine linkage using a BASR instruction . . . . . . . . . . . . . . . . . . . . . . . 759
476. Subroutine linkage using an address constant . . . . . . . . . . . . . . . . . . . . . . . 759
477. Simple shift subroutine (1) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 760
478. Simple shift subroutine (2) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 760
479. Simple shift subroutine with named arguments (3) . . . . . . . . . . . . . . . . . . . . 760
480. Simple shift subroutine (4) using argument addresses . . . . . . . . . . . . . . . . . . . 761
481. Simple shift subroutine (5) with argument addresses in memory . . . . . . . . . . . . . 761
482. Subroutine call with inline arguments . . . . . . . . . . . . . . . . . . . . . . . . . . . . 761
483. Subroutine returning past inline argument . . . . . . . . . . . . . . . . . . . . . . . . . 762
484. Subroutine call with inline argument addresses . . . . . . . . . . . . . . . . . . . . . . . 762
485. Subroutine with argument address list . . . . . . . . . . . . . . . . . . . . . . . . . . . . 763
486. Subroutine saves and restores registers . . . . . . . . . . . . . . . . . . . . . . . . . . . 764
487. General argument-passing scheme . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 766
488. Subroutine call using an argument address list . . . . . . . . . . . . . . . . . . . . . . . 766
489. Subroutine called with an argument address list . . . . . . . . . . . . . . . . . . . . . . 766
490. Constructing an argument address list . . . . . . . . . . . . . . . . . . . . . . . . . . . . 767
491. Two variable-length argument lists . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 767
492. Calling a subroutine with a variable-length argument list . . . . . . . . . . . . . . . . . 767
493. Subroutine called with a variable-length argument list . . . . . . . . . . . . . . . . . . 767
494. Sketch of a variable-length argument list . . . . . . . . . . . . . . . . . . . . . . . . . . 768
495. Sample 64-bit argument list addresses . . . . . . . . . . . . . . . . . . . . . . . . . . . . 768
496. Standard save area layout . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 771
497. Sample subroutine calling sequence . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 771
498. Save area chaining instructions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 772
499. Chained save areas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 772
500. Reloading registers and returning to a caller . . . . . . . . . . . . . . . . . . . . . . . . 772
501. Format-4 save area layout . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 774
502. Example of using a Format-4 save area . . . . . . . . . . . . . . . . . . . . . . . . . . . 774
503. Format-5 save area layout . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 775
504. Saving registers using a Format-5 save area . . . . . . . . . . . . . . . . . . . . . . . . . 776
xxiv Assembler Language Programming for IBM System zβ’ Servers Version 2.00
505. Return from a routine using a Format-5 save area . . . . . . . . . . . . . . . . . . . . 776
506. Example of an entry point identifier . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 777
507. Example of two calling point identifiers . . . . . . . . . . . . . . . . . . . . . . . . . . . 778
508. Setting a return flag . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 778
509. Setting a return code in register 15 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 779
510. Testing a return code returned in register 15 . . . . . . . . . . . . . . . . . . . . . . . . 780
511. Using a return code as a branch index . . . . . . . . . . . . . . . . . . . . . . . . . . . 780
512. Using a return code as a branch index with relative branch instructions . . . . . . . . 780
513. Checking for valid return code values . . . . . . . . . . . . . . . . . . . . . . . . . . . . 780
514. Setting a reason code in register 0 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 781
515. Using RETURN macros to set return flags and return codes . . . . . . . . . . . . . . 781
516. Returning to an error branch without a return code . . . . . . . . . . . . . . . . . . . . 781
517. Call with error branch instructions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 782
518. Convention for passing main-program parameters . . . . . . . . . . . . . . . . . . . . . 782
519. Example of calling with assisted linkage . . . . . . . . . . . . . . . . . . . . . . . . . . . 784
520. Example of a routine to implement assisted linkage . . . . . . . . . . . . . . . . . . . . 784
521. Assisted linkage routine with counters . . . . . . . . . . . . . . . . . . . . . . . . . . . 784
522. Example of a lowest level subroutine . . . . . . . . . . . . . . . . . . . . . . . . . . . . 786
523. Establish three base registers (1) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 791
524. Establish three base registers (2) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 791
525. Establish three base registers (3) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 791
526. Establish three base registers (4) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 792
527. Establish three base registers (5) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 792
528. Establish three base registers with risks (6) . . . . . . . . . . . . . . . . . . . . . . . . . 792
529. Establish three base registers (7) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 793
530. Establish three base registers (8) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 793
531. Establish three base registers (9) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 793
532. Calling a subroutine not needing local addressability . . . . . . . . . . . . . . . . . . . 798
533. Calling a subroutine not locally addressable . . . . . . . . . . . . . . . . . . . . . . . . 799
534. Subroutine with local addressability . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 799
535. Replacing based branch instructions with relative-immediates . . . . . . . . . . . . . . 800
536. Replacing a based EXecute instruction with EXRL . . . . . . . . . . . . . . . . . . . . 800
537. Replacing references to constants with immediate operands . . . . . . . . . . . . . . . 800
538. Replacing short unsigned displacements with long signed displacements . . . . . . . . 800
539. A program fragment needing reorganization . . . . . . . . . . . . . . . . . . . . . . . . 801
540. A program fragment after reorganization . . . . . . . . . . . . . . . . . . . . . . . . . . 801
541. Reorganizing a program to minimize base registers . . . . . . . . . . . . . . . . . . . . 801
542. Incorrect implied reference to a different control section . . . . . . . . . . . . . . . . . 804
543. Correct implied reference to a different control section . . . . . . . . . . . . . . . . . . 804
544. USING Table with two entries . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 805
545. Main program and subroutine in one assembly . . . . . . . . . . . . . . . . . . . . . . 805
546. Main program, subroutine, and common section in one assembly . . . . . . . . . . . 806
547. Resuming control sections . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 806
548. Main program and subroutine in one assembly, multiple CSects . . . . . . . . . . . . 807
549. Statements with Location Counter discontinuities . . . . . . . . . . . . . . . . . . . . . 808
550. Technique for rounding the length of a CSECT . . . . . . . . . . . . . . . . . . . . . . 809
551. Rearrangement of source groups by LOCTR . . . . . . . . . . . . . . . . . . . . . . . 811
552. Simple example of LOCTR (1) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 811
553. Simple example of LOCTR (2) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 812
554. Simple example of LOCTR (3) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 812
555. A program fragment using LOCTR for reorganization . . . . . . . . . . . . . . . . . . 812
556. Organizing a program to minimize addressability problems . . . . . . . . . . . . . . . 813
557. Organizing a program to minimize addressability problems . . . . . . . . . . . . . . . 813
558. Simple example of LOCTR (4) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 814
559. Example of unexpected LOCTR behavior (1) . . . . . . . . . . . . . . . . . . . . . . . 814
560. Example of unexpected LOCTR behavior (2) . . . . . . . . . . . . . . . . . . . . . . . 815
561. Calling ShftRt as an external routine . . . . . . . . . . . . . . . . . . . . . . . . . . . . 819
562. ShftRt subroutine as a separate assembly . . . . . . . . . . . . . . . . . . . . . . . . . . 819
563. External references using relative branch instructions . . . . . . . . . . . . . . . . . . . 820
564. Using WXTRN to test whether a routine was linked . . . . . . . . . . . . . . . . . . . 820
565. Calling ShftRt as an external routine . . . . . . . . . . . . . . . . . . . . . . . . . . . . 821
566. ShftRt subroutine in a different CSect . . . . . . . . . . . . . . . . . . . . . . . . . . . 822
Figures xxv
567. Main program with ENTRY for data . . . . . . . . . . . . . . . . . . . . . . . . . . . . 822
568. Subroutine using EXTRN to reference data . . . . . . . . . . . . . . . . . . . . . . . . 822
569. Subroutine using EXTRN and adcons to reference data . . . . . . . . . . . . . . . . . 823
570. Subroutine with entries for two similar functions . . . . . . . . . . . . . . . . . . . . . 824
571. Subroutine with two similar functions and some common code . . . . . . . . . . . . . 824
572. Sample assembly with external symbols . . . . . . . . . . . . . . . . . . . . . . . . . . . 825
573. External symbol dictionary from sample assembly . . . . . . . . . . . . . . . . . . . . 825
574. Program assembled with different SECTALGN options . . . . . . . . . . . . . . . . . 827
575. Example of ESD listings with different SECTALGN options . . . . . . . . . . . . . . 827
576. Assigning RMODE and AMODE to a section name . . . . . . . . . . . . . . . . . . . 828
577. ESD showing RMODE and AMODE of section names . . . . . . . . . . . . . . . . . 829
578. Example of two source modules to be linked . . . . . . . . . . . . . . . . . . . . . . . 834
579. Sketch of object module from source module 1 . . . . . . . . . . . . . . . . . . . . . . 834
580. Sketch of object module from source module 2 . . . . . . . . . . . . . . . . . . . . . . 835
581. Composite ESD after reading first object module . . . . . . . . . . . . . . . . . . . . . 835
582. Composite ESD after loading second object module . . . . . . . . . . . . . . . . . . . 836
583. Composite ESD after assigning memory addresses . . . . . . . . . . . . . . . . . . . . 836
584. Memory layout of loaded program . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 837
585. Sample DXD declarations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 838
586. External dummy section declaration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 838
587. Referencing external dummy items with Q-cons . . . . . . . . . . . . . . . . . . . . . . 838
588. External dummy items in ESD listing . . . . . . . . . . . . . . . . . . . . . . . . . . . . 839
589. Separate DXD declaration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 839
590. Example of a completed External Dummy Section . . . . . . . . . . . . . . . . . . . . 839
591. Retrieving an External Dummy Section item . . . . . . . . . . . . . . . . . . . . . . . 840
592. PL/I technique for loading Pseudo Registers . . . . . . . . . . . . . . . . . . . . . . . . 840
593. ESDID Translation Table entry for an incoming symbol . . . . . . . . . . . . . . . . . 842
594. A typical load-time CESD entry . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 842
595. Composite ESD after assigning load module addresses . . . . . . . . . . . . . . . . . . 845
596. Sketch of a load module . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 846
597. A load module after loading . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 847
598. Sketch of program object structure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 849
599. Sample program assembled with the GOFF option . . . . . . . . . . . . . . . . . . . . 849
600. ESD from program assembled with the GOFF option . . . . . . . . . . . . . . . . . . 850
601. Assigning AMODE to an entry symbol . . . . . . . . . . . . . . . . . . . . . . . . . . . 851
602. ESD showing AMODE assigned to entry and external symbols . . . . . . . . . . . . . 851
603. Sample program defining two Sections and three Classes . . . . . . . . . . . . . . . . . 851
604. Assignment of instructions and data into elements . . . . . . . . . . . . . . . . . . . . 851
605. Assembly listing for sample program . . . . . . . . . . . . . . . . . . . . . . . . . . . . 852
606. External symbol dictionary for sample program . . . . . . . . . . . . . . . . . . . . . . 852
607. Example of declaring parts in a GOFF Class . . . . . . . . . . . . . . . . . . . . . . . 853
608. ESD for parts in a GOFF Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 853
609. Sketch of virtual memory . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 856
610. Sample program defining two Sections and three Classes . . . . . . . . . . . . . . . . . 856
611. Sketch of classes in virtual memory . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 857
612. System z PSW showing addressing-mode bits . . . . . . . . . . . . . . . . . . . . . . . 858
613. Important addressing mode bits for BASSM . . . . . . . . . . . . . . . . . . . . . . . . 859
614. BASSM setting of first-operand register for 24-, 31-, and 64-bit addressing modes . . 859
615. Sketch of residence and addressing modes . . . . . . . . . . . . . . . . . . . . . . . . . 863
616. Example showing why LLGT/LLGTR are necessary . . . . . . . . . . . . . . . . . . . 864
617. Example showing why LLGTR is important . . . . . . . . . . . . . . . . . . . . . . . 865
618. Example of a dummy control section . . . . . . . . . . . . . . . . . . . . . . . . . . . . 873
619. Example using a dummy control section . . . . . . . . . . . . . . . . . . . . . . . . . . 873
620. USING Table with two entries, one for a dummy section . . . . . . . . . . . . . . . . 874
621. Object code from references to a dummy control section . . . . . . . . . . . . . . . . . 874
622. Example using a dummy control section . . . . . . . . . . . . . . . . . . . . . . . . . . 874
623. A poor method for describing two instances of a record . . . . . . . . . . . . . . . . . 875
624. A better record description with a DSECT . . . . . . . . . . . . . . . . . . . . . . . . . 876
625. Ordinary USING statement syntax . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 876
626. Copying a field from Old record to New . . . . . . . . . . . . . . . . . . . . . . . . . . 877
627. Incorrect addressing with ordinary USING . . . . . . . . . . . . . . . . . . . . . . . . . 878
628. Correct but awkward addressing with ordinary USING . . . . . . . . . . . . . . . . . 878
xxvi Assembler Language Programming for IBM System zβ’ Servers Version 2.00
629. Manual coding of base and displacement for a large DSECT . . . . . . . . . . . . . . 879
630. Labeled USING statement syntax . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 882
631. Qualified symbol syntax . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 882
632. Examples of qualifier definitions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 882
633. Copying a field with Labeled USINGs . . . . . . . . . . . . . . . . . . . . . . . . . . . 883
634. DROP statement for Labeled USING . . . . . . . . . . . . . . . . . . . . . . . . . . . 883
635. Concurrently active Ordinary and Labeled USINGs . . . . . . . . . . . . . . . . . . . 884
636. Dummy control section for record address . . . . . . . . . . . . . . . . . . . . . . . . . 885
637. Improved definition of a record description . . . . . . . . . . . . . . . . . . . . . . . . 885
638. Mapping a substructure with a second DSECT . . . . . . . . . . . . . . . . . . . . . . 886
639. Dependent USING statement syntax . . . . . . . . . . . . . . . . . . . . . . . . . . . . 886
640. Anchoring an internal DSECT with a Dependent USING . . . . . . . . . . . . . . . . 887
641. Outer DSECT with two nested DSECTs . . . . . . . . . . . . . . . . . . . . . . . . . . 887
642. Assembler listing of multiple Dependent USINGs and DSECTs . . . . . . . . . . . . 888
643. Three independent data structures with one base register . . . . . . . . . . . . . . . . . 888
644. Defining DSECTs for three independent data structures . . . . . . . . . . . . . . . . . 889
645. Defining a mapping of three independent but contiguous data structures . . . . . . . . 889
646. Example of a message-skeleton CSECT . . . . . . . . . . . . . . . . . . . . . . . . . . 889
647. Example of mapping a CSECT as though it is a DSECT . . . . . . . . . . . . . . . . 890
648. Labeled Dependent USING statement syntax . . . . . . . . . . . . . . . . . . . . . . . 891
649. Nesting two identical structures within a third . . . . . . . . . . . . . . . . . . . . . . . 891
650. Addressing two nested DSECTs with Labeled Dependent USINGs . . . . . . . . . . 893
651. Data in nested DSECTs addressed with Labeled Dependent USINGs . . . . . . . . . 893
652. Multiply-Nested Data Structures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 893
653. Doubly Nested DSECT definitions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 894
654. Addressing doubly nested DSECT definitions . . . . . . . . . . . . . . . . . . . . . . . 894
655. Using the Labeled Dependent USINGs to move data . . . . . . . . . . . . . . . . . . 895
656. Addressing two DCBs with ordinary USINGs . . . . . . . . . . . . . . . . . . . . . . . 896
657. Addressing instructions and DCBs with one register . . . . . . . . . . . . . . . . . . . 897
658. Define a personnel-file record . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 898
659. Employee-record Person DSECT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 898
660. Employee-record Date DSECT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 898
661. Employee-record Address DSECT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 899
662. Employee-record Phone DSECT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 899
663. DSECT nesting in an employee record . . . . . . . . . . . . . . . . . . . . . . . . . . . 900
664. Anchoring various DSECTs within Employee record . . . . . . . . . . . . . . . . . . . 901
665. Manipulating fields within an Employee record . . . . . . . . . . . . . . . . . . . . . . 901
666. Addressing DSECTs within Employee record with ordinary USINGs . . . . . . . . . 901
667. Comparing dates of birth in Employee record . . . . . . . . . . . . . . . . . . . . . . . 902
668. Comparing date fields in different parts of an Employee record . . . . . . . . . . . . . 902
669. Copying addresses with an Employee Record . . . . . . . . . . . . . . . . . . . . . . . 903
670. Example of a one-dimensional array of halfwords . . . . . . . . . . . . . . . . . . . . . 908
671. Sum of array elements with known subscript bounds . . . . . . . . . . . . . . . . . . . 908
672. Sum of array elements with unknown subscript bounds . . . . . . . . . . . . . . . . . 909
673. Typical arrangement of elements of a matrix . . . . . . . . . . . . . . . . . . . . . . . . 910
674. Storing an array in column order . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 910
675. Storing an array in row order . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 910
676. Retrieving a specified element of an array . . . . . . . . . . . . . . . . . . . . . . . . . 911
677. Retrieving a specified element of an array efficiently . . . . . . . . . . . . . . . . . . . 912
678. Searching for a matching table entry . . . . . . . . . . . . . . . . . . . . . . . . . . . . 914
679. Searching for a table entry mapped by a DSECT . . . . . . . . . . . . . . . . . . . . . 915
680. USING Table with two entries, one for a DSECT . . . . . . . . . . . . . . . . . . . . 915
681. Creating a table of addresses . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 917
682. Creating a better table of addresses . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 917
683. Creating a table of addresses at assembly time . . . . . . . . . . . . . . . . . . . . . . . 918
684. Example of a binary search . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 921
685. A stack growing toward higher addresses . . . . . . . . . . . . . . . . . . . . . . . . . . 924
686. A stack implemented as an array . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 924
687. Pushing a data item onto a stack . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 924
688. Adding top two elements of a stack . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 925
689. A stack growing toward lower addresses . . . . . . . . . . . . . . . . . . . . . . . . . . 925
690. Add top two elements of a stack . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 925
Figures xxvii
691. Sketch of a linked list . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 927
692. Inserting an element into a linked list . . . . . . . . . . . . . . . . . . . . . . . . . . . . 928
693. Example of inserting an element into a linked list . . . . . . . . . . . . . . . . . . . . . 928
694. DSECT describing a list element . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 928
695. Mapping multiple list elements with Labeled USINGs . . . . . . . . . . . . . . . . . . 928
696. Deleting an element from a linked list . . . . . . . . . . . . . . . . . . . . . . . . . . . . 929
697. Example of deleting an element from a linked list . . . . . . . . . . . . . . . . . . . . . 929
698. Example of deleting an element from a linked list . . . . . . . . . . . . . . . . . . . . . 929
699. Defining a free storage list as an array . . . . . . . . . . . . . . . . . . . . . . . . . . . . 930
700. Initializing a free storage list as an array . . . . . . . . . . . . . . . . . . . . . . . . . . 930
701. Example of a list anchor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 930
702. DSECT mapping a list anchor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 930
703. Defining an anchor for a working list . . . . . . . . . . . . . . . . . . . . . . . . . . . . 931
704. Moving a list element from the FSL to the working list . . . . . . . . . . . . . . . . . 931
705. A two-dimensional array to implement a linked list . . . . . . . . . . . . . . . . . . . . 932
706. Initializing a two-dimensional array implementing a linked list . . . . . . . . . . . . . 932
707. Structure of a queue element . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 934
708. A queue with several elements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 934
709. DSECT structure of a typical queue element . . . . . . . . . . . . . . . . . . . . . . . . 934
710. An element to be inserted into a queue . . . . . . . . . . . . . . . . . . . . . . . . . . . 935
711. A queue after insertion of a new element . . . . . . . . . . . . . . . . . . . . . . . . . . 935
712. Instructions to insert a new queue element . . . . . . . . . . . . . . . . . . . . . . . . . 935
713. Insert a new list element with ordinary USINGs . . . . . . . . . . . . . . . . . . . . . 936
714. Ordinary-USING Code to Insert a New List Element . . . . . . . . . . . . . . . . . . 936
715. Labeled USING example: inserting a new queue element . . . . . . . . . . . . . . . . 936
716. Node of a binary tree . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 937
717. DSECT structure of a typical tree element . . . . . . . . . . . . . . . . . . . . . . . . . 937
718. Three nodes of a binary tree . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 938
719. A growing binary tree with seven nodes . . . . . . . . . . . . . . . . . . . . . . . . . . 938
720. Entering a new node in a binary tree . . . . . . . . . . . . . . . . . . . . . . . . . . . . 939
721. Retrieving data from a binary tree . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 940
722. Example of a binary tree of 7 elements . . . . . . . . . . . . . . . . . . . . . . . . . . . 940
723. Example of searching a hash table . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 942
724. Example of searching a hash table . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 943
725. Sample macro invocation, Standard form . . . . . . . . . . . . . . . . . . . . . . . . . . 951
726. Generated statements from an OPEN macro . . . . . . . . . . . . . . . . . . . . . . . . 952
727. Sample macro invocation using List form . . . . . . . . . . . . . . . . . . . . . . . . . 952
728. Generated statements from a List form OPEN macro . . . . . . . . . . . . . . . . . . 953
729. Sample macro invocation using Execute form . . . . . . . . . . . . . . . . . . . . . . . 953
730. Generated statements from an Execute form OPEN macro . . . . . . . . . . . . . . . 953
731. Sample macro invocation using empty List form . . . . . . . . . . . . . . . . . . . . . 953
732. Generated instructions from empty List form . . . . . . . . . . . . . . . . . . . . . . . 953
733. Sample macro invocation using Execute form . . . . . . . . . . . . . . . . . . . . . . . 953
734. Generated statements from an Execute form OPEN macro . . . . . . . . . . . . . . . 953
735. Another macro invocation using Execute form and same List form . . . . . . . . . . . 954
736. An R-Type macro invocation generating an argument in a register . . . . . . . . . . . 954
737. Generated statements from R-Type macro . . . . . . . . . . . . . . . . . . . . . . . . . 954
738. A macro invocation with arguments in registers . . . . . . . . . . . . . . . . . . . . . . 954
739. Generated statements from a Standard-form macro with arguments in registers . . . . 954
740. A Standard macro invocation specifying MODE=31 . . . . . . . . . . . . . . . . . . . 955
741. Generated statements from a Standard-for macro with MODE=31 . . . . . . . . . . 955
742. Example of a mixed-case positional macro argument . . . . . . . . . . . . . . . . . . . 955
743. Example of mixed-case keyword macro arguments . . . . . . . . . . . . . . . . . . . . 955
744. Example of mixed-case keyword macro arguments . . . . . . . . . . . . . . . . . . . . 955
745. Sample ABEND macro . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 956
746. Generated statements from an ABEND macro . . . . . . . . . . . . . . . . . . . . . . 957
747. Sample R=type GETMAIN request . . . . . . . . . . . . . . . . . . . . . . . . . . . . 958
748. Expansion of a sample R-type GETMAIN request . . . . . . . . . . . . . . . . . . . . 959
749. Expansion of a sample VRU-type GETMAIN request . . . . . . . . . . . . . . . . . . 959
750. Example of an R-type FREEMAIN macro . . . . . . . . . . . . . . . . . . . . . . . . 960
751. Sample STORAGE OBTAIN request . . . . . . . . . . . . . . . . . . . . . . . . . . . 960
752. Example of a STORAGE OBTAIN macro expansion . . . . . . . . . . . . . . . . . . 961
xxviii Assembler Language Programming for IBM System zβ’ Servers Version 2.00
753. Sample STORAGE RELEASE request . . . . . . . . . . . . . . . . . . . . . . . . . . 961
754. Example of a STORAGE RELEASE macro expansion . . . . . . . . . . . . . . . . . 961
755. A Data Set with records you want to read . . . . . . . . . . . . . . . . . . . . . . . . . 962
756. You submitted a job with a program to read the records . . . . . . . . . . . . . . . . . 963
757. Your program, loaded into memory before execution . . . . . . . . . . . . . . . . . . . 963
758. Your program after executing the OPEN macro . . . . . . . . . . . . . . . . . . . . . . 964
759. Your program after executing the GET macro . . . . . . . . . . . . . . . . . . . . . . . 965
760. Your program after executing the CLOSE macro . . . . . . . . . . . . . . . . . . . . . 965
761. Example of typical DCB parameters . . . . . . . . . . . . . . . . . . . . . . . . . . . . 968
762. Unblocked and blocked F-type record and block formats . . . . . . . . . . . . . . . . 968
763. Unblocked and blocked V-type record and block formats . . . . . . . . . . . . . . . . 969
764. U-type block formats . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 969
765. Completion of a DCB during OPEN processing . . . . . . . . . . . . . . . . . . . . . 969
766. DCBD operands . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 970
767. DCBD operands . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 970
768. Using IHADCB to map two different DCBs simultaneously . . . . . . . . . . . . . . 970
769. A complete sample program . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 972
770. Instruction cycle with interruptions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 973
771. Establishing a program interruption exit . . . . . . . . . . . . . . . . . . . . . . . . . . 973
772. Expansion of an ESPIE macro establishing a program interruption exit . . . . . . . . 974
773. Terminating a program interruption exit . . . . . . . . . . . . . . . . . . . . . . . . . . 974
774. Expansion of an ESPIE macro terminating a program interruption exit . . . . . . . . 974
775. ESA/390-mode old PSW in EPIE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 975
776. Sketch of interruption handling control flow . . . . . . . . . . . . . . . . . . . . . . . . 977
777. A simple ESTAE macro. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 979
778. Skeleton form of a reenterable program . . . . . . . . . . . . . . . . . . . . . . . . . . . 985
779. I/O macros in a reenterable program . . . . . . . . . . . . . . . . . . . . . . . . . . . . 986
780. Assembly listing for a simple reenterable program . . . . . . . . . . . . . . . . . . . . . 986
781. Example of a reenterable, recursive routine . . . . . . . . . . . . . . . . . . . . . . . . . 990
782. Assembly listing of the reenterable recursive routine . . . . . . . . . . . . . . . . . . . 991
Tables
1. Binary, decimal, and hexadecimal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
2. Multiples of powers of sixteen (part 1 of 2) . . . . . . . . . . . . . . . . . . . . . . . . . 20
3. Multiples of powers of sixteen (part 2 of 2) . . . . . . . . . . . . . . . . . . . . . . . . . 21
4. Examples of two's complement representation . . . . . . . . . . . . . . . . . . . . . . . . 29
5. Examples of sign extension . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
6. RR-type instruction format . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
7. RX-type and RS-type instruction format . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
8. SI-type instruction format . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
9. SS-type instruction format . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
10. Instruction Length Code and instruction types . . . . . . . . . . . . . . . . . . . . . . . . 54
11. General instruction classifications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
12. Punched-card image of a RETURN statement . . . . . . . . . . . . . . . . . . . . . . . 78
13. Assembler Language EBCDIC character representation . . . . . . . . . . . . . . . . . . 87
14. Differences between Assembler Language and high-level language symbols . . . . . . . 94
15. Expressions with absolute and relocatable terms . . . . . . . . . . . . . . . . . . . . . . . 99
16. Typical RR-type instructions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106
17. RR-type instruction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107
18. Typical RX-type instructions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108
19. RX-type instruction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108
20. Operands of RX-type instructions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109
21. Typical RS- and SI-type instructions . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111
22. Typical RS-type instruction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111
23. Operands of RS-type instructions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112
24. Typical SI-type instruction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112
25. Operands of SI-type instructions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112
Figures xxix
26. Typical SS-type instructions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113
27. Typical type SS-1 instruction with one length field . . . . . . . . . . . . . . . . . . . . 113
28. Operands of type SS-1 single-length instructions . . . . . . . . . . . . . . . . . . . . . . 113
29. Typical type SS-2 instruction with two length fields . . . . . . . . . . . . . . . . . . . . 114
30. Operands of type SS-2 two-length instructions . . . . . . . . . . . . . . . . . . . . . . . 114
31. Examples of truncated and padded constants . . . . . . . . . . . . . . . . . . . . . . . . 152
32. Truncation/padding rules for some DC operands . . . . . . . . . . . . . . . . . . . . . 153
33. Truncation and padding rules for some DC operands with extended types . . . . . . . 158
34. Load/Store instructions for 32-bit general registers . . . . . . . . . . . . . . . . . . . . 179
35. Format of an RX-type instruction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 179
36. Multiple load/store instructions for 32-bit general registers . . . . . . . . . . . . . . . . 180
37. RS-type instruction format . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 180
38. Halfword load/store instructions for 32-bit general registers . . . . . . . . . . . . . . . 182
39. Character insert/store instructions for 32-bit general registers . . . . . . . . . . . . . . 184
40. Insert/Store characters under mask instructions for 32-bit general registers . . . . . . . 185
41. RS-type instruction format for ICM and STCM . . . . . . . . . . . . . . . . . . . . . 186
42. CC settings after ICM instruction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 187
43. Register/register instructions for 32-bit general registers . . . . . . . . . . . . . . . . . . 187
44. Action of five RR-type general register instructions . . . . . . . . . . . . . . . . . . . . 188
45. Condition Code settings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 188
46. Register/storage instructions for 64-bit general registers . . . . . . . . . . . . . . . . . . 189
47. RXY-type instruction format . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 190
48. RSY-type instruction format. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 190
49. RRE-type instruction format . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 192
50. Register/register instructions for 64-bit general registers . . . . . . . . . . . . . . . . . . 192
51. Action of five RR-type 64-bit general register instructions . . . . . . . . . . . . . . . . 192
52. Load and Test instructions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 194
53. Register/register instructions for 64-bit general registers . . . . . . . . . . . . . . . . . . 194
54. Action of 32-bit-to-64-bit general register instructions . . . . . . . . . . . . . . . . . . 194
55. Other general register load instructions . . . . . . . . . . . . . . . . . . . . . . . . . . . 196
56. Summary of instructions discussed in this section . . . . . . . . . . . . . . . . . . . . . 200
57. BCR instruction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 205
58. BC instruction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 205
59. Mask bits and corresponding CC values . . . . . . . . . . . . . . . . . . . . . . . . . . 205
60. CNOP operands . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 208
61. Extended branch mnemonics and their branch mask values . . . . . . . . . . . . . . . 210
62. Frequently used add and subtract instructions . . . . . . . . . . . . . . . . . . . . . . . 216
63. CC settings for arithmetic add and subtract instructions . . . . . . . . . . . . . . . . . 217
64. Arithmetic compare instructions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 222
65. CC settings after arithmetic comparisons . . . . . . . . . . . . . . . . . . . . . . . . . . 222
66. Logical arithmetic instructions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 224
67. CC settings for logical add and subtract instructions . . . . . . . . . . . . . . . . . . . 224
68. CC indications for logical addition and subtraction . . . . . . . . . . . . . . . . . . . . 225
69. CC settings after logical addition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 228
70. CC settings after logical subtraction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 228
71. Logical arithmetic instructions with carry/borrow . . . . . . . . . . . . . . . . . . . . . 228
72. Instructions for mixed-length operands . . . . . . . . . . . . . . . . . . . . . . . . . . . 230
73. Arithmetic compare instructions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 232
74. CC settings after logical comparisons . . . . . . . . . . . . . . . . . . . . . . . . . . . . 232
75. IPM and SPM instructions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 234
76. Program Mask bits . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 235
77. Summary of instructions discussed in this section . . . . . . . . . . . . . . . . . . . . . 236
78. General register shift instructions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 242
79. RS-type shift instruction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 243
80. RSY-type instruction format . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 243
81. CC settings for arithmetic shift instructions . . . . . . . . . . . . . . . . . . . . . . . . 252
82. Summary of shift instructions discussed in this section . . . . . . . . . . . . . . . . . . 260
83. Binary integer multiply instructions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 264
84. Double-length arithmetic multiply instructions . . . . . . . . . . . . . . . . . . . . . . 265
85. Single-length arithmetic multiply instructions . . . . . . . . . . . . . . . . . . . . . . . 268
86. Logical multiply instructions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 270
87. Binary divide instructions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 274
xxx Assembler Language Programming for IBM System zβ’ Servers Version 2.00
88. Arithmetic divide instructions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 275
89. Binary divide instructions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 279
90. Summary of multiply instructions discussed in this section . . . . . . . . . . . . . . . . 283
91. Summary of divide instructions discussed in this section . . . . . . . . . . . . . . . . . 283
92. Logical operations involving general registers . . . . . . . . . . . . . . . . . . . . . . . 288
93. CC settings by logical instructions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 289
94. Summary of the logical operations AND, OR, XOR . . . . . . . . . . . . . . . . . . . 297
95. Logical-operation instructions discussed in this section . . . . . . . . . . . . . . . . . . 297
96. Format of RXY- and RSY-type instructions . . . . . . . . . . . . . . . . . . . . . . . . 302
97. Format of R-I instructions with 16-bit immediate operands . . . . . . . . . . . . . . . 305
98. Format of R-I instructions with 32-bit immediate operands . . . . . . . . . . . . . . . 305
99. PSW addressing-mode bits . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 309
100. Load Address instructions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 309
101. Load Address instructions described in this section . . . . . . . . . . . . . . . . . . . . 314
102. RI-type instruction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 317
103. RIL-type instruction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 317
104. Insert-Immediate instructions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 318
105. Load and insert instructions with immediate operands . . . . . . . . . . . . . . . . . . 319
106. Arithmetic-immediate add and subtract instructions . . . . . . . . . . . . . . . . . . . . 321
107. Arithmetic-immediate compare instructions . . . . . . . . . . . . . . . . . . . . . . . . 322
108. Arithmetic-immediate multiply instructions . . . . . . . . . . . . . . . . . . . . . . . . 322
109. AND-immediate instructions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 323
110. OR-immediate instructions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 324
111. XOR-immediate instructions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 324
112. Load and insert instructions with immediate operands . . . . . . . . . . . . . . . . . . 326
113. Arithmetic instructions with immediate operands . . . . . . . . . . . . . . . . . . . . . 326
114. Logical instructions with immediate operands . . . . . . . . . . . . . . . . . . . . . . . 326
115. Format of the BRC instruction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 329
116. Format of the BRCL instruction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 329
117. Extended branch relative on condition mnemonics and their branch mask values . . . 330
118. Branch on count instructions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 334
119. Extended mnemonics for branch relative on count instructions . . . . . . . . . . . . . 334
120. Branch on index instructions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 341
121. RS-type BXH and BXLE instructions . . . . . . . . . . . . . . . . . . . . . . . . . . . 341
122. RSY-type BXHG and BXLEG instructions . . . . . . . . . . . . . . . . . . . . . . . . 341
123. RSI-type BRXH and BRXLE instructions . . . . . . . . . . . . . . . . . . . . . . . . . 341
124. RIE-type BRXHG and BRXLG instructions . . . . . . . . . . . . . . . . . . . . . . . 341
125. Extended mnemonics for branch relative on index instructions . . . . . . . . . . . . . 343
126. Branch relative on condition instructions . . . . . . . . . . . . . . . . . . . . . . . . . . 349
127. Branch instructions for loop control . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 349
128. SI-type instruction format . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 352
129. SIY-type instruction format . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 352
130. SI-type instruction actions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 353
131. Move Immediate instructions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 353
132. Logical Storage-Immediate instructions . . . . . . . . . . . . . . . . . . . . . . . . . . . 353
133. CC settings by SI-type logical instructions . . . . . . . . . . . . . . . . . . . . . . . . . 354
134. Compare Immediate instructions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 354
135. CC settings after CLI instruction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 355
136. Storage-Immediate instructions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 356
137. CC settings after TM instruction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 356
138. Storage-Immediate instructions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 363
139. Basic character-handling instructions . . . . . . . . . . . . . . . . . . . . . . . . . . . . 365
140. Format of single-length SS-type instructions . . . . . . . . . . . . . . . . . . . . . . . . 365
141. Instruction types and operand formats . . . . . . . . . . . . . . . . . . . . . . . . . . . 367
142. SS-type instructions with explicit length . . . . . . . . . . . . . . . . . . . . . . . . . . 367
143. SS-type instructions with implied length . . . . . . . . . . . . . . . . . . . . . . . . . . 368
144. Determining the Length Specification Byte . . . . . . . . . . . . . . . . . . . . . . . . . 370
145. MVCOS instruction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 374
146. SSF instruction format used for the MVCOS instruction . . . . . . . . . . . . . . . . . 374
147. Condition Code settings for TRT and TRTR instructions . . . . . . . . . . . . . . . . 384
148. Execute instructions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 389
149. Modifiable portions of typical EX target instructions . . . . . . . . . . . . . . . . . . . 394
Tables xxxi
150. Operands of single-length SS-type instructions . . . . . . . . . . . . . . . . . . . . . . . 396
151. Basic instructions for data in storage . . . . . . . . . . . . . . . . . . . . . . . . . . . . 397
152. Basic character-handling instructions using padding characters . . . . . . . . . . . . . . 404
153. CC settings after MVCL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 405
154. CC settings after CLCL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 407
155. Format of MVCLE and CLCLE instructions . . . . . . . . . . . . . . . . . . . . . . . 410
156. CC settings after MVCLE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 412
157. CC settings after CLCLE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 414
158. Character-handling instructions for terminated strings . . . . . . . . . . . . . . . . . . 415
159. Format of RRE-type instructions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 415
160. CC settings for SRST instruction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 416
161. CC settings for MVST instruction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 417
162. CC settings for CLST instruction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 419
163. CC settings for TRE instruction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 421
164. Compare Until Substring Equal instruction . . . . . . . . . . . . . . . . . . . . . . . . 423
165. Condition Code settings by CUSE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 424
166. Results of examples using the CUSE instruction . . . . . . . . . . . . . . . . . . . . . 424
167. Extended instructions for character data . . . . . . . . . . . . . . . . . . . . . . . . . . 425
168. Punched paper tape encodings with values 00-0F . . . . . . . . . . . . . . . . . . . . . 429
169. Punched paper tape encodings with values 10-1F . . . . . . . . . . . . . . . . . . . . . 429
170. Old six-bit BCD character representation . . . . . . . . . . . . . . . . . . . . . . . . . . 430
171. Sample EBCDIC characters with varying code points among code pages . . . . . . . 431
172. 7-bit ASCII character representation . . . . . . . . . . . . . . . . . . . . . . . . . . . . 433
173. Japanese DBCS assignments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 435
174. DBCS encoding . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 435
175. Sample Unicode assignments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 439
176. Unicode string instructions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 441
177. CC settings for SRSTU instruction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 441
178. CC settings after MVCLU . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 442
179. CC settings after CLCLU . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 443
180. RRE-type instruction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 443
181. RRF-format instruction with an optional operand . . . . . . . . . . . . . . . . . . . . 444
182. Unicode translate instructions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 444
183. Arguments and translate tables for TRxx instructions . . . . . . . . . . . . . . . . . . . 445
184. Registers used by TRxx instructions . . . . . . . . . . . . . . . . . . . . . . . . . . . . 445
185. Condition Code settings for TRxx instructions . . . . . . . . . . . . . . . . . . . . . . 445
186. Unicode format conversion instructions . . . . . . . . . . . . . . . . . . . . . . . . . . . 448
187. CC settings after Unicode format conversion instructions . . . . . . . . . . . . . . . . 448
188. Translate and Test Extended instructions . . . . . . . . . . . . . . . . . . . . . . . . . . 450
189. Function-code table sizes for TRTE, TRTRE . . . . . . . . . . . . . . . . . . . . . . . 450
190. Condition code settings for TRTE, TRTRE . . . . . . . . . . . . . . . . . . . . . . . . 451
191. Byte-reversing load and store instructions . . . . . . . . . . . . . . . . . . . . . . . . . 453
192. Extended instructions for Unicode data . . . . . . . . . . . . . . . . . . . . . . . . . . . 456
193. Unicode-based translate instructions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 456
194. Unicode format conversion instructions . . . . . . . . . . . . . . . . . . . . . . . . . . . 456
195. Summary of byte-reversing instructions . . . . . . . . . . . . . . . . . . . . . . . . . . . 456
196. Basic packed and zoned decimal instructions . . . . . . . . . . . . . . . . . . . . . . . . 460
197. Examples of zoned decimal data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 462
198. Punched-card image of two numbers, + 12345 and β 67890 . . . . . . . . . . . . . . . 463
199. Examples of packed decimal data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 466
200. Format of two-length SS-type instructions . . . . . . . . . . . . . . . . . . . . . . . . . 469
201. Operands of two-length SS-type instructions . . . . . . . . . . . . . . . . . . . . . . . . 470
202. Format of PKA and PKU instructions . . . . . . . . . . . . . . . . . . . . . . . . . . . 478
203. Format of UNPKA and UNPKU instructions . . . . . . . . . . . . . . . . . . . . . . 479
204. CC settings after UNPKA, UNPKU instructions . . . . . . . . . . . . . . . . . . . . . 480
205. Instructions for moving numeric and zone digits . . . . . . . . . . . . . . . . . . . . . . 483
206. Instructions for packing and unpacking data . . . . . . . . . . . . . . . . . . . . . . . . 483
207. CC settings for decimal addition and subtraction . . . . . . . . . . . . . . . . . . . . . 486
208. CC setting after decimal comparison . . . . . . . . . . . . . . . . . . . . . . . . . . . . 488
209. Packed decimal arithmetic instructions . . . . . . . . . . . . . . . . . . . . . . . . . . . 497
210. Operand formats for TP instruction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 498
211. Format of the TP instruction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 498
xxxii Assembler Language Programming for IBM System zβ’ Servers Version 2.00
212. CC settings for the TP instruction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 498
213. CC settings by the ZAP, AP, and SP instructions . . . . . . . . . . . . . . . . . . . . . 499
214. CC setting by the CP instruction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 504
215. Format of the SRP instruction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 511
216. Summary of decimal instruction behavior . . . . . . . . . . . . . . . . . . . . . . . . . 530
217. Instructions used for converting and formatting packed decimal . . . . . . . . . . . . . 532
218. Format of the ED and EDMK instructions . . . . . . . . . . . . . . . . . . . . . . . . 536
219. CC settings after ED, EDMK . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 544
220. ED and EDMK treatment of pattern characters . . . . . . . . . . . . . . . . . . . . . . 547
221. Basic floating-point instructions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 568
222. Instructions copying data between FPRs . . . . . . . . . . . . . . . . . . . . . . . . . . 568
223. Floating-point Load Zero instructions . . . . . . . . . . . . . . . . . . . . . . . . . . . 569
224. Instructions moving data between FPRs and GPRs . . . . . . . . . . . . . . . . . . . 570
225. Copy Sign instruction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 570
226. Basic Load/Store instructions for floating-point operands . . . . . . . . . . . . . . . . 571
227. Instructions moving operands between GPRs and FPRs . . . . . . . . . . . . . . . . . 571
228. Hexadecimal floating-point data representations . . . . . . . . . . . . . . . . . . . . . . 587
229. Unnormalized and normalized short hexadecimal floating-point numbers . . . . . . . 588
230. Short hexadecimal floating-point numbers . . . . . . . . . . . . . . . . . . . . . . . . . 588
231. Long hexadecimal floating-point numbers . . . . . . . . . . . . . . . . . . . . . . . . . 589
232. Extended hexadecimal floating-point numbers . . . . . . . . . . . . . . . . . . . . . . . 589
233. Assembled hexadecimal floating-point constants . . . . . . . . . . . . . . . . . . . . . . 591
234. Hex floating-point constants with decimal exponents . . . . . . . . . . . . . . . . . . . 591
235. Length-modified hexadecimal floating-point constants . . . . . . . . . . . . . . . . . . 592
236. Hexadecimal floating-point constants with modifiers . . . . . . . . . . . . . . . . . . . 594
237. Hexadecimal floating-point rounding modes with subtype H . . . . . . . . . . . . . . 595
238. Symbolic hexadecimal floating-point constants . . . . . . . . . . . . . . . . . . . . . . 596
239. βDifficultβ hexadecimal floating-point conversion values . . . . . . . . . . . . . . . . . 596
240. Data-moving hexadecimal floating-point instructions . . . . . . . . . . . . . . . . . . . 597
241. Hexadecimal floating-point Multiply instructions . . . . . . . . . . . . . . . . . . . . . 599
242. Summary of hexadecimal floating-point multiplication results . . . . . . . . . . . . . . 601
243. Hexadecimal floating-point Divide instructions . . . . . . . . . . . . . . . . . . . . . . 603
244. Hexadecimal floating-point Halve instructions . . . . . . . . . . . . . . . . . . . . . . . 604
245. Hexadecimal floating-point Add/Subtract instructions . . . . . . . . . . . . . . . . . . 606
246. Hexadecimal floating-point Compare instructions . . . . . . . . . . . . . . . . . . . . . 615
247. CC settings for hexadecimal floating-point comparison . . . . . . . . . . . . . . . . . . 616
248. Hexadecimal floating-point Round instructions . . . . . . . . . . . . . . . . . . . . . . 616
249. Hexadecimal floating-point Load Lengthened instructions . . . . . . . . . . . . . . . . 619
250. Hexadecimal floating-point FPR/GPR conversion instructions . . . . . . . . . . . . . 620
251. Format of HFP to fixed binary instructions . . . . . . . . . . . . . . . . . . . . . . . . 621
252. Rounding modifiers for HFP-to-binary conversion . . . . . . . . . . . . . . . . . . . . 621
253. CC settings for HFP-to-binary conversion . . . . . . . . . . . . . . . . . . . . . . . . . 622
254. Instructions moving/converting binary and hexadecimal floating-point operands . . . 622
255. Hexadecimal floating-point instructions generating floating-point integers . . . . . . . 625
256. Hexadecimal floating-point Square Root instructions . . . . . . . . . . . . . . . . . . . 627
257. Hexadecimal floating-point Multiply and add/subtract instructions . . . . . . . . . . . 627
258. Format of RRF-type HFP multiply and add/subtract instructions . . . . . . . . . . . 628
259. Format of RXF-type multiply and add/subtract instructions . . . . . . . . . . . . . . 628
260. Hexadecimal floating-point Move/Test instructions . . . . . . . . . . . . . . . . . . . . 631
261. Hexadecimal floating-point Multiply instructions . . . . . . . . . . . . . . . . . . . . . 631
262. Hexadecimal floating-point Divide instructions . . . . . . . . . . . . . . . . . . . . . . 631
263. Hexadecimal floating-point Add, Subtract, and Compare instructions . . . . . . . . . 631
264. Hexadecimal floating-point Round instructions . . . . . . . . . . . . . . . . . . . . . . 632
265. Hexadecimal floating-point Lengthening instructions . . . . . . . . . . . . . . . . . . . 632
266. Convert hexadecimal floating-point to binary instructions . . . . . . . . . . . . . . . . 632
267. Convert binary to hexadecimal floating-point instructions . . . . . . . . . . . . . . . . 632
268. Form hexadecimal floating-point integer instructions . . . . . . . . . . . . . . . . . . . 632
269. Hexadecimal floating-point Square Root instructions . . . . . . . . . . . . . . . . . . . 632
270. Hexadecimal floating-point Multiply-Add/Subtract instructions . . . . . . . . . . . . . 633
271. Binary floating-point data representations . . . . . . . . . . . . . . . . . . . . . . . . . 638
272. Examples of short-precision binary floating-point normal values . . . . . . . . . . . . 640
273. Examples of short-precision binary floating-point denormalized values . . . . . . . . . 640
Tables xxxiii
274. Examples of short-precision binary floating-point special values . . . . . . . . . . . . . 641
275. Nominal-value operands for binary floating-point special values . . . . . . . . . . . . 644
276. Assembled binary floating-point special-value constants . . . . . . . . . . . . . . . . . 644
277. Minimum bit lengths for binary floating-point constants . . . . . . . . . . . . . . . . . 645
278. Binary floating-point DXC values . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 650
279. Binary floating-point FPC register control instructions . . . . . . . . . . . . . . . . . . 651
280. Invalid operation binary floating-point exception . . . . . . . . . . . . . . . . . . . . . 652
281. Divide by zero binary floating-point exception . . . . . . . . . . . . . . . . . . . . . . . 652
282. Exponent overflow binary floating-point exception . . . . . . . . . . . . . . . . . . . . 652
283. Exponent underflow binary floating-point exception . . . . . . . . . . . . . . . . . . . 652
284. Inexact result binary floating-point exception . . . . . . . . . . . . . . . . . . . . . . . 652
285. BFP overflow/underflow scale factors . . . . . . . . . . . . . . . . . . . . . . . . . . . . 653
286. Binary floating-point Test Data Class instructions . . . . . . . . . . . . . . . . . . . . . 654
287. Test Data Class second-operand bits . . . . . . . . . . . . . . . . . . . . . . . . . . . . 654
288. Test Data Class second-operand test-bit/tested-value correspondence . . . . . . . . . . 654
289. Binary floating-point RR-type data movement instructions . . . . . . . . . . . . . . . 655
290. CC settings for BFP data movement instructions . . . . . . . . . . . . . . . . . . . . . 656
291. Binary floating-point Multiply instructions . . . . . . . . . . . . . . . . . . . . . . . . . 657
292. Binary floating-point Divide instructions . . . . . . . . . . . . . . . . . . . . . . . . . . 659
293. Binary floating-point Add and Subtract instructions . . . . . . . . . . . . . . . . . . . 661
294. CC settings after BFP add/subtract instructions . . . . . . . . . . . . . . . . . . . . . . 661
295. Binary floating-point Compare instructions . . . . . . . . . . . . . . . . . . . . . . . . 662
296. CC settings for BFP comparisons . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 662
297. Binary floating-point Compare and Signal instructions . . . . . . . . . . . . . . . . . . 663
298. Binary floating-point Round instructions . . . . . . . . . . . . . . . . . . . . . . . . . . 664
299. Binary floating-point Lengthening instructions . . . . . . . . . . . . . . . . . . . . . . . 665
300. Binary integer to binary floating-point conversion instructions . . . . . . . . . . . . . 666
301. Binary floating-point to integer conversion instructions . . . . . . . . . . . . . . . . . . 666
302. Format of BFP Convert To Fixed instructions . . . . . . . . . . . . . . . . . . . . . . 666
303. Rounding modifier for BFP convert to fixed instructions . . . . . . . . . . . . . . . . 667
304. CC settings after convert to binary instructions . . . . . . . . . . . . . . . . . . . . . . 667
305. Load floating-point integer instructions . . . . . . . . . . . . . . . . . . . . . . . . . . . 668
306. Rounding mode modifiers for BFP load integer instructions . . . . . . . . . . . . . . . 669
307. Binary floating-point Divide to Integer instructions . . . . . . . . . . . . . . . . . . . . 669
308. Format of BFP Divide to Integer instructions . . . . . . . . . . . . . . . . . . . . . . . 669
309. CC settings after divide to integer instructions . . . . . . . . . . . . . . . . . . . . . . . 670
310. Binary floating-point Square Root instructions . . . . . . . . . . . . . . . . . . . . . . 671
311. Binary floating-point Multiply and Add/Subtract instructions . . . . . . . . . . . . . . 672
312. Summary of binary floating-point instructions with uniform operand lengths . . . . . 673
313. Binary floating-point Multiply instructions . . . . . . . . . . . . . . . . . . . . . . . . . 674
314. Binary floating-point Round instructions . . . . . . . . . . . . . . . . . . . . . . . . . . 674
315. Binary floating-point Lengthening instructions . . . . . . . . . . . . . . . . . . . . . . . 674
316. Convert binary floating-point to binary integer instructions . . . . . . . . . . . . . . . 675
317. Convert binary integer to binary floating-point instructions . . . . . . . . . . . . . . . 675
318. Summary of binary floating-point operations and exceptions . . . . . . . . . . . . . . 675
319. Decimal floating-point data representations . . . . . . . . . . . . . . . . . . . . . . . . 684
320. Declet encoding for BCD digits . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 685
321. Converting decimal floating-point declets to BCD digits . . . . . . . . . . . . . . . . . 686
322. First five bits of special-values Combination Field . . . . . . . . . . . . . . . . . . . . 687
323. First 5 bits of finite-value Combination Field . . . . . . . . . . . . . . . . . . . . . . . 688
324. Properties of decimal floating-point representations . . . . . . . . . . . . . . . . . . . . 689
325. Assembled decimal floating-point special-value constants . . . . . . . . . . . . . . . . 690
326. Examples of decimal floating-point short precision zeros . . . . . . . . . . . . . . . . . 691
327. Assembler rounding-mode suffixes for DFP constants . . . . . . . . . . . . . . . . . . 691
328. Decimal floating-point Test Data Class instructions . . . . . . . . . . . . . . . . . . . . 693
329. DFP Test Data Class second-operand bits . . . . . . . . . . . . . . . . . . . . . . . . . 694
330. Test Data Class test-bit vs. tested-class correspondence . . . . . . . . . . . . . . . . . . 694
331. Example of DFP rounding modes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 696
332. Preferred quanta for some decimal floating-point operations . . . . . . . . . . . . . . . 698
333. Decimal floating-point additional DXC value . . . . . . . . . . . . . . . . . . . . . . . 699
334. Decimal floating-point quantum exception . . . . . . . . . . . . . . . . . . . . . . . . . 699
335. Decimal floating-point scale factors for exponent spills . . . . . . . . . . . . . . . . . . 699
xxxiv Assembler Language Programming for IBM System zβ’ Servers Version 2.00
336. Copy Sign instruction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 700
337. Instructions moving data between FPRs and GPRs . . . . . . . . . . . . . . . . . . . 700
338. Instructions copying data between FPRs . . . . . . . . . . . . . . . . . . . . . . . . . . 700
339. Decimal floating-point basic arithmetic instructions . . . . . . . . . . . . . . . . . . . . 701
340. Format of DFP arithmetic instructions . . . . . . . . . . . . . . . . . . . . . . . . . . . 701
341. Format of DFP arithmetic instructions with rounding mask . . . . . . . . . . . . . . . 701
342. Instruction-specific rounding mask values . . . . . . . . . . . . . . . . . . . . . . . . . 702
343. CC settings for Add/Subtract instructions . . . . . . . . . . . . . . . . . . . . . . . . . 704
344. CC settings for Compare instructions . . . . . . . . . . . . . . . . . . . . . . . . . . . . 705
345. Decimal floating-point Compare instructions . . . . . . . . . . . . . . . . . . . . . . . 705
346. Decimal floating-point Compare and Signal instructions . . . . . . . . . . . . . . . . . 705
347. Decimal floating-point Compare Biased Exponent instructions . . . . . . . . . . . . . 706
348. CC settings for Compare Biased Exponent instructions . . . . . . . . . . . . . . . . . 706
349. Decimal floating-point convert to/from fixed binary instructions . . . . . . . . . . . . 707
350. Format of Convert to Fixed Binary instructions . . . . . . . . . . . . . . . . . . . . . . 708
351. Format of Convert to Fixed Binary instructions . . . . . . . . . . . . . . . . . . . . . . 708
352. CC settings for Convert to Fixed instructions . . . . . . . . . . . . . . . . . . . . . . . 708
353. Decimal floating-point convert to/from signed packed decimal instructions . . . . . . 709
354. Format of Convert to Signed Packed instructions . . . . . . . . . . . . . . . . . . . . . 709
355. Decimal floating-point convert to/from unsigned packed decimal instructions . . . . . 711
356. Instructions converting between decimal floating-point and zoned decimal . . . . . . 712
357. Format of DFP/zoned decimal conversion instructions . . . . . . . . . . . . . . . . . . 712
358. Condition Code settings for Convert to Zoned . . . . . . . . . . . . . . . . . . . . . . 713
359. Decimal floating-point Load and Test instructions . . . . . . . . . . . . . . . . . . . . 715
360. CC setting after DFP Load and Test instructions . . . . . . . . . . . . . . . . . . . . . 715
361. Instructions copying/complementing data between FPRs . . . . . . . . . . . . . . . . 715
362. Decimal floating-point Load Floating-point Integer instructions . . . . . . . . . . . . 715
363. Format of Load FP Integer instructions . . . . . . . . . . . . . . . . . . . . . . . . . . 715
364. Decimal floating-point Load Lengthened instructions . . . . . . . . . . . . . . . . . . . 716
365. Load Lengthened special operand control mask . . . . . . . . . . . . . . . . . . . . . . 716
366. Decimal floating-point rounding/lengthening instructions . . . . . . . . . . . . . . . . 717
367. Decimal floating-point Set Rounding Mode instruction . . . . . . . . . . . . . . . . . 718
368. Decimal floating-point Insert/Extract Biased Exponent instructions . . . . . . . . . . 719
369. Extracted Biased Exponent for DFP special values . . . . . . . . . . . . . . . . . . . . 719
370. DFP Insert Biased Exponent results . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 720
371. Decimal floating-point Extract Significance instructions . . . . . . . . . . . . . . . . . 720
372. Decimal floating-point Shift Significand instructions . . . . . . . . . . . . . . . . . . . 721
373. Format of DFP shift instructions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 721
374. Decimal floating-point Quantize instructions . . . . . . . . . . . . . . . . . . . . . . . . 722
375. Format of decimal floating-point Quantize instructions . . . . . . . . . . . . . . . . . . 722
376. Decimal floating-point Reround instructions . . . . . . . . . . . . . . . . . . . . . . . . 724
377. Decimal floating-point Test Data Group instructions . . . . . . . . . . . . . . . . . . . 726
378. Test Data Group second-operand bits . . . . . . . . . . . . . . . . . . . . . . . . . . . 726
379. DFP Test Data Class and Test Data Group instructions . . . . . . . . . . . . . . . . . 732
380. DFP Arithmetic and related instructions . . . . . . . . . . . . . . . . . . . . . . . . . . 732
381. DFP length and type conversion instructions . . . . . . . . . . . . . . . . . . . . . . . 732
382. DFP rounding and lengthening instructions . . . . . . . . . . . . . . . . . . . . . . . . 732
383. DFP data-loading instructions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 733
384. Instructions copying between FPRs and GPRs . . . . . . . . . . . . . . . . . . . . . . 733
385. Instruction setting decimal rounding mode . . . . . . . . . . . . . . . . . . . . . . . . . 733
386. Non-canonical declets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 733
387. Summary of System z floating-point representations . . . . . . . . . . . . . . . . . . . 739
388. Adding 0.1 in hexadecimal, binary, and decimal floating-point . . . . . . . . . . . . . . 741
389. Exception behavior for hexadecimal floating-point . . . . . . . . . . . . . . . . . . . . 741
390. Exception behavior for binary and decimal floating-point . . . . . . . . . . . . . . . . 741
391. Length modifiers of floating-point constants . . . . . . . . . . . . . . . . . . . . . . . . 742
392. Assembler rounding-mode suffixes for floating-point constants . . . . . . . . . . . . . 742
393. Internal precision required for faithful In-Out conversion . . . . . . . . . . . . . . . . 744
394. Decimal precision required for faithful Out-In conversion . . . . . . . . . . . . . . . . 744
395. Perform Floating-Point Operation instruction . . . . . . . . . . . . . . . . . . . . . . . 745
396. Laws of real and realistic arithmetic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 746
397. Examples of hexadecimal floating-point pseudo-zeros . . . . . . . . . . . . . . . . . . . 748
Tables xxxv
398. Examples of other floating-point representations . . . . . . . . . . . . . . . . . . . . . 750
399. Equivalent decimal and floating-point precisions . . . . . . . . . . . . . . . . . . . . . 751
400. Branch and Save instructions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 758
401. Standard (Format-0) Save Area . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 770
402. Standard Format-4 save area . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 773
403. Standard Format-5 save area . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 775
404. AMODE values . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 827
405. R M O D E values . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 828
406. Default AMODE and RMODE values . . . . . . . . . . . . . . . . . . . . . . . . . . . 828
407. Valid combinations of AMODE and RMODE values . . . . . . . . . . . . . . . . . . 828
408. Differences in linking COMMONs and External dummy items . . . . . . . . . . . . . 841
409. ESD symbol search types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 841
410. Matching existing CESD SD symbol to incoming symbols . . . . . . . . . . . . . . . 843
411. Matching existing CESD LD symbol to incoming symbols . . . . . . . . . . . . . . . 843
412. Matching existing CESD CM symbol to incoming symbols . . . . . . . . . . . . . . . 843
413. Matching existing CESD ER symbol to incoming symbols . . . . . . . . . . . . . . . 844
414. Matching existing CESD ER symbol to incoming symbols . . . . . . . . . . . . . . . 844
415. Comparing load modules and program objects . . . . . . . . . . . . . . . . . . . . . . 855
416. Instructions to change addressing mode . . . . . . . . . . . . . . . . . . . . . . . . . . . 858
417. CC settings for TAM instruction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 858
418. PSW addressing-mode bits . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 858
419. BASSM actions summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 860
420. Operation of BSM instruction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 860
421. BSM actions summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 861
422. Instruction pairs for call/return with possible AMODE change . . . . . . . . . . . . . 862
423. Calling among addressing modes within an assembly . . . . . . . . . . . . . . . . . . . 863
424. LLGT and LLGTR instructions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 863
425. Symbol table entries for DSECT symbols . . . . . . . . . . . . . . . . . . . . . . . . . 873
426. Summary of USING Statements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 905
427. Summary of DROP Statement Behaviors . . . . . . . . . . . . . . . . . . . . . . . . . 905
428. Example of a non-homogeneous array . . . . . . . . . . . . . . . . . . . . . . . . . . . 914
429. Array addressing with a table of addresses . . . . . . . . . . . . . . . . . . . . . . . . . 917
430. Example of an address table's contents . . . . . . . . . . . . . . . . . . . . . . . . . . . 918
431. Supervisor and Program Call instructions . . . . . . . . . . . . . . . . . . . . . . . . . 950
432. SVC instruction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 950
433. PC instruction format . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 951
433. Program Call instruction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 951
434. GETMAIN request options . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 958
435. FREEMAIN request options . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 960
436. Comparing QSAM and BSAM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 966
437. Partial contents of Extended Program Interruption Element (EPIE) . . . . . . . . . . 975
438. Hexadecimal, decimal, and binary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 995
439. Hexadecimal Addition Table . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 996
440. Hexadecimal Multiplication Table . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 996
441. Integer powers of 2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 997
442. Integer powers of 2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 998
443. Multiples of powers of sixteen (part 1 of 2) . . . . . . . . . . . . . . . . . . . . . . . . 1000
444. Multiples of powers of sixteen (part 2 of 2) . . . . . . . . . . . . . . . . . . . . . . . . 1000
445. Powers of 10 expressed in hexadecimal . . . . . . . . . . . . . . . . . . . . . . . . . . . 1001
446. Assembler Language EBCDIC character representation . . . . . . . . . . . . . . . . . 1012
447. 7-bit ASCII character representation . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1013
448. High Level Assembler DC-Statement Constant Types . . . . . . . . . . . . . . . . . . 1014
449. ASCII Character Representation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1077
450. Examples of different types of integer division . . . . . . . . . . . . . . . . . . . . . . . 1129
451. Comparing five binary floating-point operands . . . . . . . . . . . . . . . . . . . . . . 1225
xxxvi Assembler Language Programming for IBM System zβ’ Servers Version 2.00
Tables xxxvii
xxxviii Assembler Language Programming for IBM System zβ’ Servers Version 2.00
Foreword
FFFFFFFFFFFF WW WW
FFFFFFFFFFFF WW WW
FF WW WW
FF WW WW
FF WW WW
FFFFFFFF WW WW
FFFFFFFF WW WW WW
FF WW WWWW WW
FF WW WW WW WW
FF WWWW WWWW
FF WWW WWW
FF WW WW
Chapters I-IV cover basic material needed for almost all programs.
β’ Chapter I introduces some notation we'll use, and discusses the important topics of binary and
hexadecimal number representations and arithmetic, and conversion among number represen-
tations.
β’ Chapter II introduces the βCentral Processing Unitβ or CPU. We'll survey central memory,
the registers you'll use in your programs, and the Program Status Word (PSW). Then we'll
look at some basic types of instructions and their operation codes, and see how they refer to
data in memory.
β’ Chapter III describes basic properties of the Assembler Language, including symbols, self-
defining terms, and expression evaluation. Then we will see how to write Assembler Language
statements and their components. Last, we discuss the key concept of addressability and the
important USING statement.
β’ Chapter IV describes methods for defining often-used data types, and techniques for organizing
data items in your programs.
β’ The six sections of Chapter V discuss basic instructions, emphasizing those that operate on
data in the general registers, and the important βconditional branchβ instructions.
β’ Chapter VI considers addressing techniques, loops and other iterative processes, and
βimmediateβ instructions containing useful operands.
β’ Chapter VII discusses bit and character data and techniques for handling them.
β’ Chapter VIII examines the packed and zoned decimal data representations, instructions for
packed decimal arithmetic, and for conversion between those representations and EBCDIC
characters.
β’ Chapter IX describes general concepts of floating-point arithmetic and the three floating-point
representations supported by System z: hexadecimal, binary, and decimal, and instructions for
manipulating data in and among each of the representations. It concludes with a summary of
important differences between floating-point and mathematicians' βrealβ arithmetics.
β’ Chapter X discusses large programs and modularization techniques such as subroutines and
common linkage conventions, how to combine separately assembled (or compiled) routines
into a single executable program, and how to change addressing modes.
β’ Chapter XI describes the powerful βDummy Control Sectionβ and the enhanced USING
statements, and shows how to apply them to several basic data structures.
Foreword 1
β’ 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, con-
version, and display operations.
Programming Environments
Every programming language must eventually deal with the environments under which the pro-
grams will be run. While we will see many examples of program segments, we will defer complete
programs until later sections.
I assume your programs will execute on one of z/OSβ’, z/VMβ’, or z/VSEβ’. I have purposely
omitted discussion of z/Linuxβ’, because Assembler Language is little used in that environment.
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 System's Supervisor are described in
βAppendix B: Simple I/O Macrosβ on page 1015; 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.
1 Yes, this book is too long. As my Chinese-restaurant fortune cookie said: βYou have a love for words, and should
write a book.β
2 I urge you not to look at them before you're tried your own solutions (or if you're completely stuck at some point).
It's OK to learn from someone else's programs, but best it you do it only after you're tried your own.
Foreword 3
IIIIIIIIII NN NN
IIIIIIIIII NNN NN
II NNNN NN
II NN NN NN
II NN NN NN
II NN NN NN
II NN NN NN
II NN NN NN
II NN NNNN
II NN NNN
IIIIIIIIII NN NN
IIIIIIIIII NN NN
A digital computer can be considered from various viewpoints; here are five possible views, each
treating the computer's 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 computa-
tion of a quotient.
β’ At the next level one might consider a computer's 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 macro
instructions that perform operations in a larger context.
The level that is our primary concern is usually known as βAssembler Language programmingβ or
βassembler codingβ.3 The assembler we'll 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 System z.
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 4 and the operating system Supervisor. Each will be considered
in the appropriate context.
3 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 System z processor's operations.
4 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.)
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 System z architecture. You should consult it regu-
larly 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 you're writing programs.
5 Why do I care? My first computer was the ILLIAC I, built to the IAS design.
Foreword 5
Assembler Language is also a natural vehicle for recovering lost source code (yes, it
happens!). Object or binary programs can easily be disassembled into Assembler Language
source programs.
5. It can be more efficient.
Efficiency depends on many things. Because you can specify almost the exact instruction
sequences you want, you can do many things to improve program efficiency. If you know
which parts of a program consume the most time, recoding those parts in Assembler Lan-
guage can often lead to savings.
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 program's lifetime.6
There is another objection to using Assembler Language to attain efficiency: some modern
compilers can produce quite efficient code for certain applications.7 However, even clever
coding and powerful compilers can't help a badly implemented algorithm. Also, you may
have difficulty learning the costs of various high-level language statements.
6. It's 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. It's more flexible.
There are some processor instructions and 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 else's program structures or con-
cepts of proper programming technique aren't forced on you by the language, and you have
more freedom to choose solutions you like.
8. It's more powerful.
In addition to Assembler Language's efficiency and flexibility, you also have available to you
the entire repertoire of the processor's instruction set. New instructions on your CPU are
usable immediately; you don't 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. It's 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. It's controllable.
Unlike βhigher-levelβ languages, the assembler creates machine language instructions and data
in exactly the form and order you specify. It doesn't 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β.
6 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, I've done that...)
7 Compilers do have occasional errors; finding problems with the generated code is easier if you know Assembler
Language.
Conversely, there are also reasons for not programming in Assembler Language.
1. The language can be verbose.
Economy of expression is not a characteristic of most Assembler Languages except (and this
is an important exception) for the availability of macro instructions. Usually, you must write
more lines of code to do a simple task than if you had chosen a higher-level language.
This is due mainly to the richness of the z/Architecture processor's instruction set, because
the Assembler Language itself is quite simple.
2. The language is very flexible.
It can be too flexible for some users. There are many acceptable ways to use Assembler
Language to solve a given problem, and almost all problems can be solved with a small and
manageable set of instructions.
3. The language is idiosyncratic.
To a large extent, the occasional lapses of regularity and coherence in the syntax and seman-
tics of the Assembler Language are due to irregularities in the System z instruction set and
architecture: instructions that do similar things may have different syntaxes. Thus, the
Assembler Language contains occasional βspecial casesβ and βexceptions to the rulesβ. (This
is of course not unique to Assembler Language!)
4. The language's flexibility means it's easier to make errors.
While this reason is implicit in the previous three, it also is part of the price you pay for
being able to specify everything yourself; you have more chances to make mistakes. We will
see that there are good ways to avoid some of the pitfalls that this extra freedom provides.
5. Programs can be harder to debug.
In some cases, programmers may not write programs so they can detect processing errors, or
terminate gracefully. Because programs can be written with great freedom, they might not be
organized so that errors do a minimum amount of damage. Similarly, some programmers are
often reluctant to insert the extra instructions necessary to leave an easily-followed diagnostic
trail for the person (you?) trying to discover why your program did something unexpected.
6. Programs may seem hard to maintain.
Maintenance costs are much more strongly influenced by the structure and clarity of the code
than by the language used to write it. Extensive research has shown little difference in mainte-
nance costs between Assembler Language and high-level languages.
Foreword 7
7. Lack of a run-time library.
Assembler Language programs can be written as a component of a high-level language appli-
cation. But βstand-aloneβ Assembler Language applications may not have access to the run-
time libraries provided with most high-level languages. By using careful modular design
techniques, this lack can be overcome with a set of routines or macro instructions that
provide functions shareable among many applications.
Assembler Language programs can access run-time libraries, so long as they adhere to appro-
priate programming conventions; this can often reduce programming effort.
8. Lack of portability.
Unlike programs written in some high-level languages, assembler language code is intended
for execution only on the processors for which it is created. (And, high-level language pro-
grams are not always easily moved to other processor architectures!)
If none of the reasons for programming in Assembler Language has much appeal to you β you
don't have to program in Assembler Language, you don't need its efficiency, flexibility, power, or
extensibility, and your sources of amusement (or employment) lie elsewhere β then don't. Use
whatever tool will do the job with the least time, effort, and nuisance, and get on to whatever task
comes next.
Remember!
Exercises
0.1.1.(1) + Why are you interested in Assembler Language?
Foreword 9
10 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
Chapter I: Getting Started
IIIIIIIIII
IIIIIIIIII
II
II
II
II
II
II
II
II
IIIIIIIIII
IIIIIIIIII
In this chapter, we will look at factors involved in Assembler Language programming, and then
investigate the binary number representation and its arithmetic.
β’ Section 1 looks at some notation, terminology, and conventions we'll use.
β’ Section 2 describes basic topics about the number representations used in System z processors:
binary and hexadecimal numbers, arithmetic and logical representations, 2's complement arith-
metic, and discusses alternative number representations.
11
111
1111
11
11
11
11
11
11
11
1111111111
1111111111
In this section we introduce some basic terms and notations that we'll use later, and then investi-
gate the important properties of the binary number representation.
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 super-
scripts 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.
Exercises
1.1.1.(1) What is the total width of the fields illustrated in Figure 1 on page 12?
Unlike some other processors and their assemblers, there are no reserved register names or
symbols in the System z Assembler Language.
Exercises
1.2.1.(1) If R 1 has value 9, what register is referenced by GR R 1?
8 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, it's no longer necessary to βnameβ registers.
9 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.
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.
System z, like most other digital computers, uses binaryβbase 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 System z, 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.
That is, each digit position as we move to the left is weighted by one more power of the base, ten.
To clarify which base is intended we use a notation like the Assembler's: if base 10 is intended,
the digits are written normally; if base 2 is intended, the binary digits are preceded by a βBβ and
an apostrophe, and are followed by an apostrophe. For example:
26 = B'11010', 1 = B'1', 10 = B'1010', 8 = B'1000', 999 = B'1111100111'.
Positional notation can be used for any base (or radix). For example, if humans had only one
hand we might use base 5 for numbering, so that 1413 in base 5 would have decimal value 233 (in
our ten-finger decimal world):
14135 = 1Γ53 + 4Γ52 + 1Γ51 + 3Γ50
= 125 + 100 + 5 + 3
= 23310
Exercises
2.1.1.(1) + Determine the decimal value of the following binary numbers: (a) B'000010110', (b)
B'000101100', (c) B'10101010', (d) B'1111111'.
2.1.3.(2) Suppose a binary number is represented by a string of n one bits (111...11). What is
its value?
We use the same positional notation for base 16 number representation as for decimal and binary
numbers. Thus, we can write the base 16 number A97E 16 as
AΓ163 + 9Γ162 + 7Γ161 + EΓ160,
or
10Γ163 + 9Γ162 + 7Γ161 + 14Γ160 = 10Γ4096 + 9Γ256 + 7Γ16 + 14 = 43390.
10 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β.)
The base sixteen digits in the third column are called hexadecimal12 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 Assembler's will denote hexadecimal quantities: the hexadecimal digits are preceded
by an βXβ and an apostrophe, and are followed by an apostrophe. For example:
26 = B'11010' = X'1A', X'26' = B'100110' = 38,
For example:
X'D5B' = B'1101 0101 1011' (hexadecimal to binary),
11 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.
12 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.
We use these abbreviations regularly: bit means βbinary digitβ, and hex is an abbreviation for
βhexadecimalβ.
Exercises
2.2.1.(1) Convert the following hexadecimal numbers to binary: (a) X'A', (b) X'2B', (c) X'3E8'.
2.2.2.(1) Make a table similar to Table 1 on page 18 showing binary, decimal, and octal (base
8) values.
2.2.3.(2) In grouping bits to form hex digits, why can't 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.
1. 21474
2. 77777
3. 1750
4. 60341303
5. 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 multipli-
cation tables.
The subscripts on the digits d match the power of the base A. If A has value 10, then the digit
string 73294 is the familiar decimal number seventy-three thousand, two hundred ninety four.
Suppose we want to convert X from its representation in base A to its representation in a new
base B, with digits e0, e1, e2, etc.:
X = em ΓBm + ... + e3ΓB3 + e2ΓB2 + e1ΓB1 + e0ΓB0.
We know the old and new bases A and B, and the digits d k of the old representation. To find the
digits e k of the new representation, we use the following scheme;
1. Divide X (in base A notation and arithmetic) by the new base B; save the quotient. The
remainder is the low-order digit e 0. This can be seen from the definition of the quotient and
remainder:
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 digit's 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 hex digit 3
232
-224 hex digit E
8
-8 hex digit 8
0
so that 1000 (decimal) is X'3E8'.
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 = 212 as β4Kβ. Similarly, 3Γ220 might
be referred to as β3Mβ. Thus, for example, an area of memory (which we'll discuss in Section
3.1) containing 8,192 storage locations might be said to contain β8K bytesβ or β8 K-bytesβ. 13
Exercises
2.3.1.(2) + Convert these numbers from the given base to the new bases.
1. X'7FFFFFFF'
2. X'C1C2C3'
3. X'4040405C' (This digit pattern will reappear in other forms!)
2.3.3.(3) Make a table of the hexadecimal values of the squares of the integers from 1 to 32.
1. X'257'
2. X'7FFA'
3. X'8008'
4. X'E000'
5. X'FFFA'
6. X'E1010'
2.3.5.(3) Suppose we must convert a number from its representation in base A to its represen-
tation 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?
2.3.6.(2) Convert these octal (base 8) numbers to base 10: (a) 5061, (b) 257, (c) 192. Work
carefully!
13 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.
9 4 2 1 0
2)19 2)9 2)4 2)2 2)1
18 8 4 2 0
1=e0 1=e1 0=e2 0=e3 1=e4
Hence, 19 = B'10011'.
2. Convert 1000 (base 10) to base 16. (The conversion arithmetic is done in base 10.)
62 3 0
16)1000 16)62 16)3
992 48 0
8=e0 14 (X'E')=e1 3=e2
Hence 1000 = X'3E8'.
3. Convert 627 (base 10) to base 9.
69 7 0
9)627 9)69 9)7
621 63 0
6=e0 6=e1 7=e2
so that 627 (base 10) = 766 (base 9).
4. Convert 766 (base 9) to base 7. First, we convert to base 10, and then do the arithmetic in
decimal:
89 12 1 0
7)627 7)89 7)12 7)1
623 84 7 0
4=e0 5=e1 5=e2 1=e3
so that 766 (base 9) = 1554 (base 7).
If you are mathematically inclined:
Just for fun, now do the conversion in base 9:
108 13 1 0
7)766 7)108 7)13 7)1
762 103 7 0
4=e0 5=e1 5=e2 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:
43 2 0
20)1413 20)43 20)2
130 40 0
113 3=e1 2=e2
110
3=e0
Again, we find 1413 (base 5) = 233 (base 10).
6. Convert X'3E8' to base 10. In this case it is simpler to evaluate the positional notation:
X'3E8' = 3Γ162 + 14Γ161 + 8Γ160,
and then evaluate this sum in decimal. Thus we find
X'3E8' = 3Γ256 + 14Γ16 + 8 = 768 + 224 + 8 = 1000.
This type of conversion can be simpler if you use the table of multiples of powers of 16 in Tables
2 and 3, or the conversion tables in Appendix A.
Exercises
2.4.1.(2) Perform the indicated conversions. For number bases greater than 10, assume that the
βdigitsβ corresponding to 10, 11, 12, etc., are represented by the letters A, B, C, etc., respec-
tively.
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 B'1111101000' to base 10 using binary arithmetic (that is, divide by B'1010').
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.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 = (((...(dnΓA)+...+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 multi-
plied by A, and so forth until the rightmost digit has been added. Using this technique, perform
the following conversions.
2.4.9.(2) In applying the βnested multiplicationβ technique of the previous exercise to conver-
sions from base A to base B, what base should be used for the conversion arithmetic?
2.4.10.(3) Using the base seven multiplication table you made in Exercise 2.4.6, perform the
following conversions in base 7 arithmetic: (1) 526 (base 10) to base 16, (2) 10110 (base 2) to
base 5, (3) 61436 (base 8) to base 10, (4) 666 (base 10) to base 7.
2.4.12.(3) If you have two numbers in bases A and B, what is a necessary relationship between
A and B that will allow you to use the same βdigit groupingβ technique you used to convert
between binary and hexadecimal?
2.4.13.(3) Show the value of 1610 in bases 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, and 3.
2.4.14.(4) Using base 7 arithmetic, calculate the sum and product of 435 7 and 64 7. First,
convert those two numbers to base 10 and then add and multiply the results in base 10; then
use those results to test that you have evaluated the base 7 sum and product correctly.
2.4.15.(2) Convert the following decimal values to base 3: 2, 6, 10, 12, 16, 28, 41, 99, 104.
There are three fixed-point (integer) number representations in common use: the radix-
complement, the sign-magnitude, and the diminished radix-complement representations. In prac-
tice, the widely-used radix-complement representation is called the two's complement
representation, and the diminished radix-complement representation is called the ones' complement
representation. 14 Two of these representations are used in System z: the two's complement form is
used for addressing and integer arithmetic, and the sign-magnitude form is used for floating-point
and packed decimal numbers. A variation of the radix-complement form is used internally for
packed decimal arithmetic, which we'll see in Chapter VIII.
With so many representations, you might wonder why the System z designers settled on two's
complement. The reason follows from the processor's βarchitectureβ: since virtually all computers
use the two's complement representation for address arithmetic, and because in System z the
general registers are used for both arithmetic and addressing, it is natural that ordinary integer
arithmetic has the same form.
We will illustrate the following discussion using 32-bit numbers, corresponding (as we shall see) to
the length of a word in memory and half the length of a general register.15
14 Why is it called βtwo's complementβ? The name of the ones' complement representation seems obvious: just comple-
ment each bit by subtracting it from 1 (or, change 0 to 1 and 1 to 0); but we don't get the two's complement by
subtracting each bit from 2! We'll explain this oddity shortly.
15 z/Architecture provides 64-bit general registers, but for now our examples will use the 32-bit length.
This is represented
by:
0 X'00000000'
1 X'00000001'
130 X'00000082'
224 β 1 X'00FFFFFF'
231 β 1 X'7FFFFFFF'
231 X'80000000'
2 β1
32 X'FFFFFFFF'
232+ 1 X'100000001'
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 number's
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 repre-
sentation 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 12), then the value X represented by the binary digits b31 b 30...b 1 b 0 is
X = b31Γ231 + b30Γ230 + ... + b2Γ22 + b1Γ21 + b0Γ20
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 sign-
magnitude, ones' complement, and two's 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 two's complement representation is used for most integer arithmetic in
System z, 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 represen-
tation:
1. X'DEADBEEF'
2. X'FFFFFFFF'
3. X'DEC0DED1'
Most programs must deal with both positive and negative numbers. A single bit (usually, the left-
most) is used to represent the number's sign. A 0 bit represents a β + β sign, and a 1 bit represents
a β β β sign.
First, the two's complement representation of a 32-bit nonnegative binary integer Y satisfying the
inequalities
0 β€ Y β€ 231β1 (numbers within that range with a β+ β sign bit)
is the same as the logical representation. 231 β 1 is the largest integer that can be represented using
31 bits; the remaining (32nd) digit at the left end is zero, the sign digit.
In effect, we have done the following: if Y is positive, we find its value by adding the individual
terms (biΓ2i); 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 + b30Γ230 + ... + b2Γ22 + b1Γ21 + b0Γ20,
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 represen-
tation, 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 two's complement representations is seen by examining the
above sum for the logical representation of X:
Xlogical = b31Γ231 + b30Γ230 + ... + b2Γ22 + b1Γ21 + b0Γ20.
If b31 is zero, the logical and two's complement representations yield the same value, and
Yarith = X logical. Now, suppose we are given the 32-bit two's complement representation of a
negative number Y arith , and we want to know the value those 32 bits would represent if we con-
sider them as the logical representation of a number X logical. Since bit b31 is 1, indicating a nega-
tive 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 repre-
sentation, 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 β€ 232β1 and β231 β€ Yarith β€ 231β1,
we have the following key relation between the logical and two's complement representations:
Xlogical = (Yarith + 232) (modulo 232).
That is, the bit pattern corresponding to the two's complement representation of any positive or neg-
ative number β 231 β€ Y β€ + 231 β 1 is the rightmost 32 bits of the sum 232 + Y (modulo 2 32).
Exercises
2.7.1.(3) Convert X'AB0DE' to base 15, using hexadecimal arithmetic throughout.
2.7.3.(2) What is the decimal value of the 12-bit binary number 100000000001 in a signed two's
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 two's 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.
Two's-Complementation Recipe
Given a binary number Y, to find the two's complement representation
of β Y:
1. Take the ones' complement of all bits of Y: change 0 digits to 1,
and 1 digits to 0.
2. Add 1 in the low-order (rightmost) position, and ignore carries out
of the leftmost position.
These two examples do the arithmetic with eight binary digits rather than thirty-two.
1. Find the two's complement representation of β 2.
16 Some older computers used the ones' complement representation for binary integers, so negative zeros were possible.
System z packed decimal and floating-point numbers (discussed in Chapters VIII and IX) support negative zeros.
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 two's 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 two's complement representation:
1. X'0257'
2. X'7FFA'
3. X'8008'
4. X'E000'
5. X'FFFA'
2.8.3.(2) It is sometimes said that the complement of a number X is the same as β X. State this
more precisely.
2.8.4.(2) Four 16-bit areas of a program are named A, B, C, and D. Their contents are
c(A) = X'7D40'
c(B) = X'D000'
c(C) = X'15A2'
c(D) = X'800A'
If they are the signed 16-bit two's complement binary representations of four decimal numbers,
determine their decimal values.
2.8.6.(3) Give the 32-bit two's complement representation (in either hexadecimal or binary) of
both the positive and negative values of the following decimal integers: (1) 10, (2) 729, (3)
1000000, (4) 1000000000, (5) 2147483648, (6) 65535, (7) 2147483647.
β’ Subtract 1
β’ Complement all bits
Does this differ from the two's complementation recipe given on page 27? Create examples that
show how this form does or does not differ from that recipe.
2.8.8.(1) Give the 16-bit two's complement binary representation of each decimal number in
hexadecimal.
1. + 13055
2. β 9582
2.8.9.(2) + Show the 32-bit hexadecimal value of the two's complement binary representation of
each of the following decimal values.
1. +5
2. β 97
3. + 65795
4. β 16777158
5. + 16777219
6. β 78606
2.8.10.(1) + Assuming a 16-bit two's complement representation, give the signed decimal values
of these hexadecimal values.
1. X'B00F'
2. X'FFF1'
3. X'0FFF'
4. X'F001'
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 0 1 1
+0 +1 +0 +1
0 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 two's 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 B'0010' ( + 2) to itself, and then we add B'0100' ( + 4) to itself.
0010 0100
+0010 +0100
0100 (no overflow) 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 it's done:
Exercises
2.10.1.(2) + Consider adding the 8-bit binary number X'F5' to itself. There is no carry from
X'5'+ X'5'=X'A', but there is a carry from X'F'+ X'F'=X'1E'. Since the carry out of the low-
order digit position is different from the carry out of the high-order digit position, has overflow
occurred?
While this prescription is essentially correct, there is a minor but important complication we'll
examine after illustrating the basic scheme. (In Examples 6 and 7, note that the carries into and
out of the high-order bit are different.)
β’ Example 1.
5-3: 0000 0101
-0000 0011
becomes
0000 0101
+1111 1101
(carry lost) 0000 0010 = 2
β’ Example 2.
3-5: 0000 0011
-0000 0101
becomes
0000 0011
+1111 1011
(no carry) 1111 1110 = -2
β’ Example 3.
25-(-17): 0001 1001
-1110 1111
becomes
0001 1001
+0001 0001
(no carry) 0010 1010 = 42
β’ Example 4.
(-17)-25: 1110 1111
-0001 1001
becomes
1110 1111
+1110 0111
(carry lost) 1101 0110 = -42
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. 10 β ( β 10)
2. 729 β 65535
3. 2147483647 + 2
4. 1000000000 + ( β 2147483647)
5. 0 β ( + 0)
6. ( β 10) + 10
Do the arithmetic in the two's complement representation, indicating for each case (1) the pres-
ence 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 right-
most 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 deter-
mine (a) whether an arithmetic overflow occurs, and (b) whether there is a carry out of the
leftmost bit.
1. X'7D26F071'+X'B40E99A4'
2. X'7D26F071'-X'B40E99A4'
3. X'FFFFF39A'+X'FFFE4B06'
4. X'FFFFF39A'-X'FFFE4B06'
5. X'80000003'+X'0000007C'
6. X'80000003'+X'8000007C'
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 opera-
tion! 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.
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 on page 30, compute the fol-
lowing 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.) (1) A + C; (2) D β E; (3) Z + ( β F); (4) ( β E) β C; (5) ( β B) + A; (6)
C β Z; (7) 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 comple-
ment 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.
β
o 0100
0101 o β o 0011
β
0110 o β o 0010
β
β
0111 o β o 0001
β
x overflow point β
β 0000
ββββββ’βββββββββββββββββββββββΌββββββββββββββββββββββoββββ
1000 β
β carry point x
β
1001 β’ β β’ 1111
β
β
1010 β’ β β’ 1110
β
1011 β’ β β’ 1101
β’ 1100
β
Figure 3. βCircularβ representation of two's complement representation
First, suppose the numbers are considered to be the logical representation of the integers from 0
to 15. Counting up from 0000 by one takes us around the circle counter-clockwise from 0000 to
1111 and then back to 0000, as we would expect for numbers modulo 2 4. Adding and subtracting
two numbers can be thought of as adding and subtracting the angles (measured counter-clockwise
from 0000) represented by the numbers. Thus,
0100 + 0110 = 1010, and 1100 + 0111 = 0011.
A carry condition occurs in addition if we go past the βcarry pointβ in the counter-clockwise
direction; similarly, a βborrowβ condition occurs in subtraction if we go past the βcarry pointβ in
the clockwise direction.
For the two's 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 exam-
ples 4 and 5 of Section 2.8 above.
Now, consider the numbers to be the signed 4-bit two's 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.
Exercises
2.13.1.(3) + In many early editions of the System/360 Principles of Operation, the Subtract oper-
ation was described as follows: βSubtraction is performed by adding the two's 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 satis-
factory; 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.
Thus the arithmetic and logical sums give the same binary result; the leftmost bits and the high-
order two carry bits are just interpreted differently in the two representations.
We can make a further observation about adding and subtracting numbers in the logical represen-
tation. From the examples in Section 2.11, we see that in subtraction, if the second operand is
logically smaller than or equal to the first (see examples 1, 4, 5, 7, 9, and 11) then there will be a
carry out of the leftmost bit position. Conversely, we see (in examples 2, 3, 6, 8, and 10) that if
the first operand is logically smaller than the second operand subtracted from it, there is no carry
out of the left end. In these latter cases we have in some sense generated a βnegativeβ logical
answer, since the result is not correctly represented to the given number of bits. We'll see exam-
ples of these cases when we examine instructions that perform logical arithmetic.
Exercises
2.14.1.(2) Assuming an eleven-bit word, give the logical and two's complement representations
of the following quantities: (1) 200, (2) 1023, (3) β 1000, (4) 2047, (5) β 1, (6) β 1024, (7)
β 1023, (8) 1024, (9) β 0. If a quantity is not representable, indicate that it is not.
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.)
In the sign-magnitude and ones' (diminished radix) complement representations, there are two
distinct representations for zero. In the two's (radix complement) representation, there is no rep-
resentation 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 two's complement representation is not just an indicator: it
is numerically significant.
Representing signed numbers in a computer always involves tradeoffs: how should βpeculiarβ
cases like these be handled?
17 More formally, the representation in radix r of an n-bit negative number X is r n β X in the two's complement repre-
sentation, and (r n β 1) β X in the ones' complement representation.
2.15.2.(3) Using the representations you calculated in Exercise 2.15.1, evaluate the following
using ten's 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' com-
plement) representation.
IIIIIIIIII IIIIIIIIII
IIIIIIIIII IIIIIIIIII
II II
II II
II II
II II
II II
II II
II II
II II
IIIIIIIIII IIIIIIIIII
IIIIIIIIII IIIIIIIIII
This chapter's three sections introduce the main features of System z processors:
β’ Section 3 describes basic structures: memory organization and addressing, general purpose reg-
isters, 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.
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, arith-
metic, control, and input-output. A real computer may not identify components this way, but it
helps us to think of them as distinct units.
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.
System z makes no special distinction between the arithmetic and control units, and the combina-
tion is often called the βCentral Processing Unitβ, or βCPUβ.
β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 com-
municates the status of its operations to the CPU, indicating error conditions or completion of
the operation.
β8 bitsβ
ββββββββββββ
β 11010010 β
ββββββββββββ
0 7
Figure 6. A byte containing 8 binary digits
Bytes in memory are arranged so that each byte may be referenced as easily as any other. The
bytes are individually numbered beginning at zero; the number associated with each byte is called
its memory address. Memory may be thought of as a linear string of bits; the bits are grouped
into bytes arranged in order of increasing addresses. Only bytes have addresses; bits within a byte
don't have their own addresses.
The bits in a byte are accessed (or βreadβ) by the CPU without being changed. Reading the con-
tents of a byte does not affect the contents; the memory provides the CPU with a copy of the
18 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 won't.
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.19 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.20 The possible lengths for such groups of bytes are 2, 4, 8, or 16;
we sometimes refer to them as halfwords, words (or fullwords), doublewords, and quadwords
respectively.
8DF 8E0 8E1 8E2 8E3 8E4 8E5 8E6 8E7 8E8 8E9 8EA 8EB 8EC 8ED 8EE 8EF 8F0
ββ¬ββββββ¬ββββββ¬ββββββ¬ββββββ¬ββββββ¬ββββββ¬ββββββ¬ββββββ¬ββββββ¬ββββββ¬ββββββ¬ββββββ¬ββββββ¬ββββββ¬ββββββ¬ββββββ¬ββββββ¬ββββββ¬β
β β β β β β β β β β β β β β β β β β β
ββ΄ββββββ΄ββββββ΄ββββββ΄ββββββ΄ββββββ΄ββββββ΄ββββββ΄ββββββ΄ββββββ΄ββββββ΄ββββββ΄ββββββ΄ββββββ΄ββββββ΄ββββββ΄ββββββ΄ββββββ΄ββββββ΄β
β halfword β halfword β halfword β halfword β halfword β halfword β halfword β halfword β
βββββββββwordββββββββββββββββββwordββββββββββββββββββwordββββββββββββββββββwordββββββββββ
ββββββββββββββββββdoublewordββββββββββββββββββββββββββββββββββββdoublewordβββββββββββββββββββ
βββββββββββββββββββββββββββββββββββββββββββquadwordββββββββββββββββββββββββββββββββββββββββββββ
Figure 8. A portion of memory
When some operation manipulates a group of bytes, we call that group an βoperandβ: something
that is βoperated onβ. The group always consists of data from consecutively-addressed bytes in
memory.
Some operations treat the operand as a string of bits whose meaning for that operation is inde-
pendent 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 opera-
tion, 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 operand β its rightmost bit
β corresponds to bit 7 of the byte at X'8EB'.21
Bytes in memory contain only bit patterns. Whether the bit pattern is interpreted as an instruc-
tion, 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 System z can be thought of as a continuous string of bits. Does each
individual bit in memory have an address? Explain.
19 This is true with few exceptions, which we will note as they appear. For now, remember βleftmostβ as the rule.
20 In early System/360 processors, many memory operands had to be aligned on byte boundaries whose addresses were
a multiple of the operand's length. While this is no longer required for most (but not all) instructions, proper align-
ment is always a good programming practice.
21 z/Architecture processors use what is called βbig-endianβ addressing; we'll examine βendiannessβ in detail in Chapter
VII, Section 26.7.
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 on page 43 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?
When we discuss instructions that do 32- and 64-bit arithmetic, we'll understand why this picture
shows two 32-bit parts of a 64-bit general register.
22 Because the general registers are used for so many activities, they are sometimes called βGeneral Purpose Registersβ.
This figure arranges the registers in pairs, the left register being even-numbered and the right being
the next higher odd-numbered register. Some operations require using a pair of registers, and in
such cases it is always an even-odd-numbered pair.
We will often refer to the general registers using a short notation: we sometimes write βGRnβ
(meaning the rightmost 32 bits of a 64-bit register) or βGGnβ (meaning all 64 bits) or simply
βRnβ to refer to general register n when the register length is clear from context. Thus, in
Figure 10, we might use R1 to mean register 1, R14 to mean register 14, and so on.
Be Careful!
βR1β (without a subscript) is not the same as the notation βR 1β (with a
subscript). This difference will be important when we discuss machine
instructions.
Exercises
3.3.1.(1) Suppose a shifting operation requires the use of a pair of general registers. Is it possible
to perform the shifting operation using both GR7 and GR8? Using GR15 and GR0? Using
GR6 and GR7?
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 floating-
point instruction using 128-bit operands will use a pair of floating-point registers.
We won't mention the floating-point registers until we discuss instructions for floating-point arith-
metic. 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 reg-
ister?
3.4.2.(3) Can you think of any reasons why the designers of System/360 and System z 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?
For our purposes, we need to know about only a few parts of a PSW: the Instruction Address
(IA), the Condition Code (CC), the Instruction Length Code (ILC), and the Program Mask
(PM). Of these, the IA is most important now; we'll see more about the others later.
Figure 12 illustrates these four parts of a PSW (and the βSystem Flagsβ). The IA is always in the
rightmost position; the positions of the other three aren't significant. (In fact, PSWs since about
1975 no longer have a field for the ILC.)
The PSW for the currently executing program resides in the CPU, not in memory.
The CC is set (given a value) by some instructions β for example, to indicate that the result of an
addition operation is a negative number. Other instructions may have no effect on the CC; in
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.
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 43, instructions executed by the computer reside in memory
along with the data to be processed. Instructions in System z 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 doesn't 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
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 con-
fused 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 didn't intend the fetched bytes to be an instruction, it's 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)?
Modern System z processors support over 30 instruction formats that we'll 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 on page 52 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;
βββββββββββββββββββββββββββββββ
β Registers β
βββββββββββ¬βββββββββββ¬βββββββ¬ββ
ββββββββββ
RR β
βββββββββββββββββββββ βRX,
β Instruction β βRS
βββββββββββββββββ¬ββββ β
SIβ SS β
ββββββββββ
βββ΄ββββββββ΄βββββββββββ΄βββββββ΄ββ
β Memory β
βββββββββββββββββββββββββββββββ
Figure 14. Instruction formats and data interactions
The first byte of an instruction always contains an operation code (often abbreviated βopcodeβ),
specifying the operation to be performed. The second byte usually contains data about the
location, type, or length of the data to be operated on. This second byte has several forms: it is
called the βregister specificationβ byte (for RR, RX, and RS instructions), the βimmediate dataβ
byte (for SI instructions), or the βlength specificationβ byte (for SS instructions).25 The interpreta-
tion of this second byte therefore depends on the class to which the instruction belongs.
β’ RR-type instructions are always one halfword long.
register
operation
specifica-
code
tion
Table 6. RR-type instruction
format
register
operation
specifica- addressing halfword
code
tion
Table 7. RX-type and RS-type instruction format
The RX- and RS-type instruction formats differ only in the interpretation of the bits in the
βRegister Specificationβ byte.
β’ SI-type instructions are always two halfwords long.
operation imme-
addressing halfword
code diate data
Table 8. SI-type instruction format
Instead of a register specification, the second byte of an SI-type instruction contains an 8-bit
data item used in executing the instruction.
25 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 needn't worry.
length
operation
specifica- addressing halfword addressing halfword
code
tion
Table 9. SS-type instruction format
For most instructions except RR-type instructions, an addressing halfword is used by the CPU to
compute the address of an operand; this important process is described in β5.1. The Addressing
Halfwordβ, on page 62, 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.3.(2) How is it possible for instructions of different lengths to be packed tightly into
memory with no wasted bytes?
4.2.5.(2) + Figure 14 on page 52 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?
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 on page 54* shows the relationship between the first 2
bits of the opcode and the ILC:
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 deter-
mine 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 instruc-
tion 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 on page 53, deduce a simple formula that can be used to
determine, for any System z 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 contig-
uous.)
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?
A closer examination of a complete table of operation codes reveals a great deal of symmetry in
the opcodes used for similar functions. For example, the four original System/360 instructions
Since we will refer to instructions almost entirely using mnemonics β short abbreviations for their
full names β these details are only of minor interest.
Exercises
4.4.1.(2) Examine the operation codes given in Exercise 4.3.2, and determine their general
instruction classifications from Table 11.
When an interruption occurs, the CPU stores the PSW that currently controls its operation in a
predefined area of memory, and immediately replaces it with a new one from a different prede-
fined area of memory. Many things can cause this PSW switching: a program may contain an
instruction that causes an interruption to occur, or some external event such as a completed I/O
operation could cause an interruption. The basic mechanism used for handling interruptions is
illustrated in Figure 16.
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 informa-
tion 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 inter-
ruptions. 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. Restart (operator action)
2. External (timer, clock comparator)
3. Machine Check 27 (equipment malfunction)
4. Input-Output (an I/O device has signaled a condition)
5. Program (exception condition during program execution)
6. Supervisor Call (program requests an Operating System service)
Corresponding to each class is an area of memory where an old PSW is stored, and an area from
which a new PSW is loaded by the CPU. Thus there are six areas in memory into which old
PSWs are stored, and another six areas from which new PSWs are retrieved. These areas are at
fixed positions in the low-address end of memory; a programmer has no control over where they
are placed.
We sometimes distinguish two different classes of interruption. The first is caused by events whose
occurrence cannot be predicted, or for which a program cannot test in advance: these are some-
times called involuntary or asynchronous interrupts. The first four classes of interruption are invol-
untary. Except for the restart interruption, all the involuntary interruptions can be masked.
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 exe-
cuting 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 instruc-
tion could take.
We will be most concerned with program interruptions. They may be caused by error conditions
detected during any of the three portions of the instruction cycle. For example, if the IA specifies
26 Figure 16 doesn't account for the possibility that an interruption can occur during the fetch or decode phases. In
almost all cases, this distinction is unimportant.
27 This interruption shouldn't be masked off because the CPU must save diagnostic information before the situation gets
worse.
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 interruptions are shown below with their associated Inter-
ruption 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 program's destroying part of itself.
IC=2 Privileged Operation. The program is trying to execute an instruction not allowed in
problem state.
IC=3 Execute exception. An execute instruction is attempting to execute another execute
instruction.
IC=4 Access, Protection. The program has attempted to refer to some area of memory to
which access is not allowed. There can be other causes, but this is the most common.
IC=5 Addressing. The program has attempted to address a nonexistent memory address.
IC=6 Specification Error. This can be caused by many conditions, but a common cause is
referring to an odd-numbered register when an even-numbered register is required. An
odd IA in the PSW indicates an attempt to access an instruction not starting on a
halfword boundary.
IC=7 Data Exception. This is caused by invalid packed decimal data, or by binary or decimal
floating-point conditions described in Chapter IX.
IC=8 Fixed-Point Overflow. This is caused when a fixed-point binary result is too large.
IC=9 Fixed-Point Divide Exception. A binary divide instruction has found that a quotient
would be too big to fit in a register, or a divisor is zero.
IC=A Decimal Overflow. A packed decimal result is too large to fit in the result field.
IC=B Decimal Divide. A packed decimal quotient is too large to fit in the result field, or a
divisor is zero.
IC=C Hexadecimal floating-point exponent overflow. A hexadecimal floating-point result is
too large.
IC=D Hexadecimal floating-point exponent underflow. A hexadecimal floating-point result is
too small.
IC=E Hexadecimal floating-point lost significance. A hexadecimal floating-point result has lost
all its significant digits.
IC=F Hexadecimal floating-point divide exception. A hexadecimal floating-point operation is
attempting to divide by zero.
Four of the fifteen possible program interruption conditions are often regarded as harmless: fixed-
point and decimal overflow exceptions, and hexadecimal floating-point exponent underflow and
Exercises
4.6.1.(2) + Suppose the contents of the following 8-byte System/360 PSW28 (sketched in
Figure 12 on page 47) was displayed as the result of a program interruption. What error con-
dition 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?
1. 0001
2. 0009
3. 000C
29 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.
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 System z differs from that found in many earlier computers,
where the actual memory address (or addresses) of the operand (or operands) was part of the
instruction.
ββββββββββββ¬ββββββββββββββββββββββββββββββββββββ
β opcode β operand address β
ββββββββββββ΄ββββββββββββββββββββββββββββββββββββ
Figure 17. Typical instruction format for old computers
When memory sizes were limited, this was a reasonable and efficient choice.30
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 System z, 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 System z 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 gener-
ation.
30 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.
The first 4 bits of the addressing halfword contain a hex digit called the base register specification
digit, or base digit.31 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.
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.
31 The base register specification digit was sometimes called the βbase register addressβ, but this is misleading because
the base registers aren't βaddressableβ like bytes in memory.
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?
Exercises
5.2.1.(2) + Assume general registers 0, 1, and 2 contain these values:
c(GR0) = X'12001038'
c(GR1) = X'0902A020'
c(GR2) = X'001AAEA4'
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 Effec-
tive 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 52) 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 on page 64.
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 specifi-
cation 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.
Modern CPUs add the base and index register contents with a three-input adder, so there is actu-
ally 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 compu-
tation?
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?
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.32
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) = 12001028 C(GR4) = 8888000E
C(GR1) = 8902A020 C(GR5) = 12345678
C(GR2) = 4F1AAEA4 C(GR6) = 0FDE3B72
C(GR3) = FFFFFFF8 C(GR7) = 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.
32 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.
5.4.4.(3) Suppose the contents of the general registers are as shown in Exercise 5.5.2 below. 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'.
Certain instructions operating on groups of bytes require the address of the leftmost (lowest-
addressed) byte of the operand group be exactly divisible by the length of the operand. If this
condition is not satisfied, a program interruption for a specification exception occurs. In early
processors, operand alignment was required for almost all instructions, but the requirement was
relaxed soon after.33 Few instructions in modern processors require strict operand alignment.
When you use base-displacement addressing with 12-bit displacements, the only part of the
memory that can be referenced without using a base register is the area with addresses 0 to
4095 = X'FFF', so you will almost always use a base register to refer to operands in memory.
(We'll see in Chapter VI, Section 20 that instructions with signed 20-bit displacements make this
4K-byte limitation much less severe.)
You can't put your program into those first 4096 bytes 34 because that area of memory (and more)
is reserved by the CPU and the Operating System. This means that if you want to access a byte
in memory at address XX (where XX is greater than 4095), there must be a base register available
β one of registers 1 to 15. If a base register contains a base address, and XX lies between that
base address and the base address + 4095, then we say that XX is addressable. If there is no such
number in a register, then the byte at XX is not addressable by your program.
When we place a number in a register to address a 4096-byte region of memory, that register
provides addressability for the region. However, if the number itself must be brought from
another portion of memory that is not currently addressable, we are back where we started,
needing another number to provide addressability for the first number.
Fortunately, there are simple solutions to the problems of establishing addressability. The BASR
instruction is often used (as we will see soon), and the Assembler's address constants also allow us
to refer to other areas of our program. Modern processors provide new ways to minimize these
addressing problems: long displacements and relative addressing. We will turn to them in Section
20 after we have investigated the most often-used instructions.
Exercises
5.5.1.(3) + Suppose the general registers contain the values shown in Exercise 5.2.1. Which of
the following locations in memory (given in hexadecimal) are addressable through the use of
the base-displacement addressing technique? For each location that is addressable, derive an
addressing halfword that can be used to address it. (1) X'02ABCD', (2) X'000A4D', (3) X'001139',
(4) X'88888E', (5) X'02A010'.
33 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 relax-
ation of the alignment requirement was called the βByte-Oriented Operand Featureβ; it soon was known as the
βBOOFβ.
34 Unless you're writing your own operating system!
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 accompa-
nying 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
63 (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 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. (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 53).
(1) X'D2078F1D57C4', (2) X'DCFFDCFF7000', (3) X'F26337390050', (4) X'D58DFE4FC016'.
Without DAT, a reference to a byte at X'123456' addresses that byte in the physical or βrealβ
memory of the processor. When DAT is active, your reference to a byte (at your virtual Effective
Address X'123456') is translated into a βrealβ address (such as X'27D94FA') having no obvious
relation to your address; you can't determine the relation of your virtual addresses to the real
addresses to which they are mapped. The Operating System, working with the DAT facilities,
makes it possible for your program to operate as though it is addressing βrealβ memory; but only
the Operating System works with real addresses. This is why your addresses are called βvirtualβ β
they aren't real.
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 on page 68.
To use these indexes for calculating real addresses, the Operating System first constructs (in a pro-
tected 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.
This description covers only very basic aspects of translation, and does not cover 64-bit virtual
addresses. There are many other details of the process, and (because translation is very heavily
used) the processor has a lot of additional hardware to optimize the process.
Exercises
5.6.1.(3) Some processors use a technique called indirect addressing. If a bit in the instruction
(called the indirect-addressing bit) is nonzero, the CPU uses the Effective Address not to access
an operand, but to access a second instruction. The Effective Address of this new instruction
then becomes the operand address that points to the desired operand. (On some processors, if
the instruction at the βindirect addressβ had its indirect-addressing bit set, then the entire
process repeats until an instruction is found without the indirect-addressing bit set.) Can you
think of reasons why indirect addressing is not provided by System z?
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 System z 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.
35 We will see in Section 20 that System z provides another form of base-displacement addressing with a signed 20-bit
displacement.
We have seen how the CPU executes instructions and evaluates addresses; now we'll see how we
write Assembler Language programs.
β’ Section 6 describes typical steps involved in preparing, assembling, linking, and executing pro-
grams written in Assembler Language.
β’ Sections 7 and 8 examine the components from which machine, assembler, and macro instruc-
tion 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 System z.
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 con-
ventions 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 β
βββββββββββββββββββββββ βββββββββββ
Figure 23. Simple view of Assembler processing
The Assembler converts the program from a form convenient for you (statements) to a form con-
venient for the processor (binary data and instructions), its machine language.
6.1.2. Linking
The Linker 36 combines your object module with any others needed for execution. The linking
step is sketched in Figure 24; the Linker is placed in memory and begins execution.
ββββββββββββββββββββββββ
β System z β
ββββββββββββββββββββββββ€
ββββββββββ β ββββββββββββ β ββββββββββ
β Your β β β β β β Your β
β Object βββββββΌββββ
β Linker βββββββΌββββ
β Load β
β Modulesβ ββββΌββββ
β βββββββΌββ β Module β
ββββββββββ β β ββββββββββββ β β ββββββββββ
β ββββββββββββββββββββββββ β
βββββββββββββ΄βββ β βββββββββββ
β Libraries β ββ
β Your β
β of Object or β β Linker β
β Load Modules β β Listing β
ββββββββββββββββ βββββββββββ
Figure 24. Simple view of program linking
The output of the Linker is a load module.37 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.
After your program has been loaded into memory, the Supervisor transfers control to it by setting
the Instruction Address in the PSW to the address of the instruction where you want execution to
begin. Your program then does whatever processing you told it to do 38 and when it is finished it
returns control to the Supervisor.
36 We'll use βLinkerβ to mean any program (such as the Binder and Linkage Editor) that combines object module files
into executable files like load modules.
37 The output of a Linker has many many different names and forms, depending on the operating system and the
system Linker. For example, on System z 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β. We'll
use βload moduleβ to mean a data set or file ready to be loaded directly into memory for execution.
38 Which may not always be what you intended!
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.
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 continua-
tion 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.40 This is illustrated in Figure 26. These conventions β column 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 char-
acters 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 informa-
tion. 41
A comment statement is identified by an asterisk (*) in column 1. Any information may appear in
columns 2 through 71. Figure 27 on page 76 has examples of comment statements:
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β.
40 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.
41 Even though IBM cards have 80 columns, early computers like the IBM 704 and 709 couldn't 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.
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.
If there is a name field entry in the statement, it must begin with a nonblank character in column
1. It is terminated by the first blank column after column 1. If no name field entry is desired,
column 1 must be left blank.
42 It's better to call this the βremarksβ field, to avoid confusion with comment statements.
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 influ-
ence the processing of the statement unless this field extends into column 72, indicating a contin-
uation 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β.
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 cus-
tomary 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 char-
acters 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!)
The term βoperandβ can be confusing. Section 3.1 on page 43 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 on page 78 illustrates a machine instruction statement in which entries appear in all four
fields.
43 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.
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.44
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.
RETURN
Figure 32. The macro-instruction statement R E T U R N
If the RETURN statement above had been prepared in the days of punched cards, the card 45
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
44 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β.
45 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β.)
Exercises
6.3.1.(1) Suppose a program contains the machine instruction statement shown in Figure 30 on
page 78. 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.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 on page 78 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?
A program is a sequence of Assembler Language statements. The input to the Assembler should
consist of
The last statement of the program must be an END statement telling the Assembler to stop
reading records. It is written
END progname Last statement of program
where the progname operand of the END statement should (for now) be the same as the progname
in the name field of the START statement. For our example, we would write
END TEST Begin execution at 'TEST'
The progname in the operand field of the END statement specifies the name of the instruction
where execution should start when the program is loaded into memory. The operand field entry
on the END statement may be omitted, but specifying it is a good programming practice, so we'll
write our sample programs this way.
The Assembler allows no symbol as the name-field entry in an END statement. Assembler Lan-
guage programs, unlike programs in many high-level languages, must not try to terminate exe-
cution 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 state-
ment 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
can't set the initial location or assumed origin value. We'll discuss control sections and the
CSECT instruction thoroughly in Chapter X, Section 38.
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 Assem-
bler, Linker, and Program Loader, and how to pass your program's 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 com-
puter 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 exe-
cuted; 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.
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 exe-
cuting 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?
Your operating system may provide similar facilities already, but you should check to see how or
whether they differ from these. We will use these six macro-instructions, and show how they're
used in some programming examples.
PRINTOUT Print formatted information about data and registers
READCARD Read 80-byte card-image records
PRINTLIN Print lines of characters
DUMPOUT Dump memory in hexadecimal format
CONVERTI Convert decimal characters to a 32- or 64-bit binary integer
CONVERTO Convert a 32- or 64-bit binary number to decimal characters
The macro instructions and their operands are described in βAppendix B: Simple I/O Macrosβ on
page 1015.
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
System z. The Assembler determines the needed base and displacement so that correct Effec-
tive 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.
Programming Problems
Problem 6.1.(2) + Write, assemble, link, and execute a short program (like the one in Figure 33
on page 81) 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!'
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.
46 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 we'll meet it again in Chapter VI, Section 26.4.
Character self-defining terms use the EBCDIC character representation described next.
Exercises
7.1.1.(2) + Which of the following are valid self-defining terms? If you think a term is invalid,
explain why; otherwise, give the hexadecimal value of the term.
(1) 00000012345
(2) B'10101010101010101'
(3) X'0000B4DAD'
(4) X'B4DAD0000'
(5) +65535
(6) B'000000000001111000011110000111101'
(7) B'101011010001111000011110000111101'
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?
47 Unfortunately, people sometimes call the apostrophe or single quote a βquotation markβ or βsingle quotation markβ.
Calling a quotation mark a βdouble quoteβ or ββ³β doesn't help either, because it might be understood to mean a pair
of apostrophes.
In System z the conventional character code is called the βExtended Binary Coded Decimal Inter-
change Codeβ, or EBCDIC for short. 48 Each character is represented internally by an eight-bit
number β two hexadecimal digits β as indicated in Table 13. The internal bit patterns that repre-
sent external characters are a matter of choice; any mutually agreeable set is about as good as any
other. The Extended BCD code, or EBCDIC, is the code defined by the designers of System/360
for communicating with character-sensitive components of the computer such as the CPU,
printers, graphic display devices, etc. We will see other important character encodings in Chapter
IV, Section 12.8, and again in Chapter VII, Section 26.
This table shows the EBCDIC representation used by the Assembler, βCode Page 037β. (There
are many other EBCDIC code pages used around the world.)
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'61', the binary self-defining term B'1100001', 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'50'. Which
type of term you choose is largely a matter of context; in some places, certain types will be more
natural than others.
48 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 System z.
The characters shown in Table 13 on page 87 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'40'.
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) C'#@$'
(2) C'''''
(3) C'β’Aβ’B' (one leading blank)
(4) C'RUD'
(5) C'12'
(6) C'β’β’β’12' (three leading blanks)
7.2.2.(2) + Give (in hexadecimal) the value of each of the following character self-defining terms:
(1) C'&&', (2) C'75', (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 char-
acters in Table 13 on page 87.
7.2.4.(2) + Give (in hexadecimal) the value of each of the following self-defining terms:
(1) C'''''''', (2) 1000, (3) B'01000', (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) X'405C', (5) X'F9F9F9F9',
(6) B'110001011101100111010001'.
7.2.6.(1) What EBCDIC character would be represented by the bit pattern in the byte illus-
trated in Figure 6 on page 43?
7.2.7.(1) Show the hexadecimal value of each of the following self-defining terms:
(1) B'110010110000010111010110'
(2) C'A&&B'
(3) 54721
(4) X'B00B00'
49 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.)
Symbols are more interesting than self-defining terms: they let you assign meaningful names to
parts of your program. You can give the name PLUS1 to an area containing the constant +1, and
the name READ to an instruction that reads data.
Three types of symbols are used in the Assembler Language: ordinary symbols, variable symbols,
and sequence symbols. The last two are used only in macro-instructions and in conditional
assembly, so we won't say more about them here.
There are two types of ordinary symbols: internal and external. External symbols are used during
linking to communicate with other programs (and are part of the object module, as we'll see in
Chapter X, Section 38), while internal symbols are used only during the assembly, and do not
appear in the object module. 50
For now, we assume that all symbols are internal symbols. A word of caution: if you have done
some programming in a high-level language, you may be inclined to think of symbols as variables.
They aren't; the differences are described in Section 7.7 on page 94.
A symbol is a string of letters or digits, the first of which must be a letter. The characters β$β,
β_β, β#β, and β@β are considered to be letters in the Assembler Language.51 These special charac-
ters are not allowed in symbols:
( ) + - * / = . , ' & blank
Early Assemblers restricted symbols to at most eight characters, which is why the βcustomaryβ
operation field of a statement begins in column 10. HLASM allows mixed-case symbols up to 63
characters long, but there is no difference between upper and lower case letters. Thus, NAME, Name,
and name all refer to the same symbol.
50 Internal symbols are added to the object module if you specify the Assembler's 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.
51 If there's 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 representa-
tions. Other characters usable in Assembler Language symbols β those in Table 13 on page 87 β always have the
same EBCDIC representations.
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.52 Of these, the value and
length attributes are most important; the rest will be described as needed. The length attribute is
especially useful, and we'll see how it's 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 attri-
butes, 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 relo-
cation 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.53
β’ 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 inter-
esting. 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 78, 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'10'
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.
52 Conditional assembly supports additional attributes: Assembler, Count, Number, Defined, Opcode, and Program.
The Assembler, Opcode, and Type attributes have nonnumeric values.
53 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 93. 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.
Remember: the attributes of the symbols, and the symbols themselves, exist only at assembly
time. They help in producing the object program; internal symbols and their attributes are dis-
carded when the assembly is complete.54
Exercises
7.3.1.(2) + Which of the following are valid symbols? If you think a symbol is invalid, explain
why.
(1) SuperBOY
(2) Captain Major
(3) KillerWhale
(4) Send400$Soon
(5) #@$!
(6) 4Hundred$Sent
(7) ?
(8) (Eight)
(9) @9AM
7.3.2.(2) Some Assemblers (for processors other than System z) allow you to define a symbol
as a string of alphanumeric characters at least one of which must be a letter (it needn't 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?
The most important part of the Assembler's task of converting a program from Assembler Lan-
guage statements to machine language code is determining the relative positions of all parts of
your program. To do this, the Assembler constructs an accurate model of the program as it will
eventually reside in memory when it is executed.
Because the Assembler cannot determine in advance what memory addresses will eventually hold
the program, it must produce a machine language program that will work correctly no matter
where it is placed at execution time. That is, the program must be relocatable. Thus, in building
its model of the final form of the program, the Assembler only needs to determine the relative
positions of the parts of the program it is assembling.
The Assembler doesn't know where the program will eventually be placed in memory, so it does
the next best thing:
54 This information can be saved in a SYSADATA βside fileβ when you specify the Assembler's ADATA option.
In practice, very few parts of a program depend on knowing actual addresses; these will almost
always involve the use of address constants; we'll introduce them in Section 12.2 on page 147.
Many programs can be written to contain no address-dependent information.
The relationship between locations and addresses is close; they differ at most by a single constant
value, the difference between the Assembler's assumed assembly-time starting location and the
Supervisor's assigned execution-time starting address. This difference is handled by the Program
Loader when it relocates the program just before execution, so we don't have to worry about this
at assembly time. 55
To assign locations to the various parts of your program as it is assembled, the Assembler main-
tains an internal counter called the Location Counter, or LC. The initial value of the LC is the
βinitial locationβ or βassumed originβ specified on the START statement (see Section 6.4 on page
79); or, if no initial location is specified, the Assembler assigns an initial LC value of zero.
As the Assembler reads your program, it determines how many bytes will be required in the
program for the instruction or data generated for each statement. It adds this number to the LC,
and then reads and processes the next statement. In this way, the Assembler determines the
location and length of each part of the program.
It is important to understand the difference between the Assembler's Location Counter and the
CPU's Instruction Address. The LC is a counter used by the Assembler at assembly time to
determine positions within a program; it goes away when the Assembler is removed from memory
at the completion of an assembly. The IA is a part of the CPU's PSW, and contains the address
of the next instruction to be fetched at execution time; it is always in use whenever any program is
being executed.
55 The Assembler puts the assumed origin into the object module to help the Linker adjust addresses correctly.
There is a simple test to determine whether an internal symbol is relocatable: add a constant to
the initial value of the LC, and re-assemble the program. If the value of the symbol increases by
exactly the same amount, then the symbol is relocatable. If the value doesn't change at all, the
symbol is absolute.
The names of instructions and data areas in a program are relocatable; these are the most frequent
uses of symbols. The numeric value of the relocation attribute of a symbol is assigned by the
Assembler, and can be determined from the Assembler's External Symbol Dictionary, another part
of the object module.
To illustrate how values are assigned to symbols, suppose that when the statement named
GETCONST (on page 90) is read by the Assembler, the value of the LC is X'0007B6'. Then the
symbol GETCONST would appear in the Symbol Table with value X'0007B6'; it would be relocat-
able; and because the statement specifies an RX-type instruction, the length attribute will be 4.
Before reading the next statement, the Assembler increments the LC by the length of the instruc-
tion, so that its value will then be X'0007BA'.
Similarly, if the sample statement named TEN (on page 90) was encountered when the LC value
was X'012D88', then the value of the symbol TEN would be X'012D88'; it would be marked as
relocatable; and its length attribute would be 4. The LC value after incrementing would be
X'012D8C'.
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 89 will be assigned a length attribute of 4 by the Assembler.
What is the length of the symbol?
Assembler symbols
Assembler Language symbols are not variables. There are no βvariablesβ
in the Assembler Language we're describing!56
Some of the differences in the meanings of symbols in high-level languages and Assembler Lan-
guage are shown in Table 14.
We will have more to say about this in Section 13.8 on page 173.
56 The conditional assembly language does have variable symbols, but that topic is beyond what we're discussing now.
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 sepa-
rated by commas. For example, a typical instruction statement might look like this:
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 opera-
tors.
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 Assem-
bler's 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, mul-
tiplication, 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 Assem-
bler can distinguish these two uses.
8.2. Expressions
An expression is an arithmetic combination of terms and operators. In the absence of unary plus
or minus signs or parentheses, an expression must begin and end with a term, and there must be
an operator between each pair of terms. To illustrate, two expressions are
GETCONST+X'4A' and X+L'X
The following expression uses all four types of self-defining term:
X'12'+C'.'-B'0001010001'+7
Parentheses may be used, as in ordinary mathematical use (and as in familiar procedural lan-
guages) to indicate groupings. In evaluating expressions, an expression in parentheses is treated as
a term. Thus
(A+2)*(X'4780'-JJ)
is an expression that is the product of two subexpressions, each of which has two terms and one
operator.
Syntactically, an expression may not contain two multiplication or division operators in suc-
cession, or an addition or subtraction operator followed by a multiplication or division operator.
For example:
*+2 valid because * is a Location Counter reference
-A, +A are valid uses of unary + and -
A++B, A--B, A+-B, A-+B are valid (second + and second - are unary operators)
A/+B, A/-B, A*+B, A*-B are valid (+ and - are unary operators)
A+/B, A-/B, A+*B, A-*B are invalid
A**B, A*/B, A/*B, A//B are invalid
Some syntactically valid expressions might not be evaluatable if either or both terms is relocatable
(to be described shortly).
Exercises
8.2.1.(2) What would you expect to be the result of A--B, A+-B, and A-+B?
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. A+-+-B
b. A*--B
c. A-*-B
d. A---B
e. --A-++B
The details of the rules can be rather complicated, so don't try to grasp everything on a first
reading. The examples on page 100 will help to illustrate the rules.
1. Each term (along with any preceding unary operator) is evaluated to word precision, 32 bits.
The relocation attribute of each term is noted, so that the relocation attribute of the entire
expression can be evaluated also, as described in rule 10 below.
2. Inner parenthesized subexpressions are evaluated first, using 32-bit two's complement arith-
metic. The resulting value is used in computing the rest of the expression. Thus in
(X'100'+2*(ABS425-420))+1
where ABS425 has value 425 (as defined on page 93), the subexpression (ABS425-420) would be
evaluated first. The value of the whole expression is X'0000010B', and is absolute.
3. Multiplications and divisions are done before additions and subtractions. Thus the value of
the expression just given would be evaluated as (X'100'+(2*(5)))+1 and not as
((X'100'+ 2 ) * ( 5 ) ) + 1 . Multiplication and division operators may not be combined, as in /*
and */.
4. Relocatable terms or subexpressions may not occur in multiplication or division operations.
5. Operations are performed in left-to-right order within a group of operations of the same pri-
ority. Thus 5*2/4 means the same as (5*2)/4, not 5*(2/4); similarly, 5/2*4 means the same as
(5/2)*4, not 5/(2*4).
6. Multiplications yield a 64-bit result, of which the rightmost 32 bits are kept, and the high-
order (leftmost) 32 bits are discarded. Significant bits can be lost if the product is too large.
7. Division always yields an integer result; the Assembler always discards remainders when eval-
uating expressions. Thus 5*2/4 has value 2, and 5*(2/4) has value zero. Division by zero is
permitted, and the result is simply set to zero.
In general, you can determine the relocatability of an expression roughly as follows: first, compute
the value of the expression. Second, add some constant to the initial value of the LC, which will
cause the values of relocatable symbols to change. Third, recompute the value of the expression
using the new values of the symbols. If the new value of the expression is identical to the old
value, the expression is absolute; if the values differ by the amount added to the LC, the
expression is simply relocatable; otherwise it is complexly relocatable.
To summarize the rules for combining terms, let A and R represent respectively an absolute and a
simply relocatable expression. The rules for combining terms are summarized in Table 15.
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. We'll give a precise definition of the relocation attribute in Chapter X when we discuss
external symbols.
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 98 states that the Assembler always discards remainders in evaluating
expressions. Does this mean that a program cannot compute a remainder? Explain.
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?
The example of a machine instruction statement in Figure 30 on page 78 could have been written
LOAD LR C'45'-(7*X'2A36')+ABS425*B'11111'-235,18/(Q-Q)+3
though the gain in clarity is not obvious. More reasonable usage is illustrated in the following
statements.
* EXAMPLE 8_4_1
R7 EQU 7
R3 EQU 3
LOAD LR R7,R3
Example 8_4_1 is equivalent to the two below. (The second is considered poor style, for obvious
reasons.)
* EXAMPLE 8_4_2 * EXAMPLE 8_4_3
ZORCH EQU 3 R7 EQU 3
ZILCH EQU 7 R3 EQU 7
LOAD LR ZILCH,ZORCH LOAD 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
need a symbol NBits whose value is the number of bits in the same table. We could define the
symbols in the following way.
100 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
* Example 8_4_4 EQU with expressions
NWords EQU 75 Table has 75 word entries
BitsWd EQU 32 Number of bits per word
NBits EQU NWords*BitsWd Number of bits in the table
Exercises
8.4.1.(2) What are the values of the symbols NWords, BitsWd, and NBits in Example 8_4_4
above?
8.4.2.(3) + The following short program segment contains instructions (whose purpose is of no
interest for this exercise) whose operand fields contain various expressions. For each expression,
determine (1) whether the expression is absolute or relocatable, and (2) the value of the
expression. The column headed βLOCβ gives the hexadecimal value of the Location Counter
for each instruction.
LOC Statement
466 A L 4,B+X'1C'
46A BALR R6,0
46C B ST 4,C-A+X-2*(R6/2)
470 C SLL 5,2*C'-'-C'A'+2
USING B-2,R6-2
R6 EQU 9
474 X DS 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 100. Determine the value and
relocation attributes of the following expressions.
(1) REL1+C'2'/2
(2) REL1-REL2+ABS425
(3) C'45'-(7*X'2A36')+ABS425*B'11111'-235
(4) (8/(REL2-REL1)/X'107C')+3
(5) ABS425/((REL2-REL1)/X'C701'+3)
(6) *+ABS425*(*-REL1-4900)
8.4.4.(2) Assuming that the symbols REL1, REL2, and ABS425 have the attributes defined on page
100, determine the validity of each of the following expressions. Explain why you think any
expression is invalid.
(1) -2+ABS425
(2) ((REL1))*2-2*((REL1))
(3) REL1+C'7592'*B'10110'+ABS425
(4) B'10221'+REL2
(5) ABS425*74239661-2
(6) +X'1875'
(7) -*+REL2
(8) **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 X'00172B9E' and X'00173AA6' respectively. Determine the
value and relocation attributes of the following expressions.
(1) B-A
(2) A+C'.'
(3) (A+X'00FFF')-(B-B'1101011100001')
(4) (B-A)/10
(5) B+C'B'/(B+B'101'-B)
8.4.6.(3) + The symbols SAM and JOE are simply relocatable with the same relocation attribute,
and have values X'00174D0A' and X'0016FB63' respectively. The symbol BOB is absolute and has
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 100?
8.4.8.(1) The symbols A and B are relocatable, and have values X'00172B9E' and X'00173AA6'
respectively. Determine the value and relocation of these expressions:
1. B-A
2. A+C'.'
An operand of a machine instruction statement has only one of three possible formats:
expr expr1(expr2) expr1(expr2,expr3)
where βexprβ is an abbreviation for βexpressionβ, and the subscripts indicate only that each expr
can be different from the others. To repeat: operands of machine instruction statements have one of
these three formats.
The third operand format has two interesting features. First, the comma between the second and
third expressions does not terminate the operand; it merely separates the expressions within the
parentheses. Second, the first of the expressions within the parentheses, expr2, may sometimes be
omitted, so that
expr1(,expr3)
is a valid form of the third operand format. The Assembler will assume that the omitted
expression is absolute and has value zero. The format expr1(expr2,) is never valid.
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,
102 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
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 100) 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) A+B(5)
(2) A+(B+(5))
(3) A+C'('(C')')
(4) A(C',C')
(5) 7+(X'BAD'/B'01101')
(6) (C'(')(C'),',(C'(,)'))
(7) 0-0(0,0)
(8) 0/0(,0*0)
(9) C'''(A)'*C'A('(C')'')'-X'C'*C'X)')
57 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.)
We haven't 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 don't work? (Some test cases you might
try are L'2, L'(*-10), L'*, L'ABS425, L'425, L'=F'1', and L'L'*.)
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:
104 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
A Equ 5
B Equ 3
C1 Equ L'A*B
C2 Equ A*L'B
C3 Equ L'(A*B)
Try some similar expressions and see what happens.
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 don't 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.
106 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
1. Not all of the 64 available bit combinations between X'00' and X'3F' are used as actual oper-
ation codes. For example, IBM has promised not to use X'00' as an operation code. 58
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.
The numeric subscripts β1β and β2β in the quantities βR1β and βR 2β distinguish the operand
being referenced. Using the terms βfirst operandβ, βsecond operandβ, etc. consistently will help
you remember what actions are being performed by each instruction.
To explain the notation βR 1,R 2β, refer to the example of a machine instruction statement in
Figure 30 on page 78, where the operation and operand field entries were βLRβ and β7,3β,
respectively. In this case, the βR1β operand is β7β and the βR 2β operand is β3β. The quantities
R 1 and R 2 must be absolute expressions between 0 and 15. Thus, we could just as well have
written
LOAD LR X'7',B'11'
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 52. Table 17 shows the positions of the register specification digits.
opcode R1 R2
Table 17. RR-type instruc-
tion
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 on page 106 shows that the operation code
corresponding to the mnemonic LR is X'18', so the two-byte instruction generated by the Assem-
bler would be X'1873'.
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.
58 X'00' 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 X'0000'
halfword in a program to force it to stop at an exact position so the contents of registers and memory can be veri-
fied.) Also, programs like debuggers sometimes use X'00' as βbreakpointsβ to halt instruction tracing at a specified
place.
59 Some instructions have only one or even no explicit operands!
Exercises
9.2.1.(2) + Which of the following are valid register operands for an RR-type instruction?
(1) 0, (2) B'1101', (3) X'11', (4) 4*(X'F2'βC'0')/5+X'E', (5) 4*(X'F2'βC'0')/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?
The format of an RX-type instruction was shown in Table 7 on page 52. We now look at the
parts of the instruction in Table 19 and describe Assembler Language techniques for specifying
them.
opcode R1 X2 B2 D2
Table 19. RX-type instruction
108 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
As noted when we reviewed addressing in Section 5.3 on page 63, 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.
Suppose we wish to specify explicitly the values assigned to X2, B2, and D 2: then, we write the
second operand (the βaddress-specificationβ) as
D2(X2,B2)
which is the third of the possible operand formats described in Section 8.5 on page 102. The
instructions in examples 4, 5, and 6 of Section 5.4 on page 65 could be written as shown in
Figure 34, where the assembled form is on the left, and the Assembler Language machine instruc-
tion statement is in the center; the displacements have the same value in each instruction.
Compare the machine language form of these three instructions to the fields in Table 19 on
page 108.
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 we'll see!).
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
The only way the Assembler can decide among the four forms of address specification in Table 20
on page 109 is (1) by noting whether a left parenthesis follows the first expression (if not, the
address is implied), and (2) if there is a left parenthesis, by noting whether a comma appears
before the matching right parenthesis (if so, the address is explicit). There is of course no effect of
commas and parentheses in character self-defining terms.
It helps to remember that implied addresses almost always involve relocatable expressions, and
explicit addresses always involve absolute expressions. Sometimes we accidentally use a relocatable
expression where it should have been absolute, or an absolute expression where it should have
been relocatable. The Assembler usually (but not always) diagnoses such errors.
The most common form of address specification is an implied address, where the Assembler com-
putes the proper displacement for us. While we have now seen implied addresses in the context of
RX-type instructions, they are used in many other instruction types.
Exercises
9.5.1.(2) In Table 20 on page 109, 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
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.
110 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
1. B+X'1C'
2. C-A+B-2(N/2)
3. 2*C'-'-C'A'+2(N+N)
4. B-A((B-A)/2,((B-A)*2))
5. C'A'+A(C','-99)
6. N+N(,N)
9.5.3.(2) Assume that each of the operands in Exercise 8.5.1 on page 103 is used in an RX-type
instruction. Using the rules in Section 9.5, determine whether the addresses are explicit or
implied.
Some instructions (like βShift Doubleβ) require a register operand to be an even number.
The RS-type instruction format is similar to RX-type format, except that the X2 field is replaced
by an R 3 field, so no indexing is performed when Effective Addresses are formed.
opcode R1 R3 B2 D2
Table 22. Typical RS-type instruction
The operand fields of Assembler Language instructions specifying RS-type instructions are shown
in Table 23 on page 112. 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.
SI-type instructions are different. The I2 operand is contained in the second byte of the instruc-
tion, as in Table 24:
opcode I2 B1 D1
Table 24. Typical SI-type instruction
Table 25 gives the operand fields of Assembler Language statements involving SI-type
instructions:
SI D 1(B1),I2 S1,I 2
Exercises
9.7.1.(2) The following are operand fields that 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 compo-
nents of the instruction to which each expression applies. State which expressions specify
explicit addresses and which specify implied addresses.
(1) 1(2),3
(2) 4,5(6)
(3) 7,8,9
(4) 10,11
(5) 14,15(16)
(6) 100,101
112 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
9.8. Typical SS-Type Instructions
Table 26 shows some examples of popular SS-type instructions. The column headed βLenβ
shows the number of length fields in the instruction.
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. We'll learn about them in Chapter VIII.
As with explicit and implied addresses, you can also specify explicit and implied lengths in SS-type
instructions. When we use implied lengths the Assembler determines the values put into the
length fields of the instruction, often by using the length attribute of a symbol. Implied lengths
are very useful, and we'll see many examples.
opcode L1 B1 D1 B2 D2
Table 27. Typical type SS-1 instruction with one length field
Addresses and lengths may be specified explicitly or implicitly, as summarized in the following
tables. First, we examine the single-length instructions.
The Assembler generates the value of L1 by subtracting 1 from the value of N1 (unless N1 is
zero). We'll see why this is done when we discuss SS-type instructions starting in Section 24.
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.
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. We'll see these again in Chapter VIII.
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.)
(1) 1(2)
(2) 4(5,6)
(3) A(L'B)
(4) Line
114 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
(5) Line(80)
(6) 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.
11 00000000
111 0000000000
1111 00 00
11 00 00
11 00 00
11 00 00
11 00 00
11 00 00
11 00 00
11 00 00
1111111111 0000000000
1111111111 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?β
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. (We'll 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 on page 117, the assembled contents of memory will be hexadecimal machine language
data, as shown in Figure 36 on page 118. Suppose the Program Loader has relocated the
program so that the first instruction (the BASR) was placed at memory address X'5000'.
61 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 and 64-bit addressing modes.
116 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
Address Name Operation Operand Remarks
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 con-
tents 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, we'll 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.
We can determine the proper displacement in the L instruction at X'5002' by using two important
values: the known contents of register 6 (X'00005002') and the address of the word area named N.
Using these values, we can now compute a displacement:
X'00005024' β X'00005002' = X'022'
Then, the assembled machine language instruction (using opcode X'58' for the mnemonic L) will
be X'58206022'. When this instruction is executed, its Effective Address is
X'022' + X'00005002' = X'00005024',
the address of the word named N that we want!
If we continue this way for the rest of the statements, the βassembledβ machine language
instructions and data will give the desired results at execution time. That is, after program loading
is complete, we want the memory areas starting at address X'5000' to contain the (hexadecimal)
machine language data shown under βAssembled Contentsβ in Figure 36 on page 118.
Remember that when the Assembler processes the BASR statement and produces two bytes of
machine language code containing X'0D60', 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, let's suppose the same program segment
begins at memory address X'84E8', as in Figure 37.
Address Statement
After executing the BASR, register 6 contains X'000084EA'. To address the contents of the word
named N using register 6 as a base register, the necessary displacement is
X'0000850C' β X'000084EA' = X'022'
After completing the three addressing halfwords, the assembled machine language program would
appear in memory as shown in Figure 38.
84E8 0D60
84EA 58206022
84EE 5A206026
84F2 50206022
-----------------
850C 00000008
8510 00000001
Figure 38. Same program segment, with assembled contents
The identical machine language program is generated in both Figures 36 and 38. We see that so
long as the same fixed relationship is maintained among the various parts of the program segment
(there are 22 bytes between the ST instruction and the word named N), the program segment
could be placed anywhere in memory and still execute correctly. That is, the program is relocat-
able.
118 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
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 X'00000002', and the displacements would be calculated exactly as before.
This example has two shortcomings. First, calculating displacements in advance is tedious (espe-
cially 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 displace-
ments.
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 93, 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 X'0002', X'0024', and
X'0028', respectively.
The key to this example is that when the program is executing, the base register (register 6) con-
tains the address of the instruction named BEGIN. We use this observation to rewrite the program
segment, as shown in Figure 40.
We have eliminated both of the shortcomings of the program segment in Figure 39: the displace-
ments 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).
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.
We now rewrite the sample program segment of Figure 40 on page 119 to include the USING
statement in Figure 41.
BASR 6,0
USING BEGIN,6
BEGIN L 2,N
A 2,ONE
ST 2,N
-----------------------
N DC F'8'
ONE DC F'1'
Figure 41. Program Segment with USING Instruction
If the initial LC value is zero, the value of the symbol BEGIN will be X'0002', and the values of the
symbols N and ONE will be X'0024' and X'0028' 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:
X'0024' β X'0002' = X'022'
and this is the required displacement.
Similarly, the implied address of the operand ONE of the A instruction has value X'0028'; when
the base_location value is subtracted, we find the displacement is X'026', as before. We say that
the Assembler has resolved the implied addresses of the L, A, and ST instructions into base-
displacement 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 displace-
ments and assigns base registers is described starting in Section 10.8.)
62 Section 20 describes long-displacement and relative-immediate instructions with a larger range of displacement values.
120 Assembler Language Programming for IBM System zβ’ Servers Version 2.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 120 should be noted.
1. The USING instruction does absolutely nothing about actually placing an address into a reg-
ister; it merely tells the Assembler what to assume will be there when the program is exe-
cuted.
That is, your USING statement is a promise to the Assembler that if it computes displace-
ments for you, everything will work properly when the program is executed. (It is very easy
to mislead the Assembler, as we'll see in Section 10.11 on page 129.)
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.
A common technique for specifying base registers in a program is to choose a base register, write
the statements
BASR reg,0
USING *,reg
at the beginning of the program, and then carefully avoid modifying that register. For simple pro-
grams, specifying and using base registers is very easy.
It's important to remember that while the value of β*β changes as your program is assembled, the
value used in the first operand of the USING statement does not: it has the value of the LC at
the time the USING is processed by the Assembler.
Exercises
10.5.1.(2) + A careless programmer inverted the order of his BASR and USING statements as
follows:
USING *,12
BASR 12,0
Why is this wrong? What would you expect to happen?
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
X'5000', so that when the L instruction is executed, register 6 contains X'00005002'. Now, the L
instruction copies a word from memory at the address given by the second operand into the reg-
ister 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 X'00000008' and not X'00005002',
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
X'026' + X'00000008' = X'0000002E'
and not X'00005028', 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 2's initial (and unknown) contents.
Finally, the ST instruction will attempt to store a word at X'0000002A', 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 X'5000', what
would be in that area of memory after the ST instruction is executed?
122 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
10.7. Calculating Displacements: the Assembly Process, Pass One
Now, we'll examine more closely how the Assembler computes bases and displacements.
You can visualize assembly as making two passes over the program: that is, the Assembler
βreadsβ the program twice. On the first pass, the Symbol Table is built; on the second pass, data
in the Symbol Table is used to help generate the desired instructions and data.
First, you will remember that values are assigned to symbols by the Assembler as follows:
1. A statement is read and examined to determine its general character. It is also saved in a
temporary place so it can be read again during the second pass over the program.
2. If the statement will generate instructions or data, the Assembler adjusts the Location
Counter (if necessary) to satisfy alignment requirements, so that instructions begin on
halfword boundaries, words begin on word boundaries, etc.
3. If a symbol appears in the name field of the statement, it is entered into the Assembler's
Symbol Table, and (if it is not an EQU statement) is given the value of the Location
Counter. That is, the symbol is defined, as described in Section 7.6 on page 93. (Of course, it
will be an error if the symbol is already in the table with a value; this is called multiple or
duplicate definition.)
4. The rest of the statement is scanned; if any other symbols are encountered, they are entered
into the Symbol Table (if not there already), but numeric values are not assigned to their
attributes. That is, if the symbol is not yet defined, it remains βundefinedβ.
5. The length of the instruction or data to be generated from the statement is then added to the
Location Counter. No data or instructions are generated at this time, however.
This process is repeated for each statement, until the end of the program is reached. Because the
Assembler has made a complete scan or βpassβ over the program's statements, this is called βPass
Oneβ of the assembly. At this point the Symbol Table contains all the symbols in the program,
whether or not they are defined.
The first assembly pass is sketched in Figure 43 on page 124, but the sketch is incomplete in
many ways. For example, an EQU statement lets you assign a value to a symbol, and that value
is taken from the expression in the operand field. Figure 43, however, only shows values being
assigned to symbols using the Location Counter. It also omits any description of macro-
instruction statements, and how symbols are treated in erroneous statements.
Exercises
10.7.1.(2) In the following program segment, resolve the implied addresses into base-
displacement form, and fill in the four blank fields.
Loc Object Code Statement
124 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
10.8. Calculating Displacements: the Assembly Process, Pass Two
The Assembler now begins a second pass over the program by retrieving the statements from their
temporary storage place. The Assembler creates machine language object code, converting
instruction mnemonics to operation codes and using data in the Symbol Table to evaluate all
expressions appearing in the statements.
The overall flow of the second pass of the assembly process is sketched in Figure 44. As noted
following Figure 43 on page 124 describing the first pass of the assembly, this is a very abbrevi-
ated description, so don't attach great significance to the precise sequence of processing actions
implied by the diagram.
βββββββββββββ
βββ
β€Read, Printβββ¬βββββββββββββββββββββββββββββββ
β statement β
β ββββββ¬βββββββ β β
β β β
β βββββ΄βββββyes β β
β βcomment?ββββββ β
β βββββ¬βββββ β
β no β
β βββββ΄βββββyes βββββββββββββββββββββββββββ β
β β USING ?ββββ
β€enter data in USING Tableβββ
ββ€
β βββββ¬βββββ βββββββββββββββββββββββββββ
β no β
β βββββ΄ββββyes βββββββββββββββββββββββββββββββ β
β β DROP ?ββββ
β€delete entry from USING Tableβββ
β βββββ¬ββββ βββββββββββββββββββββββββββββββ
β no
β ββββ΄ββββyes βββββββββββββββββββββββ
β β END ?ββββ
β€Create object module;β
β ββββ¬ββββ βreturn to Supervisor β
β βno βββββββββββββββββββββββ
β
β βββββ΄βββββββββyes ββββββββββyes βββββββββ
β βmachine ββββ
β€implied ββββ
β€computeβ
β βinstruction?β βaddress?β β value β
β βββββ¬βββββββββ ββββββββ¬ββ βββββ¬ββββ
β no no
β βββββ΄ββββββyes βββββββββ β ββββββββββ΄βββββββββββββ
β βdefine a ββββ
β€convertβ β βcheck USING Table forβ
β βconstant?β β data β β βa valid displacement β
β βββββ¬ββββββ ββββ¬βββββ β βββ¬ββββββββββββ¬ββββββββ
β no β OK none
β βββββββ΄βββββ β βββββ βββββββββ΄βββββββ
βββ€note errorβ β βaddressabilityβ
ββββββββββββ β β β error β
β βββββββββββββββββββββ΄βββββββ΄ββ βββββββββ¬βββββββ
ββββ€Generate instruction or dataββββββββββββββ
ββββββββββββββββββββββββββββββ
Figure 44. Sketch of pass two of an assembly
When a USING statement is encountered, the Assembler enters the value and relocation attri-
butes of the first operand expression (the base_location), and the value of the second expression
(the base_register number), into a USING Table.
Figure 45 on page 126 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
βββββββββ¬ββββββββββββββββ¬βββββ
βbaseregβ base_location β RA β
βββββββββΌββββββββββββββββΌβββββ€
β 6 β 00000002 β 01 β
βββββββββ΄ββββββββββββββββ΄βββββ
Figure 45. USING Table with one entry
When a subsequent instruction operand contains an implied address, the Assembler compares the
value and relocation attribute of that expression to each entry in the USING Table. If a matching
relocation attribute is found, and a valid displacement can be calculated from
displacement = (implied address value) β (base_location value)
then the Assembler inserts the computed displacement and the corresponding base_register digit
into the addressing halfword of the instruction. The Assembler has resolved the implied address
into base-displacement form, and the implied address is addressable.
For example, consider the second and third statements in Figure 41 on page 120. 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 X'00000002', the value of the symbol
BEGIN illustrated in Figure 45.
When the third statement in Figure 41 on page 120 is processed, the value of the implied address
is the value of the symbol N, or X'00000024'. The computed displacement is
X'00000024' β X'00000002' = X'022'
as we saw previously, so the completed addressing halfword is X'6022'.
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β.
126 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
Loc Object Code Statement
For now, we ignore the fact that the contents of register 7 are unknown.
When the second USING is processed, the value of the Location Counter is X'00000006', so the
Assembler makes a second entry in the USING Table, as shown in Figure 47.
βββββββββ¬ββββββββββββββββ¬βββββ
βbaseregβ base_location β RA β
βββββββββΌββββββββββββββββΌβββββ€
β 6 β 00000002 β 01 β
βββββββββΌββββββββββββββββΌβββββ€
β 7 β 00000006 β 01 β
βββββββββ΄ββββββββββββββββ΄βββββ
Figure 47. USING Table with multiple entries
The Assembler must make a choice: which of the two valid resolutions should be selected for the
completed machine language instruction?
00000 0D60
00002 58206022 Based on register 6
00006 5A207022 Based on register 7
0000A 5020701E Based on register 7
-----------------
00024 00000008
00028 00000001
Figure 48. Assembled contents when two USINGs are active
At this point, you could (correctly) observe that this program is seriously flawed, because the con-
tents of GR7 at execution time could be βanythingβ. When the A and ST instructions are exe-
cuted, 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 infor-
mation 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.
128 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
βββββββββ¬ββββββββββββββββ¬βββββ
βbaseregβ base_location β RA β
βββββββββΌββββββββββββββββΌβββββ€
β β empty β β
βββββββββΌββββββββββββββββΌβββββ€
β 7 β 00000006 β 01 β
βββββββββ΄ββββββββββββββββ΄βββββ
Figure 49. USING Table after D R O P statement
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 X'4000'.
BASR 9,0
USING *,9
L 4,*+54
BASR 10,0
USING *,10
L 3,*+52
DROP 9
L 2,*+48
DROP 10
L 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?
βββββββββ¬ββββββββββββββββ¬βββββ
βbaseregβ base_location β RA β
βββββββββΌββββββββββββββββΌβββββ€
β β empty β β
βββββββββΌββββββββββββββββΌβββββ€
β β empty β β
βββββββββ΄ββββββββββββββββ΄βββββ
Figure 50. USING Table after second D R O P statement
Because there are no entries left in the USING Table, there is no way for the Assembler to
resolve the implied addresses of any following instructions, and an addressability error would
be noted for those statements.
Exercises
10.11.1.(3) + Suppose these instructions are assembled and then executed in a program:
B BASR 6,0
USING *,6
L 2,B
What (if anything) would you expect to appear in GR2?
βββββββββ¬ββββββββββββββββ¬βββββ
βbaseregβ base_location β RA β
βββββββββΌββββββββββββββββΌβββββ€
β 0 β 00000000 β 00 β Assembler's hidden USING-Table entry
βββββββββΌββββββββββββββββΌβββββ€
β β β etc. β ββ β
βββββββββ΄ββββββββββββββββ΄βββββ
130 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
Thus, an implied address such as
LA 3,1000 Implied address = 1000 = X'3E8'
would be resolved to the addressing halfword X'03E8', with base register zero.
In the example in Figure 34 on page 109, 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 Base Address = 400 = X'190'
LA 3,1000 Implied address = 1000 = X'3E8'
so the USING Table would look like this:
βββββββββ¬ββββββββββββββββ¬βββββ
βbaseregβ base_location β RA β
βββββββββΌββββββββββββββββΌβββββ€
β 0 β 00000000 β 00 β
βββββββββΌββββββββββββββββΌβββββ€
β 9 β 00000190 β 00 β
βββββββββΌββββββββββββββββΌβββββ€
β β β etc. β ββ β
βββββββββ΄ββββββββββββββββ΄βββββ
The Assembler follows its usual resolution rules, and finds that there are two valid resolutions
with addressing halfwords X'03E8' and X'9258'. Since the latter provides the smallest displace-
ment, the Assembler chooses the resolution with base register 9! Fortunately, the Assembler will
issue a diagnostic message whenever a USING with an absolute operand appears to overlap with
its implicit USING 0,0 statement.
If the original resolution using base register zero is required no matter what other USINGs are
active, the operand should be written explicitly, as
LA 3,1000(0,0) Explicit displacement=1000, base=index=0
Thus, we add one further resolution rule when absolute implied addresses have not been resolved
according to the three previous rules:
4. If no previous resolution has been completed, and the implied operand is absolute and has
value between 0 and 4095, use General Register 0 as the base register and the value of the
implied address expression as the displacement.
This behavior is used often in Assembler Language programs. If any implied address has absolute
nonnegative value, a valid displacement can always be computed only if that value does not
exceed 4095.63
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 reloc-
atable, 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 reg-
ister whose base_location is relocatable, since a valid displacement cannot be computed from
(absolute) displacement = (absolute base_location) β (relocatable operand) (??)
63 Section 20 shows how to use a much larger range of displacement values with long-displacement instructions.
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 speci-
fied 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.65
A minor addition to these rules will apply when we discuss instructions with long 20-bit signed
displacements in Section 20.
The relocatability attribute of any given symbol almost always has a single value; it won't matter
if we ignore βcomplex relocatabilityβ situations for now, because they don't 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.
64 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.
65 Some programmers note that βUSINGβ is part of βconfusingβ.
132 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
10.13.1. How the Assembler Helps
The Assembler simplifies many programming tasks:
1. It automatically resolves addresses into the base-displacement and other forms used by
System z. The Assembler determines the needed base and displacement so that correct Effec-
tive Addresses will be computed at execution time.
2. Rather than remembering that operation code X'43' places a byte from memory into the
right end of a general register, a mnemonic operation code IC (βInsert Characterβ) gives a
simple indication of what the operation code does.
3. Symbols let you name areas of memory and other objects in your program.
4. Diagnostic messages help you find possible errors and oversights.
5. The Assembler converts data from convenient external representations into internal forms.
6. It creates relocatable object code to be combined with other programs by the linker.
7. It provides lots of other helpful information such as symbol and register cross-references.
8. Using macro-instructions, you can define your own instruction names to supplement existing
instructions, and your macro instructions can make use of previously defined sequences of
statements, including other macros!
9. The High Level Assembler provides an optional summary of all USING Table activity, in
the form of a USING Map. If you specify USING(MAP) as part of the parameter string when
you invoke the High Level Assembler, it will display all USING and DROP activity for the
entire program.
Exercises
10.13.1.(3) Some older assemblers let you redefine symbols in EQU statements. Thus, you
could write
A Equ 6 Define a value for A
- - - Write statements using A's value
A Equ 32 Define a new value for A
- - - Statements using A's new value
How would the assembler's treatment of the Symbol Table be changed? What would happen if
any symbol could be redefined?
Programming Problems
Problem 10.1.(1) Write and assemble a program segment like the one in Figure 41 on
page 120, with the following additional statements:
1. Following the last DC statement, place an Assembler instruction statement with the mne-
monic 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 X'5000' in the operand field.
Assemble the program, and save the Assembler's listing. Then, replace the X'5000' operand in
the START statement with the X'84E8', 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.
134 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
Chapter IV: Defining Constants and Storage Areas
IIIIIIIIII VV VV
IIIIIIIIII VV VV
II VV VV
II VV VV
II VV VV
II VV VV
II VV VV
II VV VV
II VV VV
II VV VV
IIIIIIIIII VVVV
IIIIIIIIII VV
The three sections of this chapter treat the DC (Define Constant) and DS (Define Storage) assem-
bler instruction statements, and methods used to define data and storage areas in Assembler Lan-
guage programs.
β’ Section 11 describes the Assembler's basic data definition instruction, DC.
β’ Section 12 discusses the most often-used data types, introduces the powerful constant-
referencing 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.
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 we'll describe basic rules for defining constants of any type.
System z 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 (two's complement binary), signed and unsigned
β’ doubleword precision (64 bits)
β’ word precision (32 bits)
β’ halfword precision (16 bits)
β’ byte precision (8 bits)
2. Logical data (binary and hexadecimal)
β’ doubleword (64 bits)
β’ word (32 bits)
β’ one byte (8 bits)
β’ varying-length (1 to 256 bytes)
3. Address-valued (3, 4, and 8 bytes)
4. Character data (1 to 256 bytes) in EBCDIC, Graphic (Double-Byte), ASCII, and Unicode
formats. 66
5. Decimal data (sign-magnitude representation)
β’ zoned decimal (1 to 16 digits)
β’ packed decimal data (1 to 31 digits)
6. Floating-point data (sign-magnitude representation in binary, hexadecimal, and decimal
formats)
β’ short precision (4 bytes)
β’ long precision (8 bytes)
β’ extended precision (16 bytes)
136 Assembler Language Programming for IBM System zβ’ Servers Version 2.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 doesn't really define an unchangeable constant value,
because you can change it at execution time. (It's only constant if you
don't change it!) The instruction might better be called βDefine Data
with Initial Valueβ. We'll see that literals can help you define what
appear to be βtrue constantsβ In Section 13.9 on page 174.
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, opera-
tion, operand, and remarks field entries; the operation and operand field entries are required.
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:
DC H'8' halfword binary integer
DC C'/' character constant
DC X'61' hexadecimal constant
DC B'01100001' binary constant
The last three constants are each one byte long, and contain identical bit patterns.
Important to remember
The binary, character, and hexadecimal self-defining terms use the same
notation as constants of those types. It can be easy to forget that a self-
defining 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 B'11010001',C'J',X'C5'
Constants with decimal values are written as (for example) F-type constants, as in
Of these four parts, only the second (the type) and fourth (the nominal value) are required. In the
example above, F'8' specifies type F and nominal value 8.
The three important modifier types are length, scale, and exponent. 68 Only length will be discussed
here.
DC Operands
This may help you remember the order of of the fields: duplication factor
(d), type (T), modifiers (m), and nominal value (V), where the required
type and value are specified in capital letters: dTmV
The nominal value part of the operand is specified in different ways for different constant types.
For F-type constants, the value is written as a string of decimal digits, preceded by an optional +
or β sign and followed by an optional decimal exponent. For B-type constants, the value is
expressed as a string of binary digits, so F'110' and B'110' are quite different.
The constant type also determines what conversion from external to internal representation should
be performed: the internal representations of F'110' (binary word), X'110' (hexadecimal con-
stant), E'110' (short floating-point), Z'110' (zoned decimal), and P'110' (packed decimal) are dif-
ferent, even though they all have the same nominal value.
138 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
11.3. Boundary Alignment
Many constant types have βnaturalβ boundary alignments. For example, the F-type constant is
naturally word-aligned. Other constant types don't have a natural alignment; Table 32 on
page 153 (Section 12.5) and Table 33 on page 158 (Section 12.8) summarize default alignments
for many common data types.
There is an important relationship between boundary alignment and the presence of a byte-length
modifier, which helps you align constants and data properly.69 This will be discussed shortly, in
Section 11.4.
By default, the Assembler initializes the Location Counter to zero. If you specify an initial LC
value at the start of the program, the Assembler rounds it up (if necessary) to a multiple of eight
to ensure that the program begins on a doubleword boundary. 70 Then, if a constant must fall on a
specific boundary, the Assembler only needs to be sure that the Location Counter is divisible by
the proper power of two (such as 2, 4, or 8) at the location of the leftmost byte of the constant.
The Linker and Program Loader respect this assumed alignment for the beginning of the
program. This guarantees that data and instructions will be aligned on the desired boundaries
when the program is loaded into memory for execution.
Suppose that after a sequence of instructions has been processed, the value of the LC is X'00012E'
(on a halfword boundary). If another machine instruction is assembled at this point, it would
begin on this halfword boundary between two word boundaries. But if the next statement is
instead
DC F'8'
the Assembler must place it on a word boundary to force the desired alignment.
Generating the four bytes of this constant beginning at the halfword-aligned location X'00012E'
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 X'000130' (now word-
aligned) before the word constant is assembled. The LC has value X'000134' after the constant is
processed; it would be X'000132' if automatic alignment was not done.
Automatic alignment is not performed (bytes are not automatically skipped) if:
1. it isn't needed: that is, the LC happens to fall on the desired boundary; or
2. the type of constant specified doesn't 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.71
69 We'll 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β.
70 HLASM provides the SECTALGN option to let you specify even more restrictive boundaries. See the High Level
Assembler Programmer's Guide for details.
71 For details, consult the High Level Assembler Programmer's Guide for the NOALIGN option. However, few pro-
grams use this option.
A length modifier is written immediately following the letter specifying the data type, in the form
Ln or L(expr)
The quantity βnβ is an unsigned, nonzero decimal self-defining term, and βexprβ is a positive
absolute expression enclosed in parentheses. The length modifier specifies the constant's 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.73 For example, the state-
ments
DC FL3'8'
and
DC FL(2*4-5)'8'
both cause the three-byte constant X'000008' 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.
(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,
When a symbol appears in the name field of a DC assembler instruction statement, boundary
alignment affects the symbol's value. Suppose the value of the LC is X'00012E' when each of the
statements in Figure 51 is encountered.
Because no boundary alignment is performed for the first constant, the value of the symbol
Explicit will be X'00012E'. 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, X'000130'.
Symbol definition
When a symbol is defined, it is given its value after bytes are skipped for
boundary alignment.
72 It is also possible to specify a constant's length in bits, using a bit-length modifier. They have specialized uses; we will
describe them in Section 17.5 on page 257.
73 Sometimes the Assembler will let you define symbols after they are used in length modifier expressions, but it's safest
to make sure they're defined before they're used in length modifiers.
140 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
As a general rule, the Assembler never automatically assigns the location of skipped bytes as the
value of a symbol.74 This includes cases where a byte must be skipped to ensure that an instruc-
tion 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) DC FL1'-127'
(2) DC FL2'+128'
(3) DC FL3'-99,+99'
(4) DC FL1'+127'
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
74 You can find ways to do it if you like, but there's no real value in doing so. (Why refer to something so uninter-
esting?)
75 Sometimes the Assembler will let you define symbols after they are used in duplication factor expressions, but it's
safest to make sure they're defined before they're used in duplication factors.
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'
or even
DC 0F,FL4'-1'
Zero duplication factors are discussed further in Section 13.2 on page 160.
This is equivalent to
Three8s DC 3F'8' One operand, duplication factor 3
and
Three8s DC F'8',F'8',F'8' Three operands
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 DC F'1,2,3,4,5,6,7,8,9,10'
Figure 52. Multiple constants
In cases where multiple constants are specified, any symbol in the name field (in this example,
TABLE) is given the value and Length Attribute associated with the first constant generated.
Exercises
11.6.1.(2) A meticulous programmer determined that 10 9 is the largest power of ten that will fit
in a word binary integer, and wanted to define a constant of that value. To ensure that he
wrote the constant with the correct number of zeros, he wrote the statement
TEN_to_9 DC F'1,000,000,000'
What would be generated? What would you recommend?
142 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
11.7. Length Attributes
Although its many benefits will become clear later, we noted in Section 7.3 on page 89 that the
Length Attribute of a symbol can be very useful. Its value is determined by the statement in
which the symbol is defined.
1. The Length Attribute of a symbol naming an instruction is the length of the instruction.
Thus, the Length Attribute of the symbol LOAD in
LOAD LR R7,R3 (from Example 8_4_1 on page 100 in Section 8.4.)
is 2, and the Length Attribute of the symbol BEGIN in
BEGIN L 2,N (from Figure 35 on page 117)
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 F'8' (from Figure 51 on page 140)
Explicit DC FL4'8'
Three8s DC 3F'8'
all have Length Attribute 4.
3. If the symbol names a DC statement whose first operand contains multiple values, the sym-
bol's Length Attribute is the length of the first generated constant, as noted for the symbol
Three8s above. Similarly, the Length Attribute of the symbol TABLE in
TABLE DC F'1,2,3,4,5,6,7,8,9,10' (from Figure 52 on page 142)
is 4, even though the statement defines constants occupying 40 bytes.
4. If the symbol names a DC statement with more than one operand, the Length Attribute
assigned to the symbol is determined from the first operand only, according to the previous
rules. Thus,
TwoCons DC F'2',FL2'-2'
would assign 4 as the Length Attribute of TwoCons.
5. A symbol defined in an EQU statement to have the value of a self-defining term is assigned a
Length Attribute of 1. Thus, the symbol ZILCH in
ZILCH Equ 7 (from Example 8_4_2 on page 100 in Section 8.4.)
has Length Attribute 1. (The EQU assembler instruction is described further in Section 13.3
on page 162.)
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 DC FE1'1E1' Generates X'00000064'
F100B DC FE-1'1E3' Generates X'00000064'
F1000A DC FE-7'1E10' Generates X'000003E8'
FBillion DC FE5'1E4' Generates X'3B9ACA00'
We'll see more about scale and exponent modifiers in Section 32.3, on page 574.
Exercises
11.8.1.(2) Show the constants generated by these statements, indicating which are aligned by
default and which are not.
(1) DC FE1'2E3'
(2) DC FE-1'5E5'
(3) DC FL2E2'1E2'
(4) DC FL4'8E1'
11.8.2.(1) Rewrite the intended constant in Exercise 11.6.1 on page 142 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 Object Code Statement
144 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
Terms and Definitions
boundary alignment
The Assembler's action in incrementing the Location Counter so that its value is adjusted to
the boundary required by an instruction or by a constant operand.
constant type
A letter specifying the internal data representation for a generated constant.
decimal exponent
A letter E attached at the end of the digits of a numeric constant, followed by a positive or
negative integer giving the power of ten by which the value of the digits is multiplied.
duplication factor
The number of times a constant operand should be assembled.
exponent modifier
A modifier specifying a positive or negative power of ten to be multiplied by the nominal
value of a constant.
length modifier
A modifier specifying the exact length to be used for a constant, rather than its default length.
modifier
A value following the constant type, specifying other information about the constant's
Length, Scale, and Exponent.
nominal value
The value you write between delimiters or value separators to specify the assembled value of
a constant.
11 2222222222
111 222222222222
1111 22 22
11 22
11 22
11 22
11 22
11 22
11 22
11 22
1111111111 222222222222
1111111111 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β.
The H-type constant is similar to type F, specifying two's 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' β43Γ10**6, generates X'FD6FDF40'
The decimal exponent specifies the power of ten by which the preceding value is multiplied. You
could define a table of the first six powers of ten with either of the following two statements:
Powers10 DC F'1,10,100,1000,10000,100000'
Powers10 DC F'1E0,1E1,1E2,1E3,1E4,1E5'
Figure 53. F-type constant with decimal exponent
146 Assembler Language Programming for IBM System zβ’ Servers Version 2.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!):
In practice, decimal exponents are used mainly in floating-point constants, which we'll discuss in
Chapter IX.
You may sometimes want to create unsigned or logical binary integer constants, as described in
Section 2.6 on page 25. You can define such integers by preceding the nominal value of the
constant with the letter βUβ, as in these examples:
DC F'U2147483648' X'80000000' +2**31
DC H'U65535' X'FFFF' +2**16β1
DC F'U4294967295' X'FFFFFFFF' +2**32β1
DC H'1,U2' X'00010002' Mixed signed and unsigned
DC H'-1,U32768' X'FFFF8000' Mixed signed and unsigned
No signs are allowed either before or after the βUβ.
Exercises
12.1.1.(1) + In Exercise 11.6.1 on page 142, 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'1E-0,1E-1,1E-2,1E-3,1E-4,1E-5'
What values will be generated?
12.1.3.(2) Suppose you need a halfword constant with value 1/2, so you write
Half DC H'5E-1'
What do you think will be generated?
12.1.5.(2) What would happen to the Location Counter values in Figure 35 on page 117 if
there were now 24 bytes (instead of 22 bytes) between the ST instruction and the first DC
instruction?
A special case where the nominal value of an A-type constant contains a Location Counter Refer-
ence is described in Section 13.6 on page 169.
A-type and F-type constants have similarities: a length of four bytes and word boundary align-
ment are implied. An explicit length suppresses alignment; thus A(10) and F'10' are equivalent
operands, as are AL4(10) and FL4'10'. The major difference is that you can write expressions as
the nominal value of constants like A(X'00012E') and A(1+C'.'). In some contexts, these may be
much more natural or convenient than the equivalent F-type constants F'302' and F'76'.
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') X'00000FFF'
If we had written this DC's operand field as XL4'FFF' instead, we can't 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') X'000000C1'
This is easier to read than F'193', even though the same constant is generated. A constant like
Word DC A(C'WORD') X'E6D6D9C4'
can be used as a word-aligned βcharacterβ constant.
Using such expressions can greatly simplify programming tasks. For example, you can define con-
stants using operands such as
Con425 DC A(ABS425)
where the symbol ABS425 may have been defined in an EQU statement (as in Section 7.6 on page
93) 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 140. 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(X'213'+C'*'-B'11')
2. A(92*X'F')
3. A(5*C'0'/C' ')
76 The name βaddress constantβ can be somewhat misleading, because the generated data need not be an address!
148 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
12.3. Y-Type Address Constants
Y-type address constants bear the same relationship to A-type adcons as H-type constants bear to
F-type constants, except that relocatable Y-type adcons are almost never used. The Y-type adcon
has an implied halfword length and alignment, and is identical to the A-type adcon if an explicit
length is specified. For example, the operands H'10' and Y(10) in DC statements define identical
2-byte constants, and the operands YL1(10), AL1(10), HL1'10', and FL1'10' all generate X'0A'.
If we assume that the symbol Implied is relocatable (as in Figure 51 on page 140), then the
statement
BadCon DC Y(Implied)
would fail at linking time, because 3 or more bytes will be required to hold the execution-time
address of Implied.
Other address constant types are V, S, and Q. V-type constants are very similar to A-type con-
stants, 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. We'll defer these types to later sections.
Exercises
12.3.1.(1) What hex data will be generated by these constants?
DC Y(C'A')
DC Y(X'F'*C'B')
DC Y(B'101'*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 base-
displacement 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?
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. 77 For example, you can define constants as shown in Figure 54.
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
The data generated for character (type C) constants is converted to 8-bit bytes using the EBCDIC
representation shown in Table 13 on page 87. Blank 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 gener-
ated constant, a pair of ampersands or apostrophes must appear in the nominal value between the
delimiting apostrophes. For example:
DC C'''' Generates X'7D'
DC C'&&' Generates X'50'
DC C'&&&&&&''' Generates X'5050507D'
In Section 7 we noted that the value of a character self-defining term is determined by right-
adjusting 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.78
Unlike F- and H-type constants, the implied length of C-, X-, or B-type constants is not a fixed
number. Because no length modifier is present, the two constants
Star1 DC C'*' Implied length = 1
and
Star2 DC 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.
150 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
ManyChar DC C'An example of a very long string of characters intende*
d to illustrate the length attribute of a constant that *
extends over many lines.'
the symbol ManyChar has length attribute 134; you certainly don't want to count the characters in
each line manually (and possibly make a mistake). It's much easier to use the Assembler's
Length Attribute, as in L'ManyChar, and know it's correct.
We will see in Section 27 that the Assembler can generate character constants in other representa-
tions such as ASCII and Unicode.
Exercises
12.4.1.(1) + What are the implied lengths of the constants in Figure 54 on page 150?
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 X'4040405C'. What is repres-
ented by that pattern? (You should be able to describe two different possibilities.)
1. DC C'A''B&&C'
2. DC C'''A&&B''''C'
3. DC C'ABCF'''
12.4.9. What constants are generated by these statements? Explain any differences.
12.4.10. For each of the following sets of statements, the value of the Location Counter is
X'000743' when the Assembler encounters the first statement. Give the value and length attri-
butes of all symbols (but not the generated object code).
(1) A DC AL3(A)
B DC A(8)
1. X'00000345'
2. X'00000159'
3. X'F3F4F540'
4. X'00F3F4F5'
Some examples are given in Table 31, with the generated constants. Most of the padded con-
stants could have been fit into smaller fields, if you needed desperately to save a few bytes.
Truncation Padding
Value too large Assembled Value Value not too large Assembled Value
H'65537' X'0001' (with error!) H'2' X'0002'
FL1'+300' X'2C' (with error!) FL3'-6' X'FFFFFA'
CL3'SMITH' X'E2D4C9' (C'SMI') CL3'S' X'E24040'
XL2'56789' X'6789' X'56789' X'056789'
BL1'100100100' X'24' (B'00100100') B'101' X'05' (B'00000101')
AL2(X'789AB') X'89AB' A(X'789AB') X'000789AB'
YL1(X'124') X'24' Y(X'124') X'0124'
Table 31. Examples of truncated and padded constants
152 Assembler Language Programming for IBM System zβ’ Servers Version 2.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 152, more space is allotted either explic-
itly 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 two's 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'40') to
fill out the constant to the required length of three bytes, generating C'Sβ’β’'.79
As mentioned in Section 12.4 on page 150, 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 con-
stant to ensure that no information is lost, and no more. Thus the lengths of the three constants
in Figure 54 on page 150 are 33, 7, and 5 bytes respectively; no information is lost, and no
padding was required.80
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. (We'll discuss V-type address
constants in Chapter X.)
Type H F Y A V B C X
Maximum Length 8 8 2 4 4 256 256 256
Implied Length 2 4 2 4 4 * * *
Implied Alignment 2 4 2 4 4 none none none
Value Specified by dec dec absexpr expr symbol bin char hex
Delimiters Used ' ' ' ' ( ) ( ) ( ) ' ' ' ' ' '
Truncation, Padding left left left left left left right left
Multiple Values yes yes yes yes yes yes no yes
Note: * The implied length is the minimum number of bytes required to contain the data.
Table 32. Truncation/padding rules for some D C operands
Section 12.8 on page 157 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 dif-
ferent? If so, why?
DC CL2'ABC'
DC AL2(C'ABC')
12.5.2.(2) + Show what will be assembled for each of the following DC statement operands:
(1) F'1000', (2) H'1000', (3) B'1000', (4) XL1'1000', (5) CL1'1000', (6) AL1(1000),
(7) YL3(1000). Describe the boundary alignment of each.
12.5.4.(2) The statement preceding Table 31 on page 152 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 117, 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. 81
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' =C'LongLiteral' =BL2'111101'
=H'1' =CL7'BLANK&&' =X'765432A'
=A(1) =F'1,2,3,4' =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 it's easy to modify βconstantsβ created by the DC assembler instruc-
tion statement without any assembly-time indication. (This error detection at assembly time
is what makes literals βmore constantβ than the βconstantsβ defined by DC statements.)
2. A literal may not be specified in an address constant, so that A(=F'1') is invalid.
3. Multiple operands may not be specified, but multiple values may; thus
LM 1,2,=F'1,2'
is valid, but both
LM 1,2,=F'1',=F'2'
L 1,=H'1',=H'2'
are not, because a literal must be a single operand.
4. The duplication factor may not be zero.
5. The alignment and length of the data described in the literal are implied by the constant type,
so that this L instruction,
L 2,=X'2B'
that copies 4 bytes from memory to GR2, will copy unpredictable data into the rightmost
three bytes of GR2 because we can't know precisely where the Assembler will place the
literal, and what might be in the three bytes following the single byte X'2B'.
154 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
This statement is entirely equivalent to
L 2,X2B
- - -
X2B DC X'2B' (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 109).
7. A literal may be indexed in RX-type instructions, so that
L 0,=F'1,2,3,4,5'(9)
is valid, and is exactly equivalent to
L 0,FiveInts(9)
- - -
FiveInts DC F'1,2,3,4,5'
If the value of the index in GR9 is 8, the L instruction will put the integer 3 in GR0.
8. You may refer to a portion of a literal, as in
IC 0,=F'1'+3
but this is considered a very poor programming practice.
9. In most situations, you can use the Assembler's L' Attribute Reference notation in an
address constant to refer to the Length Attribute of a literal. (Note that this does not violate
rule 2 above!)
The βmessageβ character string is 17 bytes long, but we rarely refer to the Length Attribute of
a literal.
We'll 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 117:
BASR 6,0
USING BEGIN,6
BEGIN L 2,N
A 2,=F'1'
ST 2,N
---------
N DC F'8'
Here, you didn't 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 Assem-
bler's literal table are placed into the program at an appropriate location, and the Assembler then
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 2,=A(*)
L 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.4.(2) + In Figure 55 on page 155, the constant named Message is followed by the word-
aligned A-type constant named MsgLen. How many bytes might be skipped before the A-type
constant?
After dumping the contents of its literal table, the Assembler clears the table. Excessive use of
LTORG instructions in a program with many literals might cause duplicate constants to be
defined. For example,
L 0,=F'1'
LTORG
L 1,=F'1'
LTORG
will cause two identical constants to be generated.
The literals in the literal pool are generated in decreasing order of alignment. Thus, a word literal
like =F'4' will be generated ahead of a halfword literal like =H'2'. This rule applies not only to
literals with implied alignment, but to literals whose length is a power of two. Thus, the literal
=X'00000004' will be generated in the same group as =F'4'.
82 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.
156 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
This alignment difference can sometimes be surprising. These two constants, though identical, will
be aligned differently:
L 2,=FL4'4' Explicit length 4, word aligned
L 2,FL4Const Explicit length 4, not word aligned
- - -
DS F,X Align LC off a word boundary
FL4Const DC FL4'4' Unaligned constant X'00000004'
Though rarely a problem, it's worth remembering the difference.
In the absence of any LTORG instructions, the Assembler will generate any accumulated literals
at the end of the assembly, so you will need to ensure they are addressable.
Remember:
A literal is treated by the Assembler as a special symbol with the addi-
tional effect of causing it to reserve a storage area containing the specified
constant.
While the Assembler tries to diagnose instructions appearing to modify a literal, it's easy for your
program to modify them by writing into the area where they're stored. (In fact, a program can
modify almost anything that's not memory-protected!) You should think of literals as βintendedβ
constants, not as immutable values.
An important enhancement with z/Architecture was the expansion of the 32-bit general registers
to 64 bits, as illustrated in Figure 9 on page 45. To support 64-bit data types, the Assembler
extended several existing data types to provide 64-bit constants. Among these are the F-, A-, V-,
and Q-type constants. This is done by adding a type extension letter following the constant type.
With a βDβ type extension, these constants may be up to 8 bytes long, and by default are aligned
on doubleword boundaries. For example:
DC FD'-1' X'FFFFFFFFFFFFFFFF'
DC AD(C'ABC') X'0000000000C1C2C3'
DC FD'U1E15' X'00038D7EA4C68000'
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 C'ABC' X'C1C2C3' EBCDIC by default
DC CE'ABC' X'C1C2C3' EBCDIC always
DC CA'ABC' X'414243' ASCII always
DC CU'ABC' X'004100420043' Unicode
Other type extensions are used for floating-point data; we'll 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 FD AD VD QD CA CE CU
Maximum length 8 8 8 8 256 256 256
Implied length 8 8 8 8 * * *
Implied alignment 8 8 8 8 none none none
Value specified by dec expr symbol symbol char char char
Delimiters used ' ' ( ) ( ) ( ) ' ' ' ' ' '
Truncation, padding left left left left right right 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
158 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
13. Data Storage Definition
11 3333333333
111 333333333333
1111 33 33
11 33
11 33
11 3333
11 3333
11 33
11 33
11 33 33
1111111111 333333333333
1111111111 3333333333
In this section we examine methods for defining data areas and data structures that simplify pro-
grams manipulating the data, and describe the useful assembler instruction statements DS, EQU,
and ORG.
Exercises
13.1.1.(2) Suppose the value of the Location Counter is X'012345' when the following three
statements are read by the Assembler:
X DS AL(4)
Y DS A(4)
Z DS AL4
What is generated by these statements? What are the value and Length Attributes of the
symbols X, Y, and Z?
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 state-
ments, 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:
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. We'll assume that
1. name-field symbols begin in column 1,
160 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
2. mnemonics start in column 10 and are 5 or fewer characters long,84
3. operands start in column 16 and are less than 20 characters long,
4. remarks lie within columns 36 and 71,
5. column 72 is the continuation column, and
6. columns 73-80 contain sequencing data.
Then, we can name each of the fields of an 80-byte area named Statemnt that contains the state-
ment and assign appropriate Length Attributes, as shown in Figure 57.
β’ 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.
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 reassem-
bled; 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:
84 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.
13.2.2.(3) + Assume the Assembler's Location Counter is X'345' when it reads each of the fol-
lowing sets of statements. For each symbol, give its value and Length Attribute.
β’ J DS 3H
K DS 1X
L DS 0F
β’ P DC C'A''B'
Q DC 2C'ABA'
R DC 2A(C'.')
β’ T DS XL2'234567'
V DC 4Y(37)
W DC 0F'1,2'
13.2.3.(2) + For each of the following, assume that the Location Counter value is X'345' 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. DS 0H
DC C'*'
A DC C'Asterisk'
3. DC 0F'1'
A DC 0XL27'0'
4. A DC A(A)
5. DS 19H
A DC X'12345'
6. DC 3CL4'ABCDE'
A DC C'A&&B'
7. DS CL400
A DC F'12,34,56'
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
NItems DC F'75' Number of words
Table DS 75F Table of words
162 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
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 Equ 75 Define table size
NItems DC A(TblSiz) Number of words
Table DS (TblSiz)F Table of words.
then only the EQU statement would have to be modified before re-assembling. If we also want to
refer to the word in the βmiddleβ of the table, we can write
MidTbl Equ Table+(TblSiz/2)*4
where the factor 4 is the length of each table entry. This illustrates using EQU to define a relocat-
able 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 table's 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. 85 For example, the
second statement in this example is invalid:
X Equ 5 Define X
- - -
X Equ 10 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 DC F'8'
HW8 Equ 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 Equ Table+TblSiz*4/2
MidTbl Equ Table+4*TblSiz/2
MidTbl Equ Table+TblSiz/2*4
MidTbl Equ 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.)
85 Some very early assemblers let you use multiple EQU statements to change the value assigned to a symbol. For
System z 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.
13.3.6.(3) What would you expect to happen when the Assembler encounters the following
three statements?
A Equ B
B Equ C
C Equ A
13.3.7.(2) What would you expect to happen when the Assembler processes each of the fol-
lowing pairs of statements?
ABLE Equ 2
BAKER Equ ABLE+2
13.3.8.(2) + For each of the following two sets of statements, assume that the Location Counter
value is X'01DBC5' when the first statement is encountered. Determine the value, relocatability,
and Length Attributes of all symbols.
1. ST DS 0CL8
W DS 2F
X DS 2F
2. P DS 0F
Q DS 0H
R DC 4X'0'
S Equ *
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 X'291B' in each of these sequences of statements.
Give the value and Length Attribute of the symbol B.
1. A Equ *
X DS 3H
B DS 0F
2. A Equ *
B DC CL3'Okay'
3. A Equ *
F DC F'11,22'
X DC X'123'
B Equ X-A
164 Assembler Language Programming for IBM System zβ’ Servers Version 2.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 X'12345' when the first statement of
each set is read by the Assembler.
1. A DS F
B DS 2H
C DS 2CL2
2. F DC A(F)
G DC 3AL3(F,G,H)
H DC Y(*-F,275)
3. P DC 2C'3&&'
Q DC 2A(C'3&&')
R DS 3XL3'FEDCBA93'
4. X DC 0FL5'5,10,20'
Y DC FL3'5,10,20'
Z DC 2C'5,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 X'01DBC5' when the first statement
of each set is read by the Assembler.
1. STR DS 0CL8
W DS 2F
X DS 2F
2. P DS 0F
Q DS 0H
R DC 4X'40'
S EQU *-P
13.3.14.(3) + For each of the following sequences of statements, assume that the value of the
LC is X'125' 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 DC F'-17'
B DC H'33'
2. D DC FL4'+17'
C DC H'-33'
3. E DC C'ABCDEFGH'
F DC F'1000'
4. G DS 2H
H DC A(X'129E')
5. J DS 0H
K DS 0X
L DS 0F
M DC 0FL6'15'
N DC F'-1000'
6. P DC 3C'A''B'
Q DC 2A(C'A''B')
7. R DS 100F
S DS 10CL80
8. AB DC F'900',HL5'2147483650',H'1'
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, respec-
tively. Write EQU statements to assign the symbols.
13.3.16.(3) In Exercise 13.3.14, some expressions may be difficult for an Assembler to resolve.
Which do you think they are, and why?
13.3.17.(2) + Suppose a symbol A can take values 0 or 1. Write an EQU statement to define a
symbol E whose value is 1 if A is zero, and 0 if A is 1.
13.3.18.(3) + Syppose a symbol A can take any value. Write an EQU statement to define a
symbol E whose value is 0 if A is zero, and 1 if A has any other value.
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 won't 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 XL80
OutRec Equ *,L'InRec Length attribute = 80
166 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
that defines the location of OutRec and its Length Attribute. Note that even though the Length
Attribute of the Location Counter Reference * would otherwise default to 1 in an EQU state-
ment.
Exercises
13.4.1.(2) + Assuming that the symbol Result is at location X'2000', give the value and Length
Attributes of each symbol.
Result DS XL133
Pfx Equ Result,24
Prod Equ Pfx+L'Pfx,12
Cost Equ Prod+L'Prod,8
Desc Equ Cost+L'Cost,60
Fill Equ Desc+L'Desc,(L'Result-L'Pfx-L'Prod-L'Cost-L'Desc)
LFill Equ L'Fill
We can use the ORG statement to rewrite the data area described in Figure 57 on page 161, as in
Figure 59. Note that none of the DS statements uses a zero duplication factor.
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 Statemnt Back to 'column 1'
Column1 DS CL1 To check for asterisks
at the end of Figure 59. Any statements following the last statement in the figure would begin
assembling at Statemnt+1, which is undoubtedly not what you intended.
To rectify such a mistake, you can do either of two things. First, you could place the statement
ORG Statemnt+80 Move LC to end of Statement field
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 161 is generally preferred.
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 167.86
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 DC F'8'
ORG FW8+2
HW8 DS H
Is this better than the technique used in Exercise 13.3.2? Why or why not?
13.5.2.(2) A programmer didn't 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 Assemble somewhere elsewhere
- - -
* Equ Here Set LC back to 'Here'
What is wrong with this technique? Solve his problem without using an ORG statement with a
null operand.
13.5.3.(3) + In each of the three following code segments, the symbol A has value X'982E'.
Determine the value and Length Attributes of the symbol B.
A DS 29H
B Equ A+L'A
A DS 7CL5
ORG A+10
B DS 2D
86 In higher-level languages, the overlaying of one data definition on another is sometimes called a βunionβ or a
βredefinitionβ.
168 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
A DC 0CL40'*'
DS 5CL8,3CL3
B DS 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 DC FL7'8'
ORG A+2
DC HL7'8'
ORG
B DC HL5'-8'
A Equ *
ORG A+4*L'A
DS (C'*')CL(C'*')'*'
B Equ *
13.5.5.(3) Using suitable DC and ORG statements, find a way to cause the Assembler to assign
the location of some skipped bytes as the value of a symbol SKIP3. For example, three bytes
are skipped in
DC F'1',X'2',F'3'
13.5.7.(3) In the instruction sequences illustrated in Figure 57 on page 161 and Figure 59 on
page 167, 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 Equ 80 Define record length
InRec DS CL(RecLen) Space for input record
- - -
OutRec DS CL(RecLen) Space for output record
- - -
WorkRec DS CL(RecLen) Space for record work area
Then, if the length of the record areas must be changed, you need to modify only the EQU
statement and reassemble the program.
2. Suppose a table of five words is stored starting at FTable, and we need to copy the last word
of the table into general register 5. We could do this by writing
L 5,FTable+16 Get last word of FTable
As a final example of symbolically-defined data areas, suppose we have written our own Assem-
bler, 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 symbol's length attri-
bute, (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
170 Assembler Language Programming for IBM System zβ’ Servers Version 2.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.
The program that uses this print line definition will probably need a constant containing the
number of cross-reference entries in the line, so we should also define a constant like
MaxRefs DS Y(NXrefs) Maximum number of references
to be used while the line is being formatted by the program.
Exercises
13.6.1.(2) Suppose the example above that defines the group of words named FGroup was
written
NWords Equ 5 Five-word group this time
FGroup DS (NWords-1)F Space for group
LastWord DS F Reserve space for LastWord
Determine if this definition gives the same or different results.
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 con-
stant: 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 speci-
fies 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 imme-
diately 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 0F
DC 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 Assembler's Location Counter is X'12345' 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 DC C'U&&I'
β’ B DC A(*)
β’ DS 0XL7C
C DC H'137'
β’ D DC (B'10')AL(B'10')(B'10')
β’ E DC C'A( )',A(C' ')
β’ F Equ *
DC 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 byte's offset from the start of the table. For
example, the byte at offset 19 should contain 3, the number of 1-bits in B'10011'. Consider the
following:
172 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
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.
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 F'12' β
βββββββββ ββββββββββββ
The name of the area has attributes such as value, length, and relocatability, all of which are dis-
tinct 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 F'12' β βββββ€ length, val, reloc β
βββββββββ ββββββββββββ ββββββββββββββββββββββ
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.
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 inter-
preted 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.87
In fact, you can define a βconstantβ that is actually a machine instruction. For example, if the
data generated by the statement
DC X'1A22'
is executed as an instruction, it will add the contents of GR2 to itself.
Another source of confusion may be the fact that you can specify a nominal value in a DS state-
ment, as in
NoData DS C'This won''t generate any machine language data'
There are other contexts where DC statements generate no machine language data, such as
Dummy Control Sections (βDSECTsβ) and Common (βCOMβ) sections that we'll discuss in
Chapter XI.
There are also potentially misleading names for machine instructions. For example the MVC
instruction's name is βMove Charactersβ, but its operation actually copies bytes that may or not
be character data.
In summary: don't take the names of assembler and machine instructions too literally. Follow the
old advice to βWatch what they do, not what they sayβ.
87 Some say Assembler Language gives you more βrope you can use to hang yourselfβ, but that's part of what makes
Assembler Language programming fun.
174 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
ORG Extended Syntax
Additional operands on ORG statements that allow LC alignment to a specific power-of-two
boundary, and an offset from that position.
parameterization
A valuable technique for adding flexibility and generality to program definitions, typically by
defining assembly-time constants in EQU statements.
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.
Programming Problems
Problem 13.1.(2) + Write a program to assemble the DC statements in Section 13.7 on page
171, 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 inte-
gers:
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.
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 pro-
grams.
β’ Section 14 discusses typical instructions that move data between memory and the general regis-
ters, and among the general registers. (We'll explore instructions that use data in the Floating-
Point Registers in Chapter IX.)
β’ Section 15 describes the important βBranch on Conditionβ instructions that let you make deci-
sions about alternate execution paths in your program.
β’ Section 16 introduces the instructions that perform binary addition, subtraction, and compar-
ison 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.88 Very few instructions require strict alignment of their operands; we will
point out those instructions that do require operand alignment.
88 Correct alignment is always a recommended practice, so our less-than-precise usage isn't usually harmful.
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 on
page 45 in Section 3.3 that data items in general registers are frequently manipulated in 32-bit or
64-bit lengths.)
We'll sample some typical instructions here; there are others we'll see later. The first two groups
of instructions leave the high-order half of a 64-bit register unchanged, as illustrated in Figure 61.
The high-order half is βinvisibleβ to the first groups of instructions described here. The System z
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
89 We will occasionally use the older term β32-bit general registerβ to mean βthe rightmost 32 bits of a 64-bit general
register.β In System z, 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.
178 Assembler Language Programming for IBM System zβ’ Servers Version 2.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. We'll examine instructions that affect all 64 bits of a register starting in
Section 14.7 on page 189.
We saw these two instructions in several earlier examples; the operand's Effective Address should
be divisible by 4, indicating a word operand.90 Neither instruction changes the Condition Code.
opcode R1 X2 B2 D2
Table 35. Format of an RX-type instruction
β’ The Load instruction L copies 4 bytes of data from memory, starting at the Effective Address,
to bits 32-63 of a general register. When executed,
L R1,D2(X2,B2)
places a copy of the word at the Effective Address of the assembler instruction statement's
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 exe-
cution 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.
90 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 some-
times cause programs to run much slower.
assuming that GR1 is not being used as the program's 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
BBB EQU 8
and
L 5,BBB
BBB DC F'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.
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) R1,R3,D2(B2) (explicit address)
LM (or STM) R1,R3,S2 (implied address)
The components of the assembled instruction are pictured in Table 37.
opcode R1 R3 B2 D2
Table 37. RS-type instruction format
As usual, the assembler instruction statement's R1 and R 3 operands must be absolute expressions
between 0 and 15. The base and displacement may be given explicitly, or derived by the Assem-
bler from an implied address.
180 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
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,
LM 2,6,=5F'0'
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
STM 0,15,SAVE STM 8,7,SAVE
LM 8,7,SAVE or LM 0,15,SAVE
- - - - - -
SAVE DS 16F 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 cor-
rectly, 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 0,0,XXX
ST 0,XXX
14.2.5.(5) Suppose two symbols have been defined with the statements
A EQU 4
B EQU 9
Then, the instruction STM A,B,X stores registers GR4 through GR9 starting at X, and we can
compute the number of registers stored with the statement
NREGS EQU B-A+1
On the other hand, if we had defined A and B with
A EQU 9
B EQU 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.
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.
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 two's 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!
182 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
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
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.91 This is illustrated in Figure 62.
βββββββββββββββββββββ¬ββββββββββββββββββββ
ββ signβextended ββΌs β GR R1
βββββββββββββββββββββ΄ββββββββββββββββββββ
32 48 63
βββββββββββ΄ββββββββββ
βs β Halfword in memory
βββββββββββββββββββββ
0 15
Figure 62. Sign extension by L H instruction
Suppose we execute the instructions in Figure 63. The contents of the registers is given in the
remarks fields of the instruction statements.
The contents of GR0 and GR1 will be different because the quantity in GR0 stored by the
second instruction is too large.
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.
91 We will see many uses of sign extension β copying the sign bit into the higher-order bit positions of a general register
β so it's important to understand its behavior.
14.3.2.(2) Suppose GR1 contains X'12345678'. What will be in GR2 after executing these
instructions?
ST 1,A
LH 2,A+2
Now, suppose GR1 contains X'FEDCBA98'; what will be in GR2 after executing the same
instructions?
14.3.4.(1) What similarities can you find among the opcodes assigned to L, LH, and LM com-
pared to those of ST, STH, and STM?
14.3.5.(3) + The inequality following Figure 62 on page 183 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 183 to test this assertion.
The operand field entry is written as for L and ST, but you need not worry about boundary align-
ment 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.
184 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
βββββββββββββββββββββββββββββββ¬ββββββββββ
βββββββββ unchanged ββββββββ
β β GR R1
βββββββββββββββββββββββββββββββ΄ββββββββββ
32 56 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 char-
acter constant at X, and store them in reverse order at Y.
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:
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 con-
tains in binary the number of one-bits that were present in the original byte. For example, if
the initial contents of XX was X'48', the final contents should be X'02'. (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.)
The final βMβ character on these two mnemonics does not mean βMultipleβ as in LM and STM,
but βMaskβ instead.
opcode R1 M3 B2 D2
Table 41. RS-type instruction format for ICM and STCM
The machine instruction statement operand formats for ICM and STCM are like those of LM
and STM:
ICM (or STCM) R1,M3,D2(B2) (explicit address)
ICM (or STCM) R1,M3,S2 (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) corre-
sponds 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 contig-
uous 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 X'01020304', GR12 contains
X'FFD0A061', and we execute this STCM instruction:
STCM 12,B'0101',AA Store bytes 2 and 4 at AA, AA+1
- - -
AA DC X'01020304'
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 12,AA Store rightmost byte at AA
STH 12,BB Store 2 rightmost bytes at BB
ST 12,CC Store all 4 bytes at CC
behave just like these three STCM instructions:
STCM 12,B'0001',AA Store rightmost byte at AA
STCM 12,B'0011',BB Store 2 rightmost bytes at BB
STCM 12,B'1111',CC Store all 4 bytes at CC
except that now the data areas named by the symbols BB and CC are not expected to be halfword
and word aligned, as recommended for STH and ST. A possible disadvantage of STCM is that it
cannot be indexed, since it is not an RX-type instruction.
The ICM instruction performs the inverse operation to STCM, and also does not expect the
second operand to be aligned; however, ICM does set the Condition Code. As above, suppose the
contents of the four bytes in memory in an area named AA contain X'01020304', and GR12 ini-
tially contains X'FFD0A061'. Then if we execute the instruction
ICM 12,B'0101',AA Insert into bytes 2 and 4 of GR12
- - -
AA DC X'01020304'
the contents of GR12 will become X'FF01A002'.
186 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
If all the mask bits are zero, or if all the inserted bytes are zero, the CC is set to zero. Otherwise,
the leftmost bit of the first byte inserted anywhere into GR R 1 is inspected: if the leftmost bit is a
one-bit, the CC is set to 1; otherwise the CC is set to 2. The settings are summarized in
Table 42.
CC Meaning
0 M 3 = 0, or all inserted bytes are zero
1 Leftmost bit of first inserted byte = 1
2 Leftmost bit of first inserted byte = 0
Table 42. CC settings after ICM instruction
This method of setting the CC is easier to understand if we consider the case when the mask digit
is all one-bits, meaning that four bytes are brought from memory and placed into GR R 1. If we
execute these three instructions, the CC settings are as indicated.
ICM 1,15,=F'0' CC set to 0, c(GR1) is zero
ICM 2,15,=F'-1' CC set to 1, c(GR2) is negative
ICM 3,15,=F'+1' CC set to 2, c(GR3) is positive
Exercises
14.5.1.(2) Write a sequence of two instructions (using ICM and STCM) that will set the CC to
zero if the middle two bytes of GR1 are zero. For example, if c(GR1) = X'A2000064', the CC
should be set to zero.
The action of the first five instructions is summarized in Table 44 on page 188, 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.
The CC is set to indicate the status of the result in GR R 1, as shown in Table 45.
CC Meaning
0 Result is zero
1 Result is negative
2 Result is positive
3 Result has overflowed
Table 45. Condition Code settings
You can see in Table 44 that the actions of LR and LTR are identical except that LTR sets the
CC. We often test the contents of a register by writing instructions like
LTR 4,4
that has no effect other than setting the CC. We test the CC with the important βBranch on
Conditionβ instructions we'll see in Section 15.
For LCR, LPR, and LNR, the arithmetic operations use 32-bit two's 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 27.)
If the overflow condition causes a program interruption, the Interruption Code is set to 8, indi-
cating a Fixed-Point Overflow. 92 No overflow can occur executing LNR because all representable
positive values have valid two's complement representations of their negative values.
We saw in Section 14.5 on page 185 that these three ICM instructions set the Condition Code as
indicated in the comment fields:
ICM 1,15,=F'0' CC set to 0, c(GR1) is zero
ICM 2,15,=F'-1' CC set to 1, c(GR2) is negative
ICM 3,15,=F'+1' CC set to 2, c(GR3) is positive
92 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 47. We sometimes say that such disallowed interruption conditions are βmaskedβ or βdisabledβ, and when
allowed they are βunmaskedβ or βenabledβ. We'll see in Section 16.2.1 how the SPM instruction lets you control
these four program interruptions.
188 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
These CC settings are exactly what we would have obtained if we had written the six instructions
L 1,=F'0' CC unchanged
LTR 1,1 CC set to 0, c(GR1) is zero
L 2,=F'-1' CC unchanged
LTR 2,2 CC set to 1, c(GR2) is negative
L 3,=F'+1' CC unchanged
LTR 3,3 CC 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 1,=F'0' Set GR1 to zero, CC unchanged
ICM 1,B'0011',=H'-1' Sets GR1 to X'0000FFFF', CC = 1
sets the CC to 1 (indicating a one-bit at the left end of the first inserted byte), but the leftmost
two bytes of GR1 are still zero. Conversely, the instruction
LH 1,=H'-1' Set GR1 to X'FFFFFFFF'
does not affect the CC, but GR1 will contain all one-bits.
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 187, what operands in GR R 2 can result
in the CC being set to 3?
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.
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.
For now, we'll 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.
We'll 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.
We've 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 refer-
enced by an R1 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 64-bit register referenced by GR G n ,
and GRn will mean the specific 32-bit 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 Save 64-bit GG0 through GG3
- - -
Save0123 DS 4D Reserve 4 doublewords
In memory, these would appear like this:
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Save0123+0 β c(GG0) β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
Save0123+8 β c(GG1) β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
Save0123+16β c(GG2) β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
Save0123+24β c(GG3) β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
93 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 System z. 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β.
190 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
Then, to restore the contents of the registers, we execute
LMG 0,3,Save0123 Restore GG0 through GG3
2. The other two LM/STM instructions in tref refid=s14s8t1. end in βHβ, referring to the
32-bit high-order half of a 64-bit general register.94 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β.95
For example, to store and load only the high-order halves of general registers 5 and 6, we can
write
STMH 5,6,High56 Save high-order half of GG5 and GG6
- - -
LMH 5,6,High56 Restore high-order half of GG5 and GG6
- - -
High56 DS 2F Save area for two 32-bit words
3. LGH is the 64-bit equivalent of LH: it sign-extends the 16-bit integer at the Effective Address
in memory to 64 bits, and places the result into GG R 1.
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ¬ββββββββββββββββββββ
ββββββββββββ signβextended βββββββββββββββββββββββββββββββΌs β GG R1
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ΄ββββββββββββββββββββ
0 48 63
βββββββββββββββββββββ
Halfword in memory βs β
βββββββββββββββββββββ
0 15
Figure 70. Sign extension by L G H instruction
4. The remaining two instructions in Table 46 on page 189 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 187.
To illustrate, suppose you want to swap the first and fourth bytes of GG0 β that is, the
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 βββ
94 The letter βHβ is used in mnemonics with many meanings, such as βHighβ, βHalfwordβ, etc.
95 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 high-
order 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.
14.7.2.(2) Write a sequence of instructions to exchange the high-order and low-order halves of
GG0.
opcode unused R1 R2
Table 49. RRE-type instruction format
The actions of the instructions in Table 51 are the same as for their 32-bit equivalents in
Table 44 on page 188.
The instructions in Figure 68 on page 188 dealt with data in 32-bit registers; their equivalents for
64-bit registers are shown in Figure 71.
If we compare Figures 71 and 68, we see that these equivalent instructions behave similarly and
produce identical CC settings.
192 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
LHR is similar to LR, and their operand field entries are the same. LHR takes the rightmost 16
bits of the R2 register, extends the sign bit to the left to form a 32-bit result, and places it in the
R 1 register. This is illustrated in Figure 72; note its similarity to Figure 62 on page 183. The R 1
and R 2 registers need not be distinct.
βββββββββββββββββββββ¬ββββββββββββββββββββ
ββ signβextended ββΌs β GR R1
βββββββββββββββββββββ΄ββββββββββββββββββββ
32 48 63
βββββββββββ΄ββββββββββ
βs β Rightmost 16 bits of GR R2
βββββββββββββββββββββ
0 15
Figure 72. Sign extension by L H R instruction
For example:
L 1,=X'456789AB'
LHR 2,1 c(GR2)='X'FFFF89AB'
We saw in Figure 63 on page 183 that large fullword values can yield incorrect values if truncated
to halfwords. The same problem can occur with LHR:
L 0,=F'65537' c(GR0)=X'00010001'
LHR 1,0 c(GR1)=X'00000001' Lost significance!
LGHR uses the rightmost 16 bits of the second operand register. Sign extension is indicated by
the notation (64β16) in tref refid=s14s8t1.. Figure 70 on page 191 shows its resemblance to
LH seen in Figure 62 on page 183.
Exercises
14.8.1.(2) Can you think of a reason why an LHR instruction would be used with identical
register operands?
14.8.2.(2) + Suppose GR1 contains X'12345678'. What will be in GR2 after executing this
instruction?
LHR 2,1
Now, suppose GR1 contains X'FEDCBA98'; what will be in GR2 after executing the same
instruction?
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, System z provides the LT and LTG instructions, as shown in
Table 52 on page 194:
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β?
The actions of these instructions are almost the same as their 64-bit equivalents that we saw in
Table 51 on page 192, except that no instruction sets the CC to 3.
In each case, the 32-bit second operand is first sign-extended internally, and then treated as a
64-bit operand. For example, the single instruction
LCGFR 0,1 Sign extend, complement GR1 to GG0
is equivalent to the two instructions
LGFR 0,1 Sign extend GR1 to GG0
LCGR 0,0 Two's complement of GG0
194 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
βββββββββββββββββββββββββββββββββββββββββ¬βββββββββββββββββββββββββββββββββββββββββ
βββββββββββββ signβextended βββββββββββΌs β GG R1
βββββββββββββββββββββββββββββββββββββββββ΄βββββββββββββββββββββββββββββββββββββββββ
0 63
ββββββββββββββββββββββββββββββββββββββββββ
32βbit second operand βs β GR R2
ββββββββββββββββββββββββββββββββββββββββββ
0 31
Figure 73. Sign extension for instructions with mixed 32- and 64-bit signed operands
The instructions in Table 53 on page 194 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 on page 194 to
those in Table 50 on page 192. What similarities and differences do you see?
14.10.2.(2) + What would happen in the (64β32) instructions in Table 53 on page 194 if
complementation is done before sign extension?
14.10.3.(2) + The Condition Code values shown in 51 are not the same as those shown in
Table 54 on page 194. How and why are they different?
14.10.4.(2) Consider the 32-bit maximum negative number X'80000000'. Show the contents of
general register 0 and the CC setting after each of these instruction sequences:
(1) L 0,=X'80000000'
LPR 0,0
(2) L 0,=X'80000000'
LGFR 0,0
(3) L 0,=X'80000000'
LPGFR 0,0
(4) L 0,=X'80000000'
LNGFR 0,0
14.10.5.(2) + Why can none of the instructions in Table 53 on page 194 set the CC to 3?
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:
Table 55 gives a summary of the instructions we'll review. We'll see that they are arranged in
simple groups with repeating patterns.
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 183 and Figure 70 on page 191); the others are logical load instructions that zero-extend
the second operand to the length of the first.
ββββββββββββββββββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββ¬ββββββββββ
βββββββββββββββββ LGB ββββββββββββββββββββββββββββ LB ββββββββββββββΌs β GG R1
ββββββββββββββββββββββββββββββββββββββββ΄ββββββββββββββββββββββββββββββ΄ββββββββββ
0 (unchanged by LB) 31 32 63
βββββββββββ
Byte in memory or register βs β
βββββββββββ
0 7
Figure 74. Sign extension by Load Byte instructions
For the LB and LBR instructions, the R 1 first operand is a 32-bit general register, and the high-
order 32 bits of the 64-bit register are unchanged. For example:
LB 3,=FL1'-7' c(GR3)=X'FFFFFFF9'
LGB 5,=FL1'-7' c(GG5)=X'FFFFFFFF FFFFFFF9'
196 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
ββββββββββββββββββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββ¬ββββββββββ
βββββββ (zeroed by LLGC, LLGCR) βββββ
ββββββββββ zeros ββββββββββ
β β GG R1
ββββββββββββββββββββββββββββββββββββββββ΄ββββββββββββββββββββββββββββββ΄ββββββββββ
0 (unchanged by LLC, LLCR) 63
βββββββββββ
Character in memory or register β β
βββββββββββ
0 7
Figure 75. Zero extension by Load Logical Character instructions
LLC and LLCR affect only the 32 low-order bits of the 64-bit R1 register; the high-order 32-bits
are unaffected.
These four instructions can eliminate the need to clear a register before inserting a character for
processing.
ββββββββββββββββββββββββββββββββββββββββ¬ββββββββββββββββββββ¬ββββββββββββββββββββ
βββββββ (zeroed by LLGH, LLGR) ββββββ
βββββ zeros βββββ
β β GG R1
ββββββββββββββββββββββββββββββββββββββββ΄ββββββββββββββββββββ΄ββββββββββββββββββββ
0 (unchanged by LLH, LLHR) 63
βββββββββββββββββββββ
Halfword in memory or register β β
βββββββββββββββββββββ
0 15
Figure 76. Operation of Load Logical Halfword instructions
These four Load Logical Halfword are closely related to the arithmetic βLoad Halfwordβ
instructions, except that the logical loads fill the rest of the 32- or 64-bit R1 register with zeros,
rather than sign-extending the high-order bit of the loaded halfword.
ββββββββββββββββββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββββββββ
βββββββββββββββ zeros βββββββββββββββ
β β GG R1
ββββββββββββββββββββββββββββββββββββββββ΄ββββββββββββββββββββββββββββββββββββββββ
0 63
βββββββββββββββββββββββββββββββββββββββββ
Word in memory or register β β
βββββββββββββββββββββββββββββββββββββββββ
0 31
Figure 77. Operation of Load Logical word instructions
In effect, LLGF and LLGFR are like L and LR, followed by setting the high-order half of the
G G R 1 register to zero. The R 1 operand is always a 64-bit register.
Why ignore the high-order bit of the 32-bit second operand? When we discuss βaddressing
modesβ and instructions that both change and depend on addressing mode in Section 20, we'll see
that the high-order bit of a 32-bit address was often used to indicate which mode was desired; it
can be important to set that bit to zero. 96
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?
First: by substituting L for LR, you can occasionally create an error that can't be detected by the
Assembler, and sometimes is difficult to find. For example, suppose you intended to load GR5
from GR8 with a LR instruction. If the symbols R5 and R8 have values 5 and 8, then both
L 5,8 Load GR5 with value 8 (??)
and
L R5,R8 Load GR5 from GR8 (??)
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 L 5,8 Load GR5 with value 8 (??)
000004 5850 0008 L R5,R8 Load GR5 from GR8 (??)
Exactly the same instruction will be executed.
Warning
Symbols like R8 β an βRβ followed by a number β might not refer to a
register!
96 This unusual behavior is difficult to justify now, but we'll see in Section 37 that there are good reasons to have these
instructions.
198 Assembler Language Programming for IBM System zβ’ Servers Version 2.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 state-
ment:
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.
We've 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.
We'll 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 System z architects didn't 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.
200 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
Mnemonic Opcode Mnemonic Opcode Mnemonic Opcode
IC 43 LLC E394 LPGR B900
ICM BF LLCR B994 LPR 10
ICMH EB80 LLGC E390 LR 18
L 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
We will use tables like these to summarize instruction mnemonics and their operation codes as
they are introduced.
202 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
Rn
The field of a machine instruction designating the number of a general register.
sign extension
The process of making copies of the sign bit of a shorter operand and extending it to the left,
to the length of a target field.
store operation
Place a copy of part or all of a register's 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.
11 55555555555
111 55555555555
1111 55
11 55
11 555555555
11 55555555555
11 555
11 55
11 55
11 555
1111111111 55555555555
1111111111 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 47), 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.
We'll 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.
To complete execution of a branch instruction, the IA portion of the PSW is replaced by the
branch address. The next instruction to be fetched then comes from the address specified by the
branch address. Branch instructions are also called βtransferβ instructions, in the sense that
control is transferred to the instruction at the branch address.
A successful branch instruction alters the normal sequencing of instruction fetching. If the IA is
not changed by the branch instruction, the next instruction fetched follows the branch instruction,
and we say that the branch was βnot takenβ.
204 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
15.2. The Branch Mask and Branch Condition
The branch condition is determined by examining a single bit of the third hex digit of the instruc-
tion denoted βR 1β in Table 17 on page 107 and in Table 19 on page 108. For the BCR and BC
instructions this digit does not refer to GR R 1, but is treated as a bit pattern called a mask, M 1,
as we saw in Section 14.5 for the ICM and STCM instructions. The instructions have these
formats:
07 M1 R2
Table 57. BCR instruction
47 M1 X2 B2 D2
Table 58. BC instruction
For both the RR and RX instructions, M 1 is the mask digit. Thus, we could write
The CPU matches the value of the CC to one of the mask bits, as shown in Table 59. If a 1-bit
in the mask field position corresponds to the value of the CC, the branch condition is met; if the
CC value matches a 0-bit in the mask, the branch condition is not met and no branch occurs.
Instruc-
CC value Mask bit Mask bit
tion bit
tested position value
position
0 8 0 8
1 9 1 4
2 10 2 2
3 11 3 1
Table 59. Mask bits and corresponding CC values
Thus in Figure 79, the BCR 9,4 instruction would branch if the CC had values of 0 or 3, and the
BC 7,4(8,2) instruction would not branch if the CC had value 0.
Exercises
15.2.1.(2) Show how the value of the CC can be used as a bit index in determining which bit of
the mask digit to test.
15.2.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.)
206 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
Modern processors are highly βpipelinedβ. That is, the fetch, decode, and execute phases are proc-
essed 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.97 Occasionally, it may be necessary to prevent this over-
lapped type of execution; this form of BCR instruction blocks execution of the following instruc-
tion 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.
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 0F Align to fullword boundary
NOPR 0 2-byte No-op
BASR 8,11 2-byte BASR instruction
DC A(Anywhere) Properly aligned fullword constant
Explain why this might create an unexpected problem.
15.4.2.(2) What other instructions could be used in place of NOPR and NOP?
15.4.4.(2) Explain the execution-time differences between these two pairs of instructions:
L 1,=F'0' L 0,=F'0'
BCR 15,1 BCR 15,0
97 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 couldn't 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) weren't certain which instruction caused the
interruption.
98 This is not an official description.
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 0
instruction just before it. But if the program is large or if changes must be made somewhere pre-
ceding 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) assem-
bler 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 β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.100
To achieve the alignment desired for the BASR in our example, we would write
99 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.
100 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).
208 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
CNOP 2,4 Align to middle of a word
BASR 8,11 Two-byte instruction
DC A(AnyWhere) No intervening bytes
Name field symbols on CNOP instructions are rarely used, because branch-target symbols typi-
cally are given to instructions immediately preceding or following the CNOP. Thus, you could
write a symbol that is the name of βnothingβ:
DS 0F Align on word boundary
CNopName CNOP 0,4 Align on word boundary (again?)
CallSub BASR 14,15 Go to a subroutine
- - -
The two symbols CNopName and CallSub will have the same LC value even though CNopName
doesn't name anything different; it will have length attribute 1.
Exercises
15.5.1.(2) + Suppose the Location Counter value is X'0246' when each of these CNOP
instructions is processed by the Assembler. Determine the value of the LC after each CNOP is
processed.
(1) CNOP 2,4
(2) CNOP 0,4
(3) CNOP 6,8
(4) CNOP 10,16
(5) CNOP 4,16
(6) CNOP 2,8
1. A DC AL3(A)
CNOP 2,4
B DC A(B)
2. C DC C'DS C''&&'''
CNOP 0,4
D DC C'D DC D''DC'''
3. CNOP 2,8
E DC 2F'100'
F DC (X'F')X'F'
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 X'345' when
the initial statement is processed by the Assembler. Give the value and length attributes of the
symbol A.
1. CNOP 2,4
A LM 2,6,0(1)
2. CNOP 2,8
A BC 10,Smith
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 Com-
parisons, and βTβ after Tests.
Table 61 (Page 1 of 2). Extended branch mnemonics and their branch mask values
RX Mnemonic RR Mnemonic Mask Meaning
B BR 15 Unconditional Branch
BNO BNOR 14 Branch if Not Ones (T)
Branch if No Overflow (A)
BNH BNHR 13 Branch if Not High (C)
BNP BNPR 13 Branch if Not Plus (A)
BNL BNLR 11 Branch if Not Low (C)
BNM BNMR 11 Branch if Not Minus (A)
Branch if Not Mixed (T)
210 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
Table 61 (Page 2 of 2). Extended branch mnemonics and their branch mask values
RX Mnemonic RR Mnemonic Mask Meaning
BE BER 8 Branch if Equal (C)
BZ BZR 8 Branch if Zero(s) (A,T)
BNE BNER 7 Branch if Not Equal (C)
BNZ BNZR 7 Branch if Not Zero (A,T)
BL BLR 4 Branch if Low (C)
BM BMR 4 Branch if Minus (A)
Branch if Mixed (T)
BH BHR 2 Branch if High (C)
BP BPR 2 Branch if Plus (A)
BO BOR 1 Branch if Ones (T)
Branch if Overflow (A)
NOP NOPR 0 No Operation
As this table indicates, the RR forms of the extended mnemonics are formed by adding the letter
βRβ to the equivalent RX mnemonic.
Each of these instructions needs only a single operand field entry. Because the mask digit is
implied by the extended mnemonic, the operand may take any of the forms allowed for the
second operand of an RX- or RR-type instruction.
Exercises
15.6.1.(2) + Programmers sometime write programs that contain instruction sequences like this:
Loop - - - Do something in the loop
- - - Now make a test, set the CC
BNZ Finish Exit the loop if something's nonzero
B Loop Otherwise repeat the loop
Finish - - - Rest of program
Why is this wasteful? How can it be made shorter, simpler, and (very probably) faster?
15.6.2.(1) Sometimes the conditional branch instructions are described as follows: βThe opera-
tion code for an unconditional branch is X'47F', for a branch-on-zero is X'478', 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:
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
BZ *+18 Branch to known target location
- - - More instructions
*+18 EQU * Define the target location.
Can he now be sure his BZ instruction will branch to the intended target?
101 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.
212 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
answer questions like βHow did my program start executing instructions here?β, we must depend
on the operating system's Supervisor to save the BEAR's 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 we've 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?
The instruction opcodes and mnemonics are shown in the following table:
214 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
Chapter V: Basic Instructions 215
16. Fixed-Point Binary Addition, Subtraction, and Comparison
11 6666666666
111 666666666666
1111 66 66
11 66
11 66
11 66666666666
11 666666666666
11 66 66
11 66 66
11 66 66
1111111111 666666666666
1111111111 6666666666
This section describes instructions for fixed-point two's 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.
The instructions are shown in Table 62. The first six generate 32-bit results, and the others
produce 64-bit results.
216 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
16.2. Signed-Arithmetic Operations Using 32-Bit Registers
All the instructions in Table 62 on page 216 set the Condition Code as indicated in Table 63.
Table 63 shows that these add and subtract instructions (like the LCR and LPR instructions in
Table 44 on page 188) can cause a fixed-point overflow exception. We'll see in Section 16.9 on
page 234 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 182). The notation (32β16) in Table 62
on page 216 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).
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.
In this example, the calculations inside the βloopβ102 (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 fre-
quently referenced operands to be carried in registers instead of in memory. 103
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.
Although we assumed that no overflows can occur, it may be possible that values calculated else-
where in the program could cause an overflow here. Thus, to be careful, the above code sequence
might continue with the instructions
- - - (As above)
ST 2,NewStock (As above)
BZ ReOrder None left, must order more!
BM OverSold Reorder now! Sold more than stock!
BO Disaster Error! More than 2**31 items??
Figure 84. Testing the result of arithmetic instructions
The instructions at ReOrder and OverSold will probably do similar things, except that at OverSold
the order for new items would likely be given higher priority so our customers can receive their
previously ordered products more promptly.
102 A loop is a sequence of instructions executed repeatedly until some condition is satisfied. We'll see in Section 22 how
other instructions help us write efficient loops.
103 Don't 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.)
218 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
Condition Code After Overflow
If a binary arithmetic operation causes fixed-point ovreflow, CC=3 is
given preference to indicating any other property of the result.
Exercises
16.2.1.(2) In Figure 81 on page 217, 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.
16.2.3.(2) + In Figure 82 on page 218, 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 vari-
able at VARBL by 1, so he wrote the instructions
Load L 2,VARBL
S 2,ONE
ST 2,ONE (Error! Meant to use 'VARBL'!)
- - -
B Load Try again
- - -
VARBL DC F'4'
ONE DC 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 deter-
mine 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=B'1001' is 3. If c(Data) is zero, store β 1, and if
c(Data) is negative, store β 31.
16.2.8.(3) + Complete the βassemblyβ of this program segment by showing the generated object
code and its locations.
Loc Object Code Assembler Language Statements
Ex16_2_8 Start X'5000'
5000 0D40_________ BASR 4,0
____ _____________ Using *,4
____ _____________ SR 2,2
____ _____________ IC 2,XX+3
____ _____________ LTR 0,2
____ 47___________ BZ Looper
____ _____________ STH 0,XX
____ _____________ Looper B * Loop forever here
____ _____________ YY DC CL4'Ugh'
____ _____________ XX DC F'-10'
16.2.12.(2) In Exercise 16.2.11, what data is generated for the constant named Y?
16.2.14.(3) + Complete the βassemblyβ of this (nonsensical) program segment by showing the
generated object code and its locations.
Loc Object Code Assembler Language Statements
8000 Ex16_2_E Start X'8000'
____ _____________ BASR 4,0
____ _____________ Using *,4
____ _____________ LM 1,2,Value
____ _____________ STCM 2,B'111',First
____ _____________ LCR 0,1
____ _____________ BC 10,*+8
____ _____________ STH 0,Last(1)
____ _____________ BCR 15,14
____ _____________ Value DC F'4'
____ _____________ DC F'-6'
____ _____________ First DS F
____ _____________ Last DS H'-10'
16.2.15.(2) + Show the contents of GR2 and the Condition Code setting after executing each of
the following instruction sequences:
1. L 2,=A(X'89ABCDEF')
AR 2,2
2. L 2,=F'2'
A 2,=A(X'7FFFFFFF')
3. L 2,=F'2'
A 2,=A(X'123345')
ICM 2,2,=X'12345'
16.2.16.(2) + For each of these arithmetic operations, show the result and the CC setting.
1. L 1,=X'80000000'
S 1,=X'80000000'
2. L 2,=X'00000000'
S 2,=X'80000000'
3. L 3,=X'FEDCBA98'
A 3,=X'FEDCBA98'
220 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
4. L 4,=X'FEDCBA98'
S 4,=X'87654321'
LG 6,XX
AG 6,YY c(GG6) = c(XX) + c(YY)
BNM ST Branch if sum is not negative
AG 6,ZZ It was negative; add c(ZZ)
SG 6,=FD'17' Subtract 17 (doubleword literal)
ST STG 6,DAnswer Store result
- - -
XX DC FD'7569241038'
YY DC FD'-94226701151'
ZZ DC FD'137'
DAnswer DS FD Computed result
Figure 85. Calculate a 64-bit sum with an intermediate test
In this example, we cannot use the literal =H'17' because the System z instruction set does not
(now) provide the AGH and SGH instructions. 104 (See Exercises 16.3.1 and 16.3.2.)
Suppose we add these two large numbers:
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.
104 At the time of this writing. But new instructions like AGHI (that we'll see in Section 21) are added regularly to the
System z architecture, so check the Principles of Operation.
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 Meaning
0 Operand 1 = Operand 2
1 Operand 1 < Operand 2
2 Operand 1 > Operand 2
Table 65. CC settings after arithmetic comparisons
For the CR, C, and CH instructions, the CC setting is the same as would result from performing
SR, S, and SH instructions with the same operands, assuming that no overflow occurs. In fact,
this is how the comparison is done by the CPU: a subtraction is performed internally, and the
CC is set to reflect the sign and magnitude of the difference (that would then have been placed
back in GR R 1 or GG R 1 for a subtract instruction). Further analysis of the original operands is
required by the CPU if the internal result overflows. (See Exercise 16.4.2.)
To illustrate arithmetic comparisons, consider these instructions and their comment fields:
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 218.
222 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
LH 4,=H'1' c(GR4) = accumulated sum
LR 7,4 c(GR7) = count of additions
Test CH 7,NN Compare count to c(NN)
BE Store Branch if equal, N terms added
LR 0,7 Compute next odd integer
AR 0,0 Counter + counter = 2N
AH 0,=H'1' Add 1, giving next odd term
AR 4,0 Add term to sum
AH 7,=H'1' Increment count by 1
B Test Branch back to see if finished
Store ST 4,Sum Store result
Figure 88. Calculate the sum of N odd integers
The arithmetic comparison instructions for 64-bit registers do exactly the same operations as the
equivalent instructions do for 32-bit registers. If the second operand is shorter than the R1 reg-
ister, it is sign-extended internally to the length of the first operand before doing the comparison.
Exercises
16.4.1.(1) + Why can the CC not be set to 3 in a comparison operation?
16.4.2.(3) In executing arithmetic compare instructions, the CPU performs an internal sub-
traction. By examining the possible combinations of signs and magnitudes for the two oper-
ands, 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 on page 222 as
CH 1,=F'5' (Rather than =H'5')
What would the CC setting be?
16.4.4.(2) + In the following program, some pieces of data are missing, as indicated by the ____
spaces. Using the available information, fill in those spaces.
Loc Object Code Assembler Language Statements
Ex16_4_4 Start X'4800'
4800 _____________ BASR 10,0
4802 _____________ Using *,10
4802 _________A056 Loop L 0,________
4806 _____________ A 0,One
480A 5000_________ ST 0,Number
480E <other ops> PrintOut Number
4824 59___________ C 0,Ten
4828 47___________ BL Loop
482C <other ops> PrintOut *
4854 00000000 Number DC F'0'
4858 00000001 One DC F'1'
485C _____________ Ten DC F'10'
End Ex16_4_4
105 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.
The CC settings we saw in Table 62 on page 216 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).
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.
To illustrate the differences between arithmetic and logical addition and subtraction, consider
examples 1 and 2 of Section 2.11 on page 32.
β’ Example 1. For unsigned operands, the result of 5 β 3=2 is representable.
5-3: 0000 0101
-0000 0011
becomes
0000 0101
+1111 1101
(carry lost) 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 don't exist in this 8-bit repre-
sentation).
224 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
3-5: 0000 0011
-0000 0101
becomes
0000 0011
+1111 1011
(no carry) 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.
As in Figure 86 on page 221, we can use logical arithmetic to add the same two numbers:
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. (Double-
length 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 two's complement (the negative) of such a 64-bit number. Since
we know that the two's complement is found by adding a low-order 1-bit to the ones' comple-
ment of the number, we might proceed as follows. The number to be complemented is stored in a
doubleword at ARG, and c(GR0,GR1) means the contents of the double-length register pair
formed by GR0 and GR1.
The same complementation is performed by the following code sequence, but more directly (and
less obviously).
The first LCR instruction forms the two's 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. 106
Adding the two double-length integers at A and B is straightforward: the instructions are explained
in the comments.
Subtracting 64-bit operands is done the same way, except that the condition code setting after the
first logical subtraction requires explanation.
106 This instruction sequence has a minor defect: if either of the LCR instructions complements the maximum negative
number X'80000000', a fixed-point overflow exception could occur. (See Exercise 16.6.5.)
226 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
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 represen-
tation. Hence we must βborrowβ a 1-bit from the next higher bit position, so we subtract =F'1'
if the branch condition is not met.
It might help to review the examples in Section 2.11 on page 32 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 218, revised to use logical add and subtract instructions:
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 218), 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 218. 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 on page 226, what additional
instructions would be needed to cause a branch to OverFlow if the 64-bit result of the addition
overflowed?
16.5.4.(2) + In the subtraction instructions shown in Figure 93 on page 226, what additional
instructions would be needed to cause a branch to OverFlow if the 64-bit result of the sub-
traction overflowed?
16.5.5.(2) In Figure 91 on page 226, 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 two's 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 two's 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.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 cor-
rectly 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) + 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.12.(1) If a logical subtraction is performed with two operands that are identically zero, why
is the resulting CC setting not zero?
CC bit 0 1
Left No carry Carry
Right Zero result Nonzero result
Table 69. CC settings after logical addition
Thus, the leftmost bit of the CC can be thought of as the βcarry bitβ. Similarly, referring to
Table 68 on page 225, another way to represent the CC settings for logical subtraction is pro-
vided in Table 70.
CC bit 0 1
Left Borrow (no carry) No borrow (carry)
Right Zero result Nonzero result
Table 70. CC settings after logical subtraction
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 107 by using the CC bit to
propagate a carry or borrow to the next higher-order operand.
107 Multiple-precision arithmetic is used intensively in cryptographic applications for data security.
228 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
Now, we can use these instructions to improve the examples of double-length addition and sub-
traction shown in Figures 92 and 93 on page 226. First, consider addition: now, the intermediate
branch and addition of a low-order 1 are unneeded.
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 consec-
utive 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.
16.6.4.(3) In Exercise 16.6.3, the add and subtract instructions do logical arithmetic. How
would you detect an arithmetic overflow?
16.6.5.(2) + Write an instruction sequence using ALC to add two 128-bit numbers represented
as two groups of four fullwords each.
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 partic-
ipating in the 64-bit operation, as illustrated in Figure 97.
βββββββββββββββββββββββββββββββββββββββββ¬βββββββββββββββββββββββββββββββββββββββββ
β βββββββββ sign extended ββββββββββββββΌs β GG R1
βββββββββββββββββββββββββββββββββββββββββ΄βββββββββββββββββββββββββββββββββββββββββ
0 32 63
ββββββββββββββββββββββββββββββββββββββββββ
32βbit second operand βs β
ββββββββββββββββββββββββββββββββββββββββββ
0 31
Figure 97. Sign extension for instructions with mixed 32- and 64-bit signed operands
Using SGF, we can modify the example in Figure 85 on page 221 to use a word literal:
LG 6,XX
AG 6,YY c(GG6) = c(XX) + c(YY)
BNM ST Branch if sum is not negative
AG 6,ZZ It was negative; add c(ZZ)
SGF 6,=F'17' Subtract 17 (word literal)
ST STG 6,DAnswer Store result
- - - etc.
Figure 98. Calculate a 64-bit sum with an intermediate test
The AGFR and SGFR instructions use the same sign-extension process for 32-bit second oper-
ands 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'17', we can rewrite Figure 98 as
follows:
LG 6,XX
AG 6,YY c(GG6) = c(XX) + c(YY)
BNM ST Branch if sum is not negative
AG 6,ZZ It was negative; add c(ZZ)
LH 0,=H'17' Load 17 into GR0 (32 bits)
SGFR 6,0 Extend; then subtract GR0 from GG6
ST STG 6,DAnswer Store result
- - - etc.
Figure 99. Calculate a 64-bit sum with an intermediate test
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'17'.
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 on page 231.
230 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
βββββββββββββββββββββββββββββββββββββββββ¬βββββββββββββββββββββββββββββββββββββββββ
β βββββ zeros βββββ
β β GG R1
βββββββββββββββββββββββββββββββββββββββββ΄βββββββββββββββββββββββββββββββββββββββββ
0 32 63
ββββββββββββββββββββββββββββββββββββββββββ
32βbit second operand β β
ββββββββββββββββββββββββββββββββββββββββββ
0 31
Figure 100. Sign extension for instructions with mixed 32- and 64-bit unsigned operands
For example:
(1) LG 0,=AD(X'0123456789ABCDEF')
ALG 0,=AD(X'123456789ABCDEF0') c(GG0)=X'13579BE02468ACDF', CC=1
Adding the two operands causes no overflow and the result is nonzero, so CC=1.
(2) LG 0,=AD(X'0123456789ABCDEF')
ALGF 0,=A(X'87654321') c(GG0)=X'0123456811111110', CC=1
As in (1), but the second operand is first extended with zeros.
(3) LG 0,=AD(X'0123456789ABCDEF')
SLGF 0,=A(X'87654321') c(GG0)=X'0123456702468ACE', CC=3
Subtracting the second operand causes a carry and the result is nonzero, so CC=3.
(4) SR 1,1 c(GR1)=0
SGR 0,0 c(GG0)=0
SLGFR 0,1 c(GG0)=X'0000000000000000', 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 226 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 226 to add a pair of 64-bit inte-
gers, giving a 128-bit sum.
16.7.3.(2) Revise the instructions shown in Figure 93 on page 226 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.
As we saw in Section 14.7 on page 189, 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 (you'll
note that it's identical to Table 65 on page 222).
CC Meaning
0 Operand 1 = Operand 2
1 Operand 1 < Operand 2
2 Operand 1 > Operand 2
Table 74. CC settings after logical comparisons
Logical comparisons do not give the same results as arithmetic comparisons, since numbers in the
logical representation are always nonnegative. The following instruction sequence may help to
show the differences. (Following the LM instruction, the contents of R3 will be X'80000001'.)
The 64-bit logical comparison instructions behave the same way as their 32-bit equivalents. Care-
fully compare the CC settings in Figure 101 with those in Figure 87 on page 222.
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 deter-
mined 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 185). 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
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:
232 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
L 0,=A(X'00010203') Initialize GR0
CLM 0,B'0000',=X'0123' CC = 0, because mask is 0
CLM 0,B'0001',=X'0123' CC = 2, because X'03' > X'01'
CLM 0,B'0100',=X'0123' CC = 0, because X'01' = X'01'
CLM 0,B'0110',=X'0123' CC = 1, because X'0102' < X'0123'
β’ 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 0,=AD(X'0001020304050607') Initialize GG0
CLMH 0,B'0000',=X'0123' CC = 0, because mask is 0
CLMH 0,B'0001',=X'0123' CC = 2, because X'03' > X'01'
CLMH 0,B'0100',=X'0123' CC = 0, because X'01' = X'01'
CLMH 0,B'0110',=X'0123' CC = 1, because X'0102' < X'0123'
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 regu-
larly incremented. For example, if Value has been saved at different times, we could find that
Oldest DC X'789ABCDE' Oldest value
Later DC X'89ABCDEF' A later value
Newest DC X'9ABCDEF0' Most recent value
and we can use logical comparisons to determine their ordering, as in
L 0,Oldest
L 1,Later
L 2,Newest
- - -
CLR 1,0 Compare Later to Oldest
CLR 2,1 Compare Newest to Later
Figure 102. Comparing logically ordered values
then both CLR instructions will give the correct ordering of the three values.
But if the values can βwrap aroundβ from X'FFFFFFFF' to zero, we must be more careful. For
example, suppose the three values are
Oldest DC X'FFFFFFFE' Oldest value
Later DC X'FFFFFFFF' A later value
Newest DC X'00000001' 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.
Exercises
16.8.1.(2) Show how the CC settings after SL and SLR are related to those after CL and CLR.
16.8.3.(2) + Suppose c(GR0) is X'87654321' and c(GR1) is X'01234567'. What is the CC setting
and the apparent ordering of the operands after executing each of these two instructions?
CR 0,1 Compare c(GR0) to c(GR1)
CLR 0,1 Compare c(GR0) to c(GR1)
Now, suppose the sign bit of each operand has been inverted, so that c(GR0)=X'07654321'
and c(GR1)=X'81234567'. 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 and execute a small program to verify the assertions about correctly-ordered
logical comparisons in the examples starting with Figure 102 on page 233.
IPM inserts the Condition Code and Program Mask into bits 34-39 of register R1, in the posi-
tions 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 55. These four mask bits correspond to the bit posi-
tions shown in Table 76 on page 235:
234 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
Bit Exception Condition Controlled Int. Code
36 (F) Fixed-point overflow 8
37 (D) Decimal overflow A
38 (U) Hexadecimal floating-point underflow D
39 (S) Hexadecimal floating-point lost significance E
Table 76. Program Mask bits
Setting a mask bit to 1 enables the corresponding interruption. If the mask bit is 0, the CPU takes
a default action without an interruption.
In practice, many programmers choose to set the Program Mask to zero initially, and trust to
luck that nothing goes wrong. For example:
SR 0,0 Set c(GR0) to zero
SPM 0 Set CC and Program Mask bits to zero
Careful placement of tests for overflow can help justify such faith, but it is generally better to test
in advance for possible errors, and let a program interruption catch the unexpected and truly
exceptional cases.
For now, we are concerned only with fixed-point overflow. The result of an instruction causing a
fixed-point overflow is the same whether or not an interruption occurs; the Condition Code is set
to 3.
Exercises
16.9.1.(4) For each of the conditions controlled by a bit in the Program Mask, determine what
actions are taken by the CPU (including CC settings) when the PM bit is zero or one. (You
may need to consult the z/Architecture Principles of Operation.)
16.9.2.(2) + Write instructions that will turn off the Lost-Significance mask bit in the Program
Mask, without affecting the settings of the other mask bits.
16.9.3.(2) Assume you are executing in 24-bit addressing mode. The fullword integer at CCode
has a value of 0, 1, 2, or 3. Set the Condition Code to that value, without affecting the setting
of the Program Mask.
16.9.4.(2) Assume you are executing in 24-bit addressing mode. Store the current value of the
program mask in the rightmost four bits of the byte at PMask. The remaining 4 bits of the byte
should be zero.
16.9.5.(2) Assume you are executing in 24-bit addressing mode. Store the current value of the
Condition Code in the word at CCode without changing the Condition Code.
16.10. Summary
Operands used in arithmetic and logical operations may be extended, as we noted in Sections
14.10 and 16.7.
Operand Extension
When a source operand in a register or in memory is used as an operand
in an arithmetic instruction whose target register is longer than the
operand, the operand is extended internally to the length of the target
register:
β’ arithmetic operands are sign-extended
β’ logical operands are extended with zeros.
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.
236 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
Mnemonic Opcode Mnemonic Opcode Mnemonic Opcode
A 5A C 59 SGF 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 S 5B
AR 1A SG E309
The instruction opcodes and mnemonics are shown in the following table:
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) = B'100000000000000' + X'C7A98' - 231471192,
c(Y) = X'C0FFEE' - C'@#$' - 694895668, and
c(Z) = 1073741823 + X'F194F6' + X'ABCD'.
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(WB) - 929065920, where
c(WA) = B'100000000000000' and
c(WB) = X'1230000'.
c(X) = c(XA) + 50344169 + c(XB), where
c(XA) = X'5CF17' and
c(XB) = C'000'.
c(Y) = c(YA) + c(YB) + c(YC), where
c(YA) = B'11111111',
c(YB) = X'1261F02', and
c(YC) = C'ABCD'.
c(Z) = c(ZA) + c(ZB) - c(ZC), where
c(ZA) = X'CAF75A',
c(ZB) = B'1000011', and
c(ZC) = 511686493.
All the quantities used in the calculations are four-byte word-aligned constants in memory.
Define symbols having length attribute 16 and types C and X to name the same 16 bytes of
memory. Calculate W, X, Y, and Z, and print the results of your calculation in character and
hexadecimal form (using the PRINTOUT macro, for example).
Problem 16.3. Do as in Problem 16.2, but the four quantities W, X, Y, and Z are defined this
time by
238 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
c(W) = c(WA) + c(WB) - 759375551, where
c(WA) = B'100000000000000',
c(WB) = X'CBA98'.
c(X) = c(XA) - c(XB) + 1386388536, where
c(XA) = X'C0FFEE',
c(XB) = C'@#$'.
c(Y) = c(YA) + c(YB) + c(YC), where
c(YA) = B'11111111',
c(YB) = X'1F7C05',
c(YC) = C'ABCD'.
c(Z) = c(ZA) + c(ZB) - 975583924, where
c(ZA) = X'FFFF',
c(ZB) = -65536.
As before, print the 16 bytes of the result as a character string and as a string of 32 hexadecimal
digits.
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.
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.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.12.(2) + Write and execute a program to test the results of Exercise 16.2.16 above.
(Remember that the PRINTOUT macro will display both register contents and CC settings.)
240 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
Chapter V: Basic Instructions 241
17. Binary Shifting
11 777777777777
111 777777777777
1111 77 77
11 77
11 77
11 77
11 77
11 77
11 77
11 77
1111111111 77
1111111111 77
The multiplication and division instructions in Section 18 are often combined with shift oper-
ations, so we'll 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.109
We say that single-length shifts operate on bits in a single 32- or 64- bit register, and double-
length shifts operate on bits in an even-odd pair of registers.
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 on page 243 is ignored
when the instructions are executed.
109 At the time of this writing. But new instructions are added regularly to the System z architecture, so check the Princi-
ples of Operation.
242 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
opcode R1 B2 D2
Table 79. RS-type shift instruction
Thus, the Assembler makes no provision for specifying a value in that field, and sets it to zero.
The operand field entry for shift instructions is written in either of the two forms
R1,D2(B2) (explicit address)
R1,S2 (implied address)
and no R 3 operand is specified.
The RSY-type shift instructions do have an R 3 operand, as shown in Table 80. For these
instructions, the source operand is in the R3 register and the result goes into the R1 register. We'll
see examples using the R3 operand when we discuss these instructions.
When executed, none of the logical shift instructions change the CC setting, while all of the arith-
metic 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 low-
order 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, we'll describe the unit shift, and then look at the eight RS-type instructions, all of which
involve 32-bit registers.
βββββββ¬ββββββ¬ββββββ¬ββββββ¬β β β ββ¬ββββββ¬ββββββ¬ββββββ¬ββββββ
β a β b β c β d β β w β x β y β z β Before
βββββββ΄ββββββ΄ββββββ΄ββββββ΄β β β ββ΄ββββββ΄ββββββ΄ββββββ΄ββββββ
0 1 2 3 n-4 n-3 n-2 n-1
Figure 104. Register contents before shifting
The bit positions are numbered from 0 to n β 1, where n is the number of bits participating in the
shift.
The basic shift operation is the unit shift, in which each bit moves right or left by one bit posi-
tion. 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.
The βbit bucketβ doesn't really exist; it just means that the lost bit vanishes.110
βββββββ¬ββββββ¬ββββββ¬ββββββ¬β β β ββ¬ββββββ¬ββββββ¬ββββββ¬ββββββ
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 doesn't 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 After
βββββββ΄βββ¬βββ΄ββββββ΄ββββββ΄β β β ββ΄ββββββ΄ββββββ΄ββββββ΄ββββββ
β b β
βββββ bit bucket
Figure 108. Arithmetic unit shift left
Again, the sign of the operand is preserved. Because arithmetic left shifts may lose a significant
bit, an overflow condition can occur; we'll see how this happens when we look at the arithmetic
shift instructions in Section 17.4.
110 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.
244 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
in binary, or X'43B2A190'.
The execution of a shift instruction is simple: it simply performs the number of unit shifts speci-
fied 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. X'EDCBA987'
2. X'12345678'
3. X'87654321'
4. X'00000FED'
5. X'FFFFFFFF'
6. X'27A49FC1'
7. X'6789ABC0'
To perform a unit logical left shift of the contents of R8, we can execute the instruction
SLL 8,1(0) Shift GR8 left 1 bit position
Suppose GR8 again contains X'87654321' and GR3 contains X'82F3A2B5', executing the logical
right-shift instruction
SRL 8,16(3)
first causes the Effective Address to be computed as
X'82F3A2B5' + X'010' = X'82F3A2C5'
of which the rightmost six bits are B'000101'. Thus it shifts right five bit positions, leaving
0000 0100 0011 1011 0010 1010 0001 1001
in binary, or X'043B2A19' as the result in GR8.
In these examples, we saw that the original contents of GR8 were not preserved: that is, the shifts
can be thought of as βdestructiveβ. All the RS-type shifts use the same register (or register pair) as
the source and target of the operation. The RSY-type shifts let you preserve the original source
operand if you like.
The SLL instruction is the most commonly used logical shift. It is often used to multiply index
values by a power of two (such as the length of an operand in memory) prior to executing an
RX-type instruction for which the shifted register is the index register. We will see many such
uses in discussing looping and indexing in Section 22.
β’ Suppose the word at Index contains a small positive integer N that is to be used to index into
a table of words starting at the word named Tab. To load the N-th of those words into GR0,
we could write a sequence of instructions like the following:
L 1,Index Get index word
SLL 1,2 Shift left 2 bits (multiply by 4)
L 0,Tab-4(1) Load N-th word into GR0
The shift left by two bit positions is needed so that we access the N-th word (not the N-th
byte) in the table; and we must address the table at Tab-4 because if the integer at Index is 1,
we should access the first word at Tab. If N is 1, indexing will add 4 to Tab-4, giving the
address of Tab as desired.
β’ 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
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 two's complement integer, and the
remaining three bytes contain the character data (see Figure 110).
Space for typical table entry might have been reserved with DS statements such as
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, we'll ignore the three characters repres-
ented by βxxyyzzβ.)
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.
246 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
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.
If you specify different register numbers for R3 and R 1, the shift is βnondestructiveβ because the
source operand in GG R 3 is unchanged. If you specify the same register number for both R3 and
R 1, the shift is βdestructiveβ, just like the shifts in 32-bit general registers.
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'02'. (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 posi-
tions 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 X'12345678', c(GR1) will be X'78563412'.
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.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.
Revisiting the example in Figure 109 on page 246, here is another way to round an integer to the
next higher multiple of 8 if it is not already a multiple of 8.
SR 7,7 Clear GR7 to zero
SRDL 6,3 Shift three bits into GR7 from GR6
LTR 7,7 Test whether the bits are zero
BZ A Branch if yes
A 6,=F'1' If not, add 1 to GR6
A SLL 6,3 Finally, multiply GR6 by 8
First, we clear GR7 by subtracting it from itself, a fast and simple way to do this. Then, we use a
shift instruction to divide by 8. The double-length shift moves the three βremainderβ bits into the
three high-order bit positions of GR7. The BZ instruction branches only if the remainder bits are
all zero: that is, if the number in GR6 was already a multiple of 8. If any remainder bit is
nonzero, 1 is added to GR6. Finally, GR6 is shifted left 3 bit positions to give the correct mul-
tiple of 8.
As another example, suppose a positive nonzero integer word at N is to be shifted right as many
places as necessary to ensure that its rightmost bit is nonzero. Here are two ways we might do
this:
1. Shift left from GR5 into GR4, until only zero-bits remain in GR5. That is, if two right shifts
of the integer at N were actually needed, we will do 30 double-length left shifts.
248 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
2. This time, we shift right, testing βlostβ bits:
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
System z branch instructions simplify coding of loops.111
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.)
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:
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 on page 250, the comment state-
ments 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 on page 250, a letter βxβ repres-
ents a bit whose value is 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 162, 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.
111 These special βBranch on Indexβ and βBranch on Countβ instructions neither examine nor change the CC. We will
investigate them in Section 22.
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.
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.
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.
250 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
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 illus-
trated in Figure 115 on page 249. Write a code sequence to rearrange the four unsigned inte-
gers 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 on page 249.
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.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 X'12345678' by 12 bit positions would produce X'45678123'. Write instructions
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 in GR0
L 2,=A(Hex) Addr of start of hex string in GR2
L 3,=A(Chars) Addr of start of char string in GR3
GetAByte SR 4,4 Clear GR4 for a work register
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,EBCDIC(4) Get character form of high digit
IC 5,EBCDIC(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,B'0011',0(3) Store both chars in output string
AH 2,=H'1' Increment input pointer
AH 3,=H'2' Increment output pointer
SH 0,=H'1' Reduce input byte count by 1
BP GetAByte If count > 0, do another byte
- - -
EBCDIC DC C'0123456789ABCDEF' EBCDIC form of hex digits
Does this work? Explain.
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':
252 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
L 0,=F'-8' L 0,=F'-8'
SRL 0,2 SRA 0,2
After the SRL logical shift, c(GR0)=X'3FFFFFFE', 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 on page 252, 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 32-bit number in GR0
SRDA 0,32 Sign-extend to 64-bit length in (GR0,GR1)
D 0,Divisor Divide by 32-bit number
The sign bit of the word at Dividend has been extended by the SRDA instruction to fill GR0.
For arithmetic left shifts, the situation is a little more complicated, as we saw in Figure 108 on
page 244. When an operand is shifted left one or more significant bits may be lost; though lost,
they are not ignored! An arithmetic left shift (1) always retains the original sign bit, and (2) indi-
cates 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 Inter-
ruption Code set to 8.
The following instructions will produce the results indicated in the remarks fields:
L 0,=F'-8' c(GR0)=FFFFFFF8, CC unchanged
SRL 0,2 c(GR0)=3FFFFFFE, CC unchanged
SLA 0,4 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,B'1110',0(12) c(GR5) = X'F01234??'
SRA 5,8 c(GR5) = X'FFF01234'
- - - Compute something
STCM 5,B'0111',0(12) Store result back
As indicated in Table 81 on page 252, 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 arith-
metic 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:
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 9,4 SRL 9,4
SLA 9,4 SLL 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 inte-
gers as required; we again use the symbols LA, LB, LC, and LD to represent the bit lengths of
the fields, as in Figure 117 on page 250.
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 0,=A(X'12345678') c(GR0) initialized
SRA 0,9 c(GR0) = X'00091A2B'
The contents of GR0 is changed. For these instructions,
LG 1,=AD(X'123456789ABCDEF0') c(GG1) initialized
SRAG 0,1,9 c(GG0) = X'00091A2B 3C4D5E6F'
the contents of the source register, GG1, is unchanged. If we initialize the source register with a
negative number, the sign bit is propagated:
L 0,=A(X'87654321') c(GR0) initialized
SRA 0,9 c(GR0) = X'FFC3B2A1'
and the contents of GR0 is changed. For these instructions,
LG 1,=XL8'FEDCBA9876543210' c(GG1) initialized
SRAG 0,1,9 c(GG0) = X'FFFF6E5D 4C3B2A19'
GG1 is again unchanged.
254 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
Left arithmetic shifts may cause overflow:
L 0,=A(X'87654321') c(GR0) initialized
SLA 0,9 c(GR0) = X'CA864200', 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.10.(3) Rewrite the code sequence of Exercise 17.3.9 assuming that the integers may be pos-
itive 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 is 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
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 253, 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) Repeat 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:
(1) SRAG 0,0,20
(2) SLAG 0,0,28
(3) SRA 0,18
(4) SRLG 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 X'87654321' 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 Condi-
tion 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.
17.4.21.(2) + You can use SRA to divide a number by 2. But if the number is negative, the
result isn't always what you expect. For example:
L 0,=F'+5' c(GR0) = X'00000005' = +5
SRA 0,1 C(GR0) = X'00000002' = +2
L 0,=F'-5' c(GR0) = X'FFFFFFFB' = -5
SRA 0,1 C(GR0) = X'FFFFFFFD' = -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?
256 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
17.5. Rotating Shifts
Unlike the shift instructions we've seen, the rotating shift instructions RLL and RLLG neither
lose nor introduce bits. A rotate unit shift takes the leftmost bit of the register, shifts all the other
bits left one position, and inserts the previous leftmost bit at the right end of the register, as illus-
trated in Figure 120.
βββββββ¬ββββββ¬ββββββ¬ββββββ¬β β β ββ¬ββββββ¬ββββββ¬ββββββ¬ββββββ
ββββΌ b β c β d β e β ββ β x β y β z β a βΌββ After
β βββββββ΄ββββββ΄ββββββ΄ββββββ΄β β β ββ΄ββββββ΄ββββββ΄ββββββ΄ββββββ β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Figure 120. Logical rotate unit shift
As shown in Table 80 on page 243, the source operand in R 3 and the target operand in R1 can
be the same or different registers. If they are the same, the shift does not preserve the original
operand.
The rotating shift instructions are sometimes used in data compression algorithms. In applications
where speed of rotation is not important, their functions can be βemulatedβ using logical shifts.
(See Exercises 17.5.1 and 17.5.2.)
To illustrate a rotating shift, suppose we rotate the 32-bit operand X'56789ABC' left by 10 bit posi-
tions:
L 0,=A(X'56789ABC') Load initial data into GR0
RLL 1,0,10 Rotate 10 bits, result in GR1
Then c(GR1) will be X'E26AF159'. Similarly, if we rotate the 64-bit operand X'56789ABCDEF01234'
left by 10 bit positions:
LG 0,=AD(X'56789ABCDEF01234') 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.
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.
Suppose GR1 contains a nonnegative integer less than 31; call it βnβ. Then, to leave 2 n in GR0,
we could write
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 Absolute expression for base in GR2
A EQU 10 Symbol with absolute value
* Assembled instructions:
SLL 9,12 8990 2006 (implied address) 12 shifts
SLL 9,12(0) 8990 000C (explicit address) 12 shifts
SLL 9,A 8990 2004 (implied address) 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; it's far better to use an instruc-
tion 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 con-
tents 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:
USING *,2
A EQU *
SLL 9,A
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 con-
vention 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 corre-
sponding 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
258 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
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 System z 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. L
2. BC
3. LH
4. ICM
5. LR
6. SRDA
7. STM
8. STC
We first encountered length modifiers for binary constants in Section 11.4 on page 140, where we
defined constants like
DC FL3'8'
Such length modifiers determine the byte length of the constant.
You can also define the bit length of a constant by writing a length modifier specifying the
number of bits allotted to its assembled value; follow the modifier letter L with a period and the
number of bits. For example:
DC FL3'8' can also be written
DC FL.24'8'
The same constant will be generated in both cases, aligned on the current location counter
boundary (not necessarily a word boundary).
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.
Now we can see how to generate the βpackedβ unsigned binary integers in Figure 115 on
page 249. Suppose the four integers A, B, C, and D have values 432, 12, 5001, and 47 respec-
tively. We can define a word containing these values as shown in Figure 121.
UnsdVals DC 0F,FL.9'U432',FL.4'U12',FL.13'U5001',FL.6'U47'
Figure 121. Packing four unsigned bit-length constants in a 32-bit word
Similarly, if the four values could be signed, with values β 232, β 8, β 4001, and β 31 respectively,
we could define a word containing their values as shown in Figure 122.
SgndVals DC 0F,FL.9'-232',FL.4'-8',FL.13'-4001',FL.6'-31'
Figure 122. Packing four signed bit-length constants in a 32-bit word
Exercises
17.7.1.(1) What differences might you find for these constants?
A DC F'-97'
B DC FL4'-97'
C DC 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.4.(3) + Rewrite the constant definitions in Figures 121 and 122 to use the symbolic defi-
nitions of the four field lengths named LA, LB, LC, and LD respectively, as shown in
Figure 117 on page 250.
17.7.5.(2) + If you can't 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?
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.
260 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
Mnemonic Opcode Mnemonic Opcode Mnemonic Opcode
RLL EB1D SLDL 8D SRDA 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:
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
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.
Problem 17.3.(1) Using the instructions in Figure 119 on page 254, write a program to unpack
the four signed integers of Figure 122 on page 260 at the word named SgndVals and display
the unpacked values at First, Second, Third, and Fourth as fullword integers.
262 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
Chapter V: Basic Instructions 263
18. Binary Multiplication and Division
11 8888888888
111 888888888888
1111 88 88
11 88 88
11 88888888
11 88888888
11 88 88
11 88 88
11 88 88
1111111111 888888888888
1111111111 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, 999Γ999 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.
264 Assembler Language Programming for IBM System zβ’ Servers Version 2.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 regis-
ters), β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 on page 264 indicates, there are no instructions giving a 128-bit arithmetic product
of two signed 64-bit operands.112
Condition Code
Binary multiplication and division do not change the CC setting.
Signed multiply instructions are the most frequently used, so we'll discuss them first.
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).
ββββββββββββββββββββββββ
β 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
on page 266.
112 At the time of this writing. But new instructions are added regularly to the System z architecture, so check the Princi-
ples of Operation. However, you can generate signed products using the unsigned multiply instructions; see Exercises
18.3.2 and 18.3.3.
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 odd-
numbered 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 c(GR2,GR3) = c(GR3) * c(GR7)
* Square the number in GR1
MR 0,1 c(GR0,GR1) = c(GR1) * c(GR1)
MR 8,8 c(GR8,GR9) = c(GR9) * c(GR8)
M 4,XX c(GR4,GR5) = c(GR5) * c(XX)
M 12,=F'932' c(GR12,GR13) = c(GR13) * 932
* Square the number in GR4
LR 5,4 Move multiplicand to GR5
MR 4,4 c(GR4,GR5) = c(GR5) * c(GR4)
The last two instructions show how to square the integer in GR4: the LR instruction copies the
multiplier to the odd-numbered register. The presence of the multiplier in the even-numbered
register does not cause it to be lost when that register is cleared at the beginning of the multiply
sequence; the multiplication takes place after the CPU has saved a copy of the multiplier. After
the LR we could also have used βMR 4,5β, giving c(GR5)Γc(GR5).
The product generated by the M and MR instructions is 64 bits long. If we perform these
instructions:
L 1,=A(X'10000') c(GR1) = 65536 = 2**16
MR 0,1 Square it to get 2**32
ST 1,Product Store low-order half
- - -
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 1,=A(X'10000') c(GR1) = 65536
M 0,=A(X'8000') Multiply by 32768; result = +2**31
ST 1,Product Store +2**31 (??)
we would find that c(GR0)=0, and c(Product) = β 231!
There are two situations needing caution. First, the product may be so long that significant bits
occupy more than the low-order register. Second, whether or not the high-order register contains
significant bits, the leftmost bit of the low-order register can be interpreted as a sign bit only if the
product lies in the range
-231 β€ product < +231
Otherwise, the low-order sign bit contains an arithmetically significant digit with positive weight.
266 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
L 7,G c(GR7) = c(G)
M 6,D c(GR6,GR7) = G * D
A 7,B c(GR7) = B + (G*D)
ST 7,A 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.113
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.
SR 5,5 Sum carried in GR5
L 4,=F'1' Initialize K in GR4
Repeat LR 1,4 c(GR1) = K
MR 0,1 c(GR0,GR1) = K * K
MR 0,4 c(GR0,GR1) = K cubed
AR 5,1 Accumulate sum
A 4,=F'1' Increment K
C 4,NBR Compare to upper limit at NBR
BNH Repeat Repeat if K is not bigger
ST 5,Sum Store sum of first N cubes
- - -
NBR DC F'10' N
Figure 125 shows a slightly different version of this example; it counts from N down to 1:
When you know a product will be small enough to fit correctly in a single-length register, or if
you don't care that some high-order bits may be lost, these instructions avoid needing an
even-odd register pair, and may also execute faster than the instructions generating double-length
products.
113 These distinctions are very important in Assembler Language, and can be very confusing to people whose first pro-
gramming experiences were with high-level languages.
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,=H'100' Multiply c(GR5) by 100
is a simple way to multiply the contents of GR5 by 100 without affecting the contents of the
lower even-numbered register, GR4. If X and Y are both halfword operands, their product may be
found by writing
LH 8,X Multiplicand in GR8 (even register!)
MH 8,Y Multiply by c(Y), product in GR8
and GR9 remains undisturbed. To square the halfword integer at N, we could write
LH 1,N c(N) in GR1
MH 1,N 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 we've 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 1,=F'12345' c(GR1) = 12345
MS 1,=F'12347' c(GR1) = 152423715
MSG and MSGR, and MSGF and MSGFR produce a 64-bit product in a single 64-bit register.
MSG and MSGR are exact analogs of MS and MSR:
LG 1,=FD'12345678' c(GG1) = 12345678
MSG 1,=FD'23456789' c(GG1) = 289589963907942
MSGF and MSGFR generate a 64-bit product of a 64-bit first operand and a 32-bit second
operand by first internally sign-extending the 32-bit second operand to 64 bits:
268 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
LG 1,=FD'12345678' c(GG1) = 12345678
MSGF 1,=F'23456789' c(GG1) = 289589963907942
Exercises
18.2.1.(1) + What is the value of the largest 64-bit product that can be generated by signed mul-
tiplication 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 mul-
tiplication of 32-bit and 16-bit operands? The largest 96-bit value generated by signed multipli-
cation of 32-bit and 64-bit operands?
18.2.4.(3) + Write a sequence of instructions that forms the product of the positive word inte-
gers 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 even-
numbered register. However, the multiplicand is actually in the next higher odd-numbered reg-
ister. Can you think of any reasons why the designers of System z 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?
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?
L 1,X Load first operand
M 0,Y Multiply by second operand
LTR 0,0 Check high-order 32 bits
BZ ProdOK If they're zero, product fits
- - - Not OK
X DC F'...'
Y DC F'...'
18.2.14.(3) + You have created a signed binary product in (GR0,GR1) using instructions like
L 1,X
M 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.
Logical multiply instructions are similar to arithmetic multiply instructions, except that the oper-
ands 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 required114. Although you can use arithmetic multiplication instructions to gen-
erate logical products, and logical multiplication instructions to generate arithmetic products, extra
114 Some encryption and decryption algorithms use multiple-precision arithmetic extensively.
270 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
instructions and time are needed.115 It's simplest to use whichever instruction is best suited to the
type of operand.
For example, suppose you multiply the maximum negative 32-bit number by itself using arith-
metic and logical multiply instructions:
* Arithmetic multiplication
L 1,=X'80000000' c(GR1) = -2147483648
MR 0,1 c(GR0,GR1) = X'40000000 00000000'
* Logical multiplication
L 1,=X'80000000' c(GR1) = +2147483648
MLR 0,1 c(GR0,GR1) = X'40000000 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, let's 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) = X'00000000 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 regis-
ters:
LG 1,=FD'74296604373' c(GG1) = 74296604373
MLG 0,=FD'9876543210' c(GG0,GG1) = 733793623446209457330
Exercises
18.3.1.(1) What is the value of the largest 64-bit product that can be generated by logical multi-
plication 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 229, form the product of the two 256-bit integers at
A256 and B256 to form a 512-bit product stored at Prod256.
When working with pencil and paper, we form the product of the multiplier and each of the mul-
tiplicand digits in succession, and generate a series of partial products that must be properly
aligned and then added:
Multiplicand 213
Multiplier Γ 126
partial 1278
products 426
213
Product 26838
We'll 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 000 213
Add multiplier to upper end +126
that's 1 time 126 212, count down at right
Add multiplier +126
that's 2 times 252 211, count down at right
Add multiplier +126
that's 3 times 378 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 037 821
Add multiplier +126
that's 1 time 163 820, count down at right
4. After the second shift, the final multiplicand digit is 2:
Shift right one place 016 382
Add multiplier +126
that's 1 time 142 381, count down at right
Add multiplier +126
that's 2 times 268 380, count down at right
Shift right one place 026 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 double-
length register, and all multiplicand digits have been shifted off the right-hand end.
272 Assembler Language Programming for IBM System zβ’ Servers Version 2.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 B'00110'
(=6) by B'01001' (=9) to obtain a 10-bit product in a double-length register. The sequence of
steps in Figure 126 shows how this is done.
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 two's 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.116 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 product's sign bit is the left-
most 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 mul-
tiplier in many fewer steps. This increases the speed of multiplication, since a separate addition is
not required for each 1 bit in the multiplicand.
116 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.
While multiplying two n-digit numbers usually gives a 2n-digit product, dividing a 2n-digit divi-
dend by an n-digit divisor does not necessarily produce an n-digit quotient. If for example we use
3-digit decimal numbers, 999Γ999=998001; but 998001Γ· 100 gives quotient 9980 and remainder 1,
with a 4-digit quotient.
If the divisor is zero, or if the quotient is too large to fit in a single-length register, a Fixed-Point
Divide interruption will occur, with Interruption Code 9. This condition cannot be suppressed (as
can Fixed-Point Overflow). It is important to be careful when preparing for division!
The 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,32β32+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,64β64Γ· 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,64β128Γ· 64), nor instructions (like DS, DSR)
for dividing 32-bit signed operands by 32-bit divisors.117
When any division instruction completes without interruption, the quotient is found in the odd-
numbered register of the pair, and the remainder in the even-numbered register, as illustrated in
Figure 127.
R1 R1+1
ββββββββββββββββββββββββββββββββββββββββββββββββ
β Remainder ββ Quotient β
ββββββββββββββββββββββββββββββββββββββββββββββββ
Figure 127. General result of divide operation
117 At the time of this writing. But new instructions are added regularly to the System z architecture, so check the Princi-
ples of Operation.
274 Assembler Language Programming for IBM System zβ’ Servers Version 2.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.
Exercises
18.5.1.(2) + If you divide an ND-digit dividend (numerator) by a DD-digit divisor (denomi-
nator), 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.
The Divide Single instructions (DSG, DSGR, DSGF, and DSGFR) have only a single-length
dividend; we'll examine them shortly.
ββββββββββββββββββββββββ
β 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 single-
length 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 reg-
ister 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 divi-
dend 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.)
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 can't 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.
Suppose we want to divide the positive or negative word integer at G by three, and store the
quotient at 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.)
L 3,A c(GR3) = c(A)
M 2,B c(GR2,GR3) = c(A) * c(B)
D 2,=F'29' Quotient in GR3
LTR 2,2 Test remainder in GR2
BZ Mult Branch if c(GR2) is zero
A 3,=F'1' increase quotient by 1
Mult M 2,=F'29' Form correct multiple of 29
ST 3,Result Store proper result
This example assumes the final product is correctly represented in the 32 bits of GR3.
276 Assembler Language Programming for IBM System zβ’ Servers Version 2.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.
Here's an example of rounding the quotient of a signed dividend:
See Exercise 18.6.13 for a more general technique for calculating a rounded quotient.
A simple check can be made to ensure that a fixed-point divide interruption does not occur: if the
inequality
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 .
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 X'80000000', which is not representable as a positive
number for signed division.
Because 236 is not less than 10Γ231, a fixed-point divide interruption will occur.
Even though the dividend is in the odd-numbered register, the instruction must specify the even-
numbered register as the R1 operand. This is illustrated in Figure 134 on page 278.
ββββββββββββββββββββββββ
β Divisor β R2 or D2(X2,B2)
ββββββββββββββββββββββββ (in register or memory)
Figure 134. Operands of single-length division before division
The same divisions using DSGF and DSGFR with 32-bit divisors are very similar:
LG 5,=FD'12345678901' c(GG1) = 12345678901
DSGF 4,=F'777' Divide by 777 (32-bit divisor)
Note that for single-length division, there is no need to initialize the even-numbered register R1.
Exercises
18.6.1.(2) In the inequality in Figure 132 on page 277 that assures that a division will be
correct, explain the factor of 231. Why isn't it a factor of 232?
18.6.2.(4) Suppose n is the number of some register. Under what circumstances will DR n,n not
cause a program interruption?
278 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
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.
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
on page 276?
18.6.6.(2) Rewrite the example in Figure 130 on page 276 to round the result by adding 5
before dividing by 10. Determine carefully whether or not there might be a carry from the addi-
tion into the high-order register.
18.6.7.(2) Rewrite the example in Figure 131 on page 277 to round the dividend before
dividing by adding or subtracting 5. Determine carefully how to handle a possible carry or
borrow from the low-order 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 on page 277 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 on page 276 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 4,4 Clear high-order word
D 4,=F'2' Divide c(GR5) by 2
Find a simpler way to do this.
18.6.13.(3) + Write an instruction sequence showing how to calculate a rounded integer quotient
using 32-bit operands, without knowing the magnitude of the divisor.
18.6.14.(2) + A table of 15 reasonably small halfword grades is stored starting at Grades. Write
instructions to compute their average value and store it at AvgGrade.
If both dividend and divisor are positive, logical and arithmetic division generate the same results.
For example, dividing X'00000000 FFFFFFFF' by 3 generates quotient X'55555555' and remainder 0
for both types of division.
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 nega-
tive number (X'80000000') by β1 (X'FFFFFFFF') is invalid; but a logical division using the same
operands gives quotient zero and remainder X'80000000' (because 231 is smaller than 232 β 1).
Here is a case that succeeds for arithmetic division but fails for logical division:
L 0,=X'80000001' Set GR1 to -2**31+1
SRDA 0,32 Extend to 64 bits in (GR0,GR1)
D 0,=F'-1' Arithmetic division
The remainder is 0 and the quotient is + 231 β 1, as you would expect. For a logical division, the
dividend is (264 β 231 + 1) and the divisor is 232 β 1, which leads to a fixed-point divide interruption
because the quotient is greater than 232 β 1. As another example, consider
As a final example:
L 0,=X'FFFFFFF8' Initialize GR0
LR 1,0 And GR1, with the same bits
DL 0,=X'FFFFFFFF' Divide by 2**32-1
The quotient is X'FFFFFFF9' and the remainder is X'FFFFFFF1'.
Exercises
18.7.1.(4) Show how you can use logical division instructions to generate the results that would
be obtained by using arithmetic division instructions with the same operands.
Since we start with a dividend and divisor and wish to find a quotient and remainder that satisfy
the equation
dividend = quotient Γ divisor + remainder
The dividend must be a double-length number.
Supposing again that our basic register length is three decimal digits, a requirement on the divi-
dend is clear: because (a) the quotient, to fit in a register, can be at most three digits long (that is,
not exceeding 999) and (b) the remainder must be less than the divisor, we must not have a divi-
dend larger than
280 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
999 Γ divisor + (divisor-1) = 103 Γ divisor - 1.
The factor of 10 3 is the base (10) raised to the power of the number of available digits (3). Since
multiplication by 10 3 in this example is equivalent to shifting left three places, the above relation
means that if the division is to produce a valid quotient, the high-order half of the dividend must
be less than the divisor. To illustrate: if the divisor is 456, then any dividend not smaller than
456000 = 10 3 Γ 456 would produce a 4-digit quotient; if the dividend is less than or equal to
455999 = 10 3 Γ 456 β 1, the quotient can be held in three digits. Note that the three high-
order 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 762Γ213+537=162843. Using decimal registers, the division works
like this:
162 843 High-order part of dividend less than divisor,
762 division may proceed.
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 B'00001 11011' (=59), and let the divisor be B'00110'
( = 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.
We now illustrate the binary division of 59 by 6 in Figure 137, with less detail than in the multi-
plication example.
Thus the remainder B'00101' (=5) is in the left half, and the quotient B'01001' (=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.
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:
For cases (2) and (3), show how the System z 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?
1. AR n,n
2. MR n,n
3. DR n,n
282 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
18.9. Summary
Table 90 summarizes the multiply instructions we've discussed here.
Product length
32 32 + 32 64 64 + 64
Func- (bits)
tion Operand 1 length 32 32 64 64
Operand 2 length 16 32 32 32 64 64
MH MS M MSGF MSG
Arithmetic Γ
MSR MR MSGFR MSGR
ML MLG
Logical Γ
MLR MLGR
Table 90. Summary of multiply instructions discussed in this section
The divide instructions discussed in this section are shown in Table 91.
The instruction opcodes and mnemonics are shown in the following table:
Programming Problems
Problem 18.1.(2) Write an Assembler Language program that finds the largest integer divisor x
of the integer function
f(n) = n3 - 1,
for values of n running from 2 to 8 in steps of 1, and such that βxβ is less than f(n). Your
program should search for the divisor, and not compute it from the known factors of f(n).
Problem 18.2.(3) Write an Assembler Language program to compute and print the values of Xn
and the quotient and remainder of the fraction
(Xn)**2 + 10727*Xn - 14
2*Xn - 5
where Xn is given by Xn = 2**(3*n), for n = 1, 2, ..., 10.
284 Assembler Language Programming for IBM System zβ’ Servers Version 2.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 X'80000000').
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:118
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
As a general rule, the number of digits to be generated is the same as the number of terms you
evaluate.
Write a program to generate the first 50 fraction digits of e, and print the value of the constant.
Problem 18.10.(2) + Write a program that searches for and prints the 25 prime numbers less
than 100.
Problem 18.11.(2) Write a program that creates a base-seven multiplication table like the one
you made for Exercise 2.4.6.
286 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
Chapter V: Basic Instructions 287
19. Logical Operations
11 9999999999
111 999999999999
1111 99 99
11 99 99
11 99 99
11 999999999999
11 999999999999
11 99
11 99
11 99 99
1111111111 999999999999
1111111111 9999999999
In this section we'll 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. 119
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 oper-
ands in memory and in the general registers using βlogicalβ instructions. The instructions in this
section are shown in Table 92.
There is no difference between operations involving 32- and 64-bit registers, so we'll describe only
the 32-bit forms. You can easily extend the 32-bit operations to their 64-bit equivalents.
119 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).
288 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
19.1. Logical Operations
Unlike logical arithmetic, in which carries and borrows may propagate from a bit position to one
or more of its higher-order neighbors, boolean logical operations always operate on pairs of bits,
with no interactions among neighboring bits.
The three logical operations provided by System z are AND, OR, and Exclusive OR, abbreviated
βXORβ. These operations between pairs of bits produce a result depending only on the values of
the two bits participating in the operation. The effect of the three operations is given in
Figure 138. In each box, the two bits participating in the operation are given in the left column
and the top row; the result bit is at the intersection of the corresponding row and column.
β’ 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). 120
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 repres-
entations 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.
Operation CC setting
AND
0: all result bits are zero
OR
1: result bits are not all zero
XOR
Table 93. CC settings by logical instructions
120 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β.
To see in more detail how these results are obtained, examine the fourth hexadecimal digit (3 and
9) for each case:
AND OR XOR
3 0011 3 0011 3 0011
9 1001 9 1001 9 1001
1 0001 B 1011 A 1010
Figure 139. Examples of logical operations
Exercises
19.2.1.(1) The CC settings after the logical operations indicate whether or not the result is or is
not completely zero. Can you think of any reason why a CC setting to indicate a result of all
1-bits was not provided in the design of System/360?
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.)
L 1,DataWord B'aaaaaaaaabbbbcccccccccccccdddddd'
N 1,Mask1 B'0000000000000ccccccccccccc000000'
SRL 1,6 B'0000000000000000000ccccccccccccc'
ST 1,Third Store desired third integer
- - -
Mask1 DC 0F,BL4'1111111111111000000' Mask: 13 0's 13 1's, 6 0's
290 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
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.
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
mask's 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 on
page 289.
Exercises
19.3.1.(1) + In the second example in Section 15.2 on page 205, shifts were used to set the left-
most 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 0,DataWord Get 4 packed integers
SRDL 0,6 Move fourth into GR1
L 0,NewThird Get new value of third integer
SRDL 0,13 Move it in with fourth
L 0,DataWord Get integers again
SRL 0,19 Drop old third and fourth
SRDL 0,13 Move full word into GR1
ST 1,DataWord Store updated result
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
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.
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, don't 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.
We can rewrite Figure 140 on page 291 (in a somewhat roundabout way) to use an X instruc-
tion:
The O instruction first sets all bits in the third integer's position to 1-bits, and the X instruction
then resets them all to zero. We'll see another use of this technique in Figure 143 on page 293.
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.
121 This is a very efficient way to zero a general register, because (unlike subtracting the register's contents from itself),
the CPU need not check for a possible overflow.
292 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
A 7,=F'7' Force carry if any 1s in low 3 bits
N 7,=F'-8' Now, set last 3 bits to zero
Figure 142. Rounding to the next multiple of 8
That is a faster method, but space is required for the two constants. We can also use the βOR
then XORβ technique:
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.
XR 8,8 Set shift count in GR8 to zero
Shift SLA 6,1 Shift left one bit position
BO Finish Branch if overflowed
AH 8,=H'1' Increment shift count
B Shift Try again
Finish SRA 6,1 Reposition
X 6,Digit Restore the lost bit
ST 8,Norm Store shift count
- - -
Norm DS F Storage space and alignment
Digit DC X'40000000' Mask bit for lost bit
We shift left until the overflow condition indicates that a bit different from the sign bit has been
shifted out of bit position 1. The following right shift moves everything back in place, but instead
of restoring the lost bit, extends the sign bit into the second bit position of R6, from which the
most significant bit was just lost. Since the sign is known to be the opposite of the lost bit, the X
operation inverts the second bit to give the correct result.
We can form the ones' complement of the number in GR7 by subtracting it from a word of all
1-bits, or by executing
X 7,=F'-1'
that does the same thing more simply. Thus, we can use the X instruction to form the two's
complement of a double-length integer, as in Figures 90 and 91 on page 226.
This is definitely not the most efficient way to form a complement, but does show one use of
XOR.
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 oper-
ations, a logical AND operation, but no OR or Exclusive OR. 122 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.6.(2) Rewrite Figure 142 on page 293 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 on
page 292.
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.)
122 This was true of some very early βVon Neumannβ or βInstitute-typeβ processors like the ILLIAC 1.
294 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
19.6. Interesting Uses of Logical Instructions (*)
The examples of logical instructions in the previous sections show βnormalβ uses. You can do
some other interesting things with them; we will illustrate a few.123
1. Test a nonzero, nonnegative number to see if it's a power of 2:
Y = ((2*X)-1) AND X) XOR X
If Y is zero, X is a power of 2. (Note that if X is zero or is the maximum negative number,
Y = 0 . ) To illustrate:
L 0,=F'5' X in GR0 X'00000005'
LR 1,0 Copy X to GR1 X'00000005'
SLL 1,1 2*X X'0000000A'
S 1,=F'1' (2*X-1) X'00000009'
NR 1,0 (2*X-1) AND X X'00000001'
XR 1,0 ((2*X-1) AND X) XOR X X'00000004'
JZ PowerOf2 Branch if a power of 2
so that 5 is not a power of 2.
2. Isolate a number's rightmost 1-bit. If X is a nonzero, nonnegative number:
Y = (((X-1) XOR X)+1)/2
then Y is the rightmost 1-bit of X. To illustrate:
L 0,=F'6' X in GR0 X'00000006'
LR 1,0 Copy X to GR1 X'00000006'
S 1,=F'1' (X-1) X'00000005'
XR 1,0 (X-1) XOR X X'00000003'
A 1,=F'1' ((X-1) XOR X)+1 X'00000004'
SRL 1,1 Y=(((X-1) XOR X)+1)/2 X'00000002'
which is the rightmost bit of 6 = B'00...0110'. If X is zero or the maximum negative
number, Y will be zero.
3. Turn off the rightmost 1-bit of a positive binary number X:
Y = X AND (X-1)
To illustrate:
L 0,=F'6' X in GR0 X'00000006'
LR 1,0 Copy X to GR1 X'00000006'
S 1,=F'1' (X-1) X'00000005'
NR 1,0 (X-1) AND X X'00000004'
If this process is repeated, the number of iterations is determined by the power of two
represented by the leftmost 1-bit.
4. Right-propagate the rightmost 1-bit of a nonzero word:
Y = X OR (X-1)
To illustrate:
L 0,=F'12' X in GR0 X'0000000C'
LR 1,0 Copy X to GR1 X'0000000C'
S 1,=F'1' (X-1) X'0000000B'
OR 1,0 (X-1) OR X X'0000000F'
5. Isolate the rightmost 1-bit of a word:
Y = X AND (-X)
To illustrate:
123 Some of these examples are based on IBM Thomas J. Watson Research Center Report RC 5809 Functions
Realizable with Word-Parallel Logical and 2's-Complement Addition Instructions by Henry S. Warren, Jr.
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.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.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
296 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
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.7. Summary
Table 94 gives a compact summary124 of the three logical operations:
Anything with
Operation
One Zero Itself
It remains It is changed to It remains
AND
unchanged zero unchanged
It is changed to It remains It remains
OR
one unchanged unchanged
It remains It is changed to
XOR It is inverted
unchanged zero
Table 94. Summary of the logical operations AND, OR, XOR
The instruction opcodes and mnemonics are shown in the following table:
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))
298 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
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 per-
forming 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 com-
plete, you can 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 oper-
ations 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
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 (50 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'00' Space for 400 bits
so that an appropriate single statement will print the entire string of 100 hexadecimal digits, that
should start with X'EA28...', representing 1, 2, 3, 5, 7, 11, 13, ....
If you wish, you may compute the final bit string directly, without having to go through the
intermediate steps of forming a byte table.
Problem 19.6.(2) Choose an example from Section 19.6 on page 295 and write a program to
test the given formula for a range of values.
300 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
Chapter VI: Addressing, Immediate Operands, and Loops
VV VV IIIIIIIIII
VV VV IIIIIIIIII
VV VV II
VV VV II
VV VV II
VV VV II
VV VV II
VV VV II
VV VV II
VV VV II
VVVV IIIIIIIIII
VV 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 pro-
grams 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.
2222222222 00000000
222222222222 0000000000
22 22 00 00
22 00 00
22 00 00
22 00 00
22 00 00
22 00 00
22 00 00
22 00 00
222222222222 0000000000
222222222222 00000000
For RSY-type instructions the X 2 field is replaced by an R3 field, but that doesn't affect address
generation other than not supporting indexing.
302 Assembler Language Programming for IBM System zβ’ Servers Version 2.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.
β ββ¬ββββ¬ββββ¬ββββββββββββ¬βββββββββ¬β β
Instruction β x β b β DL βs DH β
β ββ΄ββββ΄ββββ΄ββββββ¬ββββββ΄ββββ¬βββββ΄β β
βββββββββββΌββββββββββ
ββββββββββββββββββββββββββββββββββββββββββββββββββββββ
βββββββββ signβextended ββββββΌs DH β DL β 64βbit signed displacement
ββββββββββββββββββββββββββββ¬ββββββββββββββββββββββββββ
Add to
ββββββββββββββββββββββββββββ΄ββββββββββββββββββββββββββ
β c(base register b) β
ββββββββββββββββββββββββββββ¬ββββββββββββββββββββββββββ
Effective Address
Figure 145. Effective Address generation for long-displacement instructions
In these instructions, the traditional 12-bit unsigned displacement field (named βDβ) is now
named βDLβ, and the high-order 8-bit signed displacement extension is named βDHβ. A 20-bit
signed displacement is formed from DH and DL: DH is concatenated at the left end of DL, and
then sign-extended to 64 bits. This gives a displacement value in the range
0 β€ displacement β€ 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 con-
tents, if applicable.
The Assembler uses the same resolution rules described in Sections 10.9 (on page 127) and 10.13
(on page 132) with one added step:
5. If no nonnegative displacement can be assigned, choose the register giving a negative dis-
placement with the smallest magnitude.
To illustrate, suppose X has value X'2468A0'. 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
Long displacements provide far greater addressability than the traditional 12-bit displacements,
which are limited to 4KB.
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, as shown in Figure 147.
βββββββββββββββββββββββββββββββββββββ β512K
β βββββββββββββββββββββββββββββββββββββ€
β βββββββββββββββββββββββββββββββββββββ€
β βββββββββββββββββββββββββββββββββββββ€
β : :
β : :
1MB βββββββββββββββββββββββββββββββββββββ€ββ Base Register
β βββββββββββββββββββββββββββββββββββββ€
β : :
β : :
β βββββββββββββββββββββββββββββββββββββ€
β βββββββββββββββββββββββββββββββββββββ€
βββββββββββββββββββββββββββββββββββββ +512Kβ1
256 Γ 4KB
Figure 147. Addressability range with 20-bit displacements
With 12-bit unsigned displacements, addressing 1MB could require 256 base registers.
Some RX-type and SI-type instructions have equivalent forms with long displacements. They are
shown in the following table (and some of them will be described later).
12-bit dis- 20-bit dis- 12-bit dis- 20-bit dis- 12-bit dis- 20-bit dis-
placement placement placement placement placement placement
A AY LA LAY S SY
AH AHY LD LDY SH SHY
AL ALY LE LEY SL SLY
C CY LH LHY STCM STCMY
CH CHY LM LMY STC STCY
CL CLY M MY STD STDY
CLI CLIY MH MHY STE STEY
CLM CLMY MS MSY STH STHY
CVB CVBY MVI MVIY STM STMY
CVD CVDY N NY ST STY
IC IC NI NIY TM TMY
ICM ICMY O OY X XY
L LY OI OIY XI XIY
There are many other instructions with long displacements that are not direct extensions of other
RX-type and SI-type instructions.
304 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
20.1.3. Address Generation With Relative-Immediate Operands
The formats of the two relative-immediate instruction types are shown in Tables 97 and 98.
Opcode R1 Op RI 2
Table 97. Format of R-I instructions with 16-bit immediate
operands
Opcode R1 Op RI 2
Table 98. Format of R-I instructions with 32-bit immediate operands
Unlike the arithmetic and logical immediate operands we'll 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 2ΓRI 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.
RI2
ββββββββββββββββ¬βββββββββββββββ
β Opcode, regs βsbbbbbbbbbbbbbβ RIβtype instruction
ββββββββββββββββ΄ββββββββ¬βββββββ
ββ Shift left 1 bit
βββββββββββββββββββββββββββββββββββββββββββββββ΄ββββββββ
ββββββββββββ signβextended ββββββββββΌsbbbbbbbbbbbbb0β 64βbit signed offset
ββββββββββββββββββββββββββββ¬βββββββββββββββββββββββββββ
Add to
ββββββββββββββββββββββββββββ΄βββββββββββββββββββββββββββ
β address of the instruction itself β (Not the PSW's IA!)
ββββββββββββββββββββββββββββ¬βββββββββββββββββββββββββββ
Effective Address
Figure 148. Effective Address formation for relative-immediate instructions
In effect, you have added or subtracted the number of halfwords specified by the RI2 operand to
the address of the instruction.125 The signed RI2 value means that the Effective Address can either
precede or follow the address of the instruction. For 16-bit RI2 fields,
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
125 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β.
For example, a βBranch Relative on Conditionβ instruction (we'll discuss it in Section 22.1)
might look like this:
BRC 8,Target Branch if Condition Code 0
- - -
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 X'174629C' 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
4. 2
20.1.2.(1) The RIL-type instruction at address X'7B1EF0' generates an Effective Address. For
each of the following RI2 operands, show the generated Effective Address. Assume the gener-
ated address is 32 bits long.
1. β1
2. 384593
3. β 512044
4. 3
1. L 0,0(4,7)
2. L 0,3624(4,7)
3. LG 0,4(4,7)
4. LG 0,-8194(4,7)
20.1.4.(1) In Figure 148 on page 305, 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 X'27B9AE'. For each of the fol-
lowing four 2-byte immediate operands, what is the Effective Address of the instruction?
(1) X'0003'
(2) X'FFE4'
(3) X'700F'
(4) X'8000'
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?
306 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
20.2. Addressing Modes
We've seen how an Effective Address is generated; what happens when we use it? The answer
depends on the CPU's current addressing mode, often abbreviated βAModeβ. All the instructions
we've discussed have ignored AMode considerations; we now consider some basic aspects of this
important topic.
System z supports three addressing modes: 24-bit, 31-bit, and 64-bit. 24-bit addressing was used
in the original System/360, when memory was very expensive: a large processor may have had as
much as 256K bytes of storage, and many had far less.126 24-bit addresses could reference up to
224 (16 million) bytes, which seemed so large that 24-bit Effective Addresses were expected to be
enough for a very long time. Continued application growth was managed by adding virtual
addressing facilities in the early 1970s, but addresses were still limited to 24 bits.127
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 appli-
cations 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 parti-
tioning 128 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 address-
able 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 System z, 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 Addresses:
β’ in 24-bit mode, the leftmost 40 bits of the Effective Address (0-39) are set to zero, leaving the
rightmost 24 bits intact.
0 39 40 63
ββββββββββββββββββββββββββββββββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββ
β ββ 00000 .... 00000 ββ
β β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββ΄ββββββββββββββββββββββββββββββββββ
ββββββββββββββ ignored βββββββββββββββββββββββββββ
ββββββββ 24βbit address βββββββ
β’ in 31-bit mode, the leftmost 33 bits of the Effective Address (0-32) are set to zero, leaving the
rightmost 31 bits intact.
0 33 63
βββββββββββββββββββββββββββββββββββββββββββββ¬βββββββββββββββββββββββββββββββββββββββββββ
β ββ 00000 ..... 00000 ββ
β β
βββββββββββββββββββββββββββββββββββββββββββββ΄βββββββββββββββββββββββββββββββββββββββββββ
ββββββββββββββ ignored ββββββββββββββββββ
ββββββββββββ 31βbit address ββββββββββββ
126 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!
127 Another memory-saving technique was overlay, which we'll describe briefly in Section 38.9.
128 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.
0 63
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
βββββββββββββββββββββββββββββββββββ64βbit 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.
2**64 βββββββββββββββββββββββ
β β
β β β
β β β
: : β Addressable
β β β with AMODE 64
: : β
β β β
β β β
2**31 βββββββββββββββββββββββ€ β ββ the βbarβ
β β β
β β β β Addressable
: : β β with AMODE 31
β β β β
β β β β
2**24 βββββββββββββββββββββββ€ β β ββ the βlineβ
β β β β
: : β β β Addressable with AMODE 24
β β
βββββββββββββββββββββββ
Figure 149. Areas of memory addressed by three AMODEs
Instructions that place or update addresses in the general registers are called βmodalβ instructions,
because the result depends on the addressing mode. We'll see some examples in Section 20.3.
The CPU's current addressing mode is determined by two bits in the Program Status Word,
βBasic addressing modeβ and βExtended addressing modeβ, illustrated in Figure 150.
The meanings of the E and B bit settings are shown in Table 99 on page 309.
308 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
E B Addressing mode
0 0 24-bit mode
0 1 31-bit mode
1 0 Invalid combination
1 1 64-bit mode
Table 99. PSW addressing-mode bits
Almost all instructions that reference operands in memory depend in some way on the current
addressing mode; and instructions that update addresses in registers also depend on the addressing
mode. These are called modal instructions. Other instructions (like AR) are called non-modal
because their results are independent of addressing modes.
In Section 38 we will see instructions used to change addressing modes, and show why attention
to addressing modes can be very important β and very useful..
Exercises
20.2.1.(1) + Suppose c(GG1)=X'00000000 82006A04' and c(GG2)=X'00000000 FFFF8200'. An
RXY-type instruction at address X'629D58' looks like this:
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.
Although we normally wouldn't consider it a logical instruction, Load Address is often classified
that way. The three instructions are listed in Table 100.
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 305. In each
case, the Effective Address replaces the contents of GR R 1.
The affected parts of GR R 1 depend on the CPU's 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 the following LAY instruction is at address X'003B6D0E', and addressability has been
established. Then if we execute
LAY 0,-1 Put -1 in register 0 (?)
the result depends on the addressing mode:
Modal Instructions
LA, LAY, and LARL are modal instructions: the resulting Effective
Address depends on the addressing mode.
In any addressing mode, a nonnegative integer βnβ between 0 and 4095 can be placed in a register
by executing
LA r,n(0,0)
where the displacement contains the constant βnβ. Instead of writing
L 2,=F'1'
requiring 8 bytes (4 for the instruction and 4 for the constant generated by the literal), or
LH 2,=H'1'
requiring 6 bytes, we can write either
LA 2,1 or LA 2,1(0,0)
This requires only 4 bytes and less execution time, because no memory access is required.
Large signed integer values can be placed in a 64-bit register using LAY if the addressing mode is
64-bit, as shown in Figure 151.
Be Very Careful!
The Effective Address will depend on the addressing mode! LAY 0,-1
generates X'00FFFFFF' in 24-bit addressing mode, and X'7FFFFFFF' in
31-bit mode.
310 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
L 0,A L 0,A
A 0,B A 0,B
BNO ST BNO ST
LA 0,0 L 0,=F'0'
ST ST 0,Answer ST ST 0,Answer
Because the LA instruction computes an Effective Address, it also provides a simple way to incre-
ment a number in a register (other than register 0) by a small positive amount. We put the incre-
ment 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.
Be Careful!
Don't 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 248,
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.
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 program's 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 over-
flows occur. Let the integers to be added be stored in successive words beginning at QQ.
Exercises
20.3.1.(1) The LARL instruction has a signed 32-bit RI2 immediate operand. Why can LARL
not be used to load the R 1 register with a large even integer value?
20.3.2.(1) If the CPU is executing in 24-bit addressing mode, show how the LA instruction can
be used as a masking instruction, producing the same result in a register as
N reg,=A(X'FFFFFF')
20.3.3.(1) + Can the first machine instruction in Figure 153 on page 311 be written
LA 9,A(NoErr) ?
20.3.4.(1) + Can the first machine instruction in Figure 153 on page 311 be written
LA 9,=A(NoErr) ?
20.3.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 X'00000006', GR8 should contain X'00000002'. A
student claimed that the following code sequence does the job; prove or disprove that claim.
LA 8,X'100'(0,5)
SRL 8,1(8)
20.3.8.(3) In Figure 151 on page 310, 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:
312 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
L 6,=A(X'FFFFFF')
LA 6,2(,6)
What value will be in GR6?
What value will be in GR6 if the first instruction had been written
L 6,=A(X'FFFFFF00') ?
20.3.10.(2) In Figure 152 on page 311, we might want to initialize GR3 to β 1 using
LAY 3,-1
What reasons might be given for not using LAY?
20.3.11.(2) + If x and y are numbers between 1 and 15, what are the differences between
these two instructions?
LR x,y and LA x,0(0,y)
20.3.12.(3) + Suppose GR15 contains one of the values 0, 4, 8, or 12. Depending on c(GR15),
you want to branch to A, B, C, or D respectively.129 For a program with a base
register providing addressability to the code, you might write
B BList(15) Branch into table of branches
BList B A Branch if c(GR15) = 0
B B Branch if c(GR15) = 4
B C Branch if c(GR15) = 8
B D Branch if c(GR15) = 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 can't use use LA or LAY to increment a small nonnegative number in GR0?
1. Number DC X'1234'
2. Number DC X'ABCD'
Assuming 24-bit addressing mode: what hexadecimal value is left in GR10 by this instruction
sequence?
LH 10,Number
SLL 10,8
LA 10,0(10,0)
SRL 10,8
Now, in 31-bit addressing mode, what hexadecimal value is left in GR10 for each definition of
Number?
1. X'00FE'
2. X'1AF9'
3. X'2109'
129 This is a common convention for handling a βreturn codeβ from a called subroutine.
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 the instructions
shown below. Write a test program with various input values to test his assertion.
LAY 1,-1(1,2)
XR 1,2
N 1,Mask
JNZ Crossed Branch if adding crosses
- - -
Mask DC A(-8192) Negative of power of 2 boundary
Because a 33-bit translation table would be extremely large, the region index is subdivided into
three portions, called βregion firstβ, βregion secondβ, and βregion thirdβ indexes, for which the
mapping tables are more manageable. This is sketched in Figure 155.
11 11 11 11 8 12
ββββββββββββββββββ¬βββββββββββββββββ¬ββββββββββββββββββ¬βββββββββββββββ¬ββββββββββ¬βββββββββββββββββββ
β region 1st β region 2nd β region 3rd β segment β page β byte β
β index β index β index β index β index β index β
ββββββββββββββββββ΄βββββββββββββββββ΄ββββββββββββββββββ΄βββββββββββββββ΄ββββββββββ΄βββββββββββββββββββ
Figure 155. 64-bit Virtual Address with Region Indexes
Fortunately, these details are handled by the operating system so we can focus on our applica-
tions.
20.5. Summary
In this section, we discussed addressing modes and the three instructions shown in Table 101.
314 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
Instructions Discussed in this Section
The instruction mnemonics and opcodes are shown in the following table:
The instruction opcodes and mnemonics are shown in the following table:
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 51 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 52. We'll 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. 130 You may want to compare it to Figure 14
on page 52.
βββββββββββββββββββββββββββββββ
β Registers β
βββ¬ββββββββ¬βββββββββββ¬βββββββ¬ββ
ββββββββββ
RI,β RR β
RILβ β
βββββββββββββββββ΄ββββ βRX,
β Instruction β βRS
βββββββββββββββββ¬ββββ β
SIβ SS β
ββββββββββ
βββ΄ββββββββ΄βββββββββββ΄βββββββ΄ββ
β Memory β
βββββββββββββββββββββββββββββββ
Figure 156. Instruction classes, including RI, RIL
In early processors, the relative speeds of memory accesses and instruction execution using
memory operands were nearly the same. As processor speeds have increased, instructions can
often be completed in much less time than it takes to access memory operands. As this speed
difference has grown, the relative cost of memory accesses has also grown, despite many methods
130 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.
316 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
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 relative-
immediate instructions.
opcode R1 Op I2
Table 102. RI-type instruction
In RIL-type instructions, the immediate operand I 2 occupies a word, the last 32 bits of the 48-bit
instruction.
opcode R1 Op I2
Table 103. RIL-type instruction
Several of the instructions we'll 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.131 This is illustrated in Figure 157.
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.
We'll now investigate these instructions in three groupings: insert and load, arithmetic, and
logical.
131 See the comments at the start of Section 14, on page 178.
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.
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,B'1100',=C'LH' Insert 'LH' into bits 0-15 of GR5
IILH 5,C'LH' The same with an immediate operand
except that IILH avoids a memory reference. Similarly, these two are equivalent:
ICMH 3,B'1111',=F'-3' Insert -3 into bits 0-31 of GG3
IIHF 3,-3 The same with an immediate operand
You can think of the IILF instruction as though it's a βLoad Immediateβ instruction: 132
IILF 11,123456789 has the same result as...
L 11,=F'123456789' so you could even think of it as L
*** LI 11,123456789 ...but not as LI!
These instructions let you insert 16- or 32-bit operands into any halfword or word portion of a
general register without disturbing other parts of the register.
132 But you could implement your own LI macro instruction using the macro instruction capabilities of the Assembler.
318 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
Op Mnem Type Instruction Op Mnem Type Instruction
A78 LHI RI Load Halfword Immediate A79 LGHI RI Load Halfword Immediate
(32β16) (64β16)
C01 LGFI RIL Load Immediate (64β32)
C0E LLIHF RIL Load Logical Immediate C0F LLILF RIL Load Logical Immediate
(high) (64β32) (low) (64β32)
A5C LLIHH RI Load Logical Immediate A5D LLIHL RI Load Logical Immediate
(high high) (64β16) (high low) (64β16)
A5E LLILH RI Load Logical Immediate A5F LLILL RI Load Logical Immediate
(low high) (64β16) (low low) (64β16)
Table 105. Load and insert instructions with immediate operands
The LHI, LGHI, and LGFI instructions are arithmetic load operations, where the I2 immediate
operand is sign-extended from 16 to 32 bits or from 32 to 64 bits, as required by the R1 register
length. They operate just like the corresponding LH, LGH, and LGF instructions, except that
the second operand is found in the I2 field of the instruction rather than in memory. For
example, compare the operation of the LHI instruction in Figure 159 with the operation of LH
in Figure 62 on page 183:
βββββββββββββββββββββ¬ββββββββββββββββββββ
ββ signβextended ββΌs β GR R1
βββββββββββββββββββββ΄ββββββββββββββββββββ
0 31
βββββββββββββββββββββ¬ββββββββββ΄ββββββββββ
β LHI Instruction βs β Halfword in LHI instruction
βββββββββββββββββββββ΄ββββββββββββββββββββ
16 31
Figure 159. Operation of L H I instruction
Then, you can place the count of data items into GR8 using LHI:
LHI 8,NItems Initialize item counter
Defining symbols like NItems symbolically means that if the table expands or contracts, you need
only reassemble the program and the value of NItems will be recalculated automatically.
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ¬ββββββββββββββββββββ
βββββββββββββββββββ signβextended βββββββββββββββββββββββΌs β GG R1
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ΄ββββββββββββββββββββ
0 48 63
βββββββββββββββββββββ¬ββββββββββ΄ββββββββββ
β LGHI Instruction βs β
βββββββββββββββββββββ΄ββββββββββββββββββββ
16 31
Figure 160. Operation of L G H I instruction
The other six logical instructions have an unusual property: the I 2 immediate operand is placed
in the proper 16 or 32 bits of the 64-bit general register, and (unlike the insert-immediate
instructions) the rest of the entire register is set to zero! The Load Logical instructions we dis-
cussed in Section 14.11 on page 195 did zero-extension only on the left, rather than also zeroing
bits to the right of the loaded operand.
The following figure pictures the operation of these six logical load instructions.
In each case, after the I2 operand has been loaded into the specified part of GG R 1, the rest of
the register is set to zero. For example, if c(GG9)=X'FEDCBA9876543210', executing each of the
following instructions will change GG9 as indicated:
LLIHF 9,X'13579BDF' c(GG9)=X'13579BDF 00000000'
LLILF 9,X'FDB97531' c(GG9)=X'00000000 FDB97531'
LLIHH 9,X'2468' c(GG9)=X'24680000 00000000'
LLIHL 9,X'2468' c(GG9)=X'00002468 00000000'
LLILH 9,X'2468' c(GG9)=X'00000000 24680000'
LLILL 9,X'2468' c(GG9)=X'00000000 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 X'13579BDF' into the high-order 32 bits of GG9 (as in the first instruction above),
you would have to do something like
L 9,=F'13579BDF' c(GR9)=X'13579BDF'
SLLG 9,9,32 c(GG9)=X'13579BDF 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 these two instructions
SGR 9,9 Set GG9 to zero
IILH 9,X'2468' c(GG9)=X'00000000 24680000'
which uses one of the immediate-operand instructions. Or, another use could have been
320 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
SGR 9,9 Set GG9 to zero
ICM 9,B'1100',=X'2468' c(GG9)=X'00000000 24680000'
again requiring an extra instruction and a memory access.
Exercises
21.1.1.(1) What will the Assembler do if you write LHI 0,76543 ? What will be placed in
GR0?
These instructions are very useful: they can replace most memory references to constants and
literals. Consider the example in Figure 88 on page 223 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.
LHI 4,1 * c(GR4) = accumulated sum
LR 7,4 c(GR7) = count of additions
Test CH 7,NN Compare count to c(NN)
BE Store Branch if equal, N terms added
LR 0,7 Compute next odd integer
AR 0,0 Counter + counter = 2N
AHI 0,1 * Add 1, giving next odd term
AR 4,0 Add term to sum
AHI 7,1 * Increment count by 1
B Test Branch back to see if finished
Store ST 4,SUM Store result
Almost every previous example using a halfword or word literal can be replaced by an immediate
operand. This saves both execution time and the bytes needed for the storage operand.
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'80'.) You could write the test like this:
LLC 0,Char Get character, clear rest of GR0
CHI 0,X'80' Test for special character
BNH Special Special if representation <= X'80'
It helps to remember that these compare-immediate instructions always refer to operands in regis-
ters, never in memory:
CH 2,NN Compare to halfword in memory...
* CHI 2,NN ... but this would fail if assembled
- - -
NN DC H'42'
There are no multiply-immediate instructions with 32-bit operands. 133 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 Get a number to be multiplied
MHI 1,36 Multiply by 36, product in GR1
and if the product and operands are larger, you can use IILF:
L 1,Operand2 Get another number to be multiplied
IILF 15,629036721 Put multiplier temporarily in GR15
MR 0,15 Form long product in (GR0,GR1)
133 At the time of this writing. But new instructions are added regularly to the System z architecture, so check the Princi-
ples of Operation.
322 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
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.
The portions of the first operand in GG R 1 not involved in the operation of these instructions is
not affected, and remain unchanged. This was shown in Figure 158 on page 318, where the
βInsert Immediateβ instructions involve either 16 or 32 bits of the register, and the remaining bits
are unchanged. (The βLoad Immediateβ instructions do clear the remaining fields of the register!)
The last example in Section 19.3 uses a bit mask in memory. We can improve it by using an
immediate operand in an NILL instruction.
L 1,DataWord B'aaaaaaaaabbbbcccccccccccccdddddd'
SRL 1,6 B'000000aaaaaaaaabbbbccccccccccccc'
NILL 1,X'1FFF' B'0000000000000000000ccccccccccccc'
ST 1,Third Store Result
Figure 163. Extracting an unsigned integer value using A N D Immediate
The last example in Section 19.4 uses a bit mask in memory. We can also improve it using an
NILF immediate operand:
Suppose you want to set the sign bit of GG8 to a 1-bit. You can use either of these:
OIHH 8,X'8000' Set sign bit to 1
OIHF 8,X'80000000' Set sign bit to 1
but OIHF is 6 bytes long while OIHH is only 4 bytes long.
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 oper-
ands in memory. We can rewrite it to use immediate operands:
We can improve this example to reduce the possibility of typographic errors, by defining the mask
symbolically:
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.
324 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
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 mul-
tiple 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 3,X'00F0' Isolate the 4 interesting bits
BZ AllZeros Branch if all 4 bits were zero
CH 3,=X'0070' Check if leftmost bit is 1
BNL BitWas1 Branch if that bit was 1
- - - Test other values
What value will be in GR3 when control arrives at the instruction named BitWas1?
21.3.8.(2) + A programmer wanted to extract the six low-order bits of GR4, and considered
these three sequences of instructions:
(1) N 4,=X'0000003F'
(2) SLL 4,26
SRL 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 instruc-
tion 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,X'003F'
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.
The load- and insert-immediate instructions are summarized in Table 112 on page 326. The
insert-immediate instructions don't affect any part of the R1 register other than the bit positions
where the immediate operand has been inserted.
326 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
Mnemonic Opcode Mnemonic Opcode Mnemonic Opcode
AFI C29 IILF C09 NIHH 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:
In general, these immediate-operand instructions don't do anything you can't do with operands in
memory. But on modern CPUs, they will execute much faster and will help reduce the size of
your program.
Programming Problems
Problem 21.1.(2) Rewrite Problem 18.7 to generate a hexadecimal addition table, using imme-
diate operands wherever possible.
Problem 21.2.(2) Rewrite Problem 18.8 to generate a hexadecimal multiplication table, using
immediate operands wherever possible.
328 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
22. Branches, Loops, and Indexing
2222222222 2222222222
222222222222 222222222222
22 22 22 22
22 22
22 22
22 22
22 22
22 22
22 22
22 22
222222222222 222222222222
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, we'll describe a newer form of branch instruction, the relative-immediate branch.
A7 M1 4 RI 2
Table 115. Format of the BRC instruction
RI-type branch instructions for which the value of the RI2 operand lies in the range
β215 β€ RI2 β€ 215β1, or
β32768 β€ RI2 β€ 32767
allow the relative offset to the branch target to lie as far as β 65536 and + 65534 bytes away.
C0 M1 4 RI 2
Table 116. Format of the BRCL instruction
For RIL-type branch instructions the value of the RI 2 operand lies in the range
β231 β€ RI2 β€ 231β1, or
β2147483648 β€ RI2 β€ 2147483647
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 based-
branch instruction like
CR 3,12 Compare c(GR3) to c(GR12)
BC 8,Equal Branch if they're equal
or, you could use a relative branch by writing
CR 3,12 Compare c(GR3) to c(GR12)
BRC 8,Equal Branch if they're equal
While this may seem extra effort for no obvious gain, the relative branch has one major advan-
tage: 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 can't be indexed.
Like the extended mnemonics shown in Table 61 on page 210, 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.
134 That ought to be enough for most programs. (But that's what they said at one time about 24-bit addressing.)
330 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
Note:
The letter L in these mnemonics sometimes means βLongβ (as in JLU)
and sometimes βLowβ (as in JL).
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 mne-
monic is JLU, not JL. Why?
22.1.2.(1) Can you think of situations where JNOP and JLNOP will be useful?
The character comparisons are made in the rightmost bytes of registers GR0 and GR2. 136 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 exe-
cution.
22.2.2.(1) Revise the program in Figure 167 to use extended relative branch mnemonics and no
literals.
135 Table 13 on page 87 shows that in the EBCDIC character representation, all letters and numeric digits have
encodings greater than X'80'.
136 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, there's no
detectable difference in speed.
137 Review Sections 5.3 and 9.5 for a quick summary of indexing.
332 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
SR 0,0 Clear GR0 for character insertion
SR 1,1 Initialize index to 0
LA 3,C' ' c(GR3) = blank at right end
GetChar IC 0,Str(1) Get a character from string
C 0,=A(C'a') Compare to letter 'a'
JNL Okay Jump if not less than X'81'
STC 3,Str(1) Replace by a blank
Okay LA 1,1(,1) Increment index by 1
C 1,=F'80' Compare to length of string
JL GetChar Branch if not done
- - -
Figure 168. A simple loop, using indexing
The byte being examined is now addressed using GR1 as an index register. The first time the IC
instruction named GetChar is executed, the contents of GR1 is zero and the Effective Address
generated will be the address of Str. On the last execution of the IC instruction, the contents of
GR1 is 79, and the last byte of the string is inserted into GR0 for examination. Then, after the
LA instruction named Okay is executed, the contents of GR1 is 80, the branching condition for
the final JL instruction is not met, and control will pass to the following instruction.
A minor difference in this version is that the 32-bit word containing the EBCDIC representation
of the letter 'a' is now a word in memory, specified by the literal =A(C'a'), rather than in GR2 as
before.138
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.
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.
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.
138 While =F'129' and =A(X'81') would give identical results, using the fullword integer literal is a poor practice, because
your reader can't tell that the literal is intended for use in a character comparison.
22.3.3.(2) + Revise Figure 168 on page 333 to use immediate operands to replace references to
operands in memory.
Like the conditional relative branches, the Assembler provides extended mnemonics for the two
branch relative on count instructions:
The Branch on Count instructions simplify counting and branching operations like those in
Figures 167 and 168 above. As with the BCR and BC instructions, the branch address is
obtained either from R 2 for BCTR and BCTRG (unless the R 2 digit is zero, in which case no
branch is ever taken); or from the Effective Address for BCT and BCTG.
The branch address is computed first. Then, the branching condition is determined by first arith-
metically 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 on page 332 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.
334 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
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 JCT 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 on page 333: 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 4,Nbr c(GR4) = index 'K', initially N
SR 5,5 Initialize sum to zero
Next LR 1,4 c(GR1) = K
MR 0,1 K * K
MR 0,4 K cubed
AR 5,1 Add to sum
JCT 4,Next Decrease K by 1, and loop
ST 5,Sum Store sum
2. The halfword at NN contains a positive integer N; store at NSq the sum of the first N odd
integers. (See Figure 82 on page 218.)
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 as 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 two's complement of the double-length integer stored in the pair of words at Arg.
(See Figure 91 on page 226.)
LM 6,7,Arg Double-length number in (GR6,GR7)
LCR 6,6 Complement high-order part
LCR 7,7 Complement low-order part
JZ XXX Branch if carry out of GR7
BCTR 6,0 Otherwise reduce c(GR6) by 1
XXX STM 6,7,Arg Store complemented result
This is identical to the example in Figure 91 on page 226 except that the BCTR instruction
replaces
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,
but this time working backwards so the words are stored in descending order.
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 on page 335, 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?
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.
139 AHI and BCTR are both very fast, and AHI sets the condition code.
336 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
22.4.7.(2) The following code sequence is supposed to calculate the same sum of N odd integers
as in Figure 171 on page 335. Why doesn't it? What does it calculate?
LH 7,NN
LA 1,1
XXX LA 0,1(7,7)
AR 1,0
JCT 7,XXX
ST 1,Nsq
22.4.8.(3) For the program below, determine first the machine code assembled for each of the
instruction statements. Then when (at execution time) control reaches the SVC instruction,
determine c(GR2). (Don't try to assemble and then execute the program, since the SVC will
undoubtedly do something undesirable.)
Ex22_4_8 START 0
USING *,8 Establish addressability
BASR 8,0 Set base register
LA 4,4 Initialize counter
LA 7,AA Initialize address
SR 2,2 Set sum box to zero
Loop NOPR 0 Let the CPU catch its breath
AH 2,0(,7) Add a data item to the sum
LA 7,2(0,7) Increment address by 2
BCT 4,Loop Branch back if not done
SVC 3 Do something unforgettable
AA DC H'1,2,3,4,5,6,7,8,9' Table of numbers
END 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.
Loc Object Code Assembler Language Statements
____ _____________ BASR 12,0
____ _____________ Using *,12
____ _____________ LA 3,64
____ _____________ LA 7,A
____ _____________ Using A,7
____ _____________ Loop L 0,A
____ _____________ A 0,B
____ _____________ ST 0,C
____ _____________ BCT 3,Loop
____ _____________ Drop 7
____ _<32 bytes>__ PrintOut *
____ _____________ A DS 64F
____ _____________ B DS 64F
____ _____________ C DS 64F
22.4.13.(2) + In Exercise 22.4.12, the instructions don't perform the expected calculation.
Explain what happens, and what needs to be fixed.
22.4.15.(3) + Write instructions to count the number of 1-bits in GR1, leave the count in GR0,
and leave GR1 unchanged without saving and then restoring its contents.
22.4.16.(2) + State the cases in which each of the following five instruction sequences give dif-
ferent results, and explain the differences.
(1) LCR 0,0 (2) X 0,=F'-1' (3) X 0,=F'-1'
A 0,=F'1' AL 0,=F'1'
These four terms β index, increment, comparand, and condition β will appear in several forms
when we look at the branch on index instructions in Section 22.6.
338 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
The term βindexβ means the variable quantity that controls or determines completion of the loop;
it may or may not be related to a value used as an index in an RX-type instruction (that is, speci-
fied by an index register specification digit).
If the increment is negative it might be more appropriate to call it a decrement. Rather than using
special names to distinguish the sign of the increment, we will assume the increment can be either
positive or negative.
Loops have many forms; here are two of the most common. The loops we have seen tested for
loop completion at the end of the loop; this is called a βDo-Untilβ loop, because the loop is
executed until the termination condition is reached. This is illustrated in Figure 173.
The other form is called a βDo-Whileβ loop, because the loop is executed only while the termi-
nation condition has not been reached. This is illustrated in Figure 174.
ββββββββββββββββββββββββββββββββββββββββββββ
ββββββββββββββββββββββββ ββββββββββββββ ββββββββββ βββββββ΄ββββββββββ
ββ
β Initialize index, βββββ
β compare to βββββββ
β loop βββ
β add increment β
β increment, comparand β β comparand β not β body β β to index β
ββββββββββββββββββββββββ βββββββ¬βββββββ done ββββββββββ βββββββββββββββββ
done βββββββ
Figure 174. Sketch of a Do-While loop
For the Branch on Count instructions, the four loop-control items are all implied by the instruc-
tion: 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.
Note!
The terminology for Do-While and Do-Until loops can be misleading.
Such a loop is executed until the test condition becomes false, or only
while the test condition remains true.
Figure 175 on page 340 shows another method to calculate a table of the first 10 cubes. The
difference from Figure 172 on page 336 is that an address, rather than a subscripting index, is
used as the varying quantity controlling execution of the loop.
140 For many years, this was the characteristic behavior of loops in the FORTRAN programming language.
In this case an explicit address in the ST instruction is used, rather than an implied address as in
Figure 172 on page 336. 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. It's 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 on
page 336, the βindexβ of the loop in GR4 is also used in GR1 to βindexβ the ST instruction; in
Figure 175, the βindexβ of the loop is the address contained in GR1, but no RX-style βindexingβ
is done in any of the RX instructions.
Do-Until and Do-While loops are examples of βStructured Programmingβ forms, but other types
of loop structures are often used. For example, you can test for a loop-exit condition in the body
of the loop:
ββββββββββββββββββββββββββββββββββββββββββββββββββ
ββββββββββββββ ββββββββββββββ ββββββββββ ββββββββββββββ β
ββ
β Initialize βββββ
β loop body, βββ
β exit βββ
β loop body, βββ
β
ββββββββββββββ β first part β β test β β remainder β
ββββββββββββββ βββββ¬βββββ ββββββββββββββ
done βββββββ
Exercises
22.5.1.(2) A table of N halfword integers is stored beginning at HH, and N is a halfword integer
at NHwds. Store the integers into the table starting at RR in reverse order.
22.5.2.(2) Your solution to Exercise 22.4.9 will probably contain two loops. What are their
types?
340 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
Op Mnem Type Instruction Op Mnem Type Instruction
86 BXH RS Branch on Index High (32) EB44 BXHG RSY Branch on Index High (64)
87 BXLE RS Branch on Low or Equal EB45 BXLEG RSY Branch on Index Low or
(32) Equal (64)
84 BRXH RSI Branch Relative on Index EC44 B R X H G RIE Branch Relative on Index
High (32) High (64)
85 BRXLE RSI Branch Relative on Low or EC45 BRXLG RIE Branch Relative on Index
Equal (32) Low or Equal (64)
Table 120. Branch on index instructions
As there are no essential differences between BXH/BXLE and BXHG/BXLEG other than using
32-bit registers for the former and 64-bit registers for the latter, our examples will use the 32-bit
forms. None of the instructions changes the CC setting.
As with Branch on Count, these instructions provide the three functions of incrementation, com-
parison, and conditional branching, but with much greater flexibility. BXH and BXLE are
RS-type instructions requiring two register specification digits R1 and R 3, as indicated in Tables
121 and 122.
opcode R1 R3 B2 D2
Table 121. RS-type BXH and BXLE instructions
BXHG and BXLEG are RSY-type instructions that also require R 1 and R 3 operands:
The relative-immediate forms of the branch on index instructions use two different instruction
formats, RSI and RIE:
opcode R1 R3 RI 2
Table 123. RSI-type BRXH and BRXLE instructions
opcode R1 R3 RI 2 opcode
Table 124. RIE-type B R X H G and BRXLG instructions
Like the STM and LM instructions, the use of registers other than GR R 3 may be implied. First,
note that all of the loop-control quantities (index, increment, and comparand) are carried in regis-
ters. 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 7,5,NEXT
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 odd-
numbered 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 con-
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.)
It's important to note that the comparison takes place before the sum replaces the index; we will
see examples of situations where this is important. (Exercise 22.9.8 is recommended!)
Figure 177 shows another way to visualize the execution of BXH and BXLE.
βββββββββββββββββββββ
βββ
β sum β€ comparand ? ββββββββββ
β
BXLEβ ββββββββββ¬βββββββββββ no β
βββββββββββ β yesβ β βββββββββ
β sum = β βββββ΄ββββββ βββββββββββββββ β sum β
ββ
β index + βββ
β opcode? β βββ
βBr.addr to IAβββ
β’ββ
β to ββ
βincrementβ βββββ¬ββββββ βββββββββββββββ β index β
βββββββββββ β yesβ β βββββββββ
BXHβ ββββββββββ΄βββββββββββ no β
βββ
β sum > comparand ? ββββββββββ
β
βββββββββββββββββββββ
Figure 177. Operation of BXH and BXLE instructions
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
141 We are using the PL/I-language notation for the logical βORβ operation, represented by the vertical-bar character
β |β.
342 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
double-length instructions such as M, D, and SLDA specify an even-numbered R1 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:
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.
The values of the index run from 0 to 79; when control reaches the BXLE instruction, the incre-
ment ( + 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 instruc-
tion following the BXLE, c(GR1) will be 80.
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.
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.
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 consider-
ations 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 quanti-
ties are addresses.
344 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
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.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 343, 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 imme-
diate 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 con-
tents modulo (2 31 β 1) with the following instruction pair:
BXLE x,y,*+8 Form c(GRx)+c(GRy)
SL x,=F'2147483647' (231β1)
Verify or disprove his claim.
22.7.6.(2) The following code sequence tries to find the leftmost 1-bit of the positive nonzero
number in GR1, and put its bit number into GR0.
SR 0,0 Initialize bit position to 0
LA 2,1 Initialize BXLE increment
LA 3,32 Initialize BXLE comparand
X SLA 1,1 Shift test word left once
JM Y Check for minus sign
JXLE 0,2,X Count up by 1 and loop
Y - - - Rest of code
The program segment does not work correctly. Explain why not, and then correct it without
increasing the number of instructions.
22.7.7.(3) + By starting with a negative index value, it is possible to use a single register to hold
the increment and comparand of a BXLE instruction. Rewrite the examples in Figures 179
through 181 to use this technique.
22.7.8.(2) Repeat Exercise 22.7.1, but replace the first instruction with the following:
L 3,=F'1073741824' (230)
Now, do the same again, replacing the LA by
L 3,=F'-2147483647' (-231+1)
22.7.10.(2) + Suppose A, B, and C are three positive integers used to initialize the index, incre-
ment, 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?
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.
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 1,1
BXH 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.
346 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
22.9. Specialized Uses of BXH and BXLE (*)
Some specialized uses of BXH and BXLE involve unusual combinations of register specification
digits.
1. Suppose the contents of an odd-numbered register such as GR9 is zero. Then the instruction
XR 9,9 Set GR9 to zero
BXLE 4,9,XXX Branch to XXX if c(GR4) is <= 0
will branch to XXX only if the contents of GR4 is less than or equal to zero. Similarly,
BXH 4,9,YYY Branch to YYY if c(GR4) is > 0
would branch to YYY only if the contents of GR4 is greater than zero.
Since BXH and BXLE neither set nor test the condition code, this technique can be used in
situations where a condition code reflecting the state of the contents of GR4 is not available,
the current CC setting must be undisturbed, or if we want to avoid using instructions such as
LTR followed by a conditional branch.
2. Suppose we want to perform the inverse of the BCT instruction: that is, we want to incre-
ment 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 7,1 Initialize GR7 to +1
BXH 2,7,XXX Increment c(GR2), branch to XXX
will branch to XXX after incrementing c(GR2) by 1, unless the sum overflows. (There will be
no indication of the overflow in the CC setting!) Similarly, if there is a negative integer in
GR2,
BXLE 2,7,YYY Branch to YYY if c(GR2) not > +1
will increment c(GR2) and branch to YYY so long as the resulting sum does not exceed + 1.
3. If c(GR4) is + 1, then the instruction
BXH 5,4,ZZZ
will increment c(GR5) by 1 and then branch if the sum does not overflow. The index and
comparand are in the same register: if the comparison was made after the sum was placed in
GR5, equality would always be indicated, and the BXH would never branch.
Such special uses of the Branch on Index instructions are rare; they are used mostly in applica-
tions such as table searching and loop control. Try these exercises and the Programming Prob-
lems; you'll 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.3.(4) As in Exercise 22.7.6, the following code sequence tries to place in GR0 the number
of the leftmost bit in the positive nonzero number in GR1. Prove that it works correctly.
(Hint: consider the possible values of the two leftmost bits in GR1.)
22.9.6.(4) What values in GR0 and GR1 will cause the instruction
BXH 0,1,Yes
to branch to the location named Yes?
22.9.8.(2) + The operation of the Branch On Index instructions has often been described as
follows:
1. The increment is added to the index, and the sum replaces the index.
2. The new index is compared to the comparand to determine the branch condition.
How is this description different from ours, and when and why is this description incorrect?
Give an example showing how it would affect the actual operation of the Branch On Index
instructions.
22.9.9.(4) + This instruction sequence evaluates X**N (X N ) for 32-bit integer values of X and
N. The base value X is in GR3, and the exponent value N is in GR0. Determine the algorithm
used to evaluate the exponential; assume that no overflows occur.
XR 1,1 Clear GR1 to zero
SRDL 0,1 Shift low-order exponent bit to GR1
BXH 1,1,OneBit Branch if it was a 1-bit
ZeroBit MR 2,3 Was a 0-bit, square work value
SRDL 0,1 Shift another low-order bit for test
BXLE 1,1,ZeroBit Branch if it's zero to square again
OneBit BXLE 0,1,Finished Br if remaining exponent bits all 0
LR 5,3 More bits to do. Copy work value
Square MR 4,5 Square work value
SRDL 0,1 Move another bit for testing
BXLE 1,1,TestMore Branch if it's zero
MR 2,5 Otherwise multiply work into answer
TestMore BXH 0,1,Square Branch if any 1-bits remaining
Finished - - - Result is in GR3
You will find it very instructive to follow this instruction sequence for several values of the
exponent such as 1, 5, 8, 11, and 15.
348 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
22.10. Summary
The relative branch instructions discussed in this section are summarized in Table 126.
The loop-control instructions discussed in this section are summarized in Table 127.
Register Length
Operation
32 bits 64 bits
Branch on Count (Register) BCTR BCTGR
Branch on Count (Indexed) BCT BCTG
Branch on Count (Relative) BRCT BRCTG
BXH BXHG
Branch on Index
BXLE BXLEG
BRXH BRXHG
Branch on Index (Relative)
BRXLE BRXLG
Table 127. Branch instructions for loop control
The instruction opcodes and mnemonics are shown in the following table:
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 12-character position blank
in the printed output. (Remember that the 12 blanks are separated from any preceding char-
acter by 2 spaces.)
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; the bottom line is shown here only to
help you understand the spacing.
11 2222222222
111 222222222222
1111 22 22
11 22
11 22
11 22
11 22
11 22
11 22
11 22
1111111111 222222222222
1111111111 222222222222
....+....1....+....2....+....3....+....4....+....5....+....6.... etc.
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.
350 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
Chapter VII: Bit and Character Data
VV VV IIIIIIIIII IIIIIIIIII
VV VV IIIIIIIIII IIIIIIIIII
VV VV II II
VV VV II II
VV VV II II
VV VV II II
VV VV II II
VV VV II II
VV VV II II
VV VV II II
VVVV IIIIIIIIII IIIIIIIIII
VV 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 more basic System z instructions
that work with individual bits and bytes, and with varying-length character strings.
β’ 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.
2222222222 3333333333
222222222222 333333333333
22 22 33 33
22 33
22 33
22 3333
22 3333
22 33
22 33
22 33 33
222222222222 333333333333
222222222222 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 of an SI-type instruction is in memory, whereas the RI-type and
RIL-type instructions in Section 21 refer to target operands in the general registers.
opcode I2 B1 D1
Table 128. SI-type instruction format
opcode I2 B1 DL DH opcode
Table 129. SIY-type instruction format
The actions of the corresponding SI-type and SIY-type instructions are the same, so we'll 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 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 on page 353 describes the behavior of the instructions; the first operand is the single
byte at the Effective Address.
352 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
Operation Mnemonic Action CC set?
Move MVI, MVIY Operand 1 ββ I2 No
AND NI, NIY Operand 1 ββ Operand 1 AND I2 Yes
OR OI, OIY Operand 1 ββ Operand 1 OR I2 Yes
XOR XI, XIY Operand 1 ββ Operand 1 XOR I2 Yes
Compare CLI, CLIY Operand 1 Compared to I 2 Yes
Test Under Mask TM, TMY Test Selected Bits of Operand 1 Yes
Table 130. SI-type instruction actions
MVI stores its I2 operand into the byte at the Effective Address.
MVI is often used to initialize a byte whose bits will be used as bit flags, or to store a character.
For example:
MVI FlagByte,0 Set all flag bits to zero
MVI CrrgCtrl,C'1' Printer carriage control for new page
Exercises
23.2.1.(1) What do you expect will happen if you write these instructions?
MVI 0(4),B'000000000010101010'
MVI 0(4),B'000000000101010101'
MVI 0(4),-1
The CC settings after NI, OI, and XI are shown in Table 133 on page 354:
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.)
Sometimes it is better to use other types of self-defining term for the second operand; example (2)
could be written
NI X,B'11111101'
which more clearly shows that bit 6 will be zeroed.
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.
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 on page 355.
354 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
CC Indication
0 Operand 1 = I 2
1 Operand 1 < I 2
2 Operand 1 > I 2
Table 135. CC settings after CLI instruction
You'll remember that the same settings are generated by the CL and CLR instructions, in
Table 74 on page 232.
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 =C'A',X'C1' CC = 0: c(Operand 1) = I2
CLI =X'00',0 CC = 0: c(Operand 1) = I2
CLI =C' ',B'01000000' CC = 0: c(Operand 1) = I2
CLI =X'1',X'2' CC = 1: c(Operand 1) < I2
CLI =C'A',250 CC = 1: c(Operand 1) < I2
CLI =C'X',C'X'-1 CC = 2: c(Operand 1) > I2
CLI =X'1',X'0' CC = 2: c(Operand 1) > 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 332 (and its variations) to blank out the
special characters in the string at Str, now using CLI and MVI instructions. We'll start at the
right (high-addressed) end and scan from right to left.
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.3.(2) + An 80-byte record starts at Record. Using CLI, find the address of the last non-
blank 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 wasn't 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.
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 Indication
0 Bits examined are all zero, or mask is zero
1 Bits examined are mixed zero and one
3 Bits examined are all one
Table 137. CC settings after T M instruction
If the I2 mask is zero (meaning that no bits are tested), the CC is set to zero. The following
examples illustrate uses of the TM instruction.
1. Branch to Minus if the fullword integer at Num is negative. (This technique can be used to
avoid loading anything into a register.)
TM Num,X'80' Test leftmost bit at Num
JO Minus Branch if a 1-bit
2. Branch to Even if the fullword integer at Num is even.
TM Num+L'Num-1,1 Test rightmost bit of the word
JZ Even Branch if bit is zero
3. Branch to Mixed if the bits of the byte at BB are not all zeros or all ones.
356 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
TM BB,255 Test all eight bits
JM Mixed Branch if mixed zero and one
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 0's or all 1's.
TM HNum,X'FE' Test leftmost seven bits
BC 9,Small Branch if bits all zero or all one
The NI, OI, XI, and TM instructions let you set and test βon-offβ and βyes-noβ indicators in a
program. For example, as in Figure 169 on page 333, 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.
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.
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.
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 BIN,80 Test Under Mask for sign bit
BP POS Branch if nonnegative
Why didn't this work? Repair his instructions to work correctly.
23.5.5.(1) Use a TM instruction to set the Condition Code to zero without referencing any reg-
isters and without referencing any constants in storage.
23.5.6.(1) + In example 3 of Section 23.5, can the extended mnemonic BNM be used to mean
βBranch if Not Mixedβ? Why?
358 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
Trained Equ B'00100000' Define the driver-trained bit
Male Equ B'01000000' Define the male-driver bit
TM Status,Married+Trained Test 'Married' and 'Trained'
JNZ Next Branch if both not zero
TM Status,Male+Under25 Test age and sex
JO HighCost If young untrained male, branch
Next - - - 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 B'00000100' Define the assigned-risk bit
TM Status,Assigned Check assignment status
JZ Next Branch if not assigned
TM Status,Trained Check driver training
JO Next Branch if completed
OI Status,HasClaim Otherwise set claim bit on
Next - - - Rest of program
6. If the policy-holder is married, or has completed driver training, branch to LowRisk.
TM Status,Married+Trained Check status
JM LowRisk Branch if either but not both
These examples use EQU statements to assign symbolic names to values representing bits. Unfor-
tunately, 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.142
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?
Under normal circumstances, we would refer to the bits with a code sequence like
TM Flag1,Bit0 Test a bit in flag byte
JZ SomeCode Go do something if zero
142 You can use macro instructions to implement a bit-defining and bit-handling language that names bits and protects
against referring to them accidentally.
Here is a simple technique that avoids this naming problem: define MyBit and HisBit with the
following statements:
The zero duplication factors mean that no storage will be reserved by the two bit-definition state-
ments. 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
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.
If you use definitions like these to set a specific bit at a known position in a byte, the bit name
indicates the bit's 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 B'00000001' If 1, initialization completed
EndInput Equ B'00000010' If 1, no further input exists
Exercises
23.7.1.(2) Suppose the definition of MyBit in Figure 191 had been written
DS B
MyBit Equ *-1,X'80'
Would the instructions in Figure 192 work correctly? Why or why not?
360 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
23.7.2.(2) + Using the bit-naming technique illustrated in Figure 191, define two bits named
BitA and BitB in a single unnamed byte. Then, write code sequences to do the following:
The method shown here works, but is clumsy and complex. We will see when we examine
packed decimal data in Section 30 that other instructions greatly simplify this task.
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 instruc-
tion 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 won't know with any cer-
tainty 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 357) than parts of instructions. What you see in
memory might not match your program listing. (It's 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 reenterable (a property requiring no self-
modification), 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 we'll 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 on page 363 does the same calculation more rapidly and safely.
Study the actions of the JXH and JXLE instructions carefully!
362 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
L 1,NN Set up JXLE comparand N in GR1
BCTR 1,0 N-1
ALR 1,1 2 * (N-1) = 2N-2 in GR1
LA 0,2 Increment in GR0
SR 3,3 Initialize sum to zero
SR 2,2 Same for index
TM Switch,1 Test for first term adding twice
JO Twice Branch if bit is 1, meaning yes
Once AH 3,LIST(2) Add a term once
JXH 2,0,Done Increment index, branch if done
Twice AH 3,LIST(2) Add a term
AH 3,LIST(2) ...twice
JXLE 2,0,Once Increment index and loop
Done - - - Continuation of program
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.
LA 6,2
LA 4,5 Test number
VA AR 4,6
SLL 6,1
XI *-4,X'01' Flip-flop
- - - Some undecipherable material
B VA
23.9.2.(2) Show that the SI-type OI, NI, and XI instructions in Figure 194 on page 362 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:
OI Flag+1,1 Set a flag bit
- - -
Flag TM Flag+1,0 Test the flag byte
BNZ FlagSet Branch if not zero
Elsewhere in the program, other instructions modified the byte at Flag+1. Why would anyone
write a program this way?
23.10. Summary
The instructions we've discussed in this section are summarized in Table 138.
Operand 1
Function Operand 2
12-bit displacement 20-bit displacement
Move Immediate MVI MVIY I2
AND Immediate NI NIY I2
O R Immediate OI OIY I2
X O R Immediate XI XIY I2
Compare Immediate CLI CLIY I2
Test Under Mask TM TMY I2
Table 138. Storage-Immediate instructions
The instruction opcodes and mnemonics are shown in the following table:
143 Technically, a self-modifying program can be reenterable if every execution instance makes exactly the same modifi-
cations. This is considered an even poorer practice.
364 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
24. Character Data and Basic Instructions
2222222222 44
222222222222 444
22 22 4444
22 44 44
22 44 44
22 44 44
22 44444444444
22 444444444444
22 44
22 44
222222222222 44
222222222222 44
The instructions we've seen thus far have involved at most one memory operand; now we'll inves-
tigate 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.
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 it's 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 L B1 D1 B2 D2
Table 140. Format of single-length SS-type instructions
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.)
The important difference between N and L is explained in Section 24.5 on page 370.
Except for TRT and TRTR, the only reference to or use of the general registers by the
instructions in Table 139 on page 365 is for operand addressing.
The result of each operation is found in the first operand location, except for TRT, TRTR, and
CLC, which modify no data in memory.
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 generated by the Assembler is derived from the
Length Expression (N) in your machine instruction statement. The Length Expression may also
be explicit or implied; we'll discuss implied Length Expressions in Section 24.4.
You will remember from Section 8.5 on page 102 that machine instruction statement operands
can take any of these three forms:
For most of the instructions we've seen so far, these formats are used for the first four instruction
types shown in Table 141 on page 367, where S is our notation for an implied address, an abso-
lute or relocatable expression. In the last row, we see that SS-type instructions introduce new
possibilities:
144 The Encoded Length byte is sometimes called the βmachine lengthβ or βLength Specification Byteβ.
366 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
Instruction
Operand Format
Type
expr expr(expr) expr(expr,expr) expr(,expr)
RR register invalid invalid invalid
RX S S(X) D(X,B) D(,B)
RS S D(B) invalid invalid
SI S or immediate D(B) invalid invalid
SS S S(N) D(N,B) D(,B)
Table 141. Instruction types and operand formats
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 begin-
ning at BB. We could write
MVC BB(23),AA Move 23 bytes from AA to BB
where the addresses of the two operands are implied. For SS-type instructions, the number in
parentheses is not an index register specification, but an explicit Length Expression. Its value, 23,
is the number N of bytes to be moved.
There are several ways to specify the Length Expression, as shown in Table 142. (Remember
that βS 1β and βS 2β are our notations for the implied addresses of the first and second operands.)
Explicit Length
S1(N),S 2
D 1(N,B 1),S2
S1(N),D 2(B 2)
D 1(N,B 1),D 2(B 2)
Table 142. SS-type instructions with explicit length
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 X'125' and X'47D' respectively. Then,
Figure 197 shows how we could use any of the following four instructions, corresponding to the
four operand formats in Table 142:
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?
Exercises
24.3.1.(2) Can you find a way to specify an implied Length Expression whose value is zero?
24.3.2.(2) Is it possible to specify the length attribute of an expression using the L' notation?
Implied Length
S1,S2
D 1(,B1),S2
S1,D 2(B 2)
D 1(,B1),D 2(B 2)
Table 143. SS-type instructions with implied length
Note that if the address of the first operand is specified explicitly and the Length Expression is
implied, the comma following the left parenthesis is very important.
As a reminder, the words βexplicitβ and βimpliedβ that we saw in Section 11.4 were used define
constants with explicit and implied lengths:
IMPLIED DC F'8' Implied length = 4 bytes
EXPLICIT DC FL5'8' Explicit length = 5 bytes
368 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
ImplAddr L 0,=F'6' Implied address, resolved by Assembler
ExplAddr L 0,X'D4'(0,7) Explicit address, specified by you
In this section, we use the same words to describe Length Expressions: you can provide an explicit
Length Expression, or you can let the Assembler derive the value of an implied Length
Expression.
We usually don't 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 DS statement like this:
MVC BB,=120C' ' Set field at BB to blanks
- - -
BB DS CL23 Field of length 23 bytes
Even though the second operand is 120 bytes long, if more than 23 bytes are moved by the MVC
instruction, then the data or instructions following the byte at BB+22 could be overwritten! Thus
the length of the string of bytes to be moved should be determined from the first, or receiving,
operand, rather than the second.
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 X'5'+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 Length Expression cannot be immediately associated with a symbol that names an
area of the program using its length attribute. Unlike the examples in Figure 197 on page 367,
knowing the base and displacement of the symbol BB (9 and X'47D') does not necessarily give the
correct Length Expression when an implied length must be found. If an explicit base and displace-
ment are given, the value of the Length Expression is the length attribute of the displacement
expression. Thus
MVC X'47D'(,9),AA
specifies an implied length of 1 rather than 23, because X'47D' is a self-defining term. Using an
explicit address and an implied length is very rare; it's much better to use a Length Attribute Ref-
erence.
You can specify an explicit base and displacement, and still use an implied length. We could have
written
MVC BB-BB+X'47D'(,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 displace-
ment, in the improved form
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.
These rules are summarized in Table 144 on page 370. The last column shows how the Length
Expression is determined for the four possible forms of the first operand.
Exercises
24.4.1.(1) How many bytes will be moved by these instructions? What values will you find in
the first operand fields?
(1) MVC A,=X'01020304050'
A DS H
24.4.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?
24.4.3.(2) + The paragraph following Table 141 on page 367 says that the comma following the
left parenthesis is very important in some situations. Why?
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!
370 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
Because the Length Specification Byte is a single byte, it can have any value between 0 and 255;
these actually specify operand lengths between 1 and 256. This is due to two factors:
β’ Every SS-type instruction always operates on at least one byte.
β’ All the instructions in Table 139 on page 365 except MVCIN and TRTR process data from
left to right in order of increasing addresses.
β For left-to-right instructions, the CPU must calculate the address of the last byte of each
operand to check for possible memory-access violations.
β Similarly, MVCIN, TRTR, and some other instructions process data from right to left, in
order of decreasing addresses, starting at the rightmost byte.
In both cases, the CPU must compute the addresses of the leftmost and rightmost bytes of the
operand. It is simplest to locate the rightmost byte by adding the Encoded Length L to the
effective address of the operand; if there are N bytes in a string starting at address A, its right-
most byte is at address A+Nβ 1 = A+L.
That's why the Encoded Length has the value of the Length Expression minus 1.
We usually don't 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 it's important to understand this
relationship between the Encoded Length and the actual number of bytes involved. An illus-
tration (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
Length Expression is zero.
The instructions in Figure 199 on page 372 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.
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β or βprogram lengthβ).
β’ The Assembler generates the Encoded Length (the βmachine lengthβ).
Figure 200 shows how MVC can be βemulatedβ by other instructions. Remember that the length
expression LE is not the Length Specification Byte of a βrealβ MVC.
372 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
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 doesn't
modify any registers this way.
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.
Unlike MVC, the z/Architecture Principles of Operation does not guarantee βbyte-by-byteβ opera-
tion for MVCIN, so if the operands overlap by more than one byte, the results may be unpredict-
able.
The SSF instruction format illustrated in Table 146 is used for relatively few instructions.
opcode R3 op B1 D1 B2 D2
Table 146. SSF instruction format used for the MVCOS instruction
Unlike the previous SS-type instructions, you specify the true length to be moved in a register, set
GR0 to zero, 145 and the instruction will move up to 4096 bytes at a time. Its syntax is
MVCOS D1(B1),D2(B2),R3
where data is moved from the second operand to the first, and the number of bytes to move is
placed in the R3 operand register (which of course must not be GR0!). The number of bytes
actually moved is the number in the R3 register or 4096, whichever is less. The CC is set to 0 if
all bytes have been moved, or to 3 if more than 4096 bytes were specified.
For example, suppose we want to move 10000 bytes from Here to There:
145 If nonzero bits appear in GR0, your program may cause a privileged-operation exception.
374 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
LA 7,There Target address
LA 4,Here Source address
LHI 12,10000 Number of bytes to move
XGR 0,0 Set GR0 to zero (important!)
Mover MVCOS 0(7),0(4),12 Move up to 4096 bytes
JZ Done Branch if all bytes moved
AHI 7,4096 Update target address
AHI 4,4096 Update source address
AHI 12,-4096 Reduce remaining count
J Mover Repeat for more bytes
Done - - -
Figure 203. Example of MVCOS instruction
The convenience of MVCOS compared to MVC or MVCL may be outweighed by its slightly
slower performance.
Exercises
24.6.1.(2) Suppose MVCIN used predictable βbyte-by-byteβ steps for any degree of operand
overlap. What result would appear in Figure 201 on page 373 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 DS 0C
Prefix DS CL43
Insert DS CL29
Suffix DS 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?
MVC Result,Data
- - -
Data DC C'Data'
Result DS CL8
24.6.5.(2) In example 4 of Section 24.6.1, is there any reason (other than very poor style) not to
write the last two instruction statements as
STC 9,*+5
MVC LINE(0),0(8) ?
24.6.6.(3) Consider these two examples of an MVCIN instruction with overlapping operands:
24.6.9.(3) + You are given a string of characters starting at Str whose length is stored at N, and
are required to extract a substring of characters whose length is at K, starting at a character
whose offset from N is stored at P. The extracted substring should be stored at Sub, and its
length should be stored in the word at L. (N, K, P, and L are words in your program.)
In case the substring is not fully contained in Str, the values at K and L will differ; and if no
valid substring can be extracted (for example, P exceeds N), store zero at L.
24.6.10.(2) A programmer needed to move a group of N records from Source to Target, where
he assumed that the length of the record is defined by L'Rec. He wrote
MVC Target(N*L'Rec),Source
Under what circumstances will this work correctly, or not?
24.6.11.(2) What will happen in the instructions in Figure 200 on page 372 if the value of the
Length Expression exceeds 256?
376 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
OC Lump(4),Lump OR 4 bytes to each other
JZ Yes Branch if all bytes are zero
or
NC Lump(4),Lump AND 4 bytes to each other
JZ Yes Branch if all bytes are zero
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.
Don't 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 in Figure 115 on page 249, shown here:
Replace the second integer in the word at XX by the corresponding value from the word at
ZZ.
4. Exchange the contents of the halfword integers at A and B. (Compare example 3 on page
373.)
XC B,A XOR A to B
XC A,B XOR B to A
XC B,A XOR A to B
- - -
A DS H
B DS H
This technique was used to exchange register contents in Exercise 19.5.1.*
Exercises
24.7.1.(2) Revise the instructions in Figure 204 to use two masks, two NC instructions, and
one OC instruction.
24.7.2.(2) A student suggested the following code sequence as a solution to the problem of
replacing data items embedded in a larger field:
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 Count 8 bits in GR0
IC 0,BitData Get the source byte
Repeat STC 0,BitChars-1(1) Store a byte at BitChars
SRL 0,1 Shift right by one bit
JCT 1,Repeat Iterate for all 8 bits
NC BitChars,=8X'1' AND off all but low-order bit
OC BitChars,=8C'0' OR makes EBCDIC 0 or 1 characters
- - -
BitData DC B'10010001' Sample source byte
BitChars DS CL8 Converted characters
Does this work? What will be found at BitChars? Explain your answer.
378 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
LA 1,List Initialize GR1 to A(first block)
LA 2,100 Set GR2 count to number of blocks
Test CLC 0(60,1),WhoIsIt Compare blocks
JE Found Branch if blocks are equal
LA 1,60(,1) Increment address by block length
JCT 2,Test Count down and branch
J NotFound No matching block was found
Exercises
24.8.1.(2) Example 3 above claims that a logical comparison of two negative integers gives the
same result as an algebraic comparison. Show that this is or is not true.
24.8.2.(3) + Write instructions using CLC to correctly compare arithmetically two signed word
integers in memory having arbitrary signs. For example, CLC should show that + 10 > β 10.
(It can be done!)
24.8.3.(2) Suppose we wish to test the string of 220 bytes at R to see if they all contain zero. It
is claimed that each of the following instructions will set the CC to zero if and only if the string
contains all zero bytes. For which of these instructions is the claim true?
(1) OC R(220),R
(2) NC R(220),R
(3) CLC R+1(219),R
(4) CLC 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 test 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. Use a CLC
instruction.
24.8.7.(1) + What does this instruction do? Is it at all useful? If so, why?
CLC 1(7,4),0(4)
146 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). (Terminology aside, it's a simple operation.)
For example, suppose the string of five argument bytes at PP contains X'0201040503', 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'02'; the function byte at GG+X'02' is C'C', and this replaces the first
byte at PP. Similarly, the fifth and last argument byte at PP is X'03'; the function byte at
GG+X'03' is C'D', which replaces the final byte in the string at PP.
Unlike the SS-type instructions we've 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.
You can appreciate the power of TR if you consider the example in Figure 167 on page 332 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.
380 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
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.
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 380 and verify that all non-
blank characters are in positions corresponding to their EBCDIC encodings, and that the trans-
late 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 B'10110001' becomes B'11011000'. 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 on page 380 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 blank characters. (This format
was used by some early Fortran compilers to read character data into a program.) Write a
program segment (in Assembler Language, of course!) 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.
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 87 will
appear in the string, write statements to generate a translation table that will set all other char-
acters 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
X'123456' at Old, we should find X'012345' at New.
Then do the same for a left shift of one digit position; the result (starting with the same data)
would then be X'234560'.
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.
LHI 0,8
LA 1,GR9Hex
Repeat XR 8,8
SLDL 8,4
Q1 AHI 8,240
Q2 CHI 8,250
JL Store
Q3 AHI 8,-57
Store STC 8,0(,1)
AHI 1,1
JCT 0,Repeat
- - -
GR9Hex DS 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 X'01000302050405'
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.
382 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
XR 0,0 Clear a work register
XR 2,2 Input-byte index
XR 3,3 Output string index
LHI 4,L'InString Number of bytes to convert
Convert IC 0,InString(2) Get a source byte
SRDL 0,4 Shift right 4 bits
STC 0,OutStrng(3) Store leftmost hex digit
SRL 1,28 Move rightmost hex digit to end
STC 1,OutStrng+1(3) Store rightmost hex digit
AHI 2,1 Increment input index
AHI 3,2 Increment output index
JCT 4,Convert Repeat for all input bytes
TR OutStrng,=C'0123456789ABCDEF' Translate to EBCDIC
Does this work? What precautions should the student's 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)=X'12345678', the
resulting c(RevWord) will be X'1E6A2C48'. (We'll see in Section 26 that there are easier ways
to reverse bytes.)
As we saw for MVC and MVCIN, the first operand of TRT refers to the leftmost byte of the first
storage operand, while the first operand of TRTR refers to the rightmost byte of the first storage
operand.
The operation of TRT and TRTR is identical to TR through steps 1 and 2 on page 379, and
quite different thereafter.
3. The first operand is not modified; the accessed byte from the table addressed by the second
operand (the function byte) does not replace the argument byte from the first operand string.
Instead, the function byte is examined: if it is zero, we continue with step 4 of the description
of TR, incrementing (or decrementing) the first operand address and decrementing the count.
If the function byte is not zero,
β’ It is placed in the rightmost byte of GR2 (the rest of the register is unchanged);
CC Meaning
0 All accessed function bytes were zero.
1 A nonzero function byte was accessed before the
last argument byte was reached.
2 The nonzero function byte accessed corresponds to
the last argument byte.
Table 147. Condition Code settings for T R T and T R T R instructions
24.10.1. TRT
To illustrate the basic operation of TRT, suppose we must scan a string of characters to find the
address of the first numeric character. First, we create a translate table with zero function bytes in
all positions except for those corresponding to the EBCDIC representation of decimal digits,
where the function bytes are nonzero.
NumChar DC (X'F0')X'00',10X'01',6X'00'
Then, suppose we test the following strings using TRT:
String1 DC C'abc123def' Decimal digit before end of string
String2 DC C'*abcdef*' No decimal digits
String3 DC C'AB7' Decimal digit in final position
Then, after executing the following instructions, the contents of GR1, GR2, and the CC are as
shown:
The xxxxxx characters mean that those portions of GR2 are unchanged when the X'01' 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.
384 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
LA 1,Record Initialize character address
LA 2,80 Number of characters to examine
TestPunc CLI 0(1),C'.' Compare to period
BE Period Branch if found
CLI 0(1),C',' Compare to comma
BE Comma Branch if found
CLI 0(1),C'''' Compare to apostrophe
BE Apost Branch if found
AHI 1,1 Otherwise increment address by 1
JCT 2,TestPunc Count and loop
B NoPunct Branch if none were found
Figure 209. Searching for punctuation characters using CLI
The TRT instruction does the same processing much more rapidly, but at the cost of memory
space for the translate table.
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, it's 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.
As another example of the TRT instruction, suppose we are required to scan the quoted character
string starting at Sentence for the occurrence of an embedded character string containing either
apostrophes (as in β³She said, 'Never!'β³), or quotation marks (as in 'I said, β³I won'tβ³'). As
these examples indicate, the other delimiter may appear freely inside the outer string.
386 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
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 com-
plete, the number of names is stored in the word at NbrNms. To protect against omitted punctu-
ation 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.
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 on page 385 can be done with TRTR and the same translate table:
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 non-
blank character in the string. This is sometimes done with a CLI instruction:
This scan can also be done (perhaps more quickly) using a TRTR instruction:
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 385 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 387 as follows:
TRTB DC XL256'0' Define table, length 256
ORG TRTB+C'.'
DC X'1' Function byte for period
ORG TRTB+C','
DC X'2' Function byte for comma
ORG TRTB+256 Reset LC to end of table
Use this technique to construct the table in Figure 210 on page 385. 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 386, 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 386, 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 T(256),T Set entire table to zero
MVI T+C'''',4 Set to stop on apostrophe
24.10.5.(4) + In Figure 212 on page 386, 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 non-
blank character. Do the same exercise, but this time use MVCIN and TRT instructions instead
of CLI.
24.10.8.(2) In Figure 212 on page 386, why is it necessary to reset GR2 to zero before exe-
cuting the second TRT?
388 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
24.10.9.(2) The translate table in Figure 216 on page 388 is defined with a single DC state-
ment. Verify that it generates the desired data.
24.10.10.(3) Modify the coding in Figure 213 on page 387 to store each name only once, and
add a word to each name's 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:
SR 2,2
TRT XX,=XL5'20100'
- - -
XX DC X'0004010203'
24.10.12.(3) + Some experiments have shown that trailing blanks can be removed more effi-
ciently 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.14.(2) + In Figure 215 on page 388, what will happen if the content of String is all
blanks?
The two Execute instructions in Table 148 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 50.
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.
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.
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 displace-
ment fields as the RX instruction, and then execute that LA instruction.
390 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
MVC MakeLA(4),0(14) Move original RX inst'n to work area
NI MakeLA+1,X'0F' Clear old R1 digit position
OI MakeLA+1,X'60' Set new R1 digit to 6
MVI MakeLA,X'41' Set 'LA' opcode into instruction
* Contents of MakeLA is now 416xbddd
EXRL 0,MakeLA Execute the constructed 'LA'
- - - GR6 now has the desired address
MKLA DS 2H 4 bytes on halfword boundary
Figure 219. Constructing an executed instruction
This instruction sequence changes no registers other than GR6, even though R0 could have
been used in the instruction sequence without affecting the operation of the EX, because
GR0 or GG0 could not have been used by the LA as a base or index register. This illustrates
a technique you can use when all other register contents must remain unchanged.
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.
392 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
is allowed. This loop is very awkward for a CPU to stop, and is avoided simply by not
allowing Executes of Execute instructions.147
2. When possible, place the target of an Execute instruction close to the EX.148
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 Execute the relative branch
- - -
GoToXYZ BRC *-*,XYZ Branch if CC matches the mask bits
The CPU determines the Effective Address of the BRC instruction relative to its address, not
the address of the EX.
5. The Execute instruction was sometimes described as a special branch instruction! It is said
that EX causes an unconditional branch to the target instruction, followed by an uncondi-
tional 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 what's done in System z 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 modi-
fied and remaining unmodified.
147 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.
148 Some programmers use an βidiomβ like this:
LA 1,N Number of bytes to move
BCTR 1,0 Make it a machine length
MVC A(*-*),B Move only 1 byte from B to A
EX 1,*-6 Move all N bytes from B to A
This is not generally recommended, because the CPU must process the MVC instruction twice.
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:
EX 0,BASR1
Here - - -
- - -
BASR1 BASR 1,0
There - - -
What would he claim to be in GR1 after the EX is executed? What will be in GR1?
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-
394 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
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 on page 382, the string at Text was assumed to be shorter than
256 characters. Repeat the exercise, now assuming that the string's length may be up to 14000
characters.
24.11.9.(3) In Exercise 24.8.4 on page 379, 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 Con-
dition Code correctly.
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 instruc-
tion?
24.11.13.(2) + In example 5 on page 392 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
EX 1,LHIOp Load the constant into a GPR
- - -
LHIOp LHI 0,137 Executed: load into the target GPR
This won't 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 386 to use EX instructions where appro-
priate.
24.11.20.(2) How can an EX instruction choose one of multiple possible target instructions in a
single execution?
24.12. Summary
Remember:
The length you code in an SS-type assembler instruction statement (N)
specifies how many bytes are involved (unless you code zero, in which
case one byte always participates in the operation). The length you
specify as the R1 operand of an EX instruction (L) is one less than the
number of bytes involved.
The instructions discussed in this section are shown in Table 151 on page 397.
149 Modern processors may fetch, process, and store groups of several bytes, but the result still appears to be byte-at-a-
time operation.
396 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
Function Instruction Data is Processed CC Set?
MVC Left to right
Move No
MVCIN Right to left
Move MVCOS Left to right Yes
AND NC Left to right Yes
OR OC Left to right Yes
XOR OC Left to right Yes
Compare CLC Left to right Yes
Translate TR Left to right No
Translate and Test TRT Left to right Yes
Translate and Test TRTR
Right to left Yes
Reverse
EX
Execute β Depends on target
EXRL
Table 151. Basic instructions for data in storage
The instruction opcodes and mnemonics are shown in the following table:
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.150 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 shuf-
fles 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 X'015C', 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:151
AAAAAAAAAA 04 C1 00 08
AAAAABBBBB 07 C1 00 03 01 00 03
BBAA 06 C2 00 00 FF 00 (no extra 00!)
ABCDDDDDEFFGH 0D C1 01 01 01 00 03 01 01 00 00 01 01
398 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
(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.)
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 charac-
ters 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 char-
acter 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,=C'0123456789ABCDEF'
MVC HexWord,=X'0004010502060307'
TR HexWord,Temp
- - -
Temp DS D
HexWord DS CL8
Word DC X'1F2E3D4C' (For example)
Write a program to test his claim with a variety of values at Word.
Problem 24.10.(3) Write a program to simulate the execution of the TRT instruction, without
considering final Condition Code settings
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 student's grades and average, skip a line and print the
average grade for each exam. For example, the output might be formatted like this:
Student 1 nn nn nn nn nn
- - -
Student n nn nn nn nn nn
Exam Averages nn nn nn nn nn
Doaks, Joe 79 83 88 91 93
Queue, Susie 44 91 67 97 89
Shakes IV, Pete 97 89 80 100 73
Burley, Hurley 61 71 85 88 97
Throckmorton, Chauncey 90 90 88 74 92
Doaks, Jonathan 79 83 87 95 47
Problem 24.14.(3) Write a program to read the records shown below, that contain the text of
Lincoln's β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:
400 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
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 occur-
rences 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 some-
thing like this:
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.
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 (O'76543'? What's its value in decimal?) is the same as X'7D63'.
402 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
25. Character Data and Extended Instructions
2222222222 55555555555
222222222222 555555555555
22 22 55
22 55
22 555555555
22 5555555555
22 555
22 55
22 55
22 555
222222222222 55555555555
222222222222 555555555
All the instructions discussed thus far complete their task before the next instruction is processed.
In this section, we'll 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 Con-
dition 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.
The processed portion of the operands can vary greatly from instruction to instruction, and for
repeated executions of the same instruction.
152 The appropriate name for the βendβ character depends on how it's used; some names are more descriptive than
others for a given instruction.
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 next-
higher 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 β GPR R1
βββββββββββββββββββββββββββββββββ¬βββββββββ¬ββββββββββββββββββββββββββ€
β////////////////////////////////////////β Operand 1 Length β GPR R1 +1
βββββββββββββββββββββββββββββββββ΄βββββββββ΄ββββββββββββββββββββββββββ
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Operand 2 address β GPR R2
βββββββββββββββββββββββββββββββββ¬βββββββββ¬ββββββββββββββββββββββββββ€
β///////////////////////////////βpad byteβ Operand 2 length β GPR R2 +1
βββββββββββββββββββββββββββββββββ΄βββββββββ΄ββββββββββββββββββββββββββ
0 31 32 40 41 63
Figure 221. Register use by CLCL and MVCL
MVCL and CLCL simplify moving and comparing long strings of bytes, which would otherwise
require lengthy loops.
153 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. We'll see them in Section 25.2.
404 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
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.
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.
CC Meaning
0 Operand 1 length = Operand 2 length
1 Operand 1 length < Operand 2 length; part of operand 2 not moved
2 Operand 1 length > Operand 2 length; operand 1 was padded
3 Destructive Overlap, no data movement
Table 153. CC settings after MVCL
Figure 222 on page 406 may help you to to visualize the operation of MVCL, assuming there is
no destructive overlap. The figure uses these notations:
A1 Address of a first-operand byte, c(R1)
c(A1) The first-operand byte at address A1
L1 Remaining length of the first operand, c(R1 + 1)
A2 Address of a second-operand byte, c(R2)
c(A2) The second-operand byte at address A2
L2 Remaining length of the second operand, c(R2 + 1)
Pad Padding byte
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).
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 if it fits, and branch to WontFit
if all of the message won't fit in the 120-byte area.
406 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
No Execute instruction (or STC, to store a length byte into an MVC) was needed to supply a
Length Specification Byte for the move.
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 compar-
ison 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.
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.
CC Meaning
0 Operand 1 = Operand 2, or both lengths 0
1 First Operand low
2 First Operand high
Table 154. CC settings after CLCL
Figure 225 on page 408 may help clarify this description. The figure uses notations similar to
those preceding Figure 222 on page 406:
A1 Address of a first-operand byte, c(R1)
c(A1) The first-operand byte at address A1
L1 Remaining length of the first operand, c(R1 + 1)
A2 Address of a second-operand byte, c(R2)
c(A2) The second-operand byte at address A2
L2 Remaining length of the second operand, c(R2 + 1)
Pad Padding byte
x:y x is compared to y
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. 154 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.
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.
408 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
L 2,Addr1 Set first operand address
L 3,Len1 And length of first record
L 6,Addr2 Set second operand length
L 7,Len2 And length of second operand
LA 1,Equal Assume lengths are equal
CLR 3,7 Compare lengths
JE Compare Go compare if equal lengths
JH Op1Long Branch if operand 1 longer
LA 1,Equal2 Operand 2 longer, set equality exit
LR 7,3 2nd operand length = shorter value
J Compare And compare
Op1Long LA 1,Equal1 Operand 1 longer, set equality exit
LR 3,7 1st operand length = shorter value
Compare CLCL 2,6 Compare operands with equal lengths
JNE UnEqual Branch if inequality detected
BR 1 Branch to desired equality routine
Figure 227. Comparing two records without padding
The preliminary effort in this example ensures that GR3 and GR7 will both contain the shorter
operand length when the CLCL is executed. This illustrates precautions we must take if we don't
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 can't 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
where MINLEN is the smaller of the two operand lengths. Is this true? Why?
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
ββββββ΄ββββββββββ¬ββββ No destructive overlap
ββββββββββββββββ Target operand
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 on page 408, reversing the operands: that is,
make the first operand have zero length.
25.1.13.(1) Can you do a βrippleβ move with MVCL, as you can with MVC?
25.1.14.(1) + Revise Figure 223 on page 406 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.
410 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
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
βββββββββββββββ β β β βββββββββββ΄ββββββββ
Note that the second operand of the machine instruction is specified as the third operand of the
assembler instruction statement.
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 β GPR R1
βββββββββββββββββββββββββββββββββΌβββββββ΄ββββββββββββββββββββββββ€
β Operand 1 length β GPR R1 +1
βββββββββββββββββββββββββββββββββ΄βββββββββββββββββββββββββββββββ
βββββββββββββββββββββββββββββββββ¬βββββββ¬ββββββββββββββββββββββββ
β Operand 3 address β GPR R3
βββββββββββββββββββββββββββββββββΌβββββββ΄ββββββββββββββββββββββββ€
β Operand 3 length β GPR R3 +1
βββββββββββββββββββββββββββββββββ΄βββββββββββββββββββββββββββββββ
Figure 228. Register use by MVCLE and CLCLE
If these instructions are executed in 24- or 31-bit addressing modes, the rightmost 24 or 31 bits of
the even-numbered registers contain the operand addresses. On termination, the high-order (non-
address) bits of the R1 and R 3 registers may or may not be set to zero.155
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 on page 412, using similar notations as in
Figure 222 on page 406, except that the source operand address is A3 and the source operand
length is L3.
155 This is not just a whim on the part of the CPU; it's meant to give the CPU designers more freedom to decide how
best to implement the instructions. (Maybe it's a whim on the part of the CPU designers?)
CC Meaning
0 All bytes moved, operand lengths are equal
1 All bytes moved, operand 1 shorter; part of operand 2 was not moved
2 All bytes moved, operand 1 longer; operand 1 was padded
3 Some bytes moved; end of operand 1 not reached
Table 156. CC settings after MVCLE
We can use MVCLE for the same task as in Figure 223 on page 406, where we again assume
that GR8 and GR9 have been initialized already:
412 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
LA 2,PrintMsg First operand address
LA 3,L'PrintMsg First operand length
LA 0,C' ' Set padding character to blank
Move MVCLE 2,8,0 Move the string, pad if necessary
JO Move Repeat if not finished
Figure 230. Using MVCLE to set a field to blanks
As another example, suppose we use MVCLE to initialize a large area of storage starting at Work
to zeros:
It's unlikely that you'd ever need to initialize such a large an area of storage; because the value at
WorkSize is larger than 224, we can't 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 on page 408, except that the source operand address is A3 and the
source operand length is L3.
CC Meaning
0 All bytes compared, operands equal, or both zero length
1 First operand low
2 First operand high
3 Some bytes compared without finding an inequality
Table 157. CC settings after CLCLE
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 signif-
icant:
β’ CLC requires only one or two base registers to address the operands; CLCL/CLCLE both
require up to 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 (or R 3) 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.3.(2) In 24-bit addressing mode, the maximum valid address is X'00FFFFFF', 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 413, 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.
414 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
25.3. Special βC-Stringβ Instructions
The four instructions in Table 158 arose from the need to process character strings used by the C
and C+ + programming languages, where character strings are terminated by a zero byte (X'00')
called a null byte.156 The instructions have many general uses, whatever the origins of the data,
and whether or not it contains a null terminating byte.
We will use a bold italic letter βnβ to represent a null byte, as in βnβ. For example,
DC C'A C-string.',X'0' Generates 'A C-string.n'
The length of a C-string does not include the terminating null character, so that the single byte
X'00' represents a C-string of length zero (a βnull stringβ).
opcode R1 R2
Table 159. Format of RRE-type instructions
Each instruction uses a special (end, test, or terminating) character in the rightmost byte of GR0.
All but TRE require that the remaining bits of GR0 be zero.
The operation of the MVCL, MVCLE, CLCL, and CLCLE instructions is controlled by a length
in a register; the four instructions in Table 158 are controlled by the presence of the special char-
acter 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.
For finding a single character, SRST is simpler and faster than a Translate and Test instruction
like TRT, or a CLI loop. Unlike TRT, however, it searches for only a single character.
To use SRST, set the test character in GR0, set the R 2 register to the address of the leftmost byte
of the string to be scanned, and the R1 register to the address of the first byte after the end of the
string. The CPU uses the address in the R1 register to know when to stop the scan; otherwise, it
could keep scanning bytes in memory until it found a match somewhere, or caused an unexpected
interruption. This is summarized in Figure 234 on page 416.
156 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.
CC Meaning
1 Test character found; R1 points to it
2 Test character not found before the byte addressed by R1
3 Partial search with no match; R1 unchanged, R 2 points to next
byte to process
Table 160. CC settings for SRST instruction
When a register is updated, any high-order bits not used for addressing are set to zero. Figure 235
sketches the operation of the SRST instruction. The notation used in the figure is:
A1 Address of the first byte after the end of the string being searched, in R1
A2 Address of a byte being checked during the search
Test Test character, taken from GR0
Yes ββββββββββ
START ββ
Save R1,R2 βββββ
A1β€A2? ββββββββ
βDone: β
β No βSet CC2 β
β β ββββββββββ
β Yes ββββββββββ
β c(A2)=Test? ββββββ
βDone: β
β β No βSet CC1 β
β ββββββββββ
β A2=A2+1
β β
β No Yes βββββββββββββββ
ββββ Enough ββββββββ
βDone: Set CC3β
for now? βSet R2βA2 β
βββββββββββββββ
Figure 235. Conceptual execution of the SRST instruction
If the test character is found at the moment the CPU has βscanned enough for nowβ and would
otherwise set the CC to 3, it may instead set the CC to 2; the net result is the same because
branching back to the SRST instruction when CC=3 will immediately produce CC=2.
For example, suppose you want to scan the string at MyData to find the first occurrence of a blank
character:
416 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
LA 0,C' ' Search character is a blank
LA 1,MyData Set GR1 to start of the string
LA 5,MyData+L'MyData Set GR5 to byte past end of string
Repeat SRST 5,1 Scan the string for a blank
JO Repeat Scan was incomplete, try again
JH NotFound CC2, no blank was found
- - - GR5 points to the blank
If the Condition Code is 3, we simply branch back to the SRST to continue the search.
Exercises
25.4.1.(2) Write a sequence of instructions to find the last nonblank character in a C-string of
characters stored at CData, whose length (at most 256 bytes) is stored in the word at CDataLen.
If all blank characters are found, branch to AllBlank. If the C-string is empty, branch to
NullData.
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.
CC Meaning
1 Entire second operand moved; R 1 points to end of first operand
3 Incomplete move; R 1 and R 2 point to next bytes to process
Table 161. CC settings for MVST instruction
Figure 236 on page 418 sketches the operation of the MVST instruction. The notation is the
same as in Figure 235 on page 416.
It's 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.
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.)
418 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
25.5.2.(2) In Figure 238 on page 418, how would you know that you had correctly processed
the last token in the source string?
25.5.3.(2) In Figure 238 on page 418, 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.
25.5.6.(3) Repeat Exercise 25.5.5, but assume that the amount of space available for the concat-
enated string is only 150 bytes. If the result will not fit in the space available, branch to
TooLong.
25.5.8.(3) Modify the instructions in Figure 238 on page 418 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.
The operands are compared byte by byte from left to right, until unequal bytes are found or the
end of an operand is reached. Unlike SRST, there is no stop address or operand length for either
operand, so be sure the strings are properly terminated.
If the end character is found in either operand before being found in the other, the shorter
operand is low; if they are found at the same time, the operands are equal.
The Condition Code settings after CLST are the same as those for other compare instructions,
except that CC3 indicates an incomplete operation. As with SRST and MVST, if the Condition
Code is 3, you can just branch back to repeat the CLST.
CC Meaning
0 Entire operands are equal; R1 and R 2 unchanged
1 First operand low; R 1 and R 2 point to last bytes processed
2 First operand high; R 1 and R 2 point to last bytes processed
3 Operands equal so far; R1 and R 2 point to next bytes to process
Table 162. CC settings for CLST instruction
Figure 239 on page 420 sketches the operation of the CLST instruction. The notation used in the
figure is:
A1 Address of a first-operand byte, c(R1)
c(A1) The first-operand byte at address A1
A2 Address of a second-operand byte, c(R2)
c(A2) The second-operand byte at address A2
End End character in GR0
x:y x is compared to y
When an inequality is found, the ending characters of the operands are not part of the compar-
ison. 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
420 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
β1 if StringA is less than StringB. Be sure to handle cases where either or both strings are
shorter than N bytes.
(2) X DC X'0'
Y DC X'0'
(3) X DC C'ABCD',X'0'
Y DC C'ABCDEFGH',X'0'
(4) X DC C'BCDEFGH',X'0'
X DC 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 βdon't careβ character which can match any other character.) Branch to AB_Equal, A_High, or
B_High accordingly.
One important result of having a stop character is that it can't be translated, unless you add extra
instructions to do your own βtranslationβ after TRE completes.
Table 163 gives the Condition Code settings following execution of a TRE instruction:
CC Meaning
0 All bytes translated; R1 incremented by length, R1 + 1 set to 0
1 R 1 points to the byte matching the stop character; R1 + 1 decremented by the
number of bytes processed before the match
3 R 1 incremented and R 1 + 1 decremented by the number of bytes processed
Table 163. CC settings for T R E instruction
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 256AL1(*-UpperTbl) Initialize table to identities
Org UpperTbl+C'a' Position at C'a'
DC C'ABCDEFGHI' Upper-case equivalents
Org UpperTbl+C'j' Position at C'j'
DC C'JKLMNOPQR' Upper-case equivalents
Org UpperTbl+C's' Position at C's'
DC C'STUVWXYZ' Upper-case equivalents
Org , Reposition Location Counter
Exercises
25.7.1.(2) What do you think will happen to a TRE instruction if R1 = 0 or R 2 = 0?
If R 1 = R 2?
(2) N Equ 7
X DC C'Unknown?'
(3) N Equ 50
X DC 10C'Possibly? '
422 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
25.8. Compare Until Substring Equal Instruction (*)
CUSE is a very complex instruction. 157 It is unusual in another way: it is both interruptible
(βMethod Aβ) and stops and sets Condition Code 3 to allow interruption processing (βMethod
Bβ). 158 Though not widely used, it may be applicable in certain applications.
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.159
It's 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 165 on page 424.
157 Other complex instructions include EDIT and EDMK; we'll see them in Section 30 when we describe packed
decimal arithmetic.
158 At the time of this writing, I know of no other instruction that supports both types of interruption management.
159 A signed length seems strange, as it's hard to think of uses for strings with negative lengths. Other instructions like
MVCL and MVCLE use unsigned lengths. (See Exercise 25.8.7.)
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:
The results are shown in Table 166; matching substrings are underlined.
Substr Pad L1 L2
String1 L1 String2 L2 Len Char CC after after Result
CABCEFDEFEAB 12 ACBABBCEFEAB 12 3 C' ' 0 5 5 Match
ABCDEF 6 BCDEFA 6 3 C' ' 2 0 0 No match
ABCBACAC 9 BCBABCAC 9 3 C' ' 0 3 3 Match at end
ABC 3 CABAAA 6 3 C'A' 0 0 3 Match with pad
ABC 3 CABCAB 6 3 C'A' 2 0 0 No match
ABCBA 5 BCBAA 5 3 C'A' 1 1 1 No match, last bytes equal
Table 166. Results of examples using the CUSE instruction
Searching for matching substrings can be a complex and tedious process, especially if different
offsets are allowed. (See Exercise 25.8.1 and Programming Problem 25.1.)
Exercises
25.8.1.(4) Write a sequence of instructions using CLCLE instructions to emulate the function
of CUSE.
25.8.2.(2) + What is the length of the longest matching substring that can be found using
CUSE?
25.8.3.(2) Suppose a CUSE instruction detects an inequality following several equal bytes, but
the number of equal bytes is less than the required substring length. Should the instruction
restart its comparison at the second equal bytes, or at the bytes following the inequality?
25.8.4.(2) + Suppose your CUSE instruction specifies a substring length 2 with padding char-
acter 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
424 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
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, pro-
grams scanning or moving such strings may process far more data than intended, possibly over-
writing other data or parts of the program.
The instructions discussed in this section are listed in Table 167; all set the Condition Code.
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.
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 instruc-
tion 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 char-
acter. 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.9.(3) The C/C++ function strpbrk searches a C-string for the first occurrence of any char-
acter 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β.)
The instruction opcodes and mnemonics are shown in the following table:
426 Assembler Language Programming for IBM System zβ’ Servers Version 2.00
Terms and Definitions
C-string
A string of zero or more bytes ending with a zero or βnullβ byte.
destructive overlap
Destructive overlap occurs when any part of a target operand field is used for a source after
data has been moved into it.
interruptible
An instruction is interruptible if the CPU suspends its operation, updates the registers
involved in the operation and subtracts the instruction's length from the Instruction Address
in the PSW, so that when the program resumes execution, the instruction will start from the
point where it was interrupted.
null byte
A zero or X'00' byte, sometimes indicated by the character n.
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 shouldn't report a one-byte substring like '1'.
Problem 25.2.(3) + Programs must sometimes isolate a string of characters preceded and fol-
lowed by strings of blanks. For example, if the original string is 'β’β’β’ABβ’CDβ’β’' (where β’ means a
blank character), the desired result is the string 'ABβ’CD'.
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 CL80' AB CD ' As in the example above
DC 80C'*' No blanks
DC CL80'AB' No leading blanks
DC CL78' ',C'YZ' No trailing blanks
DC CL80' ' All blanks
You should create other records to exercise your program.
2222222222 6666666666
222222222222 666666666666
22 22 66 66
22 66
22 66
22 66666666666
22