(This lab was inspired by a laboratory exercise presented in ECE3724: Microprocessors developed by Jones, Reese and Bruce and offered at Mississippi State University.)
In this lab, you will convert a C program into PIC24 assembly language. The C program generates the syracuse sequence, a subject of interest in number theory. The sequence is generated by a very simple algorithm. Take any number as an input, and divide it by 2 if that number is even, or multiply by 3 and add 1 if that number is odd. The conjecture is that, no matter what number you start with as an input, if you apply the algorithm repetitively to each number generated, the output will be a sequence of numbers terminating in1. However, this is still an open question, and no one has proven this conjecture.
The new programming tasks required in this lab are:
Convert flow control structures such as while
loops and if-else
statements into assembly language instructions.
Convert simple arithmetic expressions into 16-bit assembly language instructions.
There are 2 main steps required to implement a flow control statement in assembly language:
Here's an example:
while (i < 10) { ... }
A partial translation of this loop structure into assembly language is:
MOV #10, W0 |
; setup to evaluate the test expression |
CP i |
; set status register bits by comparing i to 10 ; specifically calculate (i-10) |
BRA GEU, end_loop |
; branch if (i-10) is greater than or equal to 0 ; this means the loop test is not true |
Note that (1) a compare instruction (CP) can be used to set the status register bits, and (2) there are many forms of the branch instruction (BRA), one for each possible comparison outcome. See the PIC 24 instruction set for variations of the CP and BRA instructions.
Refer to your class lecture notes for more assembly language programming examples.
As in Lab 7, begin by opening the mptst_word.mcp project which can be found in the chap 3 directory of the PIC24 code archive downloaded in Lab 7.
Use Project -> Save Project As and save the mptst_word project as a new project named syracuse. Save the mptst_word.s file as syracuse.s. Right-click on the mptst_word.s file in the left-hand workspace window and use the Remove option to remove it from the syracuse project. Right click on the Source Files and use Add Files to add the syracuse.s file to the project. Edit the syracuse.s file and remove all of the instructions between the comment, ";User Code starts here" and the "done:" statement label. You can now use this file as the start of a new program.
The program syracuse.c contains several statements such as a prompt for user input, a call to main(), and a return statement, that we will not translate to assembly code. The relevant portion of the program is follows:
int count, num ; num = 6; ; // added to replace user input count = 0 ; while (num != 1) {
printf("%8d\n", num) ; // don't translate to assembly if (num%2==0) { num = num/2 ; } else { num = 3*num + 1 ; } ++count ; } printf("%8d\n\n", num) ; // don't translate to assembly
printf("iterations: %d\n", count) ; // don't translate to assembly
Your job is to translate the code above (minus the printf statements) into an assembly language program that calculates the same values for num
and count
. The output of the program above is:
syracuse 6 3 10 5 16 8 4 2 1 iterations: 8
You should verify that your assembly language program calculates these values by watching memory. Use the watch window to monitor the values of the variables num
and count,
and any registers you use, such as WREG and SR (the status register). Also, use the data memory window to monitor the memory locations of the variables. Write your program, simulate it, and verify that you are producing the correct results at each iteration of the while
loop.
Begin the simulation and show your instructor two iterations of your while loop as well as the source code. |
Recommended Approach
You should not try to ‘optimize’ away any statements – you should implement the C code exactly as shown. You must place a comment on a line by itself giving the line of C code followed by the assembly instructions which implement this C code. In addition, you should place comments to the right of assembly instructions which clarify their purpose. The required comments are demonstrated below.
; i = avalue; mov #avalue, W0 ; W0 = 100 mov WREG,i ; i = 100 ; i = i + 1; inc i ; i = i + 1 ; j = i mov i,WREG ; W0 = i mov WREG,j ; j = W0
Implement your assembly language solution one step at a time: