東南大學電子信息工程之微機學第3章(5學時)匯編語言.ppt
《東南大學電子信息工程之微機學第3章(5學時)匯編語言.ppt》由會員分享,可在線閱讀,更多相關《東南大學電子信息工程之微機學第3章(5學時)匯編語言.ppt(82頁珍藏版)》請在裝配圖網上搜索。
第三章匯編語言程序設計,本章內容,匯編語言源程序的格式偽操作命令DOS及BIOS功能調用,計算機程序設計語言的演變,1.機器語言直接用機器指令來編制計算機程序的方法。2.匯編語言可以用助記符來表示指令的操作和操作數,也可以用標號和符號來代替地址、常量和變量。3.高級語言更接近于人們的自然語言和習慣的教學語言來描述算法的執(zhí)行過程,從而使編寫的過程更加直觀和簡練。,為什么要用匯編語言,匯編語言非常接近機器語言程序,通過編制匯編語言程序,可以清楚地了解計算機的工作過程。現在的微機系統中,底層的一些功能仍然靠匯編語言程序來實現。匯編語言程序的效率通常高于高級語言程序。,舉例,dataSEGMENTmsgDBHello,World!$dataENDScodeSEGMENTASSUMECS:code,DS:dataMAINPROCNEARstart:MOVAX,dataMOVDS,AXLEADX,msgMOVAH,9hINT21hMOVAX,4C00hINT21hMAINENDPcodeENDSENDstart,在屏幕上顯示Hello,World!,本例將在下文中多次提及,為方便計,下文簡稱其為“Hello例”。,,3.2.1分析1—分段結構,可以看出,匯編語言源程序是分段結構的形式。一個匯編源程序由若干個段(Segment)組成。每個段以SEGMENT語句開始,以ENDS結束。整個源程序以END語句結尾。這里所說的匯編語言源程序的段和第一章中的CPU管理的存儲器的段是不同的概念。匯編語言的段是邏輯段;8086CPU管理的存儲器的段是物理段(共有4個:數據段、附加段、堆棧段、代碼段,對應4個段寄存器:DS、ES、SS和CS)。一個匯編語言源程序中可以有多個邏輯段。上例中共有兩個邏輯段:data和code。,分析2,注:功能號09H的int21中斷功能描述:輸出一個字符串到標準輸出設備上。入口參數:AH=09HDS:DX=待輸出字符的地址說明:待顯示的字符串以’$’作為其結束標志,代碼段開頭執(zhí)行了一次功能號09H的21號DOS中斷,用于在屏幕上顯示字符串。關于DOS功能調用,后文將有詳細解釋。此處先列出功能號09H的21號DOS中斷的相關資料:,最后兩行(MOVAX,4C00h、INT21h)也是一個DOS功能調用。,注:功能號4CH的int21中斷功能描述:終止程序的執(zhí)行,并可返回一個代碼入口參數:AH=4CHAL=返回的代碼,匯編語言開發(fā)過程,源程序:文件名.asm,,,,目標程序:文件名.obj,可執(zhí)行文件:文件名.exe,Finish,,編輯器,如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版本歷史(了解),開發(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ā)DOS程序的Masm下載地址:Masm5.00[羅云彬的編程樂園]http://211.90.241.130:22366/view.asp?file=51Masm615ForDos[aogo匯編小站],開發(fā)步驟演示(了解),使用MASM5.0,開發(fā)步驟演示(了解),使用MASM6.15ForDOS,3.2.2語句的類型,匯編語言源程序中的語句主要有以下兩種類型:指令性語句指示性語句指令性語句主要由CPU指令組成,對應實際的機器指令;(比如“Hello例”中的MOVDS,AX)指示性語句又稱偽操作語句,主要由偽操作指令組成。(比如“Hello例”中的codeSEGMENT),語句的組成,匯編語言的語句可以有1~4個組成部分,如下所示:[名字]操作碼/偽操作碼[操作數][;注釋]帶方括號的部分表示可選項。以“Hello例”中的幾條語句為例:,3.2.3語句的組成—名字,名字在指令性語句中,名字是一個標號,實際上就是指令的符號地址。比如“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ū)中存取操作對象的大小。,3.2.4語句的組成—操作碼/偽操作碼,操作碼/偽操作碼在匯編語言中操作碼以助記符的形式存在。8086/8088CPU的助記符總共約有90多種,比如MOV、ADC等。關于所有的助記符,參見第二章指令系統。指示性語句中的DB、SEGMENT、ENDS、ASSUME、END等都是偽操作碼,而不是CPU指令的助記符。它們在程序中的作用是定義變量的類型、定義段以及命令匯編程序(masm.exe)結束匯編等。它們是指示匯編程序(masm.exe)完成匯編,本身不產生對應的機器碼。關于偽操作碼的具體作用和使用方法,下文有專門章節(jié)討論。,3.2.5語句的組成—操作數,操作數對于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例”中的:LEADX,msg其中msg就是一個在數據區(qū)定義的變量(msgDB‘Hello,World!$’)。表達式匯編語言中的表達式按其性質可以分為兩種:數值表達式和地址表達式。數值表達式產生一個數值結果,只有大小,沒有屬性。地址表達式的結果不是一個單純的數值,它有三種屬性:段、偏移量和類型。,語句的組成—操作數,構成表達式必然有運算符。表達式中常用運算符有以下幾種:①算術運算符,如+、-、*、/和MOD(模除)這些算術運算符可用于數值表達式,運算結果是一個數值。在地址表達式中通常只使用其中的+和–兩種運算符。②邏輯運算符,如AND、OR、XOR和NOT邏輯運算符只用于數值表達式中對數值進行按位邏輯運算。對地址進行邏輯運算是沒有意義的。不要把邏輯運算符如AND、OR、XOR和NOT等與同樣名稱的CPU指令相混淆。前者可對整常數進行按位邏輯運算,是在匯編時進行;后者的操作數可以是寄存器、存儲器和立即數,是在程序運行時由CPU執(zhí)行。比如:ANDAL,01011010B;這里的AND是指令助記符MOVAL,01011010BAND11110000B;這里的AND是邏輯運算符,語句的組成—操作數,③關系運算符如EQ(等于)、NE(不等)、LT(小于)、GT(大于)、LE(小于或等于)、GE(大于或等于)等。參與關系運算的必須是兩個數值,或同一段中的兩個存儲單元地址,但運算結果只能是兩個特定的數值之一。當關系不成立(假)時,結果為0;當關系成立(真)時,結果為0FFFFH(-1)。例如:MOVAX,4EQ3;關系不成立,故(AX)←0MOVAX,4NE3;關系成立,故(AX)←0FFFFH,語句的組成—操作數,④分析運算符和合成運算符如OFFSET、SEG、TYPE、SIZE和LENGTH等;合成運算符有PTR、THIS、SHORT等。分析運算符用以分析一個存儲器操作數的屬性,如段、偏移量或類型等。合成運算符則可以規(guī)定存儲器操作數的某個屬性,例如類型。OFFSET用于獲取一個標號或變量的偏移地址,如:MOVSI,OFFSETDATA1是將變量DATA1的偏移地址送至SI寄存器。其效果等同于:LEASI,DATA1,語句的組成—操作數,SEG用于獲取標號或變量的段址,如:MOVAX,SEGARRAYMOVDS,AX是將變量ARRAY的段地址送入DS寄存器。TYPE的運算結果是一個數值,這個數值與存儲器操作數類型屬性的關系如下:,語句的組成—操作數,TYPE運算符的例子VARDW?ARRAYDD10DUP(?)STRDB‘Thisisatest’MOVAX,TYPEVAR;(AX)←2MOVBX,TYPEARRAY;(BX)←4MOVCX,TYPESTR;(CX)←1LENGTH如果一個變量已用重復操作符DUP說明其變量的個數,則利用LENGTH獲取這個變量的個數。如果未用DUP說明,則得到的結果為1。比如上例中,LENGTHARRAY運算結果為10。,語句的組成—操作數,SIZE如果一個變量已用重復操作符DUP說明,則利用SIZE運算符可得到分配給該變量的字節(jié)總數。如果未用DUP說明,則得到的結果是TYPE運算的結果。比如上例中,SIZEARRAY運算結果為104=40。由此可知,SIZE的運算結果等于LENGTH的運算結果乘以TYPE的運算結果。PTR是一個合成運算符,用于指定存儲器操作數的類型。比如INCBYTEPTR[BX][SI],指令中利用PTR運算符明確規(guī)定存儲器操作數的類型為BYTE(字節(jié)),因此,本指令將一個8位存儲器的內容加1。,語句的組成—操作數,THIS也可以指定存儲器操作數的類型。使用THIS運算符可以使標號或變量的類型具有靈活性。例如要求對同一個數據區(qū),既可以字節(jié)作為單位,又可以字作為單位進行存取,則可以用以下語句:AREAWEQUTHISWORDAREABDB100DUP(?)上面的AREAW和AREAB代表同一個數據區(qū),其中共有100個字節(jié),但AREAW的類型為WORD,而AREAB的類型為BYTE。SHORT指定一個標號的類型為SHORT(短標號),即標號到引用標號的指令間的距離在-128~127之間。短標號可用于無條件轉移和條件轉移指令中。使用短標號的指令比使用默認的近標號的指令少一個字節(jié)。,語句的組成—操作數,方括號[]間接尋址指令的存儲器操作數要在寄存器名BX、BP、SI或DI外面加上方括號,以表示存儲器地址。又如,變址尋址指令的存儲器操作數既要用算術運算符將SI或DI與一個位移量做運算,又要在外面加上方括號來表示存儲器地址。MOVCL,[BX]MOVAL,[SI+5]段超越運算符“:”是“:”(冒號)跟在段寄存器名(DS、ES、SS或CS)之后表示段超越,用以給一個存儲器操作數指定一個段屬性,而不管其原來隱含的段是什么。例如:MOVAX,ES:[SI]HIGH和LOW獲取一個數值或地址表達式的高位和低位字節(jié)。STUFFEQU0ABCDHMOVAH,HIGHSTUFF;(AH)←0ABHMOVAL,LOWSTUFF;(AL)←0CDH,語句的組成—操作數,如果一個表達式中同時具有多個運算符,那么按照以下規(guī)則進行運算:優(yōu)先級高的先運算,優(yōu)先級低的后運算;同一優(yōu)先級按表達式中從左到右的順序進行運算;圓括號可提升運算優(yōu)先級,圓括號內的運算符總是在其任何相鄰的運算之前進行。各種運算符的優(yōu)先級順序如下頁圖表所示。表中同一行的運算符具有同等優(yōu)先級。,語句的組成—操作數,3.2.6語句的組成—注釋,注釋和其他語言一樣,匯編語言中的注釋僅用于提高程序的可讀性。匯編語言中的注釋前面要求加上分號(;)。如果注釋內容較多,超過一行,則換行以后前面還要加上分號。注釋也可以從一行的最前面開始。匯編程序(masm.exe)對注釋不予理會,即注釋對匯編后產生的目標程序沒有任何影響。,3.3偽操作指令,指示性語句中的偽操作指令,因其表示形式類似于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=09HDS:DX=待輸出字符的地址說明:待顯示的字符串以’$’作為其結束標志,Hello,World!機器代碼的分析,下圖使用d1449:0000顯示了數據段中的內容:,Review(1),匯編語言源程序中語句的類型指令性語句–由CPU指令組成指示性語句–由偽指令組成匯編語言語句的組成1、名字指令性語句中的名字是一個標號指示性語句中的名字可以是變量名、段名、過程名2、操作碼/偽操作碼,Review(2),3、操作數常數寄存器標號變量表達式算術運算符邏輯運算符關系運算符分析運算符和合成運算符各種運算符的優(yōu)先級4、注釋,3.3偽操作命令,宏匯編程序MASM提供了數十種偽操作。(這里也揭示了操作碼和偽操作碼的區(qū)別:偽操作碼隨編譯器的不同而不同;而操作碼隨CPU的不同而不同。)根據偽操作的功能,大致可以分為下列幾類:,偽操作指令分類,處理器方式偽操作(了解),處理器方式偽操作用于指示匯編編譯器使用何種CPU的指令系統。常用的有以下幾種:.8086指示匯編程序只匯編8086/8088的指令系統。程序中若出現80286或80386的指令,則編譯會出錯。如果程序中不定義任何處理器方式偽操作,則匯編程序默認即是.8086方式。.386P指示匯編程序匯編8086/8088以及所有80286和80386(包括保護方式和非保護方式)的指令。,3.3.2數據定義偽指令,數據定義偽操作用于定義變量類型、給變量賦值。常用的有以下幾種:數據定義偽操作的一般格式是:[變量名]偽操作操作數[,操作數…]操作數可以是常數、表達式或字符串,但每項操作數的值不能超過偽操作所定義的數據類型限定的范圍。,例1:DATA_BDB10,5,10HDATA_WDW100H,-4DATA_DDD0FFFBH匯編后的內存分配情況如右圖所示。,,例2:操作數可以是字符串,例如STRDB‘HELLO’匯編后的情況如圖:,注意下面兩個定義的不同之處:DB‘AB’;41H在低字節(jié),42H在高字節(jié)DW‘AB’;42H在低字節(jié),41H在高字節(jié),,,,用DW定義字符串只允許包含兩個字符,否則必須用DB指令;字符串的個數不超過255個;字符串必須用單引號引起來。,幾點說明:,操作數?用來保留存儲空間,但不存入數據。例3:ABCDB0,1,2,3,4,’OK’,’$’RSVDW?,?,?,?,?,?,?,?復制操作符DUP:重復的數據可以使用復制操作符DUP,如上面RSV亦可寫成:RSVDW8DUP(?),3.3.3符號定義偽操作,符號定義偽操作用于給一個符號重新命名,或定義新的類型屬性等。這里的符號可以是匯編語言中所用的變量名、標號名、過程名、記錄名、寄存器名以及指令助記符等。常用的符號定義偽操作有EQU、=、LABELEQU格式:名字EQU表達式作用:用名字代替一個數值,或一個較長的表達式。舉例:HPIXELEQU1024VPIXELEQU768SCREENEQUHPIXEL*VPIXEL,符號定義偽操作,=格式:名字=表達式作用:類似EQU,區(qū)別在于“=”可以對一個名字重復定義。舉例:COUNT=10MOVCX,COUNT;(CX)←10COUNT=COUNT-1MOVBX,COUNT;;(BX)←9LABEL格式:名字LABEL表達式作用:定義標號或變量的類型。舉例:AREAWLABELWORDMOVAREAW,AX;AX送AREAW的第1、2字節(jié)中,3.3.4段定義偽操作,段定義偽操作用于在匯編語言源程序中定義邏輯段。常用的段定義偽操作有SEGMENT/ENDS、ASSUMESEGMENT/ENDS格式:段名SEGMENT[定位類型][組合類型][‘類別’]作用:定義一個邏輯段舉例:STACKSEGMENTDB100DUP(?)STACKENDS“定位類型”告訴編譯器如何確定邏輯段的邊界在存儲器中的位置,即對齊方式。有PARA、BYTE、WORD和PAGE四種?!敖M合類型”告訴編譯器在裝入程序時各個邏輯段如何組合?!邦悇e”的作用是在連接時決定各邏輯段的裝入順序。,段定義偽操作,ASSUME格式:ASSUME段寄存器:段名[,段寄存器:段名[,…]]說明:將某一個段寄存器和某一個邏輯段進行關聯?!岸蚊笨梢允窃肧EGMENT操作符定義過的一個段名,或是在一個標號或變量前面加上SEG構成的表達式,還可以是關鍵字NOTHING。需要注意的是,ASSUME僅僅是通知編譯器有關段寄存器和邏輯段的關系,并沒有為段寄存器賦予實際的初值。舉例:ASSUMECS:CODE,DS:DATA1,SS:STACKASSUMEDS:SEGAREA1ASSUMEES:NOTHING;取消前面ASSUME對ES的設置,3.3.5過程定義偽操作,過程定義偽操作命令為PROC/ENDP。PROC/ENDP格式:過程名PROC[NEAR/FAR]…RET過程名ENDP作用:定義一個過程,賦予過程一個名字,并指出過程的類型,并指出該過程的類型是NEAR或FAR。如果沒有特別指明,則認為過程類型是NEAR。偽操作碼ENDP標志過程定義結束。注意:PROC和ENDP必須成對出現。,過程的類型有兩種:NEAR——(默認類型)表示段內調用;(SP)?(SP-2);((SP+1):(SP))?(IP);FAR——表示段間調用。調用一個過程的格式為:CALL,3.3.6模塊定義與連接偽操作(了解),在編寫規(guī)模較大的匯編語言程序時,可將程序劃分成幾個獨立的源程序模塊,分別進行匯編,最后統一連接。各個模塊之間可以相互進行符號訪問。命令為NAME、END、PUBLIC和EXTRN。NAME格式:Name模塊名作用:指定源文件匯編后的目標文件名稱END格式:END[標號]作用:表示源程序到此結束,對于END后面語句不予理會,模塊定義與連接偽操作(了解),PUBLIC格式:PUBLIC符號[,…]作用:說明本模塊中的某些符號是公共的,即這些符號可以供將被連接在一起的其他模塊使用說明:“符號”可以是本模塊中定義的變量、標號或數值的名字,包括用PROC定義的過程名等。EXTRN格式:EXTRN名字:類型[,…]作用:說明本模塊中所用的某些符號是外部的,即這些符號在將被連接在一起的其他模塊中定義(定義這些符號的模塊中還必須用PUBLIC說明)。,3.3.7宏處理偽操作,如果在程序中需要多次使用一個程序段,可將其定義為宏。每次需要時,直接進行調用,稱為宏調用?!纠眠^程(PROC)可以實現類似功能。區(qū)別在于:宏在編譯時就插入每個宏調用處(這稱為“宏擴展”);而過程是在執(zhí)行時進行跳轉。過程具有更優(yōu)的空間效率,而宏則具有更優(yōu)的時間效率?!縈ACRO/ENDM格式:宏指令名MACRO……;(宏定義體)ENDM作用:將宏指令名定義為宏定義體中包含的程序段。,宏處理偽操作,宏定義偽操作允許帶參數,從而具有更強的通用性。例:定義一個宏,用于兩個壓縮的BCD數相加,結果放在第一個操作數中。DECADDMACROOPR1,OPR2MOVAL,OPR1ADDAL,OPR2DAAMOVOPR1,ALENDM下面使用debug來觀察該例中“宏擴展”是如何進行的:,源文件,反匯編并執(zhí)行觀察結果,3.4DOS和BIOS調用(了解),DOS和BIOS為用戶提供了兩組系統服務程序。BIOS是IBMPC的基本IO系統,包括系統測試程序、初始化引導程序、一部分中斷矢量裝入程序以及部分外設的服務程序。這些程序都固化在主板上的ROM中。DOS是IBMPC的操作系統,負責管理系統的所有資源。其中包括大量可供用戶調用的服務程序。DOS和BIOS調用不是使用CALL命令,而采用軟中斷指令INTn。,DOS和BIOS調用,用戶程序控制PC機硬件的方式使用高級語言提供的功能控制硬件調用方便,但靈活性較低、速度較慢。使用DOS提供的程序控制硬件調用較為方便,程序可移植性好,編程簡單。使用BIOS提供的程序控制硬件這種控制比較低層,因而可移植性差,但效率更高。直接訪問硬件要求用戶對硬件非常熟悉。此種方式只用于兩種情況:為了獲得高效率,或是為了獲得DOS和BIOS不支持的功能。,DOS調用,8086指令系統中,有一條軟中斷指令INTn。當n=5~1FH時,調用BIOS服務程序;當n=20~3FH時,調用DOS服務程序。下表列出了部分DOS軟中斷的功能:,,INT21H調用,其中INT21H是一個具有完整功能的服務程序,一般稱之為DOS系統功能調用。是最常用的DOS中斷。INT21H中斷具有近90個子功能,大致分為4個方面:設備管理、目錄管理、文件管理和其他。系統功能調用(INT21H)的使用步驟如下:置系統功能號n(放入AH)置入口參數執(zhí)行INT21H分析出口參數,INT21H調用示例,例:從鍵盤讀入一個字符,判斷是Y還是N,以執(zhí)行對應操作。,資料:功能號01H的int21H中斷功能描述:從標準輸入設備(如:鍵盤)讀入一個字符功能號:AH=01H,過濾掉控制字符,并回顯出口參數:AL=輸入字符的ASCII碼,KEY:MOVAH,1INT21H;執(zhí)行調用CMPAL,‘Y’JEYESCMPAL,‘N’JENOJMPKEY;輸入其他字符,退回繼續(xù)等待輸入YES:……NO:……,BIOS調用,下面列出了部分BIOS中斷:,關于BIOS中斷的所有中斷號內容(從05H~1FH),參見書附錄3.3,Review,BIOS調用,BIOS調用的使用步驟如下:置系統功能號n(放入AH)置入口參數執(zhí)行INTn分析出口參數舉鍵盤輸入服務(INT16H)為例。其主要功能有三個,分別用于讀鍵盤、讀擴展鍵盤和讀取功能鍵,分別對應功能號0、1、2(AH=0、1、2)。下面一段程序的功能是:按下F1和F2鍵,分別執(zhí)行兩段不同的程序,按其他鍵則轉至錯誤處理。,INT16H調用示例,資料:功能號00H的int16H中斷功能描述:從鍵盤讀入字符入口參數:AH=00H出口參數:AH=鍵盤的掃描碼AL=字符的ASCII碼,MOVAH,0INT16H;執(zhí)行調用CMPAL,0JNEERROR;若為字符鍵,轉ERRORCMPAH,3BH;F1鍵碼為3BHJETT1CMPAH,3CH;F2鍵碼為3CHJETT2JMPERRTT1:……;處理F1鍵功能TT2:……;處理F2鍵功能ERR:……,資料:鍵碼又稱鍵盤掃描碼,F1鍵碼為3BHF2鍵碼為3CH,INT10H調用示例,從上頁的例子中,可以看出,同樣的功能,往往既可以用BIOS中斷調用來實現,也可以用DOS中斷調用來實現。比如磁盤服務、鍵盤服務、顯示字符等。差別在于:BIOS中斷調用往往功能更強大、控制更靈活。例:INT10H功能號09H,“在當前光標位置顯示字符”。,MOVAH,9;顯示字符MOVAL,‘a’;字符MOVBL,0Ch;0表示背景黑色,0Ch表示字符紅色MOVBH,0;第0頁MOVCX,8;字符重復個數INT10h,INT10H調用示例—運行結果,提示:由于程序運行在“虛擬”的8086模式下,在操作硬件時跟純DOS仍存在一定差異。如果程序直接雙擊運行時結果跟預期不符,(比如窗口一閃而過)可使用debug加載然后輸入g運行。,匯編語言設計舉例,字符串查找內存中已經存有一張表,要求從鍵盤上輸入一個字符串,然后在表中查找該字符串,如有,則在屏幕上顯示“OK!”;如果沒有,則顯示“NO!”;若輸入字符串長度超過內存中表的長度,則顯示“Wrong!Thestringistoolong!”邏輯分析:查找可以分兩步進行,先在表中搜索字符串的第一個字符,如有,再比較字符串的其他字符是否一致。功能可行性分析:在屏幕上顯示字符串可以使用功能號09H的21號中斷;從鍵盤上接收字符串可以使用功能號0AH的21號中斷。,教材P213,流程圖,顯示提示符,從鍵盤接收提示符,字符串首址送SI,表首址送DI字符串長度送BX,表長度送CX,表長>=串長,搜索、匹配等工作,開始,返回,顯示“串太長”,,,,,,,具體見教材P214,資料1:功能號09H的int21H中斷,功能描述:顯示字符串(串尾字符為$,但不顯示)入口參數:AH=09HDS:DX=被顯示字符串的首地址出口參數:無,dataSEGMENTmsgDBHello,World!$dataENDScodeSEGMENTASSUMECS:code,DS:dataMAINPROCNEARstart:MOVAX,dataMOVDS,AXLEADX,msgMOVAH,9hINT21hMOVAH,4ChINT21hMAINENDPcodeENDSENDstart,例如:,資料2:功能號0AH的int21H中斷,功能描述:從標準輸入設備(如:鍵盤)讀入一個字符串,遇到“回車鍵”結束輸入。入口參數:AH=0AHDS:DX=存放輸入字符的起始地址接受輸入字符串緩沖區(qū)的定義說明:1、第一個字節(jié)為緩沖區(qū)的最大容量;2、第二個字節(jié)為實際輸入的字符數(不包括回車鍵);3、從第三個字節(jié)開始存放實際輸入的字符串;4、字符串以回車鍵結束,回車符是接受的最后一個字符;5、若輸入的字符數超過緩沖區(qū)的最大容量,則多出的部分被丟棄,直到輸入“回車”鍵才結束輸入。例如:BUFFDB80,?,80DUP(?);最多接受80個字符(含回車符)出口參數:無,源碼分析1,DATASEGMENTTABLEDB‘ABCDEFGHIJKLMNOPQRSTUVWXYZ’STR1DB‘Pleaseenterastring:’,0DH,0AH,’$’STR2DB‘Wrong!Thestringistoolong!$’STR3DB‘No!$’STR4DB‘OK!$’BUFFERDB40DB?DB40DUP(?)TAB_LENEQU26DATAENDSSTACKSEGMENTSTACKDB100DUP(?)STACKENDS,堆棧段定義,數據段定義,源碼分析2,CODESEGMENTASSUMECS:CODE,DS:DATA,ES:DATA,SS:STACKSEARCHPROCFARSTART:MOVAX,DATAMOVDS,AXMOVES,AXLEADX,STR1;MOVAH,09;INT21H;,顯示提示符,源碼分析3,LEADX,BUFFER;參見“0AH號系統調用”資料MOVAH,0AHINT21H;從鍵盤接收字符串MOVSI,DX;(SI)←串首址INCSIMOVBL,[SI];參閱“0AH號系統調用”資料MOVBH,0;(BX)←實際輸入字符串長度INCSI;將SI指向輸入字符串首字母LEADI,TABLE;(DI)←表首址MOVCX,TAB_LEN;(CX)←表長度CMPCX,BX;表長>=串長?JNCGOON;是,轉GOONLEADX,STR2;JMPEXIT;否則顯示串太長,源碼分析4,GOON:CLDMOVAL,[SI];(AL)←字符串第一個字符SCAN:REPNZSCASB;在表中搜索第一個字符JZMATCH;找到,轉MATCHERROR:LEADX,STR3;否則,顯示‘NO!’JMPEXITMATCH:INCCXCMPCX,BX;剩余表長>=串長?JCERROR;否,顯示‘NO!’PUSHCXPUSHSIPUSHDIMOVCX,BXDECDIREPZCMPSB;比較串中其余字符,源碼分析5,POPDIPOPSIPOPCXJZFOUND;找到字符串,轉FOUNDJCXZERROR;否則,若全表搜索完,顯示‘No!’JMPSCAN;全表未搜索完,轉SCANFOUND:DECDI;(DI)←字符串偏移地址LEADX,STR4;顯示’OK!’EXIT:MOVAH,09HINT21H;顯示退出字符串MOVAH,4CHINT21HSEARCHENDPCODEENDSENDSTART,如何閱讀匯編代碼(供參考),對于較長的匯編代碼,可通過“分塊法”閱讀。也就是根據記憶中的既有模板,將源碼拆成多個“功能塊”。這要求對一些基本模板要有一定印象。(比如:功能號09H的INT21調用模板;查找字符串、對比字符串的模板。一些常用功能的實現往往有其相對固定的套路,在源碼中能較容易看出。大家可以自己試著總結。)同時可以借助于一些標記,比如“INTxx”往往標記著一個功能塊的結束,那么可以循著往上尋找出一個完整的功能塊;“標號”也可以幫助拆分功能塊,尤其是書寫優(yōu)秀的源碼,往往采用有意義、一目了然的標號??傊?,閱讀匯編源碼要注意積累。在閱讀別人源碼時要加以留心并注意總結,逐步提升自己水平。,匯編語言程序設計小節(jié)尋址方式——存儲器操作數的尋址方式;指令系統——8088/8086指令系統;匯編語言——掌握各種“格式”、規(guī)則等;匯編高手——勇于實踐,觸類旁通??!,題2-11、題2-12、題2-13題3-1、題3-4、題3-5、題3-7,作業(yè),- 配套講稿:
如PPT文件的首頁顯示word圖標,表示該PPT已包含配套word講稿。雙擊word圖標可打開word文檔。
- 特殊限制:
部分文檔作品中含有的國旗、國徽等圖片,僅作為作品整體效果示例展示,禁止商用。設計者僅對作品中獨創(chuàng)性部分享有著作權。
- 關 鍵 詞:
- 東南大學 電子信息工程 微機 學時 匯編語言
裝配圖網所有資源均是用戶自行上傳分享,僅供網友學習交流,未經上傳用戶書面授權,請勿作他用。
鏈接地址:http://m.hcyjhs8.com/p-11501756.html