定義子過程的偽指令: PROC、ENDP
; Test8_1.asm
.386
.model flat, stdcall
include msvcrt.inc
includelib msvcrt.lib
.data
szFmt db '%d', 0DH, 0AH, 0
.code
;子過程 proc1:
proc1 proc
invoke crt_printf, addr szFmt, 1
proc1 endp
;子過程 proc2:
proc2 proc
invoke crt_printf, addr szFmt, 2
proc2 endp
;子過程 proc3:
proc3 proc
invoke crt_printf, addr szFmt, 3
proc3 endp
ret
end proc1 ;end 後面的 proc1 是入口的子過程名; 這也就是指定主過程.
;可以把 end proc1 分別換做 end proc2 和 end proc3 嘗試,
;如果這是一個供其他程序調用的代碼文件, 那麼 end 後面就不需要指定.
模仿 C 語言的樣子, 以後的程序結構應該這樣:
; Test8_2.asm
.386
.model flat, stdcall
include msvcrt.inc
includelib msvcrt.lib
.data
szText db 'Hello World!', 0DH, 0AH, 0
.code
main proc
invoke crt_printf, addr szText
ret
main endp
end main
局部變量要用 local 聲明, 和全局變量區別不小:
; Test8_3.asm
.386
.model flat, stdcall
include msvcrt.inc
includelib msvcrt.lib
.data
szFmt db '%d', 0DH, 0AH, 0
.code
main proc
;局部變量中的類型不能使用縮寫
LOCAL v1: dWord
;可用逗號間隔寫在一行
LOCAL v2: dword, v3: dWord
;不指定類型時默認 DWord(在 Win32 下)
LOCAL v4
;數組
LOCAL v5[9]: dWord
;在手動初始化前, 局部變量中都是些垃圾值:
invoke crt_printf, addr szFmt, v1
invoke crt_printf, addr szFmt, v2
invoke crt_printf, addr szFmt, v3
invoke crt_printf, addr szFmt, v4
invoke crt_printf, addr szFmt, v5[0]
ret
main endp
end main
調用子過程:
; Test8_4.asm
.386
.model flat, stdcall
include msvcrt.inc
includelib msvcrt.lib
.data
szFmt db '%d', 0DH, 0AH, 0
.code
;
proc1 proc
invoke crt_printf, addr szFmt, 1
ret
proc1 endp
;
proc2 proc
invoke crt_printf, addr szFmt, 2
ret
proc2 endp
;
main proc
invoke crt_printf, addr szFmt, 0
call proc2
call proc1
ret
main endp
end main
;注釋:
;最後一行 end main 決定了子過程將被率先調用, 這樣它就成了主過程
;然後主過程又通過 call 指令順序調用了 proc2、proc1
;這樣最後的顯示結果將是: 0 / 2 / 1
;子過程應該用 ret 指令返回
一個求和函數的例子:
; Test8_5.asm
.386
.model flat, stdcall
include msvcrt.inc
includelib msvcrt.lib
.data
szFmt db '%d', 0DH, 0AH, 0
.code
;求和的函數, 函數返回值在 eax
sum proc v1: dword, v2: dWord
mov eax, v1
add eax, v2
ret
sum endp
;
main proc
invoke sum, 11, 22
invoke crt_printf, addr szFmt, eax ;33
ret
main endp
end main