x86 程序集 MASM 中的动态堆内存
Dynamic Heap Memory in x86 Assembly MASM
我在 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 . . .
谁能解释一下我的代码哪里做错了?谢谢
每个当前 irvine32.lib
包含 WriteWindowsMsg
。您的安装出现问题。
从 Kip Irvine's homepage ("...link 库...") 获取 irvine32.inc
和 irvine32.lib
以及确保汇编程序使用 irvine32.inc
而 linker 使用 irvine32.lib
.
看看Irvine's installation hints ("Getting started with MASM...").
我无法在我的系统上收到您的错误消息。 FORMAT_MESSAGE_ALLOCATE_BUFFER
在 FormatMessage
的原型中用作参数名称,在 invoke
调用中用作常量。如果常量未在其他任何地方定义(例如在 -lib 文件中),则它是未知的。不知道为什么你的系统找不到GetLastError
.
我在 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 . . .
谁能解释一下我的代码哪里做错了?谢谢
每个当前 irvine32.lib
包含 WriteWindowsMsg
。您的安装出现问题。
从 Kip Irvine's homepage ("...link 库...") 获取 irvine32.inc
和 irvine32.lib
以及确保汇编程序使用 irvine32.inc
而 linker 使用 irvine32.lib
.
看看Irvine's installation hints ("Getting started with MASM...").
我无法在我的系统上收到您的错误消息。 FORMAT_MESSAGE_ALLOCATE_BUFFER
在 FormatMessage
的原型中用作参数名称,在 invoke
调用中用作常量。如果常量未在其他任何地方定义(例如在 -lib 文件中),则它是未知的。不知道为什么你的系统找不到GetLastError
.