繁体   English   中英

如何在 x86 程序集中连接两个字符串?

[英]How can I concatenate two strings in x86 Assembly?

例如我有两个字符串:

section .data
    stringA    db    "abcde"
    stringB    db    "fghij"

稍后,如何将它们连接成一个新的 stringC? (即 stringC 应包含“abcdefghij”)

汇编器没有数据类型,但对于 CPU 的每条指令,它都有一条指令。

不同的编程语言有不同的方法将字符串存储在内存中:

某些语言(如 C)使用终止字符串:字符串是内存中存储字符的某个数组。 字符串的结尾由特殊字符(例如 NUL)标记,因为数组的长度大于可能的最大字符串长度:

char a[100] = "Hello";

其实意思是:

char a[100] = { 'H', 'e', 'l', 'l', 'o', 0, 'f', 'o', 'o', 'b', 'a', 'r', ...};

其他语言(如 Java、Pascal 或 C#)在内部将字符串的长度存储在某个变量中,并将字符存储在数组中:

string a = "Hello";

其实意思是:

int a_len = 5;
char a_text[100] = { 'H', 'e', 'l', 'l', 'o', 'f', 'o', 'o', 'b', 'a', 'r', ...};

或者(对于旧的 Pascal 变体):

char a[100] = { 5, 'H', 'e', 'l', 'l', 'o', 'f', 'o', 'o', 'b', 'a', 'r', ...};

由于汇编语言“只是”CPU 指令的另一种表示形式,因此任何编程语言使用的所有变体都可以在汇编语言中使用。

所以这取决于你的字符串在内存中的存储方式。

如果要连接两个以 NUL 结尾的字符串,可以按以下方式进行连接:

  1. 您将ds:siesirsi (取决于您编写的是 16 位、32 位还是 64 位代码)作为第一个字符串的第一个字符。
  2. 您将es:diedirdi设置为目标内存
  3. 你清除方向标志
  4. 您使用lodsb指令读取一个字节
  5. 您使用stosb指令写入相同的字节
  6. 如果al寄存器不为零,则继续执行第 4 步。(循环)
  7. 你递减di , edirdi
  8. 您将ds:siesirsi设置为第二个字符串的第一个字符
  9. 您再次执行循环(步骤 4.-6.)

如果您想使用其他 CPU(例如 ARM、MIPS、PowerPC 等)而不是 x86,您当然必须使用其他寄存器。 大多数 CPU 没有lodsbstosb等价物,但您必须使用两条指令:加载一个字节并递增寄存器。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM