在具有寄存器空间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
任何人都可以让我知道如何做到这一点,我不知道,因为没有inc
,dec
和一些算术指令,我该怎么办?
我不需要代码,但任何线索如何我可以提前做到这一点。
答案 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)
。除非内存是字节可寻址的,但是字宽大于一个字节,你需要一个表的缩放索引,所以这不起作用。