天天爱天天做天天做天天吃中文|久久综合给久合久久综合|亚洲视频一区二区三区|亚洲国产综合精品2022

  • 
    
    <delect id="ixd07"></delect>

      汶上信息港

      標題: 匯編中參數的傳遞和堆棧修正 [打印本頁]

      作者: hbhdgpyz    時間: 2008-9-28 16:22
      標題: 匯編中參數的傳遞和堆棧修正
      &nbsp;&nbsp;在 Win32匯編中,我們經常要和 Api 打交道,另外也會常常使用自己編制的類似于 Api 的帶參數的子程序,本文要講述的是在子程序調用的過程中進行參數傳遞的概念和分析。一般在程序中,參數的傳遞是通過堆棧進行的,也就是說,調用者把要傳遞給子程序(或者被調用者)的參數壓入堆棧,子程序在堆棧取出相應的值再使用,比如說,如果你要調用 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>也就是說,調用者首先把參數壓入堆棧,然后調用子程序,在完成后,由于堆棧中先前壓入的數不再有用,調用者或者被調用者必須有一方把堆棧指針修正到調用前的狀態(tài)。參數是最右邊的先入堆棧還是最左邊的先入堆棧、還有由調用者還是被調用者來修正堆棧都必須有個約定,不然就會產生不正確的結果,這就是我在前面使用“可能”這兩個字的原因:各種語言中調用子程序的約定是不同的,它們的不同點見下表:<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /><o:p></o:p>
      / |. A+ S1 W; Z% H% v<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>8 Q1 z' t6 m8 q+ r3 Q6 k- @  q4 I- l
      <TBODY>
      . C8 E4 }- o& I6 ^7 x/ m3 ^<TR>
      5 V7 D: ]9 F* w: `. |7 {<TD style="PADDING-RIGHT: 0cm; PADDING-LEFT: 0cm; BACKGROUND: #66cccc; PADDING-BOTTOM: 0cm; PADDING-TOP: 0cm">0 b1 _. H3 j2 `) [9 L4 u' I
      <P class=MsoNormal><SPAN lang=EN-US>&nbsp;</SPAN><SPAN lang=EN-US style="FONT-SIZE: 12pt; FONT-FAMILY: 宋體"><o:p></o:p></SPAN></P></TD>1 s" z: M7 \* U
      <TD style="PADDING-RIGHT: 0cm; PADDING-LEFT: 0cm; BACKGROUND: #66cccc; PADDING-BOTTOM: 0cm; PADDING-TOP: 0cm"># C2 [% w' q) c1 U' G
      <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>
      3 P5 t. o- F) ~6 W2 ]- E( X3 R<TD style="PADDING-RIGHT: 0cm; PADDING-LEFT: 0cm; BACKGROUND: #66cccc; PADDING-BOTTOM: 0cm; PADDING-TOP: 0cm">
      - f0 G5 j# d) J9 j% U# {1 L2 u( s<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>. i. N# n6 x: n  {3 L: ^) I% B) j
      <TD style="PADDING-RIGHT: 0cm; PADDING-LEFT: 0cm; BACKGROUND: #66cccc; PADDING-BOTTOM: 0cm; PADDING-TOP: 0cm">
      3 {" S2 j  h- C1 D* Y) Z% n0 J<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>  j, L0 C0 o4 n8 ]- ?& a4 z$ K
      <TD style="PADDING-RIGHT: 0cm; PADDING-LEFT: 0cm; BACKGROUND: #66cccc; PADDING-BOTTOM: 0cm; PADDING-TOP: 0cm">
      9 ]& S; U/ K! |# P% F& e1 c9 n0 b<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>8 H6 y$ v2 Y; d8 ~
      <TD style="PADDING-RIGHT: 0cm; PADDING-LEFT: 0cm; BACKGROUND: #66cccc; PADDING-BOTTOM: 0cm; PADDING-TOP: 0cm">$ f* u0 U% y' ]. V# x9 M1 c' Y
      <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>
      " C+ e% o7 G6 P+ @0 @<TD style="PADDING-RIGHT: 0cm; PADDING-LEFT: 0cm; BACKGROUND: #66cccc; PADDING-BOTTOM: 0cm; PADDING-TOP: 0cm">3 @6 r0 R# O( q; n, i
      <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>
      4 i8 V9 Z% A% R# i+ ]<TR>
      / v' `1 h  x5 c4 a0 r4 I0 Q. }0 [<TD style="PADDING-RIGHT: 0cm; PADDING-LEFT: 0cm; BACKGROUND: #66cccc; PADDING-BOTTOM: 0cm; WIDTH: 28%; PADDING-TOP: 0cm" width="28%">) z6 P# z4 G- ~8 A$ v' x  T
      <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 style="FONT-SIZE: 12pt; FONT-FAMILY: 宋體"><o:p></o:p></SPAN></P></TD>
      , e* J* d7 L( e: P& u) ?<TD style="PADDING-RIGHT: 0cm; PADDING-LEFT: 0cm; BACKGROUND: #ccccff; PADDING-BOTTOM: 0cm; WIDTH: 12%; PADDING-TOP: 0cm" width="12%">8 V3 S. p9 @: H
      <P class=MsoNormal style="TEXT-ALIGN: center" align=center><SPAN lang=EN-US>&nbsp;</SPAN><SPAN lang=EN-US style="FONT-SIZE: 12pt; FONT-FAMILY: 宋體"><o:p></o:p></SPAN></P></TD>
      3 K) z( F; e; u: ]  K1 ~) h<TD style="PADDING-RIGHT: 0cm; PADDING-LEFT: 0cm; BACKGROUND: #ccccff; PADDING-BOTTOM: 0cm; WIDTH: 12%; PADDING-TOP: 0cm" width="12%">7 l/ A9 ~( t+ |% B+ h
      <P class=MsoNormal style="TEXT-ALIGN: center" align=center><SPAN lang=EN-US>&nbsp;</SPAN><SPAN lang=EN-US style="FONT-SIZE: 12pt; FONT-FAMILY: 宋體"><o:p></o:p></SPAN></P></TD>2 m1 X; x* L% d$ N3 N. G. l
      <TD style="PADDING-RIGHT: 0cm; PADDING-LEFT: 0cm; BACKGROUND: #ccccff; PADDING-BOTTOM: 0cm; WIDTH: 12%; PADDING-TOP: 0cm" width="12%">  @; B* ^+ D+ C1 T& v; c
      <P class=MsoNormal style="TEXT-ALIGN: center" align=center><SPAN lang=EN-US>&nbsp;</SPAN><SPAN lang=EN-US style="FONT-SIZE: 12pt; FONT-FAMILY: 宋體"><o:p></o:p></SPAN></P></TD>
      ' R+ B# m9 l  _; ]7 @7 A<TD style="PADDING-RIGHT: 0cm; PADDING-LEFT: 0cm; BACKGROUND: #ccccff; PADDING-BOTTOM: 0cm; WIDTH: 12%; PADDING-TOP: 0cm" width="12%">
      7 _: }& a0 W+ ~: o. l4 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>
      6 ~% T$ R) b# l' e. ?<TD style="PADDING-RIGHT: 0cm; PADDING-LEFT: 0cm; BACKGROUND: #ccccff; PADDING-BOTTOM: 0cm; WIDTH: 12%; PADDING-TOP: 0cm" width="12%">- N! W* S" u# N9 e% [( 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>$ j6 n( X/ a' |) C' j  v
      <TD style="PADDING-RIGHT: 0cm; PADDING-LEFT: 0cm; BACKGROUND: #ccccff; PADDING-BOTTOM: 0cm; WIDTH: 12%; PADDING-TOP: 0cm" width="12%">
      ; u0 C0 p& ~# ^( f<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>
      : x( a2 Q% F, ^  ~; D<TR>: {3 W- D9 v  e# f8 R
      <TD style="PADDING-RIGHT: 0cm; PADDING-LEFT: 0cm; BACKGROUND: #66cccc; PADDING-BOTTOM: 0cm; WIDTH: 28%; PADDING-TOP: 0cm" width="28%">
      % _1 v# E2 |% J, K% G<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 style="FONT-SIZE: 12pt; FONT-FAMILY: 宋體"><o:p></o:p></SPAN></P></TD>
      6 A: u! r" o/ v; M) m, d<TD style="PADDING-RIGHT: 0cm; PADDING-LEFT: 0cm; BACKGROUND: #ccccff; PADDING-BOTTOM: 0cm; WIDTH: 12%; PADDING-TOP: 0cm" width="12%">
      4 l/ X* O& ]. B$ x0 }8 Y<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>5 C% K- N5 n1 H  k+ }  V. B
      <TD style="PADDING-RIGHT: 0cm; PADDING-LEFT: 0cm; BACKGROUND: #ccccff; PADDING-BOTTOM: 0cm; WIDTH: 12%; PADDING-TOP: 0cm" width="12%">
      " K3 G+ X9 K. C9 Z/ F; }9 I7 k/ B<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 c+ A! f! Z$ x, ^$ O# z) C& ]$ I- C4 f
      <TD style="PADDING-RIGHT: 0cm; PADDING-LEFT: 0cm; BACKGROUND: #ccccff; PADDING-BOTTOM: 0cm; WIDTH: 12%; PADDING-TOP: 0cm" width="12%">' G4 o, K0 ^, i
      <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>" P6 J+ i! v0 O. l, @' k
      <TD style="PADDING-RIGHT: 0cm; PADDING-LEFT: 0cm; BACKGROUND: #ccccff; PADDING-BOTTOM: 0cm; WIDTH: 12%; PADDING-TOP: 0cm" width="12%">
        t( h  T0 W" k4 E- u6 h<P class=MsoNormal style="TEXT-ALIGN: center" align=center><SPAN lang=EN-US>&nbsp;</SPAN><SPAN lang=EN-US style="FONT-SIZE: 12pt; FONT-FAMILY: 宋體"><o:p></o:p></SPAN></P></TD>' }! q  W+ c! n  R: P% A, _6 H
      <TD style="PADDING-RIGHT: 0cm; PADDING-LEFT: 0cm; BACKGROUND: #ccccff; PADDING-BOTTOM: 0cm; WIDTH: 12%; PADDING-TOP: 0cm" width="12%">
      3 @* [% r5 d5 N3 d. M<P class=MsoNormal style="TEXT-ALIGN: center" align=center><SPAN lang=EN-US>&nbsp;</SPAN><SPAN lang=EN-US style="FONT-SIZE: 12pt; FONT-FAMILY: 宋體"><o:p></o:p></SPAN></P></TD>
      + V) i3 \% t5 Y3 L- D# V$ f3 C<TD style="PADDING-RIGHT: 0cm; PADDING-LEFT: 0cm; BACKGROUND: #ccccff; PADDING-BOTTOM: 0cm; WIDTH: 12%; PADDING-TOP: 0cm" width="12%">
      5 V  I- d6 i9 U9 h1 ]<P class=MsoNormal style="TEXT-ALIGN: center" align=center><SPAN lang=EN-US>&nbsp;</SPAN><SPAN lang=EN-US style="FONT-SIZE: 12pt; FONT-FAMILY: 宋體"><o:p></o:p></SPAN></P></TD></TR>6 D7 a" T9 n0 p$ w' g4 ~
      <TR>
      * y' M" s' v8 C) n3 C<TD style="PADDING-RIGHT: 0cm; PADDING-LEFT: 0cm; BACKGROUND: #66cccc; PADDING-BOTTOM: 0cm; WIDTH: 28%; PADDING-TOP: 0cm" width="28%">+ c9 n! j. Z0 ?$ J) p
      <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 style="FONT-SIZE: 12pt; FONT-FAMILY: 宋體"><o:p></o:p></SPAN></P></TD>% o" R3 D2 Z9 f" l! A7 \5 l5 O9 C) i4 X
      <TD style="PADDING-RIGHT: 0cm; PADDING-LEFT: 0cm; BACKGROUND: #ccccff; PADDING-BOTTOM: 0cm; WIDTH: 12%; PADDING-TOP: 0cm" width="12%">; I1 I! z5 O+ d! Y8 B
      <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>5 _9 g6 N; |7 ~0 m8 d
      <TD style="PADDING-RIGHT: 0cm; PADDING-LEFT: 0cm; BACKGROUND: #ccccff; PADDING-BOTTOM: 0cm; WIDTH: 12%; PADDING-TOP: 0cm" width="12%">! I# _  T8 F1 J2 b% T
      <P class=MsoNormal style="TEXT-ALIGN: center" align=center><SPAN lang=EN-US>&nbsp;</SPAN><SPAN lang=EN-US style="FONT-SIZE: 12pt; FONT-FAMILY: 宋體"><o:p></o:p></SPAN></P></TD>
      ( J: E) p; G! Q) r<TD style="PADDING-RIGHT: 0cm; PADDING-LEFT: 0cm; BACKGROUND: #ccccff; PADDING-BOTTOM: 0cm; WIDTH: 12%; PADDING-TOP: 0cm" width="12%">* O, Q+ p* f* F
      <P class=MsoNormal style="TEXT-ALIGN: center" align=center><SPAN lang=EN-US>&nbsp;</SPAN><SPAN lang=EN-US style="FONT-SIZE: 12pt; FONT-FAMILY: 宋體"><o:p></o:p></SPAN></P></TD>5 w( `; f% A1 ]' u/ ]: a
      <TD style="PADDING-RIGHT: 0cm; PADDING-LEFT: 0cm; BACKGROUND: #ccccff; PADDING-BOTTOM: 0cm; WIDTH: 12%; PADDING-TOP: 0cm" width="12%">) r$ E3 f( O+ g- q5 M4 }9 |* {; H
      <P class=MsoNormal style="TEXT-ALIGN: center" align=center><SPAN lang=EN-US>&nbsp;</SPAN><SPAN lang=EN-US style="FONT-SIZE: 12pt; FONT-FAMILY: 宋體"><o:p></o:p></SPAN></P></TD>
      ! G$ T2 p) v. s* ]& I' Q9 p% Q+ U) q<TD style="PADDING-RIGHT: 0cm; PADDING-LEFT: 0cm; BACKGROUND: #ccccff; PADDING-BOTTOM: 0cm; WIDTH: 12%; PADDING-TOP: 0cm" width="12%">+ L2 O) L" `* `" f- U
      <P class=MsoNormal style="TEXT-ALIGN: center" align=center><SPAN lang=EN-US>&nbsp;</SPAN><SPAN lang=EN-US style="FONT-SIZE: 12pt; FONT-FAMILY: 宋體"><o:p></o:p></SPAN></P></TD>3 y) j; O' u- c0 i' S( M% Q8 q
      <TD style="PADDING-RIGHT: 0cm; PADDING-LEFT: 0cm; BACKGROUND: #ccccff; PADDING-BOTTOM: 0cm; WIDTH: 12%; PADDING-TOP: 0cm" width="12%">
      ! w" c5 D! [# k$ R6 {3 g<P class=MsoNormal style="TEXT-ALIGN: center" align=center><SPAN lang=EN-US>&nbsp;</SPAN><SPAN lang=EN-US style="FONT-SIZE: 12pt; FONT-FAMILY: 宋體"><o:p></o:p></SPAN></P></TD></TR>
      - ~. \# Q+ w9 P7 k<TR>$ Y6 Q6 V0 H0 g2 d* W% P4 Z; P. g
      <TD style="PADDING-RIGHT: 0cm; PADDING-LEFT: 0cm; BACKGROUND: #66cccc; PADDING-BOTTOM: 0cm; WIDTH: 28%; PADDING-TOP: 0cm" width="28%">
      . r3 g7 e/ o! v/ f: @<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>
        L4 M# N& m& a% E. m/ m' B' ]<TD style="PADDING-RIGHT: 0cm; PADDING-LEFT: 0cm; BACKGROUND: #ccccff; PADDING-BOTTOM: 0cm; WIDTH: 12%; PADDING-TOP: 0cm" width="12%">$ S  I1 k- e4 C% A/ 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>: [- Y5 g: i! V, r, k
      <TD style="PADDING-RIGHT: 0cm; PADDING-LEFT: 0cm; BACKGROUND: #ccccff; PADDING-BOTTOM: 0cm; WIDTH: 12%; PADDING-TOP: 0cm" width="12%">
      6 K: |  E" q& U7 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>
      6 I  t2 C- c  k7 w; d* i<TD style="PADDING-RIGHT: 0cm; PADDING-LEFT: 0cm; BACKGROUND: #ccccff; PADDING-BOTTOM: 0cm; WIDTH: 12%; PADDING-TOP: 0cm" width="12%">
      ) y  s. D' H' ^+ y0 ]<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>* Q, k2 `0 i; Y7 ^, m" ~) T
      <TD style="PADDING-RIGHT: 0cm; PADDING-LEFT: 0cm; BACKGROUND: #ccccff; PADDING-BOTTOM: 0cm; WIDTH: 12%; PADDING-TOP: 0cm" width="12%">
      " D9 j( I: z8 ~9 b+ _<P class=MsoNormal style="TEXT-ALIGN: center" align=center><SPAN lang=EN-US>&nbsp;</SPAN><SPAN lang=EN-US style="FONT-SIZE: 12pt; FONT-FAMILY: 宋體"><o:p></o:p></SPAN></P></TD>" B' n! R, _9 p5 g, g0 L( N
      <TD style="PADDING-RIGHT: 0cm; PADDING-LEFT: 0cm; BACKGROUND: #ccccff; PADDING-BOTTOM: 0cm; WIDTH: 12%; PADDING-TOP: 0cm" width="12%">/ w- j7 S/ }, C( Z! E! \8 I2 ?: }
      <P class=MsoNormal style="TEXT-ALIGN: center" align=center><SPAN lang=EN-US>&nbsp;</SPAN><SPAN lang=EN-US style="FONT-SIZE: 12pt; FONT-FAMILY: 宋體"><o:p></o:p></SPAN></P></TD>' c2 o0 P7 ?8 J3 s: }
      <TD style="PADDING-RIGHT: 0cm; PADDING-LEFT: 0cm; BACKGROUND: #ccccff; PADDING-BOTTOM: 0cm; WIDTH: 12%; PADDING-TOP: 0cm" width="12%">
      % R5 o- V: |  l+ D, _; C# s  X- ?7 @<P class=MsoNormal style="TEXT-ALIGN: center" align=center><SPAN lang=EN-US>&nbsp;</SPAN><SPAN lang=EN-US style="FONT-SIZE: 12pt; FONT-FAMILY: 宋體"><o:p></o:p></SPAN></P></TD></TR></TBODY></TABLE>5 T0 G3 v% }; w  {- t
      <P><SPAN lang=EN-US>VARARG 表示參數的個數可以是不確定的,有一個例子就是 C 中的 printf 語句,在上表中,StdCall 的定義有個要說明的地方,就是如果 StdCall 使用 :VARARG 時,是由調用者清除堆棧的,而在沒有:VARARG時是由被調用者清除堆棧的。<BR>在 Win32 匯編中,約定使用 StdCall 方式,所以我們要在程序開始的時候使用 .model stdcall 語句。也就是說,在 API 或子程序中,最右邊的參數先入堆棧,然后子程序在返回的時候負責校正堆棧,舉例說明,如果我們要調用 MessageBox 這個 API,因為它的定義是 MessageBox(hWnd,lpText,lpCaption,UType) 所以在程序中要這樣使用:<o:p></o:p></SPAN></P>
      7 t7 X* D1 X* ]<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>
      : Y: N# a6 M7 w, w' l  }<P>我們不必在<SPAN lang=EN-US> API 返回的時候加上一句 add sp,4*4 來修正堆棧,因為這已經由 MessageBox 這個子程序做了。在 Windows API 中,唯一一個特殊的 API 是 wsprintf,這個 API 是 C 約定的,它的定義是 wsprintf(lpOut,lpFormat,Var1,Var2...),所以在使用時就要:<o:p></o:p></SPAN></P>
      7 \1 }, y# l3 n4 r4 N0 O<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>1 ^2 W9 J; ]. ~- v
      <P><SPAN lang=EN-US>&nbsp;<o:p></o:p></SPAN></P>
      . n2 g6 y7 R7 j<P><SPAN lang=EN-US>&nbsp;<o:p></o:p></SPAN></P>
      ; l2 v5 g. n, y3 B<P><SPAN lang=EN-US>&nbsp;<o:p></o:p></SPAN></P>" |/ y$ ~8 f4 Q& F5 _* x
      <P><SPAN lang=EN-US>&nbsp;<o:p></o:p></SPAN></P>
      $ ?. o" e1 T; `3 P<P><SPAN lang=EN-US>&nbsp;<o:p></o:p></SPAN></P>
      ) T( ^/ p* ?( q$ y" P* r+ E<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>下面要講的是子程序如何存取參數,因為缺省對堆棧操作的寄存器有<SPAN lang=EN-US> ESP 和 EBP,而 ESP是堆棧指針,無法暫借使用,所以一般使用 EBP 來存取堆棧,假定在一個調用中有兩個參數,而且在 push 第一個參數前的堆棧指針 ESP 為 X,那么壓入兩個參數后的 ESP 為 X-8,程序開始執(zhí)行 call 指令,call 指令把返回地址壓入堆棧,這時候 ESP 為 X-C,這時已經在子程序中了,我們可以開始使用 EBP 來存取參數了,但為了在返回時恢復 EBP 的值,我們還是再需要一句 push ebp 來先保存 EBP 的值,這時 ESP 為 X-10,再執(zhí)行一句 mov ebp,esp,根據右圖可以看出,實際上這時候 [ebp + 8] 就是參數1,[ebp + c]就是參數2。另外,局部變量也是定義在堆棧中的,它們的位置一般放在 push ebp 保存的 EBP 數值的后面,局部變量1、2對應的地址分別是 [ebp-4]、[ebp-8],下面是一個典型的子程序,可以完成第一個參數減去第二個參數,它的定義是:<BR><BR>MyProc proto Var1,Var2 ;有兩個參數<BR>local lVar1,lVar2 ;有兩個局部變量<o:p></o:p></SPAN></P>& G: F. u7 }- Z5 }: `8 P
      <P>注意,這里的兩個<SPAN lang=EN-US> local 變量實際上沒有被用到,只是為了演示用,具體實現的代碼是:<BR><BR>MyProc proc<BR><BR>push ebp<BR>mov ebp,esp<o:p></o:p></SPAN></P>" M0 R; V: F" p8 q, I
      <P><SPAN lang=EN-US>sub esp,8<o:p></o:p></SPAN></P>2 Q9 Z4 B; l; ^) O! A: v) I1 p+ Y$ \
      <P><SPAN lang=EN-US>mov eax,dword ptr [ebp + 8]<BR>sub eax,dword ptr [ebp + c]<o:p></o:p></SPAN></P>
      , q2 y, G4 c8 |/ A( ^<P><SPAN lang=EN-US>add esp,8<o:p></o:p></SPAN></P>0 Z5 ]7 z; s% r# G/ c% N
      <P><SPAN lang=EN-US>pop ebp<BR>ret 8<o:p></o:p></SPAN></P>
      " Q) j6 q% m, V7 {. i& i3 X<P><SPAN lang=EN-US>MyProc endp<BR><BR>現在對這個子程序分析一下,push ebp/mov ebp,esp 是例行的保存和設置 EBP 的代碼,sub esp,8 在堆棧中留出兩個局部變量的空間,mov /add 語句完成相加,add esp,8 修正兩個局部變量使用的堆棧,ret 8 修正兩個參數使用的堆棧,相當于 ret / add esp,8 兩句代碼的效果??梢钥闯?,這是一個標準的 Stdcall 約定的子程序,使用時最后一個參數先入堆棧,返回時由子程序進行堆棧修正。當然,這個子程序為了演示執(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>$ q# Z7 l& P9 F& @
      <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>2 K: I5 e" @5 B: Z9 E/ Y
      <P>好了,說到這兒,參數傳遞的原理也應該將清楚了,還要最后說的是,在使用<SPAN lang=EN-US> Masm32 編 Win32 匯編程序的時候,我們并不需要記住 [ebp + xx] 等麻煩的地址,或自己計算局部變量需要預留的堆棧空間,還有在 ret 時計算要加上的數值,Masm32 的宏指令都已經把這些做好了,如在 Masm32 中,上面的程序只要寫成為:<o:p></o:p></SPAN></P>; b( p. D, r  B' t
      <P><SPAN lang=EN-US>MyProc proc Var1,Var2<BR>local lVar1,lVar2<o:p></o:p></SPAN></P>
      . o6 W( K6 C# t. p; d<P><SPAN lang=EN-US>mov eax,Var1<BR>sub eax,Var2<BR>ret<o:p></o:p></SPAN></P>+ m: S! u4 Q* p; f+ O% A. J
      <P><SPAN lang=EN-US>MyProc endp<o:p></o:p></SPAN></P>8 P- k9 K2 N( b
      <P>編譯器會自動的在<SPAN lang=EN-US> mov eax,Var1 前面插上一句 Enter 語句,它的參數會根據 local 定義的局部變量的多少自動指定,在 ret 前會自動加上一句 Leave,同樣,編譯器會根據參數的多少把 ret 替換成 ret xxx,把 mov eax,Var1 換成 mov eax,dword ptr [ebp + 8] 等等。<o:p></o:p></SPAN></P>
      8 P& O( Q4 a( D<P>最后是使用<SPAN lang=EN-US> Masm32 的 invoke 宏指令,在前面可以看到,調用帶參數的子程序時,我們需要用 push 把參數壓入堆棧,如果不小心把參數個數搞錯了,就會使堆棧不平衡,從而使程序從堆棧中取出錯誤的返回地址引起不可預料的后果,所以有必要有一條語句來完成自動檢驗的任務,invoke 就是這樣的語句,實際上,它是自動 push 所有參數,檢測參數個數、類型是否正確,并使用 call 來調用的一個宏指令,對于上面的 push/push/call MyProc 的指令,可以用一條指令完成就是:<o:p></o:p></SPAN></P>
      # k, J- l- }- b4 a% z<P><SPAN lang=EN-US>invoke MyProc,Var1,Var2<o:p></o:p></SPAN></P>1 k+ ?, Q  ~& J
      <P>當然,當程序編譯好以后你去看機器碼會發(fā)現它被正確地換成了同樣的<SPAN lang=EN-US> push/push/call 指令。但是,在使用 invoke 之前,為了讓它進行正確的參數檢驗,你需要對函數進行申明,就象在 C 中一樣,申明的語句是:<o:p></o:p></SPAN></P>
      6 l+ |. [) ]! \; J4 b: v<P><SPAN lang=EN-US>MyProc proto :DWORD,:DWORD<o:p></o:p></SPAN></P>
      - G! j1 I' G, S- u<P>語句中<SPAN lang=EN-US> proto 是關鍵字,表示申明,:DWORD 表示參數的類型是 double word 類型的,有幾個就表示有幾個參數,在 Win32 中參數都是 double word 型的,申明語句要寫在 invoke 之前,所以我們一般把它包括在 include 文件中,好了,綜合一下,在 Masm32 中使用一個帶參數的子程序或者 Api ,我們只需用:<o:p></o:p></SPAN></P>
      , x' v' b: @/ T3 ^. H+ C<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