在64位NASM中,我正在使用C库中的malloc()分配一个8000字节的内存块,完成后通过调用free()来释放它。
我的研究得出了很多关于如何在64位NASM中做到这一点的相互冲突的信息,其中很多信息是32位的,调用约定不同,或者是C或C++,而不是NASM。
我认为我已经正确地处理了malloc部分,但我对free部分不确定。我发布这个问题是因为我不想测试它并且分配一个未被释放的内存块。
所以我的两个问题很简单: (1) 我在64位NASM中做对了吗? (2) 语法对于Windows和Linux是相同的吗?
我只显示了程序中malloc和free部分的代码:
我的研究得出了很多关于如何在64位NASM中做到这一点的相互冲突的信息,其中很多信息是32位的,调用约定不同,或者是C或C++,而不是NASM。
我认为我已经正确地处理了malloc部分,但我对free部分不确定。我发布这个问题是因为我不想测试它并且分配一个未被释放的内存块。
所以我的两个问题很简单: (1) 我在64位NASM中做对了吗? (2) 语法对于Windows和Linux是相同的吗?
我只显示了程序中malloc和free部分的代码:
extern malloc
extern free
push rdi
; Allocate the memory buffer
mov rdi,8000
call malloc
mov [array_pointer],rax ;array_pointer is initialized in .data
; Code that uses the buffer goes here.
; Free the memory buffer
push rdi
call free
add rsp,8
pop rdi
ret
malloc
函数会把指向内存块的指针返回到_RAX_寄存器。你需要将_RAX_中的值移动到_RDI_寄存器中(或者将array_pointer
储存的地址移动到_RDI_中),以便释放这块内存(因为遵循64位System V ABI协议的所有函数都是通过_RDI_来传递第一个参数)。在调用free
函数时,不需要使用push rdi
和add rsp, 8
。这样会破坏堆栈的对齐方式。 - Michael Petchfree
函数只需要一个参数(指针),没有返回值。malloc
函数需要一个参数(字节大小),并返回一个指针(在_RAX_寄存器中)。C标准库的索引在cpp reference中可以找到,链接是:http://en.cppreference.com/w/c。 - Michael Petchmalloc
返回一个16字节对齐的地址,因此如果您使用需要在该指针上进行对齐访问的指令(例如SSE),则不会失败。但是,在调用malloc
和free
(以及任何其他遵守Windows 64位调用约定的函数)之前,仍需确保栈是16字节对齐的,因为这些函数可能使用需要适当的栈对齐才能正常运行的CPU指令。如果某个函数在堆栈未对齐的情况下不会失败,请不要假定将来也会如此。 - Michael Petch