为什么在x64汇编器中调用printf时需要“mov rcx,rax”?

问题描述:

我在学习x64汇编器。我写的“Hello World”,并试图printf的使用下面的代码来调用:为什么在x64汇编器中调用printf时需要“mov rcx,rax”?

EXTERN printf: PROC 

PUBLIC hello_world_asm 

.data 
hello_msg db "Hello world", 0 


.code 
hello_world_asm PROC 
push rbp ; save frame pointer 
mov rbp, rsp ; fix stack pointer 
sub rsp, 8 * (4 + 2) ; shadow space (32bytes) 

lea rax, offset hello_msg 
mov rcx, rax ; <---- QUESTION ABOUT THIS LINE 
call printf 

; epilog. restore stack pointer 
mov rsp, rbp 
pop rbp 
ret 
hello_world_asm ENDP 


END 

在我打电话的printf没有“MOV RCX,RAX”开始,结束了访问冲突。让我感到沮丧的是,我刚刚用C++写了一个printf调用,并在反汇编器中查看。在那里,我看到了“mov rcx,rax”这一行,它固定了一切,但为什么我需要将RAX移动到RCX吗?显然我错过了一些基本的东西。

感谢您的帮助!

p.s.对良好的x64汇编程序教程的引用不止是欢迎:-)找不到一个。

+0

'rax'是易变的。 'printf'使用'rcx'来加载字符串,所以在我的理解中,这只是您错误的调用约定。很好的解释[here](http://masm32.com/board/index.php?topic=3101.0) –

+1

因为x64 printf的第一个参数在rcx中,而不是rax。 –

+0

有关文档和教程的链接,请参见[x86标记wiki](https://stackoverflow.com/tags/x86/info)。由于您使用的是Windows,因此https://software.intel.com/zh-cn/articles/introduction-to-x64-assembly可能是一个不错的选择。 –

Windows 64-bit (x64/AMD64) calling convention在RCX,RDX,R8和R9中通过the first four integer arguments

返回值存储在RAX中,它是易失性的,因此C/C++编译器可以将它用作函数中的通用存储。