【问题标题】:how to copy the register in hypothetical CPU ISA using assembly如何使用汇编复制假设的 CPU ISA 中的寄存器
【发布时间】:2018-02-06 12:35:44
【问题描述】:

在具有寄存器空间 A-Z 的假设 CPU ISA 中给出以下指令,编写程序集 程序从地址 A 复制 N 个字节到地址 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 和一些算术指令,我该怎么做?

我不需要代码,但提前感谢任何线索我该如何进行。

【问题讨论】:

  • 我不知道,因为没有任何算术指令我怎么能继续。
  • 我认为这甚至不是图灵完备的 ISA

标签: assembly instruction-set


【解决方案1】:

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

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

例如

    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

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

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


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

【讨论】:

  • 支持32位寻址
  • @torban:寄存器也是 32 位的,还是 LDR 不支持寄存器中的地址,只支持硬编码地址?无论如何,这并没有真正改变答案。
  • 是的,LDR 负载已编码,并且地址也已写入目标寄存器
  • 如果内存是字节可寻址的,但加载/存储更宽且未对齐,您可以通过将寄存器的每个字节存储在内存中来提取寄存器的每个字节,在正确的位置写入零,然后从正确的地址(假设为 LE)。这让我们将 inc32 问题拆分为四个 inc8 问题。类似的技术可用于提取寄存器的低字节,允许我们使用 8 位 LUT。然后 inc8 可以用一个 LUT 和 inc32 用四个查找来实现。
猜你喜欢
  • 2021-03-25
  • 2014-09-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-01-30
  • 1970-01-01
  • 2012-01-02
相关资源
最近更新 更多