装配64位NASM

时间:2015-02-28 13:35:43

标签: assembly 64-bit nasm

我正在做一个项目。在64位NASM中。我必须将十进制转换为二进制,二进制转换为十进制。

调用printf后,我在调试后不断出现分段错误。

    extern printf

section .bss
decsave:    resd    2   ; stores dec->bin conversion
binsave:    resd    1  

section .data       ; preset constants, writeable
dec1:    db '1','2','4','.','3','7','5',0
bin1:    dq  01010110110101B ; 10101101.10101 note where binary point should be
ten:     dq     10
debug:  db "debug 124 is %ld", 10, 0

section .text       ; instructions, code segment
    global   main       ; for gcc standard linking
main:               ; label
    push    rbp             ; save rbp

;parse and convert integer portion of dec->bin     
        mov     rax,0       ; accumulate value here
        mov     al,[dec1]   ; get first ASCII digit
        sub     al,48       ; convert ASCII digit to binary
        mov     rbx,0           ; clear register (upper part)
        mov     bl,[dec1+1]     ; get next ASCII digit
        sub     rbx,48          ; convert ASCII digit to binary
        imul    rax,10          ; ignore rdx
        add     rax,rbx         ; increment accumulator
    mov rbx,0
    mov bl,[dec1+2]
    sub rbx,48
    imul    rax,10
    add rax,rbx
    mov [decsave],rax   ; save decimal portion

        mov rdi, debug
    mov rsi, [decsave]
    mov rax,0
    call    printf  

    ; return using c-style pops to return stack to correct position 
; and registers to correct content

        pop     rbp
    mov rax,0       
        ret                     ; return





; print the bits in decsave:
        section .bss
abits:  resb    17              ; 16 characters & zero terminator

    section .data
fmts:   db      "%s",0


section .text
; shift decimal portion into abits as ascii
        mov     rax,[decsave]   ; restore rax to dec. portion
        mov     rcx,8           ; for printing 1st 8 bits
loop3: mov     rdx,0           ; clear rdx ready for a bit
        shld    rdx,rax,1       ; top bit of rax into rdx
        add     rdx,48          ; make it ASCII
        mov     [abits+rcx-1],dl ; store character
        ror     rax,1           ; next bit into top of rax
        loop    loop3          ; decrement rcx, jump non zero

        mov     byte [abits+7],'.' ; end of dec. portion string
        mov     byte [abits+8],0   ; end of "C" string
        push    qword abits     ; string to print
        push    qword fmts      ; "%s"
        call    printf
        add     rsp,8

    mov     rax,[decsave+16]     ; increment to fractional portion
    mov     rcx,16       ; for printing 3 bits as required in the directions


loop4: mov     rdx,0           ; clear rdx ready for a bit
        shld    rdx,rax,1       ; top bit of rax into rdx
        add     rdx,48          ; make it ASCII
        mov     [abits+rcx-1],dl ; store character
        ror     rax,1           ; next bit into top of rax
        loop    loop4          ; decrement rcx, jump non zero

        mov     byte [abits+3],10 ; end of "C" string at 3 places
        mov     byte [abits+4],0 ; end of "C" string
        push    qword abits     ; string to print
        push    qword fmts      ; "%s"
        call    printf
        add     rsp,8

有没有其他方法可以绕过它?

谢谢。

1 个答案:

答案 0 :(得分:2)

正如Jester所指出的,如果vararg函数不使用sse,那么al必须为零。这里有一个更大的问题:

使用x86-64调用约定,参数不会像32位那样在堆栈上传递,而是通过寄存器传递。哪些寄存器都取决于您的程序编写的操作系统。

x86 calling conventions