user-0 提问: 求拜各位大佬，我的strcat哪里错了？

回复:
user: user-1
content: 计算机组成原理→DOS命令→汇编语言→C语言（不包括C++）、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言（包括C++）、架构……

user: user-1
content: C:\Program Files (x86)\Windows Kits\10\Source\10.0.10240.0\ucrt\string\amd64\strcat.asm:         title   strcat - concatenate (append) one string to another ;*** ;strcat.asm - contains strcat() and strcpy() routines ; ;       Copyright (c) Microsoft Corporation. All rights reserved. ; ;Purpose: ;       STRCAT concatenates (appends) a copy of the source string to the ;       end of the destination string, returning the destination string. ; ;******************************************************************************* include ksamd64.inc         subttl  "strcat" ;*** ;char *strcat(dst, src) - concatenate (append) one string to another ; ;Purpose: ;       Concatenates src onto the end of dest.  Assumes enough ;       space in dest. ; ;       Algorithm: ;       char * strcat (char * dst, char * src) ;       { ;           char * cp = dst; ; ;           while( *cp ) ;                   ++cp;           /* Find end of dst */ ;           while( *cp++ = *src++ ) ;                   ;               /* Copy src to end of dst */ ;           return( dst ); ;       } ; ;Entry: ;       char *dst - string to which "src" is to be appended ;       const char *src - string to be appended to the end of "dst" ; ;Exit: ;       The address of "dst" in EAX ; ;Uses: ;       EAX, ECX ; ;Exceptions: ; ;*******************************************************************************  ;*** ;char *strcpy(dst, src) - copy one string over another ; ;Purpose: ;       Copies the string src into the spot specified by ;       dest; assumes enough room. ; ;       Algorithm: ;       char * strcpy (char * dst, char * src) ;       { ;           char * cp = dst; ; ;           while( *cp++ = *src++ ) ;                   ;               /* Copy src over dst */ ;           return( dst ); ;       } ; ;Entry: ;       char * dst - string over which "src" is to be copied ;       const char * src - string to be copied over "dst" ; ;Exit: ;       The address of "dst" in EAX ; ;Uses: ;       EAX, ECX ; ;Exceptions: ;*******************************************************************************  public ___entry_from_strcat_in_strcpy LEAF_ENTRY_ARG2 strcat, _TEXT, dst:ptr byte, src:ptr byte      OPTION PROLOGUE:NONE, EPILOGUE:NONE      mov     r11, rcx     test    cl, 7     jz      strcat_loop_begin  strcat_copy_head_loop_begin:     mov     al, [rcx]     test    al, al     jz      ___entry_from_strcat_in_strcpy     inc     rcx     test    cl, 7     jnz     strcat_copy_head_loop_begin  strcat_loop_begin:     mov     rax, [rcx]     mov     r10, rax     mov     r9, 7efefefefefefeffh     add     r9, r10     xor     r10, -1     xor     r10, r9     add     rcx, 8     mov     r9, 8101010101010100h     test    r10, r9     je      strcat_loop_begin     sub     rcx, 8  strcat_loop_end:     test    al, al     jz      ___entry_from_strcat_in_strcpy     inc     rcx     test    ah, ah     jz      ___entry_from_strcat_in_strcpy     inc     rcx     shr     rax, 16     test    al, al     jz      ___entry_from_strcat_in_strcpy     inc     rcx     test    ah, ah     jz      ___entry_from_strcat_in_strcpy     inc     rcx     shr     rax, 16     test    al, al     jz      ___entry_from_strcat_in_strcpy     inc     rcx     test    ah, ah     jz      ___entry_from_strcat_in_strcpy     inc     rcx     shr     eax, 16     test    al, al     jz      ___entry_from_strcat_in_strcpy     inc     rcx     test    ah, ah     jz      ___entry_from_strcat_in_strcpy     inc     rcx     jmp     strcat_loop_begin  LEAF_END strcat, _TEXT  LEAF_ENTRY_ARG2 strcpy, _TEXT, dst:ptr byte, src:ptr byte      OPTION PROLOGUE:NONE, EPILOGUE:NONE      mov     r11, rcx strcat_copy: ___entry_from_strcat_in_strcpy=strcat_copy  ; align the SOURCE so we never page fault  ; dest pointer alignment not important     sub     rcx, rdx ; combine pointers     test    dl, 7     jz      qword_loop_entrance  copy_head_loop_begin:     mov     al, [rdx]     mov     [rdx+rcx], al     test    al, al     jz      byte_exit     inc     rdx     test    dl, 7     jnz     copy_head_loop_begin     jmp     qword_loop_entrance  byte_exit:     mov     rax, r11     ret  qword_loop_begin:     mov     [rdx+rcx], rax     add     rdx, 8 qword_loop_entrance:     mov     rax, [rdx]     mov     r9, 7efefefefefefeffh     add     r9, rax     mov     r10, rax     xor     r10, -1     xor     r10, r9     mov     r9, 8101010101010100h     test    r10, r9     jz      qword_loop_begin  qword_loop_end:     test    al, al     mov     [rdx+rcx], al     jz      strcat_exit     inc     rdx     test    ah, ah     mov     [rdx+rcx], ah     jz      strcat_exit     inc     rdx     shr     rax, 16     test    al, al     mov     [rdx+rcx], al     jz      strcat_exit     inc     rdx     test    ah, ah     mov     [rdx+rcx], ah     jz      strcat_exit     inc     rdx     shr     rax, 16     test    al, al     mov     [rdx+rcx], al     jz      strcat_exit     inc     rdx     test    ah, ah     mov     [rdx+rcx], ah     jz      strcat_exit     inc     rdx     shr     eax, 16     test    al, al     mov     [rdx+rcx], al     jz      strcat_exit     inc     rdx     test    ah, ah     mov     [rdx+rcx], ah     jz      strcat_exit     inc     rdx     jmp     qword_loop_entrance  strcat_exit:     mov     rax, r11     ret  LEAF_END strcpy, _TEXT      end

user: user-1
content: D:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\crt\src\intel\strcat.asm:         page    ,132         title   strcat - concatenate (append) one string to another ;*** ;strcat.asm - contains strcat() and strcpy() routines ; ;       Copyright (c) Microsoft Corporation. All rights reserved. ; ;Purpose: ;       STRCAT concatenates (appends) a copy of the source string to the ;       end of the destination string, returning the destination string. ; ;*******************************************************************************          .xlist         include cruntime.inc         .list   page ;*** ;char *strcat(dst, src) - concatenate (append) one string to another ; ;Purpose: ;       Concatenates src onto the end of dest.  Assumes enough ;       space in dest. ; ;       Algorithm: ;       char * strcat (char * dst, char * src) ;       { ;           char * cp = dst; ; ;           while( *cp ) ;                   ++cp;           /* Find end of dst */ ;           while( *cp++ = *src++ ) ;                   ;               /* Copy src to end of dst */ ;           return( dst ); ;       } ; ;Entry: ;       char *dst - string to which "src" is to be appended ;       const char *src - string to be appended to the end of "dst" ; ;Exit: ;       The address of "dst" in EAX ; ;Uses: ;       EAX, ECX ; ;Exceptions: ; ;*******************************************************************************  page ;*** ;char *strcpy(dst, src) - copy one string over another ; ;Purpose: ;       Copies the string src into the spot specified by ;       dest; assumes enough room. ; ;       Algorithm: ;       char * strcpy (char * dst, char * src) ;       { ;           char * cp = dst; ; ;           while( *cp++ = *src++ ) ;                   ;               /* Copy src over dst */ ;           return( dst ); ;       } ; ;Entry: ;       char * dst - string over which "src" is to be copied ;       const char * src - string to be copied over "dst" ; ;Exit: ;       The address of "dst" in EAX ; ;Uses: ;       EAX, ECX ; ;Exceptions: ;*******************************************************************************           CODESEG  %       public  strcat, strcpy      ; make both functions available strcpy  proc \         dst:ptr byte, \         src:ptr byte          OPTION PROLOGUE:NONE, EPILOGUE:NONE          push    edi                 ; preserve edi         mov     edi,[esp+8]         ; edi points to dest string         jmp     short copy_start  strcpy  endp          align   16  strcat  proc \         dst:ptr byte, \         src:ptr byte          OPTION PROLOGUE:NONE, EPILOGUE:NONE          .FPO    ( 0, 2, 0, 0, 0, 0 )          mov     ecx,[esp+4]         ; ecx -> dest string         push    edi                 ; preserve edi         test    ecx,3               ; test if string is aligned on 32 bits         je      short find_end_of_dest_string_loop  dest_misaligned:                    ; simple byte loop until string is aligned         mov     al,byte ptr [ecx]         add     ecx,1         test    al,al         je      short start_byte_3         test    ecx,3         jne     short dest_misaligned          align   4  find_end_of_dest_string_loop:         mov     eax,dword ptr [ecx] ; read 4 bytes         mov     edx,7efefeffh         add     edx,eax         xor     eax,-1         xor     eax,edx         add     ecx,4         test    eax,81010100h         je      short find_end_of_dest_string_loop         ; found zero byte in the loop         mov     eax,[ecx - 4]         test    al,al               ; is it byte 0         je      short start_byte_0         test    ah,ah               ; is it byte 1         je      short start_byte_1         test    eax,00ff0000h       ; is it byte 2         je      short start_byte_2         test    eax,0ff000000h      ; is it byte 3         je      short start_byte_3         jmp     short find_end_of_dest_string_loop                                     ; taken if bits 24-30 are clear and bit                                     ; 31 is set start_byte_3:         lea     edi,[ecx - 1]         jmp     short copy_start start_byte_2:         lea     edi,[ecx - 2]         jmp     short copy_start start_byte_1:         lea     edi,[ecx - 3]         jmp     short copy_start start_byte_0:         lea     edi,[ecx - 4] ;       jmp     short copy_start  ;       edi points to the end of dest string. copy_start::         mov     ecx,[esp+0ch]       ; ecx -> sorc string         test    ecx,3               ; test if string is aligned on 32 bits         je      short main_loop_entrance  src_misaligned:                     ; simple byte loop until string is aligned         mov     dl,byte ptr [ecx]         add     ecx,1         test    dl,dl         je      short byte_0         mov     [edi],dl         add     edi,1         test    ecx,3         jne     short src_misaligned         jmp     short main_loop_entrance  main_loop:                          ; edx contains first dword of sorc string         mov     [edi],edx           ; store one more dword         add     edi,4               ; kick dest pointer main_loop_entrance:         mov     edx,7efefeffh         mov     eax,dword ptr [ecx] ; read 4 bytes          add     edx,eax         xor     eax,-1          xor     eax,edx         mov     edx,[ecx]           ; it's in cache now          add     ecx,4               ; kick dest pointer         test    eax,81010100h          je      short main_loop         ; found zero byte in the loop ; main_loop_end:         test    dl,dl               ; is it byte 0         je      short byte_0         test    dh,dh               ; is it byte 1         je      short byte_1         test    edx,00ff0000h       ; is it byte 2         je      short byte_2         test    edx,0ff000000h      ; is it byte 3         je      short byte_3         jmp     short main_loop     ; taken if bits 24-30 are clear and bit                                     ; 31 is set byte_3:         mov     [edi],edx         mov     eax,[esp+8]         ; return in eax pointer to dest string         pop     edi         ret byte_2:         mov     [edi],dx         mov     eax,[esp+8]         ; return in eax pointer to dest string         mov     byte ptr [edi+2],0         pop     edi         ret byte_1:         mov     [edi],dx         mov     eax,[esp+8]         ; return in eax pointer to dest string         pop     edi         ret byte_0:         mov     [edi],dl         mov     eax,[esp+8]         ; return in eax pointer to dest string         pop     edi         ret  strcat  endp          end

user: user-2
content: 建议不要玩这些操作优先级之类的游戏，把代码写的明白清楚一点，这样不容易出错，别人也能看得明白 char *mystrcat(char*dest，const char* str) {        char * ret=dest；        while(*dest)dest++；        while((*dest=*str))dest++, str++；// 多加一重括号表示里面是一个逻辑表达式        return  ret； }

user: user-3
content: char *mystrcat(char*dest，const char* str) {        char * ret=dest；        while(*dest++)；         dest--;    //经过循环之后，dest指向了'\0'的下一个字符，所以这条语句就是让他指向'\0'，以便后面的while把'\0'覆盖；        while(*dest++=*str++)；        return  ret； }  加一条语句； dest--;    //经过循环之后，dest指向了'\0'的下一个字符，所以这条语句就是让他指向'\0'，以便后面的while把'\0'覆盖；