匯編學習(三)——匯編語言程序入門


一、尋址方式

1、概念:

    一條指令由操作碼和操作數構成,操作碼是系統定義好的符號,執行指定的操作,操作數即是指令的對象,而尋址方式就是操作數的指定方式

操作碼   目的操作數,源操作數

 

2、尋址方式的三種情況:

(1)CPU中(2)儲存器(3)I/O中

 

3、尋址方式分類

(1)隱含尋址:

    指令中只有操作碼沒有指定的操作數,但是根據操作碼就可確定相應的操作數

MUL BL;
 
DIV BL;

(2)立即尋址:

    指令中直接給出要操作的數

ADD AL,50

    立即尋址只能用在源操作數上

(3)寄存器尋址:

A、指令中給出寄存器的名字,寄存器中的內容是要操作的數,這種方式稱為寄存器尋址。

B、可以使用寄存器:8個通用16位寄存器(AX,BX,CX,DX,SI,DI,BP,SP),以及8個8位寄存器(AH,AL,BH,BL,CH,CL,DH,DL)

ADD AL,BL

(4)段寄存器尋址:

A、指令中給出段寄存器的名字,段寄存器中的內容是要操作的數,這種方式稱為段寄存器尋址。

B、可以使用段寄存器:4個段寄存器(CS,DS,ES,SS)

C、8086中只有數據傳輸指令MOV,堆棧操作指令PUSH和POP可以使用段寄存器尋址方式

(5)I/0口尋址

A、操作數在I/O接口中,這種尋址方式為I/O尋址

B、只用使用IN/OUT操作。

C、直接IO尋址:使用一個8位無符號數指定端口號

    間接IO尋址:使用一個16位寄存器DX來指定端口號

(6)轉移地址的尋址:

    指令指針IP會一直指向下一條要執行的命令,所以使用指令轉移IP內容,成為轉移地址的尋址

(7)儲存器操作數的尋址

①概念:

   8086CPU有20根地址線,所以儲存器每個單元的地址是20位(2進制),稱為物理地址,而CPU內部的寄存器都是16位,只用一個寄存器不能完整表示儲存器地址,所以拆成2個分量:段地址(CS,DS,ES,SS),偏移地址(BX,BP,SI,DI)

物理地址 = 段地址*10H + 偏移地址

 

②直接尋址

ADD AL,[Xvar]

將Xvar地址中的內容與AL相加,並儲存在AL中;其中Xvar是在數據段中定義的一個變量名

A、直接尋址:要用變量名指定地址

     立即尋址:常數作為源操作數

ADD AL,[20H]

認為是立即尋址

 

③寄存器間接尋址

A、將儲存器的偏移地址存在一個16位寄存器中,然后用方括號中的16位寄存器指定此偏移地址,成為寄存器間接尋址

B、BX,SI,DI搭配DS(數據段)

    BP搭配SS(堆棧段)

ADD AL,[BX];       從數據段的此地址取數據
ADD AL,[BP];       從堆棧段的此地址取數據

 

④寄存器相對尋址

A、就是在寄存器間接尋址的基礎上,使用BX+D(8位或者16位的常數偏移量)作為地址

ADD AL [SI+5];    
ADD AL [BP-5];

 

⑤基址變址尋址

A、將一個基址寄存器(BX,BP)與一個變址寄存器(SI,DI)的內容相加作為偏移地址,段寄存器搭配由基址寄存器決定:BX搭配DS,BP搭配SS

B、計算公式:

物理地址=DS*10H+BX/DP+SI/DI

C、指令

ADD AL,[BX+SI];     只能相加
ADD AL,[BP-DI];     不能相減
ADD AL [BX+BP];     也不能是兩個基址寄存器
ADD AL,[SI+DI];     或者是兩個變址尋址器

 

⑥相對基址變址尋址

A、就是在寄存器基址變址尋址的基礎上,使用BX+SI+D(8位或者16位的常數偏移量)作為地址

ADD AL,[BP+BI+5]
ADD AL,[BP+BI-5];   同樣的,不能有減法

 

二、數據傳送指令

1、通用數據傳送指令

MOV dst,src;

(1)立即數傳送給寄存器或儲存單元

A、立即數只能作為源操作數

B、若寄存器是16位,立即數可以是16位或8位,若寄存器是8位的,立即數只能是8位的。

C、目的操作數是存儲器,而立即數是8位,則存儲器必須有類型說明

 

(2)通用寄存器與存儲器之間的傳送

若通用寄存器是8位,則按字節傳送,若是16位,則按字傳送。

 

(3)兩個通用寄存器之間的傳送

源和目的必須同為8位或者16位寄存器

 

(4)段寄存器與通用寄存器或存儲器之間的傳送

A、程序的一開始,經常需要用立即數對段寄存器賦初值,但是,立即數為源操作數,段寄存器為目的的操作數尋址方式是非法的,所以使用:

MOV AX,DATA
MOV DS,AX

B、段寄存器作為源操作數時:DS,SS,ES,CS都可以使用

              作為目的操作數:CS不能使用

C、IP不能作為源操作數或者目的操作數

D、兩個存儲單元之間的傳送是允許的,所以

MOV AX,X1
MOV X2,AX

 

2、交換指令:

(1)指令格式

XCHG dst,src;

(2)操作數不能是立即數、段寄存器、存儲器操作數

(3)操作數的長度要一致

 

3、堆棧操作指令

(1)入棧指令:

A、指令格式:

PUSH src

    將一個源操作數壓入堆棧,具體過程:先將堆棧指針SP減2,然后將源操作數存入堆棧中SP所指的地址.

(2)出棧指令:

POP src
    將堆棧頂部的數據彈出給目的操作數,具體操作: 以SS為段地址,SP為偏移地址,將此地址中的數據取出傳給目的操作數,然后堆棧指針SP加2

(3)一些注意事項:

A、POP和PUSH的操作數必須是16位的。通用寄存器和存儲器皆可。

B、一些錯誤指令:

PUSH 1234     不能是立即數
PUSH AL         不能使用8位寄存器
PUSH IP          不能使用IP寄存器
POP   1234H   不能使用立即數
POP   AL         不能使用8位寄存器
POP  CS          CS不能作為目的操作數
C、 低字節在低地址,高字節在高地址

 

4、查表指令

(1)指令格式:

XLAT
XLAT src_table
     又稱換碼指令, 用BX指向數據段中一個表格的首地址,AL為某元素的下標,查表得到此元素的值存入AL中

(2)demo

MOV BX OFFSET TABLE 
MOV AL,5
XLAT

 

5、輸入/輸出指令

(1)指令格式

image

(2)一些注意點:

A、操作數必須是累加寄存器AL或者AX;另一個操作數是8位無符號port或者16位的數據寄存器DX,用來指定I/O接口電路中的一個地址

B、地址超8位,只能使用間接尋址。

 

6、地址傳送指令

(1)有效地址傳送:

A、指令格式:

LEA reg16,mem

     源操作數必須是存儲器操作數,目的操作數必須是16位的通用寄存器,功能是將存儲器操作數的偏移地址傳送給給一個16通用寄存器.

B、OFFSET:功能是取存儲器操作數的偏移地址。

 

(2)地址指針送寄存器和DS

LDS reg16,mem32;         等同於 reg16<---[mem32],DS<---[mem32+2]

 

(3)地址指針送寄存器和ES

LES reg16,mem32;         等同於 reg16<---[mem32],ES<---[mem32+2]

 

7、標志位傳送指令

(1)標志寄存器送AH

A、指令格式:

LAHF;         等同於AH<----標志寄存器的低八位

(2)AH送標志寄存器

A、指令格式:

SAHF;       標志寄存器低8位<------AH

PS:只能對標志寄存器的低八位進行操作

(3)標志寄存器入棧

A、指令格式:

PUSHF;             SP<------SP-2    SS:[SP]<------ 標志寄存器

(4)標志寄存器出棧

A、指令格式:

POPF;         標志寄存器<-------SS:[SP], SP<----SP+2

 

三、匯編語言程序結構:

DATA SEGMENT                       ;數據段開始
   ……                                            ;偽指令,定義數據段變量
DATA ENDS                              ;數據段結束

EXTRA SEGMENT                     ;擴展段開始
   ……                                            ;偽指令,定義擴展段變量
EXTRA ENDS                            ;擴展段結束

STACK SEGMENT                    ;堆棧段開始
   ……                                            ;偽指令,定義數據段變量
STACK ENDS                            ;堆棧段結束

MAC1 MACRO                            ;宏指令定義開始
……                                                ;偽指令或者指令,宏定義體
ENDM                                         ;宏指令定義結束

CODE SEGMENT                       ;代碼段開始
ASSUME    CS:CODE,DS:DATA,ES:EXTRA,SS:STACK
START:                                       ;主程序起始地址定義
   MOV      AX,DATA                    ;寄存器初始化
   MOV      DS,AX
   MOV      AX,EXTRA
   MOV      ES,AX
   MOV      AX,STACK
   MOV      SS,AX


……                                                  ;指令
CALL  SUB1                                  ;調用子程序
……;                                                 ;指令
MAC1                                            ;調用宏指令
……                                                  ;指令
MOV AH,4CH                                ;返回DOS
  INT  21H
  SUB1  PROC                               ;子程序定義開始
  ……
  RET                                             ;返回主程序
  SUB1  ENDP                               ;子程序定義結束
CODE ENDS                                 ;代碼段結束
END START                                  ;結束匯編

1、分段結構

(1)代碼段結束處,必須加入如下代碼,實現返回系統的功能

MOV,AH,4CH
INT 21H

(2)子程序中必須有RET使之能返回主程序

 

2、語句格式

(1)指令語句:

A、格式:

標號:操作碼       目的操作數,源操作數;注釋

(2)偽指令語句:

A、格式:

變量     操作碼   操作數,……,操作數;注釋

B、作用:

    匯編時起到輔助作用,不產生機器碼,也稱為指示性語句。

(3)宏定義語句

A、格式:

標號:宏定義指令名   實際參數;注釋

B、使用MACRO偽指令定義了一條宏指令之后,在代碼段中就可以用宏指令語句來調用此宏指令。

 

3、變量和標號:

     變量和標號都是來表示存儲器中的地址,標號只能在代碼段中定義,變量可以在任意段中定義。標量和標號都有段地址、偏移地址和類型三種屬性,變量的類型屬性有:BYTE,WORD,DWORD幾種。標號的類型有NEAR或者FAR兩種。

 

4、操作數、表達式和操作符

(1)算術操作符:+ – * / 和MOD

     加減可以對地址進行操作

(2)邏輯操作符:AND,OR,XOR,NOT,SHL(左移),SHR(右移)

     和指令操作碼方法一致,但只能對數值進行操作,不能對地址進行操作

(3)關系操作符:EQ(相等)、NE(不等)、GT(大於)、LT(小於)、GE(大於等於)、LE(小於等於)

      A、用0表示假,用0FFH或者0FFFFH表示真。

      B、可以比較數值也可以比較地址

(4)分析操作符:SEG,OFFSET,TYPE,LENGTH和SIZE

SEG 取段地址
OFFSET 取偏移地址
TYPE 取類型
1:BYTE
2:WORD
4:DWORD
LENGTH 取變量中用DUP定義的數據的個數
SIZE LENGTH和TYPE的乘積

(5)屬性操作符:HIGH、LOW、SHORT、PTR、THIS和段操作符共6個

HIGH 取高字節
LOW 取低字節
SHORT 段類型
PTR 改變標號
THIS 改變變量類型

 

5、常用偽指令

(1)符號定義偽指令
A、格式:

名稱   EQU  表達式     ;使用EQU定義的名稱可以進行修改
名稱 = 表達式 ;不可以進行修改

B、作用:

   就是定義個符號常量的作用。

(2)數據定義偽指令

A、格式:

變量    偽操作符   表達式,表達式,……;注釋
變量    偽操作符   重復次數   DUP(表達式,表達式,……);注釋

B、說明

①其中變量和注釋可有可無,然后定義數據的偽操作符有以下5個:DB(字節),DW(字)、DD(雙字)、DQ(8個字節)和DT(10個字節)

②若要定義一組數是相同的,使用第二種方法

若要預留地址空間,沒有初始數值,則數據項可以寫為”?“每一個”?“代表一個數據,占用的地址為由偽操作符決定

 

四、匯編成語上機過程,(使用尋址方式驗證代碼來書寫)

1、DOSBox模擬器初始化

image

      其中g:\匯編目錄下有:

image

 

2、編輯

image

鍵入代碼后回車。

edit xunzhi.asm

image

得到如上界面,進行書寫代碼,並保存。

image

 

3、匯編

image

如圖鍵入代碼,回車回車回車

image

這里會顯示語法錯誤信息,如果有錯就會報錯

 

3、鏈接

image

鍵入代碼回車

image

沒有錯誤,則進行調試

 

5、調試

image

如圖鍵入代碼:然后回車就進入調試

(1)鍵入U回車

image

A、U命令是反匯編,將內存中的機器碼反匯編成指令顯示。

B、可能每次不能顯示全部指令,所以再U可以繼續顯示,U0可以返回到代碼段的首部

image

 

(2)在內存中查看數據段,擴展段和堆棧段中的數據

查看內存中的數據使用命令

D+地址:0
D076A:0

image

再次鍵入D命令,會繼續往下面顯示

 

(3)單步運行程序,查看運行結果

t=0 從第一句開始,按t順心執行

image


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM