您可以通過調試器找到它。下面是一個調試器查看的代碼的開頭:
CPU Disasm
Address Command Comments
00401000 CALL 0040100C ; call main
00401005 PUSH 0 ; /ExitCode = 0
00401007 CALL <JMP.&kernel32.ExitProcess> ; \KERNEL32.ExitProcess
0040100C PUSH EBP ; main
0040100D MOV EBP,ESP
0040100F ADD ESP,-4
00401012 MOV DWORD PTR SS:[LOCAL.1],0 ; dewit = 0
00401019 PUSH DWORD PTR SS:[LOCAL.1] ; /Arg1 => 0
0040101C CALL 00401024 ; print
00401021 LEAVE
00401022 RETN
所以print
叫(請記住,print
是一個宏觀的,所以它的擴展編譯一次)。 Remeber你推0至print
:
CPU Disasm
Address Command Comments
00401024 PUSH EBP ; print (guessed Arg1)
00401025 MOV EBP,ESP
00401027 ADD ESP,-0C
0040102A PUSH -0B ; /StdHandle = STD_OUTPUT_HANDLE
0040102C CALL <JMP.&kernel32.GetStdHandle> ; \KERNEL32.GetStdHandle
00401031 MOV DWORD PTR SS:[LOCAL.1],EAX
00401034 PUSH DWORD PTR SS:[Arg1] ; /Arg1 => [Arg1] *** push 0 ***
00401037 CALL 00401060 ; \so.00401060
見行0x00401034
,0被推爲一個調用的參數。
讓我們來看看代碼:
CPU Disasm
Address Command Comments
00401060 MOV EAX,DWORD PTR SS:[Arg1] ; eax = 0
00401064 LEA EDX,[EAX+3]
00401067 PUSH EBP
00401068 PUSH EDI
00401069 MOV EBP,80808080
0040106E /MOV EDI,DWORD PTR DS:[EAX] ; trying to dereference [0]...
代碼功能是在地址0(又名空指針錯誤),這是一個很大的閱讀,不,不。
看着print
宏在macros.asm
,看來這個宏沒有做任何格式化,你應該用printf
。
您的代碼固定的(你需要printf
宏,msvcrt.inc
和msvcrt.lib
仍處於macros.asm
定義):
.486
.model flat, stdcall
option casemap :none
include \masm32\include\windows.inc
include \masm32\include\msvcrt.inc
include \masm32\macros\macros.asm
include \masm32\include\masm32.inc
include \masm32\include\gdi32.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
includelib \masm32\lib\msvcrt.lib
includelib \masm32\lib\masm32.lib
includelib \masm32\lib\gdi32.lib
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\masm32.lib
.data
format_string db "value: %d", 0
.code
start:
call main
exit
main proc
LOCAL dewit:DWORD
mov dewit, 0
print "printing value: "
printf ("value: %d", dewit)
ret
main endp
end start
大致沒有任何相同的代碼包括:
; compile and link with:
; ml test.asm /link /subsystem:console /defaultlib:kernel32.lib /defaultlib:msvcrt.lib
.686
.model flat, stdcall
option casemap: none
ExitProcess PROTO STDCALL :DWORD
externdef _imp__printf:PTR c_msvcrt
crt_printf equ <_imp__printf>
.data
fmt db "value: %d", 0
.code
start:
call MyFunc
invoke ExitProcess, 0
ret
MyFunc proc
LOCAL foo:DWORD
mov foo, 42
push foo
push offset fmt
call crt_printf
ret
MyFunc endp
end start
我也完全同意@Jester:
另外,consi明鏡不使用輔助功能,直到你可以用手 做到這一點,並瞭解彙編做
宏是偉大的,但除非你能理解他們做什麼,實現手工一樣,你應該避免使用它們。他們從初學者眼中隱藏太多東西。
'MOV [DEWIT],0 高級宏觀幫助描述也許'MOV字PTR [DEWIT] 0'?還要定義「_didn't work_」。 – Jester
沒有工作 - 即它遇到了錯誤,我想..該程序'停止工作'在那一點 – daniel
這是不夠的信息,提供[mcve]。您也可以查看生成的彙編代碼。另外,考慮不要使用幫助器功能,直到您也可以手動完成,並瞭解彙編器在做什麼。 – Jester