1

我认为在具体示例中很容易解释,我理解 beq 的工作方式类似于 if r9==r10 该语句调用显示在同一行的标签,但我不完全理解其他人。

开始:.word 0 .word INSTR1:.word 1 .word 77 .word INSTR2 INSTR2:.word 2 .word 15 .word FIN:.word 3

acc:
    .word 0


.text

.global main

main:   movia r8, START
    movia r9, acc

myloop: movi r10, 1
    ldw r11, 0x0(r8)
    beq r11, r0, clear
    beq r11, r10, add
    addi r10, r10, 1
    beq r11, r10, sub
    addi r10, r10, 1
    beq r11, r10, exit
    br fail

clear:  stw r0, 0x0(r9)
    ldw r8, 0x4(r8)
    br myloop

add:    ldw r12, 0x0(r9)
    ldw r13, 0x4(r9)
    addi r12, r12, r13
    stw r12, 0x0(r9)
    ldw r8, 0x8(r8)
    br myloop

sub:    ldw r12, 0x0(r9)
    ldw r13, 0x4(r9)
    sub r12, r12, r13
    stw r12, 0x0(r9)
    ldw r8, 0x8(r8)
    br myloop

exit:   ret

fail:   movia r12, 0xFFFFFFFF
    stw r12, 0x0(r9)
    ret
4

1 回答 1

2

Movia 是一个伪语句,它将 32 位立即地址加载到寄存器中。由于 NIOS 中的指令宽度固定为 32 位,因此它使用两条指令发生:

"load_high_16_bits_and_clear_the_lower_part, register, #imm16_hi"
"or_register_with_16_bit_immediate_at_the_lower_part, register, #imm16_lo"

因为 NIOS 提供了 orhi 指令,所以同样可以这样执行:

"load_lower_bits_and_clear_the_rest register, #imm16"
"orhi register, #imm16_hi_bits"

movi == 立即移动。同样,该指令只能接受#imm16。

ldw = 加载“字” == 32 位。通过将立即数添加到寄存器来计算地址。在这种情况下,指令集只允许 14 位的位移

stw = 存储“字”== 32 位。

addi = 立即添加:寄存器 = 寄存器 + #imm_16

指令集参考在立即数之前使用希腊符号“sigma”作为执行“符号扩展”的函数的符号,这意味着将立即数中的最高有效位复制到整个 32 位寄存器(或临时值)中,也允许立即签署。(注意 sig_ned 与 sig_ma)。

编辑

NIOS 中的调用机制也需要注意:它使用“滑动窗口寄存器机制”,这意味着处理器有例如 64 或 256 个寄存器,其中只有 32 个寄存器同时可见。低 16 个寄存器 IIRC 是“全局的”,每次调用或返回时,16 个高位寄存器移位 4 或 8 个寄存器。

这意味着寄存器组会自动“分配”一些临时变量,这些临时变量会在窗口移动时成为下一个函数调用的输入参数。同样,IIRC,调用在调用时将返回地址复制到一个特定的寄存器(例如 r31),在被调用函数中被视为 r23(反之亦然)。'ret' 意味着跳转到 'r23' 并将寄存器窗口移回。同样,可以几个寄存器返回给调用者。

于 2013-01-28T07:33:40.953 回答