微機原理及應(yīng)用(第4章)_第1頁
微機原理及應(yīng)用(第4章)_第2頁
微機原理及應(yīng)用(第4章)_第3頁
微機原理及應(yīng)用(第4章)_第4頁
微機原理及應(yīng)用(第4章)_第5頁
已閱讀5頁,還剩60頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

微機原理及應(yīng)用楊杰王亭嶺主編李素萍張晉華許蘭貴胡鐵紅副主編郝用興主審第4章匯編語言程序設(shè)計

掌握偽指令的使用方法

理解匯編程序的段式結(jié)構(gòu)

掌握匯編程序的基本設(shè)計方法

學(xué)會匯編程序的調(diào)試方法學(xué)習(xí)目標:4.1匯編語言概述返回

程序設(shè)計語言是實現(xiàn)人機信息交換(對話)的基本工具,可分為機器語言、匯編語言、高級語言:

(1)機器語言(MachineLanguage)用二進制數(shù)表示指令和數(shù)據(jù)。它的優(yōu)點是執(zhí)行速度快,占用內(nèi)存少。缺點是不直觀,不易理解和記憶。因此編寫、閱讀和修改機器語言程序比較煩瑣。

(2)匯編語言(AssemblyLanguage)彌補了機器語言的不足,它用助記符來書寫指令、地址數(shù)據(jù),也可用符號進行表示。優(yōu)點:與機器語言相比,編寫、閱讀和修改程序都比較方便,不易出錯,且其程序的執(zhí)行速度和機器語言差不多,但需要用匯編程序?qū)ζ溥M行匯編。

(3)高級語言(HighLevelLanguage)不針對具體的計算機,通用性強。4.2匯編語言源程序的結(jié)構(gòu)及組成返回源程序的基本結(jié)構(gòu)匯編語言語句的類型和組成4.2.1源程序的基本結(jié)構(gòu)返回

一個匯編語言源程序是由若干個程序段組成的,這些程序段只能是數(shù)據(jù)段、堆棧段、附加段中的一個、若干個或者全部。在這些段中,代碼段是必不可少的。每個段以Segment語句開始,以Ends語句結(jié)束。整個源程序的結(jié)束用End語句。

匯編語言源程序中的段與前面討論的CPU管理的存儲器的段既有聯(lián)系又在概念上有所區(qū)別。由前述可知,微處理器對存儲器的管理是分段進行的,因而在匯編語言程序中也要求分段組織指令、數(shù)據(jù)和堆棧等,以便將源程序匯編成目標程序后可以分別裝入存儲器相應(yīng)的段中。以8086/8088微處理器為例,它有四個段寄存器(DS、ES、SS和CS),因此CPU對存儲器按照四個物理段進行管理,即數(shù)據(jù)段、附加段、堆棧段和代碼段。4.2.1源程序的基本結(jié)構(gòu)返回DATASEGMENT ;定義數(shù)據(jù)段ARRAYDB0,1,2,3,4,5,6 ;變量定義DATAENDSSSEGSEGMENTSTACK ;定義堆棧段DB100DUP(?) ;開辟堆??臻gSSEGENDSESEGSEGMENT ;定義附加段NUMDB‘HelloWorld!’ ;字符串定義ESEGENDSCODESEGMENT ;定義代碼段ASSUMECS:CODE,DS:DATA,SS:SSEG,ES:ESEGSTART:MOVAX,DATA ;初始化數(shù)據(jù)段MOVDS,AXMOVAX,SSEG ;初始化堆棧段MOVSS,AXMOVAX,ESEG ;初始化附加段MOVES,AX

……<偽指令語句系列>

……MOVAH,4CH ;返回操作系統(tǒng)INT21HCODEENDSENDSTART4.2.1源程序的基本結(jié)構(gòu)返回【例4.1】實現(xiàn)兩個十進制數(shù)求和的源程序。DATASEGMENT ;數(shù)據(jù)段開始XDB6 ;定義字節(jié)變量YDB126SUMDB? ;定義字節(jié)存儲空間DATAENDS ;數(shù)據(jù)段結(jié)束CODE SEGMENT ;代碼段開始ASSUMECS:CODE,DS:DATA ;指示段與段寄存器的關(guān)系

START:MOVAX,DATA ;給AX賦值MOVDS,AX ;設(shè)置DSMOVAL,XADDAL,Y ;實現(xiàn)X+YMOVSUM,AL ;結(jié)果存入SUM中MOVAH,4CH ;設(shè)置DOS功能調(diào)用功能號INT21H ;執(zhí)行DOS功能調(diào)用,返回DOSCODEENDS ;代碼段結(jié)束ENDSTART ;程序結(jié)束,表明源程序從START語句處開始執(zhí)行4.2.2匯編語言語句的類型和組成返回

總的來說,一個匯編語言源程序是由一行一行的語句組成的。匯編語言源程序中的語句主要有兩種類型:指令性語句、指示性語句。匯編語句一般由以下1~4部分組成,中括號內(nèi)為可選項。[名字]操作碼/偽指令[操作數(shù)][;注釋]

指令性語句簡稱指令語句,是能產(chǎn)生目標代碼的語句,這些目標代碼可供CPU執(zhí)行并完成特定操作,主要由指令組成。

例:START:MOVAX,DATA;給AX賦值

指示性語句又稱為偽操作語句,是一種不產(chǎn)生目標代碼的語句,它僅僅在匯編過程中告訴匯編程序應(yīng)如何匯編,主要由偽指令組成。

例:

XDB6;定義字節(jié)變量4.2.2匯編語言語句的類型和組成返回1.名字

匯編語言語句的第一個組成部分是名字(Name)。變量名、常量名、段名、宏名和過程名等統(tǒng)稱為名字。名字的命名規(guī)則如下。2.助記符和偽操作

匯編語言語句的第二個組成部分是助記符或偽操作(偽指令)。指令性語句中的第二部分是8086/8088CPU指令的助記符,共90余條。指示性語句中的第二部分是偽指令,偽指令在程序中的作用是定義變量類型、定義段及命令匯編程序結(jié)束匯編等。這些都是由匯編程序來完成的。3.操作數(shù)

匯編語言語句中的第三個組成部分是操作數(shù)(Operand)。對于CPU指令,可能有單操作數(shù)或雙操作數(shù),也可能是無操作數(shù),而偽指令則可能有多個操作數(shù),當操作數(shù)不止一個時互相之間用逗號隔開??梢宰鳛椴僮鲾?shù)的有常量、變量、標號、寄存器和表達式等。4.2.2匯編語言語句的類型和組成返回

(1)常量。

常量(Constant)是具有一定值的量,并且其值不能改變。匯編語言程序中的常量有數(shù)字常量、字符常量和符號常量。

(2)寄存器。8086/8088CPU中的寄存器可作為操作數(shù)。

(3)標號。

由于標號(Label)代表一條指令的符號地址,因此可作為轉(zhuǎn)移指令、過程調(diào)用和循環(huán)控制等指令的操作數(shù)。

(4)變量。

變量(Variable)通過數(shù)據(jù)定義偽指令進行定義,變量代表存儲器中某個數(shù)據(jù)區(qū)的名字,因此在指令中可作為存儲器操作數(shù)。

(5)表達式。

表達式(Expression)按性質(zhì)可分為兩種:數(shù)值表達式和地址表達式。數(shù)值表達式產(chǎn)生一個數(shù)值結(jié)果,只有大小,沒有屬性。地址表達式不只是一個單純的數(shù)值,而是一個表示存儲器地址的變量或標號,它有三種屬性:段、偏移量和類型。4.2.2匯編語言語句的類型和組成返回表達式中常用的運算符有以下幾種。(1)算術(shù)運算符。算術(shù)運算符可用于數(shù)值表達式,運算結(jié)果是一個數(shù)值。算術(shù)運算符有五種:“+”、“-”、“*”、“/”和MOD(求余)。MOD操作是將兩個整數(shù)相除后取余數(shù)。地址表達式中只能用“+”、“-”兩種運算符。例:NUMBERDB12H,34H,56H,78HMOVAX,NUMBER+1;NUMBER+1為地址表達式(2)邏輯運算符。邏輯運算符只用于數(shù)值表達式中對數(shù)值進行按位邏輯運算,并得到一個數(shù)值結(jié)果。邏輯運算符包括AND(與)、OR(或)、NOT(非)和XOR(異或)。表達式中的邏輯運算是在匯編過程中完成的,注意邏輯運算符與邏輯指令的區(qū)別。對地址進行邏輯運算無意義。例:CONSTEQU0FH;助記符中的AND在目標程序中執(zhí)行,表達式中的AND在匯編中執(zhí)行ANDAL,CONSTAND78H4.2.2匯編語言語句的類型和組成返回(3)關(guān)系運算符。關(guān)系運算符用于數(shù)的比較,關(guān)系運算符有EQ(等于)、NE(不等于)、LT(小于)、GT(大于)、LE(小于或等于)等。參與關(guān)系運算的必須是兩個數(shù)值,或同一個段中的兩個存儲單元地址,但運算結(jié)果只可能是兩個特定的數(shù)值之一:當關(guān)系成立時,結(jié)果為0FFFFH;當關(guān)系不成立時,結(jié)果為0。(4)分析運算符。分析運算符用于分析一個標號或存儲器操作數(shù)的屬性,如段、偏移量或類型等。合成運算符則可以規(guī)定操作數(shù)的某個屬性,如類型。①OFFSET。利用OFFSET可得到一個標號或變量的偏移地址。②SEG。利用運算符SEG可得到一個標號或變量的段值。③TYPE。運算符TYPE的運算結(jié)果是一個數(shù)值,這個數(shù)值與存儲器操作數(shù)類型屬性一一對應(yīng)。如果是變量,則匯編程序?qū)⒒厮驮撟兞恳宰止?jié)表示的類型:DB為1,DW為2、DD為4、DQ為8,DT為10。如果是標號,則匯編程序?qū)⒒厮痛碓摌颂栴愋偷臄?shù)值:NEAR為-1,F(xiàn)AR為-2。4.2.2匯編語言語句的類型和組成返回④LENGTH。如果一個變量已用DUP重復(fù)操作符說明其變量的個數(shù),則利用LENGTH運算符可得到變量的個數(shù)。非DUP定義的數(shù)據(jù),返回1。⑤SIZE。如果一個變量已用DUP說明,則利用SIZE運算符可得到分配給該位變量的字節(jié)數(shù)。顯然,SIZE=TYPE*LENGTH。(5)屬性運算符。屬性運算符用來建立或改變已定義變量、內(nèi)存操作數(shù)或標號的類型屬性。屬性運算符有PTR、THIS和是SHORT。①PTR。格式:類型PTR變量/標號,返回值:具有規(guī)定類型屬性的變量或標號。PTR在重新指定變量類型時使用。例:DATAWDW1122H,3344H,5566HMOVAX,DATAWMOVAX,BYTEPTRDATAW;臨時改變DATAW變量的字屬性為字節(jié)屬性PTR在指定內(nèi)存操作數(shù)的類型時使用。4.2.2匯編語言語句的類型和組成返回例:MOVAL,BYTEPTR[BX];內(nèi)存操作數(shù)為字節(jié)屬性MOVAX,WORDPTR[BX];內(nèi)存操作數(shù)為字屬性PTR與EQU一起定義一個新變量時使用。例:DATAWDW1122H,3344H,5566HDATABEQUBYTEPTRDATAW;變量DATAW和DATAB的起始地址相同MOVAX,DATAW

;進行字存取時可用變量DATAWMOVAL,DATAB;進行字節(jié)存取時可用變量DATAB②THIS。THIS可以像PTR一樣建立一個指定類型的地址操作數(shù),該操作數(shù)的段地址和偏移地址與緊靠它的下一個存儲單元地址相同。例:DATABEQUTHISBYTE;變量DATAB為字節(jié)類型DATAWDW1122H,3344H,5566H;變量DATAB和DATAW的起始地址相同③SHORT。SHORT用于JMP指令,指明是短轉(zhuǎn)移。4.2.2匯編語言語句的類型和組成返回(6)其他運算符。①方括號[]。

例:MOVAX,[1000H];方括號中的數(shù)據(jù)為有效地址,

;默認為數(shù)據(jù)段②段超越。例:MOVAX,ES:[1000H];讀取的數(shù)據(jù)在附加段中③字節(jié)分離運算符High、Low。High、Low將分別得到一個數(shù)值或地址表達式的高位和低位字節(jié)。4.注釋項

注釋項用來說明一段程序、一條或幾條指令的功能,此項為可選項,不會影響程序的執(zhí)行。對編程者而言,注釋項是一種“備忘錄”。好的注釋,使程序容易讀懂,便于維護。注釋前面應(yīng)加“;”號。4.3偽操作指令返回處理器方式偽指令數(shù)據(jù)定義偽指令符號定義偽指令段定義偽指令過程定義偽指令模塊定義和結(jié)束偽指令宏處理偽指令模塊連接偽指令4.3.1處理器方式偽指令返回

處理器方式偽指令用以設(shè)置CPU的方式。

處理器方式偽指令的格式是在處理器名稱前加一個點,如.8086,.8086偽指令將通知匯編程序只匯編8086/8088CPU的指令系統(tǒng)。此時若在源程序中出現(xiàn)80286或80386指令,將提示錯誤。如果不寫任何處理器方式偽指令,則匯編程序默認為.8086方式。

一般情況下,各種處理器方式偽指令置于整個匯編語言源程序的開關(guān),用以設(shè)定源程序的指令系統(tǒng)。4.3.2數(shù)據(jù)定義偽指令返回

數(shù)據(jù)定義偽指令的用途是定義一個變量的類型,給存儲器賦初值,或者僅僅給變量分配存儲單元,不賦予特定的值。數(shù)據(jù)定義偽指令有DB、DW、DD、DQ和DT,分別用來定義類型屬性為字節(jié)(DB)、字(DW)、雙字(DD)、4字(DQ)和5字(DT)。格式:[變量名]偽指令[操作數(shù)1,操作數(shù)2,…]功能:用來為數(shù)據(jù)分配存儲單元,建立變量與存儲單元之間的聯(lián)系。說明:①括號中的變量名為可選項,可以有也可以沒有;②變量名后面沒有冒號;③操作數(shù)可以不止一個,如有多個操作數(shù),用逗號隔開。注意:DW偽指令后面的操作數(shù)每個占兩個字節(jié)。在內(nèi)存中存放時,采用小端模式,即低位字節(jié)占用低地址,高位字節(jié)占用高地址,匯編時為每個操作數(shù)分配兩個存儲單元。4.3.3符號定義偽指令返回

符號定義偽指令是給一個符號重新命名或定義新的類型屬性等。上述符號是指匯編語言中的變量名、標號名、過程名、寄存器名及指令助記符等。常用的符號定義偽指令有EQU、“=”(等號)和LABEL。(1)EQU。格式:名字EQU表達式功能:用名字來代替表達式的值。說明:格式中的表達式可以是一個常數(shù)、符號、數(shù)值表達式或地址表達式。(2)“=”(等號)。格式:名字=表達式功能:用名字代替表達式的值。說明:“=”等號偽指令的功能與EQU偽指令基本相同,其主要區(qū)別在于它可以對同一個名字重復(fù)定義。4.3.3符號定義偽指令返回(3)LABEL。格式:變量/標號LABEL類型功能:定義變量或標號的類型,而變量或標號的段屬性和偏移量屬性由該語句所處的位置確定。說明:在定義中,若是變量,其類型可以是BYTE、WORD、DWORD等,若是標號則其定義類型只能是NEAR或FAR類型。利用LABEL偽指令可以使用一數(shù)據(jù)區(qū)兼有BYTE和WORD兩種屬性。這樣在以后的程序中可以根據(jù)不同需要分別以字節(jié)為單位或以字為單位存取其中的數(shù)據(jù)。LABEL偽指令也可以將一個屬性已定義的NEAR或者后面跟有冒號(隱含屬性為Near)的標號再定義為FAR。【例4.3】

DATAWLABELWORDDATABDB10H,20H,30H;DATAW與DATAB指向相同的數(shù)據(jù)區(qū)4.3.4段定義偽指令返回8086/8088微處理器對存儲器的管理是分段進行的,因而匯編語言程序中也要求分段組織指令、數(shù)據(jù)和堆棧等,以便將源程序匯編成為目標代碼后可分別裝入存儲器的相應(yīng)段中。

段定義偽指令的功能就是把源程序劃分為邏輯段,便于匯編程序在相應(yīng)段名下生成目標代碼,同時也便于連接程序,組合、定位、生成可執(zhí)行的目標程序。常用的段定義偽指令有SEGMENT/ENDS和ASSUME等。(1)SEGMENT/ENDS(程序段定義偽指令)。格式:段名SEGMENT[定位類型][組合類型][類別]……段名ENDS功能:用來定義程序中的一個段,指明當前數(shù)據(jù)或指令在哪一個程序段上。說明:①SEGMENT偽指令位于一個邏輯段的開始部分,而ENDS偽指令則表示一個邏輯段的結(jié)束。在匯編語言源程序中,這兩個偽指令總成對出現(xiàn),且兩者前面段名必須一致。SEGMENT后面括號中的內(nèi)容為可選項。4.3.4段定義偽指令返回②

定位類型用來指定段的地址邊界。定位類型可以是BYTE(段可從任何地址開始)、WORD(段的起始地址應(yīng)為偶地址)、PARA(段的起始地址應(yīng)為16的倍數(shù))和PAGE(段的起始地址應(yīng)為256的倍數(shù))。③

組合類型告訴匯編程序當裝入存儲器時各邏輯段應(yīng)如何組合。組合類型可以是PRIVATE(默認值,連接時不與其他模塊中的同類別名段合并)、PUBLIC(連接時與其他模塊中的同類別名段合并)、STACK(同PUBLIC,只用于堆棧段,匯編及連接后系統(tǒng)自動為SS及SP分配值)、COMMON(為各模塊相同類別名的段指派同一基地址)、MEMORY(與PUBLIC同義,裝在所有同類別名段最后)和ATexp(段地址為表達式exp的值)。④

類別主要用于控制段的存放次序,必須用單引號括起。三個選項的順序必須符合格式中的規(guī)定,這些可選項是給匯編程序和連接程序(Link)的命令。匯編程序MASM或ASM可將源程序匯編成二進制目標程序(.OBJ)。但是由于目標程序中的地址是浮動的,因此必須通過Link(連接程序)進行連接,將地址最終確定下來才可得到可執(zhí)行程序(.EXE)。4.3.4段定義偽指令返回(2)ASSUME(指定段寄存器偽指令)。在代碼段中的可執(zhí)行指令前必須要有指定段寄存器的偽指令A(yù)SSUME,它主要用來指出程序中各邏輯段應(yīng)通過哪個段寄存器尋址。在一個源程序中,至少應(yīng)該有一個ASSUME偽指令指出CS段寄存器所對應(yīng)的程序代碼段。格式:ASSUME段寄存器名:段名[,段寄存器名:段名…]功能:該偽指令用來告訴源程序中所定義的段由哪個寄存器去尋址。段寄存器可以是CS、DS、ES、SS,段名是程序中由SEGMENT所定義的段之名。說明:①ASSUME偽操作明確指出了程序中邏輯段與物理段之間的關(guān)系。當匯編一個邏輯段時,即可利用相應(yīng)的段寄存器尋址該邏輯段中的指令或數(shù)據(jù)。②ASSUME偽指令只是告訴匯編程序段與段寄存器之間的關(guān)系,并沒有給段寄存器賦初值,必須在程序中用指令給段寄存器賦初值。DS、ES的值必須在程序段中用指令語句進行賦值,而CS、SS由系統(tǒng)負責(zé)設(shè)置。4.3.5過程定義偽指令返回

在程序設(shè)計中,常把具有一定功能的程序段設(shè)計成一個子程序。匯編程序用過程來構(gòu)造子程序。過程定義偽指令是由PROC和ENDP這兩個偽指令助記符來完成的。其中PROC偽指令用來表示過程的開始,而ENDP偽指令用來表示過程的結(jié)束。格式:過程名PROC[類型]……RET過程名ENDP功能:用來定義一個過程。說明:

當一個程序被定義為過程后,程序中其他地方就可以用CALL指令來調(diào)用這個過程。CALL過程名。過程名實際上是過程入口的符號地址,它和標號一樣,有三種屬性:段、偏移量和類型。過程名由用戶自己定義。過程名的類型取值為NEAR或FAR,表示該過程是段內(nèi)調(diào)用或段間調(diào)用,默認為NEAR。當用CALL指令對該過程進行調(diào)用時,由類型屬性決定是段內(nèi)調(diào)用還是段間調(diào)用。在子程序中,RET為過程返回主程序的出口語句,該語句不可默認。偽指令PROC和ENDP必須成對出現(xiàn),它們組成一個完整的過程定義。若過程的屬性為NEAR,則只能被它所在代碼段中的CALL指令調(diào)用。4.3.6模塊定義和結(jié)束偽指令返回(1)NAME。格式:NAME模塊名功能:為源程序的目標程序指定一個模塊名。說明:如果程序中沒有NAME偽指令,則匯編程序?qū)ITLE偽指令定義的標題名前6個字符作為模塊名;如果程序中既沒有NAME,也沒有TITLE,則匯編程序?qū)⒃闯绦虻奈募鳛槟繕顺绦虻哪K名。(2)END。格式:END[起始地址]功能:END偽指令表示源程序的結(jié)束。說明:該指令中的起始地址為可選項,表示第一條要執(zhí)行指令的地址。它可以是標號。如果多個程序模塊相連接,則只有主程序要使用標號,其他子模塊只用END而不必指定標號。4.3.7宏處理偽指令返回1.宏處理偽指令的特點如果程序中需要多次使用同一個程序段,則可以將這個程序段定義為一個宏指令,然后每次需要時,即可簡單地用宏指令名來代替(稱為宏調(diào)用),從而避免了重復(fù)書寫,使源程序更加簡潔、易讀。顯然,利用子程序(過程)也能將某些需要多次調(diào)用的指令編寫成一個程序段。然后在需要的地方調(diào)用這個過程,從而使程序易于實現(xiàn)模塊化,增強源程序的可讀性。從某種意義上講,“宏處理”與“過程”有相似之處,也可以將構(gòu)成一條宏指令程序段定義為一個過程,但兩者間有明顯的區(qū)別。①

宏調(diào)用語句由宏匯編程序MASM中的宏處理程序來識別,并完成相應(yīng)的處理;而調(diào)用過程用CALL語句由CPU來執(zhí)行。4.3.7宏處理偽指令返回②

匯編語言在匯編過程中要將宏指令所代替的程序段匯編成相應(yīng)的機器代碼,并插入到源程序的目標代碼中,每次調(diào)用均要插入,這樣使用宏調(diào)用并不能縮短目標代碼的長度,但被定義的“過程”經(jīng)匯編后的代碼是與主程序分開而獨立存在的,其目標代碼在存儲器中只保留一段,因此采用過程調(diào)用能有效縮短目標代碼的長度,即節(jié)省內(nèi)存空間,而宏指令沒有這個優(yōu)點。③

過程調(diào)用時需要保留程序的斷點和現(xiàn)場,待執(zhí)行完畢還要恢復(fù)現(xiàn)場和斷點,這些操作需要耗費CPU的時間,而宏調(diào)用則不需要這些操作。因此,過程調(diào)用可以節(jié)省程序占用的存儲空間,但卻降低了程序的執(zhí)行速度;而宏調(diào)用不能節(jié)省存儲空間,卻有較快的執(zhí)行速度。④

在每次宏調(diào)用時,允許修改有關(guān)參數(shù),使得同一條宏指令在各次調(diào)用中可完成不同的操作;而“過程”一旦被定義,一般不允許修改。因此,任何一個“過程”在各次調(diào)用中完成相同的功能。從上述特點可以看出,在需要多次執(zhí)行的程序段比較長,對速度要求不高,并且不要求修改參數(shù)的情況下,宜采用過程調(diào)用方式;若要求多次執(zhí)行的程序段比較短,或希望在各次調(diào)用中能修改某些參數(shù)時,宜采用宏調(diào)用方式。4.3.7宏處理偽指令返回2.MACRO/ENDM格式:宏名MACRO[形式參數(shù)1,形式參數(shù)2,…]

ENDM功能:宏定義偽指令定義的宏名可以像指令一樣在程序中被引用。說明:①MACRO偽操作是宏定義符,它將一個宏指令名定義為宏定義陣中包含的程序段,ENDM表示宏定義結(jié)束,前面不要加宏指令名;②

進行一次宏定義,可以多次利用宏指令名進行宏調(diào)用,但必須先定義后引用;③

宏定義偽操作允許帶參數(shù),此時可定義的宏指令具有較強的通用性,宏定義中的參數(shù)稱為形式參數(shù)(DummyParameter)或稱為啞元,當形式參數(shù)不止一個時,它們之間用“,”號隔開;④

宏調(diào)用時,應(yīng)在宏指令名后面寫上相應(yīng)的實際參數(shù)(ActualParameter),稱為實元。4.3.8模塊連接偽指令返回

當一個程序較大時,可把整個程序劃分為幾個相對獨立又相互聯(lián)系的源程序模塊,分別單獨匯編后用LINK連接程序?qū)⑦@些目標模塊連接在一起形成一個統(tǒng)一的可執(zhí)行代碼文件。這種設(shè)計的程序稱為多模塊程序。每一個獨立匯編的源程序稱為一個模塊。由于每個模塊都和其他模塊相關(guān)聯(lián),允許相互訪問,可能A模塊的變量或標號被B模塊使用,這樣必須在編程時加以說明,否則在匯編時就會產(chǎn)生錯誤。(1)EXTRN。格式:EXTRN符號名1:類型[符號名2:類型,…]功能:指明本模塊中引用了哪些外部的符號名及其類型。說明:在定義符號時,必須給出其類型。類型可以是BYTE、WORD、DWORD、NEAR和FAR等。其類型必須與其他模塊定義該符號時的類型保持一致。(2)PUBLIC。格式:PUBLIC符號名1[符號名2,…]功能:指明本模塊中所定義的變量、標號和符號常量可以被其他模塊所引用。說明:符號名是本模塊中所定義的變量、標號和符號常量。4.4匯編程序的功能及匯編過程返回匯編程序的功能數(shù)據(jù)定義偽指令程序的編輯、匯編及連接過程4.4.1匯編程序的功能返回

匯編程序的主要功能是將由匯編語言(助記符)編寫的程序翻譯成用機器語言(二進制代碼)編寫的目標程序。匯編程序的功能如圖4-1所示。4.4.2程序的編輯、匯編及連接過程返回

匯編語言的程序一般要經(jīng)過編輯、匯編(MASM、ASM)、連接(Link)和調(diào)試(Debug)等步驟。匯編語言程序?qū)崿F(xiàn)的流程如圖4-2所示。從具體問題到編程解決問題,一般需要經(jīng)過如下幾個步驟:(1)分析問題,抽象出描述問題的數(shù)學(xué)模型;(2)確定解決問題的算法或算法思想;(3)繪制流程圖或結(jié)構(gòu)圖;(4)分配存儲空間及相應(yīng)的寄存器;(5)編寫程序,排除語法錯誤;(6)上機調(diào)試。4.4.2程序的編輯、匯編及連接過程返回1.建立源文件建立源文件用編輯軟件來完成,常用的編輯工具有E、Quickbasic、C語言、記事本、WORD等。2.匯編用匯編工具對源程序文件(.asm)進行匯編產(chǎn)生目標文件(.obj)等。3.程序連接匯編產(chǎn)生的二進制目標文件(.obj)并不是可執(zhí)行程序,還要用連接程序把它轉(zhuǎn)換為可執(zhí)行文件(.exe)。4.執(zhí)行程序建立了可執(zhí)行文件(.exe)后,只需在命令提示符下輸入文件名即可運行程序。若程序能夠運行但不能得到預(yù)期結(jié)果,則需要靜態(tài)或動態(tài)查錯。5.程序調(diào)試有時靜態(tài)檢查不容易發(fā)現(xiàn)問題,尤其是碰到復(fù)雜程序時更是如此,這時就需要使用調(diào)試工具動態(tài)查錯,即通過運行程序發(fā)現(xiàn)錯誤。當程序結(jié)果不能在屏幕上顯示時也需要調(diào)試工具查看結(jié)果。4.4.2程序的編輯、匯編及連接過程返回Debug調(diào)試工具是專為宏匯編語言設(shè)計的一種調(diào)試手段,是必須掌握的一種調(diào)試工具。Debug調(diào)試工具提供了18條子命令,利用它們可以對程序進行匯編和反匯編,可以觀察和修改內(nèi)存及存儲器的內(nèi)容,可以執(zhí)行跟蹤程序并觀察每一步執(zhí)行結(jié)果。【例4.4】程序調(diào)試過程如下:(1)用鼠標單擊開始菜單(針對Windows操作系統(tǒng)),單擊運行。(2)在運行窗口中輸入cmd,回車進入命令提示符。(3)在命令提示符中編譯匯編源程序并連接*.obj文件。C:\>D:↓(回車)D:\>CDMASM↓D:\MASM>MASMSY1.ASM↓D:\MASM>LINKSY1.OBJ↓(4)在命令提示行中運行并調(diào)試匯編程序。D:\MASM>SY1.EXE↓(回車)D:\MASM>DEBUGSY1.EXE↓4.5匯編程序設(shè)計方法及應(yīng)用返回概述順序結(jié)構(gòu)程序設(shè)計分支程序設(shè)計循環(huán)結(jié)構(gòu)程序設(shè)計子程序設(shè)計宏定義與使用系統(tǒng)功能調(diào)用4.5.1概述返回

程序(Program)是為實現(xiàn)特定目標或解決特定問題而用計算機語言編寫的命令序列集合。為了使程序結(jié)構(gòu)良好、易于閱讀和便于維護,應(yīng)當在設(shè)計中嚴格遵守結(jié)構(gòu)化程序設(shè)計的要求。

結(jié)構(gòu)化程序設(shè)計的主要觀點:采用自頂向下、逐步求精的程序設(shè)計方法;使用三種基本控制結(jié)構(gòu)構(gòu)造程序,任何程序都可由順序、選擇、循環(huán)三種基本控制結(jié)構(gòu)構(gòu)造。結(jié)構(gòu)化程序設(shè)計理論認為,隨著計算機運算速度的提高和內(nèi)存價格的下降,軟件的設(shè)計和維護成本在系統(tǒng)中所占的比重越來越大。因此,過分追求節(jié)省時間和空間而采用若干小技巧以致破壞程序易讀性和易維護性的方法是不可取的。保持良好的程序結(jié)構(gòu)應(yīng)當作為程序設(shè)計的首要考慮。

程序設(shè)計時,應(yīng)先考慮總體,后考慮細節(jié);先考慮全局目標,后考慮局部目標。對復(fù)雜問題,應(yīng)設(shè)計一些子目標作為過渡,逐步細化,并采用模塊化的設(shè)計思想。模塊化是把程序要解決的總目標分解為子目標,再進一步分解為具體的小目標,把每一個小目標稱為一個模塊。匯編語言程序設(shè)計中可將子過程視為一個子模塊。4.5.2順序結(jié)構(gòu)程序設(shè)計返回【例4.5】將存儲單元A中2位壓縮的BCD碼轉(zhuǎn)換成相應(yīng)的ASCII碼存入存儲單元B和C中。說明:得到低位BCD碼的方法是屏蔽操作數(shù)高4位,保留低4位;得到高位BCD碼的方法是操作數(shù)右移4位后再屏蔽高4位,保留低4位。

DSEGSEGMENTADB56H ;2位壓縮BCD碼BDB?

CDB?

DSEGENDSCSEG SEGMENTASSUMECS:CSEG,DS:DSEGSTART:MOVAX,DSEG ;給AX賦值MOVDS,AX ;設(shè)置DSMOVAL,AANDAL,0FH ;屏蔽高4位,取低位BCD碼ORAL,30H ;將低位BCD碼轉(zhuǎn)換成ASCII碼MOVB,AL ;存入單元B中MOVAL,AMOVCL,4

SHRAL,CL ;高位BCD碼移入AL的低4位ANDAL,0FHORAL,30HMOVC,ALMOVAH,4CHINT21H ;執(zhí)行DOS功能調(diào)用,返回DOSCSEGENDSENDSTART4.5.3分支程序設(shè)計返回

分支程序是指程序的運行過程中要求計算機作一些判斷,并根據(jù)判斷選擇不同的處理。在8086/8088指令系統(tǒng)中,判斷的依據(jù)主要是運算結(jié)果及運算標志寄存器中的狀態(tài)位。分支程序分為雙分支和多分支兩種結(jié)構(gòu)。雙分支結(jié)構(gòu)一般由以下三部分組成。(1)條件產(chǎn)生語句。在進行判定以前必須要有條件產(chǎn)生語句,如算術(shù)運算指令、比較指令等,通過它們影響標志寄存器狀態(tài)位SF、CF、OF、ZF等,為條件測試做準備。(2)條件測試語句。利用條件轉(zhuǎn)移指令進行測試。滿足條件,跳轉(zhuǎn)到標號處;不滿足條件,順序執(zhí)行條件測試語句下面的指令。執(zhí)行分支段程序后必須保證程序順序執(zhí)行下去。(3)標號。在分支程序段前設(shè)置標號以便于跳轉(zhuǎn)。4.5.3分支程序設(shè)計返回【例4.6】比較兩個無符號數(shù)的大小,把較大的數(shù)存入MAX單元中。說明:繪制流程圖,并根據(jù)流程圖編寫程序。流程圖如圖4-3所示。DATASEGMENTNUMDB60H,66HMAXDB?DATAENDSCODESEGMENT

ASSUMECS:CODE,DS:DATASTART: MOV AX,DATA MOV DS,AX MOV AL,NUM;取第一個數(shù) CMP AL,NUM+1;兩數(shù)相減比較大小 JNC BIG;第一個數(shù)大,跳轉(zhuǎn)BIG處 MOV AL,NUM+1

BIG: MOV MAX,AL;保存較大數(shù)

MOV AH,4CH INT 21HCODEENDS END START4.5.4循環(huán)結(jié)構(gòu)程序設(shè)計返回

循環(huán)指程序段在一定條件下重復(fù)執(zhí)行。循環(huán)結(jié)構(gòu)一般由三部分組成:

(1)設(shè)置循環(huán)初值。為程序操作、地址指針、循環(huán)計數(shù)、結(jié)束條件等設(shè)置初始值。(2)循環(huán)主體。完成程序的基本操作,使用循環(huán)結(jié)構(gòu)的目的就是為了重復(fù)執(zhí)行這段程序。(3)循環(huán)控制。循環(huán)控制包括修改循環(huán)計數(shù)值和檢測循環(huán)結(jié)束條件等,保證循環(huán)條件滿足時進入循環(huán),循環(huán)條件不滿足時退出循環(huán),執(zhí)行循環(huán)體外的后續(xù)語句。【例4.7】編程實現(xiàn)在10個無符號字節(jié)整數(shù)的數(shù)組中找出最大數(shù)。說明:首先建立一個數(shù)據(jù)指針指向數(shù)據(jù)區(qū)的首地址,將第一個數(shù)取到某個寄存器中(如AL)與下一個數(shù)相比較,若下一個數(shù)大,就將它存到AL中,替換原來的數(shù);然后調(diào)整數(shù)據(jù)指針,將AL的數(shù)與此指針所指的數(shù)進行比較,再重復(fù)上述步驟,兩兩比較下去,直到比較完畢結(jié)果AL中留下最大數(shù)為止。4.5.4循環(huán)結(jié)構(gòu)程序設(shè)計返回DATASEGMENTARRAYDB25,56,78,8,76DB90,96,33,21,06COUNTDW$-ARRAYDATAENDSCODESEGMENTASSUMECS

:CODE,DS:DATASTART:MOVAX,DATAMOV DS,AXMOV BX,OFFSETARRAY ;設(shè)置數(shù)據(jù)區(qū)指針首地址MOV CX,COUNT;設(shè)置計數(shù)器初值DEC CX;設(shè)置比較次數(shù)MOV AL,[BX];取數(shù)到AL中AGAIN:INC BX ;指向數(shù)據(jù)區(qū)下一個數(shù)據(jù)CMP AL,[BX];兩數(shù)相比較JNB NEXT ;AL≥[BX],轉(zhuǎn)NEXTMOV AL,[BX];否則,把較大數(shù)送入AL中NEXT:DEC CX;全部數(shù)據(jù)比較完否JNZ AGAIN;否,轉(zhuǎn)AGAIN處MOV AH,4CHINT 21HCODEENDSEND START4.5.4循環(huán)結(jié)構(gòu)程序設(shè)計返回【例4.8】設(shè)在內(nèi)存數(shù)據(jù)區(qū)TABLE地址開始存放一列表,表長在LEN單元,表中數(shù)據(jù)為有符號字節(jié)數(shù)據(jù),用冒泡排序法編程將表中數(shù)據(jù)從小到大排序。說明:排序的目的是為檢索提供方便,一組數(shù)據(jù)按照由小到大的順序排列稱為升序,反之稱為降序。排序的方法很多,如交換排序、選擇排序、快速排序等。下面介紹交換排序中冒泡法排序的基本思想。(1)對N個數(shù)進行相鄰兩數(shù)比較,若兩數(shù)為正序,保持原位序,若兩數(shù)為逆序,交換位置,共進行N-1次,結(jié)果最小數(shù)(升序)冒到頂部或最大數(shù)沉到底部,成為有序序列。(2)對剩余無序的N-1個數(shù)進行與第一步類似的第二輪兩兩比較,比較次數(shù)為N-2。(3)每完成一輪,有序序列中數(shù)的個數(shù)增1,無序序列中數(shù)的個數(shù)減1,共做N-1輪,所有數(shù)均歸為有序序列中,排序結(jié)束。源程序中引入的交換標志DX,其初值為0,在每一輪比較過程中只要發(fā)生過數(shù)據(jù)交換則DX置為1。每一輪比較后檢查該交換標志,若DX等于初值,說明未發(fā)生過交換,即有序表已形成,無須繼續(xù)循環(huán),排序結(jié)束,否則,還要進一步排序比較。程序流程圖如圖4-5所示。4.5.4循環(huán)結(jié)構(gòu)程序設(shè)計返回DSEGSEGMENTARRAYDB23,54,62,-12,83,-53,0,36LENEQU$-ARRAYDSEGENDSCSEGSEGMENTASSUMECS:CSEG,DS:DSEGSTART:MOVAX,DSEGMOVDS,AXMOVBX,LEN-1 ;比較輪數(shù)送入BXLP:MOVSI,LEN-1 ;比較起始位置送入SIMOVCX,BX ;比較次數(shù)計數(shù)送入CXMOVDX,0 ;交換標志清零LP1:MOVAL,ARRAY[SI] ;相鄰兩數(shù)比較CMPAL,ARRAY[SI-1]JGENEXT ;大于等于時跳轉(zhuǎn)MOVAH,ARRAY[SI-1] ;否則,相鄰兩數(shù)交換MOVARRAY[SI-1],ALMOVARRAY[SI],AHMOVDX,1 ;交換標志置1NEXT:DECSI ;修改地址,指向數(shù)組中低地址元素LOOPLP1 ;判斷內(nèi)循環(huán)是否結(jié)束CMPDX,0 ;需要下一輪嗎

JZOVER ;數(shù)組已排序好,轉(zhuǎn)到程序結(jié)束處DECBX ;外循環(huán)所有輪是否結(jié)束JNZLP ;未完繼續(xù)OVER:MOVAH,4CHINT21H ;返回DOSCSEGENDSENDSTART4.5.5子程序設(shè)計返回

如果在一個程序中的多個地方或在多個程序中都要用到同一段程序,可以把該程序段獨立出來,以供其他程序調(diào)用,這段程序稱為“子程序”或“過程”。子程序是供其他程序調(diào)用的相對固定的程序段,調(diào)用子程序的程序體稱為“主程序”或“調(diào)用程序”。采用子程序結(jié)構(gòu),具有以下優(yōu)點。(1)簡化程序設(shè)計過程,大量節(jié)省程序設(shè)計時間。(2)縮短程序長度,節(jié)省計算機匯編源程序的時間和程序所占的存儲單元。(3)增加程序的可讀性,便于程序修改。在程序設(shè)計中,一個程序可以調(diào)用某個子程序,該子程序可以調(diào)用其他子程序,這就形成了子程序嵌套。子程序嵌套調(diào)用的層次不受限制,其嵌套層數(shù)稱為“嵌套深度”。子程序中使用堆棧來保護斷點,堆棧操作的特性(后進先出)能自動保證各個層次子程序斷點的正確入棧和返回,因此在子程序中使用PUSH、POP指令時要格外小心,以免造成子程序無法正確返回。4.5.5子程序設(shè)計返回【例4.9】利用堆棧,采用遞歸子程序的方法,編程實現(xiàn)求N!。說明:由于用AX作為出口參數(shù)存放階乘值,所以N≤9,即(N-1)!≤0FFFFH。子程序中BX有兩個作用:保存并恢復(fù)原始數(shù)據(jù);保存并恢復(fù)求連乘積時所需要的乘數(shù)N,N-1,…,3,2。堆棧區(qū)也不應(yīng)設(shè)置過小,否則會限制遞歸調(diào)用的次數(shù)。用遞歸子程序求階乘示意圖如圖4-6所示。當程序執(zhí)行到EXIT時,堆棧空間示意圖如圖4-7所示。4.5.5子程序設(shè)計返回DSEGSEGMENTNDW5 ;此變量要送入AX中,應(yīng)定義為字類型RLTLDW? ;存放運算結(jié)果低16位RLTHDW? ;存放運算結(jié)果高16位DSEGENDSSSEGSEGMENTSTACK‘STACK’ ;聲明組合類型后系統(tǒng)自動為SS及SPDW100DUP(?) ;分配值SSEGENDSCSEGSEGMENTASSUMECS

:CSEG,DS:DSEG,SS:SSEGSTART:MOVAX,DSEGMOVDS,AXMOVAX,NCALLREC ;調(diào)用求階乘遞歸子程序BRK:MOVRLTL,AX ;運算結(jié)果低16位送入RLTL中

MOVRLTH,DX ;運算結(jié)果高16位送入RLTH中

MOVAH,4CH

INT21HRECPROCNEARPUSHBX ;遞歸調(diào)用時BX(5、4、3、2)依次壓入堆棧MOVBX,AXCMPAX,1JZEXITDECAXCALLREC ;遞歸調(diào)用AMD:

MULBX ;AX*BX→DXAXEXIT:POPBXRETREC

ENDPCSEGENDSENDSTART4.5.5子程序設(shè)計返回【例4.10】實現(xiàn)兩個無符號數(shù)相加,并將結(jié)果顯示在屏幕上。說明:源程序包括模塊a和模塊b,分別編譯模塊a和模塊b,并把生成的兩個OBJ文件連接成一個可執(zhí)行文件。各模塊內(nèi)的PUBLIC語句與EXTRN語句應(yīng)該相互照應(yīng)。在EXTRN出現(xiàn)的符號應(yīng)在其他模塊的PUBLIC語句中找到,并且類型相互一致,否則在連接時會出錯。多目標文件(.OBJ)連接格式為:D:\MASM>LINKA.OBJ+B.OBJ。;模塊a:源文件名A.ASMPUBLICSUM ;模塊b中引用的變量EXTRNPROC2:NEAR ;本模塊引用的b模塊定義過程DATASEGMENTPUBLIC'DATA'ARRAYDW166H,288H ;定義兩個無符號數(shù)據(jù)SUMDW? ;定義字類型變量,用于保存運算后的DATAENDSSSEGSEGMENTSTACKDW100DUP(?) ;聲明200個字節(jié)堆??臻gTOSLABELWORDSSEGENDSCODESEGMENTPUBLIC'CODE'

ASSUMECS:CODE,DS:DATA,SS:SSEG4.5.5子程序設(shè)計返回START:MOVAX,DATA

MOVDS,AX

MOVAX,SSEG

MOVSS,AX

MOVSP,OFFSETTOS ;SP指向棧頂

MOVSI,OFFSETARRAY ;無符號數(shù)首地址送入SI

CALLPROC1 ;調(diào)用本模塊的求和子程序

MOVAH,4CH ;返回DOS

INT21HPROC1

PROCNEAR ;實現(xiàn)兩個無符號數(shù)相加

PUSHDX

PUSHBX

PUSHAX

PUSHSI

PUSHCX

MOVAX,[SI] ;首個無符號數(shù)送入AX

ADDAX,[SI+2] ;兩個無符號數(shù)相加

MOVSUM,AX ;和送入SUM

CALLPROC2 ;調(diào)用b模塊中的顯示子程序

POPCX

POPSI

POPAX

POPBX

POPDX

RETPROC1ENDPCODEENDSENDSTART4.5.5子程序設(shè)計返回;模塊b:源文件名B.ASMPUBLICPROC2 ;模塊a中引用的過程EXTRNSUM:WORD ;本模塊引用的a模塊定義的變量CODESEGMENTPUBLIC'CODE'ASSUMECS:CODEPROC2PROC

NEAR

MOVBX,SUM ;和送入BX中待用

MOVCH,4 ;循環(huán)執(zhí)行4次AGAIN:MOVCL,4

ROLBX,CL ;高4位循環(huán)移入低4位

MOVAL,BL

ANDAL,0FH ;移入的低4位保留,其他位清零

ADDAL,30H ;低4位轉(zhuǎn)換成ASCII碼

CMPAL,3AH ;判斷是否為0~9的ASCII碼

JLNEXT ;如果是0~9的ASCII碼,則跳轉(zhuǎn)

ADDAL,07H ;轉(zhuǎn)換成A~F的ASCII碼NEXT:

MOVDL,AL ;入口參數(shù)DL=輸出字符

MOVAH,2 ;2號功能為顯示輸出

INT21H ;DOS功能調(diào)用

DECCH ;循環(huán)次數(shù)減1

JNZAGAIN ;循環(huán)4次退出

RETPROC2

ENDPCODE

ENDS

END4.5.6宏定義與使用返回宏是源程序中一段有獨立功能的程序代碼。它只需在匯編語言源程序中定義一次便可以多次反復(fù)調(diào)用。調(diào)用時只需要一條宏指令即可?!纠?.11】實現(xiàn)無符號數(shù)組的求和。說明:當源程序被匯編時,匯編程序?qū)γ總€宏調(diào)用進行宏擴展。宏調(diào)用中實參數(shù)之間用逗號隔開。實參數(shù)是形式參數(shù)的實際代替。實參數(shù)和形式參數(shù)的順序一致。原則上,實參數(shù)的個數(shù)應(yīng)和形式參數(shù)的個數(shù)相等。若實參數(shù)的個數(shù)大于形式參數(shù)的個數(shù),則在替換時多余的實參數(shù)不予考慮。若實參數(shù)的個數(shù)小于形式參數(shù)的個數(shù),則多余的形式參數(shù)作為空(字符)或零(數(shù)字)處理。SUM_WMACROOP1,OP2 ;數(shù)組元素連續(xù)相加宏指令NEXT:ADDOP1,[OP2]ADDOP2,2LOOPNEXTENDMEXITMACRO;返回DOS宏指令MOVAH,4CHINT21HENDM4.5.6宏定義與使用返回DSEGSEGMENTARRAYDW1,2,3,4,5,6,7,8,9,10COUNTDW($-ARRAY)/2SUMDW?DSEGENDSCSEGSEGMENTASSUMECS:CSEG,DS:DSEGSTART:MOVAX,DSEGMOVDS,AXLEASI,ARRAY ;取數(shù)組的首地址MOVCX,COUNT ;取數(shù)組中元素的個數(shù)

XORAX,AX ;AX清零SUM_WAX,SI ;數(shù)組求和宏調(diào)用MOVSUM,AXEXITCSEGENDSENDSTART4.5.7系統(tǒng)功能調(diào)用返回1.概述DOS(DiskOperationSystem)和BIOS(BasicInputandOutputSystem)為用戶提供了兩組系統(tǒng)服務(wù)程序。用戶程序可以調(diào)用這些系統(tǒng)服務(wù)程序。在調(diào)用時有如下特點。(1)與過程調(diào)用不同,不用CALL指令。(2)與宏調(diào)用不同,不用這些系統(tǒng)服務(wù)的名稱,而采用軟中斷指令I(lǐng)NTn。(3)用戶程序不必與這些服務(wù)程序的代碼連接。使用DOS和BIOS調(diào)用所編寫的程序簡單、清晰,可讀性好,而且代碼緊湊,調(diào)試方便。BIOS是IBMPC與PC/XT的基本I/O系統(tǒng),包括系統(tǒng)測試程序、初始化引導(dǎo)程序、部分矢量裝入程序及外部設(shè)備的服務(wù)程序,由于這些程序固化在ROM中,只要機器通電就可以調(diào)用它們。DOS是IBMPC及PC/XT的操作系統(tǒng),負責(zé)管理系統(tǒng)的所有資源,協(xié)調(diào)微機各組成部分的操作,其中包括大量可供用戶調(diào)用的服務(wù)程序,完成設(shè)備及磁盤文件的管理。DOS含有三個模塊,即C、Msdos.sys、IO.sys。三個模塊間可單項調(diào)用。用戶可通過兩種途徑使用DOS功能。第一種途徑是普通用戶從鍵盤輸入命令,DOS的C模塊接收識別處理輸入的命令。第二種途徑是高級用戶通過用戶程序去調(diào)用DOS和BIOS中的服務(wù)程序。當然,高級用戶需要對操作系統(tǒng)有較深入的了解。4.5.7系統(tǒng)功能調(diào)用返回

一般來說,用戶程序通過以下四種方式控制PC的硬件:(1)使用高級語言提供的功能控制。高級語言一般提供一些I/O語句及使用方法,但高級語言的I/O語句較少,執(zhí)行速度慢。(2)使用DOS提供的程序控制硬件。DOS用戶提供的I/O程序近百種,而且是在較高層次上提供的,不需要用戶對硬件有太多的了解。使用DOS調(diào)用的程序可移植性好,I/O功能多,編程簡單,調(diào)試方便,但執(zhí)行效率較低。(3)使用BIOS提供的程序控制硬件。BIOS在較低層次上為用戶提供了一組I/O程序,要求用戶對硬件有相當?shù)牧私狻IOS駐留在ROM中,獨立于任何操作系統(tǒng),使應(yīng)用BIOS調(diào)用的匯編、C和PASAL語言的可移植性較差。當DOS和BIOS提供的功能相當時,用戶應(yīng)當首選DOS調(diào)用,但BIOS調(diào)用效率高,并且BIOS調(diào)用中的一部分功能是DOS沒有的。(4)直接訪問硬件。這種方式直接訪問硬件,這就要求用戶對微型機的硬件和外設(shè)非常熟悉。此種方式只用于兩種情況:為獲得較高的效率和為獲得DOS和BIOS中不支持的功能。顯然直接訪問硬件的程序可移植性差,在一個廠商生產(chǎn)的機器上可以運行的程序在另一個廠商生產(chǎn)的兼容機上可能無法運行。4.5.7系統(tǒng)功能調(diào)用返回2.DOS系統(tǒng)功能調(diào)用8086/8088指令系統(tǒng)中有一種軟中斷指令I(lǐng)NTn。每執(zhí)行一條軟中斷指令就調(diào)用一個相應(yīng)的中斷服務(wù)程序。當n=5~1FH時,調(diào)用BIOS中的服務(wù)程序。當n=20H~3FH時,調(diào)用DOS中的服務(wù)程序。其中,INT21H是一個具有多種功能的服務(wù)程序,一般稱為DOS系統(tǒng)功能調(diào)用。

系統(tǒng)功能調(diào)用INT21H是一個具有近90個子功能的中斷服務(wù)程序,這些子功能的編號稱為功能號。INT21H的功能大致可分為四個方面,即設(shè)備管理、目錄管理、文件管理和其他功能。

設(shè)備管理主要包括鍵盤輸入、顯示輸出、打印機輸出、串行設(shè)備輸入/輸出、初始化磁盤、取剩余磁盤空間等。目錄管理主要包括查找目錄項、查找文件、置/取文件屬性、文件設(shè)備等。文件管理主要包括打開、關(guān)閉、讀寫/刪除文件等。其他功能包括終止程序、置/取中斷矢量、分配內(nèi)存、置/取日期及時間等。4.5.7系統(tǒng)功能調(diào)用返回DOS系統(tǒng)功能調(diào)用的方法如下:(1)根據(jù)需要的功能調(diào)用設(shè)置入口參數(shù)。(2)把功能調(diào)用號送入AH寄存器。(3)發(fā)軟中斷指令“INT21H”。(4)可根據(jù)有關(guān)功能調(diào)用的說明取得出口參數(shù)。下面介紹INT21H的主要功能。(1)鍵盤輸入。有關(guān)鍵盤的系統(tǒng)功能調(diào)用的功能號有1、7、8、A、B、C。功能包括單字符輸入、字符串輸入、鍵盤狀態(tài)檢驗等。①

鍵盤狀態(tài)檢驗。DOS系統(tǒng)功能調(diào)用的0BH號功能可以檢驗是否有字符輸入。如果有鍵按下時AL=0FFH,否則AL=00H。②

單字符輸入。功能號1、7、8都可以直接接收輸入的字符。程序中常利用這些功能回答程序中的提示信息,或選擇菜單中的可選項來執(zhí)行不同的程序段。其中功能號7、8有不回顯的特性,可輸入需要保密的信息。入口參數(shù)沒有,出口參數(shù)為AL=輸入字符的ASCII碼。4.5.7系統(tǒng)功能調(diào)用返回③

字符串輸入。用戶程序經(jīng)常需要從鍵盤上接收一串字符。0AH號功能可以接收輸入的字符串并將其存入內(nèi)存中用戶定義的緩沖區(qū)。緩沖區(qū)的第一個字節(jié)為用戶定義的最大輸入字符數(shù),若用戶輸入的字符數(shù)(包括回車符)大于此數(shù),則機器響鈴,且光標不再右移,直到輸入回車符為止。緩沖區(qū)的第二個字節(jié)為實際輸入字符數(shù)(不包括回車符),由DOS自動填入,從第三個字節(jié)開始存放輸入的字符。顯然,緩沖區(qū)的大小等于最大字符數(shù)加2。(2)顯示器(CRT)輸入。功能號2、6、9是關(guān)于顯示器的系統(tǒng)功能調(diào)用。使用功能調(diào)用9時,需要注意兩點:第一,被顯示的字符串必須以“$”為結(jié)束符;第二,當顯示由功能0A輸入的字符串時,DS:DX應(yīng)指向用戶定義緩沖區(qū)的第三個字節(jié),即輸入的第一個字符的存儲單元。(3)返回操作系統(tǒng)。這是4CH號系統(tǒng)功能調(diào)用,其格式如下:

MOVAH,4CH它沒有入口參數(shù),執(zhí)行結(jié)果是結(jié)束當前正在執(zhí)行的程序。4.5.7系統(tǒng)功能調(diào)用返回【例4.12】接收鍵盤輸入并在屏幕上顯示。如果是“Esc”鍵,則退出程序。

CSEGSEGMENTASSUMECS:CSEGSTART:MOVAH,01H;功能號為01H的功能是鍵盤輸入并回顯INPUT:INT21H

CMPAL,1BH;“Esc”鍵的ASCII是1BH

JZOVER;輸入為“Esc”鍵時,返回DOS

JMPINPUTOVER:MOVAH,4CHINT21HCSEGENDSENDSTART4.5.7系統(tǒng)功能調(diào)用返回【例4.13】輸出MESS中的字符串。按“Esc”鍵退出程序。

DSEGSEGMENTMESSDB'HuaBeiShuiYuan!$';顯示信息DSEGENDSCSEGSEGMENTASSUMECS:CSEG,DS:DSEGSTART:MOVAX,DSEG

MOVDS,AX

LEADX,MESS

MOVAH,9

INT21H

MOVAH,07H;功能號為07H的功能是鍵盤輸入無回顯INPUT:INT21H

CMPAL,1BH;“Esc”鍵的ASCII是1BH

J

溫馨提示

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

評論

0/150

提交評論