例如,我有两个字符串:
section .data stringA db "abcde" stringB db "fghij"
稍后,我如何将它们连接到一个新的stringC中?(即stringC应该包含“abcdefghij”)
ozxc1zmp1#
汇编程序没有数据类型,但它对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指令的另一种表示,所以任何编程语言使用的所有变体都可以用汇编语言来表示。因此,它取决于字符串在内存中的存储方式。如果要连接两个以NULL结尾的字符串,可以按以下方式进行连接:1.将ds:si、esi或rsi(取决于写入的是16位、32位还是64位代码)设置为第一个字符串的第一个字符。1.将es:di、edi或rdi设置为目标内存1.清除方向标志1.使用lodsb指令读取一个字节1.使用stosb指令写入相同的字节1.如果al寄存器不为零,则继续执行步骤4。(循环)1.减少di、edi或rdi1.将ds:si、esi或rsi设置为第二个字符串的第一个字符1.再次执行循环(步骤4 -6)如果你想使用其他的CPU(例如ARM,MIPS,PowerPC,...)来代替x86,当然你必须使用其他的寄存器。大多数CPU没有lodsb或stosb的等价物,但是你必须使用两条指令:加载一个字节并递增寄存器。
ds:si
esi
rsi
es:di
edi
rdi
lodsb
stosb
al
di
1条答案
按热度按时间ozxc1zmp1#
汇编程序没有数据类型,但它对CPU的每个指令都有一个指令。
不同的编程语言有不同的方法将字符串存储在内存中:
有些语言(如C)使用终止字符串:字符串是内存中存储字符的某个数组。字符串的结尾用一个特殊字符(例如NUL)标记,因为数组的长度大于字符串的最大可能长度:
其实意思是:
其他语言(如Java、Pascal或C#)在内部将字符串的长度存储在某个变量中,并将字符存储在数组中:
其实意思是:
或者(在旧Pascal变体的情况下):
因为汇编语言“只是”CPU指令的另一种表示,所以任何编程语言使用的所有变体都可以用汇编语言来表示。
因此,它取决于字符串在内存中的存储方式。
如果要连接两个以NULL结尾的字符串,可以按以下方式进行连接:
1.将
ds:si
、esi
或rsi
(取决于写入的是16位、32位还是64位代码)设置为第一个字符串的第一个字符。1.将
es:di
、edi
或rdi
设置为目标内存1.清除方向标志
1.使用
lodsb
指令读取一个字节1.使用
stosb
指令写入相同的字节1.如果
al
寄存器不为零,则继续执行步骤4。(循环)1.减少
di
、edi
或rdi
1.将
ds:si
、esi
或rsi
设置为第二个字符串的第一个字符1.再次执行循环(步骤4 -6)
如果你想使用其他的CPU(例如ARM,MIPS,PowerPC,...)来代替x86,当然你必须使用其他的寄存器。大多数CPU没有
lodsb
或stosb
的等价物,但是你必须使用两条指令:加载一个字节并递增寄存器。