.ORIG x3000
BRnzp TEST_BEGIN
;
; STEP 1: PRINT_DIGIT
; *******************
; Print a single-digit integer N, where N is between 0 and 9
;
; arguments: in R0 is N
;
PRINT_DIGIT
; ************************* Start your code here *************************
RET
; ************************** End your code here **************************
;
; STEP 2: PRINT_INT
; *****************
; Print an two-digit integer N followed by a new line character (x000A).
; N is between 0 and 99. For N < 10, the leading 0 should be printed.
;
; This subroutine must call PRINT_DIGIT to print a single digit.
;
; arguments: in R0 is N
;
PRINT_INT
; ************************* Start your code here *************************
RET
; ************************** End your code here **************************
;
; STEP 3: MUL
; ***********
; Subroutine that multiplies two positive integers A * B.
;
; arguments: in R0 is A and in R1 is B
; return value: in R2 will be A * B
;
MUL
; ************************* Start your code here *************************
RET
; ************************** End your code here **************************
;
; STEP 4: CUBED
; *************
; Subroutine that calculates N ^ 3.
; It MUST call subroutine MUL to do multiplications.
;
; argument: in R0 is N, a positive integer
; return value: in R0 will be N ^ 3
;
CUBED
; ************************* Start your code here *************************
RET
; ************************** End your code here **************************
; ************************************************************************
; *************** DO NOT MODIFY ANYTHING BELOW THIS LINE *****************
; ************************************************************************
;
; MAIN SECTION
; ************
; DO NOT REMOVE OR MODIFY ANYTHING IN THE MAIN SECTION BELOW
;
TEST_BEGIN
;
; ************************* TEST FOR PRINT_DIGIT *************************
;
; initialize the registers for checking callee saving
LD R1, INIT_REG_VAL
LD R2, INIT_REG_VAL
LD R3, INIT_REG_VAL
LD R4, INIT_REG_VAL
LD R5, INIT_REG_VAL
LD R6, INIT_REG_VAL
; print the message
LEA R0, PRINT_DIGIT_MSG
PUTS
; test the PRINT_DIGIT subroutine to print digits from 9 down to 0
AND R0, R0, #0 ; R0 stores the digit to print
ADD R0, R0, #9 ; initialize the current digit to 9
PRINT_DIGIT_LOOP_BEGIN
BRn PRINT_DIGIT_LOOP_END ; exit the loop if the digit is below 0
JSR PRINT_DIGIT ; print the current digit
ADD R0, R0, #-1 ; decrement the digit
BRnzp PRINT_DIGIT_LOOP_BEGIN
PRINT_DIGIT_LOOP_END
; check if the original values in the registers are preserved
LD R0, INIT_REG_VAL_NEG
ADD R1, R1, R0
BRnp PRINT_DIGIT_REG_SAVING_FAILED
ADD R2, R2, R0
BRnp PRINT_DIGIT_REG_SAVING_FAILED
ADD R3, R3, R0
BRnp PRINT_DIGIT_REG_SAVING_FAILED
ADD R4, R4, R0
BRnp PRINT_DIGIT_REG_SAVING_FAILED
ADD R5, R5, R0
BRnp PRINT_DIGIT_REG_SAVING_FAILED
ADD R6, R6, R0
BRnp PRINT_DIGIT_REG_SAVING_FAILED
BRnzp TEST_PRINT_DIGIT_END
PRINT_DIGIT_REG_SAVING_FAILED
LEA R0, REG_SAVING_MSG
PUTS
TEST_PRINT_DIGIT_END
;
; ************************** TEST FOR PRINT_INT **************************
;
; initialize the registers for checking callee saving
LD R1, INIT_REG_VAL
LD R2, INIT_REG_VAL
LD R3, INIT_REG_VAL
LD R4, INIT_REG_VAL
LD R5, INIT_REG_VAL
LD R6, INIT_REG_VAL
; print the message
LEA R0, PRINT_INT_MSG
PUTS
; test the PRINT_INT subroutine to print integers from 15 down to 00
AND R0, R0, #0 ; R0 is the current integer to pint
ADD R0, R0, #15 ; initialize the current integer to 15
PRINT_INT_LOOP_BEGIN
BRn PRINT_INT_LOOP_END ; exit the loop if the integer is below 0
JSR PRINT_INT ; print the current integer
ADD R0, R0, #-1 ; decrement the integer
BRnzp PRINT_INT_LOOP_BEGIN
PRINT_INT_LOOP_END
; check if the original values in the registers are preserved
LD R0, INIT_REG_VAL_NEG
ADD R1, R1, R0
BRnp PRINT_INT_REG_SAVING_FAILED
ADD R2, R2, R0
BRnp PRINT_INT_REG_SAVING_FAILED
ADD R3, R3, R0
BRnp PRINT_INT_REG_SAVING_FAILED
ADD R4, R4, R0
BRnp PRINT_INT_REG_SAVING_FAILED
ADD R5, R5, R0
BRnp PRINT_INT_REG_SAVING_FAILED
ADD R6, R6, R0
BRnp PRINT_INT_REG_SAVING_FAILED
BRnzp TEST_PRINT_INT_END
PRINT_INT_REG_SAVING_FAILED
LEA R0, REG_SAVING_MSG
PUTS
TEST_PRINT_INT_END
;
; ***************************** TEST FOR MUL *****************************
;
; initialize the registers for checking callee saving
LD R3, INIT_REG_VAL
LD R4, INIT_REG_VAL
LD R5, INIT_REG_VAL
LD R6, INIT_REG_VAL
; print the message
LEA R0, MUL_MSG
PUTS
; test the MUL subroutine to multiply two numbers
AND R0, R0, #0
ADD R0, R0, #13 ; initialize the first operand to 13
AND R1, R1, #0
ADD R1, R1, #6 ; initialize the second operand to 6
JSR MUL ; multiply and store the result in R2
AND R0, R2, R2 ; move the result of MUL from R2 to R0
JSR PRINT_INT ; print the value in R0
; check if the original values in the registers are preserved
LD R0, INIT_REG_VAL_NEG
ADD R3, R3, R0
BRnp MUL_REG_SAVING_FAILED
ADD R4, R4, R0
BRnp MUL_REG_SAVING_FAILED
ADD R5, R5, R0
BRnp MUL_REG_SAVING_FAILED
ADD R6, R6, R0
BRnp MUL_REG_SAVING_FAILED
BRnzp TEST_MUL_END
MUL_REG_SAVING_FAILED
LEA R0, REG_SAVING_MSG
PUTS
TEST_MUL_END
;
; **************************** TEST FOR CUBED ****************************
;
; initialize the registers for checking callee saving
LD R1, INIT_REG_VAL
LD R2, INIT_REG_VAL
LD R3, INIT_REG_VAL
LD R4, INIT_REG_VAL
LD R5, INIT_REG_VAL
LD R6, INIT_REG_VAL
; print the message
LEA R0, CUBED_MSG
PUTS
; call the CUBED subroutine to cube a number
AND R0, R0, #0
ADD R0, R0, #3 ; initialize the operand to 3
JSR CUBED ; call cube and store the result in R0
JSR PRINT_INT ; print the value in R0
; check if the original values in the registers are preserved
LD R0, INIT_REG_VAL_NEG
ADD R1, R1, R0
BRnp CUBED_REG_SAVING_FAILED
ADD R2, R2, R0
BRnp CUBED_REG_SAVING_FAILED
ADD R3, R3, R0
BRnp CUBED_REG_SAVING_FAILED
ADD R4, R4, R0
BRnp CUBED_REG_SAVING_FAILED
ADD R5, R5, R0
BRnp CUBED_REG_SAVING_FAILED
ADD R6, R6, R0
BRnp CUBED_REG_SAVING_FAILED
BRnzp TEST_CUBED_END
CUBED_REG_SAVING_FAILED
LEA R0, REG_SAVING_MSG
PUTS
TEST_CUBED_END
TEST_END
HALT ; stop the program execution
;
; DATA SECTION
; ************
; DO NOT REMOVE OR MODIFY ANYTHING IN THE DATA SECTION
;
; You should NOT directly use INIT_REG_VAL, INIT_REG_VAL_NEG, or their
; values in your code.
;
; You'll lose ALL points for callee saving if you do so
;
INIT_REG_VAL .FILL x600D ; DO NOT USE THIS LABEL/VALUE
INIT_REG_VAL_NEG .FILL #-24589 ; DO NOT USE THIS LABEL/VALUE
PRINT_DIGIT_MSG .STRINGZ "Digits 9 to 0 printed in a single line:\n"
PRINT_INT_MSG .STRINGZ "\nIntegers 15 to 00 printed in each line:\n"
MUL_MSG .STRINGZ "\n13 * 6 = "
CUBED_MSG .STRINGZ "\n3 ^ 3 = "
REG_SAVING_MSG .STRINGZ "\nCheck for callee saving failed\n"
.END