來源:http://ibf.tw/xqzCv
備註:如果作者不希望被轉帖到此處,請告知,小弟會馬上刪帖。
-------------------------------------------------------------------------------------
Library * Clrscr : 清除螢幕
call Clrscr
* Crlf : 換行
call Crlf
* Delay : 暫停程式的執行狀態
mov eax , 1000 ; 1秒
call Delay;
* DumpMem : 將一段範圍內的記憶體內容以16進位的格式寫入到標準輸出上
array DWORD 1,2,3,4,5,6,7,8,9,0Ah,0Bh
mov esi , OFFSET array ; 起始位置
mov ecx , LENGTHOF array ; 元數個數
mov ebx , TYPE array ; 單位大小
call DumpMem
* DumpRegs : 將以16進位格式顯示 eax ebx ecx edx esi edi ebp esp eip efl暫存器的值
同時也顯示進位、符號、零值及溢位旗標
call DumpRegs;
* GetCommandtail : 將程式的命令列複製到一個以NULL結尾的字串
若命令列為空,進位旗標被設定,否則被清除
cmdTail BYTE 129 DUP(0) ; empty buffer
mov edx , OFFSET buffer
call GetCommandtail ; 填入 buffer
* GetMseconds : 以milisec為單位回傳一數值存入eax,代表從午夜12點後到現在經過多少時間
startTime DWORD ?
call GetMseconds
mov startTime , eax
L1:
; 在這執行一些動作
loop L1
call GetMseconds
sub eax , startTime ; 執行迴圈內的動作需多久時間
* Gotoxy : 以重新定位游標在主控視窗中的位置 dh = row , dl = col
mov dl , 10 ; 第10列
mov dh, 20 ; 第20行
call Gotoxy ; 定位游標位置
* Random32 : 隨機產生一個32-bit整數亂數並回傳其值到 eax 中
randVal DWORD ?
call Random32
mov randVal , eax
* Randomize : 產生亂數種子,供Random32及RandomRange兩個程序中亂數產生函數使用
call Randomize
mov ecx , 10
L1 : call Random32
; 在此處使用或顯示在 eax 中的亂數值
loop L1
* RandomRange : 產生一個介於 0 到 ( n-1 )範圍的亂數
n 被輸入到 eax ,產生的亂數輸出至 eax
randVal DWORD ?
mov eax , 5000
mov RandomRange
mov randVal , eax
* ReadChar : 由標準輸入讀取一個單獨的字元,傳到 al 中
char BYTE ?
call ReadChar
mov char , al
* ReadHex : 由標準輸入讀取一個 32-bit的16進位整數,傳到 eax 中
hex DWORD ?
call ReadHex
mov hex , eax
* ReadInt : 由標準輸入讀取一個 32-bit的有號整數,傳到 eax 中
範圍-2,147,483,648 ~ +2,147,483,647
intVal SDWORD ?
call ReadInt
mov intVal , eax
* ReadString : 由標準輸入讀取一個字串,當user按下enter鍵時結束讀取
eax儲存讀取了多個位元組
buffer BYTE 50 DUP(0)
byteCount DWORD ?
mov edx , OFFSET buffer ; 指定緩衝區
mov ecx , ( SIZEOF buffer ) - 1 ; 扣掉null,指定最大讀取字串長度
call ReadString ; 輸入字串
mov byteCount , eax ; 字串的長度
* SetTextColor : 設定文字的顏色和底色
* USES運算子 : 列出程序中使用到的暫存器,在程序開始之初產生push指令
將暫存器值儲存到堆疊中,程序結束時產生pop指令回復
call Clrscr
* Crlf : 換行
call Crlf
* Delay : 暫停程式的執行狀態
mov eax , 1000 ; 1秒
call Delay;
* DumpMem : 將一段範圍內的記憶體內容以16進位的格式寫入到標準輸出上
array DWORD 1,2,3,4,5,6,7,8,9,0Ah,0Bh
mov esi , OFFSET array ; 起始位置
mov ecx , LENGTHOF array ; 元數個數
mov ebx , TYPE array ; 單位大小
call DumpMem
* DumpRegs : 將以16進位格式顯示 eax ebx ecx edx esi edi ebp esp eip efl暫存器的值
同時也顯示進位、符號、零值及溢位旗標
call DumpRegs;
* GetCommandtail : 將程式的命令列複製到一個以NULL結尾的字串
若命令列為空,進位旗標被設定,否則被清除
cmdTail BYTE 129 DUP(0) ; empty buffer
mov edx , OFFSET buffer
call GetCommandtail ; 填入 buffer
* GetMseconds : 以milisec為單位回傳一數值存入eax,代表從午夜12點後到現在經過多少時間
startTime DWORD ?
call GetMseconds
mov startTime , eax
L1:
; 在這執行一些動作
loop L1
call GetMseconds
sub eax , startTime ; 執行迴圈內的動作需多久時間
* Gotoxy : 以重新定位游標在主控視窗中的位置 dh = row , dl = col
mov dl , 10 ; 第10列
mov dh, 20 ; 第20行
call Gotoxy ; 定位游標位置
* Random32 : 隨機產生一個32-bit整數亂數並回傳其值到 eax 中
randVal DWORD ?
call Random32
mov randVal , eax
* Randomize : 產生亂數種子,供Random32及RandomRange兩個程序中亂數產生函數使用
call Randomize
mov ecx , 10
L1 : call Random32
; 在此處使用或顯示在 eax 中的亂數值
loop L1
* RandomRange : 產生一個介於 0 到 ( n-1 )範圍的亂數
n 被輸入到 eax ,產生的亂數輸出至 eax
randVal DWORD ?
mov eax , 5000
mov RandomRange
mov randVal , eax
* ReadChar : 由標準輸入讀取一個單獨的字元,傳到 al 中
char BYTE ?
call ReadChar
mov char , al
* ReadHex : 由標準輸入讀取一個 32-bit的16進位整數,傳到 eax 中
hex DWORD ?
call ReadHex
mov hex , eax
* ReadInt : 由標準輸入讀取一個 32-bit的有號整數,傳到 eax 中
範圍-2,147,483,648 ~ +2,147,483,647
intVal SDWORD ?
call ReadInt
mov intVal , eax
* ReadString : 由標準輸入讀取一個字串,當user按下enter鍵時結束讀取
eax儲存讀取了多個位元組
buffer BYTE 50 DUP(0)
byteCount DWORD ?
mov edx , OFFSET buffer ; 指定緩衝區
mov ecx , ( SIZEOF buffer ) - 1 ; 扣掉null,指定最大讀取字串長度
call ReadString ; 輸入字串
mov byteCount , eax ; 字串的長度
* SetTextColor : 設定文字的顏色和底色
黑 = 0 | 紅 = 4 | 灰 = 8 | 淡紅 = 12 |
藍 = 1 | 洋紅 = 5 | 淡藍 = 9 | 淡洋紅 = 13 |
綠 = 1 | 棕 = 6 | 淡綠 = 10 | 黃 = 14 |
青綠 = 3 | 淡灰 = 7 | 淡青綠 = 11 | 白 = 15 |
顏色設定 = 前景色 + 背景色*16
mov eax , white + ( blue*16 ) ; 白字藍底
call SetTextColor
* WaitMsg: 在螢幕上顯示"Press [Enter] to continue ..."的訊息
並讓程式停止直到user按下輸入鍵時才繼續動作
call WaitMsg
* WriteChar: 寫入一個單獨字元到標準輸出
mov al , 'A' ;顯示 "A"
call WriteChar
* WriteDec: 在標準輸出中寫入一個32-bit無號整數,以十進位顯示
mov eax , 295
call WriteDec ; 顯示 "295"
* WriteHex: 寫入一個32-bit無號整數到標準輸出,以16進位顯示
mov eax , 7FFFh
call WriteHex ; 顯示 "00007FFF"
* WriteInt: 寫入一個32-bit有號整數到標準輸出,以十進位顯示,開頭加正負號
mov eax , 216543
call WriteInt ; 顯示"+216543"
* WriteString: 寫入一個以null作結尾的字串到標準輸出
prompt BYTE "Enter your name:" , 0
mov edx , OFFSET prompt
call WriteString
● 堆疊運算 * PUSH指令 : 將堆疊指標的值減四(保護模式),並將資料拷貝到堆疊指標所指的位置
Real-Mode下可使用 16 bit ( sp減 2 )或 32-bit( sp減 4 ) push r/m16
push r/m32
push imm32
* POP指令 : 複製堆疊中由 esp 所指向的內容到一個16-bit或 32-bit 的目的運算元
然後增加 esp的值,16-bit->esp+2 , 32-bit-> esp+4
pop r/m16
pop r/m32
* PUSHFD指令 : 將 32-bit的EFLAGS暫存器PUSH到堆疊
read-mode以PUSHF將16-bit的 flags傳到堆疊中
* POPFD指令 : 由堆疊中將資料POP到EFLAGS暫存器
read-mode以POPF由堆疊中取出16-bit資料到 flags中
* PUSHAD指令 : 將一般用途的32-bit暫存器以 eax ecx edx ebx esp ebp esi edi順序push到堆疊
* POPAD指令 : 以相反順序POP出來
* PUSHA指令 : 將一般用途的16-bit途暫存器以 ax cx dx bx sp bp si di順序 push到堆疊
* POPA指令 : 以相反順序POP出來
◆堆疊應用
★使暫存器能有超過一個以上的用處,堆疊提供一個暫時存放區段
★當 call 指令執行時,cpu 會將現行程序的返回位址(return adress)存入堆疊中
★呼叫一程序時,程序的參數會被 push 到堆疊中
★程序中的區域變數會以堆疊的方式產生
●定義及使用程序 * 定義程序
程序名稱 PROC
.................
ret 程序名稱 ENDP
* 傳遞參數 : 把一般用途暫存器當作引數傳遞
theSum DWORD ?
mov eax , 10000h ; argument
mov ebx , 20000h ; argument
mov ecx , 30000h ; argument
call SumOf ; eax = ( eax + ebx + ecx)
mov theSum , eax ; save the sum
* 範例 : 計算整數陣列的和
儲存(push)及回復暫存器(pop)
mov eax , white + ( blue*16 ) ; 白字藍底
call SetTextColor
* WaitMsg: 在螢幕上顯示"Press [Enter] to continue ..."的訊息
並讓程式停止直到user按下輸入鍵時才繼續動作
call WaitMsg
* WriteChar: 寫入一個單獨字元到標準輸出
mov al , 'A' ;顯示 "A"
call WriteChar
* WriteDec: 在標準輸出中寫入一個32-bit無號整數,以十進位顯示
mov eax , 295
call WriteDec ; 顯示 "295"
* WriteHex: 寫入一個32-bit無號整數到標準輸出,以16進位顯示
mov eax , 7FFFh
call WriteHex ; 顯示 "00007FFF"
* WriteInt: 寫入一個32-bit有號整數到標準輸出,以十進位顯示,開頭加正負號
mov eax , 216543
call WriteInt ; 顯示"+216543"
* WriteString: 寫入一個以null作結尾的字串到標準輸出
prompt BYTE "Enter your name:" , 0
mov edx , OFFSET prompt
call WriteString
● 堆疊運算 * PUSH指令 : 將堆疊指標的值減四(保護模式),並將資料拷貝到堆疊指標所指的位置
Real-Mode下可使用 16 bit ( sp減 2 )或 32-bit( sp減 4 ) push r/m16
push r/m32
push imm32
* POP指令 : 複製堆疊中由 esp 所指向的內容到一個16-bit或 32-bit 的目的運算元
然後增加 esp的值,16-bit->esp+2 , 32-bit-> esp+4
pop r/m16
pop r/m32
* PUSHFD指令 : 將 32-bit的EFLAGS暫存器PUSH到堆疊
read-mode以PUSHF將16-bit的 flags傳到堆疊中
* POPFD指令 : 由堆疊中將資料POP到EFLAGS暫存器
read-mode以POPF由堆疊中取出16-bit資料到 flags中
* PUSHAD指令 : 將一般用途的32-bit暫存器以 eax ecx edx ebx esp ebp esi edi順序push到堆疊
* POPAD指令 : 以相反順序POP出來
* PUSHA指令 : 將一般用途的16-bit途暫存器以 ax cx dx bx sp bp si di順序 push到堆疊
* POPA指令 : 以相反順序POP出來
◆堆疊應用
★使暫存器能有超過一個以上的用處,堆疊提供一個暫時存放區段
★當 call 指令執行時,cpu 會將現行程序的返回位址(return adress)存入堆疊中
★呼叫一程序時,程序的參數會被 push 到堆疊中
★程序中的區域變數會以堆疊的方式產生
●定義及使用程序 * 定義程序
程序名稱 PROC
.................
ret 程序名稱 ENDP
* 傳遞參數 : 把一般用途暫存器當作引數傳遞
theSum DWORD ?
mov eax , 10000h ; argument
mov ebx , 20000h ; argument
mov ecx , 30000h ; argument
call SumOf ; eax = ( eax + ebx + ecx)
mov theSum , eax ; save the sum
* 範例 : 計算整數陣列的和
儲存(push)及回復暫存器(pop)
;---------------------------------------------------------------------
ArraySum PROC ; ;計算在一個32bit整數陣列中所有整數的和 ;Recv : esi = 陣列的 offset ; ecx = 陣列中元素個數 Ret : eax = 陣列中所有元素和 ;--------------------------------------------------------------------- push esi ; 儲存 esi , ecx push ecx mov eax , 0 ; 歸零 L1: add eax , [esi] ; 將每一個整數加到總和中 add esi , 4 ; 指向下一個整數 loop L1 ; 重覆迴圈 pop ecx ; 回復 ecx , esi pop esi ret ArraySum ENDP |
* USES運算子 : 列出程序中使用到的暫存器,在程序開始之初產生push指令
將暫存器值儲存到堆疊中,程序結束時產生pop指令回復
上面的範例可變為 | 編碼會被組譯器產生 |
ArraySum PROC USES esi ecx mov eax , 0 L1: add eax , [esi] add esi , 4 loop L1 ret ArraySum ENDP | ArraySum PROC push esi push ecx mov eax , 0 L1: add eax , [esi] add esi , 4 loop L1 pop ecx pop esi ret ArraySum ENDP |
沒有留言:
張貼留言