Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Assembly 汇编64位NASM_Assembly_64 Bit_Nasm - Fatal编程技术网

Assembly 汇编64位NASM

Assembly 汇编64位NASM,assembly,64-bit,nasm,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'

我在做一个项目。在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
还有别的办法吗


谢谢。

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

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


根据x86-64调用约定,varags函数(和
printf
是一个)期望用于传递
AL
的sse寄存器的数量。长话短说,在调用printf之前,您需要将
AL
归零。没有注意到他也把它弄糟了,因为第一个
printf
正确地使用了寄存器,但我后来看到他使用了堆栈。。。顺便说一句,第一次调用也将
al
归零。