【发布时间】:2016-06-26 21:34:04
【问题描述】:
我一直在尝试在汇编程序中与 Windows 中的标准 C 库进行交互,但遇到了麻烦。由于某种原因,我无法让 printf 接受浮点变量,所以这里出了点问题。
这是我可以创建的最短的程序来演示该问题。我已经包含了解释我对应该发生的事情的理解的 cmets。
谢谢
;
; 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.
【问题讨论】:
-
原谅我的无知,但是
osx和这有什么关系? -
对不起-该评论是给我的。在带有 NASM 的 OS X 中,您需要在 clib 函数名称的名称前放置一个 _,以便链接器正确链接它们。
-
我很确定
printf要求运行时已初始化,而您没有这样做。 -
@RaymondChen,你将如何初始化运行时? Jester 提供的代码按照编写的方式工作,我已经用文本完成了“hello world”,没有任何额外的步骤来初始化运行时。
-
哦,是的,很好看,@Raymond。他的链接器命令将入口点设置为
main,而不是让CRT 启动代码调用main。在 Linux 上,如果您想编写“裸”可执行文件,只需编写_start而不是main。即使没有 crt 启动代码,glibc 之类的 printf 和 malloc 也可以工作,至少在我完成的少量测试中是这样。
标签: windows assembly nasm x86-64 calling-convention