Old version
This is the CS 111 site as it appeared on May 10, 2018.
Problem Set 5
Preliminaries
In your work on this assignment, make sure to abide by the collaboration policies of the course.
If you have questions while working on this assignment, please
come to office hours, post them on Piazza, or email
cs111-staff@cs.bu.edu
.
Make sure to submit your work on Apollo, following the procedures found at the end of the assignment.
Part I
due by 11:59 p.m. on Thursday, March 15, 2018
Problem 0: Reading and response
5 points; individual-only
Our recent focus in CS 111 has been on low-level computer organization. This week’s reading considers one man’s vision of the future of computation hardware and, more generally, of humanity itself!
Begin by reading a profile of inventor and futurist Ray Zurzweil from The Guardian.
After you have read it, write a response that addresses–at least
to some extent–both of the following prompts. Put your response
in a file named ps5pr0.txt
. Don’t forget that the file that you submit
must be a plain-text file.
-
Kurzweil views technology as a fundamentally positive force in human development. Is his vision of the future one that you would look forward to? Why or why not?
-
Kurzweil has a track record of remarkable inventions and successful predictions. Do you believe the predictions cited in this article? Why or why not?
As always, you only need to write a short paragraph that reflects your critical thinking about the article.
Preparing for the Remaining Problems in Part I
-
Installing Logicly
In the rest of this assignment you will design several digital circuits using a circuit-design tool called Logicly. If you haven’t already installed Logicly on your own computer, you should do so now by going to the Logicly web site and taking the following steps:
-
Click on the appropriate version for your machine to download the free 30-day trial.
-
If prompted to do so, choose to save the file.
-
Double-click or tap the icon for the downloaded file. This will start up an installer program. If prompted to do so, click Yes or Run.
-
You should be able to use all of the default settings that the installer gives you by just clicking or tapping on the Next button.
-
Once the installation is complete, click/tap the Finish button. Logicly should now be installed.
Important: Although it’s possible to use Logicly in your browser, you need to download it in order to be able to save your work.
You can also use Logicly on the machines in the undergrad CS lab (EMA 302).
-
-
Using Logicly
-
When you open Logicly, it will prompt you to enter a product key. Simply click the Continue Trial button to bypass this step.
-
We strongly encourage you to watch a video on Logicly that was created by an illustrious former staff member, Alex Breen. It provides a good overview of how to use the program.
-
The Logicly documentation is available here or by selecting the Help->Contents menu option.
-
-
Downloading and opening the starter files
Next, download the following zip file: ps5partI.zipUnzip this archive, and you should find a folder named
ps5partI
, and within it a starter file for each problem in Part I.
Warning
In each of the starter files, we have included switches for the inputs and one or more light bulbs for the outputs. You must use the provided components in your circuit, and you should not change their properties in any way (e.g., by changing their names).
If you fail to use our components without changing them, we will not be able to automate the grading of your submission, and you will lose points as a result.
Problem 1: XOR
5 points; individual-only
Open the ps5pr1.logicly
starter file in Logicly (see above for
instructions on how to obtain the starter files).
The XOR function takes two inputs (x
and y
), and it outputs a 1
if and only if exactly one of its inputs is 1. It has the following
truth table:
inputs | x y | output ------------------- 0 0 | 0 0 1 | 1 1 0 | 1 1 1 | 0
Build a circuit for the XOR function using the minterm expansion
principle that we discussed in lecture. The resulting circuit should use
only AND
, OR
, and NOT
gates.
Notes:
-
We’ve provided you with switches for the inputs
x
andy
, as well as with aNOT
gate for the negation of each input. For example, the leftmost switch is forx
itself, and theNOT
gate immediately to its right is forNOT x
. We have also provided you with a light bulb for the output. You must use these components in your circuit, and you should not change their properties. -
You are welcome to move the provided components as needed, but please keep their relative positions the same. For example, the inputs should remain at the top of your circuit, and
x
should be to the left ofy
. -
Use the Selection Tool to drag the necessary logic gates into your circuit and to add the necessary wires. See the overview video for more detail.
-
You may also find it helpful to use the Pan Tool (the hand icon available at the top of the screen) and the magnification slider available in the lower right-hand corner to adjust how much of your circuit is visible. After using the Pan Tool, don’t forget to switch back to the Selection Tool.
-
Test your circuit by clicking the input switches to turn them on and off. Check to see if you obtain the correct output for all possible inputs. Remember that XOR should output a 1 if and only if exactly one of the two inputs is a 1.
-
Once this circuit is working, save your work by using the File->Save menu option.
Problem 2: Full Adder
20 points; pair-optional
This is one or only two problems that you may complete with a partner. See the rules for working with a partner on pair-optional problems for details about how this type of collaboration must be structured.
Open the ps5pr2.logicly
starter file in Logicly.
If you are working with a partner, there is a text block at the top
of this subcircuit for your partner’s name and email (if any). To add the
necessary information, select the text block with the Selection Tool
(the arrow) and edit the Text in the Label Properties pop-up
window.
Build a Full Adder (FA) as described in lecture. It is also described
in section 4.3.4 of the textbook. Use the minterm expansion
principle to create a circuit that uses only AND
, OR
, and NOT
gates.
Remember that a Full Adder adds a single column of digits from the bitwise sum of two binary numbers. It takes three inputs:
x
andy
, the two bits being added from this column of the additionc_in
, the carry bit into this column of the addition
and it should produce two separate outputs:
s
, the bit from the sum that would go at the bottom of this column of the additionc_out
, the carry bit out of this column of the addition.
See below for how to export your Full Adder so that it can be used in later problems.
Notes:
-
After opening the file, you may need to use the Pan Tool (the hand icon available at the top of the screen) and the magnification slider available in the lower right-hand corner to see all of the provided components. After using the Pan Tool, don’t forget to switch back to the Selection Tool.
-
We’ve provided you with the three inputs and the two outputs, as well as with
NOT
gates for the inputs. You must use the provided inputs and outputs, and you should not change their properties. -
You can adjust the positions of the inputs and output as needed, but please keep their relative positions the same.
-
You should start with the truth table for a Full Adder. You can write it out yourself, or you can use the one that we gave you in the lecture notes. Once you have the truth table, you should apply the minterm expansion principle twice: once to obtain a circuit that will produce the correct outputs for
s
, and once to obtain a circuit that will produce the correct outputs forc_out
. -
Don’t try to simplify your circuit, and don’t use gates other than
AND
,OR
, andNOT
. The purpose of this problem is to practice using the minterm expansion principle. (Note: Logicly provides a sample Full Adder circuit, but it uses an approach other than minterm expansion, so it’s not useful for this problem.) -
Here again, you should test your circuit by clicking the input switches to turn them on and off. Once this circuit is working, save your work by using the File->Save menu option.
-
Exporting your Full Adder: Because you will use your Full Adder in later problems, you should take the following steps to export it:
-
Use the Edit->Select All menu option to select the entire circuit.
-
Click the building block icon (which looks like a Lego piece) at the top of the screen. (Alternatively, you can select the Edit->Create Integrated Circuit menu option.)
-
In the window that pops up, give your circuit a name (e.g.,
Full Adder
) by entering it in the Full Name text box. You can also add a Symbol Label, but doing so is not required. -
Click the Create IC button to create the integrated circuit.
-
Use the File->Export Integrated Circuit Library menu option to export your work. Give the file an appropriate name (e.g.,
full_adder
) and save it in a place where you can easily find it.
-
Problem 3: 4-Bit Ripple-Carry Adder
20 points; individual-only
Open the ps5pr3.logicly
starter file in Logicly.
Build a 4-Bit Ripple-Carry Adder. We examined a 2-Bit Ripple-Carry Adder in lecture, and the textbook also discusses it. This problem requires you to extend that circuit to a 4-bit version.
Recall that a Ripple-Carry Adder combines multiple Full Adders to produce a circuit that adds two binary numbers. Each Full Adder handles one column of the addition. The circuit as a whole takes eight inputs:
- the 4 bits of one of the numbers:
x3
,x2
,x1
, andx0
- the 4 bits of the other number:
y3
,y2
,y1
, andy0
and it should produce five outputs (s4
, s3
, s2
, s1
, and s0
)
that correspond to the five bits of the sum. The relationships between the
inputs and the outputs are shown below:
x3 x2 x1 x0 + y3 y2 y1 y0 -------------- s4 s3 s2 s1 s0
Note that the sum has five bits to accommodate the possibility of a carry.
This circuit should not be built using the minterm expansion principle. Rather, it should be built by combining four instances of your Full Adder circuit.
See below for information about how to import your Full Adder, as well as for the steps needed to export Ripple-Carry Adder so that it can be used in later problems.
Notes:
-
Here again, you should use the Pan Tool and the magnification slider as needed to see all of the provided components.
-
You must use the provided inputs and outputs. Please keep their relative positions the same, and do not change their properties. (Note that we haven’t provided
NOT
gates for the inputs because you won’t need to negate them.) -
Using Your Full Adder:
- Use the File->Import Integrated Circuit Library menu option to import the file in which you stored your exported Full Adder circuit. (If you haven’t already exported your Full Adder, do so now by following the steps from the last note of the previous problem.)
- After importing the file, scroll down to the bottom of the
left-hand pane of components. You should see a section
labeled
Custom
that contains a building block for your Full Adder. - You can insert a copy of your Full Adder into your circuit by
using the Selection Tool to drag the Full Adder building block
into the circuit. You should see a box that looks like this:
- It will be easier to use a Full Adder if you rotate it
clockwise. To do so, select a Full Adder box and click the
Rotate Clockwise icon at the top of the screen (or choose the
Edit->Rotate Clockwise menu option). After rotating, the Full
Adder box should look like this:
-
You will need a
c_in
of 0 on the far right of the Ripple-Carry Adder. Use the built-in component labeledLow Constant
for this purpose. Simply drag it into your circuit and connect it to the appropriate input of the rightmost FA. -
Here again, you should test your circuit by clicking the input switches to turn them on and off. Once this circuit is working, save your work by using the File->Save menu option.
-
Exporting your Work: Because you will use your 4-Bit Ripple Carry Adder in later problems, you should take the following steps to export it:
-
Use the Edit->Select All menu option to select the entire circuit.
-
Click the building block icon (which looks like a Lego piece) at the top of the screen. (Alternatively, you can select the Edit->Create Integrated Circuit menu option.)
-
In the window that pops up, give your circuit a name (e.g.,
4-Bit Ripple-Carry Adder
) by entering it in the Full Name text box. You can also add a Symbol Label, but doing so is not required. -
Click the Create IC button to create the integrated circuit.
-
Use the File->Export Integrated Circuit Library menu option to export your work. Note that you will end up exporting both your Full Adder (since you imported it for this problem) and your Ripple-Carry Adder. Give the file an appropriate name (e.g.,
both_adders
) and save it in a place where you can easily find it.
-
Problem 4: 4x1 Multiplier
10 points; individual-only
Open the ps5pr4.logicly
starter file in Logicly.
Build a 4x1 multiplier in the space provided. This circuit takes five inputs:
- the 4 bits of the first factor:
x3
,x2
,x1
, andx0
- the 1 bit of the other factor,
y
.
It will have four outputs (p3
, p2
, p1
, and p0
) that correspond to
the four bits of the product. The relationships between the
inputs and the outputs are shown below:
x3 x2 x1 x0 * y -------------- p3 p2 p1 p0
Because you are multiplying the first factor by either 0 or 1, the product can be computed very simply, using exactly four gates! Considering some concrete cases should help you to determine which gates you should use, and how they should be arranged. You should not need to employ the minterm expansion principle.
Notes:
-
Here again, you should use the Pan Tool and the magnification slider as needed to see all of the provided components.
-
You must use the provided inputs and outputs, and you must not change their properties. Please keep their relative positions the same.
-
We’ve positioned the outputs at the bottom of the circuit, because doing so will make your circuit easier to use in the context of the next problem. Because of this, you may want to adjust the directions in which your gates are facing. After adding a gate to the circuit, you can rotate it by selecting it and then using one of the rotate icons at the top of the screen.
-
As always, you should test your circuit by clicking the input switches to turn them on and off. Once this circuit is working, save your work by using the File->Save menu option.
-
Exporting your 4x1 Multiplier: Because you will use your 4x1 Multiplier in the next problem, you should take the following steps to export it:
-
Use the Edit->Select All menu option to select the entire circuit.
-
Click the building block icon (which looks like a Lego piece) at the top of the screen. (Alternatively, you can select the Edit->Create Integrated Circuit menu option.)
-
In the window that pops up, give your circuit a name (e.g.,
4x1 Multiplier
) by entering it in the Full Name text box. You can also add a Symbol Label, but doing so is not required. -
Click the Create IC button to create the integrated circuit.
-
Use the File->Export Integrated Circuit Library menu option to export your work. Give the file an appropriate name (e.g.,
4x1_multiplier
) and save it in a place where you can easily find it.
-
Problem 5: 4x2 Multiplier
15 points; individual-only
Open the ps5pr5.logicly
starter file in Logicly.
Build a 4x2 multiplier, which takes six inputs:
- the 4 bits of the first factor:
x3
,x2
,x1
, andx0
- the 2 bits of the second factor:
y1
andy0
.
and produces as outputs the six bits of the product: p5
, p4
, p3
,
p2
, p1
, and p0
.
Your circuit should perform the computation shown below:
x3 x2 x1 x0 * y1 y0 ----------------- p5 p4 p3 p2 p1 p0
You circuit should employ the “elementary-school” binary multiplication
algorithm that we discussed in lecture. More specifically, you need to
compute two partial products: the product of the top number
(x3 x2 x1 x0
) with the bit y0
, and the product of the top number
with the bit y1
. You then need to add these partial products together
in the appropriate way.
This circuit should not be built using the minterm expansion principle. Rather, it should be built by combining one or more instances of your 4x1 Multiplier and your 4-Bit Ripple-Carry Adder. See below for information about adding those components to your circuit.
Notes:
-
Here again, you should use the Pan Tool and the magnification slider as needed to see all of the provided components.
-
You must use the provided inputs and outputs, and you must not change their properties. Please keep their relative positions the same.
-
You can insert one or more copies of your 4x1 Multiplier and 4-Bit Ripple-Carry Adder using the same procedure that you used to add instances of your Full Adder in Problem 3. In this case, you will need to import two files: the one containing both adders (i.e., your work from Problem 3), and the one containing your 4x1 Multiplier (i.e., your work from Problem 4).
-
We recommend that you rotate each 4x1 Multiplier and 4-Bit Ripple-Carry Adder clockwise, following the procedure used to rotate your Full Adder in Problem 3. Doing so will cause each component’s inputs to be at the top of its box, and its outputs to be at the bottom of its box.
-
You will need at least one constant in your circuit. See the notes that accompany Problem 3 for a reminder of how to add a constant.
-
Don’t forget to test your circuit and save your work! During testing, you may find it helpful to use a calculator that can multiply in binary. Here are three options:
-
In Windows 10, open the Calculator by searching for it from the Start menu. Then use the Programmer menu option, and choose the BIN option near the left-hand side of the window.
-
In older versions of Windows, open the Calculator by going to Start Menu->Accessories->Calculator. Then use the View->Programmer menu option, and choose the Bin option on the left-hand side of the window.
-
In Mac OS X, open the Calculator from /Applications, Spotlight, or Launchpad. Then select the View->Programmer menu option.
-
Write a function in Python that makes use of the base-conversion functions that you wrote for Problem Set 4!
-
Optional Bonus Problem: 3x2 Divider
for 10 points of extra credit; individual-only
Open the ps5pr6.logicly
starter file in Logicly.
Build a 3x2 Divider, which takes five inputs:
- the 3 bits of the dividend:
y2
,y1
, andy0
- the 2 bits of the divisor:
x1
andx0
and produces four outputs:
- the 3 bits of the quotient:
q2
,q1
, andq0
- a special output called
error
that is used to signal a division-by-zero error. It should be 1 if and only if the divisor’s value is 0. If the error bit is a 1, it doesn’t matter whether the bits in the quotient are 0 or 1.
The relationships between the inputs and the first three outputs are shown below:
q2 q1 q0 ___________ x1 x0 | y2 y1 y0
Note that the circuit should perform integer division–rounding down and ignoring any remainders. For example, 7 divided by 2 should be 3:
0 1 1 _________ 1 0 | 1 1 1
Two possible approaches:
-
Use the full truth table for 3x2 division (which we discussed in lecture), and apply the minterm expansion principle three times–once for each bit of the quotient. (The portion of the circuit that handles the error bit can be constructed more simply, because its output only depends on the divisor.)
-
Break the problem into pieces by considering each of the four possible divisors separately:
-
divisor is 1: Any dividend that is divided by 1 will be passed directly to the output quotient without any changes.
-
divisor is 2: Dividing by 2 is equivalent to shifting the bits in the dividend one place to the right to produce the quotient. The example above of 7 divided by 2 provides one illustration of this.
-
divisor is 3: This is a trickier case! Look at the rows in the truth table for this divisor, and see if you can identify any patterns that will allow you to simplify this portion of the circuit.
-
divisor is 0: This always results in an error, regardless of the value of the dividend. In addition, we don’t care what is produced for the bits of the quotient in this case.
Each of these four divisors can be a subcircuit that you build and test on its own. Then you can combine the outputs of the subcircuits by ORing the outputs for a given output bit together. For example, the value of
q0
can be obtained by ORing together the value produced forq0
by each of the subcircuits.When constructing the OR gate for a given output bit, you only need to include the subcircuits that may produce a 1 for that output bit. For example, when constructing the OR gates for the bits of the quotient, you don’t need to include the divisor-is-0 subcircuit, because that subcircuit only produces a 1 for the error bit.
-
Notes:
-
Here again, you should use the Pan Tool and the magnification slider as needed to see all of the provided components.
-
You must use the provided inputs and outputs, and you must not change their properties. Please keep their relative positions the same so that we can easily test your circuit.
-
As we did in Problems 1 and 2, we have provided a
NOT
gate for each input that you can use when you need to negate it. -
Once again: test your circuit and save your work!
Part II
due by 11:59 p.m. on Sunday, March 18, 2018
Preparing for the Problems in Part II
-
Background information on assembly language and Hmmm
Although we have covered the topics of assembly language and Hmmm in the pre-lecture materials and lectures, we encourage you to review: -
Downloading and unzipping the starter files
Next, download the following zip file: ps5partII.zipUnzip this archive, and you should find a folder named
ps5partII
that contains all of the files that you will need for Part II, including a subfolder calledhmc
.You should not move any of the files out of the
ps5partII
folder. Keeping everything together in the folder will ensure that you are able to assemble and run your programs. -
Testing the process that you will use
One of the files that we have given you in theps5partII
folder is calledexample1.txt
.To test the process that will use in this assignment, you should do the following:
-
Open the file in any text editor.
-
Review its contents
Take a moment to look over the program:00 read r1 # get # from user and store it in r1 01 read r2 # ditto, for register r2 02 mul r3 r1 r2 # r3 = r1 * r2 03 write r3 # write out (print) the contents of r3 04 halt # stop here
As you can see, the program gets two inputs from the user and stores them in registers
r1
andr2
. It then computes the product of the inputs, storing the result inr3
. Finally, it prints out the result, and stops.Pay close attention to the style of the program. In particular:
-
Each assembly-language instruction is on a separate line that begins with a memory address/line number (e.g., the number 00 at the start of the first line). We’re using two-digit memory addresses, but one-digit numbers would also be fine here.
-
There are several spaces between the memory address and the actual instruction, and all instructions are aligned with each other.
-
Comments start with a # symbol, and are also aligned with each other. You must have a comment on every line except for
nop
andhalt
statements. -
You should avoid the use of special characters (e.g.,
$
, quotes, or&
) in your comments, because they may produce errors when your code is assembled. Limit your comments to letters, numbers, spaces, and the#
symbol.
All Hmmm code that you write must follow this style.
-
-
Assemble the program
To assemble the program–converting it to machine language– you first need to open the filehmmm.py
in IDLE. It is also found in theps5partII
folder.Run
hmmm.py
in IDLE, which will bring you to the Shell. You can then assembleexample1.txt
by making the following function call from the Shell:>>> assemble('example1.txt')
You should see the following output:
---------------------- | ASSEMBLY SUCCESSFUL | ---------------------- 0 : 0000 0001 0000 0001 00 read r1 # get # from user and 1 : 0000 0010 0000 0001 01 read r2 # ditto, for register 2 : 1000 0011 0001 0010 02 mul r3 r1 r2 # r3 = r1 * r2 3 : 0000 0011 0000 0010 03 write r3 # write out (print) 4 : 0000 0000 0000 0000 04 halt # stop here wrote binary program to example1.b
Note that assembling the program creates a new binary file called
example1.b
that contains the machine-language version of the program. -
Run the program
Once you have assembled the program, you can run it by making the following function call from the Shell:>>> run('example1.b')
The Hmmm simulator will ask if you want to use step-by-step debugging mode. Enter
n
to bypass the debugger and simply run the program. Enter two integers, and you should see that their product is produced. For example:Enter debugging mode? n Enter number: 4 Enter number: 5 20
-
Warning
After each change that you make to your assembly code, make sure to resave the file before you assemble and run it.
Problem 7: Cubic countdown
10 points; individual-only
In this problem you will modify an existing assembly-language program.
Your work for this problem should go in the file ps5pr7.txt
that we have
given you in the ps5partII
folder. Begin by opening the file in any
text editor.
Start by assembling and running the existing program that we have given you.
Enter an integer (e.g., 32000), and you should see the program counting upward from that number. When it gets to 32767, which is the maximum possible value, it will stop. If you want to stop the program early, you can do so by hitting Control-C.
Look over the code, and make sure that you understand how it works!
Important
Note that line 03 of the provided code uses a jumpn
instruction to
perform an unconditional jump to line 01. You must use jumpn
when
performing an unconditional jump in Hmmm. The alias jump
(without the n
) is not the same thing as jumpn
.
Your task is to modify the code in ps5pr7.txt
so that it does the following:
-
Asks the user for an input. You may assume that the input will be positive and less than 30.
-
Computes the cube of that input, and prints the result. You will need multiple multiplications to compute the cube! Before proceeding to the next step, add a temporary
halt
statement, and test the current version of your program to ensure that it works. -
Counts downward from the cube of the input to 0, one integer at a time, and printing each value. For example, if the user’s input is 2, the program should print the following:
8 7 6 5 4 3 2 1 0
Consider starting this step by just adding the statements needed to compute and print one less than the cube of the input, and then halt. Test the program to confirm that it correctly prints that value, and then add the statements needed to create a loop that continues the countdown all the way to 0.
-
When the count is less than 0, the program should stop. Note that the last value printed should be 0, not -1.
Important notes:
-
Make sure to follow the style guidelines that we’ve specified. In particular, you must have a comment on every line except for
nop
andhalt
statements. -
Make sure that your comments do not include any special characters (e.g.,
$
, quotes, or&
). -
You will need to decide how many additional registers you need, and which one(s) you wish to use. You can use any register from
r1
tor15
. Registerr0
is not available for our purposes. -
In all of your work on this problem set, we strongly encourage you to take a one-step-at-a-time approach like the one that we’ve outlined above. Gradually add functionality to your program, and test each new addition before continuing. This should make your program development and debugging much more manageable.
-
Remember that
nop
statements are useful as spacers that provide room for you to grow your program without needing to renumber lines. -
After each change that you make to your assembly code, make sure to resave the file before you assemble and run it.
Problem 8: Computing a power by looping
20 points; pair-optional
This is the second of two problems from this assignment that you may complete with a partner. See the rules for working with a partner on pair-optional problems for details about how this type of collaboration must be structured.
Your work for this problem should go in the file ps5pr8.txt
that we
have given you in the ps5partII
folder. Begin by opening the file in a
text editor.
Your task is to write an assembly-language program that uses a loop to compute a power. Your program should do the following:
- Ask the user to enter two inputs. You may assume that these inputs will be nonnegative integers.
- Use a loop to compute the result of raising the first input to the power of the second input.
- Print the result and exit.
For example:
Enter number: 2 Enter number: 5 32
One good model for this problem is the loop-based factorial program that we reviewed in lecture. We’ve reproduced it below:
00 read r1 # get # from user and store it in r1 01 setn r2 1 # initialize r2, which will store the result 02 jeqzn r1 08 # jump to line 08 if r1 == 0 03 mul r2 r2 r1 # r2 = r2 * r1 04 addn r1 -1 # r1 = r1 - 1 05 jumpn 02 # jump back to line 02 06 nop 07 nop 08 write r2 # write out the result 09 halt
Notes/hints:
-
Don’t forget to follow the style guidelines that we’ve specified. In particular, you must have a comment on every line except for
nop
andhalt
statements. -
Make sure that your comments do not include any special characters (e.g.,
$
, quotes, or&
). -
Here again, you should take one step at a time, and test each new addition or change that you make before continuing.
-
Make sure to test your program carefully, including “edge cases” in which one or both of the inputs are
0
. Note that any number to the power of0
should produce a result of1
, including00
. Here are some additional sample runs:Enter number: 3 Enter number: 4 81 Enter number: 111 Enter number: 1 111 Enter number: 111 Enter number: 0 1 Enter number: 0 Enter number: 0 1
Problem 9: Calling a distance function twice
20 points; individual-only
Your work for this problem should go in the file ps5pr9.txt
that we
have given you in the ps5partII
folder. Begin by opening the file in a
text editor.
The distance between two integers x0
and x1
is the absolute value
of their difference. For example, in Python we could do the following:
distance = abs(x0 - x1)
Your task is to write a Hmmm assembly-language program that implements a separate function for computing the distance between two integers, and that uses that function twice to determine which of two candidate values is closer to a third value.
More specifically, your program should do the following:
-
Read three integers from the user:
- a reference value,
x0
- the first candidate value,
x1
- the second candidate value,
x2
- a reference value,
-
Call a single separate function twice to compute:
-
the distance between the reference value
x0
and the first candidate valuex1
-
the distance between the reference value
x0
and the second candidate valuex2
Note that the distance computations must be made by a separate function, and you must call the same function twice. You will lose points if you call two separate functions, or if you make only one call to a function that performs both distance computations.
-
-
Determine which of the candidate values (
x1
orx2
) is closer to the reference valuex0
, and print the closer of the two candidate values.
In other words, your program must follow the same basic approach taken by the following code, which is a mixture of Python and pseudocode:
def main(): read x0 from user # This isn't real python syntax, but the read x1 from user # idea here is to get the inputs from the user. read x2 from user d1 = distance(x0, x1) d2 = distance(x0, x2) if d1 <= d2: print(x1) else: print(x2) def distance(x, y): """ compute and return the distance between the integers x and y """ return abs(x - y)
Your task is to follow the approach taken by this code, but to do so
in Hmmm assembly language. You should have a section of Hmmm code that
corresponds to main
above, and a section that corresponds to
distance
above. Note that the distance
portion of the program does
not print anything. It simply returns its value to main
, which
determines the candidate value with the smaller distance and prints
that value.
Here are some sample runs of the program:
Enter a number: 3 Enter a number: 1 Enter a number: 7 1 Enter a number: 3 Enter a number: 7 Enter a number: 1 1 Enter a number: 0 Enter a number: -4 Enter a number: 3 3 Enter a number: 3 Enter a number: -1 Enter a number: 7 -1 Enter a number: 3 Enter a number: 7 Enter a number: -1 7
Notes/hints:
-
If
x1
andx2
are equally close tox0
, your program should printx1
, as shown in the corresponding Python program above, and in the fourth and fifth sample runs. -
Continue to follow the style guidelines that we’ve specified. In particular, you must have a comment on every line except for
nop
andhalt
statements. -
Make sure that your comments do not include any special characters (e.g.,
$
, quotes, or&
). -
As always, you should take one step at a time, and test each new addition or change before continuing.
-
Make sure that you use
call
andjumpr
instructions to call and return from the separate function. -
You should decide in advance which registers you will use for the following purposes:
-
the three user inputs to the program
-
the two inputs to the function
-
the return address of the function (we used
r14
for this in lecture) -
the return value of the function (we used
r13
for this in lecture)
-
-
You will also need registers for other purposes. In particular, we encourage you to use registers that correspond to the variables
d1
andd2
in the corresponding Python program given above. -
You should not need to use the stack in this problem.
Submitting Your Work
Note: Apollo does not accept submissions until one week before the deadline, so you won’t be able to submit your work until we are in that window.
You should use Apollo to submit the following files:
- your
ps5pr0.txt
file containing your response to the reading for Problem 0 - your
ps5pr1.logicly
file containing your circuit for Problem 1 - your
ps5pr2.logicly
file containing your circuit for Problem 2; if you worked with a partner, make sure that you each submit a copy of your joint work, and that you include your partner’s name and email in the place provided at the top of the file - your
ps5pr3.logicly
file containing your circuit for Problem 3 - your
ps5pr4.logicly
file containing your circuit for Problem 4 - your
ps5pr5.logicly
file containing your circuit for Problem 5 - optional: your
ps5pr6.logicly
file containing your circuit for Problem 6 - your
ps5pr7.txt
file containing your solution for Problem 7 - your
ps5pr8.txt
file containing your solution for Problem 8; if you worked with a partner, make sure that you each submit a copy of your joint work, and that you include your partner’s name and email in the place provided at the top of the file - your
ps5pr9.txt
file containing your solution for Problem 9
Warnings
-
Make sure to use these exact file names, or Apollo will not accept your files. If Apollo reports that a file does not have the correct name, you should rename the file using the name listed in the assignment or on the Apollo upload page.
-
Before submitting your files, make sure that your BU username is visible at the top of the Apollo page. If you don’t see your username, click the Log out button and login again.
-
If you encounter problems with Apollo, click the Log Out button, close your browser and try again. If possible, you may also want to wait an hour or two before retrying. If you are unable to submit and it is close to the deadline, email your homework before the deadline to
cs111-staff@cs.bu.edu
.
Here are the steps:
- Login to Apollo, using the link in the left-hand navigation bar. You will need to use your Kerberos user name and password.
- Check to see that your BU username is at the top of the Apollo page. If it isn’t, click the Log out button and login again.
- Find the appropriate problem set section on the main page and click Upload files.
- For each file that you want to submit, find the matching upload section for the file. Make sure that you use the right section for each file. You may upload any number of files at a time.
- Click the Upload button at the bottom of the page.
- Review the upload results. If Apollo reports any issues, return to the upload page by clicking the link at the top of the results page, and try the upload again, per Apollo’s advice.
- Once all of your files have been successfully uploaded, return to the upload page by clicking the link at the top of the results page. The upload page will show you when you uploaded each file, and it will give you a way to download the uploaded file. Click on the link for each file so that you can ensure that you submitted the correct file. Note: Because Apollo cannot display Logicly files, you will need to download each uploaded file and view it in Logicly to confirm that you have submitted the correct file.
Warning
Apollo will automatically close submissions for a given file when its final deadline has passed. We will not accept any file after Apollo has disabled its upload form, so please check your submission carefully following the instructions in Step 7 above.