用C调用汇编代码,输出错误

标签 c string assembly

我正在开发一个 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 个方 block ,每个角都有数字)。什么会导致这种情况?

最佳答案

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:

关于用C调用汇编代码,输出错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16412938/

相关文章:

css - 从 'GtkButton' 到 'GtkEntry' 的无效转换

c - 为什么我的 C 程序崩溃?

javascript - Javascript 中的字符串格式?

objective-c - 使用 stringWithContentsOfFile 打开通知中心 plist 时出现文本编码错误 :encoding:error:

java - 如何将解密的 BigInteger 转换回字符串?

javascript - 堆栈如何在其中存储值?

c - 在内存中(在后台)创建结构体时的操作顺序是什么?

c - 分段故障

c++ - 将 DevC++ 移植到 Linux

assembly - 如何在8086汇编中减去两个64位整数