【x86彙編】第三章:宏彙編語言的表達式

表達式

常量

常量分爲:

  • 數值常量:MOV AX, 10H
  • 符號常量:VAR EQU 20

數值常量可以是:

  • 二進制:0101B
  • 八進制:123Q 或者 123O
  • 十進制:467 或者 467D
  • 十六進制:0FFH
  • 字符常量:‘123abc’ “hello”

數值表達式

算術運算:

  • 加、減、乘、除、取模(MOD)、左移(SHL)、右移(SHR)
  • 注意負數的取模,根據商的值進行推算(不同語言,商可能不同)

邏輯運算:

  • 相等(EQ)、不等(NE)、小於(LT)、大於(GT)、小於等於(LE)、大於等於(GE)
  • 運算結果爲特殊常量:成立,爲0FFFFH,不成立爲0

變量

變量的屬性:

  • 段屬性:所在段的段首址
  • 偏移地址:相對段首址的EA
  • 類型:存取所需要的字節數

變量的定義使用僞指令:DB、DW、DD、DF、DQ、DT

定義格式: [變量名] 數據定義僞指令 表達式
表達式有以下幾種形式:

  • 數值表達式:VAR DB 10
  • ASCII字符串:BUF DB ‘abc123’
  • 地址表達式:只適用於DW和DD,16位段中,DW取該地址的EA,DD取段首址和EA,32位段取EA
  • ?:表示不進行初始化賦值
  • 重複子句:n DUP(表達式)
  • 上述形式的組合,逗號隔開

標號

標號是機器指令語句存放地址的符號表示,也可以是子程序名
標號的屬性:

  • 段屬性:所在段的段首址
  • 偏移地址:到段首址的EA
  • 類型:NEAR和FAR,NEAR類型的標號,只能段內使用

地址表達式

  • 地址表達式是由變量、標號、常量、寄存器的內容,和運算符組成的
  • 如果地址表達式中出現了變量、標號,則取它的EA參與運算

屬性定義算符PTR

指明該地址的操作數,是什麼數據類型,或者臨時改變操作數的類型,不能改變寄存器和立即數的類型

類型 PTR 地址表達式

例如:WORD PTR [SI]
類型:BYTE、WORD、DWORD、FWORD、NEAR、FAR

定義類型運算符THIS

指定下一個能分配的存儲單元的類型,往往與EQU、=等連用

THIS 類型

跨段前綴算符

用於臨時給變量、標號指明段屬性

段寄存器:地址表達式

屬性分離運算符

分離出變量、標號的段、EA和類型

  • 取段址運算符SEG:取出段首址
  • 取偏移地址算符OFFSET:取出EA
  • 取類型運算符TYPE:取出變量或標號的類型

其它算符

  • 取變量存儲單元個數LENGTH:它的取值根據定義該變量時,數據定義僞指令後面的一個表達式而定
  • 取變量所含數據存儲區大小算符SIZE:其值爲LENGTH * TYPE
  • 字節分離算法:HIGH和LOW

常用運算符優先級

運算優先級

常用的機器指令語句

操作規定:

  • 目的操作數與源操作數,必須類型相同
  • 目的操作數不能是立即數
  • 目的操作數與源操作數,不能都存儲在寄存器
  • 運算完後,結果送入目的操作數,源操作數不變

數據傳送指令

  • 一般數據傳送指令:MOV、MOVSX、MOVZX、XCHG、XLAT
  • 堆棧操作指令:PUSH、PUSHA、PUSHAD、POP、POPA、POPAD
  • 標誌寄存器傳送指令:PUSHF、PUSHFD、POPF、POPFD、LAHF、SAHF
  • 地址傳送指令:LEA、LDS、LES、LFS、LGS、LSS
  • 輸入輸出指令:IN、OUT

影響標誌位的指令:SAHF、POPF、POPFD

一般數據傳送指令

傳送指令

MOV OPD,OPS

將源操作數送入目的地址中

MOVSX OPD, OPS

將有符號數,向前擴展成與目的操作數相同的數據類型後,送入目的地址

MOVZX OPD, OPS

將無符號數,源操作數高位補0,擴展成與目的操作數相同的數據類型後,送入目的地址

數據交換指令

XCHG OPD, OPS

將源操作數和目的操作數中的內容互換

BSWAP OPD

將32位通用寄存器OPD中的,第一個和第三個、第二個和第四個字節的內容交換

XADD OPD,OPS

將源操作數和目的操作數中的內容互換,再求和,送入目的地址

查錶轉換指令

XLAT OPS 或者 XLAT

功能:( [ EBX/BX + AL ] ) -> AL,其中,BX爲段首址,AL爲EA

地址傳送指令

傳送偏移地址指令

LEA OPD,OPS

按照OPS提供的尋址方式,計算EA,送入OPD
其中,OPD一定是16/32位寄存器,OPS一定是存儲器地址

傳送偏移地址及數據段首址指令

CPU只能訪問6個當前段,如果需要訪問此外的段,要重新給相應的段寄存器賦值

LDS OPD,OPS

功能:( OPS ) -> OPD, ( OPS + 2/4 ) -> DS,切換當前數據段
其中:OPD一定是16/32位寄存器,OPS一定是存儲器地址,且類型爲DW/FW

傳送偏移地址及附加數據段首址指令

LES OPD,OPS

功能:( OPS ) -> OPD, ( OPS + 2/4 ) -> ES,切換當前附加數據段
其中:OPD一定是16/32位寄存器,OPS一定是存儲器地址,且類型爲DW/FW

算數運算指令

二進制算數運算指令

加類指令

ADD、ADC、INC

ADD OPD OPS
INC OPD

減類指令

DEC、NEG、SUB、SBB、CMP

DEC OPD
NEG OPD :求補指令
SUB OPD,OPS
CMP OPD,OPS:結果爲 ( OPD ) - ( OPS ),根據結果設置標誌位,但是源、目標操作數不變

乘類指令

IMUL、MUL
有符號乘:

IMUL OPD,OPS:( OPD ) * ( OPS ) -> OPD
IMUL OPD,OPS,n:( OPD ) * n -> OPD
IMUL OPS

無符號乘:

IMUL OPS

字節乘法:( AL ) * ( OPS ) -> AX
字乘法:( AX ) * ( OPS ) -> DX,AX
雙字乘法:( EAX ) * ( OPS ) -> EDX,EAX

除類指令

IDIV、DIV

無符號除:

DIV OPS

有符號除:

IDIV OPS

字節除法:( AX ) / ( OPS ) -> AL(商)、AH(餘數)
字除法:( DX、AX ) / ( OPS ) -> AX(商)、DX(餘數)
雙字除法:( EDX、EAX ) / ( OPS ) -> EAX(商)、EDX(餘數)

符號擴展指令

CBW、CWD、CWDE、CDQ

  • CBW:字節轉換爲字,將AL中的符號擴展至AH中
  • CWD:字轉換爲雙字,將AX中的符號擴展至DX中
  • CWDE:將AX中的有符號數擴展爲32位數 -> EAX
  • CDQ:將EAX中的有符號數擴展爲64位數 -> EDX,EAX

位操作指令

邏輯運算指令

求反

NOT OPD

將目的地址中的內容,逐位取反,然後送回目的地址

邏輯乘

AND OPD,OPS

目的操作數與源操作數逐位做與運算,結果存入目的地址中

測試

TEST、BT、BTC

TEST OPD,OPS

目的操作數與源操作數做邏輯乘(AND),按結果置標誌位SF、ZF、PF
該指令主要用於檢測源操作數中1的那幾位,對應於目的操作數的那幾位,是否爲0

邏輯加

OR OPD,OPS

目的操作數與源操作數逐位做或運算,結果存入目的地址中

按位加

XOR OPD,OPS

目的操作數與源操作數逐位做加運算,結果存入目的地址中

移位指令

算數、邏輯移位

SAL OPD,n:算數左移
SHL OPD,n:邏輯左移

向左移動N位,低位補0,CF標誌位爲最後移入的值

SHR OPD,n:邏輯右移

向右移動N位,高位補0

SAR OPD,n:算數右移

向右移動N位,高位保持不變(爲1則補1,爲0則補0),CF爲最後移入的值

循環移位

ROL OPD,n:循環左移
ROR OPD,n:循環右移

將目的操作數的最高位和最低位連起來,組成一個環,一起移位,CF爲最後移入的值

RCL OPD,n:帶進位的循環左移
RCR OPD,n:帶進位的循環右移

雙精度移位

SHLD OPD,OPS,n:雙精度左移
SHRD OPD,OPS,n:雙精度右移

雙精度左移:將OPS的最高n位,移入OPD低n位中,OPS保持不變,CF爲OPD最後移出的一位
雙精度右移:低n位,移入高n位

僞指令語句

僞指令語句,也叫彙編控制指令,它是在源程序中,使用一些約定好的、固定格式的符號,來告訴編譯程序,該如何工作,每一條僞指令,都對應一段處理程序

僞指令一共有九類:

  • 處理器選擇僞指令
  • 數據定義僞指令
  • 符號定義僞指令
  • 段定義僞指令
  • 過程定義僞指令
  • 程序模塊的定義與通信僞指令
  • 宏定義僞指令
  • 條件彙編僞指令
  • 格式控制、列表控制及其它功能僞指令

處理器選擇僞指令

學習的時候,一般選擇.386,根據具體芯片支持的指令集來
該指令一般放在源代碼的開頭部分,也可以放在段中

數據定義僞指令

DB、DW、DD、DF、DQ、DT
該僞指令用以定義變量時,指定其類型大小

符號定義僞指令

等價僞指令

符號名 EQU 表達式

給表達式定義一個別名,但是不申請分配新的空間,類似於C語言的宏替換

等號僞指令

符號名 = 表達式

與EQU類似,不同的是等號語句可以對定義的符號名重定義

定義符號名僞指令

變量名或標號 LABLE 類型
DWBUF LABEL WORD

給當前存儲單元定義一個指定類型的變量或者標號,類似於C語言的typedef

段定義僞指令

段定義僞指令

段名 SEGMENT [使用類型] [定位方式] [組合方式] [‘類別’]
段名 ENDS

假定僞指令

ASSUME 段寄存器:段名[,段寄存器:段名]

設定段寄存器與段之間的對應關係,即告訴彙編程序,目前哪些段爲CPU當前可訪問段

置彙編地址計數器僞指令

  • 彙編地址計數器用 符號$ 來表示,它用來記錄正在被彙編程序翻譯的語句的地址,即 $ 的內容標示了彙編程序當前的工作位置
  • 一個程序包含多個段,彙編時,每遇到一個段,就爲該段分配一個初值爲0的 $ 彙編地址計數器
  • 段內定義的所有標號和變量的偏移地址,就是彙編時,當前彙編地址計數器 $ 的值
  • 該計數器可以用ORG指令設置

源程序結束僞指令

END [表達式]

  • 標誌整個程序的結束,後面可以帶表達式,表示程序的啓動地址
  • 如果後面不帶表達式,往往是作爲子模塊被其它模塊調用

常用的DOS系統功能調用

概述

DOS提供的功能主要有:

  • 設備管理
  • 文件管理
  • 目錄管理
  • 其它功能調用

DOS系統功能調用的一般過程:

  • 將調用號放入寄存器AH中,置好入口參數
  • 然後執行軟中斷語句 INT 21H

常用的輸入輸出調用

鍵盤輸入

調用格式:

MOV AH,1
INT 21H

功能:等待從鍵盤輸入一個字符,並將ASCII碼送入寄存器AL中

顯示輸出

調用格式:

MOV DL,待顯示的ASCII碼
MOV AH,2
INT 21H

功能:將DL中的字符,送到顯示器

輸入字符串

調用格式:

LEA DX,緩衝區偏移地址(字符串首的偏移地址)
MOV AH,10
INT 21H

功能:將鍵盤輸入的字符串,送到當前數據段DS:DX中
調用要求:

  • 該緩衝區一定要定義在當前數據段中
  • 該調用要求輸入緩衝區按照規定的格式定義
BUF   DB      80
          DB      ?
          DB      80     DUP(0)
  1. 第一個字節規定緩衝區大小,不能是0
  2. 第二個字節存放實際輸入的個數
  3. 第三個字節開始,存放輸入字符串的ASCII碼,以回車 0DH 結束

顯示字符串

調用格式:

LEA DX,字符串首EA
MOV AH,9
INT 21H

功能:將當前數據段中,DS:DX所指向的,以 $ 結尾的字符串送到顯示器

MASM的功能

MASM的介紹

常用的彙編程序是微軟推出的 MASM 和 Borland推出的 TASM
MASM就是一個兩次掃描的宏彙編程序,即兩次掃描後,MASM就能將源程序翻譯成目標程序
主要功能如下:

  • 檢查彙編源程序中的語法錯誤, 並給出錯誤信息
  • 處理宏庫, 對源程序中的宏指令完成宏擴展
  • 處理各種僞指令
  • 產生與源文件對應的可再定位的目標文件(.OBJ)
  • 提供包括源程序、目標程序以及符號表在內的彙編列表文件(.LST)
  • 提供一個含有特定控制字符的符號交叉參考文件(.CRF 或.SBR)

彙編過程

MASM提供了兩個符號表:

  • 機器指令表:指令記憶符與其目標代碼的對照
  • 僞指令表:僞指令與其對應處理程序的入口地址對照表

第一次掃描,建立用戶自定義符號表和宏定義表

  • 自定義符號表分爲段表和一般符號表(符號常量、標號、變量等)
  • 段表中登記着程序中所定義的各段的段名、所佔字節數、定位、組合方式、類別
  • 一般符號表登記着程序中所定義和引用的全部符號常量、變量、標號的名字及其屬性值
  • 宏定義表記錄程序中全部宏定義的名字、內容及其有關的性質, 在掃描過程中進行宏擴展

第二次掃描,將源程序翻譯成目標程序,同時產生彙編列表文件(.LST)、符號交叉參考文件(.CRF)

彙編列表文件

彙編列表文件是源程序行、目標代碼及其在段內存放的偏移地址的一個對照表,出錯時,給出提示,可以分爲以下三部分:

  • 彙編表:主要由源程序行、對應的目標代碼及其在段內的偏移地址和錯誤信息提示組成
  • 段(組)表:列出源程序中所定義的各段(組)的名字、所佔存儲區大小及其特徵等
  • 符號表:列出了源程序中所定義或引用的全部標號、變量、符號常量的屬性值及其特徵等

符號交叉列表文件

  • 詳盡地列出了程序中用戶自定義符號, 如: 段名、標號、變量、符號常量、宏定義名等的定義符號和引用行行號
  • 用戶按照這個行號, 可以很快找到自己程序中所有符號的位置,便於程序調試
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章