【问题标题】:RISC-V Assembly language. Only printing zeroRISC-V 汇编语言。只打印零
【发布时间】:2021-03-02 21:56:22
【问题描述】:

以下代码应该采用两个列表并将它们放入一个大列表 (C[10]) 中,作为汇编的初学者,我不确定如何检查我的输出是否正确。 我尝试执行打印以检查左半部分是否有效,但它只打印零。 (https://www.kvakil.me/venus/ 使用这个网站作为模拟器)

    .data
A:
    .word 0,2,3,3,4
B:
    .word 24,22,21,25,23
C:
    .word 1,1,1,1,1,1,1,1,1,1,1
min:
    .word 0
.text
.globl _main   
_main:
    add x8,x8,x0 #x8=i=0
    addi x9,x9,5  #x9=5
    #start of the loop
loop:   
        bge x8,x9,exit
        add x18,x0,x8   #x18=i
        slli x18,x18,2  #x18=i*4
        addi x19,x18,20  #x19 =i*4+ 4*5
        la x20,A #x20=&A
        la x21,B #x21=&B
        la x22,C #x22=&C
        add x20,x18,x20 #x20=&A[i]
        lw x20,0(x20) #x23=A[i]                
        add x21,x19,x21 #x21=&B[i]
        lw x21,0(x21) #x24=B[i]
        add x23,x22,x19 #x23=&C[i+5]
        sw x23,0(x21) #C[i+5]=B[i]
        add x22,x18,x22 #x22=&C[i]
        sw x22,0(x20) #C[i]=A[i] 
        
        
        addi a0,x0,1
        add x20,x0,x20
        ecall

        
        addi x8,x8,1 #i=i+1
        beq x0,x0,loop
                   
exit:

我猜代码应该打印 0224 但它只打印 0。

【问题讨论】:

  • 使用单步功能验证代码操作。此外,您可以将右窗格切换到“内存”并选择“跳转到数据”来检查您的数组。一个明显的问题是add x21,x19,x21 #x21=&B[i] 使用的是x19 而不是x18
  • 是的,我想了很久。现在,我知道我的寄存器没有更新。

标签: assembly riscv riscv32


【解决方案1】:
loop:   
    bge x8,x9,exit
    add x18,x0,x8   #x18=i
    slli x18,x18,2  #x18=i*4
    addi x19,x18,20  #x19 =i*4+ 4*5
    la x20,A #x20=&A 
    la x21,B #x21=&B
    la x22,C #x22=&C
    add x20,x18,x20 #x20=&A[i]
    lw x20,0(x20) #x23=A[i]         # comment says x23, but code says x20             
    add x21,x19,x21 #x21=&B[i]
    lw x21,0(x21) #x24=B[i]         # comment says x24, but code says x21
    add x23,x22,x19 #x23=&C[i+5]
    sw x23,0(x21) #C[i+5]=B[i]      # (*B[i]) = &C[i+5] ... I don't think you want this
    add x22,x18,x22 #x22=&C[i]
    sw x22,0(x20) #C[i]=A[i]        # (*A[i]) = &C[i] ... or this
            
    addi a0,x0,1
    add x20,x0,x20
    ecall

    
    addi x8,x8,1 #i=i+1
    beq x0,x0,loop

像 Jester 所说的那样做,单步确认您认为正在发生的事情确实如此 - 不要等到看到最终输出是对/错,使用单步检查每条指令!每一条指令都是一个错字或设计问题的机会;如果任何一件事出错,程序将无法完全运行。

一般来说,您过早地重新利用寄存器来破坏值,因为事实证明您以后仍然想要它们的旧值。

除此之外,当 cmets 和代码不一致时,需要调查一下。我还建议使用友好的寄存器名称,例如a0t0s0,而不是原始数字名称——对于这个赋值可能无关紧要,但如果你开始进行过程/函数调用,它会.

【讨论】:

  • 非常感谢 cmets 的帮助。有什么方法可以从 *B[i] = &C[i+5] 更改为我在 cmets 中指出的内容?
  • 你过早地重新利用寄存器来破坏值,因为事实证明你以后仍然想要它们的旧值,所以不要这样做。每个寄存器只能保存一个值,这将是写入寄存器的最新值。如果您想要旧值,请不要重新调整寄存器的用途,而是选择另一个寄存器用于新用途。然后,您将可以访问新计算的值和旧值。
猜你喜欢
  • 2022-12-17
  • 2013-06-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-24
  • 2017-03-01
相关资源
最近更新 更多