Description
1 Overview
For this assignment, you will implement two short programs in AVR assembly. Both programs will require the use of memory access instructions, conditional branches and arithmetic with carry. You should start early to ensure that you can ask for help if you get stuck.
Although the AVR instruction set has a full slate of addition and subtraction instructions, there are very few multiplication instructions and no instructions for integer division. The objective of this assignment is to implement multiplication and division in AVR assembly to allow 16-bit numbers to be multiplied or divided (with both the quotient and remainder retained). Although there are several variants of the MUL instruction available, you will likely find it easier to write your solution using only addition and subtraction (since the MUL instructions have a peculiar format that does not map well onto this task).
Let A and B be 16-bit unsigned integers. The product AB requires at most 32 bits. The quotient A/B and remainder A%B each require at most 16 bits. For this assignment, your task is to write two AVR assembly programs:
- A program to compute the product AB and store it in memory as a 32-bit little-endian unsigned integer.
- A program to compute the quotient A/B and remainder A%B and store each value in memory as a 16-bit little-endian unsigned integer.
2 Code Templates
Since the only environment available for running AVR assembly (besides the AVR boards that we haven’t used yet) is the simulator, it is not really possible to write a complete program in the traditional sense, because there is no facility for input and output. Instead, two code templates have been posted on conneX: mul32.asm and divmod16.asm. In each template, the 16-bit input operands A and B are pre-loaded into two pairs of registers (R17:R16 for A and R19:R18 for B). Add your implementation of each algorithm to the indicated place in each template. You may change the loaded operand values for testing purposes, but do not move or change any other aspects of the ldi instructions. When your code has computed the result for each task, store the result in data memory (using the variables indicated in each code template). If you do not use the code templates provided to implement your solution, it will not be possible to mark your code and you will receive a mark of zero.
3 Evaluation
Submit your completed mul32.asm and divmod16.asm files electronically through the Assignments tab on conneX. Do not submit any other files.
The assignment will be marked out of 12 marks and is worth 6% of your final grade.
The marks are distributed among the components of the assignment as follows. If either file does not correctly assemble as submitted, you will receive no marks for that part of the assignment (since it will be impossible to test your code). Make sure your code assembles exactly as submitted (even if an error is caused by a minor error like a typo, you will receive a zero if the file does not assemble).
| Marks | Component |
| 1 | The mul32.asm code gives the correct result when both operands are less than 16. Note that to be “correct”, the result must be stored in the required memory locations (OUT3:OUT0) Solutions which store the result anywhere else (or leave it in registers) will not receive any marks. |
| 2 | The mul32.asm code gives the correct result when the product AB is at most 216−1. |
| 1 | The mul32.asm code gives the correct result when one operand is less than 256 (and the other operand is unconstrained). |
| 2 | The mul32.asm code gives the correct result for all valid operand pairs. |
| 2 | The divmod16.asm code gives the correct quotient value (in memory locations DIV1:DIV0) when the denominator (B) is less than 256. |
| 2 | The divmod16.asm code gives the correct remainder value (in memory locations MOD1:MOD0) when the denominator (B) is less than 256. |
| 2 | The divmod16.asm code gives the correct quotient and remainder values for all valid operand pairs. |




