彙編可以開發windows程式?答案是肯定的,用win32組合語言開發出來的windows程式具有執行效率高、占用空間小等特點。
m32v9r.zip
二、知識預備
1、暫存器
為了提高運算速度和資料的訪問速度,在計算機的cpu內,有一組硬體裝置,第乙個裝置內存放cpu運算需要的數,這些數值可供cpu直接訪問,這組裝置叫暫存器。暫存器分為通用暫存器、段暫存器、程式指標暫存器、標誌暫存器。
程式設計最常用就是通用暫存器,常用的通用暫存器有eax,ebx,ecx,edx,esi,edi等等,現代計算機的cpu一般是以32位為單位進行運算,因此乙個暫存器最大能存放32位的二進位制數。每個暫存器通常都有它預設的用法,所謂預設只是一種程式設計的習慣,你可以不遵守這些用法,但是有些情況下必須遵守,因為我們開發的是windows程式,要遵守windows作業系統的規定和彙編語法本身的約束,比如呼叫乙個windowsapi函式,返回值放在eax,堆疊的棧頂位址在esp,在組合語言的迴圈中,ecx內存放迴圈的次數。具體暫存器的使用會在以後介紹。
2、堆疊
堆疊是個非常古老的概念,在dos時代就有了,也是個非常重要的東西,程式沒了它就活不了,堆疊就是在記憶體裡分配乙個區域,使用這個區域必須遵守乙個規定:後進先出,後進來的先出去,可以把它想像成乙個空木箱,首先往裡面放棉衣,然後往裡面放書,最後放上運動服。如果要取出書,必須得把最後放上的運動服取出,放的順序是棉衣->書->運動服,取的順序是運動服->書->棉衣,堆疊也是如此。
先解釋一下什麼是位址,記憶體**的便宜和記憶體容量的擴大,windows虛擬記憶體早已出現,記憶體中放著眾多的資料,必須要有方法表示記憶體某個地點,這個地點就用位址來表示。把記憶體以位元組為單位劃分,某個位址表示某個位元組的位址,如左下圖是乙個內有4個成員的堆疊,堆疊裡的成員以乙個位元組為單位(數的右邊標明了以十六進製制表示的位址,如1001)
+--+
+--+
+--+
+--+
+--+
堆疊是向下增長的,每增加乙個成員,棧頂(堆疊頂部的位址)的位址減1,對於這個堆疊,棧頂位址是af18,如果再往這個堆疊裡增加乙個成員的話,它的位址是:af18-1=af17。如果往這個堆疊裡增加乙個32位的數,棧頂的位址是多少呢,32位的數佔4個成員的位置,棧頂的位址為:af18-4=af14。
在這個堆疊中增加乙個32位數dab0cd90,新的堆疊如下:
+--+
+--+
+--+
+--+
+--+
+--+
+--+
+--+
+--+
三、win32組合語言的語法
為了方便大家理解和入門,下面盡量使用巨集彙編和偽指令地方進行描述,也正因為有了巨集彙編和偽指令的幫助,win32彙編才具有很多高階語言的特性,很多語法和c差不多。
1、win32匯程式設計序基本結構
.386
.model flat,stdcall
.data
初始化值的全域性變數定義
.data?
未初始化值的全域性變數定義
.const
常量定義
.code
..............
...............
程式入口label
............
............
end程式入口label
2、變數定義
(1)定義全域性變數
全域性變數定義在.data和.data?內,
初始化變數的定義方式如下:
.data
變數名 型別 初始值1,初始值2,.......
變數名 型別 重複次數dup(初始值1,初始值2,....)
注意:如果用?表示初始值的話,則表示0
未初始化變數的定義方式是
.data?
變數名 型別 ?
(2)條件測試語句
(a)基本結構
.if條件
程式**
[.elseif]條件比較
程式**
.......
[.else]
程式**
.endif
(3)操作符
(a)比較操作符
== 相等
!= 不等於
> 大於
>= 大於或等於
< 小於
<= 小於或等於
& 位測試
! 邏輯非
&& 邏輯與
|| 邏輯或
(b)位操作符
and按位與
or 按位或
xor 異或
shl邏輯左移
shr邏輯右移
(c)標誌暫存器操作符
carry?是否進製
overflow? 是否溢位
parity? 奇偶位是否置位
sign? 符號位標誌位是否被置位
zero? 零位標誌位是否置位
(4)迴圈語句
(a)while語句
while 條件
..........
..........
[.break[.if 退出條件]]
[.contine[.if 退出條件]]]
.end
(b)repeat語句
.repeat
...........
..........
[.break[.if 退出條件]]
[.contine[.if 退出條件]]]
.until 條件(或.untilcxz [條件])
(5)子程式定義
1、定義
子程式名 proc [距離][語言型別][可視區域][users 暫存器列表][,引數:型別]...[vararg]local 區域性變數列表
..............
...............
...............
子程式名 endp
2、如果在未定義前使用,要宣告、
函式名 proto [距離][語言][引數1]:資料型別,[引數2]:資料型別,...............
(6)資料結構
(a)宣告
wndclass struct
....
.....
......
wndclass ends
(b)定義
mystruct wndclass<1,1,...,1>
mystruct wndclass <>
(c)使用
mov eax,mystruct.lpfnwndproc
mov esi,offset mystruct
assume esi: ptr wndclass
mov eax,[esi].lpfnwndproc
.......
assume esi:nothing
四、在win32彙編中的使用windows api
win32彙編如果沒有api的幫助無法實現很多功能,筆者沒見過在win32匯程式設計序不呼叫api的。
呼叫api實際上是靠堆疊來完成引數傳遞的,既然是堆疊,那就要遵守後進先出的原則,這意味api的第乙個引數是最後乙個放入堆疊的,最後乙個引數是第乙個放入堆疊的。
呼叫方式如下:
push 引數n
..........
push 引數2
push 引數1
call api函式名
為了簡化**,也可以使用以下這種方式呼叫api
invoke api函式名,引數1,引數2,.....,引數n
Win32彙編基礎
常用指令 mov 目標運算元,源運算元 mov eax,0x0 進行資料傳遞 movzx mov zero x 以0填充高位,用法同上,push poppushad 所有暫存器壓棧 8個 popad 所有暫存器出棧 8個 lea 取位址指令,類似c語言中的 call 呼叫函式指令 add 加 sub...
Win32彙編 實數
386 選擇的處理器 model flat,stdcall option casemap none 指明識別符號大小寫敏感 include kernel32.inc 要引用的標頭檔案 includelib kernel32.lib 要引用的庫檔案 includelib msvcrt.lib 引用c庫...
開始學習win32彙編
前段時間對於csdn的部落格系統徹底失望,在我現在寫的東西都還不知道能不能正常發出去,鬱悶,加上過年有這麼久沒有來了。這段時間開始學習彙編,說到彙編,大學開過兩門相關課程,微機原理和微控制器都是學這方面的,不過那都是8086,51級別的彙編,感覺根本跟不上時代,那時候學的還不錯 現在想學習學習win...