小白的入门之——汇编语言程序设计教程
目錄
第一章? ?基礎知識
1.1匯編語言的特點
1.2計算機中數據表示的特點
【BCD碼表示法(Binary Coded Decimal)】
【定點數】
—原碼表示法—
—反碼表示法—
—補碼表示法—
浮點數
1.3 ??????計算機的數據存儲
寄存器
存儲器
?數據在主存中的存儲方式?編輯
第二章8086宏匯編的源程序組成
2.1 源程序的分段結構
2.2匯編語言的語句結構
2.2.2操作項
2.2.3操作數項
2.2.4 注釋項
2.3 常用偽指令
2.3.1處理器選擇偽指令(略)
2.3.2段定義及源程序結束偽指令
源程序結束偽指令
3.3.3變量定義與存儲空間分配偽指令
2.3.4替代符定義偽指令
2.3.5 段內偏移地址偽指令
2.3.6 過程定義與宏定義偽指令
第三章? 8086指令系統
3.2尋址方式
寄存器尋址方式
立即尋址方式
存儲器尋址方式
直接尋址方式
寄存器間接尋址方式
寄存器相對尋址方式
基址變址尋址方式
第一章? ?基礎知識
1.1匯編語言的特點
-
- 1、計算機的程序設計語言-簡稱計算機語言-是人們用來給計算機描述操作任務的工具;
- 2、機器語言是機器指令的集合;匯編語言的主體是匯編指令。機器語言和匯編語言都屬于計算機語言中的低級語言,其余均為高級語言。
- 3、最初的計算機語言是直接用二進制代碼來表述的,也就是機器語言;為了便于掌握和使用,人們將機器語言符號化,產生了匯編語言。然而,計算機不能直接理解匯編語言的符號系統,需要一個轉換工具即匯編程序。
- 4、匯編語言編程時,必須準確的指出數據存放的地方——某個寄存器、某個存儲單元或某個I/O端口,必須直接控制相關設備完成相應的輸入/輸出。
-
1.2計算機中數據表示的特點
-
- 1、幾種常用的數制的規定標志是:
-
B:代表二進制
D:代表十進制
O:代表八進制
H:代表十六進制
- 2、字符在計算機中二進制編碼稱為字符代碼,目前計算機中普遍使用的字符代碼是ASCII碼(美國信息交換準代碼)。
- 3、基本字符集是各類應用中主要使用的字符集,由ASCII字符集的前128個字組成,編碼范圍是 0000 0000—0111 1111;
? ? ? 基本字符集的ASCII碼的最高位都為0,因此稱ASCII碼為7位編碼(最高位上的0被忽略)。
? ? ?4、擴展字符集由ASCII字符集的后128個字符組成,包含一些圖形符號和制表符號等,編碼范? ? ? ? ?圍是 1000 0000—1111 1111,一般較少使用。
? ? ? ?一個字符的ASCII碼在存儲器中存放時,需要占用存儲器的一個字節。
? ? ?5、數值數據是計算機中用于各種算術運算的數據,數值數據在計算機中的表示方法有BCD碼? ? ? ?表示法、定點數表示法和浮點數表示法三種。
【BCD碼表示法(Binary Coded Decimal)】
BCD碼采用4為二進制編碼表示1為二進制數,分有權碼與無權碼兩類。計算機中使用的是一種有權BCD碼—8421碼,運算結果為正數時也可以用8421碼表示。
BCD碼是十進制數,當兩個8421碼相加時:
如果和等于或小于 1001(即十進制數9),則不需要修正;
如果相加之和在 1010 到1111(即十六進制數 0AH~0FH)之間,則需加 6 (0110)進行修正。
這樣做的原因是,機器按二進制相加,所以 4 位二進制數相加時,是按“逢十六進一”的原則進行運算的,而實質上是 2 個十進制數相加,應該按“逢十進一”的原則相加,16 與10相差 6,所以當和超過 9或有進位時,都要加 6 進行修正。
8421碼雖然可用于十進制數的運算,但由于其數據表示效率低(4位二進制數只能表示一位十進制數),且運算效率也很低(需要對結果進行調整),所以在實際應用中很少使用。
【定點數】
—原碼表示法—
原碼是最直觀的機器數表示法,它以0表示正號,以1表示負號,直接置于數的最左端(即最高位),而數字部分于其絕對值一致。
計算機中的主要數據表示方法有定點數表示法和浮點數表示法,定點數表示法也是浮點數表示法的基礎。
所謂的定點數表示法,是指小數點被固定在數據中某個特定的位置上的數據表示法,如果把小數點固定在數據最低有效位的右邊,稱為定點整數;如果固定在最高有效位的左邊,則定點數純為小數,稱為定點小數。
符號的表示是定點數表示必須要解決的問題,帶符號的定點數有原碼、補碼、反碼等幾種編碼表示法。
n位原碼(包括符號位)的數據表示范圍是
當n=8時,8位原碼的數據范圍是 -127~127;
當 n=16時,16為原碼的數據范圍是 -32767~32767。
—反碼表示法—
正數的反碼于其原碼一致,負數的原碼與其原符號位相同,數字按位取反。
—補碼表示法—
設,則X的補碼定義為? ??(mod)
其中n為所形成的補碼位數(包括符號位);
mod表示“模”運算,即“相除取余數”運算
??被稱為“模數”,mod表示“除以?取余數”;
所形成的n位補碼中,最高位為符號位,數字部分為n-1位,X的實際取值范圍為
?
n=8時8位補碼的數據表示范圍是-128~127;
N=16時16位補碼的數據表示范圍是-32768~32767。
計算(減法)
計算(進位)
計算(溢出)
浮點數
定點數在計算機及多媒體數據處理中有著廣泛的應用,但其缺點也很明顯:一是表示數據的精度差;二是表示數據的范圍小;因此不適合科學計算。
科學計算要求用有限的數據編碼位,獲得更大的數據表示范圍和更高的是數據表示精度,這就需要采用浮點數表示形式。
浮點數的小數點可以出現在任意位置,一人浮點數可表示為(科學計數):(構成要素:指數e,基數R,有效數字m)
一個計算機系統中一般有兩個指令集:定點指令集和浮點指令集。一般說CPU是一個定點指令處理器,負責執行定點指令,而浮點指令需要專門的浮點協處理器來執行。
浮點運算有兩種實現方法:一是用定點指令編程模擬實現(軟件),二是用浮點協處理器執行浮點指令來實現(硬件)。
浮點數的一般表示格式:
1.3 ??????計算機的數據存儲
?計算機中可以用于存儲數據的裝置有:CPU內部存儲器;計算機的存儲器;I/O端口(即I/O設備接口中的一些寄存器)
寄存器
?8086CPU系統中,根據用途不同寄存器可分為三組:通用寄存器、專用寄存器和段寄存器。
?通用寄存器:
BP、SI、DI 三個寄存器為不能分解的16位寄存器。
AX: 累加器,使用頻度高,用于算術、邏輯運算以及外設傳送信息等
BX:基址寄存器,常用存放存儲地址
CX:計數器,作為循環和串操作等指令中的隱含計數器
DX:數據寄存器,存放雙字長數據的高16位,或存放外設端口地址
專用寄存器:(16位)
寄存器:
8086系統中一個匯編語言程序最多可以同時操作4個活躍的段,所以共設有4個段寄存器
存儲器
??KB(字節)、MB(字節)、GB(字節)、TB(字節)
?
段地址的最低四位必為0,其中的X表示0或1,CPU中的段寄存器實際只存放了段地址的高16位,CPU中的地址加法器會在將邏輯地址轉換成物理地址使,自動在16位段地址低位部分添加4個0,然后再與偏移地址相加。?
?數據在主存中的存儲方式
I/O接口是I/O設備與計算機主機相連時的連接電路,CPU與I/O設備交換數據(輸入/輸出操作)都要經過I/O接口。
I/O接口中設置有三類寄存器:數據寄存器、控制寄存器、狀態寄存器,這些寄存器統稱為I/O端口,均為8位寄存器,端口地址長度為16位,可以為 ?個I/O端口編地址。
訪問端口需要專門的指令,稱為輸入/輸出指令即I/O指令。
-
第二章8086宏匯編的源程序組成
2.1 源程序的分段結構
(1)、一個源程序包含三個段:代碼段、數據段和堆棧段,其段地址分別存于寄存器CS、DS和SS中。
(2)、由于一個主存段最大只有64KB,所以在一個段的存儲容量不夠時,可以多定義一些段(定義多個數據段/代碼段等),所以一個源程序可包含的段不受限制,但由于8086CPU只提供了4個段寄存器,所以一個源程序最多只能同時操作4個段,操作其他段是必需先將該段的地址存入某個寄存器。
2.2匯編語言的語句結構
(1)、匯編語句的一般結構為:
? ? ? ? ? ? ? [名字項] ?操作項 ?[操作數項] ??[; 注釋項] ?([] 內為可選項)
匯編指令可分為三類:
???偽指令:
用于說明程序運行的處理平臺,進行段定義、變量與常量定義、過程定義、源程序的開始與結束定義等。
偽指令語句是用來指示匯編程序如何進行源程序匯編的,而不是用來直接實現程序操作功能的。
???指令語句:
一條指令語句包含一條匯編語言指令,程序的操作功能是由指令語句來實現的。
???宏指令語句:
是宏匯編語言允許程序員自定義的一種特殊形式的指令,一條宏指令相當于一小段程序。
2.2.1 名字項
名字項就是一個符合特定規則的字符串,其最大長度不超過30個字符。
偽指令當中的名字項涉及如下:
指令語句中的名字項
指令語句中的名字項稱為指令標號,使用時需要加上“:”,
使用格式為:“指令標號:”用于標記當前指令的位置。
2.2.2操作項
用來描述一條語句的操作功能,是偽指令、指令或宏指令的助記符。操作項是一條必不可少的語句。
2.2.3操作數項
(1)、操作數項是用來描述一條語句的操作對象。根據語句功能的不同,數量不一,也可以沒有操作數項。
(2)、具體的操作數項可以是常量、變量、寄存器、指令標號、過程名、段名或表達式,其內容可以是數據或地址。
(3)、表達式中只能包含已知量,不能出現程序運行過程中動態確定的量。
表達式中常用的運算符:
2.2.4 注釋項
注釋項必須以“;”號開始(英文狀態下)
2.3 常用偽指令
2.3.1處理器選擇偽指令(略)
2.3.2段定義及源程序結束偽指令
匯編語言采取分段結構,段定義偽指令用于對程序的各個段進行定義,一般格式為:
? ? ? ? ? ? ? ? ? ? ? ? ? 段名 ?SEGMENT ?[定位類型] ?[組合類型] ?[‘類別’]
? ? ? ? ? ? ? ? ? ? ? ? ? ....... ?; ?段的具體內容
? ? ? ? ? ? ? ? ? ? ? ? ? 段名 ??ENDS
源程序結束偽指令
源程序各段定義都結束后,必須用源程序結束偽指令來結束整個源程序,格式為:
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?END ?[指令標號] ?
(指令標號為程序入口指令-即運行時第一條要執行的指令-的標號,用以指出程序的入口,單模塊或多模塊中的主模塊必須有指令指標)
SSEG SEGMENT STACK;堆棧段定義,采用了stack組合類型 ....... ; 在此定義堆棧段的內容 SSEG ENDS ;堆棧段定義結束 DSEG SEGMENT ;數據段定義 ....... ; 在此定義數據段的內容 DSEG ENDS ;數據段定義結束 CSEG SEGMENT ;代碼段定義 ASSUME CS: CSEG , SS : SSEG ;建立段寄存器與段之間的關系 START : MOV AX , DSEG ; 程序入口指令(標號start),; 將數據段的段地址傳給AX 寄存器MOV DS , AX ;將數據段的段地址從AX 傳到數據段寄存器DS ; 完成對DS的裝載......... ; 代碼段的其它內容MOV AH ,4CH ;以下兩條指令用于結束程序運行,返回操作系統命令狀態INT 21H CSEG ENDS ;代碼段定義結束 EDN START ;源程序結束,同時用程序入口指令標號start指出程序入口3.3.3變量定義與存儲空間分配偽指令
這類偽指令主要用在堆棧段和數據段中,為堆棧分配存儲空間,以及定義程序中需要的各種類型變量。格式:
? ? ? ? ? ? ? ? ? ? ? ? ?[變量名] ?類型定義操作符 ?數據項或表達式列表
“數據項或表達式項”是由多個數據項或表達式組成的序列,各項之間用“,”隔開。
數據段分析:
DSEG SEGMENT ;【(SEGMENT)段定義操作 (VAR1)變量名】VAR1 DB 46H ;字類型單變量【(DB)定義字節類型】VAR2 DW 2A05H ; 字節類型單變量【(DW)定義字類型】VAR3 DB 26*3 , -53 , 00101001B ;有3個元素的字節類型數組VAR4 DW 12H , 0A186H ;有2個元素的字類型數組 DSEG ENDS ;【(DSEG)段名 (ENDS)段結束操作】變量名也稱符號地址,可在源程序中直接使用。
數據段在主存中的映像:
字符變量
字符變量也是程序設計中常用的數據,分析:
CHAR1 DB ‘B’ ;單字符變量,采用字符常量形式賦初值’b’ CHAR2 DB 52H ;單字節變量,采用ASCII碼形式賦初值52H STR1 DB ‘C’,‘o’,‘m’,‘p’,‘u’,‘t’,‘e’,‘r’ STE2 DB ‘program’ ;str1和str2均為字符串,字符串本意上是字符數組字符在計算機中是以ASCII碼表示的,一個字符的SACII碼占用主存的一個字節,所以,無論是單字符變量還是字符串,都必須按字節類型定義(DB)。
很多情況下,定義變量和數組時不需要賦初值,只是用“?”來分配存儲空間
VAR5 DB ? ;為字節類型變量VAR5分配1個字節的存儲空間 VAR6 DW ?,?,?,?,?,?,?,?,?,? ;為字類型數組VAR6分配10個元素的空間 VAR7 DB 50,?,35H,?,? ;對VAR7某些元素賦初值,某些分配空間元素較多且按一定規律重復時,我們使用特殊操作符-DUP來定義
重復次數 ??DUP(數據項或表達式項)
DUP操作符按指定的重復次數,對()內的數據項或表達式進行重復定義
ARR1 DB 100 DUP(?) ;為字節類型數組ARR1分配100個元素的存儲空間 ARR2 DW 50 DUP(0) ;為字類型數組ARR2分配50個元素的存儲空間,并清0 ARR3 DB 5 DUP(12H,86H) ;定義具有10個元素的字節類型數組ARR3,并賦初值 ARR4 DB 65H,3 DUP(4AH,05H),30H ;定義具有8個元素的字節類型數組,并賦初值分析:
定義一個大小為32個字的堆棧
SSEG SEGMENT STACKDW 32 DUP(?) ;為堆棧分配32個字的存儲空間 SSEG ENDS?一些屬性的運算符可以與變量或標號組成特殊的屬性表達式
?分析例題
DSEG SEGMENT ;【(SEGMENT)段定義操作 (VAR1)變量名】VAR1 DB 46H ;字類型單變量【(DB)定義字節類型】VAR2 DW 2A05H ; 字節類型單變量【(DW)定義字類型】VAR3 DB 26*3 , -53 , 00101001B ;有3個元素的字節類型數組VAR4 DW 12H , 0A186H ;有2個元素的字類型數組 DSEG ENDS若有以下代碼插入
OFFSET VAR1 ;求取符號地址VAR1的段內偏移地址屬性,結果為0 OFFSET VAR2+1 ;求取地址表達式VAR2+1的偏移地址屬性,結果為2 SEG VAR3 ;求取符號地址VAR3的段地址屬性值,同一段內定義的變量或數組,其段地址屬性都是相同的 WORD PTR VAR3 ;對字節類型的VAR3重新指定為按字類型訪問 BYTE PTR VAR4+2 ;將字類型的AVR4+2重新指定為按字節類型訪問2.3.4替代符定義偽指令
用EQU偽指令定義替代符 格式:
替代符 ?EQU ?表達式
表達式中可包含:常量、以及定義過的其它符號(變量名、標號、替代符...)或匯編語言規定使用的一些符號
用“=”偽指令定義符號 格式:
替代符 = 表達式
“=”偽指令所起的作用于EQU偽指令相同,但“=”偽指令定義的替代符可在同一個源程序中重復定義。“=”偽指令對的替代符的有效范圍從它被定義開始到下一次被定義為止。
2.3.5 段內偏移地址偽指令
段內偏移地址指針$
匯編程序給每個段設置里一個段內偏移地址指針($),用以跟蹤匯編過程,動態指出段內下一個可分配的存儲單元的偏移地址。
段內偏移地址指針設置偽指令 格式:
ORG ?常量表達式
ORG偽指令將常量表達式的值作為段內偏移地址,直接賦予$指針
DSEG SEGMENTDAT1 DB 14H DUP(?)ORG 100HDAT2 DW 1375H,2468H DSEG ENDS若沒有ORG偽指令,DAT2應緊接著DAT1定義,其首地址應該為14H(段內偏移地址),ORG將$指針修改為了100H,因此DAT2是在段內偏移地址100H處定義的,首地址為100H。
2.3.6 過程定義與宏定義偽指令
過程定義宏指令也稱子程序 格式:
過程名 ?PROC ?[類型]
...... ?; 過程的具體代碼
過程名 ?ENDP
PROC 表示過程定義開始,ENDP 表示過程定義結束。過程的類型有近(NEAR)和遠(FAR)兩種。
NEAR ?:指過程與其調用程序代碼在同一個代碼段內,為默認值
FAR ??:則指過程與其調用程序不在同一代碼段內
過程名具有三個屬性:類型屬性、段地址屬性、偏移地址屬性。
宏定義偽指令用于定義宏指令 ?格式:
宏指令名 ?MACRO ?[形式參數表]
...... ;宏體
ENDM
宏體就是一段程序,這段程序的功能就是對應宏指令的功能
-
第三章? 8086指令系統
(為了方便梳理指令,我先把尋址方式放在前面)
3.2尋址方式
指令中描述操作數地址的方式,稱為操作數的尋址方式,簡稱尋址方式。尋址方式是匯編語言程序設計的重要基礎。
寄存器尋址方式
若操作數由寄存器提供,或操作結果要存入寄存器,則對應的操作數項就要指出所用的寄存器,操作數的這種方式就叫做寄存器尋址方式。
被加數和加數分別存于寄存器AL和BL中,寫出加法指令:
ADD ?AL,BL操作功能是:AL? ?——?(AL)+(BL),若(AL)=25H ,(BL)=36H,則AL 寄存器的內容為25H + 36H = 5BH ,而BL 中的內容不變。
將BX寄存器中所存的數據傳送給AX寄存器的指令:
MOV ?AX ,BX其操作功能是:AX? ?——?(BX) ,若執行前(AX)=1205H,(BX)=3600H,則執行指令后AX寄存器內容為3600H,BX寄存器內容不變。
立即尋址方式
若一個操作數項描述的是操作數本身(常量或表達式表示),而不是操作數的存放位置,則該操作數的尋址方式為立即尋址方式,表示該操作數的常量或表達式成為立即數。
將數據68傳送給AL寄存器的指令:
MOV ?AL,68 ?????其操作功能是:AL? ——?68
被加數存于寄存器DX中,加數為512,寫加法指令
ADD ?DX, 512立即尋址方式描述的是一個常量,而不是一個存放數據的位置,所以,立即尋址方式不能用于目的數的操作。
存儲器尋址方式
若操作數存于存儲器中,則對應的操作數項就要描述出操作數的存放地址,操作數的這種尋址方式稱為存儲器尋址方式。
指令中的存儲器地址都是邏輯地址,其中段地址由段寄存器提供,用段前綴(DS: , ES: , CS: , SS: )來指明所用的段寄存器,偏移地址(亦稱有效地址)部分的表示形式有很多種。
直接尋址方式
如果在描述操作數的地址時直接表示出操作數的偏移地址,則該操作數的尋址方式就是直接尋址方式
將存于數據段內偏移地址為0010H處的一個字節數據傳送給寄存器AL,寫出指令:
MOV ?AL , DS : [0010H]DS: ?為數據段前綴,用于指出地址由數據段寄存器DS提供,偏移地址0010H 必須置于方括號[]內。若設(DS)=2014H,則該存儲單元的物理地址=20140H + 0010H =20150H,又設(20150H)=52H,(AL)=52H。
?MOV ?AX ,DS : [2000H]該指令的執行結果是將DS :[2000H] 單元的內容傳送至AX寄存器中,其中高字節內容送至AH寄存器,低字節內容送至AL寄存器
寄存器間接尋址方式
若某個16為寄存器間接尋址的內容作為操作數的偏移地址,則該操作數的尋址方式稱為存儲器間接尋址方式。可用于寄存器間接尋址二的16位寄存器有SI、DI、BX、和BP,使用時必須置于方括號內。其中,使用SI、DI、BX時,段寄存器默認為DS,使用BP時,段寄存器默認為SS。
設(DS)=3010H ,(30220H)=0AH ,(30221H)=28H,則指令序列
MOV ?SI , 0120HMOV ?DX , [SI]執行后,(DX)=?
第一條指令,立即數0120H傳送給SI寄存器,(SI)=0120H,
第二條指令源操作數采用了寄存器間接尋址方式,以SI寄存器的內容0120H為操作數的偏移地址,段寄存器默認為DS,所形成的物理地址為 ??30100H+0120H=30220H
由于目的操作數是16位寄存器DX,所以需要從地址30220H和30221H 的兩個單元中讀取一個字傳送給DX。由題得出指令執行后(DX)=280H。
使用寄存器間接尋址方式需要注意:
寄存器相對尋址方式
寄存器相對尋址方式下,操作數的偏移地址的產生方式為:
偏移地址=(16位寄存器)+D
指令中表現的形式是:[16位寄存器+D]或D[16位寄存器]
其中的16位寄存器只能使用:SI、DI、BX、BP;D稱為位移量
當使用SI、DI、BX時段寄存器默認為DS;使用BP時,段寄存器默認為SS。
基址變址尋址方式
在16位寄存器SI、DI、BX、BP中,BX和BP也稱為基址寄存器,SI和DI又稱為變址寄存器(SI為源變址寄存器,DI為目標變址寄存器)。
在基址變址尋址方式下,操作數的偏移地址產生方式為:
偏移地址=(基址寄存器)+(變址寄存器)
在指令中表現的形式是:
[基址寄存器+變址寄存器]或[基址寄存器][變址寄存器]
其中基址寄存器用BX時,段寄存器默認為DS,而用BP時,段寄存器默認為SS。
篇一結束
總結
以上是生活随笔為你收集整理的小白的入门之——汇编语言程序设计教程的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: app上线发布流程_APP上线发布流程
- 下一篇: STM32 应用程序加密的一种设计方案