微機系統(tǒng)與接口:匯編語言程序設計完整版_第1頁
微機系統(tǒng)與接口:匯編語言程序設計完整版_第2頁
微機系統(tǒng)與接口:匯編語言程序設計完整版_第3頁
微機系統(tǒng)與接口:匯編語言程序設計完整版_第4頁
微機系統(tǒng)與接口:匯編語言程序設計完整版_第5頁
已閱讀5頁,還剩70頁未讀 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

匯編語言程序設計內容匯編語言源程序的格式偽操作命令DOS及BIOS功能調用

計算機程序設計語言的演變

1.機器語言

直接用機器指令來編制計算機程序的方法。2.匯編語言

可以用助記符來表示指令的操作和操作數,也可以用標號和符號來代替地址、常量和變量。3.高級語言

更接近于人們的自然語言和習慣的教學語言來描述算法的執(zhí)行過程,從而使編寫的過程更加直觀和簡練。為什么要用匯編語言匯編語言非常接近機器語言程序,通過編制匯編語言程序,可以清楚地了解計算機的工作過程。

現在的微機系統(tǒng)中,底層的一些功能仍然靠匯編語言程序來實現。

匯編語言程序的效率通常高于高級語言程序。舉例

data

SEGMENTmsg

DB

'Hello,World!$'data

ENDScode

SEGMENT

ASSUME

CS

:

code

,

DS

:

dataMAIN PROCNEARstart:

MOV

AX

,

data

MOV

DS

,

AX

LEA

DX,

msg

MOV

AH,

9h

INT

21h

MOV

AX

,

4C00h

INT

21hMAIN ENDPcode

ENDS

END

start數據段代碼段在屏幕上顯示Hello,World!本例將在下文中多次提及,

為方便計,下文簡稱其為“Hello例”。結束語句分析1—分段結構可以看出,匯編語言源程序是分段結構的形式。

一個匯編源程序由若干個段(Segment)組成。

每個段以SEGMENT語句開始,以ENDS結束。

整個源程序以END語句結尾。

這里所說的匯編語言源程序的段和第一章中的CPU管理的存儲器的段是不同的概念。

匯編語言的段是邏輯段;8086CPU管理的存儲器的段是物理段(共有4個:數據段、附加段、堆棧段、代碼段,對應4個段寄存器:DS、ES、SS和CS)。

一個匯編語言源程序中可以有多個邏輯段。

上例中共有兩個邏輯段:data和code。分析2注: 功能號09H的int21中斷功能描述:輸出一個字符串到標準輸出設備上。入口參數:AH=09H DS:DX=待輸出字符的地址說明:待顯示的字符串以’$’作為其結束標志代碼段開頭執(zhí)行了一次功能號09H的21號DOS中斷,用于在屏幕上顯示字符串。關于DOS功能調用,后文將有詳細解釋。此處先列出功能號09H的21號DOS中斷的相關資料:最后兩行(MOVAX,4C00h、INT21h)也是一個DOS功能調用。注: 功能號4CH的int21中斷功能描述:終止程序的執(zhí)行,并可返回一個代碼入口參數:AH=4CH

AL=返回的代碼

匯編語言開發(fā)過程

源程序:文件名.asm目標程序:文件名.obj可執(zhí)行文件:文件名.exeFinish編輯器,如notepad.exe匯編程序,如masm.exe鏈接程序,如link.exe調試程序,如debug.exe開發(fā)工具

(了解)X86+Windows平臺下常用的匯編編譯器有:Microsoft公司的MASMBorland公司的TASM開源社區(qū)的NASMMASM是微軟推出的宏匯編語言,自發(fā)布以來已有多次版本更新,下頁表格中列出了幾個較為典型的版本。注:

容易與之混淆的是MASM32,它是SteveHutchesson以個人名義發(fā)布、基于MASM而構建的軟件包。其版本號和MASM的版本號是不同的,比如MASM32V8使用的匯編編譯器是MASM6。MASM32的最新版本為MASM32V12。MASM版本歷史(了解)

MASM4.00

最先廣泛使用的一個MASM版本,適用于DOS下的匯編編程MASM5.00

開始支持.code.data寫法的段定義格式(即“簡化段定義格式”)MASM6.001992年發(fā)布,可執(zhí)行文件名從Masm.exe改為Ml.exe

開始支持.if/.endif這樣的高級語法

開始支持invoke偽指令來簡化帶參數的子程序調用MASM6.152000年4月發(fā)布MASM8.00隨VS2005一起發(fā)布開發(fā)工具

(了解)Masm5適合進行DOS程序開發(fā);Masm6以后的版本開始支持Win32程序開發(fā)。(微軟官方發(fā)布的Masm6所附的link.exe是SegmentedExecutableLinker,只能開發(fā)DOS程序;要進行Win32開發(fā)必須配備IncrementalLinker,該類型的link.exe可以從VisualStudio中獲取。開發(fā)Win32程序推薦使用MASM32開發(fā)包)開發(fā)步驟演示(了解)使用MASM5.0開發(fā)步驟演示(了解)使用MASM6.15ForDOS語句的類型匯編語言源程序中的語句主要有以下兩種類型:

指令性語句 指示性語句

指令性語句主要由CPU指令組成,對應實際的機器指令;

(比如“Hello例”中的MOV

DS

,

AX

)

指示性語句又稱偽操作語句,主要由偽操作指令組成。

(比如“Hello例”中的codeSEGMENT

)語句的組成匯編語言的語句可以有1~4個組成部分,如下所示:[名字]操作碼/偽操作碼[操作數][;注釋]帶方括號的部分表示可選項。以“Hello例”中的幾條語句為例:名字

操作碼

/偽操作碼操作數注釋dataSEGMENTmsgDB'Hello,World!$'start:MOVAX,dataENDstart語句的組成—名字名字在指令性語句中,名字是一個標號,實際上就是指令的符號地址。比如“start:MOVAX,data”中的start:。并非每條指令性語句都必須有標號。但如果有了這個標號,程序中其他地方就可引用這個標號,比如執(zhí)行跳轉或者CALL調用。指令性語句中的標號后面通常有一個冒號。標號有三種屬性:段、偏移量和類型。段屬性是定義標號的程序段的段地址。偏移量表示標號所在段的起始地址到定義該標號的地址之間的字節(jié)數。標號的類型有兩種:NEAR和FAR。前者可以在段內被引用,地址指針為兩個字節(jié);后者可以在其他段中被引用,地址指針為4個字節(jié)。語句的組成—名字在指示性語句中,名字可以是變量名、段名、過程名。比如“Hello例”中“dataSEGMENT”中的data是段名,“msgDB‘Hello,World!$‘”中的msg是變量名。指示性語句中的標號后面通常沒有冒號。變量也有三種屬性:段、偏移量和類型。段屬性是變量所代表的數據所在段的段地址。偏移量表示變量所在段的起始地址與變量的地址之間的字節(jié)數。變量的類型有:

BYTE、WORD、DWORD(四字節(jié))、QWORD(八字節(jié))和TBYTE(十字節(jié))等,表示數據區(qū)中存取操作對象的大小。語句的組成—操作碼/偽操作碼操作碼/偽操作碼在匯編語言中操作碼以助記符的形式存在。8086/8088CPU的助記符總共約有90多種,比如MOV、ADC等。關于所有的助記符,參見第二章指令系統(tǒng)。指示性語句中的DB、SEGMENT、ENDS、ASSUME、END等都是偽操作碼,而不是CPU指令的助記符。它們在程序中的作用是定義變量的類型、定義段以及命令匯編程序(masm.exe)結束匯編

等。它們是指示匯編程序(masm.exe)完成匯編,本身不產生對應的機器碼。關于偽操作碼的具體作用和使用方法,下文有專門章節(jié)討論。語句的組成—操作數操作數對于CPU指令,可能有單操作數和雙操作數,也可能無操作數;偽指令可能有更多個操作數。可以用作操作數的有:常數、寄存器、標號、變量和表達式。常數十進制數,如99D或99。后面加字母“D”,或者什么也不加。十六進制數,如64H,0F800H,后面加一個字母“H”;如果最高位數值不是0-9,前面要再加一個數字0。(以避免和寄存器名稱如“AH”沖突)ASCII常數,例如’A’、’8’、‘cat’,字符應該放在單引號中。語句的組成—操作數寄存器8086/8088的寄存器可以用作指令的操作數。8086/8088CPU的寄存器有:8位寄存器:AH、AL、BH、BL、CH、CL、DH、DL。16位寄存器:AX、BX、CX、DX、SI、DI、BP、SP、DS、ES、SS、CS。標號標號代表一條指令的符號地址,因此可以作為轉移、過程調用CALL以及循環(huán)控制LOOP等指令的操作數。比如“HELLO例”中“ENDstart”,start就是一個標號。語句的組成—操作數變量變量是存儲器中某個數據區(qū)的名字,因此在指令中可以作為存儲器操作數。如“Hello例”中的:LEA DX,msg

其中msg就是一個在數據區(qū)定義的變量(msgDB‘Hello,World!$’)。表達式匯編語言中的表達式按其性質可以分為兩種:數值表達式和地址表達式。數值表達式產生一個數值結果,只有大小,沒有屬性。地址表達式的結果不是一個單純的數值,它有三種屬性:段、偏移量和類型。語句的組成—操作數構成表達式必然有運算符。表達式中常用運算符有以下幾種:①算術運算符,如+、-、*、/和MOD(模除)這些算術運算符可用于數值表達式,運算結果是一個數值。在地址表達式中通常只使用其中的+和–兩種運算符。②邏輯運算符,如AND、OR、XOR和NOT 邏輯運算符只用于數值表達式中對數值進行按位邏輯運算。對地址進行邏輯運算是沒有意義的。不要把邏輯運算符如AND、OR、XOR和NOT等與同樣名稱的CPU指令相混淆。前者可對整常數進行按位邏輯運算,是在匯編時進行;后者的操作數可以是寄存器、存儲器和立即數,是在程序運行時由CPU執(zhí)行。比如:AND AL,01011010B ;這里的AND是指令助記符MOV AL,01011010BAND11110000B;這里的AND是邏輯運算符語句的組成—操作數③關系運算符如EQ(等于)、NE(不等)、LT(小于)、GT(大于)、LE(小于或等于)、GE(大于或等于)等。 參與關系運算的必須是兩個數值,或同一段中的兩個存儲單元地址,但運算結果只能是兩個特定的數值之一。當關系不成立(假)時,結果為0;當關系成立(真)時,結果為0FFFFH(-1)。例如:

MOV AX,4EQ3 ;關系不成立,故(AX)←0 MOVAX,4NE3 ;關系成立,故(AX)←0FFFFH語句的組成—操作數④分析運算符和合成運算符如OFFSET、SEG、TYPE、SIZE和LENGTH等;合成運算符有PTR、THIS、SHORT等。

分析運算符用以分析一個在存儲器操作數的屬性,如段、偏移量或類型等。合成運算符則可以規(guī)定存儲器操作數的某個屬性,例如類型。OFFSET用于獲取一個標號或變量的偏移地址,如:

MOV SI,OFFSETDATA1是將變量DATA1的偏移地址送至SI寄存器。其效果等同于:

LEASI,DATA1

語句的組成—操作數SEG用于獲取標號或變量的段址,如:

MOVAX,SEGARRAY MOVDS,AX是將變量ARRAY的段地址送入DS寄存器。TYPE的運算結果是一個數值,這個數值與存儲器操作數類型屬性的關系如下:

TYPE返回值操作數類型TYPE返回值操作數類型1BYTE-1NEAR2WORD-2FAR4DWORD語句的組成—操作數TYPE運算符的例子

VAR DW? ARRAY DD10DUP(?) STR DB‘Thisisatest’ MOV AX,TYPEVAR ;(AX)←2 MOV BX,TYPEARRAY ;(BX)←4 MOV CX,TYPESTR ;(CX)←1LENGTH如果一個變量已用重復操作符DUP說明其變量的個數,則利用LENGTH獲取這個變量的個數。如果未用DUP說明,則得到的結果為1。比如上例中,LENGTHARRAY

運算結果為10。

語句的組成—操作數SIZE如果一個變量已用重復操作符DUP說明,則利用SIZE運算符可得到分配給該變量的字節(jié)總數。如果未用DUP說明,則得到的結果是TYPE運算的結果。 比如上例中,SIZEARRAY

運算結果為10×4=40。由此可知,SIZE的運算結果等于LENGTH的運算結果乘以TYPE的運算結果。

PTR是一個合成運算符,用于指定存儲器操作數的類型。比如INCBYTEPTR[BX][SI],指令中利用PTR運算符明確規(guī)定存儲器操作數的類型為BYTE(字節(jié)),因此,本指令將一個8位存儲器的內容加1。語句的組成—操作數THIS也可以指定存儲器操作數的類型。使用THIS運算符可以使標號或變量的類型具有靈活性。例如要求對同一個數據區(qū),既可以字節(jié)作為單位,又可以字作為單位進行存取,則可以用以下語句:

AREAWEQUTHISWORD AREABDB100DUP(?)上面的AREAW和AREAB代表同一個數據區(qū),其中共有100個字節(jié),但AREAW的類型為WORD,而AREAB的類型為BYTE。SHORT指定一個標號的類型為SHORT(短標號),即標號到引用標號的指令間的距離在-128~127之間。短標號可用于無條件轉移和條件轉移指令中。使用短標號的指令比使用默認的近標號的指令少一個字節(jié)。語句的組成—操作數方括號[]間接尋址指令的存儲器操作數要在寄存器名BX、BP、SI或DI外面加上方括號,以表示存儲器地址。又如,變址尋址指令的存儲器操作數既要用算術運算符將SI或DI與一個位移量做運算,又要在外面加上方括號來表示存儲器地址。

MOV CL,[BX] MOV AL,[SI+5]段超越運算符“:”是“:”(冒號)跟在段寄存器名(DS、ES、SS或CS)之后表示段超越,用以給一個存儲器操作數指定一個段屬性,而不管其原來隱含的段是什么。例如:

MOVAX,ES:[DI]HIGH和LOW獲取一個數值或地址表達式的高位和低位字節(jié)。

STUFF EQU0ABCDH MOVAH,HIGHSTUFF;(AH)←0ABH MOVAL,LOWSTUFF;(AL)←0CDH語句的組成—操作數

如果一個表達式中同時具有多個運算符,那么按照以下規(guī)則進行運算:優(yōu)先級高的先運算,優(yōu)先級低的后運算;同一優(yōu)先級按表達式中從左到右的順序進行運算;圓括號可提升運算優(yōu)先級,圓括號內的運算符總是在其任何相鄰的運算之前進行。 各種運算符的優(yōu)先級順序如下頁圖表所示。表中同一行的運算符具有同等優(yōu)先級。語句的組成—操作數優(yōu)先級運算符優(yōu)先級運算符1LENGTH,SIZE,WIDTH,MASK,(),[],<>8+,-(二元運算符)2·(結構變量名后面的運算符)9EQ,NE,LT,LE,GT,GE3:(段超越預算符)10NOT4PTR,OFFSET,SEG,TYPE,THIS11AND5HIGH,LOW12OR,XOR6+,-(一元運算符)13SHORT7*,/,MOD,SHL,SHR高低語句的組成—注釋注釋和其他語言一樣,匯編語言中的注釋僅用于提高程序的可讀性。匯編語言中的注釋前面要求加上分號(;)。如果注釋內容較多,超過一行,則換行以后前面還要加上分號。注釋也可以從一行的最前面開始。匯編程序(masm.exe)對注釋不予理會,即注釋對匯編后產生的目標程序沒有任何影響。偽操作指令指示性語句中的偽操作指令,因其表示形式類似于CPU指令,故稱其為“偽指令”。偽指令與CPU指令的區(qū)別:CPU指令是給CPU的指令,對應CPU的特定操作,如加法運算;而偽指令是給匯編程序(masm.exe)的指令,指示匯編程序進行操作,比如定義段、定義數據。CPU指令在匯編后產生一一對應的目標代碼,偽指令不產生與之對應的目標代碼。下面列出“Hello例”的匯編源碼及其對應的機器碼

對比體會偽指令的作用。Hello,World!

的匯編源代碼Hello,World!

的機器代碼Hello,World!

機器代碼的分析可以看到,編譯后的機器代碼中,偽指令都已經不見了。原來的代碼段中每條指令性語句都對應一條機器碼。

匯編源代碼中的第一句MOVAX,data經編譯后變成MOVAX,1449。這是因為編譯器(masm.exe)將數據段放在1449:0000的位置。然后將DS:DX指向該位置,通過INT21的09H中斷將其顯示出來。資料回顧:

功能號09H的int21中斷功能描述:輸出一個字符串到標準輸出設備上。入口參數:AH=09H DS:DX=待輸出字符的地址說明:待顯示的字符串以’$’作為其結束標志Hello,World!

機器代碼的分析下圖使用d1449:0000顯示了數據段中的內容:偽操作指令宏匯編程序MASM提供了數十種偽操作。

(這里也揭示了操作碼和偽操作碼的另一個區(qū)別:

偽操作碼隨編譯器的不同而不同; 而操作碼隨CPU的不同而不同。)

根據偽操作的功能,大致可以分為下列幾類:偽操作指令分類偽操作類型舉例處理器方式偽操作.8086、.386數據定義偽操作DB、DW、DD、RECORD符號定義偽操作EQU、=、LABEL段定義偽操作SEGMENT/ENDS、ASSUME過程定義偽操作PROC/ENDP模塊定義與連接偽操作NAME、END、PUBLIC宏處理偽操作MACRO/ENDM、PURGE條件偽操作IF、IFE、IFDEF列表偽操作.LIST、TITLE、PAGE其他偽操作COMMENT、.RADIX處理器方式偽操作(了解)處理器方式偽操作用于指示匯編編譯器使用何種CPU的指令系統(tǒng)。常用的有以下幾種:

.8086

指示匯編程序只匯編8086/8088的指令系統(tǒng)。程序中若出現80286或80386的指令,則編譯會出錯。 如果程序中不定義任何處理器方式偽操作,則匯編程序默認即是.8086方式。

.386P

指示匯編程序匯編8086/8088以及所有80286和80386(包括保護方式和非保護方式)的指令。數據定義偽指令數據定義偽操作用于定義變量類型、給變量賦值。常用的有以下幾種: 數據定義偽操作的一般格式是:

[變量名]偽操作操作數[,操作數…]

操作數可以是常數、表達式或字符串,但每項操作數的值不能超過偽操作所定義的數據類型限定的范圍。操作符DBDWDDDQDT定義字節(jié)(1B)字

(2B)雙字(4B)四字(8B)十字節(jié)(10B)數據定義偽指令舉例:

DATA DB100,0FFH ;存入64H,FFH EXPR DB2*3+7 ;存入0DH STR DB‘WELCOME!’ ;存入8個字節(jié)

AB DB‘AB’ ;存入41H,42H BA DW‘AB’ ;存入42H,41H ABDD DD‘AB’ ;存入42H,41H,00,00 OFFAB DWAB ;存入變量AB的偏移地址

TOTAL DDAB ;依次存入變量AB的偏移地址和段地址

NUM DQ0011223344556677H ;依次存入77H,66H…00H見教材P148數據定義偽指令也可以使用“?”作為操作數,此時僅僅保留相應的存儲單元,而不賦予變量某個確定的初值。當同樣的操作數重復多次時,可使用重復操作符DUP,形式為:

nDUP(初值[,初值……])

圓括號內為重復的內容,n為重復的次數。 例如:ZERODW30DUP(0) BUFDB10DUP(?) DATDB5DUP(‘OK!’);存入5個‘OK!’,共15字節(jié)符號定義偽操作符號定義偽操作用于給一個符號重新命名,或定義新的類型屬性等。這里的符號可以是匯編語言中所用的變量名、標號名、過程名、記錄名、寄存器名以及指令助記符等。常用的符號定義偽操作有 EQU、=、LABELEQU

格式:

名字EQU表達式

作用:用名字代替一個數值,或一個較長的表達式。

舉例: HPIXEL EQU1024 VPIXEL EQU768 SCREEN EQUHPIXEL*VPIXEL符號定義偽操作=

格式:

名字=表達式

作用:類似EQU,區(qū)別在于“=”可以對一個名字重復定義。

舉例: COUNT=10 MOVCX,COUNT ;(CX)←10 COUNT=COUNT-1 MOVBX,COUNT; ;(BX)←9

LABEL

格式:

名字LABEL表達式

作用:定義標號或變量的類型。

舉例: AREAWLABELWORD MOVAREAW,AX ;AX送AREAW的第1、2字節(jié)中段定義偽操作段定義偽操作用于在匯編語言源程序中定義邏輯段。常用的段定義偽操作有SEGMENT/ENDS、ASSUMESEGMENT/ENDS

格式:

段名SEGMENT[定位類型][組合類型][‘類別’]

作用:定義一個邏輯段

舉例: STACKSEGMENT DB100DUP(?) STACKENDS

“定位類型”告訴編譯器如何確定邏輯段的邊界在存儲器中的位置,即對齊方式。有PARA、BYTE、WORD和PAGE四種。 “組合類型”告訴編譯器在裝入程序時各個邏輯段如何組合。 “類別”的作用是在連接時決定各邏輯段的裝入順序。段定義偽操作ASSUME

格式:

ASSUME

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

說明:將某一個段寄存器和某一個邏輯段進行關聯。 “段名”可以是曾用SEGMENT

操作符定義過的一個段 名,或是在一個標號或變量前面加上SEG

構成的表達式, 還可以是關鍵字NOTHING。

需要注意的是,ASSUME僅僅是通知編譯器有關段寄存器和邏輯段的關系,并沒有為段寄存器賦予實際的初值。

舉例:ASSUMECS:CODE,DS:DATA1,SS:STACK ASSUMEDS:SEGAREA1 ASSUMEES:NOTHING;取消前面ASSUME對ES的設置

過程定義偽操作過程定義偽操作命令為PROC/ENDP。

PROC/ENDP

格式:

過程名PROC[NEAR/FAR] … RET

過程名ENDP

作用:定義一個過程,賦予過程一個名字,并指出過程的類型,并指出該過程的類型是NEAR或FAR。如果沒有特別指明,則認為過程類型是NEAR。偽操作碼ENDP標志過程定義結束。 當定義一個過程后,程序中其他地方可以用CALL指令調用這個過程,或用轉移指令轉向這個過程,另外也可以順序執(zhí)行。調用的格式為:CALL過程名。過程定義偽操作過程名實際上是過程入口的符號地址,它和標號一樣,也有三種屬性:段、偏移量和類型。類型屬性可以是NEAR或FAR。類型為NEAR的過程可以在段內調用,類型為FAR的過程可以被其他段調用。過程的定義和調用均可嵌套。例如:

NAME1 PROCFAR CALLNAME2 RET NAME2 PROCNEAR RET NAME2 ENDP NAME1 ENDP模塊定義與連接偽操作(了解)在編寫規(guī)模較大的匯編語言程序時,可將程序劃分成幾個獨立的源程序模塊,分別進行匯編,最后統(tǒng)一連接。各個模塊之間可以相互進行符號訪問。命令為NAME、END、PUBLIC和EXTRN。

NAME

格式:

Name模塊名

作用:指定源文件匯編后的目標文件名稱END

格式:

END[標號]

作用:表示源程序到此結束,對于END后面語句不予理會模塊定義與連接偽操作(了解)PUBLIC

格式:

PUBLIC符號[,…]

作用:說明本模塊中的某些符號是公共的,即這些符號可以供將被連接在一起的其他模塊使用

說明:

“符號”可以是本模塊中定義的變量、標號或數值的名字,包括用PROC定義的過程名等。EXTRN

格式:

EXTRN名字:類型[,…]

作用:說明本模塊中所用的某些符號是外部的,即這些符號在將被連接在一起的其他模塊中定義(定義這些符號的模塊中還必須用PUBLIC說明)。宏處理偽操作如果在程序中需要多次使用一個程序段,可將其定義為宏。每次需要時,直接進行調用,稱為宏調用。

【利用過程(PROC)可以實現類似功能。

區(qū)別在于:宏在編譯時就插入每個宏調用處(這稱為“宏擴展”);而過程是在執(zhí)行時進行跳轉。過程具有更優(yōu)的空間效率,而宏則具有更優(yōu)的時間效率?!縈ACRO/ENDM

格式:

宏指令名MACRO ……;(宏定義體) ENDM

作用:將宏指令名定義為宏定義體中包含的程序段。宏處理偽操作宏定義偽操作允許帶參數,從而具有更強的通用性。例:定義一個宏,用于兩個壓縮的BCD數相加,結果放在第一個操作數中。

DECADD MACROOPR1,OPR2 MOVAL,OPR1 ADDAL,OPR2 DAA MOVOPR1,AL ENDM下面使用debug來觀察該例中“宏擴展”是如何進行的:源文件反匯編并執(zhí)行觀察結果DOS和BIOS調用(了解)DOS和BIOS為用戶提供了兩組系統(tǒng)服務程序。BIOS是IBMPC的基本IO系統(tǒng),包括系統(tǒng)測試程序、初始化引導程序、一部分中斷矢量裝入程序以及部分外設的服務程序。這些程序都固化在主板上的ROM中。DOS是IBMPC的操作系統(tǒng),負責管理系統(tǒng)的所有資源。其中包括大量可供用戶調用的服務程序。DOS和BIOS調用不是使用CALL命令,而采用軟中斷指令INTn。DOS和BIOS調用用戶程序控制PC機硬件的方式使用高級語言提供的功能控制硬件 調用方便,但靈活性較低、速度較慢。使用DOS提供的程序控制硬件 調用較為方便,程序可移植性好,編程簡單。使用BIOS提供的程序控制硬件 這種控制比較低層,因而可移植性差,但效率更高。直接訪問硬件 要求用戶對硬件非常熟悉。此種方式只用于兩種情況:為了獲得高效率,或是為了獲得DOS和BIOS不支持的功能。DOS調用8086指令系統(tǒng)中,有一條軟中斷指令INTn。當n=5~1FH時,調用BIOS服務程序;當n=20~3FH時,調用DOS服務程序。下表列出了部分DOS軟中斷的功能:中斷號功能INT20H程序正常退出INT21H系統(tǒng)功能調用INT22H結束退出……INT28H-2FHDOS專用INT21H調用其中INT21H是一個具有完整功能的服務程序,一般稱之為DOS系統(tǒng)功能調用。是最常用的DOS中斷。INT21H中斷具有近90個子功能,大致分為4個方面:設備管理、目錄管理、文件管理和其他。系統(tǒng)功能調用(INT21H)的使用步驟如下: 置系統(tǒng)功能號n(放入AH)

置入口參數 執(zhí)行INT21H

分析出口參數INT21H調用示例例:從鍵盤讀入一個字符,判斷是Y還是N,以執(zhí)行對應操作。

資料:功能號01H的int21H中斷功能描述:從標準輸入設備(如:鍵盤)讀入一個字符入口參數:AH=01H,過濾掉控制字符,并回顯出口參數:

AL

輸入字符的ASCII碼

KEY: MOV AH,1 INT 21H ;執(zhí)行調用

CMP AL,‘Y’ JE YES CMP AL,‘N’ JE NO JMP KEY ;輸入其他字符,退回繼續(xù)等待輸入

YES: …… NO: ……BIOS調用下面列出了部分BIOS中斷:中斷號功能INT09H鍵盤輸入INT10H顯示服務INT0EH磁盤驅動器輸入/輸出INT13H直接磁盤服務INT16H鍵盤服務

INT19H重啟系統(tǒng)關于BIOS中斷的所有中斷號內容(從05H~1FH),參見書附錄3.3BIOS調用BIOS調用的使用步驟如下: 置系統(tǒng)功能號n(放入AH)

置入口參數 執(zhí)行INTn

分析出口參數舉鍵盤輸入服務(INT16H)為例。其主要功能有三個,分別用于讀鍵盤、讀擴展鍵盤和讀取功能鍵,分別對應功能號0、1、2(AH=0、1、2)。

下面一段程序的功能是:按下F1和F2鍵,分別執(zhí)行兩段不同的程序,按其他鍵則轉至錯誤處理。INT16H調用示例資料:功能號00H的int16H中斷功能描述:從鍵盤讀入字符

入口參數:AH=00H

出口參數:

AH=鍵盤的掃描碼

AL=字符的ASCII碼 MOV AH,0 INT 16H ;執(zhí)行調用

CMP AL,0 JNE ERROR ;若為字符鍵,轉ERROR CMP AH,3BH ;F1鍵碼為3BH JE TT1 CMP AH,3CH ;F2鍵碼為3CH JE TT2 JMP ERR TT1: …… ;處理F1鍵功能TT2: …… ;處理F2鍵功能ERR: ……資料:鍵碼又稱鍵盤掃描碼,F1鍵碼為3BHF2鍵碼為3CHINT10H調用示例從上頁的例子中,可以看出,同樣的功能,往往既可以用BIOS中斷調用來實現,也可以用DOS中斷調用來實現。比如磁盤服務、鍵盤服務、顯示字符等。差別在于:BIOS中斷調用往往功能更強大、控制更靈活。例:INT10H功能號09H,“在當前光標位置顯示字符”。

MOV AH,9 ;顯示字符

MOVAL,‘a’ ;字符

MOVBL,0Ch ;0表示背景黑色,0Ch表示字符紅色

MOVBH,0 ;第0頁

MOVCX,8 ;字符重復個數

INT10hINT10H調用示例—運行結果提示:由于程序運行在“虛擬”的8086模式下,在操作硬件時跟純DOS仍存在一定差異。如果程序直接雙擊運行時結果跟預期不符,(比如窗口一閃而過)可使用debug加載然后輸入g運行。匯編語言設計舉例字符串查找內存中已經存有一張表,要求從鍵盤上輸入一個字符串,然后在表中查找該字符串,如有,則在屏幕上顯示“OK!”;如果沒有,則顯示“NO!”;若輸入字符串長度超過內存中表的長度,則顯示“Wrong!Thestringistoolong!”

邏輯分析: 查找可以分兩步進行,先在表中搜索字符串的第一個字符,如有,再比較字符串的其他字符是否一致。

功能可行性分析: 在屏幕上顯示字符串可以使用功能號09H的21號中斷; 從鍵盤上接受字符串可以使用功能號0AH的21號中斷。 教材P213/P178流程圖顯示提示符從鍵盤接收提示符字符串首址送SI,表首址送DI字符串長度送BX,表長度送CX表長>=串長搜索、匹配等工作開始返回顯示“串太長”具體見教材P214/P179資料1:功能號09H的int21H中斷功能描述:顯示字符串(串尾字符為$,但不顯示)入口參數: AH=09H

DS:DX=被顯示字符串的首地址出口參數:無data

SEGMENTmsg

DB

'Hello,World!$'data

ENDScode

SEGMENT

ASSUME

CS

:

code

,

DS

:

dataMAIN PROCNEARstart: MOV

AX

,

data

MOV

DS

,

AX

LEA

DX,

msg

MOV

AH,

9h INT

21h MOV

AH

,

4Ch INT

21hMAIN ENDPcode

ENDS

END

start例如:資料2:功能號0AH的int21H中斷功能描述:從標準輸入設備(如:鍵盤)讀入一個字符串,遇到“回車鍵”結束輸入。入口參數: AH=0AH

DS:DX=存放輸入字符的起始地址

接受輸入字符串緩沖區(qū)的定義說明:

1、第一個字節(jié)為緩沖區(qū)的最大容量;

2、第二個字節(jié)為實際輸入的字符數(不包括回車鍵);

3、從第三個字節(jié)開始存放實際輸入的字符串;

4、字符串以回車鍵結束,回車符是接受的最后一個字符;

5、若輸入的字符數超過緩沖區(qū)的最大容量,則多出的部分被丟棄, 直到輸入“回車”鍵才結束輸入。 例如:

BUFF

DB80,?,80DUP(?)

;最多接受80個字符(含回車符)出口參數:無源碼分析1DATA SEGMENTTABLE DB ‘ABCDEFGHIJKLMNOPQRSTUVWXYZ’STR1 DB ‘Please

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論