2017-04-22 29 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