组装 64 位 NASM [英] Assembly 64-bit NASM

查看:17
本文介绍了组装 64 位 NASM的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am doing a proj. in 64-bit NASM. I have to convert decimal to binary and binary to decimal.

当我调用 printf 时,我在调试后不断收到分段错误.

I keep getting segmentation fault after debugging when i call 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

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

Is there a any other way to get around it?

谢谢.

推荐答案

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

As Jester pointed out, if the vararg function is not using sse, then al must be zero. There is a bigger issue here:

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

With the x86-64 calling convention, parameters are not passed on the stack as they are for 32bit, but instead passed through registers. Which registers all depend on what OS your program is written for.

x86 调用约定

这篇关于组装 64 位 NASM的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆