2016-11-26 113 views
2

我正在製作一個程序,通過IP地址表來查看用戶輸入的IP地址是否匹配表中的任何IP地址。我的教授正在使用一張尺寸未知的桌子。我目前正在使用一個計數器,每循環遍歷循環檢查IP是否匹配,但它只在有10個條目時才起作用,因爲這是我設置它的方法。MIPS彙編語言,如何將表的大小保存到寄存器?

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 
+0

*我的教授是使用表是一個未知的大小。*但表仍然是一個編譯時常量嗎?將一個標籤放在表格的最後,或者'.equ table_len,。 - IP_ROUTING_TABLE定義了一個彙編時間常量。 (不存儲在內存中:用作立即)。 –

回答

0

一種可能是你的表終止記錄擴展,如:

.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地址單個字(四個字節)適合,你爲什麼要定義它們浪費你的RAM * 4長?

這是令人厭惡的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) 

從你的問題現在還不清楚你的教授將如何提供可變長度表(你是否可以添加終止記錄..然後再次,阿諾德·施瓦辛格批准,所以你的教授很難抗拒)

1

你已經在檢查表中是否有更多的條目:

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