【发布时间】:2017-08-29 06:47:03
【问题描述】:
我正在尝试学习 x64 汇编程序。我写了“hello world”并尝试使用以下代码调用 printf:
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 吗?显然我缺少一些基本的东西。
感谢您的帮助!
附言非常欢迎参考优秀的 x64 汇编器教程 :-) 找不到。
【问题讨论】:
-
rax是不稳定的。printf使用rcx加载字符串,所以在我的理解中,这只是你错误的调用约定。很好的解释here -
因为 x64 printf 的第一个参数进入 rcx,而不是 rax。
-
查看x86 tag wiki 获取文档和教程的链接。由于您使用的是 Windows,software.intel.com/en-us/articles/introduction-to-x64-assembly 可能是一个不错的选择。
-
与问题无关,但在我看来,您可以使用
lea将offset hello_msg加载到 RCX 中,而不是使用 RAX 作为一个中间步骤。
标签: windows assembly x86-64 calling-convention