2017-04-22 31 views
2

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

; 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)您添加了错误的标签。这显然与C无关。2)我们不是一个调试服务。阅读[问]。 – Olaf

+1

您是否真的看过错误信息?你通常可以相信他们告诉你到底什么是错的。你似乎混淆了参数名称和常量,比如'FORMAT_MESSAGE_ALLOCATE_BUFFER'。 –

回答

1

每个当前irvine32.lib包含WriteWindowsMsg。安装时出现问题。

得到Kip Irvine's homepageirvine32.incirvine32.lib“...链接库......”),并确保汇编使用该irvine32.inc和链接程序使用该irvine32.lib

看看Irvine's installation hints“MASM入门...”)。

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