2012-06-05 54 views
5

我目前正在对AT & T汇编的转让,现在我不得不追加两个字符串:追加两个String在x86汇编

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

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

任何人都可以请向我解释如何做到这一点? :)

+0

AT&T汇编不存在,它只是一个不同的语法..我想你的意思是x86汇编也许? :) – BlackBear

+0

这就是我的意思:) – Devos50

+0

好吧,我冒昧地编辑你的queston :) – BlackBear

回答

2

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

通常必须发生的事情是,您必须使用asm联系操作系统并请求一个当前空闲的内存块,该内存块足够大以包含两个字符串的内容。这将与内存分开,从两个字符串开始,它来自于被称为内存堆的内存块,一旦给出内存块的起始点,就会复制第一个内存块的第一个字符串 进入它,然后继续复制 中第二个字符串的内容。然后,释放已分配给 第一个字符串的内存,并通过更改其指针并将其重新分配给该字符串,并可能将其长度更改为 。释放的内存由操作系统返回到内存堆以便在别处重新使用。

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

换句话说,这可能是一项非常雄心勃勃的任务,而且您必须知道相当多的事情才能做正确的事情。你做错了,你可能会想到后果 像崩溃你的系统,需要重新启动。

+0

不知道如何通过执行连接字符串的程序来崩溃你的系统。 – Simon

5

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

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

  • 获得第一个字符串的长度(上写的ASM strlen的指令可以在这里找到:http://www.int80h.org/strlen/
  • 设置PTR到目标内存
  • 使用尺寸为ecx的rep(e/ne) movsb将第一个字符串复制到目标内存。

这可能是CPU的优化使用“MOVSD”首先做一个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后面。

如果复制第二个字符串的第一个字符串的结尾,你需要一个更小的复制操作,但你,以确保有足够的实际空间存在的第二个字符串复制,而不会覆盖其他重要的东西。