Needing help debugging an assembly programs infinite loop












0















I'll try to make this short. I am running into an infinite loop issue with my program and even after trying to use the debugger I am having issues with an infinite loop.



The program I am trying to make is an assignment from my instructor, to sort through a table of IP addresses that use .word. I have the program done about 95% the last issue I am having is when I type in 193.0.0.0, I run into this infinite loop, the structure for the loop is the same as the other two, which have no problems. In this program, for a class C domain IP address to match the first 3 numbers of the IP Address need to match user input other wise continue onto the rest of the table.
The specific issue that is happening is when it finds a match for the first number and continues to try and match the second number, and then for the third number. If the second number or third number doesn't match it jumps back to the loop, but then gets trapped there, which shouldn't be happening. At least, from what I can tell it shouldn't be.



The matching works beautifully, it is if it doesn't match that there is a problem, but again I am not sure why I am hoping that a fresh set of eyes will be able to help me see the issue.
Also, sorry for any sloppiness in the code, and for it being kind of lengthy, it is rather simple though. I appreciate the help.



.data

MESSAGE1: .asciiz "Enter an IP addressn"
MESSAGE2: .asciiz "First: "
MESSAGE3: .asciiz "Second: "
MESSAGE4: .asciiz "Third: "
MESSAGE5: .asciiz "Fourth: "
MESSAGE6: .asciiz "The IP address you entered: "
MESSAGE7: .asciiz "."
MESSAGE8: .asciiz "nClass A addressn"
MESSAGE9: .asciiz "nClass B addressn"
MESSAGE10: .asciiz "nClass C addressn"
MESSAGE11: .asciiz "nClass D addressn"
MESSAGE12: .asciiz "nInvalid domain classn"
MESSAGE13: .asciiz "nProgram successfully completed . . .n"
MESSAGE14: .asciiz "n"
MESSAGE15: .asciiz "Matching domain found at line: "
MESSAGE16: .asciiz "Matching domain was NOT found . . . n"
ERROROVER: .asciiz "The entered number is larger than 255.n"
ERRORUNDER: .asciiz "The entered number is smaller than 0.n"





IP_ROUTING_TABLE_SIZE:
.word 10

IP_ROUTING_TABLE:
# line #, x.x.x.x -------------------------------------
.word 0, 146, 92, 255, 255 # 146.92.255.255
.word 1, 147, 163, 255, 255 # 147.163.255.255
.word 2, 201, 88, 88, 90 # 201.88.88.90
.word 3, 182, 151, 44, 56 # 182.151.44.56
.word 4, 24, 125, 100, 100 # 24.125.100.100
.word 5, 146, 163, 140, 80 # 146.163.170.80
.word 6, 146, 163, 147, 80 # 146.163.147.80
.word 10, 201, 88, 102, 80 # 201.88.102.1
.word 11, 148, 163, 170, 80 # 146.163.170.80
.word 12, 193, 77, 77, 10 # 193.77.77.10

.text
.globl main

main:
la $a1, IP_ROUTING_TABLE_SIZE
lw $t9, ($a1)



li $t7, 255 #top limit

li $v0, 4
la $a0, MESSAGE1 #asking for the address
syscall
FIRST:
li $v0, 4
la $a0, MESSAGE2 #first number
syscall

li $v0, 5
syscall

move $t0, $v0 #saving input for later use.

bgt $t0, $t7, thi1 # if greater than 255
blt $t0,$zero, tlo1 # if less than

SECOND:
li $v0, 4
la $a0, MESSAGE3 # second number
syscall

li $v0, 5
syscall

move $t1, $v0 #saving input

bgt $t1, $t7, thi2 #if greater than
blt $t1,$zero, tlo2 #if less than
THIRD:
li $v0, 4
la $a0, MESSAGE4 #third number
syscall

li $v0, 5
syscall

move $t2, $v0 #saving input

bgt $t2, $t7, thi3 #if greater than
blt $t2,$zero, tlo3 #if less than

FOURTH:
li $v0, 4
la $a0, MESSAGE5 #fourth number
syscall

li $v0, 5
syscall

move $t3, $v0 #saving input

bgt $t3, $t7, thi4 #if greater than
blt $t3,$zero, tlo4 #if less than


Address:
li $v0, 4
la $a0, MESSAGE6
syscall

li $v0, 1
move $a0, $t0
syscall

li $v0, 4
la $a0, MESSAGE7
syscall

li $v0, 1
move $a0, $t1
syscall

li $v0, 4
la $a0, MESSAGE7
syscall

li $v0, 1
move $a0, $t2
syscall

li $v0, 4
la $a0, MESSAGE7
syscall

li $v0, 1
move $a0, $t3
syscall

li $v0, 4
la $a0, MESSAGE14
syscall


j ClassSort




P_EXIT:

li $v0, 4
la $a0, MESSAGE13
syscall



jr $31 #end of module main
################################################################


ClassSort:

#check for class A

li $t5, 127
blt $t0, $t5, ClassA

#check for class B

li $t5, 191
blt $t0, $t5, ClassB

#check for class C
li $t5, 223
blt $t0, $t5, ClassC

#check for class D
li $t5, 239
blt $t0, $t5, ClassD

#Invalid otherwise
bgt $t0, $t5, Invalid

thi1:
li $v0, 4
la $a0, ERROROVER #too High
syscall
j FIRST
tlo1:
li $v0, 4
la $a0, ERRORUNDER #too Low
syscall
j FIRST
thi2:
li $v0, 4
la $a0, ERROROVER #too High
syscall
j SECOND
tlo2:
li $v0, 4
la $a0, ERRORUNDER #too Low
syscall
j SECOND
thi3:
li $v0, 4
la $a0, ERROROVER #too High
syscall
j THIRD
tlo3:
li $v0, 4
la $a0, ERRORUNDER #too Low
syscall
j THIRD
thi4:
li $v0, 4
la $a0, ERROROVER #too High
syscall
j FOURTH
tlo4:
li $v0, 4
la $a0, ERRORUNDER #too Low
syscall
j FOURTH



ClassA:
li $v0, 4
la $a0, MESSAGE8
syscall

li $t5, 0 #reset offset
li $t6, 0 #reset counter
ALOOP:

la $a0, IP_ROUTING_TABLE #load table
add $a0, $a0, $t5 #add current offset

lw $s0, ($a0) #load words at offsets
lw $s1,4($a0)
lw $s2,8($a0)
lw $s3,12($a0)
lw $s4,16($a0)

beq $t0, $s1, LINENUMBER #branch if match

addi $t5, 20 #increment offset
addi $t6, 1 #increment counter

beq $t6, $t9, NOMAT
j ALOOP


ClassB:
li $v0, 4
la $a0, MESSAGE9
syscall

li $t5, 0 #reset offset
li $t6, 0 #reset counter
BLOOP:

la $a0, IP_ROUTING_TABLE #load table
add $a0, $a0, $t5 #add current offset

lw $s0, ($a0) #load words at offsets
lw $s1,4($a0)
lw $s2,8($a0)
lw $s3,12($a0)
lw $s4,16($a0)


addi $t5, 20 #increment offset
addi $t6, 1 #increment counter

beq $t0, $s1, MATCHSECOND #branch if match

beq $t6, $t9, NOMAT #branch if no match
j BLOOP

#############################################################
#error is some where here, I think that it is down in MATCHSECOND2
ClassC:

li $v0, 4
la $a0, MESSAGE10
syscall

li $t5, 0 #reset offset
li $t6, 0 #reset counter
CLOOP:
la $a0, IP_ROUTING_TABLE #load table

add $a0, $a0, $t5 #add current offset/ the next line in table

lw $s0, ($a0) #load words at offsets
lw $s1,4($a0)
lw $s2,8($a0)
lw $s3,12($a0)
lw $s4,16($a0)


addi $t5, 20 #increment offset
addi $t6, 1 #increment counter


beq $t0, $s1, MATCHSECOND2 #branch if match


beq $t6, $t9, NOMAT #branch if it reaches the end of the table.



j CLOOP #end of ClassC
####################################################
ClassD:
li $v0, 4
la $a0, MESSAGE11
syscall
j P_EXIT

Invalid:
li $v0, 4
la $a0, MESSAGE12
syscall
j P_EXIT

NOMAT: #no match
li $v0, 4
la $a0, MESSAGE16
syscall

j P_EXIT

LINENUMBER:
li $v0, 4
la $a0, MESSAGE15
syscall

li $v0, 1
move $a0, $s0
syscall

j P_EXIT

MATCHSECOND:
beq $s2, $t1, LINENUMBER

j BLOOP
################################################
#belong to classC/CLOOP
MATCHSECOND2:
beq $s2, $t1, MATCHTHIRD #if second number matches, branch to test third
#if it doesn't match loop back to top
j CLOOP

MATCHTHIRD:
#provide the line of matching address if all three numbers
beq $s3, $t2, LINENUMBER
#if it doesn't match loop back to top
j CLOOP
###############################################









share|improve this question




















  • 1





    Why are the IP addresses (for matching) stored in this weird 4x word format, when the whole point of IPv4 address was, that it fits into 32 bits (one word)? Blasphemy... :)

    – Ped7g
    Nov 18 '18 at 14:45













  • @Ped7g: that's exactly what I said on another question that has the exact same silly table with each byte expanded to a word, and with those redundant index numbers that make the element size not a power of 2. Trying to traverse a .word "Table" in MIPS Assembly. Apparently the table was provided as part of an assignment.

    – Peter Cordes
    Nov 18 '18 at 16:04






  • 1





    @PeterCordes some lectors should be lectured... :)

    – Ped7g
    Nov 18 '18 at 21:30











  • Hello @PeterCordes, this is actually that same person that you helped out, lol. I couldn't login to the previous account after that question, so I had to make another. This is in fact the same stupid project, where the teacher provided the table that way. I believe his intent is to make a project where we learn how to store and access the data within tables such as these, but also make it relate-able... still confuses the crap out of me and my class. But that is also because he hasn't really shown us how to actually write assembly code. Had to teach myself everything, which isn't much.

    – Tanktastic
    Nov 18 '18 at 23:36
















0















I'll try to make this short. I am running into an infinite loop issue with my program and even after trying to use the debugger I am having issues with an infinite loop.



The program I am trying to make is an assignment from my instructor, to sort through a table of IP addresses that use .word. I have the program done about 95% the last issue I am having is when I type in 193.0.0.0, I run into this infinite loop, the structure for the loop is the same as the other two, which have no problems. In this program, for a class C domain IP address to match the first 3 numbers of the IP Address need to match user input other wise continue onto the rest of the table.
The specific issue that is happening is when it finds a match for the first number and continues to try and match the second number, and then for the third number. If the second number or third number doesn't match it jumps back to the loop, but then gets trapped there, which shouldn't be happening. At least, from what I can tell it shouldn't be.



The matching works beautifully, it is if it doesn't match that there is a problem, but again I am not sure why I am hoping that a fresh set of eyes will be able to help me see the issue.
Also, sorry for any sloppiness in the code, and for it being kind of lengthy, it is rather simple though. I appreciate the help.



.data

MESSAGE1: .asciiz "Enter an IP addressn"
MESSAGE2: .asciiz "First: "
MESSAGE3: .asciiz "Second: "
MESSAGE4: .asciiz "Third: "
MESSAGE5: .asciiz "Fourth: "
MESSAGE6: .asciiz "The IP address you entered: "
MESSAGE7: .asciiz "."
MESSAGE8: .asciiz "nClass A addressn"
MESSAGE9: .asciiz "nClass B addressn"
MESSAGE10: .asciiz "nClass C addressn"
MESSAGE11: .asciiz "nClass D addressn"
MESSAGE12: .asciiz "nInvalid domain classn"
MESSAGE13: .asciiz "nProgram successfully completed . . .n"
MESSAGE14: .asciiz "n"
MESSAGE15: .asciiz "Matching domain found at line: "
MESSAGE16: .asciiz "Matching domain was NOT found . . . n"
ERROROVER: .asciiz "The entered number is larger than 255.n"
ERRORUNDER: .asciiz "The entered number is smaller than 0.n"





IP_ROUTING_TABLE_SIZE:
.word 10

IP_ROUTING_TABLE:
# line #, x.x.x.x -------------------------------------
.word 0, 146, 92, 255, 255 # 146.92.255.255
.word 1, 147, 163, 255, 255 # 147.163.255.255
.word 2, 201, 88, 88, 90 # 201.88.88.90
.word 3, 182, 151, 44, 56 # 182.151.44.56
.word 4, 24, 125, 100, 100 # 24.125.100.100
.word 5, 146, 163, 140, 80 # 146.163.170.80
.word 6, 146, 163, 147, 80 # 146.163.147.80
.word 10, 201, 88, 102, 80 # 201.88.102.1
.word 11, 148, 163, 170, 80 # 146.163.170.80
.word 12, 193, 77, 77, 10 # 193.77.77.10

.text
.globl main

main:
la $a1, IP_ROUTING_TABLE_SIZE
lw $t9, ($a1)



li $t7, 255 #top limit

li $v0, 4
la $a0, MESSAGE1 #asking for the address
syscall
FIRST:
li $v0, 4
la $a0, MESSAGE2 #first number
syscall

li $v0, 5
syscall

move $t0, $v0 #saving input for later use.

bgt $t0, $t7, thi1 # if greater than 255
blt $t0,$zero, tlo1 # if less than

SECOND:
li $v0, 4
la $a0, MESSAGE3 # second number
syscall

li $v0, 5
syscall

move $t1, $v0 #saving input

bgt $t1, $t7, thi2 #if greater than
blt $t1,$zero, tlo2 #if less than
THIRD:
li $v0, 4
la $a0, MESSAGE4 #third number
syscall

li $v0, 5
syscall

move $t2, $v0 #saving input

bgt $t2, $t7, thi3 #if greater than
blt $t2,$zero, tlo3 #if less than

FOURTH:
li $v0, 4
la $a0, MESSAGE5 #fourth number
syscall

li $v0, 5
syscall

move $t3, $v0 #saving input

bgt $t3, $t7, thi4 #if greater than
blt $t3,$zero, tlo4 #if less than


Address:
li $v0, 4
la $a0, MESSAGE6
syscall

li $v0, 1
move $a0, $t0
syscall

li $v0, 4
la $a0, MESSAGE7
syscall

li $v0, 1
move $a0, $t1
syscall

li $v0, 4
la $a0, MESSAGE7
syscall

li $v0, 1
move $a0, $t2
syscall

li $v0, 4
la $a0, MESSAGE7
syscall

li $v0, 1
move $a0, $t3
syscall

li $v0, 4
la $a0, MESSAGE14
syscall


j ClassSort




P_EXIT:

li $v0, 4
la $a0, MESSAGE13
syscall



jr $31 #end of module main
################################################################


ClassSort:

#check for class A

li $t5, 127
blt $t0, $t5, ClassA

#check for class B

li $t5, 191
blt $t0, $t5, ClassB

#check for class C
li $t5, 223
blt $t0, $t5, ClassC

#check for class D
li $t5, 239
blt $t0, $t5, ClassD

#Invalid otherwise
bgt $t0, $t5, Invalid

thi1:
li $v0, 4
la $a0, ERROROVER #too High
syscall
j FIRST
tlo1:
li $v0, 4
la $a0, ERRORUNDER #too Low
syscall
j FIRST
thi2:
li $v0, 4
la $a0, ERROROVER #too High
syscall
j SECOND
tlo2:
li $v0, 4
la $a0, ERRORUNDER #too Low
syscall
j SECOND
thi3:
li $v0, 4
la $a0, ERROROVER #too High
syscall
j THIRD
tlo3:
li $v0, 4
la $a0, ERRORUNDER #too Low
syscall
j THIRD
thi4:
li $v0, 4
la $a0, ERROROVER #too High
syscall
j FOURTH
tlo4:
li $v0, 4
la $a0, ERRORUNDER #too Low
syscall
j FOURTH



ClassA:
li $v0, 4
la $a0, MESSAGE8
syscall

li $t5, 0 #reset offset
li $t6, 0 #reset counter
ALOOP:

la $a0, IP_ROUTING_TABLE #load table
add $a0, $a0, $t5 #add current offset

lw $s0, ($a0) #load words at offsets
lw $s1,4($a0)
lw $s2,8($a0)
lw $s3,12($a0)
lw $s4,16($a0)

beq $t0, $s1, LINENUMBER #branch if match

addi $t5, 20 #increment offset
addi $t6, 1 #increment counter

beq $t6, $t9, NOMAT
j ALOOP


ClassB:
li $v0, 4
la $a0, MESSAGE9
syscall

li $t5, 0 #reset offset
li $t6, 0 #reset counter
BLOOP:

la $a0, IP_ROUTING_TABLE #load table
add $a0, $a0, $t5 #add current offset

lw $s0, ($a0) #load words at offsets
lw $s1,4($a0)
lw $s2,8($a0)
lw $s3,12($a0)
lw $s4,16($a0)


addi $t5, 20 #increment offset
addi $t6, 1 #increment counter

beq $t0, $s1, MATCHSECOND #branch if match

beq $t6, $t9, NOMAT #branch if no match
j BLOOP

#############################################################
#error is some where here, I think that it is down in MATCHSECOND2
ClassC:

li $v0, 4
la $a0, MESSAGE10
syscall

li $t5, 0 #reset offset
li $t6, 0 #reset counter
CLOOP:
la $a0, IP_ROUTING_TABLE #load table

add $a0, $a0, $t5 #add current offset/ the next line in table

lw $s0, ($a0) #load words at offsets
lw $s1,4($a0)
lw $s2,8($a0)
lw $s3,12($a0)
lw $s4,16($a0)


addi $t5, 20 #increment offset
addi $t6, 1 #increment counter


beq $t0, $s1, MATCHSECOND2 #branch if match


beq $t6, $t9, NOMAT #branch if it reaches the end of the table.



j CLOOP #end of ClassC
####################################################
ClassD:
li $v0, 4
la $a0, MESSAGE11
syscall
j P_EXIT

Invalid:
li $v0, 4
la $a0, MESSAGE12
syscall
j P_EXIT

NOMAT: #no match
li $v0, 4
la $a0, MESSAGE16
syscall

j P_EXIT

LINENUMBER:
li $v0, 4
la $a0, MESSAGE15
syscall

li $v0, 1
move $a0, $s0
syscall

j P_EXIT

MATCHSECOND:
beq $s2, $t1, LINENUMBER

j BLOOP
################################################
#belong to classC/CLOOP
MATCHSECOND2:
beq $s2, $t1, MATCHTHIRD #if second number matches, branch to test third
#if it doesn't match loop back to top
j CLOOP

MATCHTHIRD:
#provide the line of matching address if all three numbers
beq $s3, $t2, LINENUMBER
#if it doesn't match loop back to top
j CLOOP
###############################################









share|improve this question




















  • 1





    Why are the IP addresses (for matching) stored in this weird 4x word format, when the whole point of IPv4 address was, that it fits into 32 bits (one word)? Blasphemy... :)

    – Ped7g
    Nov 18 '18 at 14:45













  • @Ped7g: that's exactly what I said on another question that has the exact same silly table with each byte expanded to a word, and with those redundant index numbers that make the element size not a power of 2. Trying to traverse a .word "Table" in MIPS Assembly. Apparently the table was provided as part of an assignment.

    – Peter Cordes
    Nov 18 '18 at 16:04






  • 1





    @PeterCordes some lectors should be lectured... :)

    – Ped7g
    Nov 18 '18 at 21:30











  • Hello @PeterCordes, this is actually that same person that you helped out, lol. I couldn't login to the previous account after that question, so I had to make another. This is in fact the same stupid project, where the teacher provided the table that way. I believe his intent is to make a project where we learn how to store and access the data within tables such as these, but also make it relate-able... still confuses the crap out of me and my class. But that is also because he hasn't really shown us how to actually write assembly code. Had to teach myself everything, which isn't much.

    – Tanktastic
    Nov 18 '18 at 23:36














0












0








0








I'll try to make this short. I am running into an infinite loop issue with my program and even after trying to use the debugger I am having issues with an infinite loop.



The program I am trying to make is an assignment from my instructor, to sort through a table of IP addresses that use .word. I have the program done about 95% the last issue I am having is when I type in 193.0.0.0, I run into this infinite loop, the structure for the loop is the same as the other two, which have no problems. In this program, for a class C domain IP address to match the first 3 numbers of the IP Address need to match user input other wise continue onto the rest of the table.
The specific issue that is happening is when it finds a match for the first number and continues to try and match the second number, and then for the third number. If the second number or third number doesn't match it jumps back to the loop, but then gets trapped there, which shouldn't be happening. At least, from what I can tell it shouldn't be.



The matching works beautifully, it is if it doesn't match that there is a problem, but again I am not sure why I am hoping that a fresh set of eyes will be able to help me see the issue.
Also, sorry for any sloppiness in the code, and for it being kind of lengthy, it is rather simple though. I appreciate the help.



.data

MESSAGE1: .asciiz "Enter an IP addressn"
MESSAGE2: .asciiz "First: "
MESSAGE3: .asciiz "Second: "
MESSAGE4: .asciiz "Third: "
MESSAGE5: .asciiz "Fourth: "
MESSAGE6: .asciiz "The IP address you entered: "
MESSAGE7: .asciiz "."
MESSAGE8: .asciiz "nClass A addressn"
MESSAGE9: .asciiz "nClass B addressn"
MESSAGE10: .asciiz "nClass C addressn"
MESSAGE11: .asciiz "nClass D addressn"
MESSAGE12: .asciiz "nInvalid domain classn"
MESSAGE13: .asciiz "nProgram successfully completed . . .n"
MESSAGE14: .asciiz "n"
MESSAGE15: .asciiz "Matching domain found at line: "
MESSAGE16: .asciiz "Matching domain was NOT found . . . n"
ERROROVER: .asciiz "The entered number is larger than 255.n"
ERRORUNDER: .asciiz "The entered number is smaller than 0.n"





IP_ROUTING_TABLE_SIZE:
.word 10

IP_ROUTING_TABLE:
# line #, x.x.x.x -------------------------------------
.word 0, 146, 92, 255, 255 # 146.92.255.255
.word 1, 147, 163, 255, 255 # 147.163.255.255
.word 2, 201, 88, 88, 90 # 201.88.88.90
.word 3, 182, 151, 44, 56 # 182.151.44.56
.word 4, 24, 125, 100, 100 # 24.125.100.100
.word 5, 146, 163, 140, 80 # 146.163.170.80
.word 6, 146, 163, 147, 80 # 146.163.147.80
.word 10, 201, 88, 102, 80 # 201.88.102.1
.word 11, 148, 163, 170, 80 # 146.163.170.80
.word 12, 193, 77, 77, 10 # 193.77.77.10

.text
.globl main

main:
la $a1, IP_ROUTING_TABLE_SIZE
lw $t9, ($a1)



li $t7, 255 #top limit

li $v0, 4
la $a0, MESSAGE1 #asking for the address
syscall
FIRST:
li $v0, 4
la $a0, MESSAGE2 #first number
syscall

li $v0, 5
syscall

move $t0, $v0 #saving input for later use.

bgt $t0, $t7, thi1 # if greater than 255
blt $t0,$zero, tlo1 # if less than

SECOND:
li $v0, 4
la $a0, MESSAGE3 # second number
syscall

li $v0, 5
syscall

move $t1, $v0 #saving input

bgt $t1, $t7, thi2 #if greater than
blt $t1,$zero, tlo2 #if less than
THIRD:
li $v0, 4
la $a0, MESSAGE4 #third number
syscall

li $v0, 5
syscall

move $t2, $v0 #saving input

bgt $t2, $t7, thi3 #if greater than
blt $t2,$zero, tlo3 #if less than

FOURTH:
li $v0, 4
la $a0, MESSAGE5 #fourth number
syscall

li $v0, 5
syscall

move $t3, $v0 #saving input

bgt $t3, $t7, thi4 #if greater than
blt $t3,$zero, tlo4 #if less than


Address:
li $v0, 4
la $a0, MESSAGE6
syscall

li $v0, 1
move $a0, $t0
syscall

li $v0, 4
la $a0, MESSAGE7
syscall

li $v0, 1
move $a0, $t1
syscall

li $v0, 4
la $a0, MESSAGE7
syscall

li $v0, 1
move $a0, $t2
syscall

li $v0, 4
la $a0, MESSAGE7
syscall

li $v0, 1
move $a0, $t3
syscall

li $v0, 4
la $a0, MESSAGE14
syscall


j ClassSort




P_EXIT:

li $v0, 4
la $a0, MESSAGE13
syscall



jr $31 #end of module main
################################################################


ClassSort:

#check for class A

li $t5, 127
blt $t0, $t5, ClassA

#check for class B

li $t5, 191
blt $t0, $t5, ClassB

#check for class C
li $t5, 223
blt $t0, $t5, ClassC

#check for class D
li $t5, 239
blt $t0, $t5, ClassD

#Invalid otherwise
bgt $t0, $t5, Invalid

thi1:
li $v0, 4
la $a0, ERROROVER #too High
syscall
j FIRST
tlo1:
li $v0, 4
la $a0, ERRORUNDER #too Low
syscall
j FIRST
thi2:
li $v0, 4
la $a0, ERROROVER #too High
syscall
j SECOND
tlo2:
li $v0, 4
la $a0, ERRORUNDER #too Low
syscall
j SECOND
thi3:
li $v0, 4
la $a0, ERROROVER #too High
syscall
j THIRD
tlo3:
li $v0, 4
la $a0, ERRORUNDER #too Low
syscall
j THIRD
thi4:
li $v0, 4
la $a0, ERROROVER #too High
syscall
j FOURTH
tlo4:
li $v0, 4
la $a0, ERRORUNDER #too Low
syscall
j FOURTH



ClassA:
li $v0, 4
la $a0, MESSAGE8
syscall

li $t5, 0 #reset offset
li $t6, 0 #reset counter
ALOOP:

la $a0, IP_ROUTING_TABLE #load table
add $a0, $a0, $t5 #add current offset

lw $s0, ($a0) #load words at offsets
lw $s1,4($a0)
lw $s2,8($a0)
lw $s3,12($a0)
lw $s4,16($a0)

beq $t0, $s1, LINENUMBER #branch if match

addi $t5, 20 #increment offset
addi $t6, 1 #increment counter

beq $t6, $t9, NOMAT
j ALOOP


ClassB:
li $v0, 4
la $a0, MESSAGE9
syscall

li $t5, 0 #reset offset
li $t6, 0 #reset counter
BLOOP:

la $a0, IP_ROUTING_TABLE #load table
add $a0, $a0, $t5 #add current offset

lw $s0, ($a0) #load words at offsets
lw $s1,4($a0)
lw $s2,8($a0)
lw $s3,12($a0)
lw $s4,16($a0)


addi $t5, 20 #increment offset
addi $t6, 1 #increment counter

beq $t0, $s1, MATCHSECOND #branch if match

beq $t6, $t9, NOMAT #branch if no match
j BLOOP

#############################################################
#error is some where here, I think that it is down in MATCHSECOND2
ClassC:

li $v0, 4
la $a0, MESSAGE10
syscall

li $t5, 0 #reset offset
li $t6, 0 #reset counter
CLOOP:
la $a0, IP_ROUTING_TABLE #load table

add $a0, $a0, $t5 #add current offset/ the next line in table

lw $s0, ($a0) #load words at offsets
lw $s1,4($a0)
lw $s2,8($a0)
lw $s3,12($a0)
lw $s4,16($a0)


addi $t5, 20 #increment offset
addi $t6, 1 #increment counter


beq $t0, $s1, MATCHSECOND2 #branch if match


beq $t6, $t9, NOMAT #branch if it reaches the end of the table.



j CLOOP #end of ClassC
####################################################
ClassD:
li $v0, 4
la $a0, MESSAGE11
syscall
j P_EXIT

Invalid:
li $v0, 4
la $a0, MESSAGE12
syscall
j P_EXIT

NOMAT: #no match
li $v0, 4
la $a0, MESSAGE16
syscall

j P_EXIT

LINENUMBER:
li $v0, 4
la $a0, MESSAGE15
syscall

li $v0, 1
move $a0, $s0
syscall

j P_EXIT

MATCHSECOND:
beq $s2, $t1, LINENUMBER

j BLOOP
################################################
#belong to classC/CLOOP
MATCHSECOND2:
beq $s2, $t1, MATCHTHIRD #if second number matches, branch to test third
#if it doesn't match loop back to top
j CLOOP

MATCHTHIRD:
#provide the line of matching address if all three numbers
beq $s3, $t2, LINENUMBER
#if it doesn't match loop back to top
j CLOOP
###############################################









share|improve this question
















I'll try to make this short. I am running into an infinite loop issue with my program and even after trying to use the debugger I am having issues with an infinite loop.



The program I am trying to make is an assignment from my instructor, to sort through a table of IP addresses that use .word. I have the program done about 95% the last issue I am having is when I type in 193.0.0.0, I run into this infinite loop, the structure for the loop is the same as the other two, which have no problems. In this program, for a class C domain IP address to match the first 3 numbers of the IP Address need to match user input other wise continue onto the rest of the table.
The specific issue that is happening is when it finds a match for the first number and continues to try and match the second number, and then for the third number. If the second number or third number doesn't match it jumps back to the loop, but then gets trapped there, which shouldn't be happening. At least, from what I can tell it shouldn't be.



The matching works beautifully, it is if it doesn't match that there is a problem, but again I am not sure why I am hoping that a fresh set of eyes will be able to help me see the issue.
Also, sorry for any sloppiness in the code, and for it being kind of lengthy, it is rather simple though. I appreciate the help.



.data

MESSAGE1: .asciiz "Enter an IP addressn"
MESSAGE2: .asciiz "First: "
MESSAGE3: .asciiz "Second: "
MESSAGE4: .asciiz "Third: "
MESSAGE5: .asciiz "Fourth: "
MESSAGE6: .asciiz "The IP address you entered: "
MESSAGE7: .asciiz "."
MESSAGE8: .asciiz "nClass A addressn"
MESSAGE9: .asciiz "nClass B addressn"
MESSAGE10: .asciiz "nClass C addressn"
MESSAGE11: .asciiz "nClass D addressn"
MESSAGE12: .asciiz "nInvalid domain classn"
MESSAGE13: .asciiz "nProgram successfully completed . . .n"
MESSAGE14: .asciiz "n"
MESSAGE15: .asciiz "Matching domain found at line: "
MESSAGE16: .asciiz "Matching domain was NOT found . . . n"
ERROROVER: .asciiz "The entered number is larger than 255.n"
ERRORUNDER: .asciiz "The entered number is smaller than 0.n"





IP_ROUTING_TABLE_SIZE:
.word 10

IP_ROUTING_TABLE:
# line #, x.x.x.x -------------------------------------
.word 0, 146, 92, 255, 255 # 146.92.255.255
.word 1, 147, 163, 255, 255 # 147.163.255.255
.word 2, 201, 88, 88, 90 # 201.88.88.90
.word 3, 182, 151, 44, 56 # 182.151.44.56
.word 4, 24, 125, 100, 100 # 24.125.100.100
.word 5, 146, 163, 140, 80 # 146.163.170.80
.word 6, 146, 163, 147, 80 # 146.163.147.80
.word 10, 201, 88, 102, 80 # 201.88.102.1
.word 11, 148, 163, 170, 80 # 146.163.170.80
.word 12, 193, 77, 77, 10 # 193.77.77.10

.text
.globl main

main:
la $a1, IP_ROUTING_TABLE_SIZE
lw $t9, ($a1)



li $t7, 255 #top limit

li $v0, 4
la $a0, MESSAGE1 #asking for the address
syscall
FIRST:
li $v0, 4
la $a0, MESSAGE2 #first number
syscall

li $v0, 5
syscall

move $t0, $v0 #saving input for later use.

bgt $t0, $t7, thi1 # if greater than 255
blt $t0,$zero, tlo1 # if less than

SECOND:
li $v0, 4
la $a0, MESSAGE3 # second number
syscall

li $v0, 5
syscall

move $t1, $v0 #saving input

bgt $t1, $t7, thi2 #if greater than
blt $t1,$zero, tlo2 #if less than
THIRD:
li $v0, 4
la $a0, MESSAGE4 #third number
syscall

li $v0, 5
syscall

move $t2, $v0 #saving input

bgt $t2, $t7, thi3 #if greater than
blt $t2,$zero, tlo3 #if less than

FOURTH:
li $v0, 4
la $a0, MESSAGE5 #fourth number
syscall

li $v0, 5
syscall

move $t3, $v0 #saving input

bgt $t3, $t7, thi4 #if greater than
blt $t3,$zero, tlo4 #if less than


Address:
li $v0, 4
la $a0, MESSAGE6
syscall

li $v0, 1
move $a0, $t0
syscall

li $v0, 4
la $a0, MESSAGE7
syscall

li $v0, 1
move $a0, $t1
syscall

li $v0, 4
la $a0, MESSAGE7
syscall

li $v0, 1
move $a0, $t2
syscall

li $v0, 4
la $a0, MESSAGE7
syscall

li $v0, 1
move $a0, $t3
syscall

li $v0, 4
la $a0, MESSAGE14
syscall


j ClassSort




P_EXIT:

li $v0, 4
la $a0, MESSAGE13
syscall



jr $31 #end of module main
################################################################


ClassSort:

#check for class A

li $t5, 127
blt $t0, $t5, ClassA

#check for class B

li $t5, 191
blt $t0, $t5, ClassB

#check for class C
li $t5, 223
blt $t0, $t5, ClassC

#check for class D
li $t5, 239
blt $t0, $t5, ClassD

#Invalid otherwise
bgt $t0, $t5, Invalid

thi1:
li $v0, 4
la $a0, ERROROVER #too High
syscall
j FIRST
tlo1:
li $v0, 4
la $a0, ERRORUNDER #too Low
syscall
j FIRST
thi2:
li $v0, 4
la $a0, ERROROVER #too High
syscall
j SECOND
tlo2:
li $v0, 4
la $a0, ERRORUNDER #too Low
syscall
j SECOND
thi3:
li $v0, 4
la $a0, ERROROVER #too High
syscall
j THIRD
tlo3:
li $v0, 4
la $a0, ERRORUNDER #too Low
syscall
j THIRD
thi4:
li $v0, 4
la $a0, ERROROVER #too High
syscall
j FOURTH
tlo4:
li $v0, 4
la $a0, ERRORUNDER #too Low
syscall
j FOURTH



ClassA:
li $v0, 4
la $a0, MESSAGE8
syscall

li $t5, 0 #reset offset
li $t6, 0 #reset counter
ALOOP:

la $a0, IP_ROUTING_TABLE #load table
add $a0, $a0, $t5 #add current offset

lw $s0, ($a0) #load words at offsets
lw $s1,4($a0)
lw $s2,8($a0)
lw $s3,12($a0)
lw $s4,16($a0)

beq $t0, $s1, LINENUMBER #branch if match

addi $t5, 20 #increment offset
addi $t6, 1 #increment counter

beq $t6, $t9, NOMAT
j ALOOP


ClassB:
li $v0, 4
la $a0, MESSAGE9
syscall

li $t5, 0 #reset offset
li $t6, 0 #reset counter
BLOOP:

la $a0, IP_ROUTING_TABLE #load table
add $a0, $a0, $t5 #add current offset

lw $s0, ($a0) #load words at offsets
lw $s1,4($a0)
lw $s2,8($a0)
lw $s3,12($a0)
lw $s4,16($a0)


addi $t5, 20 #increment offset
addi $t6, 1 #increment counter

beq $t0, $s1, MATCHSECOND #branch if match

beq $t6, $t9, NOMAT #branch if no match
j BLOOP

#############################################################
#error is some where here, I think that it is down in MATCHSECOND2
ClassC:

li $v0, 4
la $a0, MESSAGE10
syscall

li $t5, 0 #reset offset
li $t6, 0 #reset counter
CLOOP:
la $a0, IP_ROUTING_TABLE #load table

add $a0, $a0, $t5 #add current offset/ the next line in table

lw $s0, ($a0) #load words at offsets
lw $s1,4($a0)
lw $s2,8($a0)
lw $s3,12($a0)
lw $s4,16($a0)


addi $t5, 20 #increment offset
addi $t6, 1 #increment counter


beq $t0, $s1, MATCHSECOND2 #branch if match


beq $t6, $t9, NOMAT #branch if it reaches the end of the table.



j CLOOP #end of ClassC
####################################################
ClassD:
li $v0, 4
la $a0, MESSAGE11
syscall
j P_EXIT

Invalid:
li $v0, 4
la $a0, MESSAGE12
syscall
j P_EXIT

NOMAT: #no match
li $v0, 4
la $a0, MESSAGE16
syscall

j P_EXIT

LINENUMBER:
li $v0, 4
la $a0, MESSAGE15
syscall

li $v0, 1
move $a0, $s0
syscall

j P_EXIT

MATCHSECOND:
beq $s2, $t1, LINENUMBER

j BLOOP
################################################
#belong to classC/CLOOP
MATCHSECOND2:
beq $s2, $t1, MATCHTHIRD #if second number matches, branch to test third
#if it doesn't match loop back to top
j CLOOP

MATCHTHIRD:
#provide the line of matching address if all three numbers
beq $s3, $t2, LINENUMBER
#if it doesn't match loop back to top
j CLOOP
###############################################






debugging assembly mips






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 19 '18 at 0:09







Tanktastic

















asked Nov 17 '18 at 20:22









TanktasticTanktastic

244




244








  • 1





    Why are the IP addresses (for matching) stored in this weird 4x word format, when the whole point of IPv4 address was, that it fits into 32 bits (one word)? Blasphemy... :)

    – Ped7g
    Nov 18 '18 at 14:45













  • @Ped7g: that's exactly what I said on another question that has the exact same silly table with each byte expanded to a word, and with those redundant index numbers that make the element size not a power of 2. Trying to traverse a .word "Table" in MIPS Assembly. Apparently the table was provided as part of an assignment.

    – Peter Cordes
    Nov 18 '18 at 16:04






  • 1





    @PeterCordes some lectors should be lectured... :)

    – Ped7g
    Nov 18 '18 at 21:30











  • Hello @PeterCordes, this is actually that same person that you helped out, lol. I couldn't login to the previous account after that question, so I had to make another. This is in fact the same stupid project, where the teacher provided the table that way. I believe his intent is to make a project where we learn how to store and access the data within tables such as these, but also make it relate-able... still confuses the crap out of me and my class. But that is also because he hasn't really shown us how to actually write assembly code. Had to teach myself everything, which isn't much.

    – Tanktastic
    Nov 18 '18 at 23:36














  • 1





    Why are the IP addresses (for matching) stored in this weird 4x word format, when the whole point of IPv4 address was, that it fits into 32 bits (one word)? Blasphemy... :)

    – Ped7g
    Nov 18 '18 at 14:45













  • @Ped7g: that's exactly what I said on another question that has the exact same silly table with each byte expanded to a word, and with those redundant index numbers that make the element size not a power of 2. Trying to traverse a .word "Table" in MIPS Assembly. Apparently the table was provided as part of an assignment.

    – Peter Cordes
    Nov 18 '18 at 16:04






  • 1





    @PeterCordes some lectors should be lectured... :)

    – Ped7g
    Nov 18 '18 at 21:30











  • Hello @PeterCordes, this is actually that same person that you helped out, lol. I couldn't login to the previous account after that question, so I had to make another. This is in fact the same stupid project, where the teacher provided the table that way. I believe his intent is to make a project where we learn how to store and access the data within tables such as these, but also make it relate-able... still confuses the crap out of me and my class. But that is also because he hasn't really shown us how to actually write assembly code. Had to teach myself everything, which isn't much.

    – Tanktastic
    Nov 18 '18 at 23:36








1




1





Why are the IP addresses (for matching) stored in this weird 4x word format, when the whole point of IPv4 address was, that it fits into 32 bits (one word)? Blasphemy... :)

– Ped7g
Nov 18 '18 at 14:45







Why are the IP addresses (for matching) stored in this weird 4x word format, when the whole point of IPv4 address was, that it fits into 32 bits (one word)? Blasphemy... :)

– Ped7g
Nov 18 '18 at 14:45















@Ped7g: that's exactly what I said on another question that has the exact same silly table with each byte expanded to a word, and with those redundant index numbers that make the element size not a power of 2. Trying to traverse a .word "Table" in MIPS Assembly. Apparently the table was provided as part of an assignment.

– Peter Cordes
Nov 18 '18 at 16:04





@Ped7g: that's exactly what I said on another question that has the exact same silly table with each byte expanded to a word, and with those redundant index numbers that make the element size not a power of 2. Trying to traverse a .word "Table" in MIPS Assembly. Apparently the table was provided as part of an assignment.

– Peter Cordes
Nov 18 '18 at 16:04




1




1





@PeterCordes some lectors should be lectured... :)

– Ped7g
Nov 18 '18 at 21:30





@PeterCordes some lectors should be lectured... :)

– Ped7g
Nov 18 '18 at 21:30













Hello @PeterCordes, this is actually that same person that you helped out, lol. I couldn't login to the previous account after that question, so I had to make another. This is in fact the same stupid project, where the teacher provided the table that way. I believe his intent is to make a project where we learn how to store and access the data within tables such as these, but also make it relate-able... still confuses the crap out of me and my class. But that is also because he hasn't really shown us how to actually write assembly code. Had to teach myself everything, which isn't much.

– Tanktastic
Nov 18 '18 at 23:36





Hello @PeterCordes, this is actually that same person that you helped out, lol. I couldn't login to the previous account after that question, so I had to make another. This is in fact the same stupid project, where the teacher provided the table that way. I believe his intent is to make a project where we learn how to store and access the data within tables such as these, but also make it relate-able... still confuses the crap out of me and my class. But that is also because he hasn't really shown us how to actually write assembly code. Had to teach myself everything, which isn't much.

– Tanktastic
Nov 18 '18 at 23:36












1 Answer
1






active

oldest

votes


















2














There's flawed logic in the CLOOP (and not only there), when the first digit is "match" and second is "no-match", the check for table size is skipped, thus the loop may get out of IP table data.





Other problems:



     #check for class D
li $t5, 239
blt $t0, $t5, ClassD

#Invalid otherwise
bgt $t0, $t5, Invalid


This doesn't cover value 240. You can do b Invalid without any test.





Some other suggestions:



If you would preserve $ra (return address from main), you would be able to use jal subroutine to re-use some generic parts of code, like thiX and tloX parts of code .. or the whole request of input values can be like one loop using just arguments to display different prompts and store the values in array (or single register, see below).



And IPv4 addresses are 32 bit values (the reason why "255" is maximum for particular value), and they are exploited as such.



For example sub-network matching uses masking, i.e. if sub-network 160.120.0.0 (that's like value 0xA0780000) has mask 255.255.0.0 (that's like value 0xFFFF0000), then to decide if particular IP a.b.c.d is part of that sub-network, you do



is_part_of_subnet = ((IP & mask) == subnetwork_IP);


Which in assembly may look like



    # fake init for example
li $t0, 0xA0780000 # subnet address 160.120.0.0
li $t1, 0xFFFF0000 # subnet mask 255.255.0.0
li $t2, 0x12345678 # some/any IP address
# (must start with 0xA078... to trigger positive match)

# sub-network match-check
# mask-out parts of IP address which are not significant for test
and $t3, $t2, $t1 # this will clear third/fourth value to zero
beq $t3, $t0, IP_is_part_of_sub_network
# IP is not part of subnetwork (first two values are different)
...

IP_is_part_of_sub_network:
...


Line number in table should be rather calculated value from traversal of the array, than part of the stored value.



After those two things put together, the IP table may be actually compressed down into single word per line, like:



.word 0x925CFFFF  # 146.92.255.255


To make beq test work, you then should mask both values by the class mask to make only the significant parts of IP address survive to the compare...



(I'm not networking expert, so I may have flipped the sub-net mask definition, maybe it's 0.0.255.255, but then the code will flip the mask for the needs of and instruction, or it will use mask like this, but use instead or to set up the bit values in lower positions to 255, from programming point of view you just have to make sure you are using the correct and/or/flip sequence to get the correct results)






share|improve this answer
























  • I'm sorry, I guess this part needs more clarification. Testing for a match on the first number, if it matches it goes to the second number that makes a comparison, but if the comparison comes back untrue it goes back to CLOOP which then reloads the table, adds the offset (which was already incremented by 20, it also is loading the next line) and continues reading the info. The check for "NOMAT" is for if it hits the end of the table when there is no "particular match". This is my fault I was trying to shorten the post, for a class C IP address to match the first 3 numbers have to match.

    – Tanktastic
    Nov 18 '18 at 23:53











  • I appreciate your help, and if there is anything else that needs more clarification please don't hesitate to ask. To me it makes sense, at least logically it makes sense. Also I am going to add a few more comments to make sure that the intent of the program is clear. It is a program from a teacher that wants this table. Also thank you for the additional information that you provided on working with IP addresses in assembly.

    – Tanktastic
    Nov 18 '18 at 23:57






  • 1





    ..... actually I think I owe you an apology and a thank you, I changed around the no match check to a little higher in the loop and moved the increments to bellow the check and it fixed the issue, so thank you. I think the issue was the fact that I was testing for the very last value in the table and the offset incremented past the table. I don't know why I didn't see that in the debugger, thank you for the help.

    – Tanktastic
    Nov 19 '18 at 0:28











  • If there is match on first value, the beq $t6, $t9, NOMAT is not executed, only j CLOOP, so the (updated) offset into table will be actually used to read data, but that may be already beyond original table. It still a bit surprises me that it actually did "trap", I would expect it to run into some zeroed memory area, failing any matching and doing the table-size test eventually... oh wait, it's beq!! Whenever possible, I write my size tests as ptr < end(), not ptr != end(), so even if due to some reason ptr is something bogus like end()+1, the test will terminate the loop.

    – Ped7g
    Nov 19 '18 at 8:04











  • @Tanktastic it's called "defensive" programming, not trusting much even inner state of code, and writing each subroutine as robust as possible (but staying reasonable), in similar case it may save and recover from some internal bugs, which may be good or bad in production (depends what you are working on, you don't want the bank payment routine to recover and finish payment when it failed on digital signature check, but you don't want the car ABS to stop working completely because specific value "140" fall through all tests to wrong "invalid state" code branch).

    – Ped7g
    Nov 19 '18 at 8:08











Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53355226%2fneeding-help-debugging-an-assembly-programs-infinite-loop%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes









2














There's flawed logic in the CLOOP (and not only there), when the first digit is "match" and second is "no-match", the check for table size is skipped, thus the loop may get out of IP table data.





Other problems:



     #check for class D
li $t5, 239
blt $t0, $t5, ClassD

#Invalid otherwise
bgt $t0, $t5, Invalid


This doesn't cover value 240. You can do b Invalid without any test.





Some other suggestions:



If you would preserve $ra (return address from main), you would be able to use jal subroutine to re-use some generic parts of code, like thiX and tloX parts of code .. or the whole request of input values can be like one loop using just arguments to display different prompts and store the values in array (or single register, see below).



And IPv4 addresses are 32 bit values (the reason why "255" is maximum for particular value), and they are exploited as such.



For example sub-network matching uses masking, i.e. if sub-network 160.120.0.0 (that's like value 0xA0780000) has mask 255.255.0.0 (that's like value 0xFFFF0000), then to decide if particular IP a.b.c.d is part of that sub-network, you do



is_part_of_subnet = ((IP & mask) == subnetwork_IP);


Which in assembly may look like



    # fake init for example
li $t0, 0xA0780000 # subnet address 160.120.0.0
li $t1, 0xFFFF0000 # subnet mask 255.255.0.0
li $t2, 0x12345678 # some/any IP address
# (must start with 0xA078... to trigger positive match)

# sub-network match-check
# mask-out parts of IP address which are not significant for test
and $t3, $t2, $t1 # this will clear third/fourth value to zero
beq $t3, $t0, IP_is_part_of_sub_network
# IP is not part of subnetwork (first two values are different)
...

IP_is_part_of_sub_network:
...


Line number in table should be rather calculated value from traversal of the array, than part of the stored value.



After those two things put together, the IP table may be actually compressed down into single word per line, like:



.word 0x925CFFFF  # 146.92.255.255


To make beq test work, you then should mask both values by the class mask to make only the significant parts of IP address survive to the compare...



(I'm not networking expert, so I may have flipped the sub-net mask definition, maybe it's 0.0.255.255, but then the code will flip the mask for the needs of and instruction, or it will use mask like this, but use instead or to set up the bit values in lower positions to 255, from programming point of view you just have to make sure you are using the correct and/or/flip sequence to get the correct results)






share|improve this answer
























  • I'm sorry, I guess this part needs more clarification. Testing for a match on the first number, if it matches it goes to the second number that makes a comparison, but if the comparison comes back untrue it goes back to CLOOP which then reloads the table, adds the offset (which was already incremented by 20, it also is loading the next line) and continues reading the info. The check for "NOMAT" is for if it hits the end of the table when there is no "particular match". This is my fault I was trying to shorten the post, for a class C IP address to match the first 3 numbers have to match.

    – Tanktastic
    Nov 18 '18 at 23:53











  • I appreciate your help, and if there is anything else that needs more clarification please don't hesitate to ask. To me it makes sense, at least logically it makes sense. Also I am going to add a few more comments to make sure that the intent of the program is clear. It is a program from a teacher that wants this table. Also thank you for the additional information that you provided on working with IP addresses in assembly.

    – Tanktastic
    Nov 18 '18 at 23:57






  • 1





    ..... actually I think I owe you an apology and a thank you, I changed around the no match check to a little higher in the loop and moved the increments to bellow the check and it fixed the issue, so thank you. I think the issue was the fact that I was testing for the very last value in the table and the offset incremented past the table. I don't know why I didn't see that in the debugger, thank you for the help.

    – Tanktastic
    Nov 19 '18 at 0:28











  • If there is match on first value, the beq $t6, $t9, NOMAT is not executed, only j CLOOP, so the (updated) offset into table will be actually used to read data, but that may be already beyond original table. It still a bit surprises me that it actually did "trap", I would expect it to run into some zeroed memory area, failing any matching and doing the table-size test eventually... oh wait, it's beq!! Whenever possible, I write my size tests as ptr < end(), not ptr != end(), so even if due to some reason ptr is something bogus like end()+1, the test will terminate the loop.

    – Ped7g
    Nov 19 '18 at 8:04











  • @Tanktastic it's called "defensive" programming, not trusting much even inner state of code, and writing each subroutine as robust as possible (but staying reasonable), in similar case it may save and recover from some internal bugs, which may be good or bad in production (depends what you are working on, you don't want the bank payment routine to recover and finish payment when it failed on digital signature check, but you don't want the car ABS to stop working completely because specific value "140" fall through all tests to wrong "invalid state" code branch).

    – Ped7g
    Nov 19 '18 at 8:08
















2














There's flawed logic in the CLOOP (and not only there), when the first digit is "match" and second is "no-match", the check for table size is skipped, thus the loop may get out of IP table data.





Other problems:



     #check for class D
li $t5, 239
blt $t0, $t5, ClassD

#Invalid otherwise
bgt $t0, $t5, Invalid


This doesn't cover value 240. You can do b Invalid without any test.





Some other suggestions:



If you would preserve $ra (return address from main), you would be able to use jal subroutine to re-use some generic parts of code, like thiX and tloX parts of code .. or the whole request of input values can be like one loop using just arguments to display different prompts and store the values in array (or single register, see below).



And IPv4 addresses are 32 bit values (the reason why "255" is maximum for particular value), and they are exploited as such.



For example sub-network matching uses masking, i.e. if sub-network 160.120.0.0 (that's like value 0xA0780000) has mask 255.255.0.0 (that's like value 0xFFFF0000), then to decide if particular IP a.b.c.d is part of that sub-network, you do



is_part_of_subnet = ((IP & mask) == subnetwork_IP);


Which in assembly may look like



    # fake init for example
li $t0, 0xA0780000 # subnet address 160.120.0.0
li $t1, 0xFFFF0000 # subnet mask 255.255.0.0
li $t2, 0x12345678 # some/any IP address
# (must start with 0xA078... to trigger positive match)

# sub-network match-check
# mask-out parts of IP address which are not significant for test
and $t3, $t2, $t1 # this will clear third/fourth value to zero
beq $t3, $t0, IP_is_part_of_sub_network
# IP is not part of subnetwork (first two values are different)
...

IP_is_part_of_sub_network:
...


Line number in table should be rather calculated value from traversal of the array, than part of the stored value.



After those two things put together, the IP table may be actually compressed down into single word per line, like:



.word 0x925CFFFF  # 146.92.255.255


To make beq test work, you then should mask both values by the class mask to make only the significant parts of IP address survive to the compare...



(I'm not networking expert, so I may have flipped the sub-net mask definition, maybe it's 0.0.255.255, but then the code will flip the mask for the needs of and instruction, or it will use mask like this, but use instead or to set up the bit values in lower positions to 255, from programming point of view you just have to make sure you are using the correct and/or/flip sequence to get the correct results)






share|improve this answer
























  • I'm sorry, I guess this part needs more clarification. Testing for a match on the first number, if it matches it goes to the second number that makes a comparison, but if the comparison comes back untrue it goes back to CLOOP which then reloads the table, adds the offset (which was already incremented by 20, it also is loading the next line) and continues reading the info. The check for "NOMAT" is for if it hits the end of the table when there is no "particular match". This is my fault I was trying to shorten the post, for a class C IP address to match the first 3 numbers have to match.

    – Tanktastic
    Nov 18 '18 at 23:53











  • I appreciate your help, and if there is anything else that needs more clarification please don't hesitate to ask. To me it makes sense, at least logically it makes sense. Also I am going to add a few more comments to make sure that the intent of the program is clear. It is a program from a teacher that wants this table. Also thank you for the additional information that you provided on working with IP addresses in assembly.

    – Tanktastic
    Nov 18 '18 at 23:57






  • 1





    ..... actually I think I owe you an apology and a thank you, I changed around the no match check to a little higher in the loop and moved the increments to bellow the check and it fixed the issue, so thank you. I think the issue was the fact that I was testing for the very last value in the table and the offset incremented past the table. I don't know why I didn't see that in the debugger, thank you for the help.

    – Tanktastic
    Nov 19 '18 at 0:28











  • If there is match on first value, the beq $t6, $t9, NOMAT is not executed, only j CLOOP, so the (updated) offset into table will be actually used to read data, but that may be already beyond original table. It still a bit surprises me that it actually did "trap", I would expect it to run into some zeroed memory area, failing any matching and doing the table-size test eventually... oh wait, it's beq!! Whenever possible, I write my size tests as ptr < end(), not ptr != end(), so even if due to some reason ptr is something bogus like end()+1, the test will terminate the loop.

    – Ped7g
    Nov 19 '18 at 8:04











  • @Tanktastic it's called "defensive" programming, not trusting much even inner state of code, and writing each subroutine as robust as possible (but staying reasonable), in similar case it may save and recover from some internal bugs, which may be good or bad in production (depends what you are working on, you don't want the bank payment routine to recover and finish payment when it failed on digital signature check, but you don't want the car ABS to stop working completely because specific value "140" fall through all tests to wrong "invalid state" code branch).

    – Ped7g
    Nov 19 '18 at 8:08














2












2








2







There's flawed logic in the CLOOP (and not only there), when the first digit is "match" and second is "no-match", the check for table size is skipped, thus the loop may get out of IP table data.





Other problems:



     #check for class D
li $t5, 239
blt $t0, $t5, ClassD

#Invalid otherwise
bgt $t0, $t5, Invalid


This doesn't cover value 240. You can do b Invalid without any test.





Some other suggestions:



If you would preserve $ra (return address from main), you would be able to use jal subroutine to re-use some generic parts of code, like thiX and tloX parts of code .. or the whole request of input values can be like one loop using just arguments to display different prompts and store the values in array (or single register, see below).



And IPv4 addresses are 32 bit values (the reason why "255" is maximum for particular value), and they are exploited as such.



For example sub-network matching uses masking, i.e. if sub-network 160.120.0.0 (that's like value 0xA0780000) has mask 255.255.0.0 (that's like value 0xFFFF0000), then to decide if particular IP a.b.c.d is part of that sub-network, you do



is_part_of_subnet = ((IP & mask) == subnetwork_IP);


Which in assembly may look like



    # fake init for example
li $t0, 0xA0780000 # subnet address 160.120.0.0
li $t1, 0xFFFF0000 # subnet mask 255.255.0.0
li $t2, 0x12345678 # some/any IP address
# (must start with 0xA078... to trigger positive match)

# sub-network match-check
# mask-out parts of IP address which are not significant for test
and $t3, $t2, $t1 # this will clear third/fourth value to zero
beq $t3, $t0, IP_is_part_of_sub_network
# IP is not part of subnetwork (first two values are different)
...

IP_is_part_of_sub_network:
...


Line number in table should be rather calculated value from traversal of the array, than part of the stored value.



After those two things put together, the IP table may be actually compressed down into single word per line, like:



.word 0x925CFFFF  # 146.92.255.255


To make beq test work, you then should mask both values by the class mask to make only the significant parts of IP address survive to the compare...



(I'm not networking expert, so I may have flipped the sub-net mask definition, maybe it's 0.0.255.255, but then the code will flip the mask for the needs of and instruction, or it will use mask like this, but use instead or to set up the bit values in lower positions to 255, from programming point of view you just have to make sure you are using the correct and/or/flip sequence to get the correct results)






share|improve this answer













There's flawed logic in the CLOOP (and not only there), when the first digit is "match" and second is "no-match", the check for table size is skipped, thus the loop may get out of IP table data.





Other problems:



     #check for class D
li $t5, 239
blt $t0, $t5, ClassD

#Invalid otherwise
bgt $t0, $t5, Invalid


This doesn't cover value 240. You can do b Invalid without any test.





Some other suggestions:



If you would preserve $ra (return address from main), you would be able to use jal subroutine to re-use some generic parts of code, like thiX and tloX parts of code .. or the whole request of input values can be like one loop using just arguments to display different prompts and store the values in array (or single register, see below).



And IPv4 addresses are 32 bit values (the reason why "255" is maximum for particular value), and they are exploited as such.



For example sub-network matching uses masking, i.e. if sub-network 160.120.0.0 (that's like value 0xA0780000) has mask 255.255.0.0 (that's like value 0xFFFF0000), then to decide if particular IP a.b.c.d is part of that sub-network, you do



is_part_of_subnet = ((IP & mask) == subnetwork_IP);


Which in assembly may look like



    # fake init for example
li $t0, 0xA0780000 # subnet address 160.120.0.0
li $t1, 0xFFFF0000 # subnet mask 255.255.0.0
li $t2, 0x12345678 # some/any IP address
# (must start with 0xA078... to trigger positive match)

# sub-network match-check
# mask-out parts of IP address which are not significant for test
and $t3, $t2, $t1 # this will clear third/fourth value to zero
beq $t3, $t0, IP_is_part_of_sub_network
# IP is not part of subnetwork (first two values are different)
...

IP_is_part_of_sub_network:
...


Line number in table should be rather calculated value from traversal of the array, than part of the stored value.



After those two things put together, the IP table may be actually compressed down into single word per line, like:



.word 0x925CFFFF  # 146.92.255.255


To make beq test work, you then should mask both values by the class mask to make only the significant parts of IP address survive to the compare...



(I'm not networking expert, so I may have flipped the sub-net mask definition, maybe it's 0.0.255.255, but then the code will flip the mask for the needs of and instruction, or it will use mask like this, but use instead or to set up the bit values in lower positions to 255, from programming point of view you just have to make sure you are using the correct and/or/flip sequence to get the correct results)







share|improve this answer












share|improve this answer



share|improve this answer










answered Nov 18 '18 at 15:56









Ped7gPed7g

13.1k21838




13.1k21838













  • I'm sorry, I guess this part needs more clarification. Testing for a match on the first number, if it matches it goes to the second number that makes a comparison, but if the comparison comes back untrue it goes back to CLOOP which then reloads the table, adds the offset (which was already incremented by 20, it also is loading the next line) and continues reading the info. The check for "NOMAT" is for if it hits the end of the table when there is no "particular match". This is my fault I was trying to shorten the post, for a class C IP address to match the first 3 numbers have to match.

    – Tanktastic
    Nov 18 '18 at 23:53











  • I appreciate your help, and if there is anything else that needs more clarification please don't hesitate to ask. To me it makes sense, at least logically it makes sense. Also I am going to add a few more comments to make sure that the intent of the program is clear. It is a program from a teacher that wants this table. Also thank you for the additional information that you provided on working with IP addresses in assembly.

    – Tanktastic
    Nov 18 '18 at 23:57






  • 1





    ..... actually I think I owe you an apology and a thank you, I changed around the no match check to a little higher in the loop and moved the increments to bellow the check and it fixed the issue, so thank you. I think the issue was the fact that I was testing for the very last value in the table and the offset incremented past the table. I don't know why I didn't see that in the debugger, thank you for the help.

    – Tanktastic
    Nov 19 '18 at 0:28











  • If there is match on first value, the beq $t6, $t9, NOMAT is not executed, only j CLOOP, so the (updated) offset into table will be actually used to read data, but that may be already beyond original table. It still a bit surprises me that it actually did "trap", I would expect it to run into some zeroed memory area, failing any matching and doing the table-size test eventually... oh wait, it's beq!! Whenever possible, I write my size tests as ptr < end(), not ptr != end(), so even if due to some reason ptr is something bogus like end()+1, the test will terminate the loop.

    – Ped7g
    Nov 19 '18 at 8:04











  • @Tanktastic it's called "defensive" programming, not trusting much even inner state of code, and writing each subroutine as robust as possible (but staying reasonable), in similar case it may save and recover from some internal bugs, which may be good or bad in production (depends what you are working on, you don't want the bank payment routine to recover and finish payment when it failed on digital signature check, but you don't want the car ABS to stop working completely because specific value "140" fall through all tests to wrong "invalid state" code branch).

    – Ped7g
    Nov 19 '18 at 8:08



















  • I'm sorry, I guess this part needs more clarification. Testing for a match on the first number, if it matches it goes to the second number that makes a comparison, but if the comparison comes back untrue it goes back to CLOOP which then reloads the table, adds the offset (which was already incremented by 20, it also is loading the next line) and continues reading the info. The check for "NOMAT" is for if it hits the end of the table when there is no "particular match". This is my fault I was trying to shorten the post, for a class C IP address to match the first 3 numbers have to match.

    – Tanktastic
    Nov 18 '18 at 23:53











  • I appreciate your help, and if there is anything else that needs more clarification please don't hesitate to ask. To me it makes sense, at least logically it makes sense. Also I am going to add a few more comments to make sure that the intent of the program is clear. It is a program from a teacher that wants this table. Also thank you for the additional information that you provided on working with IP addresses in assembly.

    – Tanktastic
    Nov 18 '18 at 23:57






  • 1





    ..... actually I think I owe you an apology and a thank you, I changed around the no match check to a little higher in the loop and moved the increments to bellow the check and it fixed the issue, so thank you. I think the issue was the fact that I was testing for the very last value in the table and the offset incremented past the table. I don't know why I didn't see that in the debugger, thank you for the help.

    – Tanktastic
    Nov 19 '18 at 0:28











  • If there is match on first value, the beq $t6, $t9, NOMAT is not executed, only j CLOOP, so the (updated) offset into table will be actually used to read data, but that may be already beyond original table. It still a bit surprises me that it actually did "trap", I would expect it to run into some zeroed memory area, failing any matching and doing the table-size test eventually... oh wait, it's beq!! Whenever possible, I write my size tests as ptr < end(), not ptr != end(), so even if due to some reason ptr is something bogus like end()+1, the test will terminate the loop.

    – Ped7g
    Nov 19 '18 at 8:04











  • @Tanktastic it's called "defensive" programming, not trusting much even inner state of code, and writing each subroutine as robust as possible (but staying reasonable), in similar case it may save and recover from some internal bugs, which may be good or bad in production (depends what you are working on, you don't want the bank payment routine to recover and finish payment when it failed on digital signature check, but you don't want the car ABS to stop working completely because specific value "140" fall through all tests to wrong "invalid state" code branch).

    – Ped7g
    Nov 19 '18 at 8:08

















I'm sorry, I guess this part needs more clarification. Testing for a match on the first number, if it matches it goes to the second number that makes a comparison, but if the comparison comes back untrue it goes back to CLOOP which then reloads the table, adds the offset (which was already incremented by 20, it also is loading the next line) and continues reading the info. The check for "NOMAT" is for if it hits the end of the table when there is no "particular match". This is my fault I was trying to shorten the post, for a class C IP address to match the first 3 numbers have to match.

– Tanktastic
Nov 18 '18 at 23:53





I'm sorry, I guess this part needs more clarification. Testing for a match on the first number, if it matches it goes to the second number that makes a comparison, but if the comparison comes back untrue it goes back to CLOOP which then reloads the table, adds the offset (which was already incremented by 20, it also is loading the next line) and continues reading the info. The check for "NOMAT" is for if it hits the end of the table when there is no "particular match". This is my fault I was trying to shorten the post, for a class C IP address to match the first 3 numbers have to match.

– Tanktastic
Nov 18 '18 at 23:53













I appreciate your help, and if there is anything else that needs more clarification please don't hesitate to ask. To me it makes sense, at least logically it makes sense. Also I am going to add a few more comments to make sure that the intent of the program is clear. It is a program from a teacher that wants this table. Also thank you for the additional information that you provided on working with IP addresses in assembly.

– Tanktastic
Nov 18 '18 at 23:57





I appreciate your help, and if there is anything else that needs more clarification please don't hesitate to ask. To me it makes sense, at least logically it makes sense. Also I am going to add a few more comments to make sure that the intent of the program is clear. It is a program from a teacher that wants this table. Also thank you for the additional information that you provided on working with IP addresses in assembly.

– Tanktastic
Nov 18 '18 at 23:57




1




1





..... actually I think I owe you an apology and a thank you, I changed around the no match check to a little higher in the loop and moved the increments to bellow the check and it fixed the issue, so thank you. I think the issue was the fact that I was testing for the very last value in the table and the offset incremented past the table. I don't know why I didn't see that in the debugger, thank you for the help.

– Tanktastic
Nov 19 '18 at 0:28





..... actually I think I owe you an apology and a thank you, I changed around the no match check to a little higher in the loop and moved the increments to bellow the check and it fixed the issue, so thank you. I think the issue was the fact that I was testing for the very last value in the table and the offset incremented past the table. I don't know why I didn't see that in the debugger, thank you for the help.

– Tanktastic
Nov 19 '18 at 0:28













If there is match on first value, the beq $t6, $t9, NOMAT is not executed, only j CLOOP, so the (updated) offset into table will be actually used to read data, but that may be already beyond original table. It still a bit surprises me that it actually did "trap", I would expect it to run into some zeroed memory area, failing any matching and doing the table-size test eventually... oh wait, it's beq!! Whenever possible, I write my size tests as ptr < end(), not ptr != end(), so even if due to some reason ptr is something bogus like end()+1, the test will terminate the loop.

– Ped7g
Nov 19 '18 at 8:04





If there is match on first value, the beq $t6, $t9, NOMAT is not executed, only j CLOOP, so the (updated) offset into table will be actually used to read data, but that may be already beyond original table. It still a bit surprises me that it actually did "trap", I would expect it to run into some zeroed memory area, failing any matching and doing the table-size test eventually... oh wait, it's beq!! Whenever possible, I write my size tests as ptr < end(), not ptr != end(), so even if due to some reason ptr is something bogus like end()+1, the test will terminate the loop.

– Ped7g
Nov 19 '18 at 8:04













@Tanktastic it's called "defensive" programming, not trusting much even inner state of code, and writing each subroutine as robust as possible (but staying reasonable), in similar case it may save and recover from some internal bugs, which may be good or bad in production (depends what you are working on, you don't want the bank payment routine to recover and finish payment when it failed on digital signature check, but you don't want the car ABS to stop working completely because specific value "140" fall through all tests to wrong "invalid state" code branch).

– Ped7g
Nov 19 '18 at 8:08





@Tanktastic it's called "defensive" programming, not trusting much even inner state of code, and writing each subroutine as robust as possible (but staying reasonable), in similar case it may save and recover from some internal bugs, which may be good or bad in production (depends what you are working on, you don't want the bank payment routine to recover and finish payment when it failed on digital signature check, but you don't want the car ABS to stop working completely because specific value "140" fall through all tests to wrong "invalid state" code branch).

– Ped7g
Nov 19 '18 at 8:08


















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53355226%2fneeding-help-debugging-an-assembly-programs-infinite-loop%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Guess what letter conforming each word

Port of Spain

Run scheduled task as local user group (not BUILTIN)