關(guān)于我們
書(shū)單推薦
新書(shū)推薦
|
匯編語(yǔ)言程序設(shè)計(jì)教程
本書(shū)以IBM PC機(jī)型和80x86指令系統(tǒng)為對(duì)象,全面而系統(tǒng)地介紹微型計(jì)算機(jī)系統(tǒng)的結(jié)構(gòu)及匯編語(yǔ)言程序設(shè)計(jì)的方法。全書(shū)由10章組成。第1章和第2章介紹匯編語(yǔ)言基礎(chǔ)知識(shí)和微型計(jì)算機(jī)的體系結(jié)構(gòu);第3章詳細(xì)介紹IBM PC的尋址方式和指令系統(tǒng);第4章介紹偽指令、匯編語(yǔ)言程序格式等知識(shí);第5章講述典型匯編語(yǔ)言程序結(jié)構(gòu)的設(shè)計(jì)方法;第6章詳細(xì)介紹子程序設(shè)計(jì)及參數(shù)傳遞的方法;第7章介紹輸入/輸出程序設(shè)計(jì)技術(shù)和方法;第8章介紹宏匯編、重復(fù)匯編和條件匯編等高級(jí)匯編技術(shù);第9章講述DOS功能調(diào)用和BIOS功能調(diào)用知識(shí);第10章是匯編語(yǔ)言上機(jī)環(huán)境及程序設(shè)計(jì)實(shí)例分析。
充分考慮微型機(jī)技術(shù)的發(fā)展、教學(xué)方法的完善以及教學(xué)手段的改進(jìn)等因素,系統(tǒng)地介紹微機(jī)原理的基礎(chǔ)知識(shí)及匯編語(yǔ)言程序設(shè)計(jì)的方法和技術(shù)。
提供大量的例程分析,幫助學(xué)生掌握匯編語(yǔ)言程序設(shè)計(jì)的步驟和方法。 提供匯編語(yǔ)言程序設(shè)計(jì)上機(jī)實(shí)驗(yàn)指導(dǎo)、實(shí)例分析及學(xué)生上機(jī)練習(xí)作業(yè)的要求。 每章均有思考與練習(xí)題,可以作為鞏固相關(guān)知識(shí)的課后作業(yè)。
前言
計(jì)算機(jī)技術(shù)及電子技術(shù)的迅猛發(fā)展,使得人們的學(xué)習(xí)、工作、生活越來(lái)越離不開(kāi)計(jì)算機(jī),計(jì)算機(jī)知識(shí)及其應(yīng)用技能已經(jīng)成為人類(lèi)知識(shí)結(jié)構(gòu)的重要組成部分。微型計(jì)算機(jī)技術(shù)的發(fā)展,不斷涌現(xiàn)新技術(shù)、新產(chǎn)品。本書(shū)以IBM PC作為背景,系統(tǒng)地介紹微機(jī)原理的基礎(chǔ)知識(shí)及匯編語(yǔ)言程序設(shè)計(jì)的方法和技術(shù)。本次再版在前三版《匯編語(yǔ)言程序設(shè)計(jì)教程》的基礎(chǔ)上,修改并增加了部分內(nèi)容。在教材編寫(xiě)過(guò)程中,參照了國(guó)內(nèi)多所高校本科“匯編語(yǔ)言程序設(shè)計(jì)”課程的教學(xué)大綱,兼顧相關(guān)專(zhuān)業(yè)的教學(xué)要求和特點(diǎn),并充分考慮到了微型機(jī)技術(shù)的發(fā)展、教學(xué)方法的完善以及教學(xué)手段的改進(jìn)等因素。全書(shū)共分10章。第1章和第2章介紹匯編語(yǔ)言基礎(chǔ)知識(shí)和微型計(jì)算機(jī)的體系結(jié)構(gòu); 第3章詳細(xì)介紹IBM PC的尋址方式和指令系統(tǒng); 第4章介紹偽指令、匯編語(yǔ)言程序格式等知識(shí); 第5章講述典型匯編語(yǔ)言程序結(jié)構(gòu)的設(shè)計(jì)方法; 第6章詳細(xì)介紹子程序設(shè)計(jì)及參數(shù)傳遞的方法。第7章介紹輸入/輸出程序設(shè)計(jì)技術(shù)和方法; 第8章介紹宏匯編、重復(fù)匯編和條件匯編等高級(jí)匯編技術(shù); 第9章講述DOS功能調(diào)用和BIOS功能調(diào)用知識(shí),通過(guò)大量程序設(shè)計(jì)實(shí)例分析系統(tǒng)功能調(diào)用的實(shí)現(xiàn); 第10章是匯編語(yǔ)言上機(jī)環(huán)境及程序設(shè)計(jì)實(shí)例分析,給出學(xué)生上機(jī)練習(xí)的要求。本書(shū)每章后均有思考與練習(xí),可以作為鞏固相關(guān)知識(shí)的課后作業(yè)。第5~10章有大量的例程分析,以幫助學(xué)生掌握匯編語(yǔ)言程序設(shè)計(jì)的步驟和方法。在附錄部分提供了DOS功能調(diào)用、BIOS功能調(diào)用和80x86指令系統(tǒng)的匯總,供讀者學(xué)習(xí)過(guò)程中查閱。本書(shū)由上海交通大學(xué)卜艷萍老師和華東理工大學(xué)周偉老師共同編著。周偉編寫(xiě)第5~8章、第10章和附錄A。卜艷萍編寫(xiě)第1~4章、第9章、附錄B和附錄C,并負(fù)責(zé)全書(shū)的統(tǒng)稿工作。由于編者水平有限及時(shí)間倉(cāng)促,書(shū)中不妥之處,敬請(qǐng)讀者批評(píng)指正。作者聯(lián)系郵箱: ypbu@sjtu.edu.cn。 作者2016年5月
目錄
第1章匯編語(yǔ)言基礎(chǔ)知識(shí) 1.1計(jì)算機(jī)基礎(chǔ)知識(shí) 1.1.1計(jì)算機(jī)的發(fā)展史 1.1.2計(jì)算機(jī)的特性 1.1.3計(jì)算機(jī)的分類(lèi)與應(yīng)用 1.1.4計(jì)算機(jī)的主要技術(shù)指標(biāo) 1.2計(jì)算機(jī)的基本結(jié)構(gòu)與組成 1.2.1計(jì)算機(jī)的硬件 1.2.2計(jì)算機(jī)的軟件 1.2.3計(jì)算機(jī)的程序設(shè)計(jì)語(yǔ)言 1.2.4計(jì)算機(jī)系統(tǒng)的層次結(jié)構(gòu) 1.3計(jì)算機(jī)中的數(shù)制與碼制 1.3.1數(shù)制及數(shù)制轉(zhuǎn)換 1.3.2機(jī)器數(shù)的編碼 1.3.3定點(diǎn)數(shù)與浮點(diǎn)數(shù) 1.3.4碼制 思考與練習(xí) 第2章微型計(jì)算機(jī)體系結(jié)構(gòu) 2.180x86微處理器 2.1.18086/8088的功能結(jié)構(gòu) 2.1.28086/8088的寄存器組織 2.1.38086/8088的存儲(chǔ)器組織 2.1.480x86微處理器的發(fā)展 2.2IA32 CPU 2.2.1IA32 CPU功能結(jié)構(gòu) 2.2.2IA32 CPU寄存器組 2.2.3IA32 CPU存儲(chǔ)器管理 2.3先進(jìn)的微處理器 2.3.1高檔Pentium微處理器 2.3.2迅馳技術(shù) 2.3.3多核技術(shù) 2.3.4專(zhuān)用微處理器 2.3.5微處理器領(lǐng)域的架構(gòu)革命 思考與練習(xí) 第3章微型計(jì)算機(jī)的指令系統(tǒng) 3.1尋址方式 3.1.1操作數(shù)的種類(lèi) 3.1.28086/8088的機(jī)器代碼格式 3.1.3與數(shù)據(jù)有關(guān)的尋址方式 3.1.4與轉(zhuǎn)移地址有關(guān)的尋址方式 3.28086/8088指令系統(tǒng) 3.2.1數(shù)據(jù)傳送類(lèi)指令 3.2.2算術(shù)運(yùn)算類(lèi)指令 3.2.3邏輯操作類(lèi)指令 3.2.4程序控制類(lèi)指令 3.2.5串操作類(lèi)指令 3.2.6處理器控制類(lèi)指令 3.2.7輸入/輸出類(lèi)指令 3.380x86指令系統(tǒng)介紹 3.3.180x86尋址方式 3.3.280286指令系統(tǒng)新增指令 3.3.380386指令系統(tǒng)新增指令 3.3.480486指令系統(tǒng)新增指令 3.3.5Pentium指令系統(tǒng)新增指令 思考與練習(xí) 第4章偽指令與匯編語(yǔ)言程序結(jié)構(gòu)設(shè)計(jì) 4.1匯編語(yǔ)言語(yǔ)句類(lèi)型和格式 4.2偽指令 4.2.1表達(dá)式賦值偽指令 4.2.2數(shù)據(jù)定義偽指令 4.2.3LABEL偽指令 4.2.4段定義偽指令 4.2.5簡(jiǎn)化段定義偽指令 4.2.6過(guò)程定義偽指令 4.2.7模塊命名、通信等偽指令 4.3匯編語(yǔ)言源程序結(jié)構(gòu) 4.3.1完整段定義結(jié)構(gòu) 4.3.2簡(jiǎn)化段定義結(jié)構(gòu) 4.3.3程序段前綴結(jié)構(gòu) 4.3.4可執(zhí)行程序結(jié)構(gòu) 思考與練習(xí) 第5章匯編語(yǔ)言程序設(shè)計(jì) 5.1匯編語(yǔ)言程序設(shè)計(jì)概述 5.2順序程序設(shè)計(jì) 5.3分支程序設(shè)計(jì) 5.3.1雙分支結(jié)構(gòu)程序設(shè)計(jì) 5.3.2多分支結(jié)構(gòu)程序設(shè)計(jì) 5.4循環(huán)程序設(shè)計(jì) 5.4.1簡(jiǎn)單循環(huán)程序設(shè)計(jì) 5.4.2多重循環(huán)程序設(shè)計(jì) 思考與練習(xí) 第6章子程序設(shè)計(jì) 6.1子程序的定義與調(diào)用 6.1.1子程序的定義 6.1.2子程序的調(diào)用 6.2子程序的參數(shù)傳遞方法 6.2.1通過(guò)寄存器傳遞參數(shù) 6.2.2通過(guò)堆棧傳遞參數(shù) 6.2.3通過(guò)內(nèi)存單元傳遞參數(shù) 6.3子程序的嵌套與遞歸 6.3.1子程序的嵌套調(diào)用 6.3.2子程序的遞歸調(diào)用 思考與練習(xí) 第7章輸入/輸出程序設(shè)計(jì) 7.1微機(jī)接口技術(shù)概述 7.2輸入/輸出的控制方式 7.2.1程序查詢(xún)傳送方式 7.2.2中斷傳送方式 7.2.3DMA傳送方式 7.3輸入/輸出綜合應(yīng)用程序舉例 思考與練習(xí) 第8章高級(jí)匯編技術(shù) 8.1宏匯編 8.1.1宏定義與宏調(diào)用 8.1.2宏匯編實(shí)例分析 8.1.3宏嵌套 8.2重復(fù)匯編與條件匯編 8.2.1重復(fù)匯編 8.2.2條件匯編 8.3復(fù)雜數(shù)據(jù)結(jié)構(gòu) 8.3.1結(jié)構(gòu) 8.3.2記錄 8.4模塊化程序設(shè)計(jì) 8.4.1宏庫(kù)的使用 8.4.2源程序的包含文件 8.4.3目標(biāo)代碼文件的連接 思考與練習(xí) 第9章DOS/BIOS功能調(diào)用 9.1概述 9.2DOS功能調(diào)用 9.2.1DOS功能調(diào)用概述 9.2.2DOS功能調(diào)用程序?qū)嵗?br /> 9.3BIOS功能調(diào)用 9.3.1BIOS功能調(diào)用概述 9.3.2BIOS功能調(diào)用程序?qū)嵗?br /> 9.3.3顯示器BIOS中斷服務(wù) 9.4綜合應(yīng)用程序設(shè)計(jì)舉例 思考與練習(xí) 第10章匯編語(yǔ)言上機(jī)環(huán)境及程序設(shè)計(jì)實(shí)例 10.1匯編語(yǔ)言程序設(shè)計(jì)上機(jī)實(shí)驗(yàn)相關(guān)知識(shí) 10.1.1匯編程序 10.1.2DEBUG命令的使用 10.1.3匯編錯(cuò)誤信息 10.2微型計(jì)算機(jī)操作系統(tǒng)介紹 10.2.1微型機(jī)操作系統(tǒng)MSDOS 10.2.2微型機(jī)操作系統(tǒng)Windows 10.3程序設(shè)計(jì)實(shí)例分析及實(shí)驗(yàn)任務(wù) 10.3.1順序程序設(shè)計(jì) 10.3.2分支程序設(shè)計(jì) 10.3.3循環(huán)程序設(shè)計(jì) 10.3.4子程序設(shè)計(jì) 10.3.5系統(tǒng)功能調(diào)用 10.4調(diào)試程序CodeView的使用 10.5匯編語(yǔ)言與C/C 的混合編程 10.6軟件逆向工程與反匯編 思考與練習(xí) 附錄ADOS功能調(diào)用(INT 21H) 附錄BBIOS功能調(diào)用 附錄C80x86指令系統(tǒng)一覽表 參考文獻(xiàn)
第3章微型計(jì)算機(jī)的指令系統(tǒng)
計(jì)算機(jī)是通過(guò)執(zhí)行指令序列來(lái)解決問(wèn)題的,每種計(jì)算機(jī)都有一套指令集合供用戶(hù)使用。在微型計(jì)算機(jī)中,微處理器能執(zhí)行的各種指令的集合稱(chēng)為指令系統(tǒng)。微處理器的主要功能是由它的指令系統(tǒng)來(lái)體現(xiàn)的。在其他條件相同的情況下,指令系統(tǒng)越強(qiáng),機(jī)器的功能也就越強(qiáng)。不同的微處理器有不同的指令系統(tǒng),其中每一條指令對(duì)應(yīng)著處理器的一種基本操作。計(jì)算機(jī)只能識(shí)別由二進(jìn)制編碼表示的指令,稱(chēng)為機(jī)器指令。一條機(jī)器指令應(yīng)包含兩部分內(nèi)容,其一般格式為: 操作碼操作數(shù) 操作碼部分指出此指令要完成何種操作; 操作數(shù)部分則指出參與操作的對(duì)象是什么。在指令中可以直接給出操作數(shù)的值或者操作數(shù)存放在何處,操作的結(jié)果應(yīng)送往何處等信息。處理器可根據(jù)指令字中給出的地址信息求出存放操作數(shù)的地址,稱(chēng)為有效地址(Effective Address,EA),然后對(duì)存放在有效地址中的操作數(shù)進(jìn)行存取操作。3.1尋 址 方 式根據(jù)操作數(shù)的種類(lèi),8086/8088指令系統(tǒng)的尋址方式分為兩大類(lèi): 數(shù)據(jù)尋址方式和轉(zhuǎn)移地址尋址方式。3.1.1操作數(shù)的種類(lèi)在8086/8088指令系統(tǒng)中,操作數(shù)可分為數(shù)據(jù)操作數(shù)和轉(zhuǎn)移地址操作數(shù)兩大類(lèi)。1. 數(shù)據(jù)操作數(shù)數(shù)據(jù)操作數(shù)是指指令中操作的對(duì)象是數(shù)據(jù)。數(shù)據(jù)操作數(shù)的類(lèi)型有以下幾種。(1) 立即數(shù)操作數(shù): 指令中要操作的數(shù)據(jù)在指令中。(2) 寄存器操作數(shù): 指令中要操作的數(shù)據(jù)存放在指定的寄存器中。(3) 存儲(chǔ)器操作數(shù): 指令中要操作的數(shù)據(jù)存放在指定的存儲(chǔ)單元中。(4) I/O操作數(shù): 指令中要操作的數(shù)據(jù)來(lái)自或送到I/O端口。對(duì)于數(shù)據(jù)操作數(shù),有的指令只有一個(gè)操作數(shù)或沒(méi)有操作數(shù)。而有的指令有兩個(gè)操作數(shù),一個(gè)稱(chēng)為源操作數(shù),在操作過(guò)程中保持原值不變; 另一個(gè)稱(chēng)為目標(biāo)操作數(shù),操作后一般被操作結(jié)果所替代。另外,還有一種隱含操作數(shù)。這種操作數(shù)從指令格式上看,好像是沒(méi)有操作數(shù),或只有一個(gè)操作數(shù),實(shí)際上隱含了一個(gè)或兩個(gè)操作數(shù)。2. 地址操作數(shù)地址操作數(shù)是指指令中操作的對(duì)象是地址。其指令只有一個(gè)目標(biāo)操作數(shù),該操作數(shù)不是普通數(shù)據(jù),而是要轉(zhuǎn)移的目標(biāo)地址。它也可以分為立即數(shù)操作數(shù)、寄存器操作數(shù)和存儲(chǔ)器操作數(shù),即要轉(zhuǎn)移的目標(biāo)地址包含在指令中,或存放在寄存器中,或存放在存儲(chǔ)單元之中。3.1.28086/8088的機(jī)器代碼格式8086/8088 CPU的機(jī)器代碼格式如圖3.1所示。 1/2字節(jié)0/1字節(jié)0/1/2字節(jié)0/1/2字節(jié) 操作碼mod reg r/m位移量立即數(shù) 圖3.18086/8088的機(jī)器代碼格式 操作碼占1或2字節(jié),后面的各字節(jié)指明操作數(shù)。其中,“mod reg r/m”字節(jié)表明尋找操作數(shù)的方式(即采用的尋址方式),“位移量”字節(jié)給出某些尋址方式需要的相對(duì)基地址的偏移量,“立即數(shù)”字節(jié)給出立即尋址方式需要的數(shù)值本身。由于設(shè)計(jì)有多種尋址方式,操作數(shù)的各個(gè)字段有多種組合,表3.1給出了各種組合情況。 表3.18086/8088指令的尋址方式字節(jié)編碼 r/m mod 000110 11 w=0w=1reg 000[BX SI][BX SI D8][BX SI D16]ALAX000001[BX DI][BX DI D8][BX DI D16]CLCX001010[BP SI][BP SI D8][BP SI D16]DLDX010011[BP DI][BP DI D8][BP DI D16]BLBX011100[SI][SI D8][SI D16]AHSP100101[DI][DI D8][DI D16]CHBP101110[D16][BP D8][BP D16]DHSI110111[BX][BX D8][BX D16]BHDI111 8086/8088指令最多可以有兩個(gè)操作數(shù)。在“mod reg r/m”字節(jié)中,reg字段表示一個(gè)采用寄存器尋址的操作數(shù),reg占用3位,不同編碼指示8個(gè)8位(w=0)或16位(w=1)通用寄存器之一; mod和r/m字段表示另一個(gè)操作數(shù)的尋址方式,分別占用2位或3位。(1) mod =00時(shí)為無(wú)位移量的存儲(chǔ)器尋址方式。但其中,當(dāng)r/m =110時(shí)為直接尋址方式,此時(shí)該字節(jié)后跟16位有效地址D16。(2) mod =01時(shí)為帶有8位位移量的存儲(chǔ)器尋址方式。此時(shí)該字節(jié)后跟一個(gè)字節(jié),表示8位位移量D8,它是一個(gè)有符號(hào)數(shù)。(3) mod =10時(shí)為帶有16位位移量的存儲(chǔ)器尋址方式。此時(shí)該字節(jié)后跟兩個(gè)字節(jié),表示16位位移量D16,它也是一個(gè)有符號(hào)數(shù)。(4) mod =11時(shí)為寄存器尋址方式,由r/m指定寄存器,此時(shí)的編碼與reg相同。3.1.3與數(shù)據(jù)有關(guān)的尋址方式指令中關(guān)于如何求出存放操作數(shù)有效地址的方法稱(chēng)為操作數(shù)的尋址方式。計(jì)算機(jī)按照指令給出的尋址方式求出操作數(shù)有效地址和存取操作數(shù)的過(guò)程,稱(chēng)為尋址操作。在微機(jī)中,尋址方式可能有如下3種情況。(1) 操作數(shù)包含在指令中,稱(chēng)為立即尋址。(2) 操作數(shù)包含在CPU的內(nèi)部寄存器中,稱(chēng)為寄存器尋址。(3) 操作數(shù)在內(nèi)存的數(shù)據(jù)區(qū)中,這時(shí)指令中的操作數(shù)字段包含著此操作數(shù)的地址,稱(chēng)為存儲(chǔ)器尋址。為了更清楚地掌握尋址方式,下面以最常用的MOV指令來(lái)舉例說(shuō)明各種尋址方式的功能。MOV指令是一個(gè)數(shù)據(jù)傳送指令,相當(dāng)于高級(jí)語(yǔ)言的賦值語(yǔ)句,其格式為: MOVOPRD1,OPRD2 MOV指令的功能是將源操作數(shù)OPRD2傳送至目的操作數(shù)OPRD1。在講述中,假設(shè)目的操作數(shù)采用寄存器尋址方式,用源操作數(shù)來(lái)反映各種尋址方式的功能和彼此的區(qū)別。1. 立即數(shù)尋址方式立即數(shù)尋址方式所提供的操作數(shù)緊跟在操作碼的后面,與操作碼一起放在指令代碼段中。立即數(shù)可以是8位數(shù)或16位數(shù)。如果是16位數(shù),則低位字節(jié)存放在低地址中,高位字節(jié)存放在高地址中。立即數(shù)尋址方式只能用于源操作數(shù)字段,不能用于目的操作數(shù)字段,經(jīng)常用于給寄存器賦初值!纠3.1】將8位立即數(shù)18存入寄存器AL中。 MOVAL,18 指令執(zhí)行后,(AL)= 12H 圖3.2立即數(shù)尋址方式示意圖 【例3.2】將16位立即數(shù)8090H存入寄存器AX中。 MOVAX,8090H 圖3.2給出了立即數(shù)尋址方式示意圖。指令執(zhí)行后的結(jié)果為: (AX)= 8090H。2. 寄存器尋址方式在寄存器尋址方式中,操作數(shù)包含于CPU的內(nèi)部寄存器之中。這種尋址方式大都用于寄存器之間的數(shù)據(jù)傳輸。對(duì)于16位操作數(shù),寄存器可以是AX、BX、CX、DX、SI、DI、SP和BP等; 對(duì)于8位操作數(shù),寄存器可以是AL、AH、BL、BH、CL、CH、DL和DH。這種尋址方式可以取得較高的運(yùn)算速度。下列指令都屬于寄存器尋址方式: MOVDS,AX MOVAL,CL MOVSI,AX MOVBL,AH 【例3.3】寄存器尋址方式的指令操作過(guò)程如下。 MOVAX,BX 如果指令執(zhí)行前(AX)= 6688H,(BX)= 1020H; 則指令執(zhí)行后,(AX)= 1020H,(BX)保持不變,圖3.3給出了寄存器尋址方式示意圖。3. 存儲(chǔ)器尋址方式 圖3.3寄存器尋址方式示意圖 寄存器尋址雖然速度較快,但CPU中寄存器數(shù)目有限,不可能把所有參與運(yùn)算的數(shù)據(jù)都存放在寄存器中。多數(shù)情況下,操作數(shù)還是要存儲(chǔ)在主存中。如何尋址主存中存儲(chǔ)的操作數(shù)稱(chēng)為存儲(chǔ)器尋址方式,也稱(chēng)為主存尋址方式。在這種尋址方式下,指令中給出的是有關(guān)操作數(shù)的主存地址信息。由于8086/8088的存儲(chǔ)器是分段管理的,因此這里給出的地址只是偏移地址(即有效地址EA),而段地址在默認(rèn)的或用段超越前綴指定的段寄存器中。為了方便各種數(shù)據(jù)結(jié)構(gòu)的存取,8086/8088設(shè)計(jì)了多種主存尋址方式。1) 直接尋址方式直接尋址方式是操作數(shù)地址的16位偏移量直接包含在指令中,和指令操作碼一起放在代碼段,而操作數(shù)則在數(shù)據(jù)段中。操作數(shù)的地址是數(shù)據(jù)段寄存器DS中的內(nèi)容左移4位后,加上指令給定的16位地址偏移量。把操作數(shù)的偏移地址稱(chēng)為有效地址EA,則物理地址=16D×(DS) EA。如果數(shù)據(jù)存放在數(shù)據(jù)段以外的其他段中,則在計(jì)算物理地址時(shí)應(yīng)使用指定的段寄存器。直接尋址方式適合于處理單個(gè)數(shù)據(jù)變量。【例3.4】直接尋址方式示例如下。 MOVAX,[400H] 如果(DS)= 1000H,則物理地址的計(jì)算式為: 圖3.4直接尋址方式示意圖 10000H(段基地址) 400H(偏移地址)= 10400H(物理地址)圖3.4給出了直接尋址方式示意圖。指令執(zhí)行后的結(jié)果為: (AX)= 1A2BH。也可以用符號(hào)地址代替數(shù)值地址,例如: MOVAX,BUFFER 此時(shí)BUFFER為存放數(shù)據(jù)單元的符號(hào)地址。它等效于如下形式: MOVAX,[BUFFER] 2) 寄存器間接尋址方式在寄存器間接尋址方式中,操作數(shù)在存儲(chǔ)器中。操作數(shù)的有效地址由變址寄存器SI、DI或基址寄存器BX、BP提供。這又分成兩種情況: 如果指令中指定的寄存器是BX、SI、DI,則用DS寄存器的內(nèi)容作為段地址,即操作數(shù)的物理地址為: 物理地址 = 10H ×(DS) (BX、SI或DI) 如指令中用BP寄存器,則操作數(shù)的段地址在SS中,即堆棧段,所以操作數(shù)的物理地址為: 物理地址 = 10H ×(SS) (BP) 【例3.5】寄存器間接尋址方式示例如下。 MOVAX,[SI] 圖3.5寄存器間接尋址方式示意圖 如果(DS)=2000H,(SI)=1500H,則物理地址的計(jì)算式為: 20000H(段基地址) 1500H(偏移地址) =21500H(物理地址) 圖3.5給出了寄存器間接尋址方式示意圖。指令執(zhí)行后的結(jié)果為: (AX)= C5D6H。3) 寄存器相對(duì)尋址方式該尋址方式是以指定的寄存器內(nèi)容,加上指令中給出的位移量(8位或16位),并以一個(gè)段寄存器為基準(zhǔn),作為操作數(shù)的地址。指定的寄存器一般是一個(gè)基址寄存器或變址寄存器。即: EA= (BX)(BP)(SI)(DI) 8位 16位位移量與寄存器間接尋址方式類(lèi)似,對(duì)于寄存器為BX、SI、DI的情況,段寄存器用DS,則物理地址為: 物理地址 = 10H ×(DS) (BX、SI或DI) 8位(或16位)位移量 當(dāng)寄存器為BP時(shí),則使用SS段寄存器的內(nèi)容作為段地址,此時(shí)物理地址為: 物理地址 = 10H ×(SS) (BP) 8位(或16位)位移量 【例3.6】寄存器相對(duì)尋址方式示例如下。 MOVAX,DISP[DI] 也可表示為 MOVAX,[DISP DI] 其中DISP為16位位移量的符號(hào)地址。如果(DS)= 3000H,(DI)= 2000H,DISP = 600H,則物理地址的計(jì)算式為: 30000H(段基地址) 2000H(變址) 600H(位移量) =32600H(物理地址) 圖3.6給出了寄存器相對(duì)尋址方式示意圖,指令執(zhí)行后的結(jié)果是: (AX)= 005AH。 圖3.6寄存器相對(duì)尋址方式示意圖 4) 基址加變址尋址方式在基址加變址尋址方式中,通常把BX和BP看作是基址寄存器,把SI和DI看作變址寄存器,可把兩種方式組合起來(lái)形成一種新的尋址方式;芳幼冎返膶ぶ贩绞绞前岩粋(gè)基址寄存器BX或BP的內(nèi)容,加上變址寄存器SI或DI的內(nèi)容,并以一個(gè)段寄存器作為地址基準(zhǔn),作為操作數(shù)的地址。兩個(gè)寄存器均由指令指定。當(dāng)基址寄存器為BX時(shí),段寄存器使用DS,則物理地址為: 物理地址 = 10H ×(DS) (BX) (SI或DI) 當(dāng)基址寄存器為BP時(shí),段寄存器用SS,此時(shí)物理地址為: 物理地址 = 10H ×(SS) (BP) (SI或DI) 【例3.7】基址加變址尋址方式示例如下。 MOVAX,[BX][DI] 或?qū)憺椋?nbsp; MOVAX,[BX DI] 如果(DS)= 1000H,(BX)= 2000H,(DI)= 3000H,則物理地址的計(jì)算式為: 10000H(段基地址) 2000H(基址) 3000H(變址) = 15000H(物理地址) 圖3.7給出了基址加變址尋址方式示意圖。指令執(zhí)行后的結(jié)果為: (AX)= 1288H。 圖3.7基址加變址尋址方式示意圖 5) 相對(duì)基址變址尋址方式在相對(duì)基址變址尋址方式中,通常把BX和BP看作是基址寄存器,把SI和DI看作變址寄存器。它是把一個(gè)基址寄存器BX或BP的內(nèi)容,加上變址寄存器SI或DI的內(nèi)容,再加上指令中給定的8位或16位位移量,并以一個(gè)段寄存器為地址基準(zhǔn),作為操作數(shù)的地址。同樣,當(dāng)基址寄存器為BX時(shí),段寄存器使用DS,則物理地址為: 物理地址 = 10H ×(DS) (BX) (SI或DI) 8位(或16位)位移量 當(dāng)基址寄存器為BP時(shí),段寄存器則用SS。此時(shí)物理地址為: 物理地址 = 10H ×(SS) (BP) (SI或DI) 8位(或16位)位移量 【例3.8】相對(duì)基址變址尋址方式示例如下。 MOVAX,DISP[BX][SI] 如果(DS)= 4000H,(BX)= 2000H,(SI)= 1000H,DISP = 800H,則物理地址的計(jì)算式為: EA =2000H(基址) 1000H(變址) 800H(位移量)=3800H 40000H(段基地址) 3800H(EA)= 43800H(物理地址) 圖3.8相對(duì)基址變址尋址方式示意圖 圖3.8給出了相對(duì)基址變址尋址方式示意圖。指令執(zhí)行后的結(jié)果為: (AX)= EEFFH。3.1.4與轉(zhuǎn)移地址有關(guān)的尋址方式微機(jī)指令系統(tǒng)中有轉(zhuǎn)移指令及子程序調(diào)用等非順序執(zhí)行指令。這類(lèi)指令所指出的地址是程序轉(zhuǎn)移到的指定的轉(zhuǎn)移地址,然后再依次順序執(zhí)行程序。這種提供轉(zhuǎn)移地址的方法稱(chēng)為程序轉(zhuǎn)移地址的尋址方式。它分為段內(nèi)直接尋址、段內(nèi)間接尋址、段間直接尋址和段間間接尋址4種情況。在8086/8088指令系統(tǒng)中,條件轉(zhuǎn)移指令只能使用段內(nèi)直接尋址方式,且位移量為8位; 而非條件轉(zhuǎn)移指令和子程序調(diào)用指令則可用4種尋址方式中的任何一種。1. 段內(nèi)直接尋址這種尋址方式是將當(dāng)前IP寄存器的內(nèi)容和指令中指定的8位或16位位移量之和作為轉(zhuǎn)向的有效地址。一般用相對(duì)于當(dāng)前IP值的位移量來(lái)表示轉(zhuǎn)向有效地址,所以它是一種相對(duì)尋址方式。當(dāng)這一程序段在內(nèi)存中的不同區(qū)域運(yùn)行時(shí),轉(zhuǎn)移指令本身不會(huì)發(fā)生變化,這是符合程序的再定位要求的。這種尋址方式適用于條件轉(zhuǎn)移及無(wú)條件轉(zhuǎn)移指令,但是當(dāng)它用于條件轉(zhuǎn)移指令時(shí),位移量只允許8位。指令格式: JMPNEAR PTR ADDR1 JMPSHORT ADDR2 其中,ADDR1和ADDR2都是轉(zhuǎn)向的符號(hào)地址,在機(jī)器指令中,用位移量來(lái)表示。2. 段內(nèi)間接尋址段內(nèi)間接尋址的轉(zhuǎn)向有效地址是一個(gè)寄存器或一個(gè)存儲(chǔ)單元的內(nèi)容,并且可以用數(shù)據(jù)尋址方式中除立即數(shù)以外的任何一種尋址方式取得轉(zhuǎn)向的有效地址。指令格式: JMPBX JMPWORD PTR [BP DISP] 其中,WORD PTR為操作符,用以指出其后的尋址方式所取得的轉(zhuǎn)向地址是一個(gè)字的有效地址,也就是說(shuō)它是一種段內(nèi)轉(zhuǎn)移。對(duì)于段內(nèi)轉(zhuǎn)移尋址方式,直接把求得的轉(zhuǎn)移的有效地址送到IP寄存器就可以了。如果需要計(jì)算轉(zhuǎn)移的物理地址,則應(yīng)是: 物理地址 = 10H ×(CS) EA 其中,EA為轉(zhuǎn)移的有效地址。下面的兩個(gè)例子說(shuō)明了在段內(nèi)間接尋址方式的轉(zhuǎn)移指令中有效地址的計(jì)算方法。假設(shè): (DS)= 2000H,(BX)= 2000H,(SI)=3000H,(25000H)=3200H!纠3.9】指令如下。 JMPBX 則執(zhí)行指令后 (IP)=2000H 【例3.10】指令如下。 JMP[BX][SI] 則執(zhí)行指令后 (IP)=(10H×(DS) (BX) (SI)) =(20000H 2000H 3000H) =(25000H) = 3200H 3. 段間直接尋址這種尋址方式直接提供轉(zhuǎn)向的段地址(16位)和偏移地址(16位),所以需要32位的地址信息。只要用指令中指定的偏移地址取代IP寄存器的內(nèi)容,用指定的段地址取代CS寄存器的內(nèi)容就完成了從一個(gè)段到另一個(gè)段的轉(zhuǎn)移操作。指令格式可表示為: JMPFAR PTR ANOSEG 其中,ANOSEG為轉(zhuǎn)向的符號(hào)地址,F(xiàn)AR PTR則是表示段間轉(zhuǎn)移的操作符。4. 段間間接尋址為了達(dá)到段間轉(zhuǎn)移,這種尋址方式是用存儲(chǔ)器中的兩個(gè)相繼字的內(nèi)容來(lái)取代IP和CS。內(nèi)存單元的地址是由指令指定的除立即尋址和寄存器尋址方式以外的任何一種數(shù)據(jù)尋址方式取得。指令格式可表示為: JMPDWORD PTR [DISP BX] 其中,[DISP BX]說(shuō)明數(shù)據(jù)尋址方式為寄存器間接尋址方式,DWORD PTR為雙字操作符,以滿(mǎn)足段間轉(zhuǎn)移地址的要求。3.28086/8088指令系統(tǒng)計(jì)算機(jī)的指令系統(tǒng)就是指該計(jì)算機(jī)能夠執(zhí)行的全部指令的集合。8086/8088指令系統(tǒng)的指令分為7類(lèi),即數(shù)據(jù)傳送類(lèi)、算術(shù)運(yùn)算類(lèi)、邏輯操作類(lèi)、程序控制類(lèi)、數(shù)據(jù)串操作類(lèi)、處理器控制類(lèi)以及輸入/輸出類(lèi)指令。在學(xué)習(xí)指令系統(tǒng)過(guò)程中,以下幾個(gè)方面是需要注意的。(1) 掌握指令的功能: 該指令能夠?qū)崿F(xiàn)何種操作,通常指令助記符就是指令功能的英文單詞或其縮寫(xiě)形式。(2) 分析指令支持的尋址方式: 該指令中的操作數(shù)可以采用何種尋址方式。(3) 清楚指令對(duì)標(biāo)志位的影響: 該指令執(zhí)行后是否對(duì)各個(gè)標(biāo)志位有影響,以及如何影響。(4) 其他特征: 如指令執(zhí)行時(shí)的約定設(shè)置、必須預(yù)置的參數(shù)、隱含使用的寄存器等。3.2.1數(shù)據(jù)傳送類(lèi)指令數(shù)據(jù)傳送是計(jì)算機(jī)中最基本、最重要的一種操作。傳送指令也是最常使用的一類(lèi)指令,可以實(shí)現(xiàn)數(shù)據(jù)從一個(gè)位置到另一個(gè)位置的移動(dòng),如執(zhí)行寄存器與寄存器之間、寄存器與主存單元之間的字或字節(jié)的多種傳送操作。1. 數(shù)據(jù)傳送指令指令格式: MOVOPRD1,OPRD2 OPRD1為目的操作數(shù),可以是寄存器、存儲(chǔ)器、累加器。OPRD2為源操作數(shù),可以是寄存器、存儲(chǔ)器、累加器和立即數(shù)。本指令的功能是將一個(gè)8位或16位的源操作數(shù)(字或字節(jié))送到目的操作數(shù)中,即OPRD1←OPRD2,本指令不影響狀態(tài)標(biāo)志位。MOV指令可以分為以下4種情況。1) 寄存器與寄存器之間的數(shù)據(jù)傳送指令例如: MOVAX,BX MOVCL,AL MOVDX,ES MOVDS,AX MOVBP,SI 代碼段寄存器CS及指令指針I(yè)P不參加數(shù)的傳送,其中CS可以作為源操作數(shù)參加傳送,但不能作為目的操作數(shù)參加傳送。2) 立即數(shù)到通用寄存器的數(shù)據(jù)傳送指令立即數(shù)只能作為源操作數(shù)使用,不能作目的操作數(shù)使用。例如: MOVAL,25H MOVBX,20A0H MOVCH,5 MOVSP,2F00H 注意: 由于傳送的數(shù)據(jù)可能是字節(jié),也可能是字,源操作數(shù)與目的操作數(shù)的類(lèi)型應(yīng)一致,8位寄存器不能和16位寄存器之間傳送數(shù)據(jù)。例如,25H送AL是允許的,2000H送AL是不允許的。在立即數(shù)參加傳送的情況下,數(shù)據(jù)類(lèi)型由寄存器確定。當(dāng)立即數(shù)送至存儲(chǔ)器時(shí),不僅其類(lèi)型應(yīng)該一致,而且還應(yīng)當(dāng)用匯編語(yǔ)言的指示性語(yǔ)句或匯編運(yùn)算符加以說(shuō)明。3) 寄存器與存儲(chǔ)器之間的數(shù)據(jù)傳送指令例如: MOVAL,BUF MOVAX,[SI] MOVDISP[BX DI],DL MOVSI,ES: [BP] MOVDS,DATA[BX SI] MOVDISP[BX DI],ES 第一條指令是將存儲(chǔ)器變量BUF的值送至AL寄存器。BUF可以看成是存儲(chǔ)數(shù)據(jù)的單元的符號(hào)名,實(shí)際上是符號(hào)地址,因?yàn)樵摰刂穯卧械臄?shù)據(jù)是可變的,用BUF作為變量名是很合適的。如果是對(duì)字進(jìn)行操作,應(yīng)將指令改寫(xiě)成如下的形式: MOVAX,BUF 這時(shí)匯編語(yǔ)言中在定義BUF變量時(shí),要用DW偽指令將其定義為字類(lèi)型變量,即在數(shù)據(jù)段中,用如下形式定義: BUFDW1234H 這樣,就可以使用“MOVAX,BUF”指令進(jìn)行數(shù)據(jù)字的傳送操作。該指令將從地址BUF開(kāi)始的兩個(gè)存儲(chǔ)單元的數(shù)據(jù)送至AX中,即(AX)= 1234H。在數(shù)據(jù)段中,如果用偽指令DB將BUF變量定義為字節(jié)類(lèi)型,但仍要對(duì)從BUF開(kāi)始的單元進(jìn)行數(shù)據(jù)字的傳送,則應(yīng)將指令寫(xiě)成如下形式: MOVAX,WORD PTR BUF 其中PTR稱(chēng)為指針操作符。其作用是將BUF定義為新的變量類(lèi)型。這個(gè)變量的起始地址沒(méi)有改變,但已將BUF變量定義為字類(lèi)型,因而指令能將一個(gè)數(shù)據(jù)字送至AX中,F(xiàn)在再來(lái)看第二條指令“MOVAX,[SI]”,其中[SI]屬于寄存器間接尋址,即由段寄存器DS與SI一起確定源操作數(shù)的物理地址。因?yàn)槭菙?shù)據(jù)字傳送,所以該操作數(shù)與求出的物理地址指向的兩個(gè)連續(xù)存儲(chǔ)單元有關(guān)。 在指令“MOVDISP[BX DI],DL”中,目的操作數(shù)是存儲(chǔ)器操作數(shù),尋址方式是相對(duì)基址變址尋址,也可把它寫(xiě)作DISP[BX][DI]。匯編語(yǔ)言將對(duì)它們進(jìn)行相同的處理,即有效地址EA = (BX) (DI) DISP。指令“MOVSI,ES: [BP]”有些特殊,源操作數(shù)是存儲(chǔ)器操作數(shù),其尋址方式是寄存器間接尋址。但沒(méi)有按照事先的約定,BP與SS段寄存器結(jié)合,找到實(shí)際的物理地址。而用“ES: [BP]”告訴匯編程序: BP將與段寄存器ES結(jié)合,即EA =(BP)。與上述指令類(lèi)似,指令“MOVDS,DATA[BX SI]”中的源操作數(shù)是存儲(chǔ)器操作數(shù),采用相對(duì)基址變址方式尋址,有效地址EA =(BX) (SI) DATA!癕OVDISP[BX DI],ES”中的目的操作數(shù)是存儲(chǔ)器操作數(shù),也是相對(duì)基址變址尋址,其有效地址為EA =(BX) (DI) DISP。由此可見(jiàn),只有深刻理解指令中各操作數(shù)的尋址方式,才能正確理解指令的真正含義。同樣要注意,寄存器IP不能參加數(shù)據(jù)傳送,CS寄存器不能作為目的操作數(shù)參與數(shù)據(jù)傳送。4) 立即數(shù)到存儲(chǔ)器的數(shù)據(jù)傳送立即數(shù)只能作為源操作數(shù),且一定要使立即數(shù)與存儲(chǔ)器變量類(lèi)型一致。存儲(chǔ)器變量的類(lèi)型可以在數(shù)據(jù)定義時(shí)指定,也可以在指令中另行指定,應(yīng)保證其與立即數(shù)的類(lèi)型一致。否則,匯編程序在匯編時(shí),將指出類(lèi)型不一致的錯(cuò)誤。例如: MOVBUF,25 MOVDS: DISP[BP],1234H MOVBYTE PTR [SI],40 以上指令如能正確執(zhí)行,則BUF變量應(yīng)定義為字節(jié)類(lèi)型,DISP[BP]所指的存儲(chǔ)單元應(yīng)定義為字類(lèi)型。第三條指令中,用指針操作符PTR重新把[SI]所指的單元定義為字節(jié)類(lèi)型。在編寫(xiě)匯編語(yǔ)言程序時(shí),用BYTR PTR[SI]能告訴匯編程序,此處按字節(jié)類(lèi)型處理,生成相應(yīng)的指令代碼。使用MOV指令傳送數(shù)據(jù),必須注意以下幾點(diǎn)。(1) 立即數(shù)只能作為源操作數(shù),不允許作目的操作數(shù),立即數(shù)也不能送至段寄存器。(2) 通用寄存器可以與段寄存器、存儲(chǔ)器互相傳送數(shù)據(jù),寄存器之間也可以互相傳送數(shù)據(jù)。但是CS不能作為目的操作數(shù)。(3) 存儲(chǔ)器與存儲(chǔ)器之間不能進(jìn)行數(shù)據(jù)直接傳送。若要實(shí)現(xiàn)存儲(chǔ)單元之間的數(shù)據(jù)傳送,可以借助于通用寄存器作為中介來(lái)進(jìn)行。【例3.11】要把DATA1單元的內(nèi)容送至DATA2單元中,并假定這兩個(gè)單元在同一個(gè)數(shù)據(jù)段中,可以通過(guò)以下兩條指令實(shí)現(xiàn): MOVAL,DATA1 MOVDATA2,AL 2. 數(shù)據(jù)交換指令數(shù)據(jù)傳送指令單方向地將源操作數(shù)送至目的操作數(shù)存儲(chǔ)單元,而數(shù)據(jù)交換指令則將兩個(gè)操作數(shù)相互交換位置,例如: XCHGOPRD1,OPRD2 指令中的OPRD1為目的操作數(shù),OPRD2為源操作數(shù),該指令把源操作數(shù)OPRD2與目的操作數(shù)OPRD1交換。OPRD1及OPRD2可為通用寄存器或存儲(chǔ)器。 圖3.9XCHG指令操作示意圖 XCHG指令不支持兩個(gè)存儲(chǔ)器單元之間的數(shù)據(jù)交換,但通過(guò)中間寄存器,可以很容易地實(shí)現(xiàn)兩個(gè)存儲(chǔ)器操作數(shù)的交換。交換操作的示意圖如圖3.9所示。本指令不影響狀態(tài)標(biāo)志位,段寄存器內(nèi)容不能用XCHG指令來(lái)交換。以下指令是合法的。 XCHGAX,BX XCHGSI,AX XCHGDL,DH XCHGDX,BUF XCHGWBUF,CX 3. 換碼指令指令格式: XLATTABLE XLAT 以上兩種格式是完全等效的。本指令的功能是把待查表格的一個(gè)字節(jié)內(nèi)容送到AL累加器中。其中TABLE為一待查表格的首地址,在執(zhí)行該指令前,應(yīng)將TABLE先送至BX寄存器中,然后將待查字節(jié)與在表格中距表首地址位移量送AL,即: (AL)←((BX) (AL)) 換碼指令常用于將一種代碼轉(zhuǎn)換為另一種代碼,如掃描碼轉(zhuǎn)換為ASCII碼,數(shù)字0~9轉(zhuǎn)換為七段顯示碼等。使用前首先在主存中建立一個(gè)字節(jié)表格,表格的內(nèi)容是要轉(zhuǎn)換成的目標(biāo)代碼。由于A(yíng)L的內(nèi)容實(shí)際上是距離表格首地址的位移量,只有8位,所以表格的最大長(zhǎng)度為256。超過(guò)256的表格需要采用修改BX和AL的方法才能轉(zhuǎn)換。本指令不影響狀態(tài)標(biāo)志位。XLAT指令中沒(méi)有顯式指明操作數(shù),而是默認(rèn)使用BX和AL寄存器。這種采用默認(rèn)操作數(shù)的方法稱(chēng)為隱含尋址方式,指令系統(tǒng)中有許多指令采用隱含尋址方式!纠3.12】將首地址為200H的表格緩沖區(qū)中的4號(hào)數(shù)據(jù)取出。 MOVBX,200H MOVAL,4 XLAT 4. 堆棧操作指令堆棧被定義為一種先進(jìn)后出的數(shù)據(jù)結(jié)構(gòu),即最后進(jìn)棧的元素將被最先彈出來(lái)。堆棧從一個(gè)稱(chēng)為棧底的位置開(kāi)始,數(shù)據(jù)進(jìn)入堆棧的操作稱(chēng)為入棧(或壓棧),數(shù)據(jù)退出堆棧的操作稱(chēng)為出棧,每進(jìn)行一次出棧操作,堆棧就減少一個(gè)元素,最后一次入棧的元素,稱(chēng)為棧頂元素,入棧操作和出棧操作都是對(duì)棧頂元素進(jìn)行的基本操作。在計(jì)算機(jī)中,堆棧設(shè)置在一個(gè)存儲(chǔ)區(qū)域中。8086/8088的堆棧段的開(kāi)始位置由(SS)×10H 0000H決定,堆棧段最大為64KB。SP稱(chēng)為堆棧指針,確切地講是指向棧頂元素的地址指針,由SP的值就可以知道棧頂元素的位置。1) 入棧操作指令實(shí)現(xiàn)入棧操作的指令是PUSH指令,其格式為: PUSHOPRD 其中,OPRD為16位(字)操作數(shù),可以是寄存器或存儲(chǔ)器操作數(shù)。PUSH的操作過(guò)程是: (SP)←(SP)-2,((SP))←OPRD 即先修改堆棧指針SP(入棧時(shí)為自動(dòng)減2),然后,將指定的操作數(shù)送入新的棧頂位置。此處的((SP))←OPRD,也可以理解為: [(SS)×10H (SP)]←OPRD 或 [SS: SP]←OPRD 例如: PUSHAX PUSHBX 每條指令的操作過(guò)程分兩步,首先將SP-1→SP,把AH的內(nèi)容送至由SP所指的單元。接下來(lái)再使SP-1→SP,把AL的內(nèi)容送到SP所指的單元。隨著入棧內(nèi)容的增加,堆棧就擴(kuò)展,SP值減少,但每次操作完,SP總是指向堆棧的頂部。圖3.10(a)給出了入棧操作的情況。以下入棧操作指令都是有效的。 PUSHDX PUSHSI PUSHBP PUSHCS PUSHBUFFER PUSHDAT[BX][SI] 注意: 每進(jìn)行一次入棧操作,都?jí)喝胍粋(gè)字(16位),例中的BUFFER,DAT[BX][SI]所指的存儲(chǔ)器操作數(shù)應(yīng)該被指定為字類(lèi)型。2) 出棧操作指令實(shí)現(xiàn)出棧操作的指令是POP指令,其格式為: POPOPRD 其中,OPRD為16位(字)操作數(shù),可以是寄存器或存儲(chǔ)器操作數(shù)。POP指令的操作過(guò)程是: OPRD←((SP)),(SP)←(SP) 2 它與入棧操作相反,是先彈出棧頂?shù)臄?shù)據(jù),然后再修改指針SP的內(nèi)容(自動(dòng)加2)。例如: POPBX POPAX 圖3.10(b)給出了出棧操作的情況。 圖3.10入棧和出棧操作 以下出棧操作指令都是有效的。 POPAX POPDS POPBUFFER POPDAT[BX][DI] 其中的BUFFER及DAT[BX][DI]所指的存儲(chǔ)器操作數(shù)也應(yīng)被指定為字類(lèi)型。PUSH及POP指令對(duì)標(biāo)志位沒(méi)有影響。 【例3.13】用堆棧操作指令實(shí)現(xiàn)兩個(gè)存儲(chǔ)器操作數(shù)BUF1及BUF2的交換。 PUSHBUF1 PUSHBUF2 POPBUF1 POPBUF2 5. 標(biāo)志傳送指令1) 取FLAGS標(biāo)志寄存器低8位至AH指令指令格式: LAHF 指令含義為: (AH)←(FLAGS)7~0 該指令不影響FLAGS的原來(lái)內(nèi)容,AH只是復(fù)制了原FLAGS的低8位內(nèi)容。2) 將AH存至FLAGS低8位指令指令格式: SAHF 指令含義為: (FLAGS)7~0←(AH) 本指令將用AH的內(nèi)容改寫(xiě)FLAGS中的SF、ZF、AF、PF和CF標(biāo)志,從而改變?cè)瓉?lái)的標(biāo)志位。3) 將FLAGS內(nèi)容入棧指令指令格式: PUSHF 本指令可以把FLAGS的內(nèi)容保存到堆棧中去。4) 從堆棧中彈出一個(gè)數(shù)據(jù)字送至FLAGS中的指令指令格式: POPF 本指令的功能與PUSHF相反,在子程序調(diào)用和中斷服務(wù)程序中,往往用PUSHF指令保護(hù)FLAGS的內(nèi)容,用POPF指令將保護(hù)的FLAGS內(nèi)容恢復(fù)。6. 地址傳送指令地址傳送指令將存儲(chǔ)器的邏輯地址送至指定的寄存器。1) 有效地址傳送指令指令格式: LEAOPRD1,OPRD2 指令中的OPRD1為目的操作數(shù),可為任意一個(gè)16位的通用寄存器。OPRD2為源操作數(shù),可為變量名、標(biāo)號(hào)或地址表達(dá)式。本指令的功能是將源操作數(shù)給出的有效地址傳送到指定的寄存器中。本指令對(duì)標(biāo)志位無(wú)影響。例如: LEABX,DATA1 LEADX,BETA[BX SI] LEABX,[BP][DI] 顯然,LEA BX,DATA1的功能是將變量DATA1的地址送至BX,而不是將變量DATA1的值送BX。如果要將一個(gè)存儲(chǔ)器變量的地址取至某一個(gè)寄存器中,也可以用OFFSET DATA1表達(dá)式實(shí)現(xiàn)。例如MOV SI,OFFSET DATA1指令,其功能是將存儲(chǔ)器變量DATA1的段內(nèi)偏移地址取至SI寄存器中,OFFSET DATA1表達(dá)式的值就是取DATA1的段內(nèi)偏移地址值。因此,LEA BX,DATA1指令與MOV BX,OFFSET DATA1指令的功能是等價(jià)的。 圖3.11LDS指令操作示意圖 2) 從存儲(chǔ)器取出32位地址的指令指令格式: LDSOPRD1,OPRD2 LESOPRD1,OPRD2 其中,OPRD1為任意一個(gè)16位的寄存器,OPRD2指定了主存的連續(xù)4字節(jié)作為邏輯地址,即32位的地址指針。例如: LDSDI,[BX] 該指令的功能是把BX所指的32位地址指針的段地址送入DS,偏移地址送入DI。指令操作示意圖如圖3.11所示!癓ES DI,[BX]”指令除將地址指針的段地址送入ES外,其他與LDS類(lèi)似。因此圖3.11不僅適用于LDS指令,也適用于LES指令。以下指令是合法的。 LDSSI,ABCD LDSBX,F(xiàn)AST[SI] LESSI,ABCD LESBX,F(xiàn)AST[SI] 注意: 以上指令不影響標(biāo)志位。3.2.2算術(shù)運(yùn)算類(lèi)指令算術(shù)運(yùn)算類(lèi)指令用來(lái)執(zhí)行二進(jìn)制及十進(jìn)制的算術(shù)運(yùn)算,主要包括加、減、乘、除指令。二進(jìn)制數(shù)運(yùn)算分為帶符號(hào)數(shù)運(yùn)算和不帶符號(hào)數(shù)運(yùn)算。帶符號(hào)數(shù)的最高位是符號(hào)位,不帶符號(hào)數(shù)所有位都是有效位。十進(jìn)制數(shù)用BCD碼表示,又分為非壓縮的BCD碼和壓縮的BCD碼兩種形式。算術(shù)運(yùn)算指令會(huì)根據(jù)運(yùn)算結(jié)果影響狀態(tài)標(biāo)志,有時(shí)要利用某些標(biāo)志才能得到正確的結(jié)果。該類(lèi)指令主要影響6個(gè)標(biāo)志位,即CF、AF、SF、ZF、PF和OF。1. 加法指令加法指令能實(shí)現(xiàn)字或字節(jié)的加法運(yùn)算。1) 基本加法指令指令格式: ADDOPRD1,OPRD2 指令含義為: OPRD1 ← OPRD1 OPRD2 OPRD1為目的操作數(shù),可以是任意一個(gè)通用寄存器,也可以是任意一個(gè)存儲(chǔ)器操作數(shù)。在A(yíng)DD指令執(zhí)行前,OPRD1的內(nèi)容為一個(gè)加數(shù),待ADD指令執(zhí)行后,OPRD1中為加法運(yùn)算的結(jié)果,即和。這給程序的編寫(xiě)帶來(lái)了很大的方便。OPRD2為源操作數(shù),它可以是立即數(shù),也可以是任意一個(gè)通用寄存器或存儲(chǔ)器操作數(shù)。立即數(shù)只能用于源操作數(shù)。OPRD1和OPRD2均為寄存器是允許的,一個(gè)為寄存器而另一個(gè)為存儲(chǔ)器也是允許的,但不允許兩個(gè)都是存儲(chǔ)器操作數(shù)。加法指令運(yùn)算的結(jié)果對(duì)CF、SF、OF、PF、ZF、AF都會(huì)有影響。以上標(biāo)志也稱(chēng)為結(jié)果標(biāo)志。加法指令適用于無(wú)符號(hào)數(shù)或有符號(hào)數(shù)的加法運(yùn)算。操作數(shù)可以是8位,也可以是16位。例如: ADDAL,38H ADDBX,0A0AH ADDDX,DATA[BX] ADDDI,CX ADDBETA[BX],AX ADDBYTE PTR[BX],55 上述第一條指令及第六條指令為字節(jié)相加指令,其他四條均為字(雙字節(jié))相加指令。第三條指令中,存儲(chǔ)器操作數(shù)是源操作數(shù),采用寄存器相對(duì)尋址方式; 第五條指令中,存儲(chǔ)器操作數(shù)是目的操作數(shù),采用寄存器相對(duì)尋址方式; 第六條指令中,存儲(chǔ)器操作數(shù)也是目的操作數(shù),采用寄存器間接尋址方式,當(dāng)立即數(shù)與存儲(chǔ)器操作數(shù)做加法時(shí),類(lèi)型必須一致,故此處用BYTE PTR[BX],將存儲(chǔ)器操作數(shù)的類(lèi)型重新指定為字節(jié)類(lèi)型,以保證兩個(gè)操作數(shù)類(lèi)型一致。2) 帶進(jìn)位加法指令指令格式: ADCOPRD1,OPRD2 指令含義為: OPRD1 ← OPRD1 OPRD2 CF 其中,OPRD1、OPRD2與指令A(yù)DD中的含義一樣。該指令對(duì)標(biāo)志位的影響同ADD指令。例如: ADCAL,CL ADCAX,SI ADCDX,MEMA ADCCL,15 ADCWORD PTR[BX][SI],25 本指令適用無(wú)符號(hào)數(shù)及帶符號(hào)數(shù)的8位或16位運(yùn)算!纠3.14】如果兩個(gè)32位的數(shù)據(jù)已分別放在A(yíng)DNUM1和ADNUM2開(kāi)始的存儲(chǔ)區(qū)中,存放時(shí)低字在前,高字在后,將兩個(gè)數(shù)相加,且將和存放在A(yíng)DNUM3開(kāi)始的存儲(chǔ)區(qū)中。實(shí)現(xiàn)兩個(gè)32位數(shù)相加的程序?yàn)椋?nbsp; MOVAX,ADNUM1 ADDAX,ADNUM2 MOVADNUM3,AX MOVAX,ADNUM1 2 ADCAX,ADNUM2 2 MOVADNUM3 2,AX 由于兩個(gè)存儲(chǔ)器操作數(shù)不能直接相加,因而不能通過(guò)“ADDADNUM1,ADNUM2”指令進(jìn)行。3) 加1指令指令格式: INCOPRD 指令含義為: OPRD ← OPRD 1 OPRD為寄存器或存儲(chǔ)器操作數(shù)。這條指令的功能是對(duì)給定的除段寄存器以外的任何寄存器或存儲(chǔ)單元內(nèi)容加1后,再送回該操作數(shù),可以實(shí)現(xiàn)字節(jié)加1或字加1。本指令執(zhí)行結(jié)果影響AF、OF、PF、SF、ZF標(biāo)志位,但不影響CF標(biāo)志位。例如: INCSI INCWORD PTR[BX] INCBYTE PTR[BX DI] INCCL 上述第二條、第三條這兩條指令,是對(duì)存儲(chǔ)字及存儲(chǔ)字節(jié)的內(nèi)容加1以替代原來(lái)的內(nèi)容。在循環(huán)程序中,常用該指令對(duì)地址指針和循環(huán)計(jì)數(shù)值進(jìn)行修改。2. 減法指令1) 基本減法指令指令格式: SUBOPRD1,OPRD2 本指令的功能是進(jìn)行兩個(gè)操作數(shù)的相減,即: OPRD1 ← OPRD1 - OPRD2 本指令的類(lèi)型及對(duì)標(biāo)志位的影響與ADD指令相同,注意立即數(shù)不能用于目的操作數(shù),兩個(gè)存儲(chǔ)器操作數(shù)之間不能直接相減。操作數(shù)可為8位或16位的無(wú)符號(hào)數(shù)或帶符號(hào)數(shù)。例如: SUBDX,CX SUB[BX 25],AL SUBDI,ALFA[SI] SUBCL,20 2) 帶借位減法指令指令格式: SBBOPRD1,OPRD2 其中,OPRD1、OPRD2的含義及指令對(duì)標(biāo)志位的影響等均與SUB指令相同。完成的操作為: OPRD1←OPRD1-OPRD2-CF。例如: SBBDX,CX SBBBX,2000H SBBAX,DATA1 SBBALFA[BX SI],SI 3) 減1指令指令格式: DECOPRD 其中,OPRD的含義與INC指令相同,本指令的功能是OPRD ←OPRD -1。對(duì)標(biāo)志位影響同INC指令。例如: DECAX DECCL DECWORD PTR[DI] DECALFA[DI BX] 4) 取補(bǔ)指令指令格式: NEGOPRD OPRD為任意通用寄存器或存儲(chǔ)器操作數(shù)。NEG指令也是一個(gè)單操作數(shù)指令,它對(duì)操作數(shù)執(zhí)行求補(bǔ)運(yùn)算,即用0減去操作數(shù),然后將結(jié)果返回操作數(shù)。求補(bǔ)運(yùn)算也可以表達(dá)成: 將操作數(shù)按位取反后加1。NEG指令對(duì)標(biāo)志位的影響與用0做減法的SUB指令一樣。例如: (AL)=44H,取補(bǔ)后,(AL)=0BCH(-44H)。5) 比較指令指令格式: CMPOPRD1,OPRD2 其中,OPRD1和OPRD2可為任意通用寄存器或存儲(chǔ)器操作數(shù),但兩者不同時(shí)為存儲(chǔ)器操作數(shù),立即數(shù)可用做源操作數(shù)OPRD2。本指令對(duì)標(biāo)志位的影響同SUB指令,完成的操作與SUB指令類(lèi)似,唯一的區(qū)別是不將OPRD1-OPRD2的結(jié)果送回OPRD1,而只是比較。因而不改變OPRD1和OPRD2的內(nèi)容,該指令用于改變標(biāo)志位。例如: CMPAL,56H CMPDX,CX CMPAX,DATA1[BX] CMPBATE[DI],BX 以CMPDX,CX為例,對(duì)標(biāo)志位的影響如下: (1) (DX)=(CX)時(shí),則ZF=1。(2) 兩個(gè)無(wú)符號(hào)數(shù)比較: 若(DX)>(CX),則CF=0,即無(wú)借位; 若(DX)<(CX),則CF=1,即有借位。(3) 兩個(gè)帶符號(hào)數(shù)比較: 可以通過(guò)溢出標(biāo)志OF及符號(hào)標(biāo)志SF共同來(lái)判斷兩個(gè)數(shù)的大小。當(dāng)OF=0,即無(wú)溢出時(shí),若SF=0,則(DX)>(CX); 若SF=1,則(DX)<(CX)。當(dāng)OF=1,即有溢出時(shí),若SF=1,則(DX)>(CX); 若SF=0,則(DX)<(CX)。3. 乘法指令1) 無(wú)符號(hào)數(shù)乘法指令指令格式: MULOPRD 其中,OPRD為源操作數(shù),即乘數(shù)。OPRD為通用寄存器或存儲(chǔ)器操作數(shù)。目的操作數(shù)是隱含的,即被乘數(shù)總是指定為累加器AX或AL的內(nèi)容。16位乘法時(shí),AX中為被乘數(shù); 8位乘法時(shí),AL為被乘數(shù)。16位乘法的32位乘積存于DX及AX中; 8位乘法的16位乘積存于A(yíng)X中。操作過(guò)程如下。(1) 字節(jié)相乘: (AX)←(AL)×OPRD,當(dāng)結(jié)果的高位字節(jié)(AH)≠0時(shí),則CF=1,OF=1。(2) 字相乘: (DX)(AX)←(AX)×OPRD,當(dāng)(DX)≠0時(shí),則CF=1,OF=1。例如: MULBETA[BX] MULDI MULBYTE PTR ALFA 【例3.15】設(shè)在DAT1和DAT2字單元中各有一個(gè)16位數(shù),若求其乘積并存于DAT3開(kāi)始的字單元中,可用以下指令組實(shí)現(xiàn): MOVAX,DAT1 MULDAT2 MOVDAT3,AX MOVDAT3 2,DX 2) 帶符號(hào)數(shù)乘法指令指令格式: IMULOPRD 其中,OPRD為任一通用寄存器或存儲(chǔ)器操作數(shù)。隱含操作數(shù)的定義與MUL指令相同。本指令的功能是完成兩個(gè)帶符號(hào)數(shù)的相乘。MUL和IMUL指令影響標(biāo)志位CF及OF。計(jì)算二進(jìn)制數(shù)乘法: B4H×11H。如果把它當(dāng)作無(wú)符號(hào)數(shù),用MUL指令,則乘的結(jié)果為0BF4H; 如果看作有符號(hào)數(shù),用IMUL指令,則乘的結(jié)果為FAF4H。由此可見(jiàn),同樣的二進(jìn)制數(shù)看作無(wú)符號(hào)數(shù)與有符號(hào)數(shù)相乘,即采用MUL與IMUL指令,其運(yùn)算結(jié)果是不相同的。4. 除法指令1) 無(wú)符號(hào)數(shù)除法指令指令格式: DIVOPRD 其中,OPRD為任一通用寄存器或存儲(chǔ)器操作數(shù)。本指令的功能是實(shí)現(xiàn)兩個(gè)無(wú)符號(hào)二進(jìn)制除法運(yùn)算。字節(jié)相除,被除數(shù)在A(yíng)X中; 字相除,被除數(shù)在DX、AX中,除數(shù)在OPRD中。操作過(guò)程如下。(1) 字節(jié)除法: (AL)←(AX)/OPRD,(AH)←(AX) MOD OPRD。(2) 字除法: (AX)←(DX)(AX)/OPRD,(DX)←(DX)(AX) MOD OPRD。例如: DIVBETA[BX] DIVCX DIVBL 2) 帶符號(hào)數(shù)除法指令指令格式: IDIVOPRD 其中,OPRD為任一通用寄存器或存儲(chǔ)器操作數(shù)。隱含操作數(shù)的定義與DIV指令相同。本指令的功能是實(shí)現(xiàn)兩個(gè)帶符號(hào)數(shù)的二進(jìn)制除法運(yùn)算,余數(shù)的符號(hào)與被除數(shù)符號(hào)相同。除法指令DIV和IDIV不產(chǎn)生有效的標(biāo)志位,但是卻可能產(chǎn)生溢出。當(dāng)被除數(shù)遠(yuǎn)大于除數(shù)時(shí),所得的商就有可能超出它所能表達(dá)的范圍。對(duì)DIV指令,除數(shù)為0,或者在字節(jié)除法時(shí)商大于255,字除法時(shí)商大于65535,則發(fā)生除法溢出。對(duì)IDIV指令,除數(shù)為0,或者在字節(jié)除法時(shí)商不在-128~127范圍內(nèi),或者在字除法時(shí)商不在-32768~32767范圍內(nèi),則發(fā)生除法溢出。3) 字節(jié)擴(kuò)展指令符號(hào)擴(kuò)展是指用一個(gè)操作數(shù)的符號(hào)位(即最高位)形成另一個(gè)操作數(shù),后一個(gè)操作數(shù)的各位是全0(正數(shù))或全1(負(fù)數(shù))。符號(hào)擴(kuò)展指令可用來(lái)將字節(jié)轉(zhuǎn)換為字,字轉(zhuǎn)換為雙字。有符號(hào)數(shù)通過(guò)符號(hào)擴(kuò)展加長(zhǎng)了位數(shù),但數(shù)據(jù)大小并沒(méi)有改變。符號(hào)擴(kuò)展指令不影響標(biāo)志位。指令格式: CBW 本指令的功能是將字節(jié)擴(kuò)展為字,即把AL寄存器的符號(hào)位擴(kuò)展到AH中。即兩個(gè)字節(jié)相除時(shí),先使用本指令形成一個(gè)雙字節(jié)長(zhǎng)的被除數(shù)。例如: MOVAL,34 CBW IDIVBYTE PTR DATA1 4) 字?jǐn)U展指令指令格式: CWD 本指令的功能是將字?jǐn)U展為雙字長(zhǎng),即把AX寄存器的符號(hào)位擴(kuò)展到DX中。即兩個(gè)字相除時(shí),先使用本指令形成一個(gè)雙字長(zhǎng)的被除數(shù)。符號(hào)擴(kuò)展指令常用來(lái)獲得除法指令所需要的被除數(shù)。例如AX=FF00H,它表示有符號(hào)數(shù)-256; 執(zhí)行CWD指令后,則DX=FFFFH,DX、AX仍表示有符號(hào)數(shù)-256。對(duì)無(wú)符號(hào)數(shù)除法應(yīng)該采用直接使用高8位或高16位清0的方法,獲得倍長(zhǎng)的被除數(shù)。這就是0位擴(kuò)展。【例3.16】在DAT1、DAT2、DAT3字節(jié)類(lèi)型變量中,分別存有8位帶符號(hào)數(shù)a、b、c,用程序?qū)崿F(xiàn) (a*b c)/a運(yùn)算。程序如下: MOVAL,DAT1 IMULDAT2 MOVCX,AX MOVAL,DAT3 CBW ADDAX,CX IDIVDAT1 5. 十進(jìn)制調(diào)整指令為了方便進(jìn)行十進(jìn)制的運(yùn)算,8086/8088提供了一組十進(jìn)制數(shù)調(diào)整指令。這組指令對(duì)二進(jìn)制運(yùn)算的結(jié)果進(jìn)行十進(jìn)制調(diào)整,以得到十進(jìn)制的運(yùn)算結(jié)果。十進(jìn)制數(shù)在計(jì)算機(jī)中也要用二進(jìn)制編碼表示,這就是二進(jìn)制編碼的十進(jìn)制數(shù): BCD碼。8086/8088支持壓縮BCD碼和非壓縮BCD碼,相應(yīng)地十進(jìn)制調(diào)整指令分為壓縮BCD碼的調(diào)整指令和非壓縮BCD碼的調(diào)整指令。壓縮BCD碼是通常的8421碼,它用4個(gè)二進(jìn)制位表示一個(gè)十進(jìn)制位,一個(gè)字節(jié)可以表示兩個(gè)十進(jìn)制位,即00~99。壓縮BCD碼調(diào)整指令包括加法和減法的十進(jìn)制調(diào)整指令DAA和DAS,它們用來(lái)對(duì)二進(jìn)制加、減法指令的執(zhí)行結(jié)果進(jìn)行調(diào)整,得到十進(jìn)制結(jié)果。非壓縮BCD碼用8個(gè)二進(jìn)制位表示一個(gè)十進(jìn)制位,實(shí)際上只是用低4個(gè)二進(jìn)制位表示一個(gè)十進(jìn)制位0~9,高4位通常默認(rèn)為0。ASCII碼中0~9的編碼是30H~39H,所以0~9的ASCII碼(高4位變?yōu)?)就可以認(rèn)為是非壓縮的BCD碼。非壓縮BCD碼調(diào)整指令包括AAA、AAS、AAM和AAD四條指令,分別用于對(duì)二進(jìn)制加、減、乘、除指令的結(jié)果進(jìn)行調(diào)整,以得到非壓縮BCD碼表示的十進(jìn)制數(shù)結(jié)果。由于只要在調(diào)整后的結(jié)果中加上30H就成為十進(jìn)制數(shù)位的ASCII碼,因此這組指令實(shí)際上也是針對(duì)ASCII碼的調(diào)整指令。在進(jìn)行十進(jìn)制數(shù)算術(shù)運(yùn)算時(shí),應(yīng)分兩步進(jìn)行: 先按二進(jìn)制數(shù)運(yùn)算規(guī)則進(jìn)行運(yùn)算,得到中間結(jié)果; 再用十進(jìn)制調(diào)整指令對(duì)中間結(jié)果進(jìn)行修正,得到正確的結(jié)果。下面通過(guò)幾個(gè)例子說(shuō)明BCD碼運(yùn)算為什么要調(diào)整以及怎樣調(diào)整!纠3.17】24 33=57。24的BCD碼為00100100B,33的BCD碼為00110011B,57的BCD碼為01010111B。24 33的二進(jìn)制算式如下: 00100100 00110011 01010111結(jié)論: 結(jié)果正確,不需要調(diào)整。【例3.18】27 54=81。27的BCD碼為00100111B,54的BCD碼為01010100B,81的BCD碼為10000001B。27 54的二進(jìn)制算式如下: 00100111 01010100 01111011結(jié)果不正確,因?yàn)樵谶M(jìn)行二進(jìn)制加法運(yùn)算時(shí),低4位向高4位有一個(gè)進(jìn)位,這個(gè)進(jìn)位是按十六進(jìn)制進(jìn)行的,即低4位逢十六才進(jìn)一,而十進(jìn)制數(shù)應(yīng)是逢十進(jìn)一。因此,比正確結(jié)果少6,這時(shí)應(yīng)在低4位上進(jìn)行加6處理,調(diào)整的算式如下: 00100111 01010100 01111011 00000110 10000001調(diào)整后的結(jié)果正確。結(jié)論: 加法運(yùn)算后,低4位若向高4位有進(jìn)位(即AF=1)時(shí),應(yīng)對(duì)低4位做加06H處理!纠3.19】97 81=178。97的BCD碼為10010111B,81的BCD碼為10000001B,178的BCD碼為000101111000B。97 81的二進(jìn)制算式如下: 10010111 10000001 CF←100011000結(jié)果不正確,因?yàn)楦?位向CF的進(jìn)位是按十六進(jìn)制進(jìn)行的,應(yīng)加60H進(jìn)行調(diào)整。調(diào)整的算式如下: 10010111 10000001 CF←100011000 01100000 01111000調(diào)整后的結(jié)果正確。結(jié)論: 加法運(yùn)算后,當(dāng)CF=1(有進(jìn)位產(chǎn)生)時(shí),應(yīng)做加60H處理!纠3.20】64 48=112。64的BCD碼為01100100B,48的BCD碼為01001000B,112的BCD碼為000100010010B。64 48的二進(jìn)制算式如下: 01100100 01001000 10101100結(jié)果不正確,因?yàn)榈?位大于9,且高4位也大于9。先加06H調(diào)整低4位,再加60H調(diào)整高4位。調(diào)整的算式如下: 01100100 01001000 10101100 00000110 10110010 01100000 CF←100010010調(diào)整后的結(jié)果正確。結(jié)論: 加法運(yùn)算后,低4位大于9時(shí),需做加06H處理; 高4位大于9時(shí),需做加60H處理。下面介紹十進(jìn)制數(shù)的調(diào)整指令。1) DAA指令指令格式: DAA DAA指令為無(wú)操作數(shù)指令。用以完成對(duì)壓縮的BCD碼加法運(yùn)算進(jìn)行校正。一般在A(yíng)DD指令之后,緊接著用一條DAA指令加以校正,在A(yíng)L中可以得到正確的結(jié)果。DAA指令的校正操作如下。(1) 若(AL∧0FH)>9或標(biāo)志位AF=1,則 AL←(AL) 6 AF←1 (2) 若AL>9FH或標(biāo)志CF=1,則 CF←AF AL←AL∧0FH AL←(AL) 60H CF←1 DAA指令影響標(biāo)志位AF、CF、PF、SF、ZF,而對(duì)OF未定義。2) DAS指令指令格式: DAS DAS指令為無(wú)操作數(shù)指令。用以完成對(duì)壓縮的BCD碼相減的結(jié)果進(jìn)行校正,得到正確的壓縮的十進(jìn)制差。一般在SUB指令之后,緊接著用一條DAS指令加以校正,在A(yíng)L中可以得到正確的結(jié)果。DAS指令校正的操作如下。(1) 若(AL∧0FH)>9或標(biāo)志位AF=1,則 AL←(AL)-6 AF←1 (2) 若AL>9FH或標(biāo)志CF=1,則 AL←(AL)-60H CF←1 DAS指令執(zhí)行時(shí),影響標(biāo)志位AF、CF、PF、SF、ZF,而對(duì)OF未定義。3) AAA指令指令格式: AAA AAA指令為無(wú)操作數(shù)指令。AAA指令對(duì)在A(yíng)L中的兩個(gè)非壓縮的十進(jìn)制數(shù)相加后的結(jié)果進(jìn)行校正。兩個(gè)非壓縮的十進(jìn)制數(shù)可以直接用ADD指令相加,但要得到正確的非壓縮的十進(jìn)制結(jié)果,必須在A(yíng)DD指令之后,用一條AAA指令加以校正,在A(yíng)X中可以得到正確的結(jié)果。AAA指令進(jìn)行校正的操作如下。若(AL∧0FH)>9或標(biāo)志位AF=1,則 AL←(AL) 6 AH←(AH) 1 AF←1 CF←AF AL←AL∧0FH AAA指令對(duì)標(biāo)志位AF和CF有影響,而對(duì)OF、PF、SF、ZF未定義。4) AAS指令指令格式: AAS AAS指令為無(wú)操作數(shù)指令。AAS指令把AL中兩個(gè)非壓縮的十進(jìn)制數(shù)相減后的結(jié)果進(jìn)行校正,產(chǎn)生一個(gè)正確的非壓縮的十進(jìn)制數(shù)差。AAS指令進(jìn)行校正的操作如下。若(AL∧0FH)>9或標(biāo)志位AF=1,則 AL←(AL)-6 AH←(AH)-1 AF←1 CF←AF AL←AL∧0FH AAS指令影響標(biāo)志位AF和CF,而對(duì)OF、PF、SF、ZF位未定義。5) AAM指令指令格式: AAM AAM指令執(zhí)行的操作為: 把AL中的積調(diào)整到非壓縮的BCD格式后送給AX寄存器。這條指令之前必須執(zhí)行MUL指令把兩個(gè)非壓縮的BCD碼相乘(此時(shí)要求其高4位為0),結(jié)果放在A(yíng)L寄存器中。本指令的調(diào)整方法是: 把AL寄存器的內(nèi)容除以0AH,商放在A(yíng)H寄存器中,余數(shù)保存在A(yíng)L寄存器中。本指令根據(jù)AL寄存器的內(nèi)容設(shè)置標(biāo)志位SF、ZF和PF,但對(duì)OF、CF和AF標(biāo)志位無(wú)影響。6) AAD指令指令格式: AAD 前面所述的對(duì)非壓縮BCD碼的調(diào)整指令都是在完成相應(yīng)的加法、減法及乘法運(yùn)算后,再使用AAA、AAS及AAM指令來(lái)對(duì)運(yùn)算結(jié)果進(jìn)行十進(jìn)制調(diào)整的。除法的情況卻不同,它針對(duì)的情況如下所述。如果被除數(shù)是存放在A(yíng)X寄存器中的兩位非壓縮BCD數(shù),AH中存放十位數(shù),AL中存放個(gè)位數(shù),而且要求AH和AL中的高4位均為0。除數(shù)是一位非壓縮的BCD數(shù),同樣要求高4位為0。在把這兩個(gè)數(shù)用DIV指令相除以前,必須先用AAD指令把AX中的被除數(shù)調(diào)整成二進(jìn)制數(shù),并存放在A(yíng)L寄存器中。因此,AAD指令執(zhí)行的操作是: 10×AH AL→AL 0→AH 這條指令根據(jù)AL寄存器的內(nèi)容設(shè)置標(biāo)志位SF、ZF和PF,但對(duì)OF、CF和AF標(biāo)志位無(wú)影響。3.2.3邏輯操作類(lèi)指令邏輯操作類(lèi)指令是按位操作指令,可以對(duì)8位或16位的寄存器或存儲(chǔ)單元的內(nèi)容按位操作。該類(lèi)指令包括邏輯運(yùn)算指令、移位指令和循環(huán)移位指令。1. 邏輯運(yùn)算指令邏輯運(yùn)算指令用來(lái)對(duì)字或字節(jié)按位進(jìn)行邏輯運(yùn)算,包括邏輯與AND、邏輯或OR、邏輯非NOT、邏輯異或XOR和測(cè)試TEST五條指令。1) 邏輯與運(yùn)算指令指令格式: ANDOPRD1,OPRD2 其中,目的操作數(shù)OPRD1為任一通用寄存器或存儲(chǔ)器操作數(shù),源操作數(shù)OPRD2為立即數(shù)、任一通用寄存器或存儲(chǔ)器操作數(shù)。也就是在這兩個(gè)操作數(shù)中,源操作數(shù)可以是任意的尋址方式,而目的操作數(shù)只能是立即數(shù)之外的其他尋址方式,并且兩個(gè)操作數(shù)不能同時(shí)為存儲(chǔ)器尋址方式。AND指令實(shí)現(xiàn)對(duì)兩個(gè)操作數(shù)按位進(jìn)行邏輯與的運(yùn)算,結(jié)果送至目的操作數(shù)。本指令可以進(jìn)行字節(jié)或字的“與”運(yùn)算。AND指令影響標(biāo)志位PF、SF、ZF,使CF=0,OF=0。例如,在同一個(gè)通用寄存器自身相與時(shí),操作數(shù)雖不變,但使CF置0。本指令主要用于修改操作數(shù)或置某些位為0。例如: ANDAL,0FH ANDAX,BX ANDDX,BUF1[DI BX] ANDBYTE[BX],00FFH 上例中的第一條指令,將使AL寄存器的高4位置成零保持AL低4位值不變。2) 邏輯或運(yùn)算指令指令格式: OROPRD1,OPRD2 其中,OPRD1、OPRD2的含義與AND指令相同,對(duì)標(biāo)志位的影響也與AND指令相同。唯一不同的地方是,OR指令完成對(duì)兩個(gè)操作數(shù)按位“或”的運(yùn)算,結(jié)果送至目的操作數(shù)中。本指令可以進(jìn)行字節(jié)或字的“或”運(yùn)算。OR指令可用于置位某些位,而不影響其他位。這時(shí)只需將要置1的位同“1”相或,維持不變的位同“0”相或即可。3) 邏輯非運(yùn)算指令指令格式: NOTOPRD 其中,OPRD可為任一通用寄存器或存儲(chǔ)器操作數(shù)。本指令的功能是完成對(duì)操作數(shù)的按位求反運(yùn)算,結(jié)果送回給原操作數(shù),本指令可以進(jìn)行字節(jié)或字的“非”運(yùn)算,不影響標(biāo)志位。4) 邏輯異或運(yùn)算指令指令格式: XOROPRD1,OPRD2 其中,OPRD1、OPRD2的含義與AND指令相同,對(duì)標(biāo)志位的影響也與AND指令相同。本指令的功能是實(shí)現(xiàn)兩個(gè)操作數(shù)按位“異或”的運(yùn)算,即相“異或”的兩位不相同時(shí),結(jié)果是1; 否則,“異或”的結(jié)果為0,結(jié)果送至目的操作數(shù)中。XOR指令可以實(shí)現(xiàn)字節(jié)或字的“異或”運(yùn)算。XOR可以用于求反某些位,而不影響其他位。要求求反的位同“1”異或,維持不變的位同“0”異或。例如,XORBL,00010001B指令的功能是將BL中D0和D4求反,其余位不變; XORAX,AX可以實(shí)現(xiàn)對(duì)AX寄存器內(nèi)容清0。5) 測(cè)試指令指令格式: TESTOPRD1,OPRD2 其中,OPRD1、OPRD2的含義同AND指令,對(duì)標(biāo)志位的影響也與AND指令相同。該指令與AND指令一樣,也是對(duì)兩個(gè)操作數(shù)進(jìn)行按位的“與”運(yùn)算,唯一不同之處是不將相“與”的結(jié)果送目的操作數(shù),即本指令對(duì)兩個(gè)操作數(shù)的內(nèi)容均不進(jìn)行修改,僅是在邏輯“與”操作后,對(duì)標(biāo)志位重新置位。TEST指令通常用于檢測(cè)一些條件是否滿(mǎn)足,但又不希望改變?cè)僮鲾?shù)的情況。這條指令之后,一般都是條件轉(zhuǎn)移指令,目的是利用測(cè)試條件轉(zhuǎn)向不同的程序段!纠3.21】寫(xiě)出判斷寄存器AX中D3和D9位是否為0的指令。 TESTAX,0008H TESTAX,0200H 2. 邏輯移位指令8086/8088指令系統(tǒng)的移位指令包括邏輯左移SHL、算術(shù)左移SAL、邏輯右移SHR、算術(shù)右移SAR等指令,其中SHL和SAL指令的操作完全相同。移位指令的操作對(duì)象可以是一個(gè)8位或16位的寄存器或存儲(chǔ)單元。移位操作可以是向左或向右移一位,也可以移多位。當(dāng)要求移多位時(shí),指令規(guī)定移位位數(shù)(次數(shù))必須放在CL寄存器中,即指令中規(guī)定的移位次數(shù)不允許是1以外的常數(shù)或CL以外的寄存器。移位指令都影響狀態(tài)標(biāo)志位,但影響的方式各條指令不盡相同。1) 邏輯左移指令指令格式: SHLOPRD1,COUNT 其中,OPRD1為目的操作數(shù),可以是通用寄存器或存儲(chǔ)器操作數(shù)。COUNT代表移位的次數(shù)(或位數(shù))。移位一次,COUNT=1,移位多于一次時(shí),COUNT=(CL),(CL)中為移位的次數(shù)。本指令的功能是對(duì)給定的目的操作數(shù)(8位或16位)左移COUNT次,每次移位時(shí)最高位移入標(biāo)志位CF中,最低位補(bǔ)0。本指令對(duì)標(biāo)志位OF、PF、SF、ZF、CF有影響。2) 邏輯右移指令指令格式: SHROPRD1,COUNT 其中,OPRD1、COUNT與指令SHL中意義相同。與SHL一樣,SHR指令也影響標(biāo)志位OF、PF、SF、ZF和CF。所不同的是,本指令實(shí)現(xiàn)由COUNT決定次數(shù)的邏輯右移操作,每次移位時(shí),最高位補(bǔ)零,最低位移至標(biāo)志位CF中。例如: SHLBL,1 SHLCX,1 SHLALFA[DI],1 或者: MOVCL,3 SHRDX,CL SHRDAT[DI],CL 上例中前三條指令完成目的操作數(shù)邏輯左移1位的運(yùn)算; 而后兩條移位指令,則實(shí)現(xiàn)由CL內(nèi)容指定的次數(shù)的右移運(yùn)算,由于(CL)=3,故分別對(duì)目的操作數(shù)邏輯右移3位。3) 算術(shù)左移指令指令格式: SALOPRD1,COUNT 其中,OPRD1、COUNT與指令SHL中意義相同。本指令與SHL的功能也完全相同,這是因?yàn)檫壿嬜笠浦噶钆c算術(shù)左移指令所要完成的操作是一樣的。如果SAL將OPRD1的最高位移至CF,改變了原來(lái)的CF值,則溢出標(biāo)志位OF=1,表示移位前后的操作數(shù)不再具有倍增的關(guān)系。因而SAL可用于帶符號(hào)數(shù)的倍增運(yùn)算,SHL只能用于無(wú)符號(hào)數(shù)的倍增運(yùn)算。4) 算術(shù)右移指令指令格式: SAROPRD1,COUNT 其中,OPRD1、COUNT與指令SHL中意義相同。本指令通常用于對(duì)帶符號(hào)數(shù)減半的運(yùn)算中,因而在每次右移時(shí),保持最高位(符號(hào)位)不變,最低位右移至CF中。圖3.12給出了上述四條移位指令的操作示意圖。 圖3.12移位指令操作示意圖 3. 循環(huán)移位指令能實(shí)現(xiàn)操作數(shù)首尾相連的移位操作是循環(huán)移位指令。循環(huán)移位指令類(lèi)似于移位指令,但要從一端移出的位返回到另一端形成循環(huán)。按進(jìn)位標(biāo)志CF是否參加循環(huán)移位,又可分為不帶CF的循環(huán)移位指令和帶CF的循環(huán)移位指令兩類(lèi),每一類(lèi)都可進(jìn)行左移或右移,循環(huán)移位的次數(shù)由COUNT操作數(shù)給出。1) 不帶進(jìn)位循環(huán)左移指令指令格式: ROLOPRD1,COUNT 2) 不帶進(jìn)位循環(huán)右移指令指令格式: ROROPRD1,COUNT 3) 帶進(jìn)位循環(huán)左移指令指令格式: RCLOPRD1,COUNT 4) 帶進(jìn)位循環(huán)右移指令指令格式: RCROPRD1,COUNT 循環(huán)移位指令的操作數(shù)形式與移位指令相同,如果僅移動(dòng)一次,可以用1表示; 如果需要移動(dòng)多次,則需用CL寄存器表示移位次數(shù)。這組指令只對(duì)標(biāo)志位CF和OF有影響。CF由移入CF的內(nèi)容決定,OF取決于移位一次后符號(hào)位是否改變,如改變,則OF=1。由于是循環(huán)移位,因此對(duì)字節(jié)移位8次,對(duì)字移位16次,就可恢復(fù)為原操作數(shù)。由于帶CF的循環(huán)移位,可以將CF的內(nèi)容移入,因此可以利用它實(shí)現(xiàn)多字節(jié)的循環(huán)。循環(huán)移位指令的操作示意圖如圖3.13所示。 圖3.13循環(huán)移位指令操作示意圖 【例3.22】有兩位BCD數(shù)存放在BUFFER單元,要求將其轉(zhuǎn)換為ASCII碼,存于RESULT開(kāi)始的兩個(gè)地址單元,并測(cè)試是否有字節(jié)為'0'的ASCII碼,如有,則CF=1,結(jié)束操作。程序如下: MOVAL,BUFFER ANDAL,0F0H MOVCL,4 SHRAL,CL ORAL,30H CMPAL,30H JZZERO MOVRESULT,AL MOVAL,BUFFER ANDAL,0FH ORAL,30H CMPAL,30H JZZERO MOVRESULT 1,AL JMPEXX ZERO: STC EXX: HLT 本程序?qū)UF單元中的兩位BCD數(shù)分離后,用ORAL,30H將AL中的BCD數(shù)轉(zhuǎn)換為ASCII碼,這是因?yàn)?0'到'9'的ASCII碼為30H至39H。同理,用比較指令CMPAL,30H 可判斷AL中內(nèi)容是否為30H,若是,則ZF=1; 否則,ZF=0。程序針對(duì)這兩種情況,作兩種不同的處理。3.2.4程序控制類(lèi)指令在8086/8088指令系統(tǒng)中,程序的執(zhí)行序列是由代碼段寄存器CS和指令指針I(yè)P確定的。CS包含當(dāng)前指令所在代碼段的段地址,IP則是要執(zhí)行的下一條指令的偏移地址。程序的執(zhí)行一般依指令序列順序執(zhí)行,但有時(shí)需用改變程序的流程?刂妻D(zhuǎn)移類(lèi)指令通過(guò)修改CS和IP寄存器的值來(lái)改變程序的執(zhí)行順序,包括五組指令: 無(wú)條件轉(zhuǎn)移指令、有條件轉(zhuǎn)移指令、循環(huán)指令、過(guò)程調(diào)用和返回指令以及中斷指令。利用程序控制類(lèi)指令,可以實(shí)現(xiàn)分支、循環(huán)、子程序等程序結(jié)構(gòu)。1. 無(wú)條件轉(zhuǎn)移指令指令格式: JMPOPRD 其中,OPRD為轉(zhuǎn)移的目的地址。程序轉(zhuǎn)移到目的地址所指向的指令后繼續(xù)向下執(zhí)行。無(wú)條件轉(zhuǎn)移,就是無(wú)任何先決條件就能使程序改變執(zhí)行順序。處理器只要執(zhí)行無(wú)條件轉(zhuǎn)移指令JMP,就能使程序轉(zhuǎn)移到指定的目標(biāo)地址處。目標(biāo)地址操作數(shù)的尋址方法可以是相對(duì)尋址、直接尋址或間接尋址。相對(duì)尋址方式以當(dāng)前IP為基礎(chǔ),加上位移量構(gòu)成目標(biāo)地址。目標(biāo)地址像立即數(shù)一樣,直接在指令的機(jī)器代碼中就是直接尋址方式。目標(biāo)地址如果在寄存器或主存單元中,就是通過(guò)寄存器或存儲(chǔ)器的間接尋址方式。相對(duì)尋址方式根據(jù)位移量進(jìn)行轉(zhuǎn)移,方便了程序段在內(nèi)存中的動(dòng)態(tài)加載,是最常用的目標(biāo)地址尋址方式。例如,同樣的一段程序,如果改變了內(nèi)存地址,轉(zhuǎn)移的目的地址也就改變了,但是轉(zhuǎn)移指令與目的指令之間的位移并沒(méi)有因此改變。JMP指令可以將程序轉(zhuǎn)移到1MB存儲(chǔ)空間的任何位置。根據(jù)跳轉(zhuǎn)的距離,JMP指令分成了段內(nèi)轉(zhuǎn)移和段間轉(zhuǎn)移。段內(nèi)轉(zhuǎn)移是指在當(dāng)前代碼段64KB范圍內(nèi)轉(zhuǎn)移,因此不需要更改CS段地址,只要改變IP偏移地址。如果轉(zhuǎn)移范圍用1字節(jié)(-128~127)表達(dá),則可以形成所謂的“短轉(zhuǎn)移short jump”; 如果地址位移用一個(gè)16位數(shù)表達(dá),則形成“近轉(zhuǎn)移near jump”,它是在±32KB范圍內(nèi)。段間轉(zhuǎn)移是指從當(dāng)前代碼段跳轉(zhuǎn)到另一個(gè)代碼段,此時(shí)需要更改CS段地址和IP偏移地址,這種轉(zhuǎn)移也稱(chēng)為“遠(yuǎn)轉(zhuǎn)移far jump”。轉(zhuǎn)移的目標(biāo)地址必須用一個(gè)32位數(shù)表達(dá),叫作32位遠(yuǎn)指針,它就是邏輯地址。由此可見(jiàn),JMP指令根據(jù)目標(biāo)地址不同的提供方法和內(nèi)容,可以分為以下4種格式。(1) 段內(nèi)轉(zhuǎn)移,相對(duì)尋址。(2) 段內(nèi)轉(zhuǎn)移,間接尋址。(3) 段間轉(zhuǎn)移,直接尋址。(4) 段間轉(zhuǎn)移,間接尋址。以下指令為合法的無(wú)條件轉(zhuǎn)移指令: JMPSHORT TARGET JMPTARGET JMPAX JMPTABLE[BX] JMPWORD PTR [BP][DI] JMPFAR PTR LABLE JMPVAR_DOUBLEWORD JMPDWORD PTR [BP][DI] 2. 條件轉(zhuǎn)移指令指令格式: JCCOPRD 條件轉(zhuǎn)移指令只有一個(gè)操作數(shù)OPRD,用以指明轉(zhuǎn)移的目的地址。指令助記符中的“CC”表示條件。這種指令的執(zhí)行包括兩個(gè)過(guò)程: 第一步,測(cè)試規(guī)定的條件; 第二步,如果條件滿(mǎn)足,則轉(zhuǎn)移到目標(biāo)地址; 否則,繼續(xù)順序執(zhí)行。條件轉(zhuǎn)移指令的操作數(shù)必須是一個(gè)短標(biāo)號(hào),也就是說(shuō),所有的條件轉(zhuǎn)移指令都是兩字節(jié)指令,轉(zhuǎn)移指令的下一條指令到目標(biāo)地址之間的距離必須為-128~127。如果指令規(guī)定的條件滿(mǎn)足,則將這個(gè)位移量加到IP寄存器上,以實(shí)現(xiàn)程序的轉(zhuǎn)移。絕大多數(shù)條件轉(zhuǎn)移指令(除JCXZ指令外)將狀態(tài)標(biāo)志位的狀態(tài)作為測(cè)試的條件。因此,首先應(yīng)該執(zhí)行影響有關(guān)的狀態(tài)標(biāo)志位的指令,然后才能用條件轉(zhuǎn)移指令測(cè)試這些標(biāo)志,以確定程序是否轉(zhuǎn)移。CMP和TEST指令常常與條件轉(zhuǎn)移指令配合使用,因?yàn)檫@兩條指令不改變目的操作數(shù)的內(nèi)容,但可以影響狀態(tài)標(biāo)志位。8086/8088的條件轉(zhuǎn)移指令非常豐富,不僅可以測(cè)試一個(gè)狀態(tài)標(biāo)志位的狀態(tài),而且可以綜合測(cè)試幾個(gè)狀態(tài)標(biāo)志位; 不僅可以測(cè)試無(wú)符號(hào)數(shù)的高低,而且可以測(cè)試帶符號(hào)數(shù)的大小等,編程時(shí)使用十分靈活、方便。所有的條件轉(zhuǎn)移指令的名稱(chēng)、助記符及轉(zhuǎn)移條件等列在表3.2中。其中同一行內(nèi)用斜杠隔開(kāi)的幾個(gè)助記符,實(shí)質(zhì)上代表同一條指令的幾種不同的表示方法。 表3.2條件轉(zhuǎn)移指令 指 令 名 稱(chēng)助記符轉(zhuǎn) 移 條 件說(shuō)明 等于/零轉(zhuǎn)移JE/JZZF=1不等于/非零轉(zhuǎn)移JNE/JNZZF=0負(fù)轉(zhuǎn)移JSSF=1正轉(zhuǎn)移JNSSF=0“1”的個(gè)數(shù)為偶轉(zhuǎn)移JP/JPEPF=1“1”的個(gè)數(shù)為奇轉(zhuǎn)移JNP/JPOPF=0溢出轉(zhuǎn)移JOOF=1不溢出轉(zhuǎn)移JNOOF=0進(jìn)位轉(zhuǎn)移JCCF=1不進(jìn)位轉(zhuǎn)移JNCCF=0判斷單個(gè)標(biāo)志位狀態(tài)續(xù)表 指 令 名 稱(chēng)助記符轉(zhuǎn) 移 條 件說(shuō)明 低于/不高于或等于轉(zhuǎn)移JB/JANECF=1高于或等于/不低于轉(zhuǎn)移JAE/JNBCF=0高于/不低于或等于轉(zhuǎn)移JA/JNBECF=1且ZF=0低于或等于/不高于轉(zhuǎn)移JBE/JNACF=0或ZF=1用于無(wú)符號(hào)數(shù)的比較 大于/不小于或等于轉(zhuǎn)移JG/JNLESF=OF且ZF=0大于或等于/不小于轉(zhuǎn)移JGE/JNLSF=OF小于/不大于或等于轉(zhuǎn)移JL/JNGESF≠OF且ZF=0小于或等于/不大于轉(zhuǎn)移JLE/JNGSF≠OF或ZF=1用于帶符號(hào)數(shù)的比較 CX等于零轉(zhuǎn)移JCXZ(CX)=0不用判斷標(biāo)志位狀態(tài) 比較兩個(gè)無(wú)符號(hào)數(shù)大小的指令,通常是根據(jù)一個(gè)標(biāo)志位或兩個(gè)標(biāo)志位以確定兩個(gè)數(shù)的大小。為了與帶符號(hào)數(shù)的大小相區(qū)別,無(wú)符號(hào)數(shù)比較常用高于、低于來(lái)表示。帶符號(hào)數(shù)比較常用大于、小于來(lái)表示。以上兩種表示方法一定要能正確地區(qū)分開(kāi),否則就不能正確理解和使用這些指令!纠3.23】設(shè)計(jì)一段程序?qū)崿F(xiàn)以下功能: 如果AL最高位為0,則設(shè)置AH=0; 如果AL最高位為1,則設(shè)置AH=FFH。程序段如下: TESTAL,80H JZNEXT0 MOVAH,0FFH JMPDONE NEXT0: MOVAH,0 DONE: … 【例3.24】設(shè)X和Y為存放于X單元和Y單元的16位操作數(shù),計(jì)算|X-Y|,并將結(jié)果存入RESULT單元中。程序段如下: MOVAX,X SUBAX,Y JNSNONNEG NEGAX NONNEG: MOVRESULT,AX 【例3.25】完成下式的判定運(yùn)算。Y=1X≥0 0X<0實(shí)現(xiàn)的程序如下: MOVAL,X CMPAL,0 JGEA1 MOVAL,0 JMPA2 A1: MOVAL,1 A2: MOVY,AL … 以上程序段中的X、Y是兩個(gè)存儲(chǔ)器變量,把X當(dāng)成帶符號(hào)數(shù)與0比較。 3. 循環(huán)控制指令循環(huán)是一種特殊的轉(zhuǎn)移流程,當(dāng)滿(mǎn)足(不滿(mǎn)足)某條件時(shí),反復(fù)執(zhí)行一系列操作,直到不滿(mǎn)足(滿(mǎn)足)條件為止。循環(huán)流程的條件一般是循環(huán)計(jì)數(shù),指令約定用CX寄存器作為計(jì)數(shù)器。在程序中用循環(huán)計(jì)數(shù)來(lái)控制循環(huán)次數(shù)。這類(lèi)指令屬于段內(nèi)SHORT短類(lèi)型轉(zhuǎn)移,目的地址必須距本指令在-127~128個(gè)字節(jié)的范圍內(nèi)。循環(huán)指令不影響標(biāo)志位。1) 循環(huán)指令指令的一般格式為: LOOP標(biāo)號(hào) 功能: (CX)←(CX)-1,(CX)≠0,則轉(zhuǎn)移至標(biāo)號(hào)處循環(huán)執(zhí)行,直至(CX)=0,繼續(xù)執(zhí)行后續(xù)程序。LOOP指令的操作是先將CX的內(nèi)容減1,如結(jié)果不等于0,則轉(zhuǎn)到指令中指定的短標(biāo)號(hào)處; 否則,順序執(zhí)行下一條指令。因此,在循環(huán)程序開(kāi)始前,應(yīng)將循環(huán)次數(shù)送CX寄存器。2) 條件循環(huán)指令指令的一般格式為: LOOPZ/LOOPE標(biāo)號(hào) 功能: (CX)←(CX)-1,(CX)≠0,且ZF=1時(shí),轉(zhuǎn)移至標(biāo)號(hào)處循環(huán)。LOOPZ和LOOPE實(shí)際上代表同一條指令。本指令的操作也是先將CX寄存器的內(nèi)容減1,如結(jié)果不為零,且零標(biāo)志ZF=1,則轉(zhuǎn)移到指定的短標(biāo)號(hào)處。3) 條件循環(huán)指令指令的一般格式為: LOOPNZ/LOOPNE標(biāo)號(hào) 功能: (CX)←(CX)-1,(CX)≠0,且ZF=0時(shí),轉(zhuǎn)移至標(biāo)號(hào)處循環(huán)。本指令也同樣有兩種表示形式。指令的操作是將CX寄存器的內(nèi)容減1,如結(jié)果不為0,且零標(biāo)志ZF=0(表示“不相等”或“不等于0”),則轉(zhuǎn)移到指定的短標(biāo)號(hào)處。4. 過(guò)程調(diào)用和返回指令如果有一些程序段需要在不同的地方多次反復(fù)地出現(xiàn),則可以將這些程序段設(shè)計(jì)成為過(guò)程(相當(dāng)于子程序),每次需要時(shí)進(jìn)行調(diào)用。過(guò)程結(jié)束后,再返回到原來(lái)調(diào)用的地方。采用這種方法不僅可以使源程序的總長(zhǎng)度大大縮短,而且有利于實(shí)現(xiàn)模塊化的程序設(shè)計(jì),使程序的編制、閱讀和修改都比較方便。 1) 過(guò)程調(diào)用指令指令格式: CALLOPRD 其中,OPRD為過(guò)程的目的地址。過(guò)程調(diào)用可以分為段內(nèi)調(diào)用和段間調(diào)用兩種。尋址方式也可以分為直接尋址和間接尋址兩種。本指令不影響標(biāo)志位。(1) 段內(nèi)直接調(diào)用。指令格式: CALLNEAR類(lèi)型的過(guò)程名 每一個(gè)過(guò)程在定義時(shí),應(yīng)指定它是近類(lèi)型(NEAR),還是遠(yuǎn)類(lèi)型(FAR)。本指令是段內(nèi)直接調(diào)用,因而過(guò)程與調(diào)用指令同處在一個(gè)代碼段內(nèi)。在執(zhí)行該調(diào)用指令時(shí),首先將IP的內(nèi)容入棧保護(hù),然后將指令代碼給出的目的地址的段內(nèi)偏移量送入IP中,從而實(shí)現(xiàn)過(guò)程調(diào)用,將程序轉(zhuǎn)至過(guò)程入口。(2) 段內(nèi)間接調(diào)用。指令格式: CALLOPRD 其中,OPRD為16位通用寄存器或存儲(chǔ)器數(shù)。本指令執(zhí)行時(shí),首先將IP的內(nèi)容入棧保護(hù),然后將目的地址在段內(nèi)偏移量由指定的16位寄存器或存儲(chǔ)器字中取至IP中,從而實(shí)現(xiàn)過(guò)程調(diào)用。(3) 段間直接調(diào)用。指令格式: CALLFAR類(lèi)型的過(guò)程名 由于是段間調(diào)用,在指令執(zhí)行時(shí),應(yīng)同時(shí)將當(dāng)前的CS及IP的值入棧保護(hù),然后將FAR類(lèi)型的過(guò)程名所在的段基址和段內(nèi)偏移值送CS及IP,從而實(shí)現(xiàn)過(guò)程調(diào)用。(4) 段間間接調(diào)用。指令格式: CALLDWORD 其中,DWORD為存儲(chǔ)器操作數(shù)。段間間接調(diào)用只能通過(guò)存儲(chǔ)器雙字進(jìn)行。本指令執(zhí)行時(shí),首先將當(dāng)前的CS及IP的值入棧保護(hù),然后將存儲(chǔ)器雙字操作數(shù)的第一個(gè)字的內(nèi)容送IP,將第二個(gè)字的內(nèi)容送CS,以實(shí)現(xiàn)段間調(diào)用。2) 返回指令指令格式: RET 本指令的作用是: 當(dāng)調(diào)用的過(guò)程結(jié)束后實(shí)現(xiàn)從過(guò)程返回至原調(diào)用程序的下一條指令。本指令不影響標(biāo)志位。由于在過(guò)程定義時(shí),已指明其近(NEAR)或遠(yuǎn)(FAR)的屬性,因此RET指令將根據(jù)段內(nèi)調(diào)用與段間調(diào)用,執(zhí)行不同的操作。對(duì)段內(nèi)調(diào)用,返回時(shí),由堆棧彈出一個(gè)字的返回地址的段內(nèi)偏移量至IP。對(duì)段間調(diào)用,返回時(shí),由堆棧彈出的第一個(gè)字為返回地址的段內(nèi)偏移量,將其送入IP中,由堆棧彈出的第二個(gè)字為返回地址的段基址,將其送入CS中。5. 中斷指令在程序運(yùn)行時(shí),遇到某些緊急情況或一些嚴(yán)重的錯(cuò)誤(如溢出),當(dāng)前程序應(yīng)能夠暫停,處理器中止當(dāng)前程序運(yùn)行,轉(zhuǎn)去執(zhí)行處理這些緊急情況的程序段。這種情況稱(chēng)為“中斷”。轉(zhuǎn)去執(zhí)行的處理中斷的子程序稱(chēng)為“中斷服務(wù)程序”或“中斷處理程序”。當(dāng)前程序被中斷的地方稱(chēng)為“斷點(diǎn)”。中斷服務(wù)程序執(zhí)行完后應(yīng)返回原來(lái)程序的斷點(diǎn),繼續(xù)執(zhí)行被中斷的程序。中斷提供了又一種改變程序執(zhí)行順序的方法。8086/8088具有很強(qiáng)的中斷系統(tǒng),可以處理256個(gè)不同方式的中斷。每一個(gè)中斷賦予一個(gè)中斷向量碼,CPU根據(jù)向量碼的不同來(lái)識(shí)別不同的中斷源。8086/8088內(nèi)部中斷源有除法錯(cuò)中斷、單步中斷、斷點(diǎn)中斷、溢出中斷、用戶(hù)自定義的軟中斷5種類(lèi)型。外部中斷是指來(lái)自CPU之外的原因引起的程序中斷,分為可屏蔽中斷和非屏蔽中斷兩種類(lèi)型。1) 溢出中斷指令指令格式: INTO 功能: 本指令檢測(cè)OF標(biāo)志位,當(dāng)OF=1時(shí),說(shuō)明已發(fā)生溢出,立即產(chǎn)生一個(gè)中斷類(lèi)型4的中斷,當(dāng)OF=0時(shí),本指令不起作用。2) 軟中斷指令指令格式: INTn 其中,n為軟中斷的類(lèi)型號(hào)。功能: 本指令將產(chǎn)生一個(gè)軟中斷,把控制轉(zhuǎn)向一個(gè)類(lèi)型號(hào)為n的軟中斷,該中斷處理程序入口地址在中斷向量表的n×4地址處的兩個(gè)存儲(chǔ)字(4個(gè)單元)中。3) 中斷返回指令指令格式: IRET 功能: 用于中斷處理程序中,從中斷程序的斷點(diǎn)處返回,繼續(xù)執(zhí)行原程序。本指令將影響所有標(biāo)志位。無(wú)論是軟中斷,還是硬中斷,本指令均可使其返回到中斷程序的斷點(diǎn)處繼續(xù)執(zhí)行原程序。3.2.5串操作類(lèi)指令串操作類(lèi)指令是一組具有修改數(shù)據(jù)串操作指針功能的指令。數(shù)據(jù)串可以是字節(jié)串,也可以是字串,即每一個(gè)數(shù)據(jù)占用兩個(gè)存儲(chǔ)單元。數(shù)據(jù)串只能放在存儲(chǔ)器中,對(duì)數(shù)據(jù)串的數(shù)據(jù)進(jìn)行處理時(shí),可以只對(duì)一個(gè)數(shù)據(jù)串進(jìn)行,也可以對(duì)兩個(gè)數(shù)據(jù)串進(jìn)行,根據(jù)數(shù)據(jù)串中數(shù)據(jù)的流動(dòng)方向,可以分源數(shù)據(jù)串和目的數(shù)據(jù)串。8086/8088指令系統(tǒng)還為串操作類(lèi)指令提供重復(fù)前綴,以便重復(fù)進(jìn)行相同的操作。在串操作指令中,源操作數(shù)用寄存器SI尋址,默認(rèn)在數(shù)據(jù)段DS中,但允許段超越; 目的操作數(shù)用寄存器DI尋址,默認(rèn)在附加段ES中,不允許段超越。每執(zhí)行一次串操作指令,作為源地址指針的SI和作為目的地址指針的DI將自動(dòng)修改: ±1(對(duì)于字節(jié)串)或±2(對(duì)于字串)。地址指針是增加還是減少則取決于方向標(biāo)志DF。在系統(tǒng)初始化后或執(zhí)行指令CLD后,DF=0,此時(shí)地址指針是增1或2; 在執(zhí)行指令STD后,DF=1,此時(shí)地址指針減1或2。1. 串傳送指令指令格式: MOVSOPRD1,OPRD2 MOVSB MOVSW 其中,OPRD1為目的串符號(hào)地址,OPRD2為源串符號(hào)地址。功能: OPRD1←OPRD2。串傳送指令MOVS將數(shù)據(jù)段主存單元的1字節(jié)或字,傳送到附加段的主存單元中。定義數(shù)據(jù)串時(shí),要求源串和目的串類(lèi)型一致,并以其類(lèi)型區(qū)別是字節(jié)或字操作。在指令中不出現(xiàn)操作數(shù)時(shí),字節(jié)串傳送格式為MOVSB,字串傳送格式為MOVSW。MOVS指令不影響標(biāo)志位。(1) 對(duì)字節(jié)串操作時(shí),若DF=0,則做加,即: [ES: DI] ← [DS: SI],(SI)←(SI) 1,(DI)←(DI) 1 若DF=1,則做減,即: (SI)←(SI)-1,(DI)←(DI)-1 (2) 對(duì)字串操作時(shí),若DF=0,則做加,即: (SI)←(SI) 2,(DI)←(DI) 2 若DF=1,則做減,即: (SI)←(SI)-2,(DI)←(DI)-2 【例3.26】將存儲(chǔ)器中變量BUFA開(kāi)始的160個(gè)數(shù)據(jù)串傳送至BUFB開(kāi)始的存儲(chǔ)區(qū),可用以下程序段實(shí)現(xiàn)。 MOVSI,OFFSET BUFA MOVDI,OFFSET BUFB MOVCX,160 CLD AGAIN: MOVSBUFB,BUFA DECCX JNZAGAIN 2. 串比較指令指令格式: CMPSOPRD1,OPRD2 CMPSB CMPSW 其中,OPRD1為目的串符號(hào)地址,OPRD2為源串符號(hào)地址。串比較指令CMPS將由SI尋址的源串中的數(shù)據(jù)與DI尋址的目的串中的數(shù)據(jù)(字或字節(jié))進(jìn)行比較,比較結(jié)果送標(biāo)志位,而不改變操作數(shù)本身。同時(shí),SI、DI將自動(dòng)調(diào)整。CMPS指令影響標(biāo)志位AF、CF、OF、SF、PF、ZF。CMPS指令可用來(lái)檢查兩個(gè)字符串是否相同,可以使用循環(huán)控制方法對(duì)整串進(jìn)行比較。 【例3.27】如對(duì)兩個(gè)字節(jié)串進(jìn)行比較,若一致,則AL內(nèi)容置為0; 若不一致,則AL內(nèi)容置為0FFH。程序段如下: MOVSI,OFFSET DAT1; DAT1中是內(nèi)存中定義的字節(jié)串1 MOVDI,OFFSET DAT2; DAT2中是內(nèi)存中定義的字節(jié)串2 MOVCX,N CLD NEXT: CMPSB JNZFIN DECCX JNZNEXT MOVAL,0 JMPEXX FIN: MOVAL,0FFH EXX: MOVDAT3,AL; DAT3是內(nèi)存中存放結(jié)果的單元 3. 串掃描指令指令格式: SCASOPRD SCASB SCASW 其中,OPRD為目的串符號(hào)地址。串掃描指令SCAS將AL或AX的內(nèi)容與附加段中由DI寄存器尋址的目的串中的數(shù)據(jù)進(jìn)行比較,根據(jù)比較結(jié)果設(shè)置標(biāo)志位,但不改變操作數(shù)本身。每次比較后修改DI寄存器的值,使之指向下一個(gè)元素。SCAS指令影響標(biāo)志位AF、CF、OF、SF、PF、ZF。SCAS指令可查找字符串中的一個(gè)關(guān)鍵字,只需在本指令執(zhí)行前,把關(guān)鍵字放在A(yíng)L或AX中,用重復(fù)前綴可在整串中查找。【例3.28】在附加段定義了一個(gè)字符串,首地址由STRING指示,共有100個(gè)字符。在字符串中查找“空格”(ASCII碼為20H)字符。 MOVDI,OFFSET STRING MOVAL,20H MOVCX,100 CLD AGAIN: SCASB JZFOUND; ZF=1,發(fā)現(xiàn)空格,轉(zhuǎn)移到FOUND DECCX ; 不是空格 JNZAGAIN; 搜索下一個(gè)字符 …; 不含空格,則繼續(xù)執(zhí)行 FOUND: … 4. 串讀取指令指令格式: LODSOPRD LODSB LODSW 其中,OPRD為源串符號(hào)地址。串讀取指令LODS的功能是把SI尋址的源串的數(shù)據(jù)字節(jié)送AL或數(shù)據(jù)字送AX中,并根據(jù)DF的值,地址指針SI進(jìn)行自動(dòng)調(diào)整。LODS指令不影響標(biāo)志位。5. 字符串存儲(chǔ)指令指令格式: STOSOPRD STOSB STOSW 其中,OPRD為目的串符號(hào)地址。本指令的功能是把AL或AX中的數(shù)據(jù)存儲(chǔ)到DI為目的串地址指針?biāo)鶎ぶ返拇鎯?chǔ)器單元中。地址指針DI將根據(jù)DF的值進(jìn)行自動(dòng)調(diào)整。STOS指令與LODS指令功能互逆。STOS指令不影響標(biāo)志位!纠3.29】將附加段64KB主存區(qū)全部設(shè)置為0。 MOVAX,0 MOVDI,0 MOVCX,8000H; CX←傳送次數(shù)(32×1024) CLD ; 設(shè)置DF=0,實(shí)現(xiàn)地址增加 AGAIN: STOSW; 傳送一個(gè)字 DECCX JNZAGAIN ; 判斷傳送次數(shù)CX是否為0 在此例中,將CLD指令改為STD指令就能反向傳送,實(shí)現(xiàn)同樣功能。另外,此例中實(shí)際上只要保證DI為偶數(shù)即可!纠3.30】數(shù)據(jù)段DS中有一個(gè)數(shù)據(jù)塊,具有100個(gè)字節(jié),起始地址為BBUF。現(xiàn)在要把其中的正數(shù)、負(fù)數(shù)分開(kāi),分別存入同一個(gè)段的兩個(gè)緩沖區(qū)。存放正數(shù)的起始地址為DATAA,存放負(fù)數(shù)的起始地址為DATAB。 MOVSI,OFFSET BBUF MOVDI,OFFSET DATAA MOVBX,OFFSET DATAB MOVAX,DS MOVEX,AX ; 所有數(shù)據(jù)都在一個(gè)段中,所以設(shè)置ES=DS MOVCX,100 CLD GOON: LODSB ; 從BBUF中取出一個(gè)數(shù)據(jù) TESTAL,80H ; 檢測(cè)符號(hào)位,判斷是正是負(fù) JNZMINUS; 符號(hào)位為1,是負(fù)數(shù),轉(zhuǎn)向MINIS STOSB; 符號(hào)位為0,是正數(shù),存入DATAA JMPAGAIN MINUS: XCHGBX,DI STOSB ; 將負(fù)數(shù)存入DATAB XCHGBX,DI AGAIN: DECCX JNZGOON 6. 重復(fù)前綴的說(shuō)明在串操作指令前加上重復(fù)前綴,可以對(duì)數(shù)據(jù)串進(jìn)行重復(fù)處理。由于加上重復(fù)前綴后,對(duì)應(yīng)的指令代碼是不同的,因此指令的功能便具有重復(fù)處理的功能,重復(fù)的次數(shù)存放在CX寄存器中。重復(fù)前綴形式有: REP; CX≠0,重復(fù)執(zhí)行字符串指令 REPZ/REPE ; CX≠0且ZF=1,重復(fù)執(zhí)行字符串指令 REPNZ/REPNE; CX≠0且ZF=0,重復(fù)執(zhí)行字符串指令 REP與MOVS或STOS串操作指令結(jié)合使用,完成一組數(shù)據(jù)的傳送或建立一組相同數(shù)據(jù)的數(shù)據(jù)串。REPZ/REPE與CMPS串操作指令結(jié)合使用,可以完成兩組數(shù)據(jù)串的比較。當(dāng)串未結(jié)束時(shí),繼續(xù)重復(fù)執(zhí)行數(shù)據(jù)串指令。它可用來(lái)判定兩數(shù)據(jù)串是否相同。REPZ/REPE與SCAS串操作指令結(jié)合使用,可以完成在一個(gè)數(shù)據(jù)串中搜索一個(gè)關(guān)鍵字。只要當(dāng)數(shù)據(jù)串未結(jié)束且當(dāng)關(guān)鍵字與元素相同時(shí),繼續(xù)重復(fù)執(zhí)行串搜索指令,用于在數(shù)據(jù)串中查找與關(guān)鍵字不相同的數(shù)據(jù)的位置。REPNZ/REPNE與CMPS指令結(jié)合使用,表示當(dāng)串未結(jié)束且當(dāng)對(duì)應(yīng)串元素不相同時(shí),繼續(xù)重復(fù)執(zhí)行串比較指令。它可在兩數(shù)據(jù)串中查找相同數(shù)據(jù)的位置。REPNZ/REPNE與SCAS指令結(jié)合使用,表示串未結(jié)束且當(dāng)關(guān)鍵字與元素不相同時(shí),繼續(xù)重復(fù)執(zhí)行串搜索指令,用于在數(shù)據(jù)串中查找與關(guān)鍵字相同的數(shù)據(jù)的位置!纠3.31】對(duì)兩個(gè)字符串STR1與STR2進(jìn)行比較。 MOVSI,OFFSET STR1 MOVDI,OFFSET STR2 MOVCX,COUNT CLD REPZCMPSB JNZNEQU MOVAL,0 JMPOVR NEQU: MOVAL,0FFH OVR: MOVRESULT,AL HLT 【例3.32】在字符串中搜索關(guān)鍵字,記下搜索的次數(shù)和關(guān)鍵字在串中的位置。 CLD MOVDI,OFFSET BUF MOVCX,COUNT MOVAL,CHAR REPNESCASB JZFOUND MOVDI,0 JMPDONE FOUND: DECDI MOVBUFF,DI MOVBX,OFFSET BUF SUBDI,BX MOVBUFF 2,DI DONE: HLT 在本程序中,由于DI是自增的,若找到關(guān)鍵字,這時(shí)DI已指向關(guān)鍵字的下一個(gè)字符,故DI減1才是真正的關(guān)鍵字在字符串中的位置。用當(dāng)前關(guān)鍵字的位置減去串首地址,即能得到搜索的次數(shù)。3.2.6處理器控制類(lèi)指令處理器控制指令用于控制CPU的動(dòng)作,修改標(biāo)志寄存器的狀態(tài)等,實(shí)現(xiàn)對(duì)CPU的管理。1. 標(biāo)志位操作指令標(biāo)志位操作指令有7條,可以直接設(shè)置或清除CF、DF和IF標(biāo)志位。例如,串操作中的程序,經(jīng)常用CLD指令清方向標(biāo)志使DF=0,在串操作指令執(zhí)行時(shí),按增量的方式修改串指針。標(biāo)志位操作指令的格式、功能等信息列于表3.3中。 表3.3標(biāo)志位操作指令 指 令 格 式功 能 說(shuō) 明 CLCCF=0,進(jìn)位標(biāo)志位置0STCCF=1,進(jìn)位標(biāo)志位置1CMC進(jìn)位標(biāo)志位求反CLDDF=0,方向標(biāo)志位置0STDDF=1,方向標(biāo)志位置1CLIIF=0,中斷標(biāo)志位置0,使CPU禁止響應(yīng)外部中斷STIIF=1,中斷標(biāo)志位置1,使CPU允許響應(yīng)外部中斷 這些指令僅對(duì)有關(guān)狀態(tài)標(biāo)志位執(zhí)行操作,而對(duì)其他狀態(tài)標(biāo)志位則沒(méi)有影響。2. CPU控制指令1) 處理器暫停指令指令格式: HLT HLT指令使CPU進(jìn)入暫停狀態(tài),這時(shí)CPU不進(jìn)行任何操作。當(dāng)CPU發(fā)生復(fù)位(RESET)或來(lái)自外部的中斷(NMI或 INTR)時(shí),CPU脫離暫停狀態(tài)。HLT指令不影響標(biāo)志位。HLT指令可用于程序中等待中斷。當(dāng)程序中必須等待中斷時(shí),可用HLT,而不必用軟件死循環(huán)。然后,中斷使CPU脫離暫停狀態(tài),返回執(zhí)行HLT的下一條指令。注意: 該指令在PC中將引起所謂的“死機(jī)”,一般的應(yīng)用程序不要使用。2) 處理器等待指令指令格式: WAIT WAIT指令在8086/8088的測(cè)試輸入引腳為高電平無(wú)效時(shí),使CPU進(jìn)入等待狀態(tài),這時(shí),CPU并不做任何操作; 測(cè)試為低電平有效時(shí),CPU脫離等待狀態(tài),繼續(xù)執(zhí)行WAIT指令后面的指令。WAIT指令不影響標(biāo)志位。浮點(diǎn)指令經(jīng)由8086/8088 CPU處理發(fā)往8087,并與8086/8088本身的整數(shù)指令在同一個(gè)指令序列; 而8087執(zhí)行浮點(diǎn)指令較慢,所以8086/8088必須與8087保持同步。8086/8088就是利用WAIT指令和測(cè)試引腳實(shí)現(xiàn)與8087同步運(yùn)行的。3) 處理器交權(quán)指令指令格式: ESCEXTOPRD,OPRD 其中,EXTOPRD為外部操作碼(浮點(diǎn)指令的操作碼),是一個(gè)6位立即數(shù); OPRD為源操作數(shù),可以是寄存器或內(nèi)存單元。當(dāng)OPRD為寄存器時(shí),它的編碼也作為操作碼; 如果為存儲(chǔ)器操作數(shù),CPU讀出這個(gè)操作數(shù)送給協(xié)處理器。交權(quán)指令ESC把浮點(diǎn)指令交給浮點(diǎn)處理器執(zhí)行。為了提高系統(tǒng)的浮點(diǎn)運(yùn)算能力,8086/8088系統(tǒng)中可加入浮點(diǎn)運(yùn)算協(xié)處理器8087。但是,8087的浮點(diǎn)指令是和8086/8088的整數(shù)指令組合在一起的,8086/8088主存中存儲(chǔ)8087的操作碼及其所需的操作數(shù)。當(dāng)8086/8088發(fā)現(xiàn)是一條浮點(diǎn)指令時(shí),就利用ESC指令將浮點(diǎn)指令交給8087執(zhí)行。ESC指令不影響標(biāo)志位。4) 空操作指令指令格式: NOP NOP指令不執(zhí)行任何有意義的操作,但占用1字節(jié)存儲(chǔ)單元,空耗一個(gè)指令執(zhí)行周期。該指令常用于程序調(diào)試。例如,在需要預(yù)留指令空間時(shí)用NOP填充,代碼空間多余時(shí)也可用NOP填充,還可以用NOP指令實(shí)現(xiàn)軟件延時(shí)。事實(shí)上,NOP指令就是XCHGAX,AX指令,它們的代碼一樣。NOP指令不影響標(biāo)志位。5) 封鎖總線(xiàn)指令LOCK是一個(gè)指令前綴,可放在指令的前面。這個(gè)前綴使得在當(dāng)前指令執(zhí)行時(shí)間內(nèi),8086/8088 處理器的封鎖輸出引腳有效,即把總線(xiàn)封鎖,使別的控制器不能控制總線(xiàn),直到該指令執(zhí)行完后,總線(xiàn)封鎖解除。當(dāng)CPU與其他處理器協(xié)同工作時(shí),LOCK指令可避免破壞有用信息。6) 段超越前綴指令 SEG: ; 即CS: ,SS: ,DS: ,ES: ,取代默認(rèn)段寄存器 在允許段超越的存儲(chǔ)器操作數(shù)之前,使用段超越前綴指令,將不采用默認(rèn)的段寄存器,而是采用指定的段寄存器尋址操作數(shù)。3.2.7輸入/輸出類(lèi)指令輸入/輸出指令共有兩條。輸入指令I(lǐng)N用于從外設(shè)端口接收數(shù)據(jù),輸出指令OUT則向端口發(fā)送數(shù)據(jù)。無(wú)論是接收到的數(shù)據(jù)或是準(zhǔn)備發(fā)送的數(shù)據(jù)都必須在累加器AL(字節(jié))或AX(字)中,所以這是兩條累加器專(zhuān)用指令。輸入/輸出指令可以分為兩大類(lèi): 一類(lèi)是端口直接尋址的輸入/輸出指令; 另一類(lèi)是端口通過(guò)DX寄存器間接尋址的輸入/輸出指令。在直接尋址的指令中只能尋址256個(gè)端口(0~255),而間接尋址的指令中可尋址64K個(gè)端口(0~65535)。1. 輸入指令指令格式: INAL,n(AL)←(n) INAX,n (AX)←(n 1),(n) INAL,DX (AL)← [(DX)] INAX,DX (AX)← [(DX 1)],[(DX)] 其中,n為8位的端口地址,當(dāng)字節(jié)輸入時(shí),將端口地址n的內(nèi)容送至AL中; 當(dāng)字輸入時(shí),將端口地址n 1的內(nèi)容送至AH中,端口地址n的內(nèi)容送至AL中。端口地址也可以是16位的,但必須將16位的端口地址送入DX中。當(dāng)字節(jié)尋址時(shí),由DX內(nèi)容作端口地址的內(nèi)容送至AL中; 當(dāng)輸入數(shù)據(jù)字時(shí),[(DX 1)]送AH,[(DX)]送AL中,用符號(hào)(AX)← [(DX 1)],[(DX)]表示。指令舉例: INAL,20H 或: MOVDX,0400H INAL,DX 2. 輸出指令指令格式: OUTn,AL(n)←(AL) OUTn,AX(n 1),(n)←(AX) OUTDX,AL[(DX)]←(AL) OUTDX,AX[(DX 1)],[(DX)]←(AX) OUT指令中各個(gè)操作數(shù)的定義與IN指令相同。指令舉例: MOVAL,0FH OUT20H,AL 或: MOVDX,0400H MOVAL,86H OUTDX,AL 輸入/輸出指令對(duì)標(biāo)志位不產(chǎn)生影響。3.380x86指令系統(tǒng)介紹80x86系列微處理器指令系統(tǒng)保持向上兼容,如80486微處理器可兼容執(zhí)行8086、80286和80386的指令。在介紹了8086/8088指令系統(tǒng)的基礎(chǔ)上,本節(jié)講述80286、80386、80486和Pentium的新增指令以及在8086/8088基礎(chǔ)上擴(kuò)充的新的功能的一些指令。3.3.180x86尋址方式由于80x86系列CPU對(duì)8086/8088的指令是向上兼容的,因此此前所介紹的8086/8088的尋址方式也適用于80x86。下面介紹的尋址方式都是針對(duì)存儲(chǔ)器操作數(shù)的尋址方式,它們均與比例因子有關(guān),這些尋址方式只能用在80386及其后繼機(jī)型中,8086/8088/80286不支持這幾種尋址方式。在80386及其后續(xù)機(jī)型中,8個(gè)32位的通用寄存器EAX、EBX、ECX、EDX、ESP、EBP、ESI、EDI既可以存放數(shù)據(jù),也可以存放地址,也就是說(shuō),這些寄存器都可以用來(lái)提供操作數(shù)在段內(nèi)的偏移地址。1. 比例變址尋址方式操作數(shù)的有效地址是變址寄存器的內(nèi)容乘以指令中指定的比例因子再加上位移量之和,所以有效地址由3種成分組成。這種尋址方式與寄存器相對(duì)尋址相比,增加了比例因子,其優(yōu)點(diǎn)在于: 對(duì)于元素大小為2、4、8字節(jié)的數(shù)組,可以在變址寄存器中給出數(shù)組元素下標(biāo),而由尋址方式控制直接用比例因子把下標(biāo)轉(zhuǎn)換為變址值。例如: MOVEAX,COUNT[ESI×4] 假設(shè)(DS)=4000H,位移量為500H。如果要求把雙字?jǐn)?shù)組中的元素3送到EAX(EAX為32位累加器)中,用這種尋址方式可以直接在ESI中放入3,選擇比例因子4(數(shù)組元素為4字節(jié)長(zhǎng))就可以方便地達(dá)到目的,不必像在寄存器相對(duì)尋址方式中要把變址值直接裝入寄存器中。物理地址的計(jì)算如圖3.14所示。 圖3.14比例變址尋址方式 2. 基址比例變址尋址方式操作數(shù)的有效地址是變址寄存器的內(nèi)容乘以比例因子再加上基址寄存器的內(nèi)容,所以有效地址由3種成分組成。這種尋址方式與基址變址尋址方式相比,增加了比例因子,其優(yōu)點(diǎn)是很明顯的。例如: MOVECX,[EAX][EDX×8] 此例中,EAX作為基址,EDX作變址,比例因子為8。3. 相對(duì)基址比例變址尋址方式操作數(shù)的有效地址是變址寄存器的內(nèi)容乘以比例因子,加上基址寄存器的內(nèi)容,再加上位移量之和,所以有效地址由4種成分組成。這種尋址方式比相對(duì)基址變址尋址方式增加了比例因子,便于對(duì)元素為2、4、8字節(jié)的二維數(shù)組的處理。例如: MOVEAX,TABLE[EBP][EDI×4] 在此例中,EBP作為基址,EDI作變址,比例因子為4,位移量為T(mén)ABLE。3.3.280286指令系統(tǒng)新增指令80286指令系統(tǒng)除了包括所有的8086/8088指令外,新增指令以及增強(qiáng)了功能的指令列于表3.4中。其中,控制保護(hù)態(tài)指令是80286工作在保護(hù)模式下的一些特權(quán)方式指令,常用于操作系統(tǒng)及其他控制軟件中。保護(hù)模式是集實(shí)地址模式的能力、存儲(chǔ)器管理、對(duì)虛擬存儲(chǔ)器的支持和對(duì)地址空間的保護(hù)為一體而建立起來(lái)的一種特殊工作方式。 表3.480286增強(qiáng)與增加的指令 類(lèi)別增強(qiáng)的指令增加的指令 數(shù)據(jù)傳送類(lèi)PUSH 立即數(shù)PUSHA POPA算術(shù)運(yùn)算類(lèi)IMUL 寄存器,寄存器 IMUL 寄存器,存儲(chǔ)器 IMUL 寄存器,立即數(shù) IMUL 寄存器,寄存器,立即數(shù) IMUL 寄存器,存儲(chǔ)器,立即數(shù)續(xù)表 類(lèi)別增強(qiáng)的指令增加的指令 邏輯運(yùn)算與移位類(lèi)SHL 目的操作數(shù),立即數(shù)(1~31) 其余SAL、SAR、SHR、ROL、ROR、RCL、RCR 7條移位指令同SHL 串操作類(lèi)[REP]INS 目的串,DX [REP]OUTS DX,源串 [REP]INSB/OUTB [REP]INSW/OUTW高級(jí)語(yǔ)言BOUND 寄存器,存儲(chǔ)器 ENTER 立即數(shù)16,立即數(shù) LEAVE 保護(hù)模式的系統(tǒng)控制指令類(lèi)LAR(裝入訪(fǎng)問(wèn)權(quán)限)、LSL(裝入段界限)、LGDT(裝入全局描述符表)、SGDT(存儲(chǔ)全局描述符表)、LIDT(裝入8字節(jié)中斷描述符表)、SIDT(存儲(chǔ)8字節(jié)中斷描述符表)、LLDT(裝入局部描述符表)、SLDT(存儲(chǔ)局部描述符表)、LTR(裝入任務(wù)寄存器)、STR(存儲(chǔ)任務(wù)寄存器)、LMSW(裝入機(jī)器狀態(tài)字)、SMSW(存儲(chǔ)機(jī)器狀態(tài)字)、VERR(存儲(chǔ)器或寄存器讀校驗(yàn))、VERW(存儲(chǔ)器或寄存器寫(xiě)校驗(yàn))、ARPL(調(diào)整已請(qǐng)求特權(quán)級(jí)別)、CLTS(清除任務(wù)轉(zhuǎn)移標(biāo)志) 下面介紹80286指令系統(tǒng)中主要的新增及擴(kuò)展指令。1. 堆棧操作指令指令格式: PUSH16位立即數(shù) PUSH指令將16位立即數(shù)壓入堆棧,如果給出的數(shù)不夠16位,則自動(dòng)擴(kuò)展為16位后壓入堆棧。該指令不影響狀態(tài)標(biāo)志位。在8086/8088指令系統(tǒng)中,PUSH指令允許的操作數(shù)只能是兩字節(jié)的寄存器操作數(shù)或存儲(chǔ)器操作數(shù)。2. 通用寄存器入棧操作指令指令格式: PUSHA PUSHA指令將所有通用寄存器AX、CX、DX、BX、SP、BP、SI和DI的內(nèi)容按順序壓入堆棧,入棧的SP值是執(zhí)行該指令之前的SP值,在執(zhí)行完本指令后,SP值減16。3. 通用寄存器內(nèi)容出棧操作指令指令格式: POPA POPA指令將棧頂?shù)膬?nèi)容順序彈至DI、SI、BP、SP、BX、DX、CX和AX。SP中的值是堆棧中所有通用寄存器彈出后,堆棧指針實(shí)際指向的值(不是棧中保存的SP值),也即該指令執(zhí)行后SP的值,可以通過(guò)加16來(lái)恢復(fù)。4. 有符號(hào)整數(shù)乘法指令(兩個(gè)操作數(shù))指令格式: IMUL16位寄存器,立即數(shù) 有符號(hào)整數(shù)乘法指令I(lǐng)MUL將16位通用寄存器中的有符號(hào)數(shù)作為被乘數(shù),與有符號(hào)立即數(shù)相乘,乘積送回通用寄存器。若乘積超出有符號(hào)數(shù)的表示范圍(-32768~ 32767),除丟失溢出部分外,并將OF及CF置為1; 否則,將OF及CF置為0。5. 有符號(hào)整數(shù)乘法指令(3個(gè)操作數(shù))指令格式: IMUL16位寄存器,16位存儲(chǔ)器,立即數(shù) 該指令與上一條指令功能類(lèi)似,區(qū)別僅在于,將16位存儲(chǔ)器操作數(shù)作為被乘數(shù)與立即數(shù)相乘,結(jié)果送16位寄存器。6. 移位指令8086/8088中有8條移位指令,移位計(jì)數(shù)使用CL或1表示,且規(guī)定當(dāng)移位次數(shù)大于1時(shí),必須使用CL。在80286中,將上述限制修改為當(dāng)移位次數(shù)為1~31次時(shí),允許使用立即數(shù)。7. 串輸入/輸出指令I(lǐng)NS/OUTS指令格式: [REP]INS目的串,DX [REP]OUTSDX,源串 [REP]INSB [REP]OUTB [REP]INSW [REP]OUTW 串輸入/輸出指令可以帶兩個(gè)操作數(shù),也可以采用默認(rèn)操作數(shù)形式,指令中不指出操作數(shù),但要在指令助記符中用B或W指明輸入/輸出的數(shù)據(jù)串是字節(jié)還是字。該類(lèi)指令可以實(shí)現(xiàn)DX指定的端口與由指定的內(nèi)存地址之間的數(shù)據(jù)塊傳送,其類(lèi)型可以是字節(jié)或字。如果加重復(fù)前綴REP,完成整個(gè)串的輸入/輸出操作,這時(shí)CX寄存器中為重復(fù)前綴操作的次數(shù)。8. 內(nèi)存范圍檢查指令指令格式: BOUND16位寄存器,32位存儲(chǔ)器 BOUND指令以32位存儲(chǔ)器低兩字節(jié)的內(nèi)容為下界,高兩字節(jié)的內(nèi)容為上界。若16位寄存器的內(nèi)容在此上、下界表示的地址范圍內(nèi),程序正常執(zhí)行; 否則產(chǎn)生INT 5中斷。當(dāng)出現(xiàn)這種中斷時(shí),返回地址指向BOUND指令,而不是BOUND后面的指令,這與返回地址指向程序中下一條指令的正常中斷是有區(qū)別的。9. 設(shè)置堆棧空間指令格式: ENTER16位立即數(shù),8位立即數(shù) 在ENTER指令中,兩個(gè)操作數(shù)中的16位立即數(shù)表示堆?臻g的大小,也即表示給當(dāng)前過(guò)程分配多少字節(jié)的堆?臻g,8位立即數(shù)指出在高級(jí)語(yǔ)言?xún)?nèi)調(diào)用自身的次數(shù),也即嵌套層數(shù)。值得注意的是該指令使用BP寄存器而非SP作為;。10. 撤銷(xiāo)堆?臻g指令指令格式: LEAVE LEAVE指令撤銷(xiāo)由ENTER指令建立的堆?臻g。例如: TASKPROC NEAR ENTER400,8; 建立堆棧空間為400字節(jié),允許過(guò)程嵌套8層 … LEAVE ; 釋放堆?臻g RET TASKENDP 3.3.380386指令系統(tǒng)新增指令80386指令系統(tǒng)包括了所有80286指令,并對(duì)80286的部分指令進(jìn)行了功能擴(kuò)充,還新增了一些指令,特別指出的是,80386提供了32位尋址方式,可對(duì)32位數(shù)據(jù)直接操作。所有16位指令均可擴(kuò)充為32位指令。表3.5列出了80386增強(qiáng)及增加的指令。 表3.580386增強(qiáng)與增加的指令 類(lèi)別增強(qiáng)的指令增加的指令 數(shù)據(jù)傳送類(lèi)PUSH 立即數(shù) PUSHAD/POPAD PUSHFD/POPFDMOVSX 寄存器,寄存器/存儲(chǔ)器 MOVZX 寄存器,寄存器/存儲(chǔ)器 算術(shù)運(yùn)算類(lèi)IMUL 寄存器,寄存器/存儲(chǔ)器 IMUL 寄存器,寄存器/存儲(chǔ)器,立即數(shù) CWDE CDQ邏輯運(yùn)算與移位類(lèi)SHLD/SHRD 寄存器/存儲(chǔ)器,寄存器,CL/立即數(shù)串操作類(lèi)所有串操作指令后面擴(kuò)展D,如MOVSD、OUTD等位操作類(lèi)BT/BTC/BTS/BTR 寄存器/存儲(chǔ)器,寄存器/立即數(shù) BSF/BSR 寄存器,寄存器/存儲(chǔ)器條件設(shè)置類(lèi)SET條件 寄存器/存儲(chǔ)器 下面介紹80386指令系統(tǒng)中主要的新增及擴(kuò)展指令。1. 數(shù)據(jù)傳送與擴(kuò)展指令1) MOVSX指令格式: MOVSX寄存器,寄存器/存儲(chǔ)器 MOVSX指令將源操作數(shù)傳送到目的操作數(shù)中。目的操作數(shù)可以是16位或32位寄存器; 源操作數(shù)可以是寄存器或存儲(chǔ)器操作數(shù),其位數(shù)應(yīng)小于或等于目的操作數(shù)的位數(shù)。當(dāng)源操作數(shù)的位數(shù)少于目的操作數(shù)時(shí),目的操作數(shù)的高位用源操作數(shù)的符號(hào)位填補(bǔ)。此指令適用于有符號(hào)數(shù)的傳送與擴(kuò)展。2) MOVZX指令格式: MOVZX寄存器,寄存器/存儲(chǔ)器 MOVZX指令與MOVSX功能基本相同,唯一區(qū)別的是當(dāng)源操作數(shù)的位數(shù)少于目的操作數(shù)位數(shù)時(shí),目的操作數(shù)的高位補(bǔ)“0”。該指令適用于無(wú)符號(hào)數(shù)的傳送與擴(kuò)展。2. 堆棧操作指令1) PUSH指令格式: PUSH32位立即數(shù) 該指令將32位立即數(shù)壓入堆棧。該指令執(zhí)行后SP的值將減4。2) PUSHAD指令格式: PUSHAD 該指令將所有通用寄存器EAX、ECX、EDX、EBX、ESP、EBP、ESI和EDI的內(nèi)容順序壓入堆棧,其中壓入堆棧的ESP是該指令執(zhí)行前ESP的值。執(zhí)行該指令后,ESP的值減32。3) POPAD指令格式: POPAD 該指令將當(dāng)前棧頂內(nèi)容順序彈至EDI、ESI、EBP、ESP、EBX、EDX、ECX和EAX,但是最終ESP的值為彈出操作對(duì)堆棧指針調(diào)整后的值(而不是堆棧中保存的ESP的值)。即執(zhí)行該指令后ESP的值,可以通過(guò)增加32來(lái)恢復(fù)。4) PUSHFD指令格式: PUSHFD 該指令將32位標(biāo)志寄存器EFLAGS的內(nèi)容壓入堆棧。5) POPFD指令格式: POPFD 該指令將當(dāng)前棧頂?shù)?字節(jié)內(nèi)容彈至EFLAGS寄存器。3. 有符號(hào)數(shù)乘法指令1) 兩操作數(shù)乘法指令指令格式: IMUL寄存器,寄存器/存儲(chǔ)器 該指令將16位或32位通用寄存器中的有符號(hào)數(shù)作為被乘數(shù),相同位數(shù)通用寄存器或存儲(chǔ)單元中的有符號(hào)數(shù)作為乘數(shù),乘積送目的操作數(shù)。若乘積溢出,溢出位部分將丟失,且將OF及CF置1; 否則將OF及CF清0。2) 三操作數(shù)乘法指令指令格式: IMUL寄存器,寄存器/存儲(chǔ)器,立即數(shù) 該指令與前一個(gè)指令功能基本相同,唯一區(qū)別在于,寄存器/存儲(chǔ)器為被乘數(shù),立即數(shù)為乘數(shù),乘積存放在第一個(gè)操作數(shù)中。3) 符號(hào)擴(kuò)展指令該指令將AX中16位有符號(hào)數(shù)的符號(hào)位擴(kuò)展到EAX的高16位中,即把AX的16位有符號(hào)數(shù)擴(kuò)展為32位后,送EAX。4) 符號(hào)擴(kuò)展指令該指令將EAX中32位有符號(hào)數(shù)擴(kuò)展到EDX: EAX寄存器中,使之成為64位有符號(hào)數(shù),即將EAX中的符號(hào)位擴(kuò)展到EDX中。4. 移位指令80386中新增加了一組移動(dòng)多位的指令。它們可以把指定的一組位左移或右移到一個(gè)操作數(shù)中。1) SHLD指令格式: SHLD寄存器/存儲(chǔ)器,寄存器,CL/立即數(shù) 該指令將第一操作數(shù)(16位或32位)左移若干位(由8位立即數(shù)或CL指定),空出位用第二操作數(shù)(與第一操作數(shù)等位寬)高位部分填補(bǔ),但第二操作數(shù)的內(nèi)容不變,CF標(biāo)志位中保留第一操作數(shù)最后的移出位。若僅移一位,當(dāng)CF值與移位后的第一操作數(shù)的符號(hào)位不一致時(shí),OF置1; 否則OF清0。SHLD指令操作示意圖如圖3.15所示。2) SHRD指令格式: SHRD寄存器/存儲(chǔ)器,寄存器,CL/立即數(shù) 該指令將第一操作數(shù)(16位或32位)右移若干位(由8位立即數(shù)或CL指定),空出位用第二操作數(shù)(與第一操作數(shù)等位寬)低位部分填補(bǔ),指令執(zhí)行后,第二操作數(shù)的內(nèi)容不變,CF標(biāo)志位中保留第一操作數(shù)最后的移出位。SHRD指令操作示意圖如圖3.16所示。 圖3.15SHLD指令功能示意圖 圖3.16SHRD指令功能示意圖 5. 位操作指令1) 位測(cè)試及設(shè)置指令測(cè)試指令可用來(lái)對(duì)指定位進(jìn)行測(cè)試,因而可根據(jù)該位的值來(lái)控制程序流的執(zhí)行方向,而置位指令可對(duì)指定的位進(jìn)行設(shè)置。指令格式及功能如表3.6所示。 表3.6位測(cè)試與設(shè)置指令 指 令 格 式功能 BT 寄存器/存儲(chǔ)器,寄存器/立即數(shù)第一操作數(shù)指定要測(cè)試的內(nèi)容(16位或32位),第二操作數(shù)(與第一操作數(shù)同長(zhǎng)度的通用寄存器或8位立即數(shù))指定要測(cè)試的位,將被測(cè)內(nèi)容的指定測(cè)試位的值送CF BTC 寄存器/存儲(chǔ)器,寄存器/立即數(shù)在BT指令功能的基礎(chǔ)上,將被測(cè)試位取反BTR 寄存器/存儲(chǔ)器,寄存器/立即數(shù)在BT指令功能的基礎(chǔ)上,將被測(cè)試位清0BTS 寄存器/存儲(chǔ)器,寄存器/立即數(shù)在BT指令功能的基礎(chǔ)上,將被測(cè)試位置1 2) 位掃描指令位掃描指令用于找出寄存器或存儲(chǔ)器地址中所存數(shù)據(jù)的第一個(gè)或最后一個(gè)是1的位。該指令可用于檢查寄存器或存儲(chǔ)單元是否為0。BSF和BSR指令格式及功能如表3.7所示。 表3.7位掃描指令 指 令 格 式功能 BSF 寄存器,寄存器/存儲(chǔ)器對(duì)第二操作數(shù)(16位或32位通用寄存器或存儲(chǔ)器)從最低位到最高位進(jìn)行掃描,將首先掃描到“1”的位號(hào)送第一操作數(shù),且使ZF=0。若第二操作數(shù)的各位均為0,則第一操作數(shù)的值不確定,且使ZF=1BSR 寄存器,寄存器/存儲(chǔ)器與BSF指令功能基本相同,唯一區(qū)別的是該指令從最高位到最低位進(jìn)行掃描 6. 條件設(shè)置指令指令格式: SET條件寄存器/存儲(chǔ)器 這是80386特有的指令,用于測(cè)試指定的標(biāo)志位所處的狀態(tài),并根據(jù)測(cè)試結(jié)果,將指定的一個(gè)8位寄存器或內(nèi)存單元置1或清0。它們類(lèi)似于條件轉(zhuǎn)移指令中的標(biāo)志位測(cè)試,但前者根據(jù)測(cè)試結(jié)果將操作數(shù)置1或清0,而后者根據(jù)測(cè)試結(jié)果決定轉(zhuǎn)移還是不轉(zhuǎn)移。指令中的條件是指令助記符的一部分,用于指定要測(cè)試的標(biāo)志位,如SETZ或SETNZ等。3.3.480486指令系統(tǒng)新增指令在80486微處理器中既包含有Cache存儲(chǔ)器,又包含有浮點(diǎn)運(yùn)算器,因此,新增了用于比較和對(duì)Cache、TLB進(jìn)行操作的指令以及比較完整的浮點(diǎn)操作指令。全部指令可分為13類(lèi),共計(jì)200多條。表3.8列出了80486新增加的指令。 表3.880486增加的指令 類(lèi)別指 令 格 式功能 數(shù)據(jù)傳送類(lèi)BSWAP reg32字節(jié)交換 算術(shù)運(yùn)算類(lèi) XADD 寄存器/存儲(chǔ)器,寄存器交換與相加CMPXCHG 寄存器/存儲(chǔ)器,寄存器比較與交換 Cache管理類(lèi)INVD WBINVD INVLPG這類(lèi)指令用于80486管理CPU內(nèi)部的8KB Cache 下面介紹80486指令系統(tǒng)中新增的指令。1. 字節(jié)交換指令指令格式: BSWAPreg32 該指令可以實(shí)現(xiàn)雙字交換。使32位寄存器中的操作數(shù)按字節(jié)首尾交換,即D31~D24與D7~D0交換,D23~D16與D15~D8交換!纠3.33】[EAX]=01234567H,執(zhí)行以下指令,并分析結(jié)果。 BSWAPEAX 結(jié)果: [EAX]= 67452301H。2. 算術(shù)運(yùn)算指令指令格式: XADD寄存器/存儲(chǔ)器,寄存器 該指令將源操作數(shù)與目的操作數(shù)交換并相加,其中源操作數(shù)必須為寄存器,而目的操作數(shù)可以是寄存器也可以是內(nèi)存單元,然后相加,其結(jié)果存放在目的操作數(shù)中!纠3.34】設(shè)[EAX]= 12000001H,[EBX]= 30000002H,執(zhí)行以下指令,并分析結(jié)果。 XADD EAX,EBX 結(jié)果: [EAX]= 42000003H,[EBX]=12000001H。3. 比較與交換指令指令格式: CMPXCHG寄存器/存儲(chǔ)器,寄存器 該指令使用3個(gè)操作數(shù): 一個(gè)寄存器中的源操作數(shù)、一個(gè)寄存器或內(nèi)存儲(chǔ)器單元的目的操作數(shù)和一個(gè)隱含(不出現(xiàn)在用戶(hù)所書(shū)寫(xiě)的指令中)的累加器(AL/AX/EAX)。如果目的操作數(shù)與累加器的值相等,源操作數(shù)送目的單元,否則將目的操作數(shù)送累加器!纠3.35】設(shè)[EAX]=01010101H,[EBX]=02020202H,[ECX]=03030303H,執(zhí)行以下指令,并分析結(jié)果。 CMPXCHG ECX,EBX 結(jié)果: CF=0,[EAX]=03030303H,[EBX]=02020202H,[ECX]=03030303H。4. 作廢Cache指令指令格式: INVD INVD指令用于將Cache的內(nèi)容作廢。其具體操作是: 刷新內(nèi)部Cache,并分配一個(gè)專(zhuān)用總線(xiàn)周期刷新外部Cache。執(zhí)行該指令不會(huì)將外部Cache中的數(shù)據(jù)寫(xiě)回主存儲(chǔ)器。5. 寫(xiě)回和作廢Cache指令指令格式: WBINVD WBINVD指令先刷新內(nèi)部Cache,并分配一個(gè)專(zhuān)用總線(xiàn)周期將外部Cache的內(nèi)容寫(xiě)回主存儲(chǔ)器,并在此后的一個(gè)總線(xiàn)周期將外部Cache刷新。6. 作廢TLB項(xiàng)指令指令格式: INVLPG INVLPG指令用于使TLB中的某一項(xiàng)作廢。如果TLB中含有一個(gè)存儲(chǔ)器操作數(shù)映像的有效項(xiàng),則該TLB項(xiàng)被標(biāo)記為無(wú)效。3.3.5Pentium指令系統(tǒng)新增指令與80486相比,Pentium新增加了3條處理器專(zhuān)用指令和5條系統(tǒng)控制指令,但某些新增的指令是否有效與Pentium的型號(hào)有關(guān),可利用處理器特征識(shí)別指令CPUID判別處理器是否支持某些新增指令。表3.9列出了Pentium增加的指令。由于Pentium系列處理器的指令集是向上兼容的,因此所有早期的軟件可直接在Pentium機(jī)器上運(yùn)行。 表3.9Pentium增加的指令 類(lèi)別指 令 格 式含義操作 專(zhuān) 用 指 令 CMPXCHG8B 存儲(chǔ)器8字節(jié)比較與交換IF(EDX: EAX=D) ZF=1,D←ECX: EBX ELSE ZF=0,EDX: EAX←D CPUIDCPU標(biāo)識(shí)IF(EAX=0H) EAX,EBX,ECX,EDX←廠(chǎng)商信息 IF(EAX=1H) EAX,EBX,ECX,EDX←CPU信息 RDTSC讀時(shí)間標(biāo)記計(jì)數(shù)器EDX; EAX←時(shí)間標(biāo)記計(jì)數(shù)器 系 統(tǒng) 控 制 指 令 RDMSR讀模式專(zhuān)用寄存器EDX; EAX←MSR ECX=0H,MSR選擇MCA ECX=1H,MSR選擇MCT WRMSR寫(xiě)模式專(zhuān)用寄存器MSR←EDX; EAX ECX=0H,MSR選擇MCA ECX=1H,MSR選擇MCT RSM恢復(fù)系統(tǒng)管理模式 MOV CR4,寄存器 MOV 寄存器,CR4與CR4傳輸CR4←reg32 reg32←CR4 下面介紹Pentium指令系統(tǒng)中新增指令的功能。1. 處理器標(biāo)識(shí)指令指令格式: CPUID 使用該指令可以辨別微機(jī)中Pentium處理器的類(lèi)型和特點(diǎn)。在執(zhí)行CPUID指令前,EAX寄存器必須設(shè)置為0或1,根據(jù)EAX中設(shè)置值的不同,軟件會(huì)得到不同的標(biāo)志信息。2. 8字節(jié)比較交換指令指令格式: CMPXCHG8B存儲(chǔ)器 該指令帶有一個(gè)內(nèi)存儲(chǔ)器單元操作數(shù)。它能實(shí)現(xiàn)將EDX: EAX中的8字節(jié)值與指定的8字節(jié)存儲(chǔ)器操作數(shù)相比較,若相等,則使ZF=1,且將ECX: EBX中的值送指定的8字節(jié)存儲(chǔ)單元替換原有的存儲(chǔ)器操作數(shù); 否則使ZF=0,且將指定的8字節(jié)存儲(chǔ)器操作數(shù)送EDX: EAX。【例3.36】設(shè)[EAX]=01010101H,[EBX]=02020202H,[ECX]=03030303H,[EDX]=04040404H,而DS: 2000H所指的內(nèi)存單元開(kāi)始的8個(gè)連續(xù)單元的內(nèi)容為0404040401010101H。執(zhí)行以下指令,并分析結(jié)果。 CMPXCHG8B[2000H] 結(jié)果是將DS: 2000H所指單元開(kāi)始的8個(gè)字節(jié)和EDX: EAX中的8個(gè)字節(jié)比較,由于[EDX: EAX]中為0404040401010101H,而存儲(chǔ)器DS: [2000H]中開(kāi)始的8個(gè)字節(jié)也是0404040401010101H,因此ZF=1,并將ECX: EBX中的數(shù)送給DS: 2000H開(kāi)始的8個(gè)單元,使得DS: [2000H]開(kāi)始的8個(gè)字節(jié)為0303030302020202H。3. 讀時(shí)間標(biāo)記計(jì)數(shù)器指令指令格式: RDTSC Pentium處理器有一個(gè)片內(nèi)64位計(jì)數(shù)器,稱(chēng)為時(shí)間標(biāo)記計(jì)數(shù)器。計(jì)數(shù)器的值在每個(gè)時(shí)鐘周期都遞增,在RESET后該計(jì)數(shù)器被置0。執(zhí)行RDTSC指令可以將Pentium中的64位時(shí)間標(biāo)記計(jì)數(shù)器的高32位送EDX,低32位送EAX。一些應(yīng)用軟件需要確定某個(gè)事件已經(jīng)執(zhí)行了多少個(gè)時(shí)鐘周期,在執(zhí)行該事件之前和之后分別讀出時(shí)鐘標(biāo)志計(jì)數(shù)器的值,計(jì)算兩次值的差就可得出時(shí)鐘周期數(shù)。4. 讀模式專(zhuān)用寄存器指令指令格式: RDMSR 該指令使軟件可訪(fǎng)問(wèn)模式專(zhuān)用寄存器的內(nèi)容,這兩種模式專(zhuān)用寄存器是機(jī)器地址檢查寄存器(MCA)和機(jī)器類(lèi)型檢查寄存器(MCT)。若要訪(fǎng)問(wèn)MCA,指令執(zhí)行前需將ECX置為0; 而為了訪(fǎng)問(wèn)MCT,需要將ECX置為1。執(zhí)行指令時(shí)在訪(fǎng)問(wèn)的模式專(zhuān)用寄存器與寄存器組EDX: EAX之間進(jìn)行64位的操作。具體來(lái)說(shuō),是將ECX所指定的模式專(zhuān)用寄存器的內(nèi)容送EDX: EAX,高32位送EDX,低32位送EAX。5. 寫(xiě)模式專(zhuān)用寄存器指令指令格式: WRMSR 該指令將EDX: EAX的內(nèi)容送到由ECX指定的模式專(zhuān)用寄存器。具體來(lái)說(shuō),EDX和EAX的內(nèi)容分別作為高32位和低32位。若指定的模式寄存器有未定義或保留的位,則這些位的內(nèi)容不變。6. 恢復(fù)系統(tǒng)管理模式指令指令格式: RSM Pentium處理器有一種稱(chēng)為系統(tǒng)管理模式(SMM)的操作模式,這種模式主要用于執(zhí)行系統(tǒng)電源管理功能。外部硬件的中斷請(qǐng)求使系統(tǒng)進(jìn)入SMM模式,執(zhí)行RSM指令后返回原來(lái)的實(shí)模式或保護(hù)模式。7. 32位寄存器與CR4之間的傳輸指令指令格式: MOVCR4,reg32 MOVreg32,CR4 該指令實(shí)現(xiàn)將32位寄存器的內(nèi)容傳送至控制寄存器CR4或?qū)⒖刂萍拇嫫鰿R4的內(nèi)容送到32位寄存器中。思考與練習(xí)1. 什么叫尋址方式?8086/8088系統(tǒng)中關(guān)于存儲(chǔ)器操作數(shù)的尋址方式有哪幾類(lèi)?80386及后繼處理器支持的新增的存儲(chǔ)器尋址方式有哪幾種?2. 指令中數(shù)據(jù)操作數(shù)的種類(lèi)有哪些?3. 指出段地址、偏移地址與物理地址之間的關(guān)系。有效地址EA又是指什么?4. 在8086/8088系統(tǒng)中,能用于寄存器間接尋址及相對(duì)尋址的寄存器有哪些?它們通常與哪個(gè)段寄存器配合形成物理地址?5. 80x86指令系統(tǒng)中新增加的數(shù)據(jù)傳送類(lèi)指令有哪些?分析它們的功能。6. 什么是堆棧操作?以下關(guān)于堆棧操作的指令執(zhí)行后,SP的值是多少? PUSHAX PUSHCX PUSHDX POPAX PUSHBX POPCX POPDX 7. 用匯編語(yǔ)言指令實(shí)現(xiàn)以下操作。(1) 將寄存器AX、BX和DX的內(nèi)容相加,和放在寄存器DX中。(2) 用基址變址尋址方式(BX和SI)實(shí)現(xiàn)AL寄存器的內(nèi)容和存儲(chǔ)器單元BUF中的一個(gè)字節(jié)相加的操作,和放到AL中。(3) 用寄存器BX實(shí)現(xiàn)寄存器相對(duì)尋址方式(位移量為100H),將DX的內(nèi)容和存儲(chǔ)單元中的一個(gè)字相加,和放到存儲(chǔ)單元中。(4) 用直接尋址方式(地址為0500H)實(shí)現(xiàn)將存儲(chǔ)器中的一個(gè)字與立即數(shù)3ABCH相加,和放回該存儲(chǔ)單元中。(5) 用串操作指令實(shí)現(xiàn)將內(nèi)存定義好的兩個(gè)字節(jié)串BUF1和BUF2相加后,存放到另一個(gè)串BUF3中的功能。8. 指出下列指令中,源操作數(shù)及目的操作數(shù)的尋址方式。(1) SUBBX,[BP 35](2) MOVAX,2030H(3) SCASB(4) INAL,40H(5) MOV[DI BX],AX(6) ADDAX,50H[DI](7) MOVAL,[1300H](8) MULBL9. 已知(DS)=1000H,(SI)=0200H,(BX)=0100H,(10100H)=11H,(10101H)=22H,(10600H)=33H,(10601H)=44H,(10300H)=55H,(10301H)=66H,(10302H)=77H,(10303H)=88H,試分析下列各條指令執(zhí)行完后AX寄存器的內(nèi)容。(1) MOVAX,2500H(2) MOVAX,500H[BX] (3) MOVAX,[300H](4) MOVAX,[BX](5) MOVAX,[BX][SI](6) MOVAX,[BX SI 2]10. 判斷下列指令是否有錯(cuò),如果有錯(cuò),說(shuō)明理由。(1) SUBBL,BX(2) MOVBYTE PTR[BX],3456H(3) SHLAX,CH(4) MOVAH,[SI][DI](5) SHRAX,4(6) MOVCS,BX(7) MOV125,CL(8) MOVAX,BYTE PTR[SI](9) MOV[DI],[SI]11. 設(shè)(DS)=1000H,(ES)=2000H,(SS)=3000H,(SI)=0080H,(BX)=02D0H,(BP)=0060H,試指出下列指令的源操作數(shù)字段是什么尋址方式?它的物理地址是多少?(1) MOVAX,0CBH(2) MOVAX,[100H](3) MOVAX,[BX](4) MOVAX,[BP](5) MOVAX,[BP 50](6) MOVAX,[BX][SI] 12. 分別說(shuō)明下列每組指令中的兩條指令的區(qū)別。(1) ANDCL,0FHORCL,0FH(2) MOVAX,BXMOVAX,[BX](3) SUBBX,CXCMPBX,CX(4) ANDAL,01HTESTAL,01H(5) JMPNEAR PTR NEXTJMPSHORT NEXT(6) ROLAX,CLRCLAX,CL(7) PUSHAXPOPAX13. 試分析以下程序段執(zhí)行完后BX的內(nèi)容為何? MOVBX,1030H MOVCL,3 SHLBX,CL DECBX 14. 寫(xiě)出下列指令序列中每條指令的執(zhí)行結(jié)果,并在DEBUG環(huán)境下驗(yàn)證,注意各標(biāo)志位的變化情況。 MOVBX,126BH ADDBL,02AH MOVAX,2EA5H ADDBH,AL SBBBX,AX ADCAX,26H SUBBH,-8 15. 編寫(xiě)能實(shí)現(xiàn)以下功能的程序段。根據(jù)CL中的內(nèi)容決定程序的走向,設(shè)所有的轉(zhuǎn)移都是短程轉(zhuǎn)移。若D0位等于1,其他位為0,轉(zhuǎn)向LAB1; 若D1位等于1,其他位為0,轉(zhuǎn)向LAB2; 若D2位等于1,其他位為0,轉(zhuǎn)向LAB3; 若D0、D1、D2位都是1,則順序執(zhí)行。
你還可能感興趣
我要評(píng)論
|