The purpose of this assignment is to help you learn about computer
architecture, assembly language programming, and testing
strategies. It also will give you the opportunity to learn more about
the GNU/Unix programming tools,
especially bash
, emacs
(or any other
editor), gcc209
, and gdb
for assembly
language programs.
dc
(desk
calculator) program in assembly language. We provide you the skeleton
code for dc
written in assembly language, a startup file
(details are in the below). You will start from reviewing this code
and modifying and adding the code with respect to the requirement
specified below. Good luck!
dc
(desk calculator) is a tool on
Unix-like operating systems. In its simplest form, dc
reads a list of numbers from the standard input (stdin) and uses a set
of command keys to display the results of the user-specified
operations on the standard output (stdout).
In dc
, the operands (numbers) and operators are added
in dc
is
used.
567 343223 + p 343790 q
dc
uses a stack to store numbers in LIFO order
(last-in, first-out). Whenever it encounters an arithmetic operator,
it first pops out the last 2 operands from the stack, runs the
operation on those numbers and then pushes the result back into the
stack. In the example above, 567
and 343223
are pushed in the stack one after the other. Once the
operator '+'
is entered, dc
first
pops 343223
and then
567
from the stack. It then adds the two integers and finally
pushes the result (343790
) back in the stack. The command
p
is used to print the value that sits on the top of the
stack. Please note that p
only retrieves the value without
popping (this is also known as a peek operation). The user can
either quit the program by entering q
or EOF
character to the program. In other words, if the annotated text mentioned
above is stored in a file named values.txt then dc
can also be
executed in the following manner:
$ dc < values.txt
which will print the result to the standard output stream as:
343790The
dc
tool supports a number of operators and subsidiary
commands which you can study on the man
page. For this assignment, you are required to implement only the
following operations.
p
+, -, *, /, |
'|'
performs abssum(a, b)
, which performs the summation of the absolute values from min(a, b)
to max(a, b)
. min(a, b)/max(a,b)
refers to the minimum/maximum of the two values, a
and b
. Note '|'
in original dc
performs modular exponentiation, which is different from ours. The pseudocode in C for abssum()
is as follows.
int abssum(int a, int b) { int i, s = 0; for (i = min(a, b); i <= max(a,b); i++) s += |i|; // |i| means the absolute value of i return s; }
'/'
) computes the quotient (in integer) in integer division. For example, 3/2 = 1
.
q
To make the assignment tractable in assembly programming, we make some simplifying assumptions:
You might want to use esp
and ebp
registers to implment your stack for computation in your code.
We are providing a startup file which
contains the pseudo-code of dc.s file. Please go through the
pseudo-code before you begin writing the program. It is acceptable to
use global (i.e. bss section or data section) variables
in mydc.s
. Please make sure that you write abssum()
as a separate function in your assembly language code. In the dc
input, negative numbers can be added by pre-appending '_'
symbol to the number. This allows us to identify '-'
(subtraction) operation by checking only the the first character in the input line. For example
_4 3 - p -7 qcalculates "-4 - 3", prints the top value (
p
), and quit the program (q
).
dc
tool also provides additional operations that
manipulate the input. You are required to implement the following
operators for this assignment.
Advanced Operations | Short description |
f
|
Prints the contents of the stack in LIFO order. This is a useful command to use if the user wants to keep track of the numbers he/she has pushed in the stack. |
c
|
Clears the contents of the stack. |
d
|
Duplicates the top-most entry of the stack and pushes it in the stack. |
r
|
Reverses the order of (swaps) the top two values on the stack. |
Please note that 'f'
does not pop out any
numbers out of the stack. The following example run of dc shows how a
combination of different dc
operators can be used:
53 48 35 + + 343223 43 56 76 35 98 1 f 1 98 35 76 56 43 343223 136 q
dc
keeps on pushing the integers on the stack (53,
48, 35
) till it encounters the first '+'
operator.
It pops out 35
and 48
, computes the addition and
inserts 83
back in the top of the stack. When the second
'+'
is inserted, it repeats the same process with the integers
83
and 53
and inserts back 136
in
the empty stack. Later when 'f'
is entered, dc
prints out all the contents of the stack in LIFO order.
The following self-explanatory example shows how one can use 'd'
in dc
4 d * p 16 q
Finally, 'r'
is used to reverse the order of (swaps) the
top two values on the stack as is shown in the example below:
4 8 f 8 4 r f 4 8 q
dc
has to
divide by 0). Your program should ignore those input values that have mixed
alphanumeric characters. You should check whether the stack has at
least two operands for +, -, *, /, |
operations. In
case there are not enough operands, dc
should print out
'dc: stack empty
' to standard output. For p, d,
r
operators, dc
should again print 'dc:
stack empty
' if the stack does not contain at least one
operand (two for r
). For all other operators, dc
should do nothing if
the stack is empty.
Elaboration(5/17/2021): For correct input, we expect the correct behavior from your program. However, for wrong input, it's just OK that your program does not crash. For example, if the input line has "pabcd" (wrong input), you can choose to interpret it as 'p' command or ignore it as wrong command (with an (optional) error message). If the input line is "123abc", you can choose to insert 123 into the stack or ignore the entire line as invalid input line. Either way is fine.
Develop on lab machines. Use your favorite editor to create source code. Use gdb
to debug.
Do not use a C compiler to produce any of your assembly language code. Doing so would be considered an instance of academic dishonesty. Instead, you should write your assembly language code manually.
We encourage you to develop "flattened" pseudo-code (as described in EE209 and EE485) to bridge the gap between the given pseudo-code and your assembly language code. Using flattened pseudo-code as a bridge can eliminate logic errors from your assembly language code, leaving only the possibility of translation errors.
We also encourage you to use your flattened pseudo-code as comments in your assembly language code. Such comments can clarify your assembly language code substantially.
Your readme
file should contain:
Use KAIST KLMS to submit your assignments. Your submission should be one gzipped tar file whose name is
YourStudentID_assign4.tar.gz
Your submission need to include the following files:
mydc.s
file.readme
file.mydc
program with.As always, we will grade your work on quality from the user's and programmer's points of view. To encourage good coding practices, we will deduct points if gcc209
generates warning messages.
Comments in your assembly language programs are especially important. Each assembly language function -- especially the main
function -- should have a comment that describes what the function does. Local comments within your assembly language functions are equally important. Comments copied from corresponding "flattened" C code are particularly helpful.
Your assembly language code should use .equ
directives to avoid "magic numbers." In particular, you should use .equ
directives to give meaningful names to:
.equ TRUE, 1
..equ OADDEND1, 8
..equ UICARRY, -4
..equ EBXOFFSET, -4
.