MIPS组装语言,如何将表格的尺寸保存到寄存器



我正在制作一个程序,该程序通过IP地址表进行浏览,以查看用户输入的IP地址是否匹配表中的任何内容。我的教授正在使用一张尺寸未知的桌子。我目前正在使用一个通过循环进行检查的计数器,该计数器是否可以检查IP的匹配,但仅在有10个条目时起作用,因为这是我设置的方式。

IP_ROUTING_TABLE_SIZE:
.word 10
IP_ROUTING_TABLE:
# line #, x.x.x.x -------------------------------------
.word 0, 146, 163, 255, 255     # 146.163.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 7, 146, 164, 147, 80      # 146.164.147.80
.word 8, 148, 163, 170, 80      # 148.146.170.80
.word 9, 193, 77, 77, 10        # 193.77.77.10
.text
.globl main

main:
la $t5, IP_ROUTING_TABLE_SIZE

PROMPT:
li $t6, 0
li $v0, 4
la $a0, ENTER_PROMPT
syscall 
FIRST_ENTER:
li $v0, 4
la $a0, FIRST
syscall
li $v0, 5
syscall
move $t1, $v0
blt $t1, 0, ERROR_FIRST_L
bgt $t1, 255, ERROR_FIRST_G
j SECOND_ENTER
    ERROR_FIRST_G:
        li $v0, 4
        la $a0, ERROR_LARGE
        syscall
        j FIRST_ENTER
    ERROR_FIRST_L:
        li $v0, 4
        la $a0, ERROR_SMALL
        syscall
        j FIRST_ENTER
SECOND_ENTER:
li $v0, 4
la $a0, SECOND
syscall
li $v0, 5
syscall
move $t2, $v0
blt $t2, 0, ERROR_SECOND_L
bgt $t2, 255, ERROR_SECOND_G
j THIRD_ENTER
    ERROR_SECOND_G:
        li $v0, 4
        la $a0, ERROR_LARGE
        syscall
        j SECOND_ENTER
    ERROR_SECOND_L:
        li $v0, 4
        la $a0, ERROR_SMALL
        syscall
        j SECOND_ENTER
THIRD_ENTER:
li $v0, 4
la $a0, THIRD
syscall
li $v0, 5
syscall
move $t3, $v0
blt $t3, 0, ERROR_THIRD_L
bgt $t3, 255, ERROR_THIRD_G
j FOURTH_ENTER
    ERROR_THIRD_G:
        li $v0, 4
        la $a0, ERROR_LARGE
        syscall
        j THIRD_ENTER
    ERROR_THIRD_L:
        li $v0, 4
        la $a0, ERROR_SMALL
        syscall
        j THIRD_ENTER
FOURTH_ENTER:
li $v0, 4
la $a0, FOURTH
syscall
li $v0, 5
syscall
move $t4, $v0
blt $t4, 0, ERROR_FOURTH_L
bgt $t4, 255, ERROR_FOURTH_G
j IP_ADDRESS
    ERROR_FOURTH_G:
        li $v0, 4
        la $a0, ERROR_LARGE
        syscall
        j FOURTH_ENTER
    ERROR_FOURTH_L:
        li $v0, 4
        la $a0, ERROR_SMALL
        syscall
        j FOURTH_ENTER

IP_ADDRESS:
li $v0, 4
la $a0, IP_IS
syscall
li $v0, 1
move $a0, $t1
syscall
li $v0, 4
la $a0, DOT
syscall
li $v0, 1
move $a0, $t2
syscall
li $v0, 4
la $a0, DOT
syscall
li $v0, 1
move $a0, $t3
syscall
li $v0, 4
la $a0, DOT
syscall
li $v0, 1
move $a0, $t4
syscall
li $v0, 4
la $a0, RETURN
syscall
li $v0, 4
la $a0, RETURN
syscall
IP_CLASS:
bgt $t1, 0, CLASSA
    CLASSA:
        bgt $t1, 127, CLASSB
        li $v0, 4
        la $a0, CLASS_A
        syscall
        j END
        CLASSB:
            bgt, $t1, 191, CLASSC
            li $v0, 4
            la $a0, CLASS_B
            syscall
            j END
            CLASSC:
                bgt, $t1, 223, CLASSD
                li $v0, 4
                la $a0, CLASS_C
                syscall
                j END
                CLASSD:
                    bgt, $t1, 239, CLASSE
                    li $v0, 4
                    la $a0, CLASS_D
                    syscall
                    j END
                    CLASSE:
                        li $v0, 4
                        la $a0, CLASS_E
                        syscall
END:
la $s0, IP_ROUTING_TABLE
CHECKPHASE:

lw $s1, 4($s0)
lw $s2, 8($s0)
lw $s3, 12($s0)
lw $s4, 16($s0)
bgt $s1, 0, MORETHAN1
    MORETHAN1:
        bgt $s1, 127, MORETHAN127
        beq $s1, $t1, MATCH_FOUND
        j END_CHECK
        MORETHAN127:
            bgt $s1, 191, MORETHAN191
            beq $s1, $t1, CHECK_1
            j END_CHECK
                CHECK_1:
                    beq $s2, $t2, MATCH_FOUND
            j END_CHECK
            MORETHAN191:
                bgt $s1, 223, ERRORNOTFOUND
                beq $s1, $t1, CHECK_1_2
                j END_CHECK
                    CHECK_1_2:
                        beq $s2, $t2, CHECK_2_2
                        j END_CHECK
                            CHECK_2_2:
                                beq $s3, $t3, MATCH_FOUND
                                j END_CHECK

这是我需要帮助的地方。我如何确定表何时不再有条目,并且应该跳到Errornotfound?

END_CHECK:
add $t6, $t6, 1
beq $t6, $t5, ERRORNOTFOUND
addi $s0, $s0, 20

j CHECKPHASE
MATCH_FOUND:
li $v0, 4
la $a0, MATCH_FOUND_PRINT
syscall
li $v0, 1
move $a0, $t6
syscall
li $v0, 4
la $a0, RETURN
syscall
j END_OF_PROGRAM
ERRORNOTFOUND:
li $v0, 4
la $a0, ERROR_NOT_FOUND
syscall
j END_OF_PROGRAM
END_OF_PROGRAM:
li $v0, 4
la $a0, PROGRAM_COMPLETE
syscall
jr $31
syscall

您已经检查了表中是否还有更多条目:

END_CHECK:
add $t6, $t6, 1
beq $t6, $t5, ERRORNOTFOUND

T5寄存器应该具有表格的大小,但是您将整个单词都放在其中。如果将值加载到其他寄存器,则可以在表末端分支:

la $t5, IP_ROUTING_TABLE_SIZE
lw $t7, 0($t5)

然后,只需更改您的end_check即可工作

END_CHECK:
add $t6, $t6, 1
beq $t6, $t7, ERRORNOTFOUND

一种可能性是用终结器记录扩展表格,例如:

.word 9, 193, 77, 77, 10        # 193.77.77.10
.word -1, 0, 0, 0, 0        # Terminator record

(如果您不能在第一个单词中使用-1,则可以考虑使用256之类的第一个IP字节,因为您定义.word而不是.byte

btw,为什么?每个IPv4地址都符合单个单词(四个字节),为什么您要通过定义4个浪费它们的ram?

这是对IPv4设计的令人作呕的误解,它于1981年设计为适合32位,因为有40亿个单独的设备地址足以容纳有史以来生产的每台大型机器机器的计算机...同时,某些Smartass开始出售家用计算机和〜十年后来有人想到将它们连接到大型网络……并毁了一切。因此,然后设计了IPv6,这次是如此...如此之多,以至于几乎没有人想在设备中首先实现它,这就是为什么迁移到IPv6仍处于婴儿期的原因。)

然后在代码中:

    la $s0, IP_ROUTING_TABLE
CHECKPHASE:
    # load the first word in table (line number?)
    lw $s1, 0($s0)
    # check with -1?
    # Nah, generally for negative number should be OK, as you
    # will run out of memory before reaching line 0x80000000
    bltz $s1, ERRORNOTFOUND
    # continue with original code
    lw $s1, 4($s0)

从您的问题中,尚不清楚您的教授将如何提供可变长度表(您是否可以添加终结者记录。然后,Arnold Schwarzenegger再次批准了这一点,因此您的教授几乎无法抗拒)

最新更新