0

我正在使用 C 语言编写一个程序,该程序接收一个字符串并通过调用用汇编编写的函数打印出相同的字符串。

我的 C 代码是:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

// These functions will be implemented in assembly:
//
void strrev(char *str) ;

int main(){
    char *str1;
    str1 = strdup("Hello World");
    strrev(str1);
    printf("str1 reversed: \"%s\"\n", str1) ;
    free(str1);
    return 0;
}

我的 .asm 文件是:

; File: strrev.asm
; A subroutine called from C programs.
; Parameters: string A
; Result: String is reversed and returned.


    SECTION .text
    global strrev
_strrev: nop
strrev:
    push    ebp
    mov ebp, esp

    ; registers ebx,esi, and edi must be saved if used
    push ebx
    push edi

    xor esi, esi    
    xor eax, eax
    mov ecx, [ebp+8]    ; load the start of the array into ecx
    jecxz   end     ; jump if [ecx] is zero
    ;mov    edi, ecx


mainLoop:
    add     eax, 1  ;inc eax would work as well
    add ecx, 1  
    mov dl, [ecx]
    cmp     dl, 0   ; compare current ecx with 0
    je  reverseLoop ;if ecx is 0, we are done
    jmp mainLoop    ;if ecx isnt 0, keep looping

reverseLoop:
    mov     ecx, [ebp+8]    ;reload the start of the arrary into ecx
    mov esi, ecx    ; esi poinst to start of array
    add ecx, eax
    mov edi, ecx
    dec edi     ;edi points to end of array
    shr eax, 1      ;eax is the count
    jz  end     ;if string is 0 or 1 chars long, jump to end

reverseLoop_1:

    mov cl, [esi]   ;load start of array into cl
    mov bl, [edi]   ;load end of array into bl
    mov [esi], bl   ;swap
    mov [edi], al   
    inc esi
    dec edi
    dec eax     ;loop
    jnz reverseLoop_1

end:
    pop     edi     ;restore registers
    pop     ebx         
    mov esp, ebp    ;take down stack frame
    pop ebp
    ret

程序运行成功,但输出为:

str1 reversed: "dlroW "

在第一个单词之后,第二部分“Hello”被打印为字节(5 个正方形,每个角都有数字)。什么会导致这个?

4

3 回答 3

1
reverseLoop:
    mov     ecx, [ebp+8]    ;reload the start of the arrary into ecx
    mov esi, ecx    ; esi points to start of array
    add ecx, eax    ;
    mov edi, ecx    ;
    dec edi         ;edi points to end of array
    shr eax, 1      ;eax is the count
    jz  end         ;if string is 0 or 1 chars long, jump to end

reverseLoop_1:
    mov cl, [esi]   ;load start of array into cl
    mov bl, [edi]   ;load end of array into bl
    mov [esi], bl   ;swap
    mov [edi], al   ; AL?!? Should it not be CL?
    inc esi         ;
    dec edi         ; 
    dec eax         ;loop
    jnz reverseLoop_1

在上面,您在 CL 中读取,然后存储 AL。

我会这样做,并且完全不检查 eax:

    mov edi, ecx    ;
    dec edi         ;edi points to end of array
reverseLoop_1:
    cmp esi, edi    ; when esi >= edi we're done.
    jae finished    ; 
    mov cl, [esi]   ;load start of array into cl
    mov bl, [edi]   ;load end of array into bl
    mov [esi], bl   ;swap
    mov [edi], cl   ;
    inc esi         ;
    dec edi         ;
    jmp reverseLoop_1
 finished:
于 2013-05-07T07:07:10.050 回答
1

你给了

mov [edi], al 

代替

mov [edi], cl 

reverseLoop_1

于 2013-05-07T07:07:13.070 回答
0

shr eax, 1 ;eax is the count应该是sub ...?即减1,而不是除以2。

于 2013-05-07T07:05:05.407 回答