Author Topic: Nasm 64 bit  (Read 6104 times)

Offline rockstar

  • New Member
  • Posts: 1
Nasm 64 bit
« on: March 05, 2015, 03:59:04 PM »
Hello
I am programming in NASM 64bit Assembly. I am doing a project on converting decimal to binary and binary to decimal.
I having trouble with the call printf and converting decimal to binary.

Code: [Select]
; Convert Decimal to Binary

extern printf

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

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 rsi, 46
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



; Convert Binary to Decimal


section .data
fmtd:    db      "%d.",0
fmtd2:   db      "%d",10,0

section .text

;convert binary integer portion to decimal
mov rax, 0 ; clear accumulator
mov rdx, 0 ; clear for bin storage


mov rdx, [bin1]
shld ax, dx, 11 ; shift binary value into rax
        mov     qword [binsave], rax ; end of "C" string
        push    qword [binsave]   ; string to print
        push    qword fmtd      ; "%d."
        call    printf
        add     rsp,8


; convert binary fraction to decimal
mov rbx, 0

mov rdx, [bin1]
shl rdx, 11
shld bx, dx, 5 ; shift fractional portion into bl

mov rdx, 0 ; accumulator
mov al, 1 ; quotient
shl bx, 3 ; place 5 digits at end of bl
mov ch, 0 ; our count


loop5:
cmp ch, 4 ; check to see that we've done all 5 digits
je save3 ; finished
mov cl, 2 ; base to convert from1
mov bh, 0 ; clear bh
imul  cl ; multiply to get divisor in (1/32, 1/16,1/8,etc)
shl     bx, 1 ; place single digit in bh
cmp bh, 1 ; if if fractional digit is a 1 accumlate value
jne loop5

push rcx ; store rcx (loop counter and base)
push rax ; store rax (divisor)
mov al, 1 ; dividen
pop rcx ; restore divisor for use
push rcx ; save it again for rax
push rdx ; idiv will destroy rdx
mov rdx, 0 ; set quotient

break1:
idiv cl

pop rdx ; restore rdx
add dx, ax
pop rax ; restore rax
pop rcx ; restore rcx
inc ch
jmp loop5

save3:

        push    qword rdx     ; string to print
        push    qword fmtd2      ;
        call    printf
        add     rsp,8

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

        pop     rbp
mov rax,0
        ret                     ; return


Any suggestions would be helpful.
Thank You

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: Nasm 64 bit
« Reply #1 on: March 05, 2015, 09:48:18 PM »
Hi rockstar,

I'm not very familiar with 64-bit code, but it looks like you're doing a proper 64-bit call to printf once - parameters in rdi, rsi, rdx..., number of float parameters in rax, but then you switch to a 32-bit style call - pushing parameters on the stack. I don't think that's going to work. Perhaps if you fix that, you can see what else (if anything) is wrong.

Best,
Frank