Needing help debugging an assembly programs infinite loop
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
add a comment |
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
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
add a comment |
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
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
debugging assembly mips
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
add a comment |
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
add a comment |
1 Answer
1
active
oldest
votes
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)
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, thebeq $t6, $t9, NOMAT
is not executed, onlyj 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'sbeq
!! Whenever possible, I write my size tests asptr < end()
, notptr != end()
, so even if due to some reason ptr is something bogus likeend()+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
|
show 2 more comments
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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)
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, thebeq $t6, $t9, NOMAT
is not executed, onlyj 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'sbeq
!! Whenever possible, I write my size tests asptr < end()
, notptr != end()
, so even if due to some reason ptr is something bogus likeend()+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
|
show 2 more comments
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)
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, thebeq $t6, $t9, NOMAT
is not executed, onlyj 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'sbeq
!! Whenever possible, I write my size tests asptr < end()
, notptr != end()
, so even if due to some reason ptr is something bogus likeend()+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
|
show 2 more comments
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)
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)
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, thebeq $t6, $t9, NOMAT
is not executed, onlyj 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'sbeq
!! Whenever possible, I write my size tests asptr < end()
, notptr != end()
, so even if due to some reason ptr is something bogus likeend()+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
|
show 2 more comments
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, thebeq $t6, $t9, NOMAT
is not executed, onlyj 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'sbeq
!! Whenever possible, I write my size tests asptr < end()
, notptr != end()
, so even if due to some reason ptr is something bogus likeend()+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
|
show 2 more comments
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
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