2016-05-04 10 views
0

Я пытаюсь написать функцию для копирования нуля строки завершающейся на другую строку, включая завершающую 0.Копировать ноль строки завершающейся включая завершение-в x86Assembly (MASM)

После того как я называю stringCopy (str1, str2); Выход должен быть Good-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

Выход должен быть Good-bye0ld0 но Прощайте :(что мне не хватает?

IIUC, вам не хватает на то, что C/C++ обработка строк функ останавливаются при первом встреченном нулевом байте (вот почему строки называются «нулевыми»). Таким образом, после копирования всей строки 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;