在64位NASM中,我使用来自C库的malloc()分配一个8000字节的内存块,当我完成它时,我通过调用free()来释放它。
我的研究已经提出了很多关于如何在64位NASM中执行此操作的相互矛盾的信息,并且大部分信息是32位,其中调用约定不同,或者它是C或C ++,而不是NASM 。
我认为我有正确的malloc部分,但我不确定免费部分。我发布这个问题是因为我不想测试它并且分配了一个内存块但没有释放。
所以我的两个问题很简单:
(1)我对64位NASM有这个权利吗?
(2)Windows和Linux的语法是否相同?
我只显示我的程序的malloc和免费部分:
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
答案 0 :(得分:1)
让我们从 Windows x64 开始。在 malloc
寄存器中传递单个整数大小的参数(如同时提供给 free
和 rcx
),并将整数返回值放入 rax
寄存器。< /p>
基本规则是对前四个整数参数使用 rcx
、rdx
、r8
和 r9
,对其他任何参数使用堆栈。非整数参数会使事情变得有点复杂,但是由于 malloc
或 free
调用中没有这些参数,所以我不会在这里介绍。如果您需要更多信息,Microsoft 在 X64 Calling Convention
上有一篇很好的文章。
因此,用于分配和立即释放块的简单代码将类似于,如果不同,则在注释后的括号中给出 AT&T 语法:
mov rcx, 1000 ; Allocate a block (mov $1000, %rcx).
call malloc ; Allocate, address returned in rax.
mov rcx, rax ; Address needed in rcx (mov %rax, %rcx).
call free ; And free it.
请注意,此示例和下面的示例仅说明了寄存器的使用,您还需要考虑其他事项,例如阴影空间和对齐要求。
Linux 使用不同的方法(尽管仍然使用寄存器以提高效率)。它使用 System V AMD64 ABI,在这种情况下,您会发现 rax
仍用于返回值,但 rdi
用于参数。
此 ABI 从 { rdi, rsi, rdx, rcx, r8, r9 }
中提取其整数寄存器集,并带有在堆栈上传递的任何额外参数。
因此 Linux 的代码更改将相当简单,使用 rdi
代替 rcx
:
mov rdi, 1000 ; Allocate a block (mov $1000, %rdi).
call malloc ; Allocate, address returned in rax.
mov rdi, rax ; Address needed in rdi (mov %rax, %rdi).
call free ; And free it.
Raymond Chen(The Old New Thing 出名)有一系列关于调用约定的系列文章,您可能会感兴趣,从 here 开始。
答案 1 :(得分:-3)
汇编语言没有标准库。因此,这不是一个汇编语言问题,我必须拥有一组符合此调用约定的库,或者由X编译器和具有此类设置的版本制作的库。我想链接并使用汇编语言中的那些库。首先,最重要的是用该语言编写它,编译并保存temps或编译成汇编,然后从该代码开始。或者反汇编这样的代码以发现调用约定,并将其与使用此编译器读取此目标平台的调用约定时所发现的内容进行比较。
如果是系统调用并且您想直接执行此操作而不是库调用,那么您需要读取此平台和操作系统的系统调用接口,没有理由认为任何两个是相同的( Linux,BSD,Windows等)。它们的主要版本也不一样,尽管它们可能是......
然后编写代码以符合您找到的任何一个。