Win32ASM學習[20]:子程序

關于函數調用約定?:函數調用約定

這是以前的一個求和函數的例子
----------------------------------------------------------------------------------------------------------------
.386
.model flat, stdcall

include??? windows.inc
include??? kernel32.inc
include??? masm32.inc
include??? debug.inc
includelib kernel32.lib
includelib masm32.lib
includelib debug.lib

.code
sum proc v1:dword, v2:dword, v3:dword
??? mov eax, v1
??? add eax, v2
??? add eax, v3
??? ret
sum endp
;
main proc
??? invoke sum, 11, 22, 33
??? PrintDec eax; 66
??? ret
main endp
end main
----------------------------------------------------------------------------------------------------------------
把上面的例子改為用寄存器傳遞參數:
----------------------------------------------------------------------------------------------------------------
.386
.model flat, stdcall

include??? windows.inc
include??? kernel32.inc
include??? masm32.inc
include??? debug.inc
includelib kernel32.lib
includelib masm32.lib
includelib debug.lib

.code
sum proc
??? add eax, ecx
??? add eax, edx
??? ret
sum endp
;
main proc
??? mov eax, 11
??? mov ecx, 22
??? mov edx, 33
??? invoke sum
??? PrintDec eax; 66
??? ret
main endp
end main
----------------------------------------------------------------------------------------------------------------
如果調用的函數在之后實現, 須用 PROTO 提前聲明:
----------------------------------------------------------------------------------------------------------------
.386
.model flat, stdcall

include??? windows.inc
include??? kernel32.inc
include??? masm32.inc
include??? debug.inc
includelib kernel32.lib
includelib masm32.lib
includelib debug.lib

;sum proto v1:dword, v2:dword, v3:dword
sum proto :dword, :dword, :dword ;函數聲明的主要是參數類型, 一般省略參數名

.code
main proc
??? invoke sum, 11, 22, 33 ;現在調用的是之后的函數
??? PrintDec eax; 66
??? ret
main endp
;
sum proc v1, v2, v3
??? mov eax, v1
??? add eax, v2
??? add eax, v3
??? ret
sum endp
end main
----------------------------------------------------------------------------------------------------------------
測試 StdCall 模式下的參數壓棧順序:
----------------------------------------------------------------------------------------------------------------
?子程序可以指定語言模式(StaCall、C、SysCall、Basic、Fortran、Pascal);
如果不指定則默認使用在 .model 中指定的語言模式.

StaCall、C、SysCall 是從右到左壓棧參數;
Basic、Fortran、Pascal 是從左到右壓棧參數.
----------------------------------------------------------------------------------------------------------------
.386
.model flat, stdcall

include??? windows.inc
include??? kernel32.inc
include??? masm32.inc
include??? debug.inc
includelib kernel32.lib
includelib masm32.lib
includelib debug.lib

.code
sum proc stdcall v1, v2, v3
??? ;查看參數壓棧順序(StdCall 是從右到左 push)
??? mov edx, [ebp+16]
??? PrintHex edx????? ;33
???
??? mov edx, [ebp+12]
??? PrintHex edx????? ;22
???
??? mov edx, [ebp+8]
??? PrintHex edx????? ;11
???
??? PrintLine
???
??? ;下面求和代碼
??? mov eax, v1
??? add eax, v2
??? add eax, v3
??? ret
sum endp
;
main proc
??? invoke sum, 11h, 22h, 33h
??? PrintDec eax; 66
??? ret
main endp
end main
----------------------------------------------------------------------------------------------------------------
測試 Pascal 模式下的參數壓棧順序:
----------------------------------------------------------------------------------------------------------------
這是和上面的對比練習, 它們的壓棧參數的順序是反的.
其中的 EBX+8 是最后壓棧參數(DWORD)的地址, 同樣 EBX 向上偏移 12、16 就分別是另外兩個參數的地址.
地址 EBX+4 是 RET 將要返回的地址.
為什么參數不是在 EBX 的下偏移? 因為是先壓棧參數在調用函數.
----------------------------------------------------------------------------------------------------------------
.386
.model flat, stdcall

include??? windows.inc
include??? kernel32.inc
include??? masm32.inc
include??? debug.inc
includelib kernel32.lib
includelib masm32.lib
includelib debug.lib

.code
sum proc pascal v1, v2, v3
??? ;查看參數壓棧順序(pascal 是從左到右 push)
??? mov edx, [ebp+16]
??? PrintHex edx????? ;11
???
??? mov edx, [ebp+12]
??? PrintHex edx????? ;22
???
??? mov edx, [ebp+8]
??? PrintHex edx????? ;33
???
??? PrintLine
???
??? ;下面求和代碼
??? mov eax, v1
??? add eax, v2
??? add eax, v3
??? ret
sum endp
;
main proc
??? invoke sum, 11h, 22h, 33h
??? PrintDec eax; 66
??? ret
main endp
end main
----------------------------------------------------------------------------------------------------------------
如果用 Call 代替 invoke 能更好地理解壓參順序:
----------------------------------------------------------------------------------------------------------------
.386
.model flat, stdcall

include??? windows.inc
include??? kernel32.inc
include??? masm32.inc
include??? debug.inc
includelib kernel32.lib
includelib masm32.lib
includelib debug.lib

.code
ViewParam proc C v1, v2, v3 ;把這里的 C 換為 pascal 會有完全不同的結果
??? PrintDec v1 ;11
??? PrintDec v2 ;22
??? PrintDec v3 ;33
??? ret
ViewParam endp
;
main proc
??? push 33
??? push 22
??? push 11
??? call ViewParam
??? leave ;leave 是上面幾個 push 的反操作, 省了不少 pop
??? ret
main endp
end main
----------------------------------------------------------------------------------------------------------------
子過程使用 uses 保護寄存器:
----------------------------------------------------------------------------------------------------------------
?所謂保護就是在子過程執行前先壓棧, 執行后在出棧.
----------------------------------------------------------------------------------------------------------------
.386
.model flat, stdcall

include??? windows.inc
include??? kernel32.inc
include??? masm32.inc
include??? debug.inc
includelib kernel32.lib
includelib masm32.lib
includelib debug.lib

.data
??? dwVal dd ?
.code
sum proc stdcall uses eax ecx edx, v1, v2, v3 ;這其中的 stdcall 可省略
??? mov eax, v1
??? mov ecx, v2
??? mov edx, v3
??? add eax, ecx
??? add eax, edx
??? mov dwVal, eax
??? ret
sum endp
;
main proc
??? ;sum 對這三個寄存器進行的保護, 先給些測試值
??? mov eax, 7
??? mov ecx, 8
??? mov edx, 9
???
??? invoke sum, 11, 22, 33
??? PrintDec dwVal ;66
???
??? PrintDec eax ;7
??? PrintDec ecx ;8
??? PrintDec edx ;9
??? ret
main endp
end main
----------------------------------------------------------------------------------------------------------------
使用 uses 不如使用 pushad 和 popad 來得簡潔:
----------------------------------------------------------------------------------------------------------------
.386
.model flat, stdcall

include??? windows.inc
include??? kernel32.inc
include??? masm32.inc
include??? debug.inc
includelib kernel32.lib
includelib masm32.lib
includelib debug.lib

.data
??? dwVal dd ?
.code
sum proc v1, v2, v3
??? pushad
??? mov eax, v1
??? mov ecx, v2
??? mov edx, v3
??? add eax, ecx
??? add eax, edx
??? mov dwVal, eax
??? popad
??? ret
sum endp
;
main proc
??? mov eax, 7
??? mov ecx, 8
??? mov edx, 9
???
??? invoke sum, 11, 22, 33
??? PrintDec dwVal ;66
???
??? PrintDec eax ;7
??? PrintDec ecx ;8
??? PrintDec edx ;9
??? ret
main endp
end main
----------------------------------------------------------------------------------------------------------------
和子程序密切相關的有兩個指令: call 和 ret
call 相當于 push+jmp;
ret 相當于 pop+jmp;
有些 ret 后面還有個數字, 如 ret 8, 這相當于 ret 后再 esp+8(這是清理 8 字節的堆棧).

另外程序可以同 public 和 private 指定是否能跨模塊使用, 默認是 public, 極少用到 private.

聲明其他模塊成員的 extrn、extern、public 關鍵字, 現在用 proto 都可以代替了.

?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/375338.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/375338.shtml
英文地址,請注明出處:http://en.pswp.cn/news/375338.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Mac聯網恢復系統重新安裝Lion

Mac的Lion系統,雖然不像Windows那樣需要經常重裝,但也難免會有要重置的時候,比如更換硬盤。本文介紹如何利用Mac的聯網恢復系統進行Lion系統的在線恢復。Mac的在線恢復系統只在近幾年的機型上才有,在進行系統恢復前,請…

【線性代數公開課MIT Linear Algebra】 第二十三課 微分方程與exp(At)

本系列筆記為方便日后自己查閱而寫,更多的是個人見解,也算一種學習的復習與總結,望善始善終吧~ 一階常系數微分方程 Aududt 將一階常系數微分方程轉換為線性代數問題的關鍵在于常系數微分方程的解一定是指數形式的。那么我們的需要求解的東西…

Win32ASM學習[21]:宏匯編(1)

-------------------------------------------------------------------------------------------------------------------- 嗯 上個星期到現在 把Win32ASM基礎匯編復習了下 在網上找到了 這個不錯系列 于是就轉載過來了 其中 根據我自己的水平 刪減了一些內容 或…

ubunu安裝軟件的一個錯誤

http://tonychiu.blog.51cto.com/656605/654776/ 由于ubuntu/debian軟件庫中有時候不同的庫更新速度不一致,apt-get 出出現如下的錯誤提示 Some packages could not be installed. This may mean that you have requested an impossible situation or if you are us…

常用的基本Windows數據類型

常用的基本Windows數據類型 --------------------------------------------------------------------------------------------------------------------------------------------------------- 類 型 …

刪除空文件夾 清除CS擴展名文件 bat

刪除空文件夾。刪的干凈。刪的徹底。 將下列代碼復制到txt中保存。并把后綴.txt命成.bat。然后運行即可。 方案1.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 刪除指定目錄及其子目錄下的空文件夾.bat 代碼:…

ios 坐標轉換

// 將像素point由point所在視圖轉換到目標視圖view中,返回在目標視圖view中的像素值 - (CGPoint)convertPoint:(CGPoint)point toView:(UIView *)view; // 將像素point從view中轉換到當前視圖中,返回在當前視圖中的像素值 - (CGPoint)convertPoint:(C…

80X86偽指令

8086 偽指令表 一、數據定義偽操作 偽 指 令 名 稱 語 句 格 式 功 能 定義字節類型的數據存儲區 [變量名] DB 表達式[,…] 定義一個以變量名為首址的字節類型數據存儲區,所含數據元素的個數由其后表達式的個數所決定,數據存儲單元…

jQuery慢慢啃之選擇器(二)

1.$("#myDiv");ID匹配一個元素 <span id"foo[bar]"></span> $("#foo\\[bar\\]);//轉義 2.$("div");//元素標簽名匹配 3.$(".myClass"); css類名匹配 4.$("*") 匹配所有元素&#xff0c;多用于結合上下文…

iOS學習之基本概念

學習iOS最重要的是態度和興趣&#xff0c;如果你對于學習始終抱有不斷的熱情和端正的態度&#xff0c;那么&#xff0c;無論是什么&#xff0c;你總會成功的&#xff01; 有一句話與大家共勉&#xff1a;過程中跌倒多少次都沒有關系&#xff0c;重要的是&#xff0c;跌倒后你能…

Win32ASM代碼基本模塊

;-------------------------------------------------------------------------------- ;程序環境設置 .386 .model flat,stdcall option casemap:none ;-------------------------------------------------------------------------------- ;頭文件與庫文件導入 include windo…

ORA-16038: log 3 sequence# 103 cannot be archived

[sizelarge]今天在自己機器做了個實驗&#xff0c;插入10萬條&#xff0c;由于空間少&#xff0c;重啟數據庫時出現&#xff1a; [sizex-large]SQL> startup ORACLE instance started. Total System Global Area 188743680 bytes Fixed Size 1218460 byte…

Win32ASM學習[23]:RadASM快捷鍵

RadASM快鍵操作 一.書簽 SHIFTF8為所在行下書簽或刪除書簽(Crtl0-9能定義存于文件中的10個書簽)&#xff0c; 可通過編輯\書簽\開關書簽。&#xff08;CRTLF8為下一書簽&#xff0c;F8為上一書簽&#xff09; 二、列選擇&#xff1a; 拉框時用到&#xff0c;CRTLB為切換行…

SAP MM/FI 自動過賬實現 OBYC 接口執行

一. 自動過賬原理 在MM模塊的許多操作都能實現在FI模塊自動過賬&#xff0c;如PO收貨、發票驗證(LIV)、工單發料、向生產車間發料等等。不用說&#xff0c;一定需要在IMG中進行配置才可以實現自動處理。但SAP實現的這種自動配置的機制是怎樣的呢&#xff1f;其實也并不復雜&…

JAVA 字符處理

/** * 分割字符串 * * param str String 原始字符串 * param splitsign String 分隔符 * return String[] 分割后的字符串數組 */ SuppressWarnings("unchecked") public static String[] split(String str, String splitsign) { int index; if (str null || …

Win32ASM-進程學習【1】

關于一些進程的概念就不說了。。。 一創建進程GreateProcess (1).當一個進程被創建時: ①.系統為進程創建一個內核對象,并將這個對象的計數設置為1,進程對象只是一個比較小的數據結構,可以通過進程句柄來引用 ②.系統為進程創建一個虛擬地址空間,并將可執行文件裝載到這個地…

Object-C,NSArraySortTest,數組排序3種方式

晚上回來&#xff0c;繼續寫Object-C的例子&#xff0c;今天不打算寫iOS可視化界面的程序&#xff0c;太累了。剛剛dady又電話過來&#xff0c;老一套&#xff0c;煩死了。其實&#xff0c;我一直一個觀點&#xff0c;無論發生什么事情&#xff0c;不要整天一副不開心的樣子。開…

android中listview的一些樣式設置

在Android中&#xff0c;ListView是最常用的一個控件&#xff0c;在做UI設計的時候&#xff0c;很多人希望能夠改變一下它的背景&#xff0c;使他能夠符合整體的UI設計&#xff0c;改變背景背很簡單只需要準備一張圖片然后指定屬性 android:background"drawable/bg"&…

Win32ASM-進程學習【2】

獲取運行中的句柄 1.從窗口句柄中獲取進程句柄 要對進程進行某種操作,就必須首先知道該進程的句柄或者進程ID 對于自己創建的子進程來說CreateProcess函數返回了子進程句柄和進程的ID 但是如果如果要對系統中運行的某個進程進行操作,那么首先獲取他們的句柄才行 如果知道某個…

完美解決IE8有兩個進程的問題

完美解決IE8有兩個進程的問題&#xff0c;照以下方法設置后就只有一個進程了&#xff0c;沒有什么負影響哦&#xff01; 方法&#xff1a; 1、winR&#xff0c;在運行框里輸入&#xff1a;gpedit.msc&#xff0c;回車進入組策略設置。 2、依次展開&#xff1a;計算機配置——管…