0

我正在尝试在 linux ubuntu 32 位中编译汇编代码。但是当我编译它时,nasm -felf32 assembly.asm && gcc assembly.o && ./a.out 我面对的是Segmentation fault (core dumped). 我知道问题出在 printf 上。

我在网上搜索了很多,有几个这样的问题。但没有一个答案对我有用。

    global  main
    extern  printf

    section .text
    main:
    push    ebx                     ; we have to save this since we use it

    mov     ecx, 90                 ; ecx will countdown to 0
    xor     eax, eax                ; rax will hold the current number
    xor     ebx, ebx                ; rbx will hold the next number
    inc     ebx                     ; rbx is originally 1
    print:
    ; We need to call printf, but we are using rax, rbx, and rcx.  printf
    ; may destroy rax and rcx so we will save these before the call and
    ; restore them afterwards.

    push    eax                     ; caller-save register
    push    ecx                     ; caller-save register

    mov     edi, format             ; set 1st parameter (format)
    mov     esi, eax                ; set 2nd parameter (current_number)
    xor     eax, eax                ; because printf is varargs

    ; Stack is already aligned because we pushed three 8 byte registers
    call    printf                ; printf(format, current_number)

    pop     ecx                     ; restore caller-save register
    pop     eax                     ; restore caller-save register

    mov     edx, eax                ; save the current number
    mov     eax, ebx                ; next number is now current
    add     ebx, edx                ; get the new next number
    dec     ecx                     ; count down
    jnz     print                   ; if not done counting, do some more

    pop     ebx                     ; restore rbx before returning

    ret
    format:
    db  "%20ld", 10, 0

*** 源代码是从Nasm 教程站点复制的。它用于打印斐波那契数。

4

1 回答 1

1

对于所有这些大惊小怪,这个问题太容易了。找到了 64 位的教程,转成 32 位并不像rax改成eax. 以下是调用printf32 位代码的方法。

 print:
    ; We need to call printf, but we are using rax, rbx, and rcx.  printf
    ; may destroy rax and rcx so we will save these before the call and
    ; restore them afterwards.

; comment does not match code!

    push    eax                     ; caller-save register
    push    ecx                     ; caller-save register

    push eax ; (current number)
    push format             ; set 1st parameter (format)
    call    printf                ; printf(format, current_number)
    add esp, 4 * 2 ; "remove" 2 parameters - 4 bytes each

    pop     ecx                     ; restore caller-save register
    pop     eax                     ; restore caller-save register
; etc...

那是未经测试的。只有 32 位,我不认为你会得到完整的 90 个数字。您可能需要更改format字符串。您可以通过使用两个寄存器获得带有 32 位代码的 64 位结果,但是您没有用于该代码的代码...

于 2015-06-18T19:20:46.330 回答