需要帮助调试汇编程序无限循环

时间:2018-11-17 20:22:36

标签: debugging assembly mips

我会尽量简短。我的程序遇到了无限循环问题,甚至在尝试使用调试器后,我也遇到了无限循环问题。

我要制作的程序是我老师的一项作业,目的是对使用.word的IP地址表进行排序。我完成了大约95%的程序,最后一个问题是当我键入193.0.0.0时,遇到了这个无限循环,该循环的结构与其他两个相同,没有问题。在此程序中,要使C类域IP地址与IP地址的前3个数字匹配,需要与用户输入匹配,否则,请继续表的其余部分。    发生的特定问题是,当它找到第一个数字的匹配项并继续尝试与第二个数字匹配,然后再与第三个数字匹配。如果第二个数字或第三个数字不匹配,它会跳回到循环中,但随后会被困在那里,这本不应该发生。至少,根据我的判断,应该不会。

匹配效果很好,如果不匹配,则有问题,但是我不确定为什么希望新的眼睛能够帮助我解决问题。    另外,对代码中的任何草率和冗长的代码表示抱歉,这很简单。感谢您的帮助。

.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    $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
 ###############################################

1 个答案:

答案 0 :(得分:2)

CLOOP中(不仅是那里)存在有缺陷的逻辑,当第一个数字为“匹配”而第二个数字为“不匹配”时,将跳过对表大小的检查,因此循环可能IP表数据不足。


其他问题:

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

     #Invalid otherwise
     bgt $t0, $t5, Invalid

这不包括值240。您可以b Invalid进行任何测试。


其他一些建议:

如果您保留$ra(来自main的返回地址),则可以使用jal subroutine重用某些通用代码部分,例如thiXtloX代码的一部分..或整个输入值的请求就像一个循环,仅使用参数来显示不同的提示并将值存储在数组中(或单个寄存器,请参见下文)。

IPv4地址是32位值(对于特定值,“ 255”最大的原因),因此被利用。

例如,子网匹配使用掩码,即,如果子网160.120.0.0(类似于值0xA0780000)具有掩码255.255.0.0(类似于值0xFFFF0000),则确定特定的IP abcd是否属于该子网,您可以

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:
    ...

表中的行号应该是从遍历数组计算得出的值,而不是部分存储值。

将这两件事放在一起后,实际上可以将IP表压缩为每行一个单词,例如:

.word 0x925CFFFF  # 146.92.255.255

要使beq测试正常,您应该使用类掩码屏蔽这两个值,以使IP地址中只有重要部分可以生存下来进行比较...

(我不是网络专家,所以我可能已经翻转了子网掩码定义,也许是0.0.255.255,但是随后代码会根据and指令的需要翻转掩码,或者将使用这样的掩码,但是使用or来将较低位置的位值设置为255,从编程的角度来看,您只需确保使用正确的和/或/翻转序列即可正确的结果)