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

fd3cxomn  于 2023-04-21  发布在  其他
关注(0)|答案(1)|浏览(103)

其实我有两个问题是有联系的。
1.在程序集中,堆句柄和指向堆的指针有什么区别?
1.堆句柄可以从指向堆的指针中确定吗?
我正在使用的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 copy, a given
; string, into the allocated memory location.
; 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 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

    ; returning heap handle and pointer to handle
    MOV eax, hHandle
    MOV ebx, pHeap
    RET
StringHeapAlloc ENDP

END main

第一季度

在汇编中,我使用的动态内存分配方法是:
1.使用 GetProcessHeap 生成堆句柄
1.使用 HeapAlloc 分配内存。(此步骤将给予我一个指向堆的指针
1.做一些关于记忆的事情。
1.使用 HeapFree 释放内存。
我明白heap指针只是分配给某个内存位置的地址,我不太明白heap句柄是什么,我用VS调试器做了一点调查,发现:

  • 执行 GetProcessHeap 时,将堆句柄返回到EAX寄存器。After GetProcessHeap is executed.
  • 当执行 HeapAlloc 时,它将堆指针返回到EAX寄存器。After HeapAlloc is executed.
    堆句柄为006E0000,堆指针为006E6568,我每次运行代码时都注意到堆句柄似乎在堆指针内,如果我们以此类推,堆句柄是不是就像一条街道,房子的地址是19000,而指针指向堆,比如该街道上居民的地址(19000,19001等)?

第二季度

堆指针是否总是可以派生出堆句柄**?在我运行代码的示例中,堆句柄为006E0000,堆指针为006E6568,堆句柄是否总是堆指针的前4个字节?
为了释放内存,我需要使用 HeapFree。然而,该函数要求我具有堆句柄堆指针。现在,每次动态分配内存时,我将堆句柄存储在一个包含堆句柄的数组中,并将堆指针存储到一个包含指针的数组中。如果堆句柄那么我就可以去掉那个额外的数组来存储堆句柄。
编辑:在main函数中将EDX改为ESI。testString的偏移量应该存储在ESI中,以便StringHeapAlloc工作。
编辑:完善了StringHeapAlloc函数的文档,在StringHeapAlloc函数末尾增加了“MOV eax,hHandle”和“MOV ebx,pHeap”,应该不会影响原题。

o4hqfura

o4hqfura1#

所有类型的句柄都只是值。它们可以是指针,但在某些情况下只是整数。(指针通常是首选,因为它们允许不同类型的句柄在具有类型概念的语言中进行类型区分-如C)。
上面的要点是,你不必担心什么样的结构支持指针,它只是一个由调用代码存储并被调用代码理解的值。
请注意,大多数windows句柄的格式为

struct HNAME__ { int unused };
typedef HNAME__ * HNAME;

但是你从来不使用'HNAME__'结构,你只需要使用API提供给你的HNAME值。

相关问题