2016-05-04 73 views
0

我試圖寫用於複製零終止的字符串終止0複印零包括x86Assembly(MASM)終止0結尾的字符串

後我請stringCopy(STR1,STR2)另一個字符串包括函數;輸出應該好,bye0ld0再見 :(我錯過什麼? 如何打印正確的結果?

;------------------ 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 
+2

爲什麼不簡化成一個循環,以便同時複製和查找終止0?這是實現'strcpy(3)'的「正常」方式。另外,MASM不會讓你在'push' /'call'之後修復堆棧嗎? 'getStringLength'返回'ret',而不是'ret 4',所以它不會將操作數彈出堆棧。無論如何,**在調試器**中逐步完成,或者查看反彙編輸出以查看MASM指令產生的代碼。 –

回答

1

輸出應該好,bye0ld0再見 :(我錯過什麼?

IIUC,你缺少的事實,C/C++字符串處理FUNC tions在第一個遇到的空字節停止(這就是爲什麼字符串被稱爲「零終止」)。因此,在將整個str2字符串複製到str1之後,標準C++ lib將打印它的8個首字節。

如何打印正確的結果?

這是正確的結果。如果您希望打印空字節或初始str1內容的字符數,則可以在初始長度str1上循環一次以使用cout << str1[counter]來放置一個字符。您可能會看到一些對應於空字節的微笑或空白字符。

int l = sizeof(str1); 
for(int i=0; i<l; i++){ 
    cout << str1[i]; 
} 
cout << endl;