需要帮助调试汇编程序无限循环
Needing help debugging an assembly programs infinite loop
我会尽量缩短。我 运行 我的程序陷入了无限循环问题,甚至在尝试使用调试器后我也遇到了无限循环问题。
我要编写的程序是我的讲师布置的作业,用于对 table 使用 .word 的 IP 地址进行分类。我的程序完成了大约 95% 最后一个问题是当我输入 193.0.0.0 时,我 运行 进入这个无限循环,循环的结构与其他两个相同,没有问题。在此程序中,要使 class C 域 IP 地址匹配 IP 地址的前 3 个数字,需要匹配用户输入,否则继续 table 的其余部分。
发生的具体问题是当它找到第一个数字的匹配项并继续尝试匹配第二个数字,然后是第三个数字。如果第二个数字或第三个数字不匹配,它会跳回循环,但随后会被困在那里,这是不应该发生的。至少,据我所知不应该。
匹配效果很好,如果不匹配就说明有问题,但我还是不确定为什么我希望有新的眼睛能帮助我看清问题。
另外,对于代码中的任何草率,以及它有点冗长,但它很简单,我们深表歉意。感谢您的帮助。
.data
MESSAGE1: .asciiz "Enter an IP address\n"
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 address\n"
MESSAGE9: .asciiz "\nClass B address\n"
MESSAGE10: .asciiz "\nClass C address\n"
MESSAGE11: .asciiz "\nClass D address\n"
MESSAGE12: .asciiz "\nInvalid domain class\n"
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 #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
###############################################
CLOOP
中存在逻辑缺陷(不仅如此),当第一个数字为 "match" 且第二个数字为 "no-match" 时,检查 table 大小被跳过,因此循环可能会超出 IP table 数据。
其他问题:
#check for class D
li $t5, 239
blt $t0, $t5, ClassD
#Invalid otherwise
bgt $t0, $t5, Invalid
这不包括值 240。您可以 b Invalid
无需任何测试。
其他一些建议:
如果您保留 $ra
(来自 main
的 return 地址),您将能够使用 jal subroutine
重新使用代码的一些通用部分,像代码的 thiX
和 tloX
部分 .. 或者输入值的整个请求可以像一个循环,只使用参数来显示不同的提示并将值存储在数组中(或单个寄存器,见下文) .
并且 IPv4 地址是 32 位值(“255”对于特定值来说是最大值的原因),它们就这样被利用了。
例如子网匹配使用掩码,即如果子网 160.120.0.0
(类似于值 0xA0780000
)具有掩码 255.255.0.0(类似于值 0xFFFF0000
),然后确定特定 IP a.b.c.d 是否是该子网的一部分,您需要
is_part_of_subnet = ((IP & mask) == subnetwork_IP);
在汇编中可能看起来像
# 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:
...
table中的行号应该是遍历数组的计算值,而不是存储值的一部分。
将这两件事放在一起后,IP table 实际上可能会被压缩成每行一个单词,例如:
.word 0x925CFFFF # 146.92.255.255
要使 beq
测试工作,您应该用 class 掩码屏蔽两个值,使 IP 地址的重要部分在比较中幸存下来...
(我不是网络专家,所以我可能翻转了子网掩码定义,可能是0.0.255.255,但是代码会根据and
指令的需要翻转掩码,或者它会像这样使用掩码,而是使用 or
将较低位置的位值设置为 255,从编程的角度来看,您只需确保使用正确的 and/or/flip 序列以获得正确的结果)
我会尽量缩短。我 运行 我的程序陷入了无限循环问题,甚至在尝试使用调试器后我也遇到了无限循环问题。
我要编写的程序是我的讲师布置的作业,用于对 table 使用 .word 的 IP 地址进行分类。我的程序完成了大约 95% 最后一个问题是当我输入 193.0.0.0 时,我 运行 进入这个无限循环,循环的结构与其他两个相同,没有问题。在此程序中,要使 class C 域 IP 地址匹配 IP 地址的前 3 个数字,需要匹配用户输入,否则继续 table 的其余部分。 发生的具体问题是当它找到第一个数字的匹配项并继续尝试匹配第二个数字,然后是第三个数字。如果第二个数字或第三个数字不匹配,它会跳回循环,但随后会被困在那里,这是不应该发生的。至少,据我所知不应该。
匹配效果很好,如果不匹配就说明有问题,但我还是不确定为什么我希望有新的眼睛能帮助我看清问题。 另外,对于代码中的任何草率,以及它有点冗长,但它很简单,我们深表歉意。感谢您的帮助。
.data
MESSAGE1: .asciiz "Enter an IP address\n"
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 address\n"
MESSAGE9: .asciiz "\nClass B address\n"
MESSAGE10: .asciiz "\nClass C address\n"
MESSAGE11: .asciiz "\nClass D address\n"
MESSAGE12: .asciiz "\nInvalid domain class\n"
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 #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
###############################################
CLOOP
中存在逻辑缺陷(不仅如此),当第一个数字为 "match" 且第二个数字为 "no-match" 时,检查 table 大小被跳过,因此循环可能会超出 IP table 数据。
其他问题:
#check for class D
li $t5, 239
blt $t0, $t5, ClassD
#Invalid otherwise
bgt $t0, $t5, Invalid
这不包括值 240。您可以 b Invalid
无需任何测试。
其他一些建议:
如果您保留 $ra
(来自 main
的 return 地址),您将能够使用 jal subroutine
重新使用代码的一些通用部分,像代码的 thiX
和 tloX
部分 .. 或者输入值的整个请求可以像一个循环,只使用参数来显示不同的提示并将值存储在数组中(或单个寄存器,见下文) .
并且 IPv4 地址是 32 位值(“255”对于特定值来说是最大值的原因),它们就这样被利用了。
例如子网匹配使用掩码,即如果子网 160.120.0.0
(类似于值 0xA0780000
)具有掩码 255.255.0.0(类似于值 0xFFFF0000
),然后确定特定 IP a.b.c.d 是否是该子网的一部分,您需要
is_part_of_subnet = ((IP & mask) == subnetwork_IP);
在汇编中可能看起来像
# 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:
...
table中的行号应该是遍历数组的计算值,而不是存储值的一部分。
将这两件事放在一起后,IP table 实际上可能会被压缩成每行一个单词,例如:
.word 0x925CFFFF # 146.92.255.255
要使 beq
测试工作,您应该用 class 掩码屏蔽两个值,使 IP 地址的重要部分在比较中幸存下来...
(我不是网络专家,所以我可能翻转了子网掩码定义,可能是0.0.255.255,但是代码会根据and
指令的需要翻转掩码,或者它会像这样使用掩码,而是使用 or
将较低位置的位值设置为 255,从编程的角度来看,您只需确保使用正确的 and/or/flip 序列以获得正确的结果)