天天爱天天做天天做天天吃中文|久久综合给久合久久综合|亚洲视频一区二区三区|亚洲国产综合精品2022
汶上信息港
標題:
匯編中參數(shù)的傳遞和堆棧修正
[打印本頁]
作者:
hbhdgpyz
時間:
2008-9-28 16:22
標題:
匯編中參數(shù)的傳遞和堆棧修正
在 Win32匯編中,我們經(jīng)常要和 Api 打交道,另外也會常常使用自己編制的類似于 Api 的帶參數(shù)的子程序,本文要講述的是在子程序調(diào)用的過程中進行參數(shù)傳遞的概念和分析。一般在程序中,參數(shù)的傳遞是通過堆棧進行的,也就是說,調(diào)用者把要傳遞給子程序(或者被調(diào)用者)的參數(shù)壓入堆棧,子程序在堆棧取出相應的值再使用,比如說,如果你要調(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>
2 d' u- W7 R1 Y' d& b
<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>
$ Y- U6 v3 [' J8 `
<TBODY>
5 k4 _3 q& L( r$ O/ I6 i
<TR>
# Z0 o, |- O1 E8 K( p- Z9 p
<TD style="PADDING-RIGHT: 0cm; PADDING-LEFT: 0cm; BACKGROUND: #66cccc; PADDING-BOTTOM: 0cm; PADDING-TOP: 0cm">
% n, s3 H0 i6 [; e2 @6 d
<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>
E1 \% `6 N. X- K
<TD style="PADDING-RIGHT: 0cm; PADDING-LEFT: 0cm; BACKGROUND: #66cccc; PADDING-BOTTOM: 0cm; PADDING-TOP: 0cm">
9 n3 g8 [6 i3 o" v 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>
$ [- H) N# i0 |( t- w0 @
<TD style="PADDING-RIGHT: 0cm; PADDING-LEFT: 0cm; BACKGROUND: #66cccc; PADDING-BOTTOM: 0cm; PADDING-TOP: 0cm">
: p8 l, F1 Z: }/ {- P
<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>
3 }+ Q9 B: a1 F) F5 A1 y
<TD style="PADDING-RIGHT: 0cm; PADDING-LEFT: 0cm; BACKGROUND: #66cccc; PADDING-BOTTOM: 0cm; PADDING-TOP: 0cm">
' y% |: \3 U* ]% ~; ?( c2 k
<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>
0 t- {3 s. z9 W
<TD style="PADDING-RIGHT: 0cm; PADDING-LEFT: 0cm; BACKGROUND: #66cccc; PADDING-BOTTOM: 0cm; PADDING-TOP: 0cm">
4 w* W5 L) `- C. f& J+ p& Y- W
<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>
" p, m. m# _# W2 s% E6 @2 m; A8 T
<TD style="PADDING-RIGHT: 0cm; PADDING-LEFT: 0cm; BACKGROUND: #66cccc; PADDING-BOTTOM: 0cm; PADDING-TOP: 0cm">
3 z+ A; o5 ]; P) N8 `, L
<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>
8 {2 W! n2 k$ [
<TD style="PADDING-RIGHT: 0cm; PADDING-LEFT: 0cm; BACKGROUND: #66cccc; PADDING-BOTTOM: 0cm; PADDING-TOP: 0cm">
( w: [/ t0 j) b% U" C5 q! s; d
<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>
. q3 L7 ? T9 S+ O6 G! H
<TR>
/ s ]6 C8 R$ v' Y9 B# x
<TD style="PADDING-RIGHT: 0cm; PADDING-LEFT: 0cm; BACKGROUND: #66cccc; PADDING-BOTTOM: 0cm; WIDTH: 28%; PADDING-TOP: 0cm" width="28%">
& I4 x j: z. }1 u/ q1 Q' g
<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>
/ ]& f% o% H" R/ t. }2 H. B m0 w
<TD style="PADDING-RIGHT: 0cm; PADDING-LEFT: 0cm; BACKGROUND: #ccccff; PADDING-BOTTOM: 0cm; WIDTH: 12%; PADDING-TOP: 0cm" width="12%">
, K- t3 N: E2 [
<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 P/ O- N0 C3 k7 V
<TD style="PADDING-RIGHT: 0cm; PADDING-LEFT: 0cm; BACKGROUND: #ccccff; PADDING-BOTTOM: 0cm; WIDTH: 12%; PADDING-TOP: 0cm" width="12%">
; P+ w6 I$ I4 O1 e1 A- c. E* _
<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>
; L" A& ~7 i# _- f9 u. p2 S
<TD style="PADDING-RIGHT: 0cm; PADDING-LEFT: 0cm; BACKGROUND: #ccccff; PADDING-BOTTOM: 0cm; WIDTH: 12%; PADDING-TOP: 0cm" width="12%">
4 W. z1 ~' v) C$ e/ K
<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>
0 f' Q% U) a' O& y6 x% _
<TD style="PADDING-RIGHT: 0cm; PADDING-LEFT: 0cm; BACKGROUND: #ccccff; PADDING-BOTTOM: 0cm; WIDTH: 12%; PADDING-TOP: 0cm" width="12%">
' r7 _. b- z6 U& _$ T9 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>
9 e! L. [# e8 `, @, Z. p! ?3 y
<TD style="PADDING-RIGHT: 0cm; PADDING-LEFT: 0cm; BACKGROUND: #ccccff; PADDING-BOTTOM: 0cm; WIDTH: 12%; PADDING-TOP: 0cm" width="12%">
! N5 F! I9 |( _- P* d5 |3 U
<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>
4 N) Q; O! y+ q5 b& v
<TD style="PADDING-RIGHT: 0cm; PADDING-LEFT: 0cm; BACKGROUND: #ccccff; PADDING-BOTTOM: 0cm; WIDTH: 12%; PADDING-TOP: 0cm" width="12%">
4 T0 r$ D! j" R5 E& P4 Q3 x% r# w
<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>
8 e# i# u3 q3 _" S; o1 v y3 n$ S
<TR>
/ x! B9 X0 N J+ ^3 v
<TD style="PADDING-RIGHT: 0cm; PADDING-LEFT: 0cm; BACKGROUND: #66cccc; PADDING-BOTTOM: 0cm; WIDTH: 28%; PADDING-TOP: 0cm" width="28%">
; m8 v- i) O* F6 S) U) h7 c1 v* m0 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>
" ?! P3 }+ t3 u9 {/ w
<TD style="PADDING-RIGHT: 0cm; PADDING-LEFT: 0cm; BACKGROUND: #ccccff; PADDING-BOTTOM: 0cm; WIDTH: 12%; PADDING-TOP: 0cm" width="12%">
d; J R. m8 x; a+ T
<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# A2 }. K( X2 v8 \) l" R! v
<TD style="PADDING-RIGHT: 0cm; PADDING-LEFT: 0cm; BACKGROUND: #ccccff; PADDING-BOTTOM: 0cm; WIDTH: 12%; PADDING-TOP: 0cm" width="12%">
7 M' _; C9 c' m5 r5 v" r
<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 @; q: V# s4 Y1 J* l. @0 N
<TD style="PADDING-RIGHT: 0cm; PADDING-LEFT: 0cm; BACKGROUND: #ccccff; PADDING-BOTTOM: 0cm; WIDTH: 12%; PADDING-TOP: 0cm" width="12%">
3 K9 c1 R6 Y! b8 L9 M, ]
<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>
2 {& W: s2 Z/ y: |5 |) R
<TD style="PADDING-RIGHT: 0cm; PADDING-LEFT: 0cm; BACKGROUND: #ccccff; PADDING-BOTTOM: 0cm; WIDTH: 12%; PADDING-TOP: 0cm" width="12%">
5 l0 n2 o/ m2 u; R3 u# a
<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>
/ x$ H8 q( x: W0 \8 \ s
<TD style="PADDING-RIGHT: 0cm; PADDING-LEFT: 0cm; BACKGROUND: #ccccff; PADDING-BOTTOM: 0cm; WIDTH: 12%; PADDING-TOP: 0cm" width="12%">
( j- l2 I) Y5 d8 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>
3 d7 v6 C: X/ P3 P& W
<TD style="PADDING-RIGHT: 0cm; PADDING-LEFT: 0cm; BACKGROUND: #ccccff; PADDING-BOTTOM: 0cm; WIDTH: 12%; PADDING-TOP: 0cm" width="12%">
) c& y1 X8 _* Q$ j' K; ]2 V9 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></TR>
* F2 Y: \! ~* d/ [) S
<TR>
) w9 B! \2 M c0 Y& X/ V
<TD style="PADDING-RIGHT: 0cm; PADDING-LEFT: 0cm; BACKGROUND: #66cccc; PADDING-BOTTOM: 0cm; WIDTH: 28%; PADDING-TOP: 0cm" width="28%">
6 L% a! d8 Z6 `, J* A# o) a% _
<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>
* M" N) a |( d( s5 c! i
<TD style="PADDING-RIGHT: 0cm; PADDING-LEFT: 0cm; BACKGROUND: #ccccff; PADDING-BOTTOM: 0cm; WIDTH: 12%; PADDING-TOP: 0cm" width="12%">
1 b6 S7 j6 a g7 M5 }8 H
<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>
# q3 b- i! M" G2 \/ a+ m
<TD style="PADDING-RIGHT: 0cm; PADDING-LEFT: 0cm; BACKGROUND: #ccccff; PADDING-BOTTOM: 0cm; WIDTH: 12%; PADDING-TOP: 0cm" width="12%">
: i- g( a* @# L+ s3 X
<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>
, Z5 |; q0 G+ N c
<TD style="PADDING-RIGHT: 0cm; PADDING-LEFT: 0cm; BACKGROUND: #ccccff; PADDING-BOTTOM: 0cm; WIDTH: 12%; PADDING-TOP: 0cm" width="12%">
. U' B. ? q- W5 y6 x" 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>
7 I9 i9 Q% k! Q( F1 n- }: U2 g; }- ]4 n8 K" r
<TD style="PADDING-RIGHT: 0cm; PADDING-LEFT: 0cm; BACKGROUND: #ccccff; PADDING-BOTTOM: 0cm; WIDTH: 12%; PADDING-TOP: 0cm" width="12%">
2 g) P: h6 |1 t! T6 e0 a
<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 Z8 c' z2 }3 Q/ \* N' S
<TD style="PADDING-RIGHT: 0cm; PADDING-LEFT: 0cm; BACKGROUND: #ccccff; PADDING-BOTTOM: 0cm; WIDTH: 12%; PADDING-TOP: 0cm" width="12%">
4 i$ `/ \( F' t5 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>
, U6 e/ i# e* m! y5 H# ~
<TD style="PADDING-RIGHT: 0cm; PADDING-LEFT: 0cm; BACKGROUND: #ccccff; PADDING-BOTTOM: 0cm; WIDTH: 12%; PADDING-TOP: 0cm" width="12%">
. y; |, m [8 r* }& W/ 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>
. e( m7 H1 a( c2 ~; ]
<TR>
6 p+ |; | O' {& ?+ U3 A
<TD style="PADDING-RIGHT: 0cm; PADDING-LEFT: 0cm; BACKGROUND: #66cccc; PADDING-BOTTOM: 0cm; WIDTH: 28%; PADDING-TOP: 0cm" width="28%">
1 ? r) E0 l6 d9 h Y" Y% n
<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>
7 `" Q) i4 s X# ^
<TD style="PADDING-RIGHT: 0cm; PADDING-LEFT: 0cm; BACKGROUND: #ccccff; PADDING-BOTTOM: 0cm; WIDTH: 12%; PADDING-TOP: 0cm" width="12%">
8 }9 d# q; v. ~
<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>
2 F% \. O. {3 e( d0 ^- x4 n
<TD style="PADDING-RIGHT: 0cm; PADDING-LEFT: 0cm; BACKGROUND: #ccccff; PADDING-BOTTOM: 0cm; WIDTH: 12%; PADDING-TOP: 0cm" width="12%">
. \. b- X3 [' j. z% Z
<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 I9 A+ T6 }/ f3 c" A
<TD style="PADDING-RIGHT: 0cm; PADDING-LEFT: 0cm; BACKGROUND: #ccccff; PADDING-BOTTOM: 0cm; WIDTH: 12%; PADDING-TOP: 0cm" width="12%">
1 {0 O# l0 x6 ^7 Q( g# d; z
<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>
) s+ j# z' p1 F2 P8 _2 Z8 l; p
<TD style="PADDING-RIGHT: 0cm; PADDING-LEFT: 0cm; BACKGROUND: #ccccff; PADDING-BOTTOM: 0cm; WIDTH: 12%; PADDING-TOP: 0cm" width="12%">
" p, C- W! n. n8 }; Y 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>
& \. a' ?8 C( ?( E9 l# V( L/ d
<TD style="PADDING-RIGHT: 0cm; PADDING-LEFT: 0cm; BACKGROUND: #ccccff; PADDING-BOTTOM: 0cm; WIDTH: 12%; PADDING-TOP: 0cm" width="12%">
8 I/ x3 _" k7 L: `0 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>
8 {+ r1 B; T; T( o# ?0 ?
<TD style="PADDING-RIGHT: 0cm; PADDING-LEFT: 0cm; BACKGROUND: #ccccff; PADDING-BOTTOM: 0cm; WIDTH: 12%; PADDING-TOP: 0cm" width="12%">
% e9 h2 @4 c+ b4 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></TR></TBODY></TABLE>
% A' ~+ A# ^! \) O
<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ù)先入堆棧,然后子程序在返回的時候負責校正堆棧,舉例說明,如果我們要調(diào)用 MessageBox 這個 API,因為它的定義是 MessageBox(hWnd,lpText,lpCaption,UType) 所以在程序中要這樣使用:<o:p></o:p></SPAN></P>
8 q& j! E. x4 O6 |; _6 O
<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* p) h0 T+ R. Z
<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>
! p) M2 G8 H. G. t6 Y
<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>
! J, G6 ~1 V& @1 n8 N
<P><SPAN lang=EN-US> <o:p></o:p></SPAN></P>
9 V2 V N2 R1 K7 H$ \; A! \
<P><SPAN lang=EN-US> <o:p></o:p></SPAN></P>
7 F1 ~3 F' p7 M5 k% ~! b
<P><SPAN lang=EN-US> <o:p></o:p></SPAN></P>
0 `; B4 A& ?; d: }, O5 L7 [( f
<P><SPAN lang=EN-US> <o:p></o:p></SPAN></P>
/ x. W4 \, L7 ?" e* U
<P><SPAN lang=EN-US> <o:p></o:p></SPAN></P>
% d3 K* `6 [6 n I$ \
<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ù)了,但為了在返回時恢復 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對應的地址分別是 [ebp-4]、[ebp-8],下面是一個典型的子程序,可以完成第一個參數(shù)減去第二個參數(shù),它的定義是:<BR><BR>MyProc proto Var1,Var2 ;有兩個參數(shù)<BR>local lVar1,lVar2 ;有兩個局部變量<o:p></o:p></SPAN></P>
7 O; V2 ]; E! @ T+ `
<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>
$ G5 W3 q5 i6 J- B# J
<P><SPAN lang=EN-US>sub esp,8<o:p></o:p></SPAN></P>
6 _) A' O$ Y6 Z8 ?& k
<P><SPAN lang=EN-US>mov eax,dword ptr [ebp + 8]<BR>sub eax,dword ptr [ebp + c]<o:p></o:p></SPAN></P>
+ J: S- n2 i0 z4 `5 t: e
<P><SPAN lang=EN-US>add esp,8<o:p></o:p></SPAN></P>
2 W( A+ ?% Q6 k* p7 A, {
<P><SPAN lang=EN-US>pop ebp<BR>ret 8<o:p></o:p></SPAN></P>
6 D! V9 R6 G Q
<P><SPAN lang=EN-US>MyProc endp<BR><BR>現(xiàn)在對這個子程序分析一下,push ebp/mov ebp,esp 是例行的保存和設置 EBP 的代碼,sub esp,8 在堆棧中留出兩個局部變量的空間,mov /add 語句完成相加,add esp,8 修正兩個局部變量使用的堆棧,ret 8 修正兩個參數(shù)使用的堆棧,相當于 ret / add esp,8 兩句代碼的效果??梢钥闯?,這是一個標準的 Stdcall 約定的子程序,使用時最后一個參數(shù)先入堆棧,返回時由子程序進行堆棧修正。當然,這個子程序為了演示執(zhí)行過程,使用了手工保存 ebp 并設置局部變量的方法,實際上,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>
& |- l. u* R; ?3 o0 W- e3 C8 S8 R
<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>
. J' O! s; G6 {+ ]+ J
<P>好了,說到這兒,參數(shù)傳遞的原理也應該將清楚了,還要最后說的是,在使用<SPAN lang=EN-US> Masm32 編 Win32 匯編程序的時候,我們并不需要記住 [ebp + xx] 等麻煩的地址,或自己計算局部變量需要預留的堆??臻g,還有在 ret 時計算要加上的數(shù)值,Masm32 的宏指令都已經(jīng)把這些做好了,如在 Masm32 中,上面的程序只要寫成為:<o:p></o:p></SPAN></P>
6 G8 u( j; T: ~0 A1 W
<P><SPAN lang=EN-US>MyProc proc Var1,Var2<BR>local lVar1,lVar2<o:p></o:p></SPAN></P>
; ~( v; Y8 e. D
<P><SPAN lang=EN-US>mov eax,Var1<BR>sub eax,Var2<BR>ret<o:p></o:p></SPAN></P>
2 X2 \+ x) {. r
<P><SPAN lang=EN-US>MyProc endp<o:p></o:p></SPAN></P>
5 P7 T' X0 X/ q: ]( E# F: g: a4 I
<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>
# D/ B; s6 H4 ]. w5 w0 r8 m4 z
<P>最后是使用<SPAN lang=EN-US> Masm32 的 invoke 宏指令,在前面可以看到,調(diào)用帶參數(shù)的子程序時,我們需要用 push 把參數(shù)壓入堆棧,如果不小心把參數(shù)個數(shù)搞錯了,就會使堆棧不平衡,從而使程序從堆棧中取出錯誤的返回地址引起不可預料的后果,所以有必要有一條語句來完成自動檢驗的任務,invoke 就是這樣的語句,實際上,它是自動 push 所有參數(shù),檢測參數(shù)個數(shù)、類型是否正確,并使用 call 來調(diào)用的一個宏指令,對于上面的 push/push/call MyProc 的指令,可以用一條指令完成就是:<o:p></o:p></SPAN></P>
/ r$ M9 }: ?2 g" }$ D( i: c! Z- N
<P><SPAN lang=EN-US>invoke MyProc,Var1,Var2<o:p></o:p></SPAN></P>
1 Q" V1 p. ]3 d; K& J/ q2 F
<P>當然,當程序編譯好以后你去看機器碼會發(fā)現(xiàn)它被正確地換成了同樣的<SPAN lang=EN-US> push/push/call 指令。但是,在使用 invoke 之前,為了讓它進行正確的參數(shù)檢驗,你需要對函數(shù)進行申明,就象在 C 中一樣,申明的語句是:<o:p></o:p></SPAN></P>
8 } }! z' x$ f. f |( v# L
<P><SPAN lang=EN-US>MyProc proto :DWORD,:DWORD<o:p></o:p></SPAN></P>
! @; H8 t" v, k6 @+ c' _
<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>
+ m0 c1 k( N5 `
<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://vancelump.com/)
Powered by Discuz! X3.5