Dev*_*s50 5 string x86 string-concatenation att
我目前正在AT&T Assembly工作,现在我必须追加两个字符串:
message: .asciz "String 1"
before: .asciz "String 2"
Run Code Online (Sandbox Code Playgroud)
我真的不知道该怎么做或如何开始.我已经在网上搜索过但我找不到任何有用的信息.我想我必须手动将第二个字符串的字符复制到第一个字符串的末尾,但我不确定.
谁有人可以向我解释如何做到这一点?:)
这个问题没有提到目标记忆,这使得回答有些困难.我也不知道你是16位,32位还是64位.为方便起见,我还假设它们是C风格的0端接字符串.
无论如何,这似乎是一般程序:
rep(e/ne) movsbecx中的大小将第一个字符串复制到目标内存.这可以通过使用'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
Run Code Online (Sandbox Code Playgroud)
如果您将第二个字符串复制到第一个字符串的末尾,则需要少一个复制操作,但是您必须确保实际上有足够的空间来复制第二个字符串而不会覆盖其他重要的内容.
小智 2
这不是一件小事。字符串的长度是可变的,并且在内存中占据不同的空间,并且必须有某种方法来知道它们的长度或结束位置。对于 C 或 C++,nul 字节(零值字节)表示字符串的结尾。对于其他一些程序语言,您有一个指向字符串开头的指针和单独存储的字符串长度,这具有允许您在字符串中存储二进制(包括零值的字节)的优点。即使使用 C 和其他语言,您也必须有一个指向字符串开始位置的指针。
通常必须发生的情况是,您必须使用 asm 联系操作系统并请求当前空闲的内存块,该内存块足够大以包含两个字符串附加后的内容。这将是与两个字符串之一分开的内存,它来自所谓的内存堆,一旦给出该内存块的起始点,您就可以将第一个字符串的内容复制到其中,然后继续将第二个字符串的内容复制到第一个字符串后面。然后释放分配给第一个字符串的内存,并通过更改其指针(可能还有其长度)将块重新分配给该字符串。释放的内存由操作系统返回到内存堆,以便在其他地方重用。
实际上,操作系统并不是释放内存的唯一来源。一些编译器,甚至汇编器,要么自己处理内存管理,要么为程序员提供合适的工具来根据需要进行管理。
换句话说,这可能是一项非常雄心勃勃的事业,您必须对正在发生的事情有很多了解才能正确完成它。如果你做错了,你可能会遇到诸如系统崩溃和需要重新启动之类的后果。