我的代码有问题,它只是打印“无效方向”,并且矩阵信息是正确的,我的输入是这个.word 3 1 1 1 0 5 2 2 0 1 6 4。
下面是程序应该如何工作的解释。
敌舰被放置在一个名为" ships“的字符串中,该字符串出现在区域数据(.data)中,必须在游戏开始时由insert_ships函数读取。字符串ships具有以下模式。在插入的第一行中通知船舶数量。下面的每一行都有一条船。指定船舶的行有4个值,用空格分隔,如下所示:第一个值是船舶布局0(水平船舶),1(垂直船舶);第二个值是船舶长度;第三个值是船舶的起始线;第四个值是船舶的起始列。观察示例:3 1 5 1 1 0 5 2 2 0 1 6 4
船舶的定位高于以下定位的结果:
插入船舶的函数必须验证船舶定位的有效性,并在以下情况下生成错误消息:
-The船的位置无效。示例:0 3 11 7
-The ship根据矩阵的维数进行外推。示例:0 4 2 7
-The重叠发生在船舶上。示例0 4 2 2和1 3 0 3
现在完整的代码,它有什么问题吗?
.data
campo: .space 400
.align 2
navios: .word 3 1 1 1 0 5 2 2 0 1 6 4
letras: .asciz "abcdefgh"
arrume_sobreposicao : .asciz "Arrange the Overlay\n"
erro_nav: .asciz "ship out of bounds\n"
erro_direcao: .asciz "Invalid direction\n"
.text
main:
la t4, letras
la t5, navios
lw t6, 0(t5) # n = *np
addi t5,t5,1
li t1,0
li t2,100
la t3, campo
li a0, '~'
for1:
beq t1,t2, endfor1
#sw a0,0(t3)
lbu a0,0(t3)
addi t3,t3,4
addi t1,t1,1
j for1
endfor1:
li t1,0
for2:
beq t1,t6, endfor2
lbu a0, 0(t5) # dir
addi t5,t5,4
lbu a1, 0(t5) # size
addi t5,t5,4
lbu a2, 0(t5) # x
addi t5,t5,4
lbu a3, 0(t5) # y
addi t5,t5,4
jal ra, insert_ships
addi t1,t1,1
j for2
endfor2:
li a7, 10 # sai sem codigo de retorno
ecall # fim do programa
insert_ships:
li t1,1
li t2, 10
bne a1, t1, endif0 # if dir == 1
bgt a2,t2, fracasso1
bgt a3, t2,fracasso1
add t1, a3, a1 # x + size
bge t1, t2, else1 # if not (y + size >= 10)
blt a3, zero, else1 # if not (y < 0)
blt a2, zero, else1 # if not (x < 0)
bge a2, t2, else1 # if not (x >= 10)
# letra em t3, i em t1, x em a2 e y em a3
li t1, 0
fracasso1:
la a0, arrume_sobreposicao
li a7, 4
ecall
#j
for3:
bge t1,a2, endfor3 # i < size
la t5, campo
add t5, t5, a2 # m + x
add t2, a3, t1 # y + i
slli t4, t2, 3 # 8 * (y + i)
slli t2, t2, 1 # 2 * (y + i)
add t5, t5, t4 # m + x + 8*(y + i)
add t5, t5, t2 # m + x + 10*(y + i)
lbu t2, 0(t5)
li t4, '~'
bne t2, t3, else7 # if (m[x][y + i] == '~') ...
sb t3, 0(t5) # m[x][y+i] = letra
j endif7
else7:
la a0, arrume_sobreposicao
li a7, 4
ecall
#j endfor1 # break
#j endfor3
endif7:
addi t1, t1, 1
j for3
endfor3:
#j endif1
j endfor3
else1:
la a0, erro_nav
li a7, 4
ecall
endif1:
endif0:
li t2, 10
bne a1, zero, endif2 # if dir == 0 caso horizontal
bgt a2,t2, fracasso1
bgt a3, t2,fracasso1
bge a2,t2, fracasso1 # if(x < 10 && y < 10)
bge a3, t2,fracasso1
add t1, a2, a1 # x + size
# li t2, 10
bge t1, t2, else3 # if not (x + size >= 10)
blt a2, zero, else3 # if not (x < 0)
blt a3, zero, else3 # if not (y < 0)
bge a3, t2, else3 # if not (y >= 10)
# letra em t3, i em t1, x em a2 e y em a3
li t1, 0 # i = 0
for4:
bge t1,a2, endfor4 # i < size
la t5, campo
add t5, t5, a2 # m + x
add t5, a5, t1 # m + x + i
slli t4, a3, 3 # 8 * y
slli t2, a3, 1 # 2 * y
add t5, t5, t4 # m + x + i + 8*y
add t5, t5, t2 # m + x + i + 10*y
lbu t2, 0(t5)
li t4, '~'
bne t2, t3, else8 # if (m[x+i][y] == '~') ...
sb t3, 0(t5) # m[x+i][y] = letra
j endif8
else8:
la a0, arrume_sobreposicao
li a7, 4
ecall
j endfor2 # break
endif8:
addi t1, t1, 1
j for4
endfor4:
j endif3
else3:
la a0, erro_nav
li a7, 4
ecall
endif3:
endif2:
li t1, 1
ble a0, t1, endif5 # if dir > 1 eh erro
la a0, erro_direcao
li a7, 4
ecall
endif5:
#j ra # fim
li a7, 10 # sai sem codigo de retorno
ecall # fim do programa发布于 2021-09-16 15:25:29
你需要观察byte addressable机器上多字节数据的基本特性,这些字是32位宽的,这意味着它们每个字需要4个字节的存储空间。
从位置X开始的一对字的第一个字的地址为X,第二个字的地址为X+4,因为我们必须跳过第一个字的所有4个字节才能到达第二个字。
我们还必须使用适当的处理器指令来访问存储在内存中的字数据。lw将访问位置X、X+1、X+2和X+3,以便从内存加载4字节的数据。lbu将仅访问一个字节的位置,因此将丢失字的3个字节。
注意你的数据类型,并确保使用的一致性。在你的程序中,你有字数据和(字)指针以及字节数据,(字节)指针。字数据应该总是使用lw & sw,而字指针应该总是使用4的倍数,而字节数据使用lbu和1的倍数。不要把字数据当作字节数据,反之亦然。
学习单步执行代码的指令,并验证每条指令是否都在做你所期望的事情。大多数指令只有一个效果:用一个值加载一个寄存器,或者计算一个和或乘积,或者存储到内存中。
在运行程序之前,还要检查你的数据,以确保事情看起来像你预期的那样,并且数据必须被程序正确使用。
不要等到你有了一个完整的程序才能单步验证。你可以写一小段代码,然后运行它,以确保它通过单步执行每条指令来工作,并验证每条指令都做了你期望的事情。
随着程序的进一步发展,您可以在新代码处设置断点,而不是一直到那里的单步执行,然后运行到断点和单步执行来验证新代码。
https://stackoverflow.com/questions/69153805
复制相似问题