【问题标题】:Copying words from memory address assistance (assembly)从内存地址辅助复制单词(汇编)
【发布时间】:2012-08-02 05:07:50
【问题描述】:

我正在尝试从内存中复制一些单词并使用汇编将其保存到另一个内存地址。 我正在尝试为其编写代码,但我不确定某些部分。我将简要描述一下我想做什么。

源地址、目标地址和要复制的字数是函数的输入参数。

【问题讨论】:

  • 很抱歉打扰你们。我感谢我得到的所有帮助 xx
  • 对于您得到的异常 4,请参阅我对答案所做的编辑。
  • @Michael 请在您的答案下方查看我的评论,请 xx
  • 你从哪个地址执行代码?此外,这将有助于了解导致异常的确切行。
  • 我正在使用 PCSpim 运行代码。我所做的只是单击运行按钮,然后出现一个小的弹出窗口,询问我输入 0x00400000 的起始地址并发生错误,因此我尝试不同的地址,甚至 0x10000000 及以上。当我这样做时,我得到的错误是异常 6

标签: c assembly mips lc3


【解决方案1】:

根据您的描述,它听起来像一个常规的 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 来避免数据对齐异常。

【讨论】:

  • NOP = 无操作。它什么都不做(从技术上讲,它被实现为 SLL $0,$0,0)。 MIPS 使用延迟分支 - 这意味着分支之后的指令在实际执行分支之前执行 - 所以为了避免那里有可能会弄乱复制循环的指令,我在那里放了一个 NOP。
  • 嗨,这两个代码都给我内存地址的算术错误。我正在我的问题区域上传代码,所以请看一下并告诉我是否做错了什么。
  • 嗨 Mic xx 所以如果我使用 lb 和 sb,加法运算是否如下:addiu $a0,$a0,1 和 addiu $a1,$a1,1
  • 哦,我尝试了 sb 和 lb 的加法操作,但仍然给出相同的错误
  • =( 这么麻烦我很抱歉
【解决方案2】:

编辑:在分支后添加 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:

【讨论】:

  • 谢谢,让我尝试在 MIPS 中实现它,如果可行,将接受您的回答
  • 嗨,这两个代码都给我内存地址的算术错误。我正在我的问题区域上传代码,所以请看一下并告诉我是否做错了什么。
  • 现在,对于 mips 中的每个分支或跳转,在其后放置一个 nop,执行分支后的指令。直到你手动调整代码放一个 nop。如果使用 gnu 汇编器,您可能需要 .set_reorder 或类似指令之类的东西,否则汇编器在汇编时会将分支与它之前的指令交换,或者更糟的是,要让它执行您告诉它执行的操作 gnu 汇编器需要指令。
  • 我还不知道该怎么做=(我们还没有在课堂上被教过
  • 我们昨天学习了分支,但是当你想让我包含 .set_reorder 时我不知道你的意思
猜你喜欢
  • 1970-01-01
  • 2011-06-02
  • 1970-01-01
  • 1970-01-01
  • 2021-07-06
  • 2012-01-05
  • 2013-04-04
  • 2015-10-27
相关资源
最近更新 更多