我在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 . . .
有人可以解释我的代码出错了吗?感谢
答案 0 :(得分:1)
每个当前irvine32.lib
都包含WriteWindowsMsg
。您的安装出了问题。
从Kip Irvine's homepage(&#34; ...链接库...&#34; )获取irvine32.inc
和irvine32.lib
并确保汇编程序使用irvine32.inc
,链接器使用irvine32.lib
。
查看Irvine's installation hints(&#34; MASM入门......&#34; )。
我无法在系统上收到您的错误消息。 FORMAT_MESSAGE_ALLOCATE_BUFFER
的原型中使用FormatMessage
作为参数的名称,invoke
调用中使用GetLastError
作为常量。如果常量未在其他任何地方定义(例如在-lib文件中),则它是未知的。我不知道为什么你的系统找不到<
。