x86汇编MASM中的动态堆内存

时间:2017-04-22 21:27:59

标签: assembly x86 masm irvine32

我在Kip Irvine的Assembly x86书中找到的以下示例使用动态内存分配来重复分配大块内存,直到超出堆大小。我通过包含WriteWindowsMsg过程修改了代码的某些部分,因为由于某些奇怪的原因,我收到一个错误,即此过程不存在。这是修改后的代码:

; Heap Test #2 (Heaptest2.asm)
INCLUDE Irvine32.inc
.data

HANDLE TEXTEQU <DWORD>

HeapCreate PROTO,
flOptions:DWORD, ; heap allocation options
dwInitialSize:DWORD, ; initial heap size, in bytes
dwMaximumSize:DWORD ; maximum heap size, in bytes

LocalFree PROTO,
pErrorMsg:DWORD 




FormatMessage PROTO,
FORMAT_MESSAGE_ALLOCATE_BUFFER: DWORD,
messageID: DWORD, 
messageID: BYTE,
pErrorMsg: DWORD



HeapDestroy PROTO,
hHeap:DWORD ; heap handle


HeapAlloc PROTO,
hHeap:HANDLE, ; handle to existing heap block
HEAP_ZERO_MEMORY:DWORD, ; heap allocation control flags
BLOCK_SIZE:DWORD ; number of bytes to allocate


HeapFree PROTO,
hHeap:HANDLE,
dwFlags:DWORD,
lpMem:DWORD



HEAP_START = 2000000 ; 2 MByte

HEAP_MAX = 400000000 ; 400 MByte
BLOCK_SIZE = 500000 ; .5 MByte
hHeap HANDLE ? ; handle to the heap
pData DWORD ? ; pointer to block
str1 BYTE 0dh,0ah,"Memory allocation failed",0dh,0ah,0
HEAP_ZERO_MEMORY DWORD ?
WriteWindowsMsg_1 BYTE "Error ",0 
WriteWindowsMsg_2 BYTE ": ",0 
pErrorMsg DWORD ? 
messageId DWORD ? 


.code

main PROC

INVOKE HeapCreate, 0,HEAP_START, HEAP_MAX
.IF eax == NULL ; failed?
    call WriteWindowsMsg
    call Crlf
    jmp quit
.ELSE
    mov hHeap,eax ; success
.ENDIF
    mov ecx,2000 ; loop counter
    L1: call allocate_block ; allocate a block
.IF Carry? ; failed?
    mov edx,OFFSET str1 ; display message
    call WriteString
    jmp quit
.ELSE ; no: print a dot to
    mov al,'.' ; show progress
    call WriteChar
.ENDIF
;call free_block ; enable/disable this line
loop L1
quit:
    INVOKE HeapDestroy, hHeap ; destroy the heap
.IF eax == NULL ; failed?
    call WriteWindowsMsg ; yes: error message
    call Crlf
.ENDIF
exit
main ENDP


allocate_block PROC USES ecx
; allocate a block and fill with all zeros.
INVOKE HeapAlloc, hHeap, HEAP_ZERO_MEMORY, BLOCK_SIZE
.IF eax == NULL
    stc ; return with CF = 1
.ELSE
    mov pData,eax ; save the pointer
    clc ; return with CF = 0
.ENDIF
ret
allocate_block ENDP


free_block PROC USES ecx
INVOKE HeapFree, hHeap, 0, pData
ret
free_block ENDP




WriteWindowsMsg PROC USES eax edx 

call GetLastError 
mov messageId, eax 
mov edx, OFFSET WriteWindowsMsg_1 
call WriteString 
call WriteDec 
mov edx, OFFSET WriteWindowsMsg_2 
call WriteString 

INVOKE FormatMessage, FORMAT_MESSAGE_ALLOCATE_BUFFER + \
    FORMAT_MESSAGE_FROM_SYSTEM, NULL, messageID, NULL, 
    ADDR pErrorMsg, NULL, NULL 

mov edx, pErrorMsg 
call WriteString 

INVOKE LocalFree, pErrorMsg 

ret 
WriteWindowsMsg ENDP



END main

我得到以下结果:

 Assembling: bobnew.asm
bobnew.asm(122) : error A2136: too many arguments to INVOKE
bobnew.asm(122) : error A2114: INVOKE argument type mismatch : argument : 3
bobnew.asm(122) : error A2006: undefined symbol : FORMAT_MESSAGE_ALLOCATE_BUFFER

bobnew.asm(122) : error A2114: INVOKE argument type mismatch : argument : 1
bobnew.asm(114) : error A2006: undefined symbol : GetLastError
Press any key to continue . . .

有人可以解释我的代码出错了吗?感谢

1 个答案:

答案 0 :(得分:1)

每个当前irvine32.lib都包含WriteWindowsMsg。您的安装出了问题。

Kip Irvine's homepage&#34; ...链接库...&#34; )获取irvine32.incirvine32.lib并确保汇编程序使用irvine32.inc,链接器使用irvine32.lib

查看Irvine's installation hints&#34; MASM入门......&#34; )。

我无法在系统上收到您的错误消息。 FORMAT_MESSAGE_ALLOCATE_BUFFER的原型中使用FormatMessage作为参数的名称,invoke调用中使用GetLastError作为常量。如果常量未在其他任何地方定义(例如在-lib文件中),则它是未知的。我不知道为什么你的系统找不到<