Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Memory management Malloc和Free程序集中的多个数组_Memory Management_Assembly_X86 64_Nasm - Fatal编程技术网

Memory management Malloc和Free程序集中的多个数组

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

我正在尝试malloc和free的汇编代码(NASM,64位)

我尝试对两个数组进行malloc,每个数组都有2个64位数字的空间。现在我希望能够写入它们的值(不确定是否/如何准确地访问它们),然后在整个程序结束时,或者在任何点出现错误时,释放内存

如果有一个数组,我现在的工作正常,但是一旦添加另一个数组,它在第一次尝试释放任何内存时失败:(

我的代码当前如下所示:

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