我正在尝试从内存中复制一些单词并使用程序集将其保存到另一个内存地址。我正在尝试为其编写代码,但我不确定某些部分。我将简要描述我想做什么。
源地址、目标地址和要复制的字数是函数的输入参数。
根据您的描述,它听起来像一个常规的 memcpy,除了您指定要复制的字数而不是字节数。不确定整个堆栈缓冲区的想法来自哪里(?)。
像这样的东西会将单词从源地址复制到目标地址:
sll $a2,$a2,2
addu $a2,$a1,$a2 ; $a2 = address of first byte past the dest buffer
Loop:
lw $t0,0($a0)
sw $t0,0($a1)
addiu $a0,$a0,4
addiu $a1,$a1,4
bne $a1,$a2,Loop
nop
编辑:如果您的源缓冲区和目标缓冲区未在字边界上对齐,则需要使用 lb/sb 来避免数据对齐异常。
编辑:在分支后添加 nops
所以考虑一下你将如何在 C 中做到这一点......在低级别。
unsigned int *src,*dst;
unsigned int len;
unsigned int temp;
...
//assume *src, and *dst and len are filled in by this point
top:
temp=*src;
*dst=temp;
src++;
dst++;
len--;
if(len) goto top;
你混合了太多东西,专注于一个计划。首先你说你在两个寄存器中有一个源地址和目标地址,为什么涉及堆栈?您不是在复制或使用堆栈,而是在使用两个地址。
乘以 4 得到字节数是正确的,但是如果一次复制一个单词,则不需要计算字节数,只需计算单词即可。这是假设源地址和目标地址是对齐的,或者您不必对齐。(如果未对齐,则一次做一个字节)。
那么这在汇编中是什么样子的,您可以转换为 mips,这是伪代码:rs 是源寄存器 $a0,rd 是目标寄存器 $a1,rx 是长度寄存器 $a2,rt 是临时寄存器。现在,如果您想从内存中加载一个字,请使用加载字(lw)指令,如果您想加载一个字节,请执行 lb(加载字节)。
top:
branch_if_equal rx,0,done
nop
load_word rt,(rs)
store_word rt,(rd)
add rs,rs,4
add rd,rd,4
subtract rx,rx,1
branch top
nop
done:
现在,如果您一次复制字节而不是单词,那么
shift_left rx,2
top:
branch_if_equal rx,0,done
nop
load_byte rt,(rs)
store_byte rt,(rd)
add rs,rs,1
add rd,rd,1
subtract rx,rx,1
branch top
nop
done: