如何在 x86 程序集 (MASM) 中复制以零结尾的字符串,包括以 0 结尾的字符串?
How to copy zero terminated string including terminating 0 in x86 Assembly (MASM)?
我正在尝试编写一个函数,用于将以零结尾的字符串复制到另一个包括以 0 结尾的字符串。
在我调用 stringCopy(str1, str2); 之后输出应该是 Good-bye0ld0 但是 Good -再见 :(我错过了什么?
如何打印正确的结果?
;------------------ in my .cpp file
extern "C" void __stdcall stringCopy(char[], char[]);
int main()
{
char str1[] = { 'h','e','l','l','o',' ','w','o','r','l','d',0 };
cout << str1 << endl;
char str2[] = { 'G','o','o','d','-','b','y','e',0};
cout << str2 << endl;
stringCopy(str1, str2);
cout << str1 << endl; ;should be Good-bye0ld0
;but is Good-bye
}
;------------------ in my .asm file
; Copy zero terminated string2 (including terminating 0)
stringCopy PROC uses ecx eax esi edi, ;save registers used
string1:DWORD, ;address of string1
string2:DWORD ;address of string2
cld ;forward direction - clear direction flag
push string2 ;address of str2 arg to StrlenAsm
call getStringLength ;get length of str2
;called function responsible for stack cleanup
mov ecx,eax ;length of string in ecx for rep
mov edi,string1 ;edi gets destination address for copy
mov esi,string2 ;esi gets source address for copy
rep movsb ;copy byte from source to desintation ecx times
mov byte ptr[edi],0 ;null terminate copied string
ret
stringCopy ENDP
getStringLength PROC uses edi, ;save edi
strAdd:DWORD ;address of string to find length of
mov edi, strAdd ;edi = address of string to get length of
xor eax,eax ;eax to hold length so 0 it out
looptop:
cmp byte ptr [edi],0 ;have we reached the end of the string yet?
je done ;Yes, done
inc edi ;no, increment to next character
inc eax ;and increment length
jmp looptop ;repeat
done:
ret
getStringLength ENDP
The output should be Good-bye0ld0 but is Good-bye :( what am I missing ?
IIUC,您忽略了 C/C++ 字符串处理函数在遇到第一个空字节时停止的事实(这就是字符串被称为 "zero-terminated" 的原因)。因此在将整个 str2
字符串复制到 str1
之后,标准 C++ 库将打印它的前 8 个字节。
How to print the correct result?
这是正确的结果。如果您希望打印空字节或初始 str1
内容的字符数,您可以在 str1
的初始长度上循环使用 [=15 一次放置一个字符=].您可能会看到一些与空字节相对应的微笑或空字符。
int l = sizeof(str1);
for(int i=0; i<l; i++){
cout << str1[i];
}
cout << endl;
我正在尝试编写一个函数,用于将以零结尾的字符串复制到另一个包括以 0 结尾的字符串。
在我调用 stringCopy(str1, str2); 之后输出应该是 Good-bye0ld0 但是 Good -再见 :(我错过了什么? 如何打印正确的结果?
;------------------ in my .cpp file
extern "C" void __stdcall stringCopy(char[], char[]);
int main()
{
char str1[] = { 'h','e','l','l','o',' ','w','o','r','l','d',0 };
cout << str1 << endl;
char str2[] = { 'G','o','o','d','-','b','y','e',0};
cout << str2 << endl;
stringCopy(str1, str2);
cout << str1 << endl; ;should be Good-bye0ld0
;but is Good-bye
}
;------------------ in my .asm file
; Copy zero terminated string2 (including terminating 0)
stringCopy PROC uses ecx eax esi edi, ;save registers used
string1:DWORD, ;address of string1
string2:DWORD ;address of string2
cld ;forward direction - clear direction flag
push string2 ;address of str2 arg to StrlenAsm
call getStringLength ;get length of str2
;called function responsible for stack cleanup
mov ecx,eax ;length of string in ecx for rep
mov edi,string1 ;edi gets destination address for copy
mov esi,string2 ;esi gets source address for copy
rep movsb ;copy byte from source to desintation ecx times
mov byte ptr[edi],0 ;null terminate copied string
ret
stringCopy ENDP
getStringLength PROC uses edi, ;save edi
strAdd:DWORD ;address of string to find length of
mov edi, strAdd ;edi = address of string to get length of
xor eax,eax ;eax to hold length so 0 it out
looptop:
cmp byte ptr [edi],0 ;have we reached the end of the string yet?
je done ;Yes, done
inc edi ;no, increment to next character
inc eax ;and increment length
jmp looptop ;repeat
done:
ret
getStringLength ENDP
The output should be Good-bye0ld0 but is Good-bye :( what am I missing ?
IIUC,您忽略了 C/C++ 字符串处理函数在遇到第一个空字节时停止的事实(这就是字符串被称为 "zero-terminated" 的原因)。因此在将整个 str2
字符串复制到 str1
之后,标准 C++ 库将打印它的前 8 个字节。
How to print the correct result?
这是正确的结果。如果您希望打印空字节或初始 str1
内容的字符数,您可以在 str1
的初始长度上循环使用 [=15 一次放置一个字符=].您可能会看到一些与空字节相对应的微笑或空字符。
int l = sizeof(str1);
for(int i=0; i<l; i++){
cout << str1[i];
}
cout << endl;