×86 (16/32位)組合語言學習——基於masm32
×86處理器中的暫存器:
組合語言必須要指明程式中的各個語句,變數該去的地方(在高階語言中這一工作由編譯器完成)
8086(16位處理器)中的暫存器
8086處理器有16根資料線和20根地址線,故可定址空間為1MB;
上圖所示為8086處理器的暫存器結構,所有的暫存器均為16位結構;其中資料暫存器可對其中的高8位和低8位分別進行定址;
段暫存器用來存放各個程式段的段首地址;
控制暫存器中:IP存放下一條要執行的指令地址;(跳轉,分支指令會修改其中的地址值而控制程式的執行順序)(其功能類似於8位處理器中的程式計數器,但又有所區別:程式計數器指向當前指令的下一條指令地址,但當前指令的下一條指令並不一定是下條要執行的指令)
狀態標誌暫存器(FLAGS)——其中9位作為標誌位(剩餘7位未定義)
需要注意的是:×86處理器在記憶體中使用小端方式儲存和檢索資料:資料的低位放在小地址記憶體中:
彙編基礎知識
相關概念:
由組合語言編寫的程式稱為原始檔;
原始檔經過彙編之後的檔案稱為目標檔案;(同時彙編器也可能生成列表檔案:列表檔案包括了原始檔的副本符號表及相關資訊)
目標檔案經過連結器裝入相關連結檔案之後產生可執行檔案:可執行檔案即可直接在目標處理器上直接執行的機器指令集合;
映像檔案:表明每個段在儲存器中的分配情況
組合語言的特點:
面向硬體,不可移植
彙編基礎知識概要:
基本語言元素:
整數常量
整型常量表達式:在彙編時由彙編器計算其值;計算結果必須為整數;
地址表示式:結果是一個儲存單元的地址
實數常量
字元常量:彙編器儲存其ASCII碼值;
字串產常量:儲存為位元組序列
保留字:
指令助記符
暫存器名稱
屬性
運算子
預定義符號
識別符號
偽指令
指令
註釋
語句型別和格式
執行性語句:
標號:硬指令助記符 運算元,運算元 ;註釋
標號反應指令的邏輯地址,為迴圈跳轉指令提供轉移的目的地址
說明性語句:
名字 偽指令 引數,引數; 註釋
名字既反映邏輯地址,又具有自身的各種屬性
組合語言的程式格式
組合語言的程式由各種邏輯意義上的程式段組成:資料段,程式碼段,堆疊段,附加段;
獨立執行的程式必須包含一個程式碼段,並指示程式執行的起始位置
可執行語句必須位於程式碼段內
一個段的開始自動結束前一個段
完整段,簡化段
彙編指令語法概要總結
常見的偽指令
資料定義偽指令
變數定義偽指令:根據申請到的主存空間歸類
DB
DW
DD
DF
DQ
DF
DT
定位偽指令:
ORG 引數
使當前偏移地址指標指向引數表達的偏移地址
EVEN
使當前偏移地址指標指向偶數地址
ALIGN n
當前偏移地址指標指向n的整數倍
地址操作符:
OFFSET 名字/標號
返回名字或標號的段內偏移地址
SEG 名字/標號
返回名字或標號的段地址
型別操作符:
PTR
THIS 型別名
建立當前地址,具有指定的型別
SHORT 標號
設定標號為短轉移標號
TYPE 操作符
根據型別返回數值;
簡化段定義偽指令
.CODE
.DATA
.STACK
儲存模式偽指令
MODEL 儲存模式 [,語言型別] [,作業系統型別] [,堆疊選項]
【7種不同的儲存模式:
TINY:所有的段地址暫存器設定為同一個值,即所有的程式段在同一個段內
SMALL:最多隻有一個程式碼段和一個數據段;每段不大於64KB
COMPAC:
MEDIUM:
】
option casemap:none 定義程式是否對大小寫敏感
程式開始偽指令
.STARTUP
按照給定的CPU型別,根據儲存模式,作業系統和堆疊型別,產生程式開始執行的程式碼;
程式終止偽指令
.EXIT [返回數碼]
終止程式執行,將返回數碼返回給作業系統
彙編結束偽指令
END [標號]
到此結束彙編過程
完整段定義偽指令
段名 SEGMENT [定位] [組合] [段字] ['類別']
段名 ENDS
1)段定位屬性:
BYTE
WORD
DWORD
PARA
PAGE
2)段組合屬性
PRIVATE
PUBLIC
STACK
COMMON
AT表示式
3)段字屬性
4)段類別屬性
指定段暫存器偽指令
ASSUME 段暫存器:段名[,段暫存器:段名...]
通知彙編器用指定的段暫存器來定址對應的邏輯段
複雜資料結構
結構
記錄
巨集彙編
巨集定義指令
巨集名 MARO [形參表]
巨集定義體
ENDM
順序程式設計
順序執行,無分支,迴圈,跳轉
分支程式設計
無條件轉移指令
JMP dest
JMP reg/m16
無條件轉移指令所指定的地址,目標地址由標號、暫存器或儲存器提供
三種類型的轉移:
SHOT
NEAR
FAR
有條件轉移指令
條件轉移均為短轉移;
分為有符號轉移和無符號轉移
單分支結構程式
雙分支結構
迴圈程式設計
串處理程式設計
子程式設計
子程式即過程;
過程定義
過程中的標號
標號只在過程被定義的過程中可見;
使用雙冒號::可以使標號定義為全域性標號;
過程呼叫
CALL和RET指令:
CALL指令呼叫一個過程,將返回地址(過程呼叫之後的地址)壓入棧中,將過程起始地址複製到指令指標暫存器中,使得CPU開始執行被呼叫過程;過程執行完畢後,RET指令把返回地址從堆疊中彈出,複製到指令暫存器中,使得程式繼續執行呼叫後程序的部分;
過程的巢狀呼叫
連結到外部庫
連結庫是包含已經彙編為機器d程式碼的過程的檔案;
組合語言沒有Microsoft認證的標準連結庫;現在使用的是長期積累自發形成的
呼叫連結庫中的過程
使用PROTO偽指令標識庫中的過程,然後使用CALL指令呼叫
子程式呼叫的底層實現
以數值或引用的方式來傳遞引數;
定義和撤銷區域性變數
實現遞迴
堆疊引數
32位模式下,堆疊引數由Windows API函式使用;
堆疊幀:
一塊堆疊保留區域;用於存放被傳遞的實參,過程的返回值`區域性變數,以及被儲存的暫存器;
訪問堆疊引數
高階語言彙編程式設計
這些偽指令在彙編時自動展開,自動生成相應的比較和條件轉移指令序列,實現程式分支;
條件控制偽指令
.IF 條件表示式
分支一
.ELSEIF 條件表示式
分支二
.ELSE
分支三
.ENDIF
迴圈控制偽指令
WHILE 結構
.WHILE 條件表示式
迴圈體
.ENDW
先判斷迴圈條件,為真時再執行迴圈體
UNTIL 結構
一)———
.REPEAT
迴圈體
.UNTIL 條件表示式
功能:先執行一次迴圈體,然後判斷迴圈條件
二)——
.REPEAT
迴圈體
.UNTILCXZ[條件表示式]
功能:先執行一次迴圈體,並CX=CX-1,直到CX=0或者條件為真時結束迴圈
彙編與C語言的混合程式設計
C程式內嵌彙編指令
嵌入的彙編指令前用關鍵字asm 說明
asm <操作碼><運算元>(使用;或換行結束語句)
在C語言中,Register變數使用DI和SI兩個暫存器存放,故在內嵌組合語言時,要注意程式中是否定義了Register變數,否則不能使用這兩個暫存器作為指令運算元;
彙編指令中可以使用結構體成員作為運算元;
彙編與C的模組連線
模組連線是不同語言之間混合程式設計經常使用的方法:利用各自的開發環境編譯形成OBJ檔案,然後將他們連線在一起