为什么在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汇编程序教程的引用不止是欢迎:-)找不到一个。
答
Windows 64-bit (x64/AMD64) calling convention在RCX,RDX,R8和R9中通过the first four integer arguments。
返回值存储在RAX中,它是易失性的,因此C/C++编译器可以将它用作函数中的通用存储。
'rax'是易变的。 'printf'使用'rcx'来加载字符串,所以在我的理解中,这只是您错误的调用约定。很好的解释[here](http://masm32.com/board/index.php?topic=3101.0) –
因为x64 printf的第一个参数在rcx中,而不是rax。 –
有关文档和教程的链接,请参见[x86标记wiki](https://stackoverflow.com/tags/x86/info)。由于您使用的是Windows,因此https://software.intel.com/zh-cn/articles/introduction-to-x64-assembly可能是一个不错的选择。 –