Tuesday, May 10, 2011

The Postroom Computer Assignment

This is a programming assignment for the Postroom Computer. It is an individual assignment. In this assignment you are going to extend the range of values that can be used in arithmetic calculations on the two address, register addressed Postroom Computer (PC2r).

Backgound
Word Size
The Postroom Computer has a limited word size. This means that the pigeonholes (memory cells) can only hold a limited range of values -- for example a two address Postroom Computer memory cell can only store up to nine decimal digits. This means that the largest unsigned integer value1 that can be stored on the PC2r is 999,999,999. If a calculation results in a value outside this range any digits ``in the milliards''2 or above are lost.
Arithmetic instructions
The only arithmetic instructions on the Postroom Computer are ADD, SUB, SHF and MSK. These are all limited by the limited word size of the Postroom Computer. Initially we will only consider the ADD and SUB instructions (but see section 4.6).
Consider an ADD instruction which is to add 750 million (750,000,000) and 500 million (500,000,000). The ``real world'' result of this addition is one milliard 250 million (1,250,000,000). On the PC2r the actual result will be 250 million (250,000,000). The figure in the milliards will be lost. All results on the PC2r are calculated modulus one milliard (1,000,000,000). I.e. the result of any calculation is actually the remainder when the ``real world'' result is divided by one milliard. So the result, on the PC2r, of adding 750,000,000 and 500,000,000 is:

This is obviously a limitation. In this assignment you are going to extend the Postroom Computer to handle larger values (up to one trillion -- 1,000,000,000,000,000,000 [3].
Condition Codes
An arithmetic instruction leading to an incorrect result (because the real result is too big) will set the carry flag, in the same way that a negative (signed integer) result will set the negative flag and a zero result will set the zero flag. These are the values tested by the or JMP instruction. The condition codes (the argument of the JMP instruction) indicate which flag(s) to test. There are 12 arithmetic condition codes with their own mnemonic

In this assignment you will mostly be using the carry codes CRY and NCRY.
Long words
A long word is a value stored in two memory cells. One memory cell contains the milliards, the other the units. For example, if memory cell :x: contains 236 and memory cell :y: contains 724,912,824, the long word made up of :x: and :y:. represents the number 236,724,912,824. The memory cell :x: is called the most significant word (MSW or msw) and the cell :y: the least significant word (LSW or lsw). We can picture this as:

The Assignment
The aim of this assignment is to extend the Postroom Computer to handle long word arithmetic. Initially you will only need to extend addition and subtraction. You will do this by implementing the following long word macros:
ADDL x y
add the long word y to the long word x, leaving the result in long word x,
SUBL x y
subtract the long word y from the long word x, leaving the result in long word x.
Later you may need to implement:
SHFL x y
shift the long word x by the amount specified in the standard word y, leaving the result in long word x,
MSKL x y
mask the long word x against the ``mask pattern'' in long word y, leaving the result in long word x.
You may find it useful, for writing your own test programmes, to also define the following macros:
OUTL x
output the unsigned long word x (you could extend this to OUTL x f: output the long word x in the format (signed or unsigned) specified by the standard word f),
INPL x
input an unsigned long word value to the long word x (because of the way input works on the PC2r you will almost certainly have to input the long word as two separate unsigned integers, one for the most significant word, one for the least significant word).
Note that, in some cases, your macros may have a different number of parameters than given here -- see sections 4.1 and 4.2 for details.
You will be given a set of test programes for testing your solution. These will form part of a larger set of test programmes that will be used to mark your code -- see section 6 for details. You may also want to write some more complex test programmes yourself -- e.g. a programme that, given two numbers, n and m say, computes .
General Approach
To add (or subtract) two long word numbers you will first have to perform the operation on the least significant words and then on the most significant words, adjusting this result if the operation on the least significant words resulted in a carry. For example, when adding 12,500,000,000 (represented by the long word with MSW=12, LSW=500,000,000) and 532,750,000,000 (long word with MSW=532, LSW=750,000,000) the addition of the least significant words gives the result 250,000,000 with a carry. Adding the most significant words gives 544. This should be increased by one because of the carry, giving 545, so that the final result is the long word with MSW=545, LSW=250,000,000 representing 545,250,000,000.

Methodology
General Method
Design your programme using (pseudo) high level code, and then refine this to a (low level) Postroom Computer programme.
Storage and Addressing
You are going to have to make some decisions about how (where) to store the two components of long words. This will also affect the ways in which you can address long words. You should be asking yourself the following questions.
Storage.
Is it better to store the least significant and most significant words in consecutive memory locations or not? If not, how can you address the two components of a long word? What are the advantages and disadvantages of each approach? If so, is it better to store the least significant word first (at the lower address), or the most significant word first? I.e. should you store 123,456,987,654,321 as:

or as:

Can registers be used to hold long word values? If so, how will you allocate registers for the least and most significant word? If not, why not? What are the advantages and disadvantages?
Addressing.
How do storage decisions affect the addressing of long words? Are explicit addresses needed for both the least significant and most significant word of a long word -- e.g. will your ADDL macro require four parameters: , or can the programme ``deduce'' e.g. the most significant word from the least significant word (or vice versa)? Should the parameters of your macros contain the values or the addresses of long words -- e.g. in a macro call ADDL .R0 .R4 does .R0 contain the value of the least (or most) significant word of the first operand, or does it contain the address of the least (or most) significant word?
Recommended Development Process
This section provides a step by step guide to developing your double word macros. I would recommend starting by writing a high level (pseudo) code programme to add and subtract two long word numbers on the two address, register addressed Postroom Computer. For the time being assume that all operands are at fixed locations -- e.g. the least significant word of the first operand is in R0, with the most significant word in R1; the second operand is in R2 (least significant word) and R3 (most significant word); and the result will be in R4 (lsw) and R5 (msw).
Step E
Implement your pseudocode on the two address, register addressed Postroom Computer as code fragments, and adapt these code fragments for use as simple (parameterless) ADDL and SUBL macros. Your code will define two macros, called ADDL and SUBL. The ADDL macro will take the long word value in (R0 [lsw],R1 [msw]), add it to the long word in (R2 [lsw],R3 [msw]), and put the result in the long word (R4 [lsw],R5 [msw]). The SUBL macro should do the same, but for subtraction.
Do not worry, for the time being, about possible side effects of calls to your macros.
Save your code in a file called lword-e.pca. If you have used any subroutines they should be in a separate file called lwsub-e.pca.
Step D
Add parameters to your macros to increase their flexibility. Both the least and most significant words will be given explicitly -- i.e. your ADDL and SUBL macros will require four parameters (e.g. ) as described in section 3.2.2. A call of this macro should take the long word in and (the source value), add it to the long word in and (the destination value), and put the result in and . In these macros the value of, for example, will be the value of the first long word's least significant word.
Try to minimise any side effects of calls to your macros, but do not, as yet, worry too much about the ``difficult'' addressing modes such as predecrement and postincrement direct and indirect.
Save your code in a file called lword-d.pca. If you have used any subroutines they should be in a separate file called lwsub-d.pca.
Step C
From now on, assume that:
• long words are always to be found in memory, not (directly) in registers;
• the most significant and least significant words of any one long word are always stored in consecutive memory locations;
• the least significant word is stored first -- i.e. in the lower of the two memory locations, so that 123,456,987,654,321 will be stored as

Adapt your macros from the previous step so that they now only need one parameter for each long word. E.g. , where the value of, for example, the parameter would be the effective address of the least significant word of the destination long word for the ADDL ``instruction''.
Calls to your macros should have no unexpected side effects, except, maybe, if ``difficult'' addressing modes are used in the macro call's parameters.
Save your code in a file called lword-c.pca. If you have used any subroutines they should be in a separate file called lwsub-c.pca.
Step B
Your macros should now be completely transparent -- i.e. there should be no unexpected side effects no matter which addressing modes are used.
Save your code in a file called lword-b.pca. If you have used any subroutines they should be in a separate file called lwsub-b.pca.
Step A
Not only will your macros be transparent, but they will also ``set the flags'' correctly -- e.g. adding the long word values 750 billiard (750,000,000,000,000,000) and 500 billiard (500,000,000,000,000,000) should, in the real world, give one trillion, 250 billiard (1,250,000,000,000,000,000) as a result will, in long word arithmetic give 250 billiard (250,000,000,000,000,000) -- the trillions value has been lost -- should set the carry flag so that a JMP CRY :label: instruction would jump to address :label:. Note: not only the carry flag has to be set correctly -- the zero, negative and overflow flags should also be correct.
Save your code in a file called lword-a.pca. If you have used any subroutines they should be in a separate file called lwsub-a.pca.
Step A+
As for step A, but you should now also implement SHFL and MSKL macros as described in section 3. You should also write a short proposal on how you would implement ``infinite length'' arithmetic, as described in a footnote.
Save your code, containing all four macros, in a file called lword-a+.pca. If you have used any subroutines they should be in a separate file called lwsub-a+.pca.

No comments:

Post a Comment