I've written an arm assembly code on Xilinx SDK
to program ZedBoard
to act like a calculator.
Overall the assembly follows this loop:
-
User input the first number from switches
-
User pushes one of the pushbuttons to either add, multiply, subtract, or divide depending on the GPIO bit that is on
-
User inputs the second number from the switches
-
ZedBoard calculates this and outputs the result to LEDs
-
Repeat 1
Now, my code works when I go through the step by step debugging mode. But automatically, the ZedBoard's LEDs are all turned on and I'm assuming its overflowing because I have an overflow subroutine that tells me if theres an overflow then turn all on LEDs.
My question is what is wrong with my code and why is it overflowing the moment I program my assembly code to the ZedBoard?
.section .data
.section .text
;@Define the base addresses of the GPIO ports we might want to use.
.align ;@align the variable to 4 bytes word boundary
GpioBTN: .word 0x41200000
GpioLED: .word 0x41210000
GpioSW: .word 0x41220000
.global asm_main ;@ make asm_main visible to the linker program
.func asm_main ;@ generate debugging information for asm_main
asm_main:
;@ An empty main project doing nothing
;@ Follow the tutorial instruction and complete the main program to read from switches and update LEDs
ldr r0, =GpioBTN ;@r0 has buttons
ldr r0, [r0]
ldr r1, =GpioLED ;@r1 has LED
ldr r1, [r1]
ldr r3, =GpioSW
ldr r3, [r3] ;@r4 has switches
ldr r2, [r1, #4] ;@make led as output
bic r2, #0xFF;
str r2, [r1, #4]
;@ldr r3, [r4, #4] ;@make led as output
;@bic r3, #0xFF;
;@str r3, [r4, #4]
;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@
;@ idea: first number + second number = sum1 + third number = sum2 + 4th number and so on..
;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@
poll:
mov r10, #0 ;@counter
mov r8, #0 ;@ counter 2
mov r9, #0 ;@ used for nothing
mov r7, #0 ;@ used for nothing
mov r6, #0 ;@ sum
mov r5, #0 ;@ second number
mov r4, #0 ;@ first number
str r6, [r1]
;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ First number
get_first_number: ;@
;@ read first number = r4
ldr r4, [r3]
cmp r4, #0
beq get_first_number ;@ keep finding a number other than zero -> current result = 0
;@ first number is not zero
;@ get operator
operators1:
cmp r6, #255
bge overflow
cmp r6, #0
blt overflow
ldr r2, [r0] ;@ read pushbuttons
cmp r2, #1 ;@clear
beq poll
cmp r2, #8 ;@ right button is pressed therefore addition
beq store_add
cmp r2, #16 ;@ up button is pressed therefore multiplication
beq store_mul
cmp r2, #2 ;@ down button is pressed therefore division
beq store_div
cmp r2, #4 ;@ left button is pressed therefore subtraction
beq store_sub
b operators1 ;@ this is a loop that waits for the user to detemrine which operator to use with the first number
;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ Second number
;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@
store_add:
;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@
cmp r6, #0
beq find_second_number
find_third_number:
add r10, #1
beq find_second_number ;@ this is to jump to find more number because r6 is more than 0
ldr r4, [r3]
cmp r4, r5
bne third_number ;@ if first number and second number is not the same then that means
;@ were good to add them right now (e.g. 1 + 0 = 1)
add r6, r6, r4 ;@ switch have not changed so add third number
str r6, [r1]
b operators1
third_number:
add r6, r6, r4 ;@ switch have changed so add third number
str r6, [r1]
b operators1
find_second_number:
ldr r5, [r3] ;@ read second number = r5
cmp r5, r4
bne second_number ;@ if first number and second number is not the same then that means
;@ were good to add them right now (e.g. 1 + 0 = 1)
b first_or_more_same
first_or_more_same:
cmp r6, #0
beq first_same
b more_same
first_same:
add r6, r4, r4
str r6, [r1]
b operators1
more_same:
cmp r5, r4
bne more_number
add r6, r6, r5 ;@ switch have not changed so add x number
str r6, [r1]
mov r10, #2
b operators1
more_number:
add r6, r5, r6 ;@ add it by themselves
str r6, [r1]
b operators1
second_number:
add r6, r4, r5
str r6, [r1]
;@ find the third number
b operators1
;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@
store_mul:
;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@
cmp r6, #0
beq find_second_number_mul
find_third_number_mul:
add r10, #1
beq find_second_number_mul ;@ this is to jump to find more number because r6 is more than 0
ldr r4, [r3]
cmp r4, r5
bne third_number_mul ;@ if first number and second number is not the same then that means
;@ were good to add them right now (e.g. 1 + 0 = 1)
mul r6, r4, r6 ;@ switch have not changed so add third number
str r6, [r1]
b operators1
third_number_mul:
mul r6, r4, r6 ;@ switch have changed so add third number
str r6, [r1]
b operators1
find_second_number_mul:
ldr r5, [r3] ;@ read second number = r5
cmp r5, r4
bne second_number_mul ;@ if first number and second number is not the same then that means
;@ were good to add them right now (e.g. 1 + 0 = 1)
b first_or_more_same_mul
first_or_more_same_mul:
cmp r6, #0
beq first_same_mul
b more_same_mul
first_same_mul:
mul r6, r4, r4
str r6, [r1]
b operators1
more_same_mul:
cmp r5, r4
bne more_number_mul
mul r6, r5, r6 ;@ switch have not changed so add x number
str r6, [r1]
mov r10, #2
b operators1
more_number_mul:
mul r6, r5, r6 ;@ add it by themselves
str r6, [r1]
b operators1
second_number_mul:
mul r6, r4, r5
str r6, [r1]
;@ find the third number
b operators1
;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@
store_div:
;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@
cmp r6, #0
beq find_second_number_div
find_third_number_div:
add r10, #1
beq find_second_number_div ;@ this is to jump to find more number because r6 is more than 0
ldr r4, [r3]
cmp r4, r5
bne third_number_div ;@ if first number and second number is not the same then that means
;@ were good to add them right now (e.g. 1 + 0 = 1)
subtract1:
subs r6, r6, r4 ;@ switch have not changed so add third number
add r8, r8, #1
bhi subtract1
add r6, r8, r6
str r6, [r1]
b operators1
third_number_div:
subtract2:
subs r6, r6, r4 ;@ switch have not changed so add third number
add r8, r8, #1
bhi subtract2
add r6, r8, r6
str r6, [r1] ;@ switch have changed so add third number
b operators1
find_second_number_div:
ldr r5, [r3] ;@ read second number = r5
cmp r5, r4
bne second_number_div ;@ if first number and second number is not the same then that means
;@ were good to add them right now (e.g. 1 + 0 = 1)
b first_or_more_same_div
first_or_more_same_div:
cmp r6, #0
beq first_same_div
b more_same_div
first_same_div:
subtract3:
subs r6, r4, r4 ;@ switch have not changed so add third number
add r8, r8, #1
bhi subtract3
add r6, r8, r6
str r6, [r1] ;@ switch have changed so add third number
b operators1
more_same_div:
cmp r5, r4
bne more_number_div
subtract4:
subs r6, r6, r5 ;@ switch have not changed so add third number
add r8, r8, #1
bhi subtract4
add r6, r8, r6
str r6, [r1] ;@ switch have changed so add third number
mov r10, #2
b operators1
more_number_div:
subtract5:
subs r6, r5, r6 ;@ switch have not changed so add third number
add r8, r8, #1
bhi subtract5
add r6, r8, r6
str r6, [r1] ;@ switch have changed so add third number
b operators1
second_number_div:
subtract6:
subs r6, r4, r5 ;@ switch have not changed so add third number
add r8, r8, #1
bhi subtract6
add r6, r8, r6
str r6, [r1] ;@ switch have changed so add third number
b operators1
str r6, [r1]
;@ find the third number
b operators1
;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@
store_sub:
;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@ ;@
cmp r6, #0
beq find_second_number_sub
find_third_number_sub:
add r10, #1
beq find_second_number_sub ;@ this is to jump to find more number because r6 is more than 0
ldr r4, [r3]
cmp r4, r5
bne third_number_sub ;@ if first number and second number is not the same then that means
;@ were good to add them right now (e.g. 1 + 0 = 1)
sub r6, r6, r4 ;@ switch have not changed so add third number
str r6, [r1]
b operators1
third_number_sub:
sub r6, r6, r4 ;@ switch have changed so add third number
str r6, [r1]
b operators1
find_second_number_sub:
ldr r5, [r3] ;@ read second number = r5
cmp r5, r4
bne second_number_sub ;@ if first number and second number is not the same then that means
;@ were good to add them right now (e.g. 1 + 0 = 1)
b first_or_more_same
first_or_more_same_sub:
cmp r6, #0
beq first_same_sub
b more_same_sub
first_same_sub:
sub r6, r4, r4
str r6, [r1]
b operators1
more_same_sub:
cmp r5, r4
bne more_number_sub
sub r6, r6, r5 ;@ switch have not changed so add x number
str r6, [r1]
mov r10, #2
b operators1
more_number_sub:
sub r6, r5, r6 ;@ add it by themselves
str r6, [r1]
b operators1
second_number_sub:
sub r6, r4, r5
str r6, [r1]
;@ find the third number
b operators1
overflow:
mov r10, #255
str r10, [r1]
ldr r2, [r0] ;@read if center is push which clears the calculator to zero
cmp r2, #1
beq poll
b overflow
bx lr
.endfunc