I understand the math to the following problem, however I\'m not sure how to cod
ID: 3678598 • Letter: I
Question
I understand the math to the following problem, however I'm not sure how to code this in msp430 assembly language. I have the structure given to me and I'll repost it down below. The summation of X should be equal to 310 (136h in hex) which in turn makes F equal to 90(5Ah in hex). Some help would be amazing!
Implement the following arithmetic function using subroutines and develop the code to be as efficient as possible. The only input to the function is variable (a) that is initialized in register R4 at the beginning of the program to 5 and maintained thereafter. The X calculation result (X) is stored in R5. The final answer (F) is stored in R7. Register R0-R3 are never to be used since they have designated purpose in the MSP430 Launchpad.
F = ((X+50)/4) where X= the summation of (2(i!)) i=0 to i=|a|
Write an MSP430 assembly language program that implements the above function using subroutines for Multiplication and Factorial. Multiply subroutine should take into account sign values. The overall program structure should be as follows:
RESET mov.w #__STACK_END,SP ; Initialize stack pointer
StopWDT mov.w #WDTPW+WDTHOLD,&WDTCTL ; Stop WDT
LAB2 mov.w #5,R4 ; Load "a" into R4
CLEAR clr R5 ; clear the entire register
clr R6 ; clear the entire register
clr R7 ; clear the entire register
XCALC ... ... ; the X calculation part of your program
... ... ; taking value of R4 as an input
... ... ; and returning result (X) in R5
FCALC ... ... ; the final part of your program
... ... ; taking inputs from R5 and R6
... ... ; and returning result (F) in R7
MainLoop jmp Mainloop ; Infinite Loop
;Subroutines have to be implemented after MainLoop
;Multiply Subroutine must be develop taking into ;account negative values
;**Negative Value can be given as input and program should still
; execute correctly.
** **Subroutines must take into account all possible cases**
Explanation / Answer
.bss i,2 // Declare i as an integer which takes 2 spaces
mov.w #0,&i // Initialize i =0
XCALC: PUSH R4
cmp.w #0,R4
jne Myelse:
mov.w #(-1) , R5
push R5
push R4
call #Multiply
pop R4
Myelse :
cmp.w R4,&i
jge for_done
PUSH R7
call #srFact
POP R7
PUSH R7
call #Multiplyby2
POP R7
add.w R5,R7
add.w #1,&i
jmp XCALC
for done:
Multiplyby2:
mov.w #2,R4
push R4
push R5
call #Multiply
pop R5
jump XCALC
divide : mov.w #0 , &i
push R5
push R6
push R7
sub.w R5,R6
move.w R7,R5 // move contents of R5 to R7
add.w #1,&i
jmp divide
FCALC: push R5 //contains X
add.w #50,R5
mov.w #4,R6
PUSH R5
PUSH R6
PUSH R7
call #divide
jmp main
srFact: push R4 ; Where A will be stored push R5 ; Where result will be stored mov.w 8(SP), R4 ; mov.w R4, R5 ; srFactCond: nop ; MAKE SURE THAT R4 >1 cmp #1, R4 ; jnz srFactLoop ; Execute recursive mult. if R4>1 mov.w R5, 6(SP) ; Once done, move result to bottom of stack pop R5 ; Restore R4 pop R4 ; Restore R5 ret srFactLoop: dec R4 ; becomes R4-1 push R4 ; first operand is A-1 push R5 ; next operand is A push R5 ; store the Result in here call #Multiply ; Multiply R4(R4-1) pop R5 ; jmp srFactCond ; return to condition check ; Multiplication Subroutine Multiply: push R2 push R5 push R6 push R7 clr R7 ; looped sum mov.w 12(SP), R6 ; copy B[i] from the stack mov.w 14(SP), R5 ; copy A[i] from the stack cmp R5, R6 ; compare B[i]-A[i] jge SmallA ; Go to the loop which executes fewer times jmp SmallB SmallA: add R6, R7 ; Add R6 to result, R7, R5 number of times dec R5 jnz SmallA mov.w R7, 10(SP) ; move the result to word before Return Address pop R7 ; restore Registers used in this subroutine pop R6 pop R5 pop R2 mov.w 0(SP), 4(SP) ; move return address to overwrite operand 2 passed in mov.w 2(SP), 6(SP) ; move result to overwrite operand 1 passed in add #4, SP ; move the SP address up by to words ret ; return from subroutine SmallB: add R5, R7 ; Add R6 to result, R7, R5 number of times dec R6 ; Does the same logic otherwise jnz SmallB mov.w R7, 10(SP) pop R7 pop R6 pop R5 pop R2 mov.w 0(SP), 4(SP) mov.w 2(SP), 6(SP) mov.w 4(SP), SP add #4, SP ret
divide : mov.w #0 , &i
push R5
push R6
push R7
sub.w R5,R6
move.w R7,R5 // move contents of R5 to R7
add.w #1,&i
jmp divide
FCALC: push R5 //contains X
add.w #50,R5
mov.w #4,R6
PUSH R5
PUSH R6
PUSH R7
call #divide
jmp main