微機(jī)原理第3章-匯編語(yǔ)言程序設(shè)計(jì)_第1頁(yè)
微機(jī)原理第3章-匯編語(yǔ)言程序設(shè)計(jì)_第2頁(yè)
微機(jī)原理第3章-匯編語(yǔ)言程序設(shè)計(jì)_第3頁(yè)
微機(jī)原理第3章-匯編語(yǔ)言程序設(shè)計(jì)_第4頁(yè)
微機(jī)原理第3章-匯編語(yǔ)言程序設(shè)計(jì)_第5頁(yè)
已閱讀5頁(yè),還剩231頁(yè)未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

第3章第3章:匯編語(yǔ)言的特點(diǎn)匯編語(yǔ)言是一種以處理器指令系統(tǒng)為基礎(chǔ)的低級(jí)程序設(shè)計(jì)語(yǔ)言,它采用助記符表達(dá)指令操作碼,采用標(biāo)識(shí)符號(hào)表示指令操作數(shù)利用匯編語(yǔ)言編寫程序的主要優(yōu)點(diǎn)是可以直接、有效地控制計(jì)算機(jī)硬件,因而容易創(chuàng)建代碼序列短小、運(yùn)行快速的可執(zhí)行程序在有些應(yīng)用領(lǐng)域,匯編語(yǔ)言的作用是不容置疑和無(wú)可替代的匯編程序設(shè)計(jì)的過(guò)程是與其他高級(jí)語(yǔ)言程序設(shè)計(jì)大致相同第3章:教學(xué)重點(diǎn)匯編語(yǔ)言源程序格式與開發(fā)常量、變量和標(biāo)號(hào)匯編語(yǔ)言程序設(shè)計(jì)方法順序程序設(shè)計(jì)分支程序設(shè)計(jì)循環(huán)程序設(shè)計(jì)子程序設(shè)計(jì)第3章:3.1匯編語(yǔ)言源程序格式完整的匯編語(yǔ)言源程序由段組成一個(gè)匯編語(yǔ)言源程序可以包含若干個(gè)代碼段、數(shù)據(jù)段、附加段或堆棧段,段與段之間的順序可隨意排列需獨(dú)立運(yùn)行的程序必須包含一個(gè)代碼段,并指示程序執(zhí)行的起始點(diǎn),一個(gè)程序只有一個(gè)起始點(diǎn)所有的可執(zhí)行性語(yǔ)句必須位于某一個(gè)代碼段內(nèi),說(shuō)明性語(yǔ)句可根據(jù)需要位于任一段內(nèi)通常,程序還需要一個(gè)堆棧段

源程序由語(yǔ)句序列構(gòu)成第3章:匯編語(yǔ)言的語(yǔ)句格式⑴執(zhí)行性語(yǔ)句——執(zhí)行性語(yǔ)句用于表達(dá)處理器指令(也稱為硬指令),匯編后對(duì)應(yīng)一條指令代碼。由處理器指令組成的代碼序列是程序設(shè)計(jì)的主體標(biāo)號(hào):

硬指令助記符操作數(shù),操作數(shù)

;注釋⑵說(shuō)明性語(yǔ)句——說(shuō)明性語(yǔ)句用于表達(dá)偽指令,指示源程序如何匯編、變量怎樣定義、過(guò)程怎么設(shè)置等名字偽指令助記符

參數(shù),參數(shù),……;注釋第3章:硬指令與偽指令硬指令(Instruction)——使CPU產(chǎn)生動(dòng)作、并在程序執(zhí)行時(shí)才處理的指令

硬指令就是第2章學(xué)習(xí)的處理器指令,與具體的處理器有關(guān)、與匯編程序無(wú)關(guān)偽指令(Directive)——不產(chǎn)生CPU動(dòng)作、在程序執(zhí)行前由匯編程序處理的說(shuō)明性指令

偽指令與具體的處理器類型無(wú)關(guān),但與匯編程序有關(guān)。不同版本的匯編程序支持不同的偽指令

硬指令和偽指令采用易于記憶的符合表達(dá),這就是助記符第3章:標(biāo)號(hào)、名字與標(biāo)識(shí)符標(biāo)號(hào)是反映硬指令位置(邏輯地址)和屬性的標(biāo)識(shí)符,后跟一個(gè)冒號(hào)分隔名字是反映偽指令位置(邏輯地址)和屬性的標(biāo)識(shí)符,后跟空格或制表符分隔,沒(méi)有冒號(hào)標(biāo)識(shí)符(Identifier)一般最多由31個(gè)字母、數(shù)字及規(guī)定的特殊符號(hào)(如_、$、?、@)組成,不能以數(shù)字開頭。默認(rèn)情況下,匯編程序不區(qū)別標(biāo)識(shí)符中的字母大小寫一個(gè)源程序中,每個(gè)標(biāo)識(shí)符的定義是唯一的,還不能是匯編語(yǔ)言采用的保留字第3章:保留字保留字(ReservedWord)是匯編程序已經(jīng)利用的標(biāo)識(shí)符(也稱為關(guān)鍵字),主要有:硬指令助記符——例如:MOV、ADD偽指令助記符——例如:DB、DW操作符——例如:OFFSET、PTR寄存器名——例如:AX、CS預(yù)定義符號(hào)——例如:@data

匯編語(yǔ)言大小寫不敏感第3章:操作數(shù)和參數(shù)處理器指令的操作數(shù)可以是立即數(shù)、寄存器和存儲(chǔ)單元偽指令的參數(shù)可以是常數(shù)、變量名、表達(dá)式等,可以有多個(gè),參數(shù)之間用逗號(hào)分隔第3章:注釋語(yǔ)句中由分號(hào)“;”開始的部分為注釋內(nèi)容,用以增加源程序的可讀性必要時(shí),一個(gè)語(yǔ)句行也可以由分號(hào)開始作為階段性注釋匯編程序在翻譯源程序時(shí)將跳過(guò)該部分,不對(duì)它們做任何處理第3章:分隔符語(yǔ)句的4個(gè)組成部分要用分隔符分開標(biāo)號(hào)后用冒號(hào),注釋前用分號(hào)操作數(shù)之間和參數(shù)之間使用逗號(hào)分隔其他部分通常采用空格或制表符多個(gè)空格和制表符的作用與一個(gè)相同MASM支持續(xù)行符“\”第3章:例3.1在屏幕上顯示一段信息 ;數(shù)據(jù)段(定義要顯示的字符串)string db’Hello,Assembly!’,0dh,0ah,’$’

;代碼段(顯示字符串的程序)

movdx,offsetstring

movah,9

int21h

Hello,Assembly!程序功能第3章:3.1.1簡(jiǎn)化段定義格式 .modelsmall ;定義程序的存儲(chǔ)模式(小型模式)

.stack ;定義堆棧段(默認(rèn)是1KB空間) .data ;定義數(shù)據(jù)段

…… ;數(shù)據(jù)定義 .code ;定義代碼段start: movax,@data ;程序起始點(diǎn)

movds,ax ;設(shè)置DS指向用戶定義的數(shù)據(jù)段

…… ;程序代碼 movax,4c00h int21h ;程序結(jié)束點(diǎn),返回DOS …… ;子程序代碼 endstart ;匯編結(jié)束,同時(shí)指明程序起始點(diǎn)start第3章:第一個(gè)源程序文件wjl301.asm;wjl301.asm .modelsmall .stack .datastring db’Hello,Assembly!’,0dh,0ah,’$’ .code start: movax,@data movds,ax movdx,offsetstring movah,9 int21h

movax,4c00h int21h

endstart第3章:匯編語(yǔ)言程序的開發(fā)過(guò)程(附錄B)編輯文本編輯器,如記事本程序源程序:文件名.asm匯編匯編程序,如MASM.EXE目標(biāo)模塊:文件名.obj連接連接程序,如LINK.EXE可執(zhí)行文件:文件名.exe調(diào)試調(diào)試程序,如DEBUG.EXE應(yīng)用程序錯(cuò)誤錯(cuò)誤錯(cuò)誤錯(cuò)誤開發(fā)過(guò)程1:源程序的編輯源程序文件要以ASM為擴(kuò)展名源程序文件的形成(編輯)可以通過(guò)任何一個(gè)文本編輯器實(shí)現(xiàn):DOS中的全屏幕文本編輯器EDIT其他程序開發(fā)工具中的編輯環(huán)境(如UltraEdit)Windows中的記事本NotepadEDITwjl301.asm開發(fā)過(guò)程2:源程序的匯編(MASM6.x)匯編是將源程序翻譯成由機(jī)器代碼組成的目標(biāo)模塊文件的過(guò)程MASM6.x提供的匯編程序是ML.EXE:ML/cwjl301.asm如果源程序中沒(méi)有語(yǔ)法錯(cuò)誤,MASM將自動(dòng)生成一個(gè)目標(biāo)模塊文件(wjl301.obj);否則MASM將給出相應(yīng)的錯(cuò)誤信息。這時(shí)應(yīng)根據(jù)錯(cuò)誤信息,重新編輯修改源程序后,再進(jìn)行匯編開發(fā)過(guò)程2:源程序的匯編(MASM3.x)MASM3.x提供的匯編程序是MASM.EXE:MASMwjl301.asm;如果利用分號(hào)“;”結(jié)尾命令,則匯編程序不再提示輸入模塊文件名、列表文件名等,直接采用默認(rèn)的文件名。默認(rèn)采用源程序文件相同的主文件名,擴(kuò)展名則是相應(yīng)類型文件的擴(kuò)展名,例如模塊文件(.obj)和列表文件(.lst)等開發(fā)過(guò)程2:源程序的匯編(生成列表文件)匯編過(guò)程中,可以通過(guò)參數(shù)選擇生成列表文件(.LST)。列表文件是一種文本文件,含有源程序和目標(biāo)代碼,對(duì)我們學(xué)習(xí)匯編語(yǔ)言程序設(shè)計(jì)和發(fā)現(xiàn)錯(cuò)誤很有用匯編程序ML.EXE和MASM.EXE都可帶其他參數(shù),為了生成列表文件,各自的命令是: ML/Flwjl301.asm MASM/lwjl301.asm;該命令除產(chǎn)生模塊文件wjl301.obj(和可執(zhí)行文件wjl301.exe)外,還將生成列表文件wjl301.lst開發(fā)過(guò)程3:目標(biāo)模塊的連接連接程序能把一個(gè)或多個(gè)目標(biāo)文件和庫(kù)文件合成一個(gè)可執(zhí)行程序(.EXE、.COM文件):LINKwjl301.obj;如果沒(méi)有嚴(yán)重錯(cuò)誤,LINK將生成一個(gè)可執(zhí)行文件(wjl301.exe);否則將提示相應(yīng)的錯(cuò)誤信息。這時(shí)需要根據(jù)錯(cuò)誤信息重新修改源程序文件后再匯編、鏈接,直到生成可執(zhí)行文件ML.EXE匯編程序(MASM6.x)可自動(dòng)調(diào)用LINK連接程序,實(shí)現(xiàn)匯編和連接的依次進(jìn)行MLwjl301.asm開發(fā)過(guò)程4:可執(zhí)行程序的調(diào)試經(jīng)匯編、連接生成的可執(zhí)行程序在操作系統(tǒng)下只要輸入文件名就可以運(yùn)行:wjl301操作系統(tǒng)裝載該文件進(jìn)入主存,并開始運(yùn)行如果出現(xiàn)運(yùn)行錯(cuò)誤,可以從源程序開始排錯(cuò),也可以利用調(diào)試程序幫助發(fā)現(xiàn)錯(cuò)誤采用DEBUG.EXE調(diào)試程序:DEBUGwjl301.exe第3章:1.存儲(chǔ)模式(MemoryModel)存儲(chǔ)模式?jīng)Q定了一個(gè)程序的規(guī)模,也確定了子程序調(diào)用、指令轉(zhuǎn)移和數(shù)據(jù)訪問(wèn)等的缺省屬性當(dāng)使用簡(jiǎn)化段定義的源程序格式時(shí),必須有存儲(chǔ)模式.MODEL語(yǔ)句,且位于所有簡(jiǎn)化段定義語(yǔ)句之前。其格式為:

.MODEL存儲(chǔ)模式.MODEL語(yǔ)句確定了程序采用的存儲(chǔ)模式,MASM有7種可以選擇,如表4.1所示

本課程學(xué)習(xí)過(guò)程中,均采用小型模式SMALL第3章:2.邏輯段的簡(jiǎn)化定義.STACK[大小];堆棧段定義偽指令.STACK創(chuàng)建一個(gè)堆棧段,段名是:STACK??蛇x的“大小”參數(shù)指定堆棧段所占存儲(chǔ)區(qū)的字節(jié)數(shù),默認(rèn)是1KB(=1024=400H字節(jié)).DATA;數(shù)據(jù)段定義偽指令.DATA創(chuàng)建一個(gè)數(shù)據(jù)段,段名是:_DATA。數(shù)據(jù)段名可用@DATA預(yù)定義標(biāo)識(shí)符表示.CODE[段名];代碼段定義偽指令.CODE創(chuàng)建一個(gè)代碼段,可選的“段名”參數(shù)指定該代碼段的段名。如果沒(méi)有給出段名,則采用默認(rèn)段名

一個(gè)段的開始自動(dòng)結(jié)束前面的一個(gè)段

簡(jiǎn)化段定義偽指令之前,需有存儲(chǔ)模式語(yǔ)句第3章:4.程序開始為了指明程序開始執(zhí)行的位置,需要使用一個(gè)標(biāo)號(hào)(例題中采用了start標(biāo)識(shí)符)連接程序會(huì)根據(jù)程序起始點(diǎn)正確地設(shè)置CS和IP值,根據(jù)程序大小和堆棧段大小設(shè)置SS和SP值連接程序沒(méi)有設(shè)置DS和ES值。程序如果使用數(shù)據(jù)段或附加段,必須明確給DS或ES賦值大多數(shù)程序需要數(shù)據(jù)段,程序的執(zhí)行開始應(yīng)是:start: movax,@data

;@data表示數(shù)據(jù)段的段地址

movds,ax

;設(shè)置DS第3章:4.程序終止應(yīng)用程序執(zhí)行結(jié)束,應(yīng)該將控制權(quán)交還操作系統(tǒng)匯編語(yǔ)言程序設(shè)計(jì)中,有多種返回DOS的方法,但一般利用DOS功能調(diào)用的4CH子功能實(shí)現(xiàn),它需要的入口參數(shù)是AL=返回?cái)?shù)碼(通常用0表示程序沒(méi)有錯(cuò)誤)于是,應(yīng)用程序的終止代碼就是:

movax,4c00h int21h第3章:5.匯編結(jié)束匯編結(jié)束表示匯編程序到此結(jié)束將源程序翻譯成目標(biāo)模塊代碼的過(guò)程源程序的最后必須有一條END偽指令

END[標(biāo)號(hào)]可選的“標(biāo)號(hào)”參數(shù)指定程序開始執(zhí)行點(diǎn),連接程序據(jù)此設(shè)置CS和IP值(例題中采用了start標(biāo)識(shí)符)

————不要糊涂————程序終止和匯編結(jié)束是兩碼事第3章:第一個(gè)源程序文件wjl301.asm;wjl301.asm .modelsmall .stack .datastring db’Hello,Assembly!’,0dh,0ah,’$’ .code start: movax,@data movds,ax movdx,offsetstring movah,9 int21h

movax,4c00h int21h

endstart第3章:簡(jiǎn)化段定義的源程序格式 .modelsmall ;小型模式存儲(chǔ)模式

.stack ;1KB空間堆棧段

.data ;數(shù)據(jù)段

…… ;數(shù)據(jù)定義 .code ;代碼段start: movax,@data ;起始點(diǎn)

movds,ax ;設(shè)置DS …… ;程序代碼 movax,4c00h int21h ;結(jié)束點(diǎn),返回DOS …… ;子程序代碼 endstart ;匯編結(jié)束第3章:3.1.2完整段定義格式完整段定義利用SEGMENT和ENDS一對(duì)偽指令定義邏輯段同時(shí)需要配合ASSUME偽指令指明邏輯段是代碼段、堆棧段、數(shù)據(jù)段還是附加段完整段定義的優(yōu)勢(shì)是可以指明邏輯段的定位、組合、類別等屬性;而簡(jiǎn)化段定義只能采用系統(tǒng)默認(rèn)的屬性完整段定義和簡(jiǎn)化段定義的實(shí)質(zhì)是一致的第3章:3.1.3可執(zhí)行程序的結(jié)構(gòu)DOS操作系統(tǒng)支持兩種可執(zhí)行程序結(jié)構(gòu)1.EXE程序程序可以有多個(gè)代碼段和多個(gè)數(shù)據(jù)段,程序長(zhǎng)度可以超過(guò)64KB通常生成EXE結(jié)構(gòu)的可執(zhí)行程序2.COM程序只有一個(gè)邏輯段,程序長(zhǎng)度不超過(guò)64KB需要滿足一定條件才能生成COM結(jié)構(gòu)的可執(zhí)行程序(MASM6.x需要采用TINY模式)第3章:3.2常量、變量和標(biāo)號(hào)匯編語(yǔ)言的數(shù)據(jù)可以簡(jiǎn)單分為常量和變量常量可以作為硬指令的立即數(shù)或偽指令的參數(shù),變量主要作為存儲(chǔ)器操作數(shù)匯編語(yǔ)言語(yǔ)句中的名字和標(biāo)號(hào)具有邏輯地址和類型屬性,主要用做地址操作數(shù),也可以作為立即數(shù)和存儲(chǔ)器操作數(shù)本節(jié)將詳細(xì)討論語(yǔ)句中的參數(shù)和操作數(shù)、名字和標(biāo)號(hào),并引出相關(guān)的偽指令和操作符第3章:3.2.1常量常量表示一個(gè)固定的數(shù)值,它又分成多種形式常數(shù)字符串符合常量數(shù)值表達(dá)式第3章:1.常數(shù)指由10、16、2和8進(jìn)制形式表達(dá)的數(shù)值,各種進(jìn)制的數(shù)據(jù)以后綴字母區(qū)分,默認(rèn)不加后綴字母的是十進(jìn)制數(shù)十進(jìn)制由0~9數(shù)字組成,以字母D(d)結(jié)尾(缺省情況可以省略)100,255D十六進(jìn)制由0~9、A~F數(shù)字組成,以字母H(h)結(jié)尾,以字母開頭的常數(shù)需要加一個(gè)前導(dǎo)064H,0FFH0B800H二進(jìn)制由0和1兩個(gè)數(shù)字組成,以字母B(b)結(jié)尾01100100B第3章:2.字符串字符串常量是用單引號(hào)或雙引號(hào)括起來(lái)的單個(gè)字符或多個(gè)字符其數(shù)值是每個(gè)字符對(duì)應(yīng)的ASCII碼值例如:

‘d’(等于64H)

‘AB’(等于4142H)

‘Hello,Assembly!’第3章:4.符號(hào)常量符號(hào)常量使用標(biāo)識(shí)符表達(dá)一個(gè)數(shù)值MASM提供等價(jià)機(jī)制,用來(lái)為常量定義符號(hào)名符號(hào)定義偽指令有“等價(jià)EQU”和“等號(hào)=”: 符號(hào)名EQU

數(shù)值表達(dá)式

符號(hào)名EQU<字符串> ;MASM3.x不支持

符號(hào)名=數(shù)值表達(dá)式EQU用于數(shù)值等價(jià)時(shí)不能重復(fù)定義符號(hào)名,但“=”允許有重復(fù)賦值。例如: X =7 ;等效于:Xqeu7 X =X+5 ;“XEQUX+5”是錯(cuò)誤的第3章:4.數(shù)值表達(dá)式數(shù)值表達(dá)式一般是指由運(yùn)算符連接的各種常量所構(gòu)成的表達(dá)式匯編程序在匯編過(guò)程中計(jì)算表達(dá)式,最終得到一個(gè)確定的數(shù)值,所以也是常量表達(dá)式的數(shù)值在程序運(yùn)行前的匯編階段計(jì)算,所以組成表達(dá)式的各部分必須在匯編時(shí)就能確定匯編語(yǔ)言支持多種運(yùn)算符(表4.4)我們經(jīng)常使用的是加減乘除(+-*/

)例如:movax,3*4+5 ;等價(jià)于:movax,17第3章:3.2.2變量變量實(shí)質(zhì)上是指內(nèi)存單元的數(shù)據(jù),雖然內(nèi)存單元地址不變,但其中存放的數(shù)據(jù)可以改變變量需要事先定義才能使用變量定義(Define)偽指令為變量申請(qǐng)固定長(zhǎng)度為單位的存儲(chǔ)空間,并可以同時(shí)將相應(yīng)的存儲(chǔ)單元初始化定義后的變量可以利用變量名等方法引用其中的數(shù)據(jù),即變量的數(shù)值第3章:1.變量的定義變量定義的匯編語(yǔ)言格式為:

變量名偽指令初值表變量名為用戶自定義標(biāo)識(shí)符,表示初值表首元素的邏輯地址,常稱為符號(hào)地址。變量名也可以沒(méi)有初值表是用逗號(hào)分隔的參數(shù),主要由常量、數(shù)值表達(dá)式或“?”組成。其中“?”表示未賦初值多個(gè)存儲(chǔ)單元如果初值相同,可以用復(fù)制操作符DUP進(jìn)行定義:

重復(fù)次數(shù)DUP(重復(fù)參數(shù))變量定義偽指令有DB、DW、DD等(表4.5)第3章:字節(jié)變量的定義DB(DefineByte)DB偽指令用于分配一個(gè)或多個(gè)字節(jié)單元,并可以將它們初始化為指定值初值表中每個(gè)數(shù)據(jù)一定是字節(jié)量,存放一個(gè)8位數(shù)據(jù):可以是0~255的無(wú)符號(hào)數(shù)或是-128~+127帶符號(hào)數(shù)也可以是字符串常數(shù)實(shí)例字節(jié)變量定義實(shí)例;數(shù)據(jù)段X db'a',-5 db2dup(100),?Y db'ABC'應(yīng)用第3章:字節(jié)變量的應(yīng)用moval,X;此處X表示它的第1個(gè)數(shù)據(jù),故AL←'a'decX+1;對(duì)X為始的第2個(gè)數(shù)據(jù)減1,故成為-6movY,al;現(xiàn)在Y這個(gè)字符串成為'aBC'第3章:字變量的定義DW(DefineWord)DW偽指令用于分配一個(gè)或多個(gè)字單元,并可以將它們初始化為指定值初值表中每個(gè)數(shù)據(jù)是字量,一個(gè)字單元可用于存放任何16位數(shù)據(jù):一個(gè)段地址一個(gè)偏移地址兩個(gè)字符0~65535之間的無(wú)符號(hào)數(shù)-32768~+32767之間的帶符號(hào)數(shù)字變量定義實(shí)例;數(shù)據(jù)段count dw8000h,?,'AB'maxint equ64hnumber dwmaxintarray dwmaxintdup(0)第3章:雙字變量的定義DD(DefineDoubleword)DD偽指令用于分配一個(gè)或多個(gè)雙字單元,并可以將它們初始化為指定值初值表中每個(gè)數(shù)據(jù)是一個(gè)32位的雙字量:可以是有符號(hào)或無(wú)符號(hào)的32位整數(shù)也可以用來(lái)表達(dá)16位段地址(高位字)和16位的偏移地址(低位字)的遠(yuǎn)指針vardd DD0,?,12345678hfarpoint DD00400078h第3章:2.變量的應(yīng)用變量具有存儲(chǔ)單元的邏輯地址程序代碼中通過(guò)變量名引用其指向的首個(gè)數(shù)據(jù)通過(guò)變量名加減位移量存取以首個(gè)數(shù)據(jù)為基地址的前后數(shù)據(jù)例題4.2變量的定義和應(yīng)用第3章:例題3.2變量的定義

;數(shù)據(jù)段bvar1 db100,01100100b,64h,'d'

;字節(jié)變量:不同進(jìn)制表達(dá)同一個(gè)數(shù)值,內(nèi)存中有4個(gè)64Hminint =5 ;符號(hào)常量:minint數(shù)值為5,不占內(nèi)存空間bvar2 db-1,minint,minint+5 ;內(nèi)存中數(shù)值依次為FFH,5,0AH db?,2dup(20h) ;預(yù)留一個(gè)字節(jié)空間,重復(fù)定義了2個(gè)數(shù)值20Hwvar1 dw2010h,4*4

;字變量:兩個(gè)數(shù)據(jù)是2010H、0010H,共占4個(gè)字節(jié)wvar2 dw?;wvar2是沒(méi)有初值的字變量第3章:例題3.2變量的定義(續(xù))dvar dd12347777h,87651111h,? ;雙字變量:2個(gè)雙字?jǐn)?shù)據(jù),一個(gè)雙字空間abc db’a’,’b’,’c’,?

;定義字符,實(shí)際是字節(jié)變量maxint equ0ah

;符號(hào)常量:maxint=10string db’ABCDEFGHIJ’

;定義字符串:使用字節(jié)定義DB偽指令crlfs db13,10,’$’

;回車符0DH、換行符0AH和字符'$'=24Harray1 dwmaxintdup(0)

;10個(gè)初值為0的字量,可以認(rèn)為是數(shù)組array db2dup(2,3,2dup(4))

;6個(gè)字節(jié)內(nèi)容依次為:0203040402030404第3章:例題3.2變量的應(yīng)用;代碼段movdl,bvar1

;DL=100decbvar2+1

;bvar2+1=4movabc[3],dl

;abc=’abcd’movax,wordptrdvar[0]

;取雙字到DX.AXmovdx,wordptrdvar[2]addax,wordptrdvar[4]

;加雙字到DX.AXadcdx,wordptrdvar[6]movwordptrdvar[8],ax

;保存雙字的求和結(jié)果movwordptrdvar[10],dx第3章:例題3.2變量的應(yīng)用(續(xù)) movcx,maxint

;CX=10 movbx,0

;BX=0again: addstring[bx],3

;string每個(gè)數(shù)值加3 incbx loopagain

;循環(huán) leadx,abc

;從abc開始 movah,9

;09H號(hào)DOS功能調(diào)用 int21h;顯示結(jié)果:abcdDEFGHIJKLM第3章:4.變量的定位匯編程序按照指令的先后順序一個(gè)接著一個(gè)分配存儲(chǔ)空間,按照段定義偽指令規(guī)定的邊界定位屬性確定每個(gè)邏輯段的起始位置(包括偏移地址)定位偽指令ORG控制數(shù)據(jù)或代碼所在的偏移地址

ORG

參數(shù)ORG偽指令是將當(dāng)前偏移地址指針指向參數(shù)表達(dá)的偏移地址。例如:

ORG100h

;從100H處安排數(shù)據(jù)或程序

ORG$+10

;偏移地址加10,即跳過(guò)10個(gè)字節(jié)空間匯編語(yǔ)言程序中,符號(hào)“$”表示當(dāng)前偏移地址值第3章:3.2.3名字和標(biāo)號(hào)的屬性名字和標(biāo)號(hào)是用戶自定義的標(biāo)識(shí)符。名字指向一條偽指令,標(biāo)號(hào)指向一條硬指令。名字和標(biāo)號(hào)一經(jīng)使用便具有兩類屬性:⑴邏輯地址——名字和標(biāo)號(hào)對(duì)應(yīng)存儲(chǔ)單元的邏輯地址,含有段地址和偏移地址;⑵類型——變量名的類型可以是BYTE(字節(jié))、WORD(字)和DWORD(雙字)等;標(biāo)號(hào)、段名、子程序名的類型可以是NEAR(近)和FAR(遠(yuǎn)),分別表示段內(nèi)或段間調(diào)用匯編程序提供有關(guān)的操作符,以便獲取這些屬性值第3章:1.地址操作符地址操作符取得名字或標(biāo)號(hào)的段地址和偏移地址[]將括起的表達(dá)式作為存儲(chǔ)器地址指針$當(dāng)前偏移地址:段前綴,采用指定的段地址寄存器OFFSET名字/標(biāo)號(hào)返回名字或標(biāo)號(hào)的偏移地址SEG名字/標(biāo)號(hào)返回名字或標(biāo)號(hào)的段地址第3章:2.類型操作符類型操作符對(duì)名字或標(biāo)號(hào)的類型屬性進(jìn)行設(shè)置

類型名PTR名字/標(biāo)號(hào)其中可以是BYTE、WORD、DWORD(依次表示字節(jié)、字、雙字)等,或者是NEAR、FAR(分別表示近、遠(yuǎn)),還可以是由結(jié)構(gòu)、記錄等定義的類型對(duì)變量:LENGTHOF操作符獲知某變量名指向多少個(gè)數(shù)據(jù)項(xiàng)SIZEOF操作符獲知它共占用多少字節(jié)空間第3章:3.3順序程序設(shè)計(jì)沒(méi)有分支、循環(huán)等轉(zhuǎn)移指令的程序,會(huì)按指令書寫的前后順利依次執(zhí)行,這就是順序程序順序結(jié)構(gòu)是最基本的程序結(jié)構(gòu)完全采用順序結(jié)構(gòu)編寫的程序并不多見(jiàn)例題4.4順序程序設(shè)計(jì)實(shí)例采用查表法,實(shí)現(xiàn)一位16進(jìn)制數(shù)轉(zhuǎn)換為ASCII碼顯示第3章:例3.4數(shù)據(jù)段;數(shù)據(jù)段ASCII db30h,31h,32h,33h,34h,35h,36h,37h,38h,39h

;對(duì)應(yīng)0~9的ASCII碼 db41h,42h,43h,44h,45h,46h

;對(duì)應(yīng)A~F的ASCII碼hex db04h,0bh

;假設(shè)兩個(gè)數(shù)據(jù)第3章:例3.4代碼段

;代碼段movbx,offsetASCII;BX指向ASCII碼表moval,hex ;AL取得一位16進(jìn)制數(shù);恰好就是ASCII碼表中的位移andal,0fh ;只有低4位是有效的,高4位清0xlat;換碼:AL←DS:[BX+AL]XLAT第3章:例3.4代碼段(續(xù))movdl,al ;入口參數(shù):DL←ALmovah,2 ;02號(hào)DOS功能調(diào)用int21h ;顯示一個(gè)ASCII碼字符moval,hex+1 ;轉(zhuǎn)換并顯示下一個(gè)數(shù)據(jù)andal,0fhxlatmovdl,almovah,2int21hXLAT第3章:3.4分支程序設(shè)計(jì)分支程序根據(jù)條件是真或假?zèng)Q定執(zhí)行與否判斷的條件是各種指令,如CMP、TEST等執(zhí)行后形成的狀態(tài)標(biāo)志轉(zhuǎn)移指令Jcc和JMP可以實(shí)現(xiàn)分支控制分支結(jié)構(gòu)有單分支結(jié)構(gòu)雙分支結(jié)構(gòu)多分支結(jié)構(gòu)第3章:?jiǎn)畏种ЫY(jié)構(gòu)條件成立跳轉(zhuǎn),否則順序執(zhí)行分支語(yǔ)句體注意選擇正確的條件轉(zhuǎn)移指令和轉(zhuǎn)移目標(biāo)地址實(shí)例:求絕對(duì)值第3章:計(jì)算AX中有符號(hào)數(shù)的絕對(duì)值

cmpax,0

jgenonneg

;條件滿足(AX≥0),轉(zhuǎn)移

negax

;條件不滿足,求補(bǔ)nonneg:

movresult,ax

;條件滿足

;不恰當(dāng)?shù)姆种?/p>

cmpax,0

jlyesneg

;條件滿足(AX<0),轉(zhuǎn)移 jmpnonnegyesneg:

negax

;條件不滿足,求補(bǔ)nonneg:

movresult,ax

;條件滿足第3章:雙分支結(jié)構(gòu)條件成立跳轉(zhuǎn)執(zhí)行第2個(gè)分支語(yǔ)句體,否則順序執(zhí)行第1個(gè)分支語(yǔ)句體注意第1個(gè)分支體后一定要有一個(gè)JMP指令跳到第2個(gè)分支體后實(shí)例:顯示BX的最高位第3章:顯示BX的最高位 shlbx,1 ;BX最高位移入CF標(biāo)志

jcone

;CF=1,即最高位為1,轉(zhuǎn)移 movdl,30h

;CF=0,即最高位為0:DL←30H=‘0’

jmptwo

;一定要跳過(guò)另一個(gè)分支體one: movdl,31h ;DL←31H=‘1’two: movah,2 int21h ;顯示可以用JNC替換JC第3章:顯示BX的最高位(續(xù)) shlbx,1 ;BX最高位移入CF標(biāo)志

jncone

;CF=0,即最高位為0,轉(zhuǎn)移 movdl,31h

;CF=1,即最高位為1:DL←31H=‘1’

jmptwo

;一定要跳過(guò)另一個(gè)分支體one: movdl,30h ;DL←30H=‘0’two: movah,2 int21h ;顯示轉(zhuǎn)換為單分支結(jié)構(gòu)第3章:顯示BX的最高位(另解) movdl,’0’ ;DL←30H=‘0’ shlbx,1 ;BX最高位移入CF標(biāo)志

jnctwo

;CF=0,即最高位為0,轉(zhuǎn)移 movdl,’1’

;CF=1,即最高位為1:DL←31H=‘1’two: movah,2 int21h ;顯示

編寫分支程序,需留心分支的開始和結(jié)束第3章:顯示BX的最高位(無(wú)分支) movdl,0 shlbx,1 ;BX最高位移入CF標(biāo)志

adcdl,30h

;CF=0,DL←0+30h+0=30H=‘0’

;CF=1,DL←0+30h+1=31H=‘1’two: movah,2 int21h ;顯示第3章:例題3.5顯示壓縮BCD碼,無(wú)前導(dǎo)0 ;數(shù)據(jù)段BCD db04h

;代碼段 movdl,BCD testdl,0ffh

;如果BCD碼為0,顯示0

jzzero

;雙分支結(jié)構(gòu) testdl,0f0h

;如果BCD碼高位為0,不顯示0 jzone ;單分支結(jié)構(gòu)第3章:例題3.5顯示壓縮BCD碼,無(wú)前導(dǎo)0(續(xù))

movcl,4

;處理高位 shrdl,cl ordl,30h

;轉(zhuǎn)換為ASCII碼 movah,2

;顯示高位

int21hone: movdl,BCD

;處理低位 anddl,0fh

ordl,30h

jmptwozero: movdl,’0’two: movah,2 int21h第3章:大小寫字母轉(zhuǎn)換(參例題3.6)

;如果DL是一個(gè)小寫字母,則轉(zhuǎn)換為大寫 cmpdl,‘a(chǎn)’ ;小于小寫字母a,不需要處理 jbdisp cmpdl,‘z’

;大于小寫字母z,也不需要處理 jadisp

subdl,20h

;是小寫字母,則轉(zhuǎn)換為大寫disp: ……轉(zhuǎn)換原理第3章:多分支結(jié)構(gòu)多分支結(jié)構(gòu)是多個(gè)條件對(duì)應(yīng)各自的分支語(yǔ)句體,哪個(gè)條件成立就轉(zhuǎn)入相應(yīng)分支體執(zhí)行AH=0fuction0YNAH=1fuction1YNAH=2fuction2YNorah,ah ;=cmpah,0jzfunction0decah ;=cmpah,1jzfunction0decah ;=cmpah,2jzfunction0第3章:3.5循環(huán)程序設(shè)計(jì)循環(huán)程序結(jié)構(gòu)是滿足一定條件的情況下,重復(fù)執(zhí)行某段程序循環(huán)結(jié)構(gòu)的程序通常有3個(gè)部分:

循環(huán)初始部分——為開始循環(huán)準(zhǔn)備必要的條件,如循環(huán)次數(shù)、循環(huán)體需要的數(shù)值等

循環(huán)體部分——指重復(fù)執(zhí)行的程序部分,其中包括對(duì)循環(huán)條件等的修改程序段循環(huán)控制部分——判斷循環(huán)條件是否成立,決定是否繼續(xù)循環(huán)關(guān)鍵是什么?第3章:循環(huán)控制循環(huán)結(jié)構(gòu)程序的設(shè)計(jì)關(guān)鍵是循環(huán)控制部分循環(huán)控制可以在進(jìn)入循環(huán)之前進(jìn)行,也可以在循環(huán)體后進(jìn)行,于是形成兩種結(jié)構(gòu):“先判斷、后循環(huán)”結(jié)構(gòu)“先循環(huán)、后判斷”結(jié)構(gòu)循環(huán)結(jié)束的控制可以用循環(huán)次數(shù),還可以用特定條件等,于是又有:計(jì)數(shù)控制循環(huán)條件控制循環(huán)圖示第3章:先循環(huán)后判斷的循環(huán)結(jié)構(gòu)

結(jié)束

初始化

循環(huán)的初始狀態(tài)

循環(huán)體

循環(huán)的工作部分及修改部分

計(jì)數(shù)控制循環(huán)條件控制循環(huán)修改部分控制條件YN第3章:3.5.1計(jì)數(shù)控制循環(huán)計(jì)數(shù)控制循環(huán)利用循環(huán)次數(shù)作為控制條件易于采用循環(huán)指令LOOP和JCXZ實(shí)現(xiàn)初始化:將循環(huán)次數(shù)或最大循環(huán)次數(shù)置入CX循環(huán)體循環(huán)控制:用LOOP指令對(duì)CX減1、并判斷是否為0第3章:用二進(jìn)制顯示BL內(nèi)容(參例3.7)

movcx,8

;CX←8(循環(huán)次數(shù))again: shlbl,1 ;左移進(jìn)CF,從高位開始顯示 movdl,0

;MOV指令不改變CF adcdl,30h

;DL←0+30H+CF

;CF若是0,則DL←'0'

;CF若是1,則DL←'1' movah,2 int21h

;顯示

loopagain

;CX減1,如果CX未減至0,則循環(huán)計(jì)數(shù)控制循環(huán)先循環(huán)后判斷第3章:例3.8求數(shù)組元素的最大值和最小值 ;數(shù)據(jù)段array dw10;假設(shè)一個(gè)數(shù)組,其中頭個(gè)數(shù)據(jù)10表示元素個(gè)數(shù) dw-3,0,20,900,587,-632,777,234,-34,-56;這是一個(gè)有符號(hào)字量元素組成的數(shù)組maxay dw? ;存放最大值minay dw? ;存放最小值初始化:循環(huán)次數(shù)=元素個(gè)數(shù)-1循環(huán)體:逐個(gè)比較求最大、小值循環(huán)控制:比較完所有數(shù)據(jù)第3章:例3.8代碼段

;代碼段 leasi,array movcx,[si]

;取得元素個(gè)數(shù) deccx

;減1后是循環(huán)次數(shù) addsi,2 movax,[si]

;取出第一個(gè)元素給AX,AX用于暫存最大值 movbx,ax

;取出第一個(gè)元素給BX,BX用于暫存最小值初始化第3章:例3.8代碼段(續(xù))maxck: addsi,2 cmp[si],ax

;與下一個(gè)數(shù)據(jù)比較 jleminck movax,[si]

;AX取得更大的數(shù)據(jù) jmpnextminck: cmp[si],bx jgenext movbx,[si] ;BX取得更小的數(shù)據(jù)next: loopmaxck

;計(jì)數(shù)循環(huán) movmaxay,ax ;保存最大值 movminay,bx ;保存最小值循環(huán)體第3章:3.5.2條件控制循環(huán)條件控制循環(huán)需要利用特定條件判斷循環(huán)是否結(jié)束條件控制循環(huán)用條件轉(zhuǎn)移指令判斷循環(huán)條件轉(zhuǎn)移指令可以指定目的標(biāo)號(hào)來(lái)改變程序的運(yùn)行順序,如果目的標(biāo)號(hào)指向一個(gè)重復(fù)執(zhí)行的語(yǔ)句體的開始或結(jié)束,便構(gòu)成了循環(huán)控制結(jié)構(gòu)第3章:顯示以0結(jié)尾的字符串

;數(shù)據(jù)段string db'Letushaveatry!',0

;代碼段 movbx,offsetstringagain: movdl,[bx] cmpdl,0

jzdone

;為0結(jié)束 movah,2 ;不為0,顯示 int21h incbx ;指向下一個(gè)字符

jmpagaindone: ……條件控制循環(huán)先判斷后循環(huán)第3章:例3.10記錄某個(gè)字存儲(chǔ)單元數(shù)據(jù)中1的個(gè)數(shù)

;數(shù)據(jù)段number dw1110111111100100B

;代碼段 movbx,number xordl,dl ;循環(huán)初值:DL←0again: testbx,0ffffh ;也可以用cmpbx,0 jzdone

;全部是0就可以退出循環(huán),減少循環(huán)次數(shù) shlbx,1 ;用指令shrbx,1也可以 adcdl,0

;利用ADC指令加CF的特點(diǎn)進(jìn)行計(jì)數(shù)

jmpagain條件控制循環(huán)先判斷后循環(huán)第3章:例3.10十進(jìn)制顯示(0~16數(shù)值)done: cmpdl,10 ;判斷1的個(gè)數(shù)是否小于10

jbdigit

;1的個(gè)數(shù)小于10,轉(zhuǎn)移 pushdx movdl,‘1’ ;1的個(gè)數(shù)大于或等于10 movah,2 ;則要先顯示一個(gè)1 int21h popdx subdl,10digit: adddl,‘0’ ;顯示個(gè)數(shù) movah,2 int21h單分支結(jié)構(gòu)第3章:3.6子程序設(shè)計(jì)把功能相對(duì)獨(dú)立的程序段單獨(dú)編寫和調(diào)試,作為一個(gè)相對(duì)獨(dú)立的模塊供程序使用,就形成子程序子程序可以實(shí)現(xiàn)源程序的模塊化,可簡(jiǎn)化源程序結(jié)構(gòu),可以提高編程效率主程序(調(diào)用程序)需要利用CALL指令調(diào)用子程序(被調(diào)用程序)子程序需要利用RET指令返回主程序第3章:3.6.1過(guò)程定義和子程序編寫匯編語(yǔ)言中,子程序要用一對(duì)過(guò)程偽指令PROC和ENDP聲明,格式如下:

過(guò)程名

PROC[NEAR|FAR] …… ;過(guò)程體

過(guò)程名

ENDP可選的參數(shù)指定過(guò)程的調(diào)用屬性。沒(méi)有指定過(guò)程屬性,則采用默認(rèn)屬性NEAR屬性(段內(nèi)近調(diào)用)的過(guò)程只能被相同代碼段的其他程序調(diào)用FAR屬性(段間遠(yuǎn)調(diào)用)的過(guò)程可以被相同或不同代碼段的程序調(diào)用第3章:子程序編寫注意事項(xiàng)⑴子程序要利用過(guò)程定義偽指令聲明⑵子程序最后利用RET指令返回主程序,主程序執(zhí)行CALL指令調(diào)用子程序⑶子程序中對(duì)堆棧的壓入和彈出操作要成對(duì)使用,保持堆棧的平衡⑷子程序開始應(yīng)該保護(hù)使用到的寄存器內(nèi)容,子程序返回前相應(yīng)進(jìn)行恢復(fù)⑸子程序應(yīng)安排在代碼段的主程序之外,最好放在主程序執(zhí)行終止后的位置(返回DOS后、匯編結(jié)束END偽指令前),也可以放在主程序開始執(zhí)行之前的位置第3章:例3.11用顯示器功能調(diào)用輸出一個(gè)字符的子程序

;主程序 moval,‘?’ ;主程序提供顯示字符

calldpchar

;調(diào)用子程序

;子程序:顯示AL中的字符dpchar proc

;過(guò)程定義,過(guò)程名為dpchar

pushax

;順序入棧,保護(hù)寄存器

pushbx movbx,0 movah,0eh ;顯示器0EH號(hào)輸出一個(gè)字符功能 int10h

popbx

;逆序出棧,恢復(fù)寄存器

popax

ret

;子程序返回dpchar endp

;過(guò)程結(jié)束第3章:例3.11源程序;wjl313.asm .modelsmall .stack .codestart: movax,@data movds,ax moval,‘?’

;主程序提供顯示字符

calldpchar

;調(diào)用子程序

movax,4c00h int21h主程序部分本程序不需要數(shù)據(jù)段第3章:例3.11源程序(續(xù))dpchar proc

;過(guò)程定義,過(guò)程名為dpchar pushax ;順序入棧,保護(hù)寄存器 pushbx movbx,0 movah,0eh ;顯示器0EH號(hào)輸出一個(gè)字符功能 int10h popbx ;逆序出棧,恢復(fù)寄存器 popax

ret

;子程序返回dpchar endp

;過(guò)程結(jié)束 endstart子程序安排在主程序執(zhí)行終止后的位置第3章:子程序編寫注意事項(xiàng)(續(xù))⑹子程序允許嵌套和遞歸⑺子程序可以與主程序共用一個(gè)數(shù)據(jù)段,也可以使用不同的數(shù)據(jù)段(注意修改DS),還可以在子程序最后設(shè)置數(shù)據(jù)區(qū)(利用CS尋址)⑻子程序的編寫可以很靈活,例如具有多個(gè)出口(多個(gè)RET指令)和入口,但一定要保證堆棧操作的正確性⑼處理好子程序與主程序間的參數(shù)傳遞問(wèn)題⑽提供必要的子程序說(shuō)明信息第3章:例3.12顯示以“0”結(jié)尾字符串的嵌套子程序

;數(shù)據(jù)段msg db'Well,Imadeit!',0

;代碼段(主程序) movsi,offsetmsg

;主程序提供顯示字符串

calldpstri

;調(diào)用子程序第3章:例3.12子程序;子程序dpstri:顯示DS:SI指向的字符串(以0結(jié)尾)

dpstri proc pushaxdps1: moval,[si]

;取顯示字符 incsi cmpal,0 ;是結(jié)尾,則顯示結(jié)束 jzdps2

calldpchar

;調(diào)用字符顯示子程序 jmpdps1dps2: popax

retdpstri endp;子程序dpchar:顯示AL中的字符(同例題4.15)第3章:含數(shù)據(jù)區(qū)的子程序;子程序HTOASC:十六進(jìn)制數(shù)轉(zhuǎn)換為ASCII碼HTOASC proc pushbx movbx,offsetASCII andal,0fh xlatCS:ASCII ;換碼:AL←CS:[BX+AL] popbx

ret;數(shù)據(jù)區(qū)ASCII db30h,31h,32h,33h,34h,35h,36h,37h,38h,39h db41h,42h,43h,44h,45h,46hHTOASC endp第3章:多出口子程序;子程序HTOASC:十六進(jìn)制數(shù)轉(zhuǎn)換為ASCII碼HTOASC proc andal,0fh cmpal,9 jbehtoasc1 addal,37h ;是A~F,加37H ret ;子程序返回htoasc1: add,30h ;是0~9,加30H

ret ;子程序返回HTOASC endp第3章:參數(shù)傳遞主程序與子程序間一個(gè)主要問(wèn)題是參數(shù)傳遞入口參數(shù)(輸入?yún)?shù)):主程序調(diào)用子程序時(shí),提供給子程序的參數(shù)出口參數(shù)(輸出參數(shù)):子程序執(zhí)行結(jié)束返回給主程序的參數(shù)參數(shù)的具體內(nèi)容傳數(shù)值:傳送數(shù)據(jù)本身傳地址:傳送數(shù)據(jù)的主存地址常用的參數(shù)傳遞方法;寄存器共享變量堆棧第3章:3.6.2用寄存器傳遞參數(shù)最簡(jiǎn)單和常用的參數(shù)傳遞方法是通過(guò)寄存器,只要把參數(shù)存于約定的寄存器中就可以了由于通用寄存器個(gè)數(shù)有限,這種方法對(duì)少量數(shù)據(jù)可以直接傳遞數(shù)值,而對(duì)大量數(shù)據(jù)只能傳遞地址采用寄存器傳遞參數(shù),注意帶有出口參數(shù)的寄存器不能保護(hù)和恢復(fù),帶有入口參數(shù)的寄存器可以保護(hù)、也可以不保護(hù),但最好能夠保持一致dpchardpstriHTOASC第3章:3.6.3用共享變量傳遞參數(shù)子程序和主程序使用同一個(gè)變量名存取數(shù)據(jù)就是利用共享變量(全局變量)進(jìn)行參數(shù)傳遞如果變量定義和使用不在同一個(gè)源程序中,需要利用PUBLIC、EXTREN聲明如果主程序還要利用原來(lái)的變量值,則需要保護(hù)和恢復(fù)利用共享變量傳遞參數(shù),子程序的通用性較差,但特別適合在多個(gè)程序段間、尤其在不同的程序模塊間傳遞數(shù)據(jù)第3章:3.6.4用堆棧傳遞參數(shù)參數(shù)傳遞還可以通過(guò)堆棧這個(gè)臨時(shí)存儲(chǔ)區(qū)。主程序?qū)⑷肟趨?shù)壓入堆棧,子程序從堆棧中取出參數(shù);子程序?qū)⒊隹趨?shù)壓入堆棧,主程序彈出堆棧取得它們采用堆棧傳遞參數(shù)是程式化的,它是編譯程序處理參數(shù)傳遞、以及匯編語(yǔ)言與高級(jí)語(yǔ)言混合編程時(shí)的常規(guī)方法子程序參數(shù)傳遞—堆棧傳遞

堆棧傳遞參數(shù)方式是指子程序的入口參數(shù)和出口參數(shù)通過(guò)堆棧傳遞。主程序在調(diào)用子程序之前應(yīng)將需要傳遞給子程序的參數(shù)壓入堆棧,子程序則從堆棧中取出參數(shù),經(jīng)過(guò)運(yùn)算后,將運(yùn)算結(jié)果也壓入堆棧。返回后,主程序再?gòu)亩褩V腥〕鼋Y(jié)果。

注意:主程序壓入?yún)?shù)的順序以及子程序傳遞結(jié)果的方式必須事先約定。下面通過(guò)例子說(shuō)明堆棧傳遞參數(shù)的基本方法;例

編寫一程序,完成將一組BCD數(shù)轉(zhuǎn)換成16位二進(jìn)制數(shù)。假設(shè)一組BCD數(shù)以分離BCD數(shù)的方式存于內(nèi)存的某個(gè)區(qū),并且BCD數(shù)據(jù)的高未存于高地址端,低位存于低地址端。由于轉(zhuǎn)換后的二進(jìn)制數(shù)為16位,所以分離BCD數(shù)最多為5個(gè)字節(jié)。子程序參數(shù)傳遞—堆棧傳遞本程序算法:

根據(jù)數(shù)學(xué)多項(xiàng)式A0A1A2A3A4=A0*10000+A1*1000+A2*100+A3*10+A4例如:十進(jìn)制數(shù)24975=2*10000+4*1000+9*100+7*10+5。實(shí)現(xiàn)步驟:

1)、DX=0

2)、取要轉(zhuǎn)化的一組BCD數(shù)中

的高位數(shù)——〉(AX);

3)、(DX)=(DX)*10+(AX);

4)、重復(fù)(2)、(3)兩步,直到BCD碼的所有位都轉(zhuǎn)化為止。BCD數(shù)在內(nèi)存中存放的形式0507090402低位數(shù)高位數(shù)子程序參數(shù)傳遞—堆棧傳遞stack

segmentdw128dup(?)toplabelwordstackendsdatasegmentbcd1db5dup(?)leng1dw?

resultdw?dataendscodemsegmentassumecs:codem,ds:data,ss:stackmain:movax,datamovds,axmovax,stackmovss,axmovsp,offsettop

pushds;將參數(shù)3送入堆棧leaax,bcd1pushax;將參數(shù)2送入堆棧movcx,leng1pushcx;將參數(shù)1送入堆棧callfarptrbcd_16bpopax;從堆棧中去結(jié)果movresult,ax

movah,4chint21hcodemends子程序參數(shù)傳遞—堆棧傳遞

codessegment

assumecs:codes

bcd_16bprocfarpushbpmovbp,sppushespushsipushcxpushbxpushaxmovcx,[bp+6];從堆棧中取第1個(gè)參數(shù)movsi,[bp+8];從堆棧中取第2個(gè)參數(shù)子程序參數(shù)傳遞—堆棧傳遞moves,[bp+0ah]

;從堆棧中取第3個(gè)參數(shù)addsi,cxdecsimovdx,0bcdl:pushcxmoval,es:[si]decsiandal,0fhcbwmovbx,ax

;1位十進(jìn)制數(shù)暫存bxmovax,dxmovcx,10mulcxmovdx,ax

;部分積存入dxadddx,bx

;(dx*10+bx)popcx

;恢復(fù)循環(huán)計(jì)數(shù)值子程序參數(shù)傳遞—堆棧傳遞

loopbcdl

;(cx)-1-->(cx)(cx)=0?mov[bp+0ah],dx

;將結(jié)果送入堆棧popax

;恢復(fù)斷點(diǎn)處個(gè)寄存器的值popbxpopcxpopsipopespopbpret4

;堆棧指針下移4個(gè)字節(jié)bcd_16bendpendmain

說(shuō)明:整個(gè)程序包含兩個(gè)代碼段codem和codes,codem為主程序代碼段,codes為子程序代碼段,子程序完成將bcd數(shù)轉(zhuǎn)換為二進(jìn)制數(shù)。主程序通過(guò)3條PUSH指令一次將bcd1的段地址、偏移地址以及字節(jié)數(shù)送入堆棧,進(jìn)入子程序后,為了從堆棧中取得所需的子程序參數(shù)傳遞—堆棧傳遞數(shù)據(jù)首先將SP的位置記下,即在子程序的開始,將BP的原始內(nèi)容存入堆棧。再把SP的內(nèi)容送入BP,其后在子程序中取得參數(shù)和存放結(jié)果都基于BP中的當(dāng)前值進(jìn)行。子程序調(diào)用前、運(yùn)行中和子程序調(diào)用后的堆棧變化情況假設(shè):堆棧段的棧低(棧頂)地址為0400:0100H,棧底(棧頂)…棧底SP0400:0100H圖a堆棧初始情況子程序參數(shù)傳遞—堆棧傳遞(DS)=BCD1的段地址(AX)=BCD1的偏移地址(CX)=BCD字?jǐn)?shù)…SP棧底棧頂0400:00FEH0400:00FCH0400:00FAH圖b執(zhí)行調(diào)用指令但未進(jìn)入子程序的堆棧(CS)=返回處的段地址(IP)=返回處的偏移地址0040:00F8H0040:00F6H(SP)=00F6H子程序參數(shù)傳遞—堆棧傳遞(DS)=BCD1的段地址(AX)=BCD1的偏移地址(CX)=BCD字?jǐn)?shù)…SP棧底00FEH=00F4+0AH00FCH=00F4+08H00FAH=00F4+06H(CS)=返回處的段地址(IP)=返回處的偏移地址00F8H=00F4+04H00F6H=00F4+02HBP00F4H=00F4+00H(SP)=00F4HESSI此處為分界點(diǎn),從堆棧中取參數(shù)以此值為參考點(diǎn)圖C進(jìn)入子程序并運(yùn)行PUSH指令后的堆棧子程序參數(shù)傳遞—堆棧傳遞(DX)=轉(zhuǎn)換結(jié)果(AX)=BCD1的偏移地址(CX)=BCD字?jǐn)?shù)…SP棧底0400:00FEH0400:00FCH0400:00FAH圖D子程序運(yùn)行POP和RET指令后但還未進(jìn)行下移的堆棧從上面的堆棧情況可以看出,如果子程序末尾執(zhí)行RET指令,而不是RET4指令;則主程序就取不到運(yùn)算結(jié)果,為了使程序返回主程序后,主程序能夠取到子程序傳遞給主程序的運(yùn)算結(jié)果須將堆棧指針下移4個(gè)字節(jié),即執(zhí)行RET4指令,讓SP指向保存結(jié)果的地方。這樣再主程序中執(zhí)行POPAX指令后取到正確的結(jié)果。子程序參數(shù)傳遞—堆棧傳遞注意點(diǎn):在堆棧傳遞參數(shù)時(shí),重要的是要將進(jìn)入子程序時(shí)的SP內(nèi)容保存起來(lái),因?yàn)樗c參數(shù)之間的位置關(guān)系是固定的。若為段間調(diào)用,則棧中第一個(gè)參數(shù)的位置在[BP+6]處;若為段內(nèi)調(diào)用,則棧中第一個(gè)參數(shù)的位置在[BP+4]處,此后,堆棧繼續(xù)使用都不會(huì)影響參數(shù)的存取。子程序參數(shù)傳遞—堆棧傳遞3.7BIOS和DOS中斷功能調(diào)用

一、概述

1.BIOS和DOS中斷子程層次特點(diǎn)2.中斷類型分類3.調(diào)用方法二、BIOS功能調(diào)用1.設(shè)置顯示方式(10H類型,00H功能)2.置光標(biāo)位置(10H類型,02H功能)3.清屏、清窗口(10H類型,06H或07H功能)三、

DOS系統(tǒng)功能調(diào)用(21H類型中斷調(diào)用)1.顯示單字符(02H功能)2.顯示字符串(09H功能)3.單字符輸入(01H、07H、08H功能)4.字符串輸入(0AH功能)3.檢測(cè)鍵盤狀態(tài)(0BH功能)6.保存中斷向量(35H功能)(第六章介紹)7.設(shè)置中斷向量(25H功能)1、BIOS和DOS中斷功能調(diào)用

一)、概述

二)、BIOS功能調(diào)用三)、

DOS系統(tǒng)功能調(diào)用(21H類型中斷調(diào)用)一)、概述1.BIOS和DOS中斷子程層次特點(diǎn)2.

中斷類型分類3.

調(diào)用方法1)、BIOS和DOS中斷子程層次特點(diǎn)用戶程序磁盤管理模塊(DOS內(nèi)核)MSDOS.SYS系統(tǒng)功能基本輸入/輸出BIOS模塊IO.SYS設(shè)備驅(qū)動(dòng)ROMBIOS基本I/O系統(tǒng)硬件裝入命令處理模塊COMMAND.COM用戶命令DOS系統(tǒng)層次結(jié)構(gòu)

層次特點(diǎn):ROMBIOS中的中斷子程

使用IN/OUT指令直接控制外設(shè),實(shí)現(xiàn)與外設(shè)之間的輸入/輸出操作,

以軟件形式向其上層提供服務(wù)。IO.SYS中的中斷子程

(稱基本輸入/輸出BIOS模塊)

調(diào)用ROMBIOS的基本I/O功能,向MSDOS.SYS提供設(shè)備驅(qū)動(dòng)服務(wù)。用戶程序磁盤管理模塊(DOS內(nèi)核)MSDOS.SYS系統(tǒng)功能基本輸入/輸出BIOS模塊IO.SYS設(shè)備驅(qū)動(dòng)ROMBIOS基本I/O系統(tǒng)硬件裝入命令處理模塊COMMAND.COM用戶命令

MSDOS.SYS中的中斷子程(稱DOS內(nèi)核模塊)調(diào)用IO.SYS,實(shí)現(xiàn)對(duì)外設(shè)的控制。與標(biāo)準(zhǔn)外設(shè)有兩層隔離:IO.SYS和ROMBIOS。其中21H類型的中斷子程提供了豐富的系統(tǒng)服務(wù),稱21類型的中斷調(diào)用為DOS系統(tǒng)(功能)調(diào)用。用戶程序磁盤管理模塊(DOS內(nèi)核)MSDOS.SYS系統(tǒng)功能基本輸入/輸出BIOS模塊IO.SYS設(shè)備驅(qū)動(dòng)ROMBIOS基本I/O系統(tǒng)硬件裝入命令處理模塊COMMAND.COM用戶命令

用戶編程原則①盡可能使用DOS的系統(tǒng)功能調(diào)用,

提高程序可移植性。②在DOS功能不能實(shí)現(xiàn)情況下,

考慮用BIOS功能調(diào)用。③在DOS和BIOS的中斷子程

不能解決問(wèn)題時(shí),

使用IN/OUT指令直接控制硬件。用戶程序磁盤管理模塊(DOS內(nèi)核)MSDOS.SYS系統(tǒng)功能基本輸入/輸出BIOS模塊IO.SYS設(shè)備驅(qū)動(dòng)ROMBIOS基本I/O系統(tǒng)硬件裝入命令處理模塊COMMAND.COM用戶命令2.中斷類型分類

向量表中的中斷類型分為七類:①處理CPU特殊操作(除0、溢出)的00H、04H類型。②

為DEBUG調(diào)試程序設(shè)置的單步(01H)、斷點(diǎn)(03H)類型。③

處理CPU的NMI引腳信號(hào)的02H類型。

非屏蔽硬中斷子程④

處理CPU的INTR引腳信號(hào)的08~0FH類型。

可屏蔽類型硬中斷子程⑤

用INT指令調(diào)用的中斷子程

BIOS功能調(diào)用(如10~1AH)DOS功能調(diào)用(如21H)NMIINTR8088⑥

保留類型為DOS系統(tǒng)保留

1)指現(xiàn)在未用到,以后系統(tǒng)可能會(huì)用到。

2)已用到,但不向用戶公開。為用戶保留

1)被系統(tǒng)子程嵌套調(diào)用了的類型(如1BH、1CH)。

使用戶在系統(tǒng)功能基礎(chǔ)上擴(kuò)充功能。

2)系統(tǒng)未占用類型(如60H~67H)。⑦非中斷向量類型對(duì)應(yīng)向量表中的4個(gè)單元存放的不是中斷向量。

(如1DH、1EH、1FH、41H、46H、22H)

通常是一些參數(shù)表的地址信息.

中斷向量分配表3.調(diào)用方法設(shè)置入口參數(shù)在AH設(shè)置功能號(hào)m執(zhí)行中斷指令I(lǐng)NTN分析、應(yīng)用出口參數(shù)例1

單字符顯示功能調(diào)用MOVDL,‘A’;設(shè)置入口參數(shù)MOVAH,02H;設(shè)置功能號(hào)INT21H;執(zhí)行中斷調(diào)用

例2

單字符輸入功能調(diào)用MOVAH,01H;設(shè)置功能號(hào)

INT21H;執(zhí)行中斷調(diào)用CMPAL,0DH;分析、應(yīng)用出口參數(shù)JZexit、、、二、BIOS功能調(diào)用

基本輸入/輸出模塊BIOS:實(shí)現(xiàn)對(duì)輸入/輸出設(shè)備的控制,內(nèi)含0–1CH等類型中斷子程,包括顯示器、磁盤、鍵盤、打印機(jī)等標(biāo)準(zhǔn)外設(shè)的驅(qū)動(dòng)程序。

(參看中斷類型分配表)

BIOS功能調(diào)用指對(duì)BIOS模塊中的中斷子程的調(diào)用。

有關(guān)顯示器①顯示器通過(guò)顯卡(顯示適配器)連接到計(jì)算機(jī)上。②單色顯示器只能顯示黑白兩色。

彩色顯示器能顯示多種顏色。③屏幕上各象素的顯示信息,存放在顯示緩沖區(qū)(顯存)中。640KBRAM基本內(nèi)存0000:00000040:00000050:00000070:0000

A000:0000B000:0000

C800:0000F600:0000FE00:0000FE00:1FFF顯示緩存區(qū)(顯存)硬盤驅(qū)動(dòng)器控制ROM32KBROMBASIC8KBROMBIOSIO.SYS模塊COMMAND.COM常駐模塊MSDOS.SYS模塊用戶程序空間COMMAND.COM暫駐模塊256KBROMDOS工作區(qū)ROMBIOS工作區(qū)128KBRAM保留區(qū)1KB中斷向量表④顯示器有兩種顯示方式:

圖形方式:將屏幕劃分為m×n的點(diǎn)陣,在每個(gè)點(diǎn)的位置顯示象素,一個(gè)點(diǎn)是一個(gè)象素。文本方式將屏幕劃分為若干行和列,在每個(gè)網(wǎng)格位置上顯示象素,一個(gè)字符是一個(gè)象素。文本方式將屏幕劃分為m列和n行(m×n),在每個(gè)網(wǎng)格位置上顯示象素,一個(gè)字符是一個(gè)象素。80×25文本方式A~~~~~~~~~~~~~~~~0列0行79列24行BC在文本方式下,對(duì)應(yīng)屏幕上的每個(gè)字符,在顯示緩沖區(qū)中占用兩個(gè)單元:一個(gè)存放ASCII碼,一個(gè)存放顯示屬性。41H07H42H07H61H70H62H70H、、、顯示緩沖區(qū)(顯存)字符A,

黑底白字字符B,

黑底白字字符a,白底黑字字符b,

白底黑字例10000111B或87H

表示黑底白字,閃爍

01110000B或70H

表示白底黑字,不閃爍16種0000黑1000灰

0010綠

1010淺綠0100紅

1100淺紅0111灰白

1111白BLRGBIRGB閃爍背景前景765432108種000黑010綠

100紅111白0不閃爍1閃爍屬性字節(jié)的含義:

據(jù)顯存大小,可存儲(chǔ)若干頁(yè)的字符象素。

16KB顯存能存儲(chǔ):80×25方式,4頁(yè)(0~3),80×25×2×4=1600040×25方式,8頁(yè)(0~7),40×25×2×8=160001.設(shè)置顯示方式入口參數(shù)

AL=顯示方式值

0040×25黑白文本方式

0140×25彩色文本方式

0280×25黑白文本方式

0380×25彩色文本方式

04320×320彩色圖形方式功能號(hào)

AH=00H類型號(hào)

10H出口參數(shù)無(wú)實(shí)現(xiàn)功能將顯示方式設(shè)置為指定形式例將顯示方式設(shè)置為80×25彩色文本方式MOVAL,03HMOV

AH,00

INT10H2.

清屏、清窗口功能入口參數(shù)

AL=0CH=窗口左上角行號(hào)CL=窗口左上角列號(hào)DH=窗口右下角行號(hào)DL=窗口右下角列號(hào)BH=窗口屬性功能號(hào)

AH=06H

或AH=07H類型號(hào)

10H出口參數(shù)無(wú)實(shí)現(xiàn)功能按給定屬性清除指定的窗口內(nèi)容例清除屏幕顯示,將其屬性置為反白(白底黑字)顯示。MOVAL,0;清屏功能MOVBH,70H;白底黑字MOVCH,0;左上角行號(hào)MOVCL,0;左上角列號(hào)MOVDH,24;右下角行號(hào)MOVDL,79;右下角列號(hào)MOVAH,6;功能號(hào)INT10H;中斷調(diào)用3.置光標(biāo)位置

光標(biāo)控制開始顯示的位置,

計(jì)算機(jī)有專門的硬件控制光標(biāo)的顯示大小、位置。

光標(biāo)只在文本方式中出現(xiàn),在圖形方式下光標(biāo)消失。~~~~~~~~~~~~~~~~0列0行79列24行5列1列1行2行置光標(biāo)位置

入口參數(shù)

DH=行號(hào)DL=列號(hào)BH=頁(yè)號(hào)

功能號(hào)

AH=02H

溫馨提示

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

評(píng)論

0/150

提交評(píng)論