简体   繁体   中英

Windows ASM printf with float

I have been trying to interface with the standard C library in Windows in assembler and I'm having trouble. For some reason, I can't make printf accept floating point variables, so something is wrong here.

This is the shortest program I can create that demonstrates the problem. I've included comments that explain my understanding of what is supposed to be happening.

Thanks

;
; Hello64.asm
; A simple program to print a floating point number in windows
;
; assemble: nasm float64.asm -f win64
; link: golink /console /entry main float64.obj MSVCRT.dll
;

; tell assembler to generate 64-bit code
;
bits 64

; data segment
section .data use64

pi  dq 3.14159

textformat: db "hello, %lf!",0x0a, 0x00     ; friendly greeting

; set up the .text segment for the code
section .text use64

; global main is the entry point
global main
; note that there is no _ before printf here, unlike in OS X
extern printf

main:
mov rcx, textformat 
movq xmm0, qword [pi]
mov rax, 1      ; need to tell printf how many floats
call printf

; note next step - this puts a zero in rax
xor rax,rax
ret ; this returns to the OS based on how Windows calls programs.
; this return causes a delay then the program exits.

You managed to mix the microsoft and the sysv convention. The correct way is:

mov rcx, textformat 
movq xmm1, qword [pi]
movq rdx, xmm1  ; duplicate into the integer register
sub rsp, 40     ; allocate shadow space and alignment (32+8)
call printf
add rsp, 40     ; restore stack
xor eax, eax
ret

According to MSDN , when using varargs:

For floating-point values only, both the integer and the floating-point register will contain the float value in case the callee expects the value in the integer registers.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM