版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
第4章匯編語(yǔ)言程序格式4.1硬指令和偽指令4.2循環(huán)與分支程序設(shè)計(jì)4.3子程序設(shè)計(jì)4.4宏匯編與條件匯編2023/7/23教學(xué)重點(diǎn)第3章學(xué)習(xí)了8086硬指令,第4章介紹MASM基本的偽指令。第4章重點(diǎn)掌握:偽操作匯編語(yǔ)言程序格式2023/7/233硬指令和偽指令硬指令——使CPU產(chǎn)生動(dòng)作、并在程序執(zhí)行時(shí)才處理的語(yǔ)句,就是第3章學(xué)習(xí)的處理器指令偽指令(Directive)——不產(chǎn)生CPU動(dòng)作、在程序執(zhí)行前由匯編程序處理的說(shuō)明性語(yǔ)句,例如,數(shù)據(jù)說(shuō)明、變量定義等等偽指令與具體的處理器類(lèi)型無(wú)關(guān),但與匯編程序的版本有關(guān)
本課程采用微軟宏匯編程序MASM5.0語(yǔ)句格式⑴執(zhí)行性語(yǔ)句——由硬指令構(gòu)成的語(yǔ)句,它通常對(duì)應(yīng)一條機(jī)器指令,出現(xiàn)在程序的代碼段中:標(biāo)號(hào):硬指令助記符操作數(shù),操作數(shù) ;注釋⑵說(shuō)明性語(yǔ)句——由偽指令構(gòu)成的語(yǔ)句,它通常指示匯編程序如何匯編源程序:名字偽指令助記符參數(shù),參數(shù),… ;注釋第4章 MOVCX,0 ;傳送指令,具有2個(gè)操作數(shù)DELAY: NOP ;空操作指令,沒(méi)有操作數(shù),帶有標(biāo)號(hào)
LOOPDELAY ;循環(huán)指令,標(biāo)號(hào)DELAY說(shuō)明轉(zhuǎn)移位置BUFFER DB1,2,3,4,5,6,7
;數(shù)據(jù)定義偽指令,在主存中開(kāi)辟7個(gè)連續(xù)的字節(jié)單元,初值依次為1~7,BUFFER表示首地址匯編語(yǔ)言語(yǔ)句實(shí)例標(biāo)號(hào)、名字與標(biāo)識(shí)符標(biāo)號(hào)是反映硬指令位置(邏輯地址)的標(biāo)識(shí)符,后跟一個(gè)冒號(hào)分隔名字是反映偽指令位置(邏輯地址)和屬性的標(biāo)識(shí)符,后跟空格或制表符分隔,沒(méi)有一個(gè)冒號(hào)標(biāo)識(shí)符(Identifier)一般最多由31個(gè)字母、數(shù)字及規(guī)定的特殊符號(hào)(如_、$、?、@)組成,不能以數(shù)字開(kāi)頭。默認(rèn)情況下,匯編程序不區(qū)別標(biāo)識(shí)符中的字母大小寫(xiě)一個(gè)程序中,每個(gè)標(biāo)識(shí)符的定義是唯一的,還不能是匯編語(yǔ)言采用的保留字第4章保留字保留字(ReservedWord)是匯編程序已經(jīng)利用的標(biāo)識(shí)符,主要有:硬指令助記符——例如:MOV、ADD偽指令助記符——例如:DB、EQU操作符——例如:OFFSET、PTR寄存器名——例如:AX、CS預(yù)定義符號(hào)——例如:@data第4章
匯編語(yǔ)言大小寫(xiě)不敏感2023/7/238操作數(shù)與參數(shù)硬指令的操作數(shù)可以是立即數(shù)、寄存器和存儲(chǔ)單元偽指令的參數(shù)可以是常數(shù)、變量名、表達(dá)式等,可以有多個(gè),參數(shù)之間用逗號(hào)分隔2023/7/239注釋語(yǔ)句中由分號(hào)“;”開(kāi)始的部分為注釋內(nèi)容,用以增加源程序的可讀性必要時(shí),一個(gè)語(yǔ)句行也可以由分號(hào)開(kāi)始作為階段性注釋匯編程序(如MASM.EXE)在翻譯源程序時(shí)將跳過(guò)該部分,不對(duì)它們做任何處理2023/7/2310分隔符語(yǔ)句的4個(gè)組成部分要用分隔符分開(kāi)標(biāo)號(hào)后用冒號(hào),注釋前用分號(hào)操作數(shù)之間和參數(shù)之間使用逗號(hào)分隔其他部分通常采用空格或制表符多個(gè)空格和制表符的作用與一個(gè)相同MASM支持續(xù)行符“\”2023/7/2311匯編語(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è)堆棧段2023/7/23121處理器選擇偽操作.8086
選擇8086指令系統(tǒng).286
選擇80286指令系統(tǒng).286P
選擇保護(hù)模式下的80286指令系統(tǒng).386
選擇80386指令系統(tǒng).386P
選擇保護(hù)模式下的80386指令系統(tǒng).486
選擇80486指令系統(tǒng).486P
選擇保護(hù)模式下的80486指令系統(tǒng).586
選擇Pentium指令系統(tǒng).586P
選擇保護(hù)模式下的Pentium指令系統(tǒng)2023/7/23132段定義偽操作源程序分別用兩種格式書(shū)寫(xiě)第一種格式從MASM5.0開(kāi)始支持簡(jiǎn)化段定義格式第二種格式MASM5.0以前就具有完整段定義格式Hello,Everybody!程序功能;lt401a.asm(文件名)
.modelsmall ;定義程序的存儲(chǔ)模式
.stack ;定義堆棧段
.data ;定義數(shù)據(jù)段string db’Hello,Everybody!’,0dh,0ah,’$’
;在數(shù)據(jù)段定義要顯示的字符串
.code ;定義代碼段start:movax,@data ;程序起始點(diǎn),建立DS、SS movds,ax
movdx,offsetstring
;指定字符串
movah,9 int21h
;利用功能調(diào)用顯示信息
movax,4c00h ;程序結(jié)束點(diǎn),返回DOS int21h end ;匯編結(jié)束例4.1a:簡(jiǎn)化段定義格式;SampleA.ASM .modelsmall .stack .data
... ;在數(shù)據(jù)段定義數(shù)據(jù)
.code .startup ;(注1)
... ;在代碼段填入指令序列
.exit0 ;(注2)
...
;子程序代碼
end ;(注3)簡(jiǎn)化段定義格式
MASM6.x支持;SampleC.ASM .modelsmall .stack .data
... ;在數(shù)據(jù)段定義數(shù)據(jù)
.codestart:movax,@data movds,ax
... ;在代碼段填入指令序列
movax,4c00h int21h
...
;子程序代碼
endstart簡(jiǎn)化段定義格式
MASM5.x支持◆段定義偽操作:完整的段定義格式datasegment;定義數(shù)據(jù)段
…dataends;extrasegment;定義附加段
…extraends;codesegment;定義代碼段
assumecs:code,ds:data,es:extrastart:movax,datamovds,ax;段地址段寄存器
…codeendsendstart……codesegmentmainprocfarassume……start:pushdsmovax,0pushax……retmainendpcodeendsendstart……codesegmentmainprocfarassume……start:…………movax,4c00hint21hmainendpcodeendsendstart;lt401b.asm(文件名)stack segmentstack ;定義堆棧段
dw512dup(?) ;堆棧段有512字(1024字節(jié))空間stack ends ;堆棧段結(jié)束data segment ;定義數(shù)據(jù)段string db’Hello,Everybody!’,0dh,0ah,’$’data endscode segment’code’ ;定義代碼段
assumecs:code,ds:data,ss:stackstart: movax,data ;建立DS段地址
movds,ax例4.1b:完整段定義格式 movdx,offsetstring movah,9 int21h movax,4c00h int21h ;利用功能調(diào)用返回DOScode ends ;代碼段結(jié)束
endstart ;匯編結(jié)束,同時(shí)指明程序起始點(diǎn)例4.1b:完整段定義格式;SampleB.ASMstack segmentstack dw512dup(?)stack endsdata segment
... ;在數(shù)據(jù)段定義數(shù)據(jù)data endscode segment’code’ assumecs:code,ds:data,ss:stackstart: movax,data movds,ax
... ;在代碼段填入指令序列
movax,4c00h int21h
...
;子程序代碼code ends endstart完整段定義格式
MASM5.x支持完整段定義偽指令段名 segment 定位組合段字'類(lèi)別' ... ;語(yǔ)句序列段名 ends完整段定義由SEGMENT和ENDS這一對(duì)偽指令實(shí)現(xiàn),SEGMENT偽指令定義一個(gè)邏輯段的開(kāi)始,ENDS偽指令表示一個(gè)段的結(jié)束段定義指令后的4個(gè)關(guān)鍵字用于確定段的各種屬性,堆棧段要采用stack組合類(lèi)型,代碼段應(yīng)具有‘code’類(lèi)別,其他為可選屬性參數(shù)如果不指定,則采用默認(rèn)參數(shù);但如果指定,注意要按照上列次序2023/7/2323完整段定義偽指令為了對(duì)段定義作進(jìn)一步地控制,SEGMENT偽指令還可以增加類(lèi)型及屬性的說(shuō)明,其格式如下:
段名SEGMENT
[定位類(lèi)型][組合類(lèi)型][‘類(lèi)別’]
…
段名ENDS
一般情況下,這些說(shuō)明可以不用。但是,如果需要用連接程序把本程序與其他程序模塊相連接時(shí),就需要提供類(lèi)型和屬性的說(shuō)明。
‘類(lèi)別’給出連接時(shí)組成段組的類(lèi)型名。類(lèi)別說(shuō)明并不能把相同類(lèi)別的段合并起來(lái),但在連接后形成的裝入模塊中,可以把它們的位置靠在一起。2023/7/2324定位類(lèi)型定位類(lèi)型:說(shuō)明段的起始邊界值(物理地址)。定位類(lèi)型說(shuō)明定位類(lèi)型說(shuō)明BYTE段可以從任何地址邊界開(kāi)始WORD段從字邊界開(kāi)始,即段的起始邊界值為偶數(shù)DWORD段從雙字的邊界開(kāi)始,即段的起始邊界值為4的倍數(shù)PARA段從小段邊界開(kāi)始,即段的起始邊界值為16(或10H)的倍數(shù)PAGE段從頁(yè)邊界開(kāi)始,即段的起始邊界值為256(或100H)的倍數(shù)2023/7/2325組合類(lèi)型組合類(lèi)型:說(shuō)明程序連接時(shí)的段組合方法。組合類(lèi)型說(shuō)明PRIVATE該段為私有段,連接時(shí)將不與其它模塊中的同名段合并PUBLIC該段連接時(shí)將與其它同名段連接在一起,連接次序由連接命令指定COMMON該段在連接時(shí)與其它同名段有相同的起始地址,所以會(huì)產(chǎn)生覆蓋AT表達(dá)式段地址=表達(dá)式的值,其值必為16位但AT不能用來(lái)指定代碼段MEMORY與PUBLIC同義STACK將多個(gè)同名堆棧段連接在一起,SP設(shè)置在第一個(gè)堆棧段的開(kāi)始指定段寄存器偽指令A(yù)SSUME段寄存器:段名[,段寄存器名:段名,...]通知MASM用指定的段寄存器來(lái)尋址對(duì)應(yīng)的邏輯段,即建立段寄存器與段的缺省關(guān)系在明確了程序中各段與段寄存器之間的關(guān)系后,匯編程序會(huì)根據(jù)數(shù)據(jù)所在的邏輯段,在需要時(shí)自動(dòng)插入段超越前綴。這是ASSUME偽指令的主要功能ASSUME偽指令并不為段寄存器設(shè)定初值,連接程序LINK將正確設(shè)置CS:IP和SS:SP由于數(shù)據(jù)段通常都需要,所以在樣板源程序中,首先為DS賦值;如果使用附加段,還要賦值ES存儲(chǔ)模式與簡(jiǎn)化段定義偽操作(1)MODEL偽操作
.MODEL存儲(chǔ)模式[,語(yǔ)言類(lèi)型][,操作系統(tǒng)類(lèi)型][,堆棧選項(xiàng)]
存儲(chǔ)模式:tinysmallmediumcompactlargehugeflat.modelsmall.stack100H.data…….code.startup…….exit0end(2)簡(jiǎn)化的段定義偽操作.code[name].data.data?.fardata[name].fardata?[name].const.stack[size].modelsmall.data…….code.startup…….exit0end.modelsmall.data…….codestart:movax,@datamovds,ax……movax,4c00hint21hendstart.modelsmall.const…….data…….codestart:movax,DGROUPmovds,ax……movax,4c00hint21hendstart;SampleA.ASM
.modelsmall
.stack .data
... ;在數(shù)據(jù)段定義數(shù)據(jù)
.code
.startup
... ;在代碼段填入指令序列
.exit0
...
;子程序代碼
end簡(jiǎn)化段定義格式
MASM6.x支持存儲(chǔ)模式偽指令.MODEL存儲(chǔ)模式使用簡(jiǎn)化段定義,必須有存儲(chǔ)模式偽指令.model語(yǔ)句必須位于所有段定義語(yǔ)句之前存儲(chǔ)模式?jīng)Q定一個(gè)程序的規(guī)模,確定進(jìn)行子程序調(diào)用、指令轉(zhuǎn)移和數(shù)據(jù)訪問(wèn)的缺省屬性MASM有7種不同的存儲(chǔ)模式:①TINY ②SMALL③COMPACT ④MEDIUM⑤LARGE ⑥HUGE⑦FLAT存儲(chǔ)模型功能適用操作系統(tǒng)Tiny(微型)所有數(shù)據(jù)和代碼都放在一個(gè)段內(nèi),其訪問(wèn)都為NEAR型,整個(gè)程序≤64K,并會(huì)產(chǎn)生.COM文件。MS-DOSSmall(小型)所有代碼在一個(gè)64KB的段內(nèi),所有數(shù)據(jù)在另一個(gè)64KB的段內(nèi)(包括數(shù)據(jù)段,堆棧段和附加段)。MS-DOS
WindowsMedium(中型)所有代碼>64K時(shí)可放在多個(gè)代碼段中,轉(zhuǎn)移或調(diào)用可為FAR型。所有數(shù)據(jù)限在一個(gè)段內(nèi),DS可保持不變。MS-DOS
WindowsCompact(緊湊型)所有代碼限在一個(gè)段內(nèi),轉(zhuǎn)移或調(diào)用可為NEAR型。數(shù)據(jù)>64K時(shí),可放在多個(gè)段中。MS-DOS
WindowsLarge(大型)允許代碼段和數(shù)據(jù)段都可超過(guò)64K,被放置在有多個(gè)段內(nèi),所以數(shù)據(jù)和代碼都是遠(yuǎn)訪問(wèn)。MS-DOS
WindowsHuge(巨型)單個(gè)數(shù)據(jù)項(xiàng)可以超過(guò)64K,其它同Large模型MS-DOS
WindowsFlat(平展型)所有代碼和數(shù)據(jù)放置在一個(gè)段中,但段地址是32位的,所以整個(gè)程序可為4GB。MASM6.0支持該模型。OS/2
WindowsNTMASM5.0和MASM6.0支持的存儲(chǔ)模型TINY微型模式微型模式用于創(chuàng)建COM類(lèi)型程序用微型模式編寫(xiě)匯編語(yǔ)言程序時(shí),所有的段地址寄存器都被設(shè)置為同一值這意味著代碼段、數(shù)據(jù)段、堆棧段都在同一個(gè)段內(nèi),不大于64KB;訪問(wèn)操作數(shù)或指令都只需要使用16位偏移地址SMALL小型模式一般的程序(例如本書(shū)的絕大多數(shù)程序示例和習(xí)題)都可用這種模式在小型模式下,一個(gè)程序至多只能有一個(gè)代碼段和一個(gè)數(shù)據(jù)段,每段不大于64KB
這里的數(shù)據(jù)段是指數(shù)據(jù)段、堆棧段和附加段的總和,它們共用同一個(gè)段基址,總長(zhǎng)度不可超過(guò)64KB;因此小模式下程序的最大長(zhǎng)度為128KB
訪問(wèn)操作數(shù)或指令都只需要使用16位偏移地址;這意味著諸如指令轉(zhuǎn)移、程序調(diào)用以及數(shù)據(jù)訪問(wèn)等都是近屬性(NEAR),即小型模式下的調(diào)用類(lèi)型和數(shù)據(jù)指針缺省分別為近調(diào)用和近指針COMPACT緊湊模式適合于數(shù)據(jù)量大但代碼量小的程序緊湊模式下,代碼段被限制在一個(gè)不大于64KB的段內(nèi);而數(shù)據(jù)段則可以有多個(gè),超過(guò)64KB
這種模式下的調(diào)用類(lèi)型缺省仍為近調(diào)用;而數(shù)據(jù)指針缺省為遠(yuǎn)(FAR)指針,因?yàn)楸仨氂枚蔚刂穪?lái)區(qū)別多個(gè)數(shù)據(jù)段MEDIUM中型模式中型模式是與緊湊模式互補(bǔ)的模式適合于數(shù)據(jù)量小但代碼量大的程序中型模式的代碼段可以超過(guò)64KB,有多個(gè);但數(shù)據(jù)段只能有一個(gè)不大于64KB的段這種模式下的數(shù)據(jù)指針缺省為近指針;但調(diào)用類(lèi)型缺省是遠(yuǎn)(FAR)調(diào)用,因?yàn)橐枚蔚刂穮^(qū)別多個(gè)代碼段LARGE大型模式較大型程序通常采用的存儲(chǔ)模式大型模式允許的代碼段和數(shù)據(jù)段都有多個(gè),都可以超過(guò)64KB;但全部的靜態(tài)數(shù)據(jù)(不能改變的數(shù)據(jù))仍限制在64K字節(jié)內(nèi)大型模式下的調(diào)用類(lèi)型和數(shù)據(jù)指針缺省分別為遠(yuǎn)調(diào)用和遠(yuǎn)指針HUGE(巨型模式)與大型模式基本相同,只是靜態(tài)數(shù)據(jù)不再被限制在64K字節(jié)之內(nèi)FLAT平展模式平展模式用于創(chuàng)建一個(gè)32位的程序,它只能運(yùn)行在32位x86CPU上。DOS下不能使用FLAT模式,而編寫(xiě)32位Windows9.x或Windows-NT的程序時(shí),必須采用FLAT模式。DOS下編程可選擇前六種模式,一般可以選用SMALL模式TINY模式產(chǎn)生COM程序,其他模式產(chǎn)生EXE程序,F(xiàn)LAT模式只能用于保護(hù)模式的32位程序簡(jiǎn)化段偽指令功能注釋.CODE[段名]創(chuàng)建一個(gè)代碼段段名為可選項(xiàng),如不給出段名,則采用默認(rèn)段名。對(duì)于多個(gè)代碼段的模型,則應(yīng)為每個(gè)代碼段指定段名。.DATA創(chuàng)建一個(gè)數(shù)據(jù)段段名是:_DATA.DATA?創(chuàng)建無(wú)初值變量的數(shù)據(jù)段段名是:_BSS.FARDATA[段名]建立有初值的遠(yuǎn)調(diào)用數(shù)據(jù)段可指定段名,如不指定,則將以FAR_DATA命名。.FARDATA?[段名]建立無(wú)初值的遠(yuǎn)調(diào)用數(shù)據(jù)段可指定段名,如不指定,則將以FAR_BSS命名。.CONST建立只讀的常量數(shù)據(jù)段段名是:CONST.STACK[大小]創(chuàng)建一個(gè)堆棧段并指定堆棧段大小段名是:stack。如不指定堆棧段大小,則缺省值為1KB簡(jiǎn)化段偽指令的格式簡(jiǎn)化段定義偽指令.STACK[大小]
;堆棧段開(kāi)始.DATA
;數(shù)據(jù)段開(kāi)始.CODE[段名]
;代碼段開(kāi)始簡(jiǎn)化段定義偽指令指明一個(gè)邏輯段的開(kāi)始,同時(shí)自動(dòng)結(jié)束前面的一個(gè)段采用簡(jiǎn)化段定義偽指令前,需有.model語(yǔ)句使用簡(jiǎn)化段定義,各段名稱(chēng)和其他用戶(hù)所需的信息可以使用MASM預(yù)定義符號(hào),例如:@data表示由.data等定義的數(shù)據(jù)段的段名堆棧段偽指令.STACK[大小]堆棧段偽指令.STACK創(chuàng)建一個(gè)堆棧段,段名是:stack它的參數(shù)指定堆棧段所占存儲(chǔ)區(qū)的字節(jié)數(shù),默認(rèn)是1KB(=1024=400h字節(jié))數(shù)據(jù)段偽指令.DATA數(shù)據(jù)段偽指令.data創(chuàng)建一個(gè)數(shù)據(jù)段,段名是:_DATA。它用于定義具有初值的變量,當(dāng)然也允許定義無(wú)初值的變量無(wú)初值變量可以安排在另一個(gè)段中,它用.data?偽指令創(chuàng)建,數(shù)據(jù)段名是:_BSS.const偽指令用于建立只讀的常量數(shù)據(jù)段(段名:CONST)代碼段偽指令.CODE[段名]代碼段偽指令.code創(chuàng)建一個(gè)代碼段,它的參數(shù)指定該代碼段的段名如果沒(méi)有給出段名,則采用默認(rèn)段名:在TINY、SMALL、COMPACT和FLAT模式下,默認(rèn)的代碼段名是:_TEXT在MEDIUM、LARGE和HUGE模式下,默認(rèn)的代碼段名是:模塊名_TEXT程序開(kāi)始偽指令.STARTUP按照CPU類(lèi)型、存儲(chǔ)模式、操作系統(tǒng)和堆棧類(lèi)型,產(chǎn)生程序開(kāi)始執(zhí)行的代碼;同時(shí)還指定程序開(kāi)始執(zhí)行的起始點(diǎn)在DOS下,還將設(shè)置DS值,調(diào)整SS和SP值movdx,dgroupmovds,dx ;設(shè)置DSmovbx,sssubbx,dxshlbx,1shlbx,1shlbx,1shlbx,1cli ;關(guān)中斷movss,dx ;調(diào)整SS和SPaddsp,bxsti ;開(kāi)中斷movdx,@datamovds,dx 程序終止偽指令.EXIT[返回參數(shù)]產(chǎn)生終止程序執(zhí)行返回操作系統(tǒng)的指令代碼它的可選參數(shù)是一個(gè)返回的數(shù)碼,通常用0表示沒(méi)有錯(cuò)誤。例如.exit0對(duì)應(yīng)的代碼是:movax,4c00hint21hDOS功能調(diào)用的4ch子功能(返回DOS):入口參數(shù):AH=4ch,AL=返回?cái)?shù)碼匯編結(jié)束偽指令END[標(biāo)號(hào)]指示匯編程序MASM到此結(jié)束匯編過(guò)程源程序的最后必須有一條END語(yǔ)句可選的標(biāo)號(hào)用于指定程序開(kāi)始執(zhí)行點(diǎn),連接程序?qū)?jù)此設(shè)置CS:IP值采用了.startup偽指令就不需要再用“end標(biāo)號(hào)”指明開(kāi)始執(zhí)行點(diǎn),但還要有end偽指令
————不要糊涂————程序終止和匯編結(jié)束是兩碼事;SampleB.ASMstack segmentstack dw512dup(?)stack endsdata segment
... ;在數(shù)據(jù)段定義數(shù)據(jù)data endscode segment’code’
assumecs:code,ds:data,ss:stackstart: movax,data movds,ax
... ;在代碼段填入指令序列
movax,4c00h int21h
...
;子程序代碼code ends endstart完整段定義格式
MASM5.x支持2023/7/2347段組定義偽指令段組定義偽指令能把多個(gè)同類(lèi)段合并為一個(gè)64KB的物理段,并用一個(gè)段組名統(tǒng)一存取它。段組定義偽指令GROUP的格式如下:
段組名GROUP段名[,段名…]在各種存儲(chǔ)模型中,匯編程序自動(dòng)地把各數(shù)據(jù)段組成一個(gè)段組DGROUP,以便程序在訪問(wèn)各數(shù)據(jù)段時(shí)使用一個(gè)數(shù)據(jù)段寄存器DS,而GROUP偽指令允許用戶(hù)自行指定段組。例將兩個(gè)數(shù)據(jù)段DSEG1和DSEG2合并在一個(gè)段組DATAGROUP中。
;
DSEG1
SEGMENTWORDPUBLIC‘DATA’
……
DSEG1
ENDS
;
DSEG2
SEGMENTWORDPUBLIC‘DATA’
……
DSEG2
ENDS
;
DATAGROUP
GROUPDSEG1,DSEG2
;組合成段組
CSEG
SEGMENTPARAPUBLIC‘CODE’
ASSUME
CS:CSEG,DS:DATAGROUP
START:MOV
AX,DATAGROUP
MOV
DS,AX;DS賦值為段組地址
.
.
.
MOV
AX,4C00H
INT
21H
CSEG
ENDS
;
END
STARTexe程序它可以有獨(dú)立的代碼、數(shù)據(jù)和堆棧段,還可以有多個(gè)代碼段或多個(gè)數(shù)據(jù)段,程序長(zhǎng)度可以超過(guò)64KB,執(zhí)行起始處可以任意指定當(dāng)DOS裝入或執(zhí)行一個(gè)程序時(shí),DOS確定當(dāng)時(shí)主存最低的可用地址作為該程序的裝入起始點(diǎn)。此點(diǎn)以下的區(qū)域稱(chēng)為程序段。在程序段內(nèi)偏移0處,DOS為該程序建立一個(gè)程序段前綴控制塊PSP(ProgramSegmentPrefix),它占256(=100h)個(gè)字節(jié);而在偏移100h處才裝入程序本身內(nèi)存映象exe程序的內(nèi)存映象圖com程序COM程序是一種將代碼、數(shù)據(jù)和堆棧段合一的結(jié)構(gòu)緊湊的程序,所有代碼、數(shù)據(jù)都在一個(gè)邏輯段內(nèi),不超過(guò)64KB在程序開(kāi)發(fā)時(shí),需要滿(mǎn)足一定要求并采用相應(yīng)參數(shù)才能正確生成COM結(jié)構(gòu)的程序COM文件存儲(chǔ)在磁盤(pán)上是主存的完全影象,不包含重新定位的加載信息,與EXE文件相比其加載速度更快,占用的磁盤(pán)空間也少盡管DOS也為COM程序建立程序段前綴PSP,但由于兩種文件結(jié)構(gòu)不同,所以加載到主存后各段設(shè)置并不完全一樣內(nèi)存映象com程序的內(nèi)存映象圖COM文件的建立(MASM5.0支持的格式)例:
;TITLE文件名--程序功能描述
.model
tiny
;微小模型
.code
;定義代碼段
org
100h
;指定程序起始地址
start:jmp
begin
;跳過(guò)數(shù)據(jù)區(qū)
;數(shù)據(jù)定義語(yǔ)句
begin:
;程序語(yǔ)句
mov
ax,4c00h ;返回DOS
int
21h
end
start
;匯編結(jié)束.modeltiny;微型模型.code;定義代碼段org100h ;指定程序起始地址start:jmpbegin;跳過(guò)數(shù)據(jù)區(qū)bufdb'HelloWorld!',0dh,0ah,'$'begin:movax,csmovds,axmovdx,offsetbufmovah,9int21h movax,4c00h ;返回DOSint21hendstart ;匯編結(jié)束2023/7/2355COM文件的建立使用COM文件時(shí),程序不分段,其入口點(diǎn)(開(kāi)始運(yùn)行的起始點(diǎn))必須是100H,在此之前的256個(gè)字節(jié)是程序段前綴。COM文件不必設(shè)置堆棧段。在程序裝入時(shí),由系統(tǒng)自動(dòng)把SP建立在該段之末。對(duì)于所有的過(guò)程則應(yīng)定義為NEAR。用戶(hù)在建立源文件以后,經(jīng)過(guò)匯編、連接形成EXE文件,然后可以通過(guò)EXE2BIN程序來(lái)建立COM文件,操作命令如下:
C>exe2binfilename<CR>COM文件還可以直接在調(diào)試程序DEBUG中用A或E命令建立,對(duì)于一些短小的程序,這也是一種相當(dāng)方便的方法。2023/7/2356數(shù)據(jù)定義及存儲(chǔ)器分配偽操作2023/7/2357參數(shù)、變量和標(biāo)號(hào)本節(jié)詳細(xì)討論匯編語(yǔ)言程序語(yǔ)句的主要部分:參數(shù)變量名標(biāo)號(hào)并引出相關(guān)的偽指令和操作符本節(jié)重點(diǎn)掌握:常數(shù)的表達(dá)變量定義偽指令DB/DW/DD地址操作符和類(lèi)型操作符2023/7/2358地址型參數(shù)匯編語(yǔ)言程序中,指令參數(shù)還有地址型,它的主要形式是標(biāo)號(hào)和名字(變量名、段名、過(guò)程名等)硬指令的操作數(shù)有存儲(chǔ)單元;存儲(chǔ)單元就應(yīng)該用地址型參數(shù)(存儲(chǔ)器操作數(shù))表達(dá)2023/7/2359變量定義偽指令變量定義(Define)偽指令為變量申請(qǐng)固定長(zhǎng)度的存儲(chǔ)空間,并可同時(shí)將相應(yīng)的存儲(chǔ)單元初始化變量名偽指令助記符初值表
變量定義偽指令最常使用2023/7/2360變量名變量名為用戶(hù)自定義標(biāo)識(shí)符,表示初值表首元素的邏輯地址;用這個(gè)符號(hào)表示地址,常稱(chēng)為符號(hào)地址變量名可以沒(méi)有。這種情況,匯編程序?qū)⒅苯訛槌踔当矸峙淇臻g,無(wú)符號(hào)地址設(shè)置變量名是為了方便存取它指示的存儲(chǔ)單元2023/7/2361初值表初值表是用逗號(hào)分隔的參數(shù)主要由數(shù)值常數(shù)、表達(dá)式或?、DUP組成?——表示初值不確定,即未賦初值;DUP——表示重復(fù)初值DUP的格式為:重復(fù)次數(shù)DUP(重復(fù)參數(shù))2023/7/2362變量定義偽指令根據(jù)申請(qǐng)的主存空間單位分類(lèi)DB——定義字節(jié)偽指令DW——定義字偽指令DD——定義雙字偽指令DF——定義3字偽指令DQ——定義4字偽指令DT——定義10字節(jié)偽指令還有定位偽指令定義字節(jié)單元偽指令DBDB偽指令用于分配一個(gè)或多個(gè)字節(jié)單元,并可以將它們初始化為指定值初值表中每個(gè)數(shù)據(jù)一定是字節(jié)量(Byte),存放一個(gè)8位數(shù)據(jù):可以是0~255的無(wú)符號(hào)數(shù)或是-128~+127帶符號(hào)數(shù)也可以是字符串常數(shù)實(shí)例data segment ;數(shù)據(jù)段X db'a',-5 db2dup(100),?Y db'ABC'data ends字節(jié)單元定義實(shí)例應(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'字節(jié)變量的應(yīng)用定義字單元偽指令DWDW偽指令用于分配一個(gè)或多個(gè)字單元,并可以將它們初始化為指定值初值表中每個(gè)數(shù)據(jù)一定是字量(Word),一個(gè)字單元可用于存放任何16位數(shù)據(jù):一個(gè)段地址一個(gè)偏移地址兩個(gè)字符
0~65535之間的無(wú)符號(hào)數(shù)-32768~+32767之間的帶符號(hào)數(shù)實(shí)例data segment ;數(shù)據(jù)段count dw8000h,?,'AB'maxint equ64hnumber dwmaxintarray dwmaxintdup(0)data ends字單元定義實(shí)例字變量和字常量的定義:WNUM EQU5678H ;定義WNUM為常量COUNTDW20H;定義COUNT變量,假設(shè)在數(shù)據(jù)段的偏移地址為10H字變量和字常量的應(yīng)用:MOVAX,[BX+SI+WNUM] ;MOVAX,[BX+SI+5678H]MOVAX,COUNT ;MOVAX,[0010H]MOVAX,[SI+COUNT] ;MOVAX,COUNT[SI] ;MOVAX,[SI+10H]LEABX,COUNT ;LEABX,[0010H]MOVBX,OFFSETCOUNT ;MOVBX,0010H字變量和字常量定義雙字單元偽指令DDDD偽指令用于分配一個(gè)或多個(gè)雙字單元,并可以將它們初始化為指定值初值表中每個(gè)數(shù)據(jù)是一個(gè)32位的雙字量(DoubleWord):可以是有符號(hào)或無(wú)符號(hào)的32位整數(shù)也可以用來(lái)表達(dá)16位段地址(高位字)和16位的偏移地址(低位字)的遠(yuǎn)指針vardd DD0,?,12345678hfarpoint DD00400078h其他數(shù)據(jù)單元定義偽指令定義3字偽指令DF——用于為一個(gè)或多個(gè)6字節(jié)變量分配空間及初始化6字節(jié)常用在32位CPU中表示一個(gè)48位遠(yuǎn)指針(16位段選擇器:32位偏移地址)定義4字偽指令DQ——用于為一個(gè)或多個(gè)8字節(jié)變量分配空間及初始化8字節(jié)變量可以表達(dá)一個(gè)64位整數(shù)定義10字節(jié)偽指令DT——用于為一個(gè)或多個(gè)10字節(jié)變量分配空間及初始化10字節(jié)變量可以表達(dá)擴(kuò)展精度浮點(diǎn)數(shù)例4.2:數(shù)據(jù)定義綜合應(yīng)用-1/2 .modelsmall .stack .databvar DB16wvar DW4*3dvar DD12345678h qvar DQ?
DB1,2,3,4,5tvar DT2345 ;定義了BCD碼2345Habc DB'a','b','c'msg DB'Hello',13,10,'$'bbuf DB12DUP('month')dbuf DD25DUP(?)CALLDOS EQU<int21h>例4.2:數(shù)據(jù)定義綜合應(yīng)用-2/2 .code .startup movbl,bvar movax,wordptrdvar[0] movdx,wordptrdvar[2] ;取雙字到DX.AX movdx,offsetmsg movah,09h CALLDOS .exit0 end例4.3:數(shù)據(jù)復(fù)制和顯示-1/2 .modelsmall .stack .datasourcedb33h,34h,35h,36h ;定義4個(gè)字符數(shù)據(jù)targetdb80dup(?) ;分配數(shù)據(jù)空間4×20=80 .code .startup movax,ds moves,ax ;data也作為附加段
cld movsi,offsetsource movdi,offsettarget movcx,80例4.3:數(shù)據(jù)復(fù)制和顯示-2/2
repmovsb
;串傳送
movsi,0 ;顯示
movbx,offsettargetagain: movdl,[bx+si] movah,2 int21h incsi cmpsi,80 jbagain .exit0 end表達(dá)式賦值偽操作利用一個(gè)標(biāo)識(shí)符表達(dá)的一個(gè)數(shù)值MASM提供等價(jià)機(jī)制,用于常量定義符號(hào)定義偽指令:等價(jià)EQU偽指令符號(hào)名EQU數(shù)值表達(dá)式符號(hào)名EQU<字符串>等號(hào)=偽指令符號(hào)名=數(shù)值表達(dá)式常數(shù)若使用有意義的符號(hào)名來(lái)表示,可以提高程序的可讀性,同時(shí)更具有通用性實(shí)例EQU偽操作中的標(biāo)號(hào)名是不允許重復(fù)定義的,而“=”
偽操作是允許重復(fù)定義的?!舯磉_(dá)式賦值偽操作:表達(dá)式名EQU表達(dá)式ALPHAEQU9BETAEQUALPHA+18BBEQU[BP+8]“=”偽操作(允許重復(fù)定義)……EMP=7……EMP=EMP+1……符號(hào)定義
DosWriteChar equ 2 CarriageReturn = 13 CallDOS equ <int21h>符號(hào)應(yīng)用(左邊程序段等價(jià)右側(cè)的符號(hào)形式)
movah,2 ;movah,DosWriteChar movdl,13 ;movdl,CarriageReturn int21h ;CallDOS符號(hào)常數(shù)實(shí)例地址計(jì)數(shù)器與對(duì)準(zhǔn)偽操作定位偽指令控制數(shù)據(jù)的偏移地址ORG
參數(shù)ORG偽指令是將當(dāng)前偏移地址指針指向參數(shù)表達(dá)的偏移地址:ORG100h ;從100h處安排數(shù)據(jù)或程序ORG$+10;使偏移地址加10,即跳過(guò)10個(gè)字節(jié)空間MASM中,符號(hào)“$”表示當(dāng)前偏移地址值EVEN ;從偶地址開(kāi)始ALIGNn ;從n的整數(shù)倍地址開(kāi)始2023/7/2379
變量和標(biāo)號(hào)的屬性標(biāo)號(hào)和名字一經(jīng)定義便具有以下兩類(lèi)三種屬性:①段值標(biāo)號(hào)和名字對(duì)應(yīng)存儲(chǔ)單元的段地址②偏移值標(biāo)號(hào)和名字對(duì)應(yīng)存儲(chǔ)單元的偏移地址③類(lèi)型標(biāo)號(hào)、子程序名的類(lèi)型可以是NEAR(近)和FAR(遠(yuǎn)),分別表示段內(nèi)或段間變量名的類(lèi)型可以是BYTE(字節(jié))、WORD(字)和DWORD(雙字)等地址屬性類(lèi)型屬性地址操作符取得名字或標(biāo)號(hào)的段地址和偏移地址兩個(gè)屬性[]
將括起的表達(dá)式作為存儲(chǔ)器地址$
當(dāng)前偏移地址:
采用指定的段地址寄存器OFFSET名字/標(biāo)號(hào)返回名字或標(biāo)號(hào)的偏移地址SEG名字/標(biāo)號(hào)返回名字或標(biāo)號(hào)的段地址實(shí)例 org$+10array db45,45h .code movax,segarray movds,ax movbx,offsetarray ;等價(jià)于leabx,array movcl,[array+4] ;等效于movcl,array[4] movax,es:[2000h]地址操作符實(shí)例
加4個(gè)字節(jié)單元ARRAY
DW1,2,$+4,3,4,$+4
假設(shè)匯編時(shí)ARRAY分配的偏移地址為0074H,則匯編后,$+4所在的兩個(gè)字單元:
(ARRAY+4)=0078+4=007CH
(ARRAY+0A)=007E+4=0082H
地址操作符實(shí)例2023/7/2383表達(dá)式表達(dá)式是常數(shù)、寄存器、標(biāo)號(hào)、變量與一些操作符相組合的序列,可以有數(shù)字表達(dá)式和地址表達(dá)式兩種。在匯編期間,匯編程序按照一定的優(yōu)先規(guī)則對(duì)表達(dá)式進(jìn)行計(jì)算后可得到一個(gè)數(shù)值或一個(gè)地址。
常用的表達(dá)式操作符介紹如下:
(1)算術(shù)操作符(2)邏輯操作符(3)關(guān)系操作符2023/7/2384(1)算術(shù)操作符算術(shù)操作符有+、-、*、/和MOD。例:如果要求把首地址為BLOCK的字?jǐn)?shù)組的第6個(gè)字傳送到DX寄存器,可用指令如下:
MOV
DX,BLOCK+(6-1)*2例:如數(shù)組ARRAY定義如下,寫(xiě)出把數(shù)組長(zhǎng)度(字?jǐn)?shù))存入CX寄存器的指令。
ARRAY
DW1,2,3,4,5,6,7
ARYEND
DW?
其中ARYEND是為計(jì)算數(shù)組長(zhǎng)度而建立的符號(hào)地址,所需指令如下:
MOV
CX,(ARYEND-ARRAY)/2
匯編程序在匯編期間將計(jì)算出表達(dá)式的值而形成指令:
MOV
CX,7
2023/7/2385(2)邏輯操作符邏輯操作符有:AND(與)、OR(或)、XOR(異或)、NOT(非)。
邏輯操作符都是按位操作的,只能用于數(shù)字表達(dá)式中。例: OUTPORT_VALAND0FEH,AL
上例中PORT_VAL為端口號(hào),OUT指令中的表達(dá)式說(shuō)明只為偶數(shù)號(hào)端口輸出數(shù)據(jù)。例: ANDDX,PORT_VALAND0FEH
由匯編程序?qū)χ噶钪械谋磉_(dá)式進(jìn)行計(jì)算得到一個(gè)端口號(hào),而在程序運(yùn)行時(shí),該指令的執(zhí)行是把DX寄存器的內(nèi)容與匯編程序計(jì)算得到的端口號(hào)進(jìn)行“與”操作,結(jié)果保存在DX寄存器中。2023/7/2386(3)關(guān)系操作符關(guān)系操作符有:EQ(相等)、NE(不等)、LT(小于)、GT(大于)、LE(小于或等于)、GE(大于或等于)。
關(guān)系操作符的兩個(gè)操作數(shù)必須都是數(shù)字或是同一段內(nèi)的兩個(gè)存儲(chǔ)器地址。計(jì)算的結(jié)果應(yīng)為邏輯值:結(jié)果為真,表示為0FFFFH;結(jié)果為假,則表示為0。例如:MOVBX,((PORT_VALLT5)AND20)OR((PORT_VALGE5)AND30)
則當(dāng)PORT_VAL<5時(shí),匯編結(jié)果應(yīng)該是:
MOVBX,20
否則,匯編結(jié)果應(yīng)該是:
MOVBX,30類(lèi)型操作符類(lèi)型操作符對(duì)名字或標(biāo)號(hào)的類(lèi)型屬性進(jìn)行有關(guān)設(shè)置類(lèi)型名
PTR
名字/標(biāo)號(hào)THIS
類(lèi)型名SHORT
標(biāo)號(hào)TYPE
名字/標(biāo)號(hào)SIZE
變量名LENGTH
變量名PTR操作符類(lèi)型名PTR名字/標(biāo)號(hào)PTR操作符使名字或標(biāo)號(hào)具有指定的類(lèi)型類(lèi)型名可以是BYTE/WORD/DWORD/FWORD/QWORD/TBYTE或者是NEAR/FAR,還可以是由STRUCT、RECORD、UNION以及TYPEDEF定義的類(lèi)型moval,byteptrw_var ;w_var是一個(gè)字變量jmpfarptrn_label ;n_label是一個(gè)標(biāo)號(hào)使用PTR操作符,可以臨時(shí)改變名字或標(biāo)號(hào)的類(lèi)型THIS操作符THIS類(lèi)型名利用THIS說(shuō)明的操作數(shù)具有匯編時(shí)的當(dāng)前邏輯地址,但具有指定的類(lèi)型b_varequ
THISbytew_vardw10dup(0) ;按字訪問(wèn)變量w_var;按字節(jié)訪問(wèn)變量b_var,但與w_var的地址相同f_jumpequTHISfarn_jump:movax,w_var;用f_jump為段間轉(zhuǎn)移(f_jumplabelfar);用n_jump為段內(nèi)近轉(zhuǎn)移,但兩者指向同一條指令LABEL偽指令的功能等同于“EQUTHIS”SHORT操作符SHORT標(biāo)名指定標(biāo)號(hào)作為-128~+127字節(jié)范圍內(nèi)的短轉(zhuǎn)移jmpshortn_jump當(dāng)然,如果標(biāo)號(hào)實(shí)際上超出了這個(gè)范圍,則出錯(cuò)。
對(duì)高版本MASM已無(wú)意義TYPE操作符TYPE名字/標(biāo)名返回表明名字或標(biāo)號(hào)類(lèi)型的一個(gè)字量數(shù)值對(duì)字節(jié)、字和雙字變量依次返回1、2和4;對(duì)近和遠(yuǎn)轉(zhuǎn)移依次返回-1、-2movax,TYPEw_var ;匯編結(jié)果為movax,2movax,TYPEn_jump;匯編結(jié)果為movax,-1(near標(biāo)號(hào))操作符SIZE返回整個(gè)變量占用的字節(jié)數(shù)LENGTH返回整個(gè)變量的數(shù)據(jù)項(xiàng)數(shù)
SIZE=
LENGTH×TYPE2023/7/2392注意LENGTH運(yùn)算符和SIZE運(yùn)算符僅加在變量名的前面如果變量是用DUP定義的,那么LENGTH的運(yùn)算結(jié)果是外層DUP的重復(fù)次數(shù)如果變量沒(méi)有用DUP定義,那么LENGTH的運(yùn)算結(jié)果總是1例題:屬性及其應(yīng)用-1/5 .modelsmall .stack .datav_byte equthisbyte;v_byte是字節(jié)類(lèi)型,與變量v_word的地址相同v_word dw3332h,3735h
;v_word是字類(lèi)型的變量target dw5dup(20h)
;分配數(shù)據(jù)空間2×5=10字節(jié)crlf db0dh,0ah,'$'flag db0n_point dwoffsets_label
;取得標(biāo)號(hào)s_label的偏移地址例題:屬性及其應(yīng)用-2/5 .code .startup moval,byteptrv_word;用PTR改變v_word的類(lèi)型,否則類(lèi)型不匹配
decal movv_byte,al;對(duì)v_word的頭一個(gè)字節(jié)操作,原為32H、現(xiàn)為31Hn_label: cmpflag,1 jzs_label ;flag單元為1轉(zhuǎn)移
incflag jmpshortn_label ;進(jìn)行短轉(zhuǎn)移例題:屬性及其應(yīng)用-3/5s_label: cmpflag,2 jznext ;flag單元為2轉(zhuǎn)移
incflag
jmpn_point;段內(nèi)的存儲(chǔ)器間接尋址,轉(zhuǎn)移到s_label標(biāo)號(hào)處next: movax,typev_word ;匯編結(jié)果為movax,2 movcx,lengthoftarget ;匯編結(jié)果為movcx,5例題:屬性及其應(yīng)用-4/5 movsi,offsettargetw_again: mov[si],ax ;對(duì)字單元操作
incsi ;SI指針加2 incsi loopw_again ;循環(huán)
movcx,sizeoftarget
;匯編結(jié)果為
movcx,0ah moval,'?' movdi,offsettargetb_again: mov[di],al ;對(duì)字節(jié)單元操作
incdi ;DI指針加1 loopb_again ;循環(huán)例題:屬性及其應(yīng)用-5/5 movdx,offsetv_word ;顯示結(jié)果:1357?????????? movah,9 int21h .exit0 end1.設(shè)X和X+2單元的內(nèi)容為雙精度數(shù)P,Y和Y+2單元的內(nèi)容為雙精度數(shù)Q,X、Y為低位字。下列程序段使2P>Q時(shí)(AX)=1,2P<=Q時(shí)(AX)=2。請(qǐng)將程序段填寫(xiě)完整。
MOVDX,X+2
MOVAX,X
ADDAX,X
ADCDX,X+2
CMPDX,Y+2
L2
L1
CMPAX,Y
L2
L1: MOVAX,1
JMPEXIT
L2: MOVAX,2
EXIT:……JLJGJLE2.假設(shè)程序中的數(shù)據(jù)定義如下,
PARTNO DW ?
PNAME
DB 16DUP(?)
COUNT
DD ?
PLENTH EQU $-PARTNO
問(wèn)PLENTH的值為多少?3.給出賦值語(yǔ)句如下:
ALPHA EQU100
BETA EQU25
GAMMA EQU2
下列表達(dá)式的值是多少?
(1)ALPHA*100+BETA
(2)ALPHAMODGAMMA+BETA
(3)(ALPHA+2)*BETA-2
(4)(BETA/3)MOD5
(5)(ALPHA+3)*(BETAMODGAMMA)
(6)ALPHAGEGAMMA
(7)BETAAND7
(8)GAMMAOR3
4.對(duì)于下面的數(shù)據(jù)定義,各條MOV指令單獨(dú)執(zhí)行后,有關(guān)寄存器的內(nèi)容是什么?
FLDB DB?
TABLEA DW20DUP(?)
TABLEB DB'ABCD'
(1)MOVAX,TYPEFLDB
(2)MOVAX,TYPETABLEA
(3)MOVCX,LENGTHTABLEA
(4)MOVDX,SIZETABLEA
(5)MOVCX,LENGTHTABLEB2023/7/23102循環(huán)程序設(shè)計(jì)分支程序設(shè)計(jì)循環(huán)與分支程序設(shè)計(jì)2023/7/23103分支結(jié)構(gòu)子程序結(jié)構(gòu)程序結(jié)構(gòu):
復(fù)合結(jié)構(gòu):多種程序結(jié)構(gòu)的組合…
順序結(jié)構(gòu)循環(huán)結(jié)構(gòu)2023/7/23104編制匯編語(yǔ)言程序的步驟:(1)分析題意,確定算法(2)根據(jù)算法畫(huà)出程序框圖(3)根據(jù)框圖編寫(xiě)程序(4)上機(jī)調(diào)試程序2023/7/231051.循環(huán)程序設(shè)計(jì)DO-WHILE結(jié)構(gòu)
DO-UNTIL結(jié)構(gòu)控制條件初始化循環(huán)體YN控制條件初始化循環(huán)體YN2023/7/23106初始化:設(shè)置循環(huán)的初始狀態(tài)循環(huán)體:循環(huán)的工作部分及修改部分控制條件:計(jì)數(shù)控制特征值控制地址邊界控制2023/7/23107
BX1234例:把BX中的二進(jìn)制數(shù)以十六進(jìn)制的形式顯示在屏幕上2023/7/23108
……
movch,4 ;計(jì)數(shù)值4個(gè)數(shù)rotate:movcl,4 ;移幾位
rolbx,clmoval,blandal,0fhaddal,30h;’0’~’9’ASCII30H~39Hcmpal,3ahjlprintitaddal,7h;’A’~’F’ASCII41H~46Hprintit:movdl,almovah,2int21hdecchjnzrotate
……2023/7/23109
……movbx,0newchar:movah,1;鍵盤(pán)輸入
int21hsubal,30hjlexit;<0退出
cmpal,9jgexit;>9退出
cbwxchgax,bxmovcx,10mulcxxchgax,bxaddbx,axjmpnewcharexit:……例:從鍵盤(pán)接收十進(jìn)制數(shù)并存入BX((0×10)+1)×10+2)×10+51253132352023/7/23110
……movbx,0newchar:movah,1;鍵盤(pán)輸入
int21hsubal,30hjlexit;<0退出
cmpal,10jladd_tosubal,27h;‘a(chǎn)’~‘f’cmpal,0ahjlexit;<‘a(chǎn)’退出
cmpal,10hjgeexit;>’f’退出add_to:movcl,4shlbx,clmovah,0addbx,axjmpnewcharexit:……例:從鍵盤(pán)接收十六進(jìn)制數(shù)并存入BX1af316166((0×16)+1)×16+0a)×16+0f2023/7/231112.分支程序設(shè)計(jì)…case1case2casen??case1case2casenCASE結(jié)構(gòu)
IF-THEN-ELSE結(jié)構(gòu)(1)邏輯尺控制(2)條件控制(3)地址跳躍表(值與地址有對(duì)應(yīng)關(guān)系的表)判斷方程ax2+bx+c=0是否有實(shí)根,若有置tag為1,否則置0(a,b,c,tag均為字節(jié)變量)。計(jì)算b2-4ac,判其>0否,DatasegmentA db 1B db 2C db 1Tag db ?DataendsCodesegment assumecs:code,ds:dataStart: mov ax,data mov ds,ax mov al,b imul al mov bx,ax ;b*b→bx mov al,a imul c ;a*c→ax mov cl,2 shl ax,cl ;4ac→ax
cmp bx,ax jge yes mov tag,0 jmp exitYes: mov tag,1Exit: mov ax,4c00h int 21hCode ends endstart例4.17顯示兩位壓縮BCD碼值(00-99),要求不顯示前導(dǎo)0.顯示要區(qū)分BCD碼值為0,為0~9,和10~99三種情況,分別進(jìn)行處理。.dataBCD db 04h.code mov dl,BCD test dl,0FFH jz zero ;若為0,則表示BCD=0 test dl,0F0hH
jz one ;若為0,表明BCD的高位是0,BCD:01~09 mov cl,4 ;此時(shí)表明BCD是10~99間的數(shù)
shr dl,cl or dl,30h mov ah,2 int 21h mov dl,BCD and dl,0FhOne: or dl,30h jmp twoZero: mov dl,‘0’Two: mov ah,2 int 21h mov ax,4c00h int 21h例4.18從鍵盤(pán)輸入一個(gè)字符串,將其小寫(xiě)字母轉(zhuǎn)換為大寫(xiě)字母,然后顯示。鍵盤(pán)輸入字符串:int21h的0A功能,DX+1為字符串中的字符個(gè)數(shù),DX+2為字符串首地址。.data Keynum=255Keybuf db keynum ;定義鍵盤(pán)輸入緩沖區(qū) db 0db keynumdup(0) .code lea dx,keybuf mov ah,0ah int 21h mov dl,oah ;顯示換行符
mov ah,2 int 21h lea bx,keybuf+1 mov cl,[bx] movch,0 ;取出字符個(gè)數(shù)Again: inc bx mov dl,[bx] ;取出一個(gè)字符
cmp dl,‘a(chǎn)’ jb disp ;是大寫(xiě)字母或數(shù)字,不需轉(zhuǎn)換,直接顯示
cmp dl,‘z’ ja disp ;不是小寫(xiě)字母,直接顯示
sub dl,20h ;是小寫(xiě)字母,轉(zhuǎn)換為大寫(xiě)字母Disp: mov ah,2 int 21h loop again mov ax,4c00 int 21h例4.19利用地址表實(shí)現(xiàn)多分支結(jié)構(gòu)。從底位到高位逐位檢測(cè)一個(gè)字節(jié)數(shù)據(jù),為0時(shí)繼續(xù),為1時(shí)轉(zhuǎn)移。.dataNumber db 78hAddrs dw offsetfun0,offsetfun1,offsetfun2,offsetfun3 dw offsetfun4,offsetfun5.offsetfun6,offsetfun7;取得各處理程序的偏移地址.code mov al,number mov dl,‘?’ cmp al,0 jz disp ;number=0直接顯示 mov bx,0 ;BX記錄為1的位數(shù)Again: shr al,1 ;LSB→CF jc next ;CF=1,轉(zhuǎn)移
inc bx ;CF=0,繼續(xù)
jmp againNext: shl bx,1 ;位數(shù)乘2, jmp addrs[bx]Fun0: mov dl,‘0’ jmp dispFun1: mov dl,‘1’ jmp dispFun2: mov dl,‘2’ jmp dispFun3: mov dl,‘3’ jmp dispFun4: mov dl,‘4’ jmp dispFun5: mov dl,‘5’ jmp dispFun6: mov dl,‘6’ jmp dispFun7: mov dl,‘7’ jmp disp …Disp: mov ah,2 int 21h例4.20用二進(jìn)制顯示從鍵盤(pán)輸入的一個(gè)字符的ASCII碼。 .model small .data .stack .codeStart: movax,@data movds,ax mov ah,1 int 21h mov bl,al ;鍵盤(pán)輸入字符→bl保存 mov ah,2 mov dl,‘:’ int 21h ;顯示冒號(hào)
mov cx,8 ;字符有8位Again: shl bl,1 :MSB→CF mov dl,0 adc dl,30h ;將最高位轉(zhuǎn)換成顯示字符
mov ah,2 int 21h loop again mov ax,4c00h int 21h endstart
例4.21求數(shù)組元素的最大值和最小值。.dataArray dw 10,-3,0,20,900,587,-632,777,234,-34,-56Maxay dw ?Minay dw ?.code ;此處初始化ds lea si,array mov cx,[si] ;取數(shù)組元素個(gè)數(shù) dec cx add si,2 mov ax,[si] ;AX暫存最大值 mov bx,ax ;BX暫存最小值Maxchk: add si,2 cmp [si],ax jle minchk ;當(dāng)前元素小于等于ax,轉(zhuǎn)去判最小數(shù) mov ax,[si] ;當(dāng)前元素大于AX,則→ax jmp nextMinchk: cmp [si],bx jge next ;當(dāng)前元素大于bx,則繼續(xù)
mov bx,[si];當(dāng)前元素小于bx,則將其保存到bxNext: loop maxchk mov maxay,ax mov minay,bx mov ax,4c00h int 21h例4.22從鍵盤(pán)接受一個(gè)十進(jìn)制數(shù)N,然后顯示N次問(wèn)號(hào).code mov ah,1 int 21h and al,0fh xor ah,ah mov cx,ax jcxz doneAgain: mov dl,‘?’ mov ah,2 int 21h loop again mov ax,4c00h int 21hDone:………….例4.23記錄字存儲(chǔ)單元數(shù)據(jù)中1的個(gè)數(shù),以十進(jìn)制形式顯示結(jié)果。.dataNumber dw 1110111111100100B.code mov bx,number xor dl,dlAgain: test bx,0ffffh jz done shl bx,1 ;MSB→CF adc dl,0 jmp againDone: cmp dl,10 jb digit push dx mov dl,‘1’ mov ah,2 int 21h pop dx sub dl,10Digit: add dl,‘0’ mov ah,2 int 21h mov ax,4c00h int 21h例4.24現(xiàn)有一個(gè)以’0’結(jié)尾的字符串,要求剔除其中的空格字符。.dataString db ‘Letushaveatry!’,0.code mov al,20h lea di,stringOutlp: cmp byteptr[di],0 jz done ;字符串結(jié)束
cmp al,[di] jnz next mov si,diInlp: inc si mov ah,[si] mov [si-1],ah
cmp byteptr[si],0 jnz inlpNext: inc di jmp outlp ….Done: mov ax,4c00h
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
- 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ì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 三方參與股權(quán)轉(zhuǎn)讓合同示范文本版
- 初中英語(yǔ)七年級(jí)知識(shí)點(diǎn)總結(jié)
- 2024西安存量房買(mǎi)賣(mài)資金監(jiān)管服務(wù)協(xié)議
- 2025年度智能制造勞動(dòng)合同法實(shí)施細(xì)則3篇
- 2024期限內(nèi)渣土外運(yùn)進(jìn)度保障合同
- 2025年度創(chuàng)意辦公空間轉(zhuǎn)租及配套服務(wù)合同3篇
- 2024年租賃場(chǎng)所安全協(xié)議書(shū)2篇
- 2024年蘋(píng)果手機(jī)維修服務(wù)合同范本3篇
- 2024藥品采購(gòu)合同范本:慢性病藥品采購(gòu)合作協(xié)議3篇
- 專(zhuān)業(yè)化運(yùn)輸作業(yè)承包協(xié)議模板
- 就業(yè)招聘服務(wù)行業(yè)經(jīng)營(yíng)模式分析
- 港口液體?;费b卸管理人員理論考試題庫(kù)-下(判斷題)
- 【中小企業(yè)融資難問(wèn)題探究的國(guó)內(nèi)外綜述5800字】
- 2024關(guān)于家長(zhǎng)會(huì)家長(zhǎng)代表發(fā)言稿(30篇)
- 中醫(yī)內(nèi)科學(xué):中醫(yī)內(nèi)科學(xué)肢體經(jīng)絡(luò)病證考試題(題庫(kù)版)
- 高中生物學(xué)科思維導(dǎo)圖(人教版必修一)
- DL∕T 2138-2020 電力專(zhuān)利價(jià)值評(píng)估規(guī)范
- NB-T10859-2021水電工程金屬結(jié)構(gòu)設(shè)備狀態(tài)在線(xiàn)監(jiān)測(cè)系統(tǒng)技術(shù)條件
- 深圳市購(gòu)物中心租金調(diào)查
- GJB9001C產(chǎn)品風(fēng)險(xiǎn)評(píng)估報(bào)告
- 2024年天津三源電力集團(tuán)限公司社會(huì)招聘33人【重點(diǎn)基礎(chǔ)提升】模擬試題(共500題)附帶答案詳解
評(píng)論
0/150
提交評(píng)論