【问题标题】:Appending two string in x86 assembly在 x86 程序集中附加两个字符串
【发布时间】:2012-06-05 10:28:48
【问题描述】:

我目前正在处理 AT&T 大会的一项任务,现在我必须附加两个字符串:

message: .asciz "String 1"
before: .asciz "String 2"

我真的不知道该怎么做或如何开始。我已经在互联网上搜索过,但找不到任何有用的信息。我想我必须手动将第二个字符串的字符复制到第一个字符串的末尾,但我不确定。

谁能向我解释一下如何做到这一点? :)

【问题讨论】:

  • AT&T 程序集不存在,只是语法不同。我猜你的意思是 x86 程序集? :)
  • 好的,我冒昧地编辑了你的问题:)

标签: string x86 string-concatenation att


【解决方案1】:

这个问题没有提到目标内存,这使得它有点难以回答。我也不知道你是16位,32位还是64位。为方便起见,我也假设它们是 C 风格的以 0 结尾的字符串。

无论如何,这似乎是一般程序:

  • 获取第一个字符串的长度(有关编写 asm strlen 的说明可在此处找到:http://www.int80h.org/strlen/
  • 将ptr设置为目标内存
  • 将第一个字符串复制到目标内存,使用rep(e/ne) movsb,大小为ecx。

这可以通过使用'movsd'来优化CPU,首先对你的长度执行shr ecx, 2,以4字节为一组,然后使用movsb执行剩余部分。我见过这样做的:

mov     edi, dest
mov     esi, string_address
mov     ecx, string_length
mov     eax, ecx
shr     ecx, 2
repne movsd
mov     cl, al
and     cl, 3
repne movsb ; esi and edi move along the addresses as they copy, meaning they are already set correctly here
  • 获取第二个字符串的长度(如果需要,请务必在堆栈或其他寄存器中备份您的 edi;它包含您需要将下一个字符串复制到的地址)
  • 将第二个字符串复制到目标内存(我说过,第一个字符串操作后正确的地址应该在edi中)
  • 为安全起见,请在其后面添加一个新的 0。

如果您将第二个字符串复制到第一个字符串的末尾,您需要少做一次复制操作,但您必须确保那里实际上有足够的空间来复制第二个字符串不会覆盖其他重要内容。

【讨论】:

    【解决方案2】:

    这不是一件小事。字符串的长度是可变的,并且在内存中占据不同的空间,并且必须有一些方法可以知道它们有多长或它们在哪里结束。对于 C 或 C++,一个 nul 字节(零值字节)表示字符串的结尾。与其他一些 程序语言,你有一个指向字符串开头的指针和字符串的长度分开存储,这有一个好处是可以让你存储二进制(包括字节 零值)在字符串中。即使使用 C 和其他语言,您也必须有一个指向字符串开始位置的指针。

    通常必须发生的是,您必须使用 asm 联系操作系统并请求当前空闲的内存块,该内存块大到足以包含两个字符串的内容,一旦它们被附加。这将是与任何一个分开的内存 两个字符串开头,它来自所谓的内存堆,一旦你得到了那个内存块的起点,你就复制第一个的内容 将字符串插入其中,然后继续复制第二个字符串的内容 就在第一个后面。然后释放分配给 第一个字符串并通过更改其指针将块重新分配给该字符串,并且可能 它的长度。释放的内存由操作系统返回到内存堆以供其他地方重用。

    实际上,操作系统并不是释放内存的唯一来源。一些编译器,甚至是汇编器,要么自己处理内存管理,要么提供合适的工具 让程序员在需要时去做。

    换句话说,这可能是一项雄心勃勃的事业,而且您必须了解很多 有点关于如何正确地做这件事。你做错了,你可以期待后果 就像使您的系统崩溃并需要重新启动一样。

    【讨论】:

    • 不确定如何通过执行连接字符串的程序来使系统崩溃。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-12
    • 2020-03-21
    • 1970-01-01
    • 2020-09-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多