Memory management Malloc和Free程序集中的多个数组
我正在尝试malloc和free的汇编代码(NASM,64位) 我尝试对两个数组进行malloc,每个数组都有2个64位数字的空间。现在我希望能够写入它们的值(不确定是否/如何准确地访问它们),然后在整个程序结束时,或者在任何点出现错误时,释放内存 如果有一个数组,我现在的工作正常,但是一旦添加另一个数组,它在第一次尝试释放任何内存时失败:( 我的代码当前如下所示:Memory management Malloc和Free程序集中的多个数组,memory-management,assembly,x86-64,nasm,Memory Management,Assembly,X86 64,Nasm,我正在尝试malloc和free的汇编代码(NASM,64位) 我尝试对两个数组进行malloc,每个数组都有2个64位数字的空间。现在我希望能够写入它们的值(不确定是否/如何准确地访问它们),然后在整个程序结束时,或者在任何点出现错误时,释放内存 如果有一个数组,我现在的工作正常,但是一旦添加另一个数组,它在第一次尝试释放任何内存时失败:( 我的代码当前如下所示: extern printf, malloc, free LINUX equ 80H ; int
extern printf, malloc, free
LINUX equ 80H ; interupt number for entering Linux kernel
EXIT equ 60 ; Linux system call 1 i.e. exit ()
segment .text
global main
main:
push dword 16 ; allocate 2 64 bit numbers
call malloc
add rsp, 4 ; Undo the push
test rax, rax ; Check for malloc failure
jz malloc_fail
mov r11, rax ; Save base pointer for array
; DO SOME CODE/ACCESSES/OPERATIONS HERE
push dword 16 ; allocate 2 64 bit numbers
call malloc
add rsp, 4 ; Undo the push
test rax, rax ; Check for malloc failure
jz malloc_fail
mov r12, rax ; Save base pointer for array
; DO SOME CODE/ACCESSES/OPERATIONS HERE
malloc_fail:
jmp dealloc
; Finish Up, deallocate memory and exit
dealloc:
dealloc_1:
test r11, r11 ; Check that the memory was originally allocated
jz dealloc_2 ; If not, try the next block of memory
push r11 ; push the address of the base of the array
call free ; Free this memory
add rsp, 4
dealloc_2:
test r12, r12
jz dealloc_end
push r12
call free
add rsp, 4
dealloc_end:
call os_return ; Exit
os_return:
mov rax, EXIT
mov rdi, 0
syscall
我假设上面的代码正在调用C函数
malloc()
和free()
如果第一次malloc()
失败,则在从malloc()
返回后,您将使用r11
和r12
中的任何垃圾到达deallocu 1
如果第二次malloc()
失败,则在从malloc()
返回后,您将使用r12
中的任何垃圾到达dealloc_1
因此,在进行第一次分配之前,您必须将r11
和r12
归零
由于这是64位模式,所有指针/地址和大小通常为64位。当您将其中一个指针/地址和大小传递给函数时,它必须是64位。因此,push dword 16
不太正确。它应该是push qword 16
。同样,当您从堆栈中删除这些参数时,您必须完全删除相同数量的byt正如您在那里所说的那样,因此添加rsp,4
必须更改为添加rsp,8
最后,我不知道哪些寄存器malloc()
和free()
保留,哪些不保留。您可能需要保存和恢复所谓的易失性寄存器(请参阅C编译器文档)。对于未显示的代码也是如此。它必须保留r11
和r12
,以便用于解除分配。EDIT:我会检查通过堆栈传递参数的方法是否正确(再次,请参阅编译器文档)
编辑:您在第二个free()
之前测试r11
的0。它应该是r12
。但是free()
并不介意接收空指针。因此,可以删除这些检查
注意你的代码。我假设上面的代码正在调用C函数malloc()
和free()
如果第一次malloc()
失败,则在从malloc()
返回后,您将使用r11
和r12
中的任何垃圾到达deallocu 1
如果第二次malloc()
失败,则在从malloc()
返回后,您将使用r12
中的任何垃圾到达dealloc_1
因此,在进行第一次分配之前,您必须将r11
和r12
归零
由于这是64位模式,所有指针/地址和大小通常为64位。当您将其中一个指针/地址和大小传递给函数时,它必须是64位。因此,push dword 16
不太正确。它应该是push qword 16
。同样,当您从堆栈中删除这些参数时,您必须完全删除相同数量的byt正如您在那里所说的那样,因此添加rsp,4
必须更改为添加rsp,8
最后,我不知道哪些寄存器malloc()
和free()
保留,哪些不保留。您可能需要保存和恢复所谓的易失性寄存器(请参阅C编译器文档)。对于未显示的代码也是如此。它必须保留r11
和r12
,以便用于解除分配。EDIT:我会检查通过堆栈传递参数的方法是否正确(再次,请参阅编译器文档)
编辑:您在第二个free()
之前测试r11
的0。它应该是r12
。但是free()
并不介意接收空指针。因此,可以删除这些检查
请注意您的代码。至少有两个错误,因为您需要再次测试r11
(在dealloc\u 2:
之后的行test r11,r11
,但您应该想在这里测试r12
。此外,如果您处于64位模式,您还需要推送一个qword
解除分配根本不起作用的原因可能是您正在更改r11
或r12
的内容
并不是说两个测试都不需要,因为使用空指针调用free
是完全安全的。至少有两个错误,因为您需要再次测试r11
(行测试r11,r11
在解除锁定2:
之后,但您可能想在此处测试r12
。此外,如果您处于64位模式,您还想推送一个Q字
解除分配根本不起作用的原因可能是您正在更改r11
或r12
的内容
并不是说这两个测试都不需要,因为使用空指针调用free
是完全安全的。您必须遵守:在malloc的情况下,参数可能通过寄存器传递,这将是大小的RDI。正如前面所指出的,您必须注意被调用函数保留了哪些寄存器。(在函数调用中仅保留RBP、RSP和R12-R15)您必须遵守:在malloc的情况下,参数可能通过寄存器传递,这将是大小的RDI。正如前面所指出的,您必须注意被调用函数保留了哪些寄存器。(在函数调用中仅保留RBP、RSP和R12-R15)复制粘贴失败:dealloc_2执行测试r11、r11
但必须执行测试R12、R12