2016-11-26 2 views
2

사용자가 입력 한 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 바이트, 대신 .byte.word을 정의한다.

BTW,? 각 IPv4 주소는 한 단어 (4 바이트)에 맞는 왜, 왜 당신이 그들을 정의하여 RAM을 낭비 할 * 4 더 이상?

이것은 IPv4 디자인에 대한 오해입니다. 그것은 32 비트에 맞도록 1981 년에 설계되었습니다. 4 억 개의 개별 장치 주소가 모든 메인 프레임 컴퓨터에 충분하기 때문입니다 ... 한편으로 일부 스마트 카드는 가정용 컴퓨터를 판매하기 시작했으며 ~ 10 년 후 누군가는 큰 네트워크에 연결하는 아이디어를 얻었고 ... 모든 것을 망 쳤어. 그래서 다음의 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