Reading: Ch 2.1-2.2 and Appendix C
We begin with the introduction to a hypothetical CPU based on the readings from the Brookshear text.
To bring that hypothetical CPU to life, we use a CPU software simulator based upon a version from the publisher's website.
Developing interesting programs in a machine language takes great care. To demonstrate some non-trivial programs we look at the following examples.
We can perform multiplication of two numbers based upon repeated aditions. For example, 5 * 7 can be computed as 7+7+7+7+7.
Before discussing the code, we should describe our overall design and the use of the registers. We load the original two operands from memory locations 20 and 21, storing them respectively in registers 0 and 1. Our use of registers is as follows.
| register | usage | initialization |
|---|---|---|
| 0 | first operand | from memory 20 |
| 1 | second operand | from memory 21 |
| 2 | accumulator | 0 |
| 3 | counts number of passes thus far | 0 |
| 4 | The value one (used for incrementing) | 1 |
| address | instruction | formal description | comment |
|---|---|---|---|
| 00: | 1020 | Load register 0 with bit pattern found at 20 | (loads first operand) |
| 02: | 1121 | Load register 1 with bit pattern found at 21 | (loads second operand) |
| 04: | 2200 | Load register 2 with bit pattern 00 | (accumulator starts at 00) |
| 06: | 2300 | Load register 3 with bit pattern 00 | (counter starts at 00) |
| 08: | 2401 | Load register with bit pattern 01 | (used for increment by one) |
| 0a: | b312 | If bit pattern in register 3 equals the value in register 0, jump to location 12 |
(enough repetitions) |
| 0c: | 5212 | Add bit patterns in registers 1 and 2, store result in register 2 |
(add to accumulator) |
| 0e: | 5334 | Add bit patterns in registers 3 and 4, store result in register 3 |
(increment counter) |
| 10: | b00a | If bit pattern in register 0 equals the value in register 0, jump to location 0a |
(unconditional jump) |
| 12: | 3223 | Store bit pattern from register 2 at address 23 | (write result) |
| 14: | c000 | Halt |
We can compute the absolute value of a given number as follows. First, we need to determine whether or not the bit pattern represents a negative number. Because numbers are stored using the twos-complement system, a negative number is one which starts with a leftmost bit of 1, whereas a non-negative number has a leftmost bit of 0.
When the original number is non-negative, the absolute value is the same as the original. When a number is negative, we can compute the absolute value by negating the number. Because negative numbers are represented with the twos-complement system, the negation can be computed by first reversing all of the individual bits (by XORing with mask ff), and then by adding one to that value.
Here is code which performs this task.
| address | instruction | formal description | comment |
|---|---|---|---|
| 00: | 1120 | Load register 0 with bit pattern found at 20 | (loads original) |
| 02: | 2280 | Load register 2 with bit pattern 80 | (mask for checking sign bit) |
| 04: | 8312 | AND the bit patterns in registers 1 and 2, and store result in register 3/td> | (check sign bit) |
| 06: | 2000 | Load register 0 with bit pattern 00 | (for comparison to sign bit) |
| 08: | b312 | If bit pattern in register 3 equals the value in register 0, jump to location 12 |
(original is positive) |
| 0a: | 22ff | Load register 2 with bit pattern ff | (mask for complementing) |
| 0c: | 9112 | XOR bit patterns in registers 1 and 2, store result in register 1 |
(complement original) |
| 0e: | 2201 | Load register 2 with bit pattern 01 | (about to add one) |
| 10: | 5112 | ADD bit patterns in registers 1 and 2, store result in register 1 |
(done negating) |
| 12: | 3121 | Store bit pattern from register 1 at address 21 | (write result) |
| 14: | c000 | Halt |