0

我的代码有问题,它只是打印“方向无效”,并且矩阵信息是正确的,我的输入是这个 .word 3 1 1 1 0 5 2 2 0 1 6 4。

以下是该程序应如何工作的说明。

敌舰被放置在一个名为“ships”的字符串中,该字符串存在于区域数据 (.data) 中,必须在游戏开始时由 insert_ships 函数读取。弦船具有以下模式。在插入的第一行中告知船舶的数量。以下每一行都有一艘船。指定船只的行有 4 个值,用空格分隔,如下所示:第一个值是船的布局,0 表示水平船,1 表示垂直船;第二个值是船的长度;第三个值是船舶的起跑线;第四个值是船的起始列。观察示例: 3 1 5 1 1 0 5 2 2 0 1 6 4

船舶的定位高于结果如下定位:

在此处输入图像描述

插入船只的功能必须验证船只定位的有效性,在以下情况下会生成错误消息:
- 船只的位置无效。示例:0 3 11 7
- 船舶根据矩阵的维度进行外推。示例:0 4 2 7
- 重叠发生在船上。示例 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
        

4

1 回答 1

1

您需要在字节可寻址机器上观察多字节数据的基本特性。字是 32 位宽的,这意味着它们每个占用 4 个字节的存储空间。

从位置 X 开始的一对字的第一个字位于 X 地址,第二个字位于 X+4 地址,因为我们必须跳过第一个字的所有 4 个字节才能到达第二个字.

我们还必须使用适当的处理器指令来访问存储在内存中的字数据。  lw将访问位置 X、X+1、X+2 和 X+3 以从内存中加载 4 个字节的数据。  lbu将仅访问一个字节位置,因此将丢失该字的 3 个字节。

请注意您的数据类型,并确保使用的一致性。在您的程序中,您有字数据和(字)指针以及字节数据,(字节)指针。字数据应始终使用lw& sw,而字指针应始终使用 4 的倍数,而字节数据使用lbu1 的倍数。不要将字数据视为字节数据,反之亦然。


学习单步执行代码指令,并验证每条指令是否完全符合您的预期。大多数指令只有一个效果:用一个值加载一个寄存器,或者计算一个和或乘积,可能存储到内存中。

在运行程序之前还要检查您的数据,以确保事情看起来像您预期的那样,并且程序必须正确使用数据。

不要等到你有一个完整的程序才能通过单步验证。编写一小段代码,然后运行它以通过单步执行每条指令来确保它工作,并验证每条指令是否符合您的预期。

随着程序的深入,您可以在新代码处设置断点,而不是一直单步执行,然后运行到断点并单步验证新代码。

于 2021-09-16T15:25:29.317 回答