(MASM x86) 在汇编中,堆句柄和指向堆的指针有什么区别?

问题描述 投票:0回答:0

其实我有两个问题有些联系。

  1. 在汇编中,堆句柄和指向堆的指针有什么区别?
  2. 堆句柄是否可以根据指向堆的指针来确定?

我使用的Windows功能是:

我正在使用 Irvine32 库和 Visual Studio 2022 作为我的 IDE。这是我将用来讨论问题的代码:

; main.asm
INCLUDE Irvine32.inc

.386
.model flat, stdcall
.stack 4096
ExitProcess PROTO, dwExitCode: DWORD

.data
    testString BYTE "HELLO", 0

.code
main PROC
    MOV esi, OFFSET testString
    CALL StringHeapAlloc

    INVOKE ExitProcess, 0
main ENDP

; --------------------------------------------------------------------
; StringHeapAlloc
;
; This function will allocate memory in the heap and 
; RECEIVES: ESI
; RETURNS:  EAX contains the heap handle;
;           EBX contains the array address
; REQUIRES: ESI contains the address to the string being copied
; --------------------------------------------------------------------
StringHeapAlloc PROC USES eax esi
    .data
    MAX_STRING_SIZE = 20

    ; Dynamic Memory Information
    hHandle DWORD ?             ; contains the heap handle
    pHeap DWORD ?               ; contains the pointer to the memory allocated
    dwFlag DWORD HEAP_ZERO_MEMORY       ; contains the flags for allocating memory
    dwByte DWORD MAX_STRING_SIZE + 1    ; contains the number of bytes to allocate

    .code
    ; gets heap handle for heap allocation
    INVOKE GetProcessHeap
    MOV hHandle, eax            ; storing heap handle

    ; allocates memory in the heap for the string
    INVOKE HeapAlloc, hHandle, dwFlag, dwByte
    MOV pHeap, eax              ; storing pointer to array

    ; copies string into the allocated memory
    INVOKE Str_copy, esi, pHeap
    RET
StringHeapAlloc ENDP

END main

Q1

在汇编中,我使用的动态内存分配的方法是:

  1. 使用 GetProcessHeap 生成一个 heap handle.
  2. 使用 HeapAlloc 分配内存。 (这一步会给我一个指向堆的指针
  3. 用记忆做点什么。
  4. 使用HeapFree释放内存。

我知道指向堆的指针只是指向分配的特定内存位置的地址。不太明白heap handle是什么。我使用 VS 调试器做了一些调查,发现:

  • 当执行GetProcessHeap时,它将堆句柄返回到EAX寄存器。 After GetProcessHeap is executed.

  • 当执行HeapAlloc时,它将指向堆指针返回到EAX寄存器。 After HeapAlloc is executed.

堆句柄是006E0000。指向堆指针是006E6568。我注意到每次运行代码时,堆句柄似乎都在指向堆指针内。如果我们类似地考虑这个问题,堆句柄是否就像一条街道上的房屋地址为 19000,而指向堆的指针就像那条街道上居民的地址(19000、19001 等)?

Q2

我总能从指向堆指针导出堆句柄吗?在我运行代码的例子中,堆句柄是006E0000,堆指针是006E6568。 堆句柄总是指向堆的指针中的前4个字节吗?

要释放内存,我需要使用 HeapFree。但是,该函数要求我有 heap handlepointer to the heap。现在,每次我动态分配内存时,我都会将堆句柄存储在一个包含堆句柄的数组中,并将指向堆的指针存储在一个包含指针的数组中。如果 heap handle 可以导出,那么我可以摆脱那个额外的数组来存储堆句柄。

编辑:抱歉,我对代码做了一个小修改。在主函数中将 EDX 更改为 ESI。 testString 的偏移量应该存储在 ESI 中,以便 StringHeapAlloc 工作。

assembly winapi x86 masm masm32
© www.soinside.com 2019 - 2024. All rights reserved.