如何使用程序集在假设的CPU ISA中复制寄存器

时间:2018-02-06 12:35:45

标签: assembly risc

在具有寄存器空间A-Z的假设CPU ISA中给出以下指令,编写程序集 程序将N个字节从地址A复制到地址B

MOV C, 100 - Move a constant value 100 to register C
LDR A, Addr – Load Register A with contents of address Addr
STR B, Addr - Store the contents of register B to address Addr
CMP X, Y - Compare X & Y and set Equal/Less than and Greater than status flags
BEQ address – Branch/Jump to address, on status flag Equal is set
BGT address – Branch on greater than
BLT address – Branch on less than

任何人都可以让我知道如何做到这一点,我不知道,因为没有incdec和一些算术指令,我该怎么办?

我不需要代码,但任何线索如何我可以提前做到这一点。

1 个答案:

答案 0 :(得分:3)

ldr / str支持哪些寻址模式?你能ldr C, 4(A)吗?如果是这样,您可以将循环完全展开到寻址模式允许的任何位移限制。

仍然包括比较,除非你可以将N视为构建时常量(这是有道理的,因为你被要求编写程序,而不是函数......)< / p>

e.g。

    cmp   N, 1
    blt   done
    ldr   C, 0(A)
    str   C, 0(B)

    cmp   N, 5       # registers are probably 4 bytes wide, if addresses are 32-bit
    blt   done
    ldr   C, 4(A)    # copy next word
    str   C, 4(B)

    cmp   N, 9
    beq   done
    ...
done:

寄存器大于1个字节时,不可能只复制一个字节。 (没有ALU指令将字节合并到一个字的旧值,而没有字节存储)。

假设寄存器宽4个字节(因为OP表示它有32位寻址),我们可以复制4个字节。如果机器允许未对齐的地址,我们可以通过一次增加1个字节的地址从4向上复制任何数量,但上面的代码总是复制4个字节的倍数。

如果机器仅支持字对齐的加载/存储,则将最后一个字重叠3个字节甚至不是一个选项。

或者您可以使用MOV立即和CMP / BEQ 实现完全展开搜索下一个最高数字的INC。 (或用于二进制搜索的BLT / BGT)。

我假设A应该是寄存器名称而非标签

,我发明了寄存器地址的语法
.copyloop:
    ldr    C, (A)
    str    C, (B)

    mov    D, 2
    cmp    A, 1
    beq    .found_A

    mov    D, 3
    cmp    A, 2
    beq    .found_A

    mov    D, 4
    cmp    A, 3
    beq    .found_A

    ...

 .found_A:
    mov    A, D       # presumably this is allowed, not only the mov-immediate form shown?

    # Then repeat that for B

    cmp    A, end_pointer   # end_pointer is a register holding a value you calculated somehow.
    blt  .copyloop

如果您的指令集真的瘫痪了,那么您的计算机几乎可编程,并且需要大量程序来枚举寄存器可能具有的每个可能值。

您可以使用二进制搜索使增量在O(log(register_width))时间内运行而不是O(值)时间。

也许您可以在内存中存储查找表,以便将inc A实现为ldr A, 5000(A)。除非内存是字节可寻址的,但是字宽大于一个字节,你需要一个表的缩放索引,所以这不起作用。