사용자가 입력 한 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
작동합니다 : 다른 레지스터에 값을로드하는 경우, 테이블의 끝에서 분기 할 수 있습니다 테이블은 알 수없는 크기입니다. * 그러나 테이블은 여전히 컴파일 타임 상수입니까? 테이블 끝 부분에 레이블을 넣거나'.equ table_len,. - IP_ROUTING_TABLE'은 어셈블 타임 상수를 정의합니다. (메모리에 저장되지 않습니다 : 즉시 사용하십시오). –