如何在 MASM x86 中连接字符串?

How do I concatenate strings in MASM x86?

我花了最后 3 个小时尝试完成这个程序。

32位。

我环顾四周并阅读了分配给我 class 的书,但我找不到适合我的案例的字符串连接的好信息。

StrCatAsm 过程在应该打印时一直将“Pat”打印到输出文本文件 'hello Pat'。

这些 asm 函数是从 C++ 文件中调用的。

string1Add 包含 char str7[MAX_SIZE] = {'h','e','l','l','o',0,'@','@','@','@','@','@','@','@','@',0};

string2Add 包含 char str8[MAX_SIZE] = {' ','P','a','t',0,'@','@','@','@','@','@','@','@','@',0};

这是为 class 提供此功能的编程公会:

    ;--------------------------------------------
;StrCatAsm - append  0 terminated string2 to  0 terminated string1
;   entry: str1Add contains the address of string1
;          str2Add contains the address of string2
;   exit:  NONE
;   note: StrCatAsm puts in terminating 0
;
;   example: char str1[] = {'h','e','l','l','o',0};
;            char str2[] = {'w','o','r','l','d',0};
;   after StrCatAsm(str1,str2) 
;            string1 = 'h','e','l','l','o','w','o','r','l','d',0
;
;  The above is how you would call StrCatAsm from C++.
;
;  To call StrCatAsm from another asm function use:
;
;   To call StrCatAsm from an asm function use:
;       
;       push str2Add ;address of string 2
;       push str1Add ;address of string 1
;       call StrCatAsm
;       ;no add esp, 8 needed because stack cleaup automatically done

;
; Do not use a loop in this function. 
; Do not call StrLenAsm in this function.

; StrCatAsm should zero terminate the concatenated string which is done by StrCpyAsm
; when you call it to copy str2 to the end of str1.
;
; Choose 2 instructions from the following string instructions to use:
; rep, repe, repne, movsb,stosb,cmpsb,scasb
;
;populate ecx with MAX_LEN defined at the top of this file
;get to the end of str1 using two string instructions
;then call StrCpyAsm to copy str2 to end of str1.
;
;   Note: the parameters below (str1Add and str2Add) contain the address of the 
;         strings you want to work with. To transfer those addesses to a register
;         just use mov reg, str1Add 
;         Do not use mov reg, offset str1Add and 
;         do not use lea reg, str1Add

这是我到目前为止的工作。 Max len 在文件顶部定义为:MAX_LEN EQU 0FFFFFFFFh

StrCatAsm PROC  uses eax edi ecx esi  ,  ;save registers used
                str1Add:DWORD,  ;address of string1
                str2Add:DWORD   ;address of string2

mov edi, str1Add
;mov esi, str2Add

;Student code here( you may change or delete any of the above 2 lines of code for efficiency if necessary)
;If you use the above 2 lines, you  must comment them
mov ecx, MAX_LEN                ;Move max len to ecx.
mov al, 'h'
cld 
repne scasb
jnz quit
dec edi

push str2Add                        ;address of string 2
push str1Add                    ;address of string 1
call StrCpyAsm                  ;Call StrCpyAsm to copy the strings together.

quit:
    ret                             ;return to caller

StrCatAsm ENDP

我做错了什么?

push str1Add                    ;address of string 1

应该是

push edi                        ;address of string 1

因为你想推送你修改的指针而不是你传递的原始指针

What am I doing wrong here?

  • 为了找出第二个字符串需要将其自身附加到第一个字符串的位置,您需要扫描第一个字符串的终止零。您的代码目前错误地扫描 'h' 字符。这需要变成 mov al, 0.

  • StrCpyAsm 的第一个参数不是第一个字符串的开头而是结尾(您发现终止零的位置)。 repne scasb指令后,EDI-1就是这个地址。

mov edi, str1Add   ; Address of START of string 1
mov ecx, MAX_LEN
mov al, 0
cld 
repne scasb
dec edi

push str2Add       ; Address of START of string 2
push edi           ; Address of END of string 1
call StrCpyAsm     ; Call StrCpyAsm to copy the strings together.

您不需要 jnz quit 因为 ECX 寄存器中有如此巨大的 (0FFFFFFFFh) 重复计数,几乎不可能不遇到零字节!

Choose 2 instructions from the following string instructions to use:

从技术上讲 repne scasb,您选择了 1 个 字符串指令 和一个附带的 指令前缀 repne 本身不是指令。