Loops MIPS汇编语言,如何将表的大小保存到寄存器?
我正在制作一个程序,查看IP地址表,看看用户输入的IP地址是否与表中的任何地址匹配。我的教授正在使用一张大小不详的桌子。我目前正在使用一个计数器,在循环的每个迭代中检查IP是否匹配,但它只在有10个条目时工作,因为这是我设置它的方式Loops MIPS汇编语言,如何将表的大小保存到寄存器?,loops,assembly,mips,Loops,Assembly,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
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
一种可能性是使用terminator记录扩展表,如:
.word 9, 193, 77, 77, 10 # 193.77.77.10
.word -1, 0, 0, 0, 0 # Terminator record
(如果你不能在第一个单词中使用-1,你仍然可以考虑使用第一个IP字节,比如<代码> 256 /代码>,因为你定义了<代码> Word < /COD>而不是<代码>。 顺便说一句,为什么?每个IPv4地址都可以放在一个字(四个字节)中,为什么定义它们会浪费内存*4个字节
这是对IPv4设计的令人厌恶的误解,它在1981年被设计为适合32位,因为40亿个单独的设备地址将足以满足每台大型机的生产……与此同时,一些聪明人开始销售家用计算机,~十年后,有人想到将它们连接到大网络……并毁掉了所有的一切。于是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)
从您的问题来看,不清楚教授将如何提供可变长度表(您是否可以添加终止符记录。然后,阿诺德·施瓦辛格再次批准了它,因此您的教授几乎无法抗拒)您已经在检查表中是否有更多的条目:
END_CHECK:
add $t6, $t6, 1
beq $t6, $t5, ERRORNOTFOUND
la $t5, IP_ROUTING_TABLE_SIZE
lw $t7, 0($t5)
t5寄存器应该有表的大小,但是你把整个单词都放进去了。如果将值加载到其他寄存器,则可以在表的末尾进行分支:
END_CHECK:
add $t6, $t6, 1
beq $t6, $t5, ERRORNOTFOUND
la $t5, IP_ROUTING_TABLE_SIZE
lw $t7, 0($t5)
然后,只需改变你的结束检查,它应该工作
END_CHECK:
add $t6, $t6, 1
beq $t6, $t7, ERRORNOTFOUND
我的教授正在使用一张大小不详的桌子。但是这个表仍然是一个编译时常量,对吗?将标签放在表格的末尾,或.eq table\u len,.-IP_路由_表
定义组装时间常数。(未存储在内存中:将其用作立即数)。