【问题标题】:Copying Array Content to Another Array in Assembly将数组内容复制到程序集中的另一个数组
【发布时间】:2011-03-08 23:07:13
【问题描述】:

我希望将数组的一些元素复制到 Assembly 中的另一个元素。两个数组都通过存储在寄存器中的指针访问。因此, edx 将指向一个数组,而 eax 将指向另一个数组。基本上, edx 指向从文本文件中读取的字符数组,我希望 eax 只包含 32 个字符。这是我正在尝试做的事情:

使用 NASM 进行 I386 组装

add edx, 8 ; the first 8 characters of the string are not wanted

mov cl, 32
ip_address:
; move the character currently pointed to by edx to eax (mov [eax], [edx])
inc edx
inc eax
loop ip_address

再次,我希望将前八个字符之后的 32 个字符放在第二个数组中。问题是我对如何做到这一点感到困惑。非常感谢任何帮助。

【问题讨论】:

    标签: arrays assembly cpu-registers


    【解决方案1】:

    您不能在 x86 中进行直接的内存到内存移动。您需要使用另一个暂存器:

    mov ecx, [edx]
    mov [eax], ecx
    

    或者类似的...

    【讨论】:

    • 使用ecx 时会出现段错误,因为它会覆盖循环计数器(clecx 的低8 位)。您需要为副本使用不同的寄存器:ebx 似乎是合乎逻辑的选择。
    • @Stephen Canon 实际上,我使用的是 ebx。 seg错误是由于mov cl,32被注释掉了。
    • 实际上,您可以执行“x86 中的直接内存到内存移动”。
    • @DigitalRoss:你的意思是在现代英特尔处理器中?以及如何?
    • @TheMask,他指的是字符串复制说明。看看他的回答。
    【解决方案2】:

    ia32 和 ia64 do 都包含一个内存到内存的字符串移动指令,可以移动字节、“字”和“双字”。

    movsb
    movsw
    movsd
    

    源地址在 ESI 中指定,目标在 EDI 中指定。1 它本身移动一个字节、字或双字。如果使用 rep 前缀,则 ECX 将包含一个计数,并且该指令将移动整个值字符串。


    1.我认为这些指令是 ESI 和 EDI 寄存器如此命名的原因。 (来源索引和目的地索引。)

    【讨论】:

      【解决方案3】:

      简单的解决方案就是这样做:

      mov  ebx, [edx]
      mov [eax], ebx
      

      请注意,在许多平台的 ABI 下,ebx 是一个被调用者保存寄存器,因此您需要在函数中保存和恢复其值。

      更简单的解决方案是链接标准库并调用memcpy,这在汇编中完全可以接受,并且通常比编写自己的循环要快得多。

      【讨论】:

      • 谢谢,斯蒂芬。如果我需要上述方法的替代方法,我必须记住这一点。
      • 或者你可以使用rep movs[esi]复制到[edi]
      • @ninjalj:可以,但至少在某些架构上调用 memcpy 会快得多。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-11-30
      • 1970-01-01
      • 2013-01-15
      • 2020-09-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多