久久综合伊人噜噜色,日本三级香港三级人妇电影精品,亚洲中文色资源,国产高清一区二区三区人妖
汶上信息港
標(biāo)題:
匯編中參數(shù)的傳遞和堆棧修正
[打印本頁]
作者:
hbhdgpyz
時間:
2008-9-28 16:22
標(biāo)題:
匯編中參數(shù)的傳遞和堆棧修正
在 Win32匯編中,我們經(jīng)常要和 Api 打交道,另外也會常常使用自己編制的類似于 Api 的帶參數(shù)的子程序,本文要講述的是在子程序調(diào)用的過程中進(jìn)行參數(shù)傳遞的概念和分析。一般在程序中,參數(shù)的傳遞是通過堆棧進(jìn)行的,也就是說,調(diào)用者把要傳遞給子程序(或者被調(diào)用者)的參數(shù)壓入堆棧,子程序在堆棧取出相應(yīng)的值再使用,比如說,如果你要調(diào)用 SubRouting(Var1,Var2,Var3),編譯后的最終代碼<SPAN style="COLOR: red">可能</SPAN>是<BR><BR>push Var3<BR>push Var2<BR>push Var1<BR>call SubRouting<BR>add esp,12<BR><BR>也就是說,調(diào)用者首先把參數(shù)壓入堆棧,然后調(diào)用子程序,在完成后,由于堆棧中先前壓入的數(shù)不再有用,調(diào)用者或者被調(diào)用者必須有一方把堆棧指針修正到調(diào)用前的狀態(tài)。參數(shù)是最右邊的先入堆棧還是最左邊的先入堆棧、還有由調(diào)用者還是被調(diào)用者來修正堆棧都必須有個約定,不然就會產(chǎn)生不正確的結(jié)果,這就是我在前面使用“可能”這兩個字的原因:各種語言中調(diào)用子程序的約定是不同的,它們的不同點見下表:<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /><o:p></o:p>
! O* x5 X0 }$ H0 @- w5 T
<TABLE style="WIDTH: 581.25pt; mso-cellspacing: 0cm; mso-padding-alt: 0cm 0cm 0cm 0cm" cellSpacing=0 borderColorDark=#ffffff cellPadding=0 width=775 borderColorLight=#000000 border=1>
# G; e/ r8 @1 G; V
<TBODY>
. P; y: n4 o0 h% c7 _) A. t4 ?0 w
<TR>
- T5 R+ P Y7 U8 d) A* M: U
<TD style="PADDING-RIGHT: 0cm; PADDING-LEFT: 0cm; BACKGROUND: #66cccc; PADDING-BOTTOM: 0cm; PADDING-TOP: 0cm">
! I0 U6 W+ z" k8 Q+ [( p# t: {
<P class=MsoNormal><SPAN lang=EN-US> </SPAN><SPAN lang=EN-US style="FONT-SIZE: 12pt; FONT-FAMILY: 宋體"><o:p></o:p></SPAN></P></TD>
+ i/ s; ? Y3 O/ ^: w9 z0 T
<TD style="PADDING-RIGHT: 0cm; PADDING-LEFT: 0cm; BACKGROUND: #66cccc; PADDING-BOTTOM: 0cm; PADDING-TOP: 0cm">
5 x, s# G$ g+ M6 m6 P
<P class=MsoNormal style="TEXT-ALIGN: center" align=center><SPAN lang=EN-US>C</SPAN><SPAN lang=EN-US style="FONT-SIZE: 12pt; FONT-FAMILY: 宋體"><o:p></o:p></SPAN></P></TD>
d4 @5 }; i& r& v
<TD style="PADDING-RIGHT: 0cm; PADDING-LEFT: 0cm; BACKGROUND: #66cccc; PADDING-BOTTOM: 0cm; PADDING-TOP: 0cm">
% m/ S8 U! Y* ]" ]) w; Q3 P0 x
<P class=MsoNormal style="TEXT-ALIGN: center" align=center><SPAN lang=EN-US>SysCall</SPAN><SPAN lang=EN-US style="FONT-SIZE: 12pt; FONT-FAMILY: 宋體"><o:p></o:p></SPAN></P></TD>
1 J. l- e& U+ M/ p, c0 o* G6 o
<TD style="PADDING-RIGHT: 0cm; PADDING-LEFT: 0cm; BACKGROUND: #66cccc; PADDING-BOTTOM: 0cm; PADDING-TOP: 0cm">
5 ?; z* g* ]. O# w$ e8 e
<P class=MsoNormal style="TEXT-ALIGN: center" align=center><SPAN lang=EN-US>StdCall</SPAN><SPAN lang=EN-US style="FONT-SIZE: 12pt; FONT-FAMILY: 宋體"><o:p></o:p></SPAN></P></TD>
) _( M3 {( [# U$ z' b
<TD style="PADDING-RIGHT: 0cm; PADDING-LEFT: 0cm; BACKGROUND: #66cccc; PADDING-BOTTOM: 0cm; PADDING-TOP: 0cm">
4 T9 h& l9 V+ n! F
<P class=MsoNormal style="TEXT-ALIGN: center" align=center><SPAN lang=EN-US>Basic</SPAN><SPAN lang=EN-US style="FONT-SIZE: 12pt; FONT-FAMILY: 宋體"><o:p></o:p></SPAN></P></TD>
( ?0 F5 |; b, \' G: t
<TD style="PADDING-RIGHT: 0cm; PADDING-LEFT: 0cm; BACKGROUND: #66cccc; PADDING-BOTTOM: 0cm; PADDING-TOP: 0cm">
; Y9 J5 k& t% W# m5 Y f, Q
<P class=MsoNormal style="TEXT-ALIGN: center" align=center><SPAN lang=EN-US>Fortran</SPAN><SPAN lang=EN-US style="FONT-SIZE: 12pt; FONT-FAMILY: 宋體"><o:p></o:p></SPAN></P></TD>
2 d8 m& v( i7 f& t0 w R. x l
<TD style="PADDING-RIGHT: 0cm; PADDING-LEFT: 0cm; BACKGROUND: #66cccc; PADDING-BOTTOM: 0cm; PADDING-TOP: 0cm">
. \* P- v- H5 m* j
<P class=MsoNormal style="TEXT-ALIGN: center" align=center><SPAN lang=EN-US>Pascal</SPAN><SPAN lang=EN-US style="FONT-SIZE: 12pt; FONT-FAMILY: 宋體"><o:p></o:p></SPAN></P></TD></TR>
' m# L& I: q' i* J+ r- P4 g
<TR>
* S1 {% Q- z: x5 f5 ~
<TD style="PADDING-RIGHT: 0cm; PADDING-LEFT: 0cm; BACKGROUND: #66cccc; PADDING-BOTTOM: 0cm; WIDTH: 28%; PADDING-TOP: 0cm" width="28%">
! r5 c% @% {1 y7 r, W9 m
<P class=MsoNormal><SPAN style="FONT-FAMILY: 宋體; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">參數(shù)從左到右</SPAN><SPAN lang=EN-US style="FONT-SIZE: 12pt; FONT-FAMILY: 宋體"><o:p></o:p></SPAN></P></TD>
& @' Y' n: a$ k
<TD style="PADDING-RIGHT: 0cm; PADDING-LEFT: 0cm; BACKGROUND: #ccccff; PADDING-BOTTOM: 0cm; WIDTH: 12%; PADDING-TOP: 0cm" width="12%">
* O" V+ m$ R S9 B
<P class=MsoNormal style="TEXT-ALIGN: center" align=center><SPAN lang=EN-US> </SPAN><SPAN lang=EN-US style="FONT-SIZE: 12pt; FONT-FAMILY: 宋體"><o:p></o:p></SPAN></P></TD>
! n& v% ~6 p/ I8 A# h/ {: `
<TD style="PADDING-RIGHT: 0cm; PADDING-LEFT: 0cm; BACKGROUND: #ccccff; PADDING-BOTTOM: 0cm; WIDTH: 12%; PADDING-TOP: 0cm" width="12%">
4 s0 ]4 x( D5 d9 ?
<P class=MsoNormal style="TEXT-ALIGN: center" align=center><SPAN lang=EN-US> </SPAN><SPAN lang=EN-US style="FONT-SIZE: 12pt; FONT-FAMILY: 宋體"><o:p></o:p></SPAN></P></TD>
& {3 t8 a2 _& A# C
<TD style="PADDING-RIGHT: 0cm; PADDING-LEFT: 0cm; BACKGROUND: #ccccff; PADDING-BOTTOM: 0cm; WIDTH: 12%; PADDING-TOP: 0cm" width="12%">
8 G/ O2 _7 D4 z& l7 E5 L
<P class=MsoNormal style="TEXT-ALIGN: center" align=center><SPAN lang=EN-US> </SPAN><SPAN lang=EN-US style="FONT-SIZE: 12pt; FONT-FAMILY: 宋體"><o:p></o:p></SPAN></P></TD>
4 e% d* A5 G* d
<TD style="PADDING-RIGHT: 0cm; PADDING-LEFT: 0cm; BACKGROUND: #ccccff; PADDING-BOTTOM: 0cm; WIDTH: 12%; PADDING-TOP: 0cm" width="12%">
, ~% G4 `) A) M' l7 |
<P class=MsoNormal style="TEXT-ALIGN: center" align=center><SPAN style="FONT-FAMILY: 宋體; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">是</SPAN><SPAN lang=EN-US style="FONT-SIZE: 12pt; FONT-FAMILY: 宋體"><o:p></o:p></SPAN></P></TD>
: _' P$ @0 V; X O. x& Y2 c( h
<TD style="PADDING-RIGHT: 0cm; PADDING-LEFT: 0cm; BACKGROUND: #ccccff; PADDING-BOTTOM: 0cm; WIDTH: 12%; PADDING-TOP: 0cm" width="12%">
+ n9 T6 g7 g2 w. M4 n
<P class=MsoNormal style="TEXT-ALIGN: center" align=center><SPAN style="FONT-FAMILY: 宋體; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">是</SPAN><SPAN lang=EN-US style="FONT-SIZE: 12pt; FONT-FAMILY: 宋體"><o:p></o:p></SPAN></P></TD>
, W3 q0 {" V0 Q- J9 N, x) L' a/ h# ~
<TD style="PADDING-RIGHT: 0cm; PADDING-LEFT: 0cm; BACKGROUND: #ccccff; PADDING-BOTTOM: 0cm; WIDTH: 12%; PADDING-TOP: 0cm" width="12%">
% b! L( g1 N# }2 q- B+ ~. A# j
<P class=MsoNormal style="TEXT-ALIGN: center" align=center><SPAN style="FONT-FAMILY: 宋體; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">是</SPAN><SPAN lang=EN-US style="FONT-SIZE: 12pt; FONT-FAMILY: 宋體"><o:p></o:p></SPAN></P></TD></TR>
; o( A5 L& g1 n: J
<TR>
% n! }* r: O, A
<TD style="PADDING-RIGHT: 0cm; PADDING-LEFT: 0cm; BACKGROUND: #66cccc; PADDING-BOTTOM: 0cm; WIDTH: 28%; PADDING-TOP: 0cm" width="28%">
, N# H# m$ \$ B) L3 r: Q4 A/ N% O
<P class=MsoNormal><SPAN style="FONT-FAMILY: 宋體; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">參數(shù)從右到左</SPAN><SPAN lang=EN-US style="FONT-SIZE: 12pt; FONT-FAMILY: 宋體"><o:p></o:p></SPAN></P></TD>
" `6 S+ H' }* Y7 l
<TD style="PADDING-RIGHT: 0cm; PADDING-LEFT: 0cm; BACKGROUND: #ccccff; PADDING-BOTTOM: 0cm; WIDTH: 12%; PADDING-TOP: 0cm" width="12%">
4 i+ v5 L# h& n) `% b+ c
<P class=MsoNormal style="TEXT-ALIGN: center" align=center><SPAN style="FONT-FAMILY: 宋體; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">是</SPAN><SPAN lang=EN-US style="FONT-SIZE: 12pt; FONT-FAMILY: 宋體"><o:p></o:p></SPAN></P></TD>
; K m0 |7 x _3 ^% }- t1 }& O
<TD style="PADDING-RIGHT: 0cm; PADDING-LEFT: 0cm; BACKGROUND: #ccccff; PADDING-BOTTOM: 0cm; WIDTH: 12%; PADDING-TOP: 0cm" width="12%">
2 k9 @* i5 a7 S
<P class=MsoNormal style="TEXT-ALIGN: center" align=center><SPAN style="FONT-FAMILY: 宋體; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">是</SPAN><SPAN lang=EN-US style="FONT-SIZE: 12pt; FONT-FAMILY: 宋體"><o:p></o:p></SPAN></P></TD>
. k# @0 S2 Y7 o$ u, l# `
<TD style="PADDING-RIGHT: 0cm; PADDING-LEFT: 0cm; BACKGROUND: #ccccff; PADDING-BOTTOM: 0cm; WIDTH: 12%; PADDING-TOP: 0cm" width="12%">
& G* _) g8 M& [. G& ]
<P class=MsoNormal style="TEXT-ALIGN: center" align=center><SPAN style="FONT-FAMILY: 宋體; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">是</SPAN><SPAN lang=EN-US style="FONT-SIZE: 12pt; FONT-FAMILY: 宋體"><o:p></o:p></SPAN></P></TD>
7 C+ t7 F- Q% ^+ i7 D
<TD style="PADDING-RIGHT: 0cm; PADDING-LEFT: 0cm; BACKGROUND: #ccccff; PADDING-BOTTOM: 0cm; WIDTH: 12%; PADDING-TOP: 0cm" width="12%">
( Q2 u+ T. z- z- o: l, e6 b7 P" V
<P class=MsoNormal style="TEXT-ALIGN: center" align=center><SPAN lang=EN-US> </SPAN><SPAN lang=EN-US style="FONT-SIZE: 12pt; FONT-FAMILY: 宋體"><o:p></o:p></SPAN></P></TD>
2 a# o4 G$ K( ?# r& e! m
<TD style="PADDING-RIGHT: 0cm; PADDING-LEFT: 0cm; BACKGROUND: #ccccff; PADDING-BOTTOM: 0cm; WIDTH: 12%; PADDING-TOP: 0cm" width="12%">
$ B; G: s: f3 p3 o, K4 E+ a$ {) T3 Y
<P class=MsoNormal style="TEXT-ALIGN: center" align=center><SPAN lang=EN-US> </SPAN><SPAN lang=EN-US style="FONT-SIZE: 12pt; FONT-FAMILY: 宋體"><o:p></o:p></SPAN></P></TD>
- i. i+ r# N( h L) c4 _0 A
<TD style="PADDING-RIGHT: 0cm; PADDING-LEFT: 0cm; BACKGROUND: #ccccff; PADDING-BOTTOM: 0cm; WIDTH: 12%; PADDING-TOP: 0cm" width="12%">
) e9 J+ Q1 o/ P2 L
<P class=MsoNormal style="TEXT-ALIGN: center" align=center><SPAN lang=EN-US> </SPAN><SPAN lang=EN-US style="FONT-SIZE: 12pt; FONT-FAMILY: 宋體"><o:p></o:p></SPAN></P></TD></TR>
( ?- W7 E* j0 q9 ^6 Y
<TR>
& ]& X" m- `# _1 }" e, I$ b* j
<TD style="PADDING-RIGHT: 0cm; PADDING-LEFT: 0cm; BACKGROUND: #66cccc; PADDING-BOTTOM: 0cm; WIDTH: 28%; PADDING-TOP: 0cm" width="28%">
' z/ S& r3 g* ^& b4 K! {
<P class=MsoNormal><SPAN style="FONT-FAMILY: 宋體; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">調(diào)用者清除堆棧</SPAN><SPAN lang=EN-US style="FONT-SIZE: 12pt; FONT-FAMILY: 宋體"><o:p></o:p></SPAN></P></TD>
% c( q% c9 S6 B6 W, q
<TD style="PADDING-RIGHT: 0cm; PADDING-LEFT: 0cm; BACKGROUND: #ccccff; PADDING-BOTTOM: 0cm; WIDTH: 12%; PADDING-TOP: 0cm" width="12%">
1 L" v l7 ?+ O5 j% k5 I2 u8 n
<P class=MsoNormal style="TEXT-ALIGN: center" align=center><SPAN style="FONT-FAMILY: 宋體; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">是</SPAN><SPAN lang=EN-US style="FONT-SIZE: 12pt; FONT-FAMILY: 宋體"><o:p></o:p></SPAN></P></TD>
, y C: j1 n8 ^
<TD style="PADDING-RIGHT: 0cm; PADDING-LEFT: 0cm; BACKGROUND: #ccccff; PADDING-BOTTOM: 0cm; WIDTH: 12%; PADDING-TOP: 0cm" width="12%">
" x* k) z* e/ K$ g( v+ Q
<P class=MsoNormal style="TEXT-ALIGN: center" align=center><SPAN lang=EN-US> </SPAN><SPAN lang=EN-US style="FONT-SIZE: 12pt; FONT-FAMILY: 宋體"><o:p></o:p></SPAN></P></TD>
& W8 e9 u8 W7 ^" H0 A4 Q0 ^
<TD style="PADDING-RIGHT: 0cm; PADDING-LEFT: 0cm; BACKGROUND: #ccccff; PADDING-BOTTOM: 0cm; WIDTH: 12%; PADDING-TOP: 0cm" width="12%">
" J8 c) w( f' l
<P class=MsoNormal style="TEXT-ALIGN: center" align=center><SPAN lang=EN-US> </SPAN><SPAN lang=EN-US style="FONT-SIZE: 12pt; FONT-FAMILY: 宋體"><o:p></o:p></SPAN></P></TD>
/ c* t0 }' Z! j- ]: R/ x9 O
<TD style="PADDING-RIGHT: 0cm; PADDING-LEFT: 0cm; BACKGROUND: #ccccff; PADDING-BOTTOM: 0cm; WIDTH: 12%; PADDING-TOP: 0cm" width="12%">
3 F/ T2 c- |& M% A! W6 v+ p5 W7 R) c
<P class=MsoNormal style="TEXT-ALIGN: center" align=center><SPAN lang=EN-US> </SPAN><SPAN lang=EN-US style="FONT-SIZE: 12pt; FONT-FAMILY: 宋體"><o:p></o:p></SPAN></P></TD>
! v/ I9 b6 F' c9 K$ S' {
<TD style="PADDING-RIGHT: 0cm; PADDING-LEFT: 0cm; BACKGROUND: #ccccff; PADDING-BOTTOM: 0cm; WIDTH: 12%; PADDING-TOP: 0cm" width="12%">
5 o/ Q6 E& S- } c
<P class=MsoNormal style="TEXT-ALIGN: center" align=center><SPAN lang=EN-US> </SPAN><SPAN lang=EN-US style="FONT-SIZE: 12pt; FONT-FAMILY: 宋體"><o:p></o:p></SPAN></P></TD>
9 k9 Q8 m, ^7 p* _
<TD style="PADDING-RIGHT: 0cm; PADDING-LEFT: 0cm; BACKGROUND: #ccccff; PADDING-BOTTOM: 0cm; WIDTH: 12%; PADDING-TOP: 0cm" width="12%">
' m- [% C: _. `; Z. P
<P class=MsoNormal style="TEXT-ALIGN: center" align=center><SPAN lang=EN-US> </SPAN><SPAN lang=EN-US style="FONT-SIZE: 12pt; FONT-FAMILY: 宋體"><o:p></o:p></SPAN></P></TD></TR>
- h# Q! i2 t8 { Z3 S1 I
<TR>
* o2 m9 S7 @& w. Q/ |
<TD style="PADDING-RIGHT: 0cm; PADDING-LEFT: 0cm; BACKGROUND: #66cccc; PADDING-BOTTOM: 0cm; WIDTH: 28%; PADDING-TOP: 0cm" width="28%">
; i! p6 v% {5 C Q) A) E
<P class=MsoNormal><SPAN style="FONT-FAMILY: 宋體; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">允許使用</SPAN><SPAN lang=EN-US>:VARARG</SPAN><SPAN lang=EN-US style="FONT-SIZE: 12pt; FONT-FAMILY: 宋體"><o:p></o:p></SPAN></P></TD>
6 p& t$ Q, Y+ v7 d8 e. |
<TD style="PADDING-RIGHT: 0cm; PADDING-LEFT: 0cm; BACKGROUND: #ccccff; PADDING-BOTTOM: 0cm; WIDTH: 12%; PADDING-TOP: 0cm" width="12%">
" a$ r( q* m( i. h4 A
<P class=MsoNormal style="TEXT-ALIGN: center" align=center><SPAN style="FONT-FAMILY: 宋體; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">是</SPAN><SPAN lang=EN-US style="FONT-SIZE: 12pt; FONT-FAMILY: 宋體"><o:p></o:p></SPAN></P></TD>
0 S+ J! m; _4 o4 h6 Q9 V* \2 R
<TD style="PADDING-RIGHT: 0cm; PADDING-LEFT: 0cm; BACKGROUND: #ccccff; PADDING-BOTTOM: 0cm; WIDTH: 12%; PADDING-TOP: 0cm" width="12%">
6 m7 v ^* F( Z% S
<P class=MsoNormal style="TEXT-ALIGN: center" align=center><SPAN style="FONT-FAMILY: 宋體; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">是</SPAN><SPAN lang=EN-US style="FONT-SIZE: 12pt; FONT-FAMILY: 宋體"><o:p></o:p></SPAN></P></TD>
# l6 t5 ~/ x B; x3 r, \
<TD style="PADDING-RIGHT: 0cm; PADDING-LEFT: 0cm; BACKGROUND: #ccccff; PADDING-BOTTOM: 0cm; WIDTH: 12%; PADDING-TOP: 0cm" width="12%">
8 h3 N3 {. Q! l& _- N% ~& l
<P class=MsoNormal style="TEXT-ALIGN: center" align=center><SPAN style="FONT-FAMILY: 宋體; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">是</SPAN><SPAN lang=EN-US style="FONT-SIZE: 12pt; FONT-FAMILY: 宋體"><o:p></o:p></SPAN></P></TD>
+ t, Z9 K! R) D: h
<TD style="PADDING-RIGHT: 0cm; PADDING-LEFT: 0cm; BACKGROUND: #ccccff; PADDING-BOTTOM: 0cm; WIDTH: 12%; PADDING-TOP: 0cm" width="12%">
' m* K6 A6 x# E- |3 Q: B2 W
<P class=MsoNormal style="TEXT-ALIGN: center" align=center><SPAN lang=EN-US> </SPAN><SPAN lang=EN-US style="FONT-SIZE: 12pt; FONT-FAMILY: 宋體"><o:p></o:p></SPAN></P></TD>
Z- v7 M: X1 z# r
<TD style="PADDING-RIGHT: 0cm; PADDING-LEFT: 0cm; BACKGROUND: #ccccff; PADDING-BOTTOM: 0cm; WIDTH: 12%; PADDING-TOP: 0cm" width="12%">
/ p" B& W6 C# q& |. m: H: D
<P class=MsoNormal style="TEXT-ALIGN: center" align=center><SPAN lang=EN-US> </SPAN><SPAN lang=EN-US style="FONT-SIZE: 12pt; FONT-FAMILY: 宋體"><o:p></o:p></SPAN></P></TD>
6 l) y; u5 w) v4 r; `
<TD style="PADDING-RIGHT: 0cm; PADDING-LEFT: 0cm; BACKGROUND: #ccccff; PADDING-BOTTOM: 0cm; WIDTH: 12%; PADDING-TOP: 0cm" width="12%">
6 H( u! y% x" T i9 M# y
<P class=MsoNormal style="TEXT-ALIGN: center" align=center><SPAN lang=EN-US> </SPAN><SPAN lang=EN-US style="FONT-SIZE: 12pt; FONT-FAMILY: 宋體"><o:p></o:p></SPAN></P></TD></TR></TBODY></TABLE>
9 o4 G" q0 }$ a6 n4 x% L* j9 n! |
<P><SPAN lang=EN-US>VARARG 表示參數(shù)的個數(shù)可以是不確定的,有一個例子就是 C 中的 printf 語句,在上表中,StdCall 的定義有個要說明的地方,就是如果 StdCall 使用 :VARARG 時,是由調(diào)用者清除堆棧的,而在沒有:VARARG時是由被調(diào)用者清除堆棧的。<BR>在 Win32 匯編中,約定使用 StdCall 方式,所以我們要在程序開始的時候使用 .model stdcall 語句。也就是說,在 API 或子程序中,最右邊的參數(shù)先入堆棧,然后子程序在返回的時候負(fù)責(zé)校正堆棧,舉例說明,如果我們要調(diào)用 MessageBox 這個 API,因為它的定義是 MessageBox(hWnd,lpText,lpCaption,UType) 所以在程序中要這樣使用:<o:p></o:p></SPAN></P>
4 F k, e: I2 N0 S
<P><SPAN lang=EN-US>push MB_OK<BR>push offset szCaption<BR>push offset szText<BR>push hWnd<BR>call MessageBox<BR>...<o:p></o:p></SPAN></P>
- {6 p, J9 [, ?# V
<P>我們不必在<SPAN lang=EN-US> API 返回的時候加上一句 add sp,4*4 來修正堆棧,因為這已經(jīng)由 MessageBox 這個子程序做了。在 Windows API 中,唯一一個特殊的 API 是 wsprintf,這個 API 是 C 約定的,它的定義是 wsprintf(lpOut,lpFormat,Var1,Var2...),所以在使用時就要:<o:p></o:p></SPAN></P>
. i8 d. E z2 P+ r7 ]# i: x
<P><SPAN lang=EN-US>push 1111<BR>push 2222<BR>push 3333<BR>push offset szFormat<BR>push offset szOut<BR>call wsprintf<BR>add esp,4*5</SPAN></P>
3 U5 B: D, O. S' P, R2 q! u
<P><SPAN lang=EN-US> <o:p></o:p></SPAN></P>
8 C. e4 l4 e+ \6 r
<P><SPAN lang=EN-US> <o:p></o:p></SPAN></P>
3 d6 L. ~, h+ z7 t6 K
<P><SPAN lang=EN-US> <o:p></o:p></SPAN></P>
$ Z% G) w" K, d4 g1 V; E
<P><SPAN lang=EN-US> <o:p></o:p></SPAN></P>
1 n: ?& V! _+ H" ~ N
<P><SPAN lang=EN-US> <o:p></o:p></SPAN></P>
& e7 _! T' o* b: M" n2 D! ^: J2 l
<P><?xml:namespace prefix = v ns = "urn:schemas-microsoft-com:vml" /><v:shapetype id=_x0000_t75 stroked="f" filled="f" path=" m@4@5 l@4@11@9@11@9@5 xe" o:preferrelative="t" o:spt="75" coordsize="21600,21600"><v:stroke joinstyle="miter"></v:stroke><v:formulas><v:f eqn="if lineDrawn pixelLineWidth 0 "></v:f><v:f eqn="sum @0 1 0 "></v:f><v:f eqn="sum 0 0 @1 "></v:f><v:f eqn="prod @2 1 2 "></v:f><v:f eqn="prod @3 21600 pixelWidth "></v:f><v:f eqn="prod @3 21600 pixelHeight "></v:f><v:f eqn="sum @0 0 1 "></v:f><v:f eqn="prod @6 1 2 "></v:f><v:f eqn="prod @7 21600 pixelWidth "></v:f><v:f eqn="sum @8 21600 0 "></v:f><v:f eqn="prod @7 21600 pixelHeight "></v:f><v:f eqn="sum @10 21600 0 "></v:f></v:formulas><v:path o:connecttype="rect" gradientshapeok="t" o:extrusionok="f"></v:path><o:lock aspectratio="t" v:ext="edit"></o:lock></v:shapetype><v:shape id=_x0000_s1026 style="MARGIN-TOP: 0px; Z-INDEX: 1; MARGIN-LEFT: 130.25pt; WIDTH: 170.25pt; POSITION: absolute; HEIGHT: 180pt; mso-wrap-distance-left: 3.75pt; mso-wrap-distance-top: 3.75pt; mso-wrap-distance-right: 3.75pt; mso-wrap-distance-bottom: 3.75pt; mso-position-horizontal: right; mso-position-horizontal-relative: text; mso-position-vertical-relative: line" alt="" coordsize="21600,21600" type="#_x0000_t75" o:allowoverlap="f"><?xml:namespace prefix = w ns = "urn:schemas-microsoft-com:office:word" /><w:wrap type="square"></w:wrap></v:shape>下面要講的是子程序如何存取參數(shù),因為缺省對堆棧操作的寄存器有<SPAN lang=EN-US> ESP 和 EBP,而 ESP是堆棧指針,無法暫借使用,所以一般使用 EBP 來存取堆棧,假定在一個調(diào)用中有兩個參數(shù),而且在 push 第一個參數(shù)前的堆棧指針 ESP 為 X,那么壓入兩個參數(shù)后的 ESP 為 X-8,程序開始執(zhí)行 call 指令,call 指令把返回地址壓入堆棧,這時候 ESP 為 X-C,這時已經(jīng)在子程序中了,我們可以開始使用 EBP 來存取參數(shù)了,但為了在返回時恢復(fù) EBP 的值,我們還是再需要一句 push ebp 來先保存 EBP 的值,這時 ESP 為 X-10,再執(zhí)行一句 mov ebp,esp,根據(jù)右圖可以看出,實際上這時候 [ebp + 8] 就是參數(shù)1,[ebp + c]就是參數(shù)2。另外,局部變量也是定義在堆棧中的,它們的位置一般放在 push ebp 保存的 EBP 數(shù)值的后面,局部變量1、2對應(yīng)的地址分別是 [ebp-4]、[ebp-8],下面是一個典型的子程序,可以完成第一個參數(shù)減去第二個參數(shù),它的定義是:<BR><BR>MyProc proto Var1,Var2 ;有兩個參數(shù)<BR>local lVar1,lVar2 ;有兩個局部變量<o:p></o:p></SPAN></P>
1 j( W% {0 T7 v% B) Y% K) O- k4 X
<P>注意,這里的兩個<SPAN lang=EN-US> local 變量實際上沒有被用到,只是為了演示用,具體實現(xiàn)的代碼是:<BR><BR>MyProc proc<BR><BR>push ebp<BR>mov ebp,esp<o:p></o:p></SPAN></P>
2 G& s# l3 F& m( \/ e9 c. i
<P><SPAN lang=EN-US>sub esp,8<o:p></o:p></SPAN></P>
+ p n" }3 R1 T0 ]4 u4 {$ s- f8 Y! T
<P><SPAN lang=EN-US>mov eax,dword ptr [ebp + 8]<BR>sub eax,dword ptr [ebp + c]<o:p></o:p></SPAN></P>
r5 K7 K, F0 F$ k$ n
<P><SPAN lang=EN-US>add esp,8<o:p></o:p></SPAN></P>
: \! Z- ^2 S+ H. o
<P><SPAN lang=EN-US>pop ebp<BR>ret 8<o:p></o:p></SPAN></P>
7 I1 [6 G& {- S# N, f* G2 r/ `6 S# z3 H
<P><SPAN lang=EN-US>MyProc endp<BR><BR>現(xiàn)在對這個子程序分析一下,push ebp/mov ebp,esp 是例行的保存和設(shè)置 EBP 的代碼,sub esp,8 在堆棧中留出兩個局部變量的空間,mov /add 語句完成相加,add esp,8 修正兩個局部變量使用的堆棧,ret 8 修正兩個參數(shù)使用的堆棧,相當(dāng)于 ret / add esp,8 兩句代碼的效果??梢钥闯?,這是一個標(biāo)準(zhǔn)的 Stdcall 約定的子程序,使用時最后一個參數(shù)先入堆棧,返回時由子程序進(jìn)行堆棧修正。當(dāng)然,這個子程序為了演示執(zhí)行過程,使用了手工保存 ebp 并設(shè)置局部變量的方法,實際上,386 處理器有兩條專用的指令是完成這個功能用的,那就是 Enter 和 Leave,Enter 語句的作用就是 push ebp/mov ebp,esp/sub esp,xxx,這個 xxx 就是 Enter 的,Leave 則完成 add esp,xxx/pop ebp 的功能,所以上面的程序可以改成:<o:p></o:p></SPAN></P>
# H9 j; B& Z% ~( I5 [# z- w
<P><SPAN lang=EN-US>MyPorc proc<BR>enter 8,0<BR><BR>mov eax,dword ptr [ebp + 8]<BR>sub eax,dword ptr [ebp + c]<BR><BR>leave<BR>ret 8<BR>MyProc endp<o:p></o:p></SPAN></P>
0 M9 g( @2 k' i0 |0 [2 t" c& A
<P>好了,說到這兒,參數(shù)傳遞的原理也應(yīng)該將清楚了,還要最后說的是,在使用<SPAN lang=EN-US> Masm32 編 Win32 匯編程序的時候,我們并不需要記住 [ebp + xx] 等麻煩的地址,或自己計算局部變量需要預(yù)留的堆??臻g,還有在 ret 時計算要加上的數(shù)值,Masm32 的宏指令都已經(jīng)把這些做好了,如在 Masm32 中,上面的程序只要寫成為:<o:p></o:p></SPAN></P>
" q% K& G5 `3 {; t# P! {* A/ Q4 x
<P><SPAN lang=EN-US>MyProc proc Var1,Var2<BR>local lVar1,lVar2<o:p></o:p></SPAN></P>
2 `& T f+ G. ^3 s% }2 m9 G: S
<P><SPAN lang=EN-US>mov eax,Var1<BR>sub eax,Var2<BR>ret<o:p></o:p></SPAN></P>
3 Q3 X9 U: j' {' I/ m. U
<P><SPAN lang=EN-US>MyProc endp<o:p></o:p></SPAN></P>
+ ^! E: X* _6 A0 \: \6 [. [ z
<P>編譯器會自動的在<SPAN lang=EN-US> mov eax,Var1 前面插上一句 Enter 語句,它的參數(shù)會根據(jù) local 定義的局部變量的多少自動指定,在 ret 前會自動加上一句 Leave,同樣,編譯器會根據(jù)參數(shù)的多少把 ret 替換成 ret xxx,把 mov eax,Var1 換成 mov eax,dword ptr [ebp + 8] 等等。<o:p></o:p></SPAN></P>
+ z' k: z0 U$ C1 N/ A
<P>最后是使用<SPAN lang=EN-US> Masm32 的 invoke 宏指令,在前面可以看到,調(diào)用帶參數(shù)的子程序時,我們需要用 push 把參數(shù)壓入堆棧,如果不小心把參數(shù)個數(shù)搞錯了,就會使堆棧不平衡,從而使程序從堆棧中取出錯誤的返回地址引起不可預(yù)料的后果,所以有必要有一條語句來完成自動檢驗的任務(wù),invoke 就是這樣的語句,實際上,它是自動 push 所有參數(shù),檢測參數(shù)個數(shù)、類型是否正確,并使用 call 來調(diào)用的一個宏指令,對于上面的 push/push/call MyProc 的指令,可以用一條指令完成就是:<o:p></o:p></SPAN></P>
* \5 E% l6 ]5 @* |, X9 |# ?+ @* X
<P><SPAN lang=EN-US>invoke MyProc,Var1,Var2<o:p></o:p></SPAN></P>
! a) c9 H7 b# I( c
<P>當(dāng)然,當(dāng)程序編譯好以后你去看機器碼會發(fā)現(xiàn)它被正確地?fù)Q成了同樣的<SPAN lang=EN-US> push/push/call 指令。但是,在使用 invoke 之前,為了讓它進(jìn)行正確的參數(shù)檢驗,你需要對函數(shù)進(jìn)行申明,就象在 C 中一樣,申明的語句是:<o:p></o:p></SPAN></P>
( _2 O* e3 [& n1 \
<P><SPAN lang=EN-US>MyProc proto :DWORD,:DWORD<o:p></o:p></SPAN></P>
0 I: q, F% ? i( }! h6 b
<P>語句中<SPAN lang=EN-US> proto 是關(guān)鍵字,表示申明,:DWORD 表示參數(shù)的類型是 double word 類型的,有幾個就表示有幾個參數(shù),在 Win32 中參數(shù)都是 double word 型的,申明語句要寫在 invoke 之前,所以我們一般把它包括在 include 文件中,好了,綜合一下,在 Masm32 中使用一個帶參數(shù)的子程序或者 Api ,我們只需用:<o:p></o:p></SPAN></P>
$ k, T- k# O( c* T$ H \$ C* Y
<P><SPAN lang=EN-US>...<BR>MyProc proto :dword,:dword<BR>... <BR>.data<BR>x dd ?<BR>y dd ?<BR>dwResult dd ?<BR>...<BR>mov x,1<BR>mov y,2<BR>invoke MyProc x,y<BR>mov dwResult,eax<BR>... <o:p></o:p></SPAN></P>
歡迎光臨 汶上信息港 (http://www.junkejituan.com/)
Powered by Discuz! X3.5