




版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
第1章第2章第3章第4章第5章第6章第7章第8章第9章第10章
第二早
匯編語(yǔ)言程序設(shè)計(jì)
指令系統(tǒng)中的指令,在計(jì)算機(jī)內(nèi)存中,都是以二進(jìn)制編碼的形式存儲(chǔ)的,這種編碼
稱為機(jī)器碼,或者稱為機(jī)器指令.在程序運(yùn)行時(shí),指令由內(nèi)存讀入CPU,然后譯碼,
執(zhí)行.只有內(nèi)存中的機(jī)器碼,計(jì)算機(jī)才能執(zhí)行.然而,.機(jī)器碼很難記憶,使用時(shí)極
易出錯(cuò),因此,直接利用機(jī)器碼編制程序是極其困難又枯燥乏味的工作.編程的程
序,晦澀難懂,即使編程者本人,,編程后不出數(shù)日,對(duì)自己的程序,也可能不解其
慧,需仔細(xì)琢磨才能恍然大悟.這時(shí),若有詳細(xì)的程序注釋,那將會(huì)給你帶來(lái)極大
方便,免除再度疲勞之苦.
實(shí)際的需要激發(fā)人們?nèi)?chuàng)造一種符號(hào)一助記符,用他們?nèi)ゴ鏅C(jī)器碼來(lái)表示指令,
既有簡(jiǎn)單明了的詞意,一目了然,又便于理解和記憶,于是,匯編語(yǔ)言應(yīng)運(yùn)而生.
現(xiàn)在,我們可以用指令助記符和表示地址或數(shù)據(jù)等的各種符號(hào),按照規(guī)定的格式,
來(lái)編制程序,這樣的程序,稱為匯編語(yǔ)言程序.這些表示指令,地址,數(shù)據(jù)等的符號(hào)
以及有關(guān)規(guī)定,是計(jì)算機(jī)進(jìn)行:“思想”的工具,亦即計(jì)算機(jī)匯編語(yǔ)言.
匯編語(yǔ)言與具體的計(jì)算機(jī)類型有密切的關(guān)系,不同的中央處理單元,其指令系統(tǒng)
也各不相同,相應(yīng)的匯編語(yǔ)言也互不相同.與硬件關(guān)系密切的程序,或者實(shí)時(shí)性要
求很高的程序,往往采用匯編程序.
在編輯程序的支持下,匯編語(yǔ)言程序從鍵盤輸入,編輯形成匯編語(yǔ)言源程序.源程
序是用匯編語(yǔ)言的語(yǔ)句編寫的,在計(jì)算機(jī)內(nèi)部,源程序的各條語(yǔ)句是以ascii碼
表示的,存在磁盤上,又稱為源文件。它區(qū)別與機(jī)器指令之處是不能被計(jì)算機(jī)執(zhí)行,
但它可以用來(lái)顯示和打印,作為檢查和保存的檔案.
匯編語(yǔ)言源程序經(jīng)過(guò)匯編程序的語(yǔ)法檢查和翻譯,形成二進(jìn)制代碼表示的目的碼
文件.如果源程序中有語(yǔ)法錯(cuò)誤,匯編程序會(huì)指出錯(cuò)誤的類型和出錯(cuò)所在的語(yǔ)句,
以便用戶重新進(jìn)行編輯修改,再形成新的源程序.源文件和有其生成的目的碼文
件可以是一個(gè)或者是兒個(gè).
目的碼文件并不能直接上機(jī)運(yùn)行,必須經(jīng)過(guò)連接程序把它和庫(kù)文件連接在一起,
形成可執(zhí)行文件.這個(gè)可執(zhí)行文件有操作系統(tǒng)裝入計(jì)算機(jī)內(nèi)存,才能運(yùn)行.
本章介紹匯編語(yǔ)言的語(yǔ)法規(guī)則,它是匯編語(yǔ)言的“法律”,編程時(shí)必須遵循,同時(shí)
也介紹匯編語(yǔ)言程序設(shè)計(jì)方法,以共參考.
3.1宏匯編基本語(yǔ)法
ibmpc微機(jī)中,有兩個(gè)匯編程序,一個(gè)是小匯編程序asm,另一個(gè)是宏匯編程序
masm,宏匯編程序功能比較強(qiáng),并且支持宏匯編和有關(guān)的函數(shù)及偽指令,自然它需
要的存儲(chǔ)容量,比小匯編程序所需要的要稍微大一些.
3.1.1匯編語(yǔ)言程序舉例
我們通過(guò)一個(gè)例子介紹匯編語(yǔ)言的格式.這個(gè)例子的功能是把block中的正數(shù),
負(fù)數(shù)分別送到兩個(gè)緩沖區(qū)中去.程序如下:
datasegment;定義數(shù)據(jù)段
blockdb43h,Oabh;定義block變量及其數(shù)據(jù)初值
pdatadb20dup(?);定義存放正數(shù)的緩沖區(qū)
npatadb20dup(?);定義存放負(fù)數(shù)的緩沖區(qū)
dataends;數(shù)據(jù)段定義結(jié)束
codesegment;定義碼段
assumecs:code,ds:data;確定cs,ds和對(duì)應(yīng)段的關(guān)系
explprofar;定義過(guò)程
start:pushds;保存原ds
movax,0
pushas;ax;保存在堆棧
movax,data
movds,ax;數(shù)據(jù)段段址送ds,es
moves,ax
leasi,block;分別置偏移地址
leadi,pdata
leabx,ndata
cld
movex,pdata-block;數(shù)據(jù)個(gè)數(shù)送ex
goon:lodsb;數(shù)據(jù)送al
testal,80h
jnzminus;判是負(fù)數(shù),則轉(zhuǎn)minus
stosb;判是正數(shù),送去存入緩沖器
jmpagain
minus:xchgbx,di;交換,使di中為負(fù)數(shù)緩沖器便址
stosb;存負(fù)數(shù)
xchgbx,di;恢復(fù)原便址寄存器
again:loopgoon;循環(huán)次數(shù)未完,則轉(zhuǎn)goon
ret;返回dos
explendp;過(guò)程定義結(jié)束
codeends;碼段定義結(jié)束
endstart;匯編結(jié)束,斷定入口地址
從這個(gè)例子,不難發(fā)現(xiàn)匯編語(yǔ)言程序通常由數(shù)據(jù)段,碼段組成.數(shù)據(jù)段存放數(shù)據(jù),
碼段存放程序指令,實(shí)現(xiàn)相應(yīng)的功能.程序結(jié)束處,必須是規(guī)定程序執(zhí)行的起始地
址,也稱為入口地址.本程序開(kāi)始執(zhí)行的地址是start.
程序語(yǔ)句行由四個(gè)部分組成,即標(biāo)號(hào)(或名字),操作碼,操作數(shù)和注釋.語(yǔ)句左邊
第?列起為標(biāo)號(hào)區(qū),句末分號(hào)后的為注釋區(qū),中間的部分為操作數(shù)區(qū).按照這種格
式書寫并輸入計(jì)算機(jī),既是程序的要求,也使人閱讀時(shí)清清楚楚,賞心悅目.
3.1.2匯編語(yǔ)言程序結(jié)構(gòu)
匯編語(yǔ)言源程序通常由一個(gè)或兒個(gè)程序模塊組成,每個(gè)模塊包括數(shù)據(jù)段,堆棧段
和若干個(gè)代碼段.有時(shí)程序中可以不設(shè)堆棧段,而利用系統(tǒng)中已設(shè)定的堆棧段.代
碼段中有若干個(gè)過(guò)程,過(guò)程又稱子程序。過(guò)程中的語(yǔ)句分為兩類,兩類是指示性
語(yǔ)句,另一類是指示性語(yǔ)句.指示性語(yǔ)句是計(jì)算機(jī)能執(zhí)行的指令,而指示性語(yǔ)句,
計(jì)算機(jī)并不能執(zhí)行。匯編時(shí),依據(jù)指示性語(yǔ)句的規(guī)定,匯編程序?qū)υ闯绦蜻M(jìn)行相
應(yīng)的處理操作,進(jìn)行諸如定義數(shù)據(jù)、分配存儲(chǔ)區(qū)、指示程序開(kāi)始和結(jié)束等服務(wù)性
工作,以減輕編程員的負(fù)擔(dān)。指示性語(yǔ)句又成偽指令。
這里,用等式表示程序和過(guò)程的結(jié)果內(nèi)容:
程序={塊[數(shù)據(jù)段,堆棧段,代碼段(過(guò)程1,過(guò)程2,……)],快……}
過(guò)程={指示性語(yǔ)句,指令性語(yǔ)句}
指示性語(yǔ)句的格式如下:
[名字][偽指令][操作數(shù)][;注釋]
例如:
SUMPROCFAR;定義一個(gè)過(guò)程
SUMENDP;過(guò)程定義結(jié)束
指令性語(yǔ)句的格式為:
[標(biāo)號(hào):][前綴][指令助記符][操作數(shù)][;注釋]
例如:
LP1:MOVBX,OFFSETDAREA;DAREA的地址送BX
語(yǔ)句中名字和符號(hào),又稱為符標(biāo)識(shí)符,是程序員自己確定的,它不允許與指令助
記符或偽指令同名,也不允許有數(shù)字打頭,字符個(gè)數(shù)不得超過(guò)31個(gè)。
3.1.3數(shù)據(jù)項(xiàng)與表達(dá)式
操作數(shù)是指令和偽指令中很重要的一部分內(nèi)容,它可以用寄存器、存儲(chǔ)器單元或
數(shù)據(jù)項(xiàng)來(lái)表示。其中,數(shù)據(jù)項(xiàng)是最靈活多變的,它有三種形式:常量、標(biāo)號(hào)、變
量。常量、變量和標(biāo)號(hào)以及他們的表達(dá)式都可以作為操作數(shù)使用。下面分別介紹。
1常量
常量包括數(shù)字常量和字符常量?jī)煞N。
(1)數(shù)字常量
二進(jìn)制常量——以字母為結(jié)尾的數(shù)為二進(jìn)制數(shù)。例如,10111010。
十進(jìn)制常量——以字母結(jié)尾或沒(méi)有字母結(jié)尾的數(shù)為十進(jìn)制數(shù)。例如8914,2376
十六進(jìn)制常量——以字母結(jié)尾的數(shù)為十六進(jìn)制數(shù)。例如1在匯編程序中,凡是以
字母開(kāi)始的十六進(jìn)制數(shù),必須在前面加上數(shù)字0,以避免和表示符相混淆。
(2)字符串常量
以單引號(hào)內(nèi)一個(gè)或多個(gè)ASCH字符構(gòu)成字符串常量。匯編程序把他們翻譯成對(duì)應(yīng)
的ASCH碼值,一個(gè)字符對(duì)應(yīng)一個(gè)字節(jié)。例如,字符串常量,AB,和'C,在匯
編時(shí)分別被翻譯成4142H和43Ho
2.標(biāo)號(hào)
標(biāo)號(hào)是存放某條指令的存儲(chǔ)單元的符號(hào)地址,通常他用作條件轉(zhuǎn)移,無(wú)條件轉(zhuǎn)移
指令或調(diào)用指令的目標(biāo)操作數(shù)。
標(biāo)號(hào)是由標(biāo)識(shí)符即標(biāo)號(hào)后面跟一個(gè)冒號(hào)來(lái)定義的。例如:
START:MOVAX,DATA
LP1:MOVCX,COUNT
這兩條語(yǔ)句分別定義了兩個(gè)標(biāo)號(hào)START和LP1,他們可以供轉(zhuǎn)移指令,循環(huán)指令
或調(diào)用指令當(dāng)作目標(biāo)操作數(shù)來(lái)使用。
標(biāo)號(hào)作為存儲(chǔ)單元的符號(hào)地址,他具有3種屬性:段值,偏移量和類型。標(biāo)號(hào)的
段值,偏移量屬性分別指它的段地址和偏移地址,而標(biāo)號(hào)的類型分NEAR和FAR
兩種。
NEAR類型的標(biāo)號(hào)是指標(biāo)號(hào)所在的語(yǔ)句和調(diào)用指令或轉(zhuǎn)移指令在同一個(gè)碼段中,
執(zhí)行調(diào)用指令或轉(zhuǎn)移指令時(shí),只需要把標(biāo)號(hào)的偏移地址送給IP,就可以實(shí)現(xiàn)調(diào)
用或轉(zhuǎn)移,并不需要改變碼段段址。
而FAR和NEAR類型不同,F(xiàn)AR類型標(biāo)號(hào)所在語(yǔ)句與其調(diào)用指令或轉(zhuǎn)移指令不
在用一碼段中,執(zhí)行調(diào)用指令或轉(zhuǎn)移指令時(shí),不僅需要改變偏址IP的值,而且
需要改變段值CS的值。這是段間的調(diào)用或轉(zhuǎn)移。
3.變量
變量是內(nèi)存中的數(shù)據(jù)區(qū),由若干個(gè)存儲(chǔ)單元構(gòu)成,內(nèi)存中的內(nèi)容是可以修改的,
因此,變量的值也是可以哦改變的。變量在程序中,作為存儲(chǔ)器操作數(shù)來(lái)使用。
變量具有3中屬性:
(1)段值(SEGMENT)——變量定義所在段的段地址。為了確保匯編程序能找
到該變量,應(yīng)在偽指令(ASSUME)中加以說(shuō)明,把其段值放在一個(gè)短寄存器中,
如CS,DS,ES或SS。
(2)偏移量(OFFSET)一—變量的地址和變量所在段的起始地址之間的偏移量。
(3)類型(TYPE)——變量的類型定義了該變量存儲(chǔ)區(qū)內(nèi)每個(gè)數(shù)據(jù)所占內(nèi)存單
元的字節(jié)數(shù),如字節(jié),字,雙字類型變量分別站用內(nèi)存1,2,4個(gè)字節(jié)單元。
變量定義的格式如下:
[變量名],[數(shù)據(jù)定義偽操作],[表達(dá)式]
變量名有字母打頭,最多允許31個(gè)字符,定義以后,凡是用到這個(gè)變量名時(shí),
必須注意其三個(gè)屬性。數(shù)據(jù)定義偽操作將該變量名定義成某種類型的變量(數(shù)據(jù)
定義偽操作在以后敘述)。而表達(dá)式則確定了變量的初值和這個(gè)變量數(shù)據(jù)區(qū)的大
小,它允許采用數(shù)值表達(dá)式或地址表達(dá)式。
變量使用時(shí),要注意以下幾點(diǎn):
(1)變量類型與指令要求的操作數(shù)類型相符。例如,MOVAL,VARI指令中,
要求VARI應(yīng)該是字節(jié)類型的,才與AL的類型匹配。而指令MOVBX,VAR2則要
求VAR2應(yīng)該定義成字類型的變量。
(2)變量的編址。變量定義以后,變量名僅僅對(duì)應(yīng)這個(gè)數(shù)據(jù)區(qū)的首地址。若這
個(gè)數(shù)據(jù)區(qū)中有若干個(gè)數(shù)據(jù)項(xiàng),在對(duì)其后面的數(shù)據(jù)項(xiàng)進(jìn)行操作時(shí),其地址需要改變。
例如,欲求變量XY數(shù)據(jù)區(qū)中20個(gè)字的和,在加下一個(gè)數(shù)據(jù)項(xiàng)時(shí),地址應(yīng)該進(jìn)行
修改,以指向那個(gè)數(shù)據(jù)項(xiàng)。具體程序段如下:
XYDW20DUP(?)
MOVAX,XY+38;送最后一個(gè)字給AX
MOVBX,38
LP1:SUBBX,2;偏址修改
ADDAX,XY[BX];求和
CUPBX,0;判是否是第一個(gè)數(shù)字
JNELP1;不是,則幾需求和
(3)變量的斷址。指令中的操作數(shù)的斷址往往不直接表示出來(lái),而是隱含的,
或者稱為默認(rèn)的或缺省的。變量使用時(shí),其段屬性應(yīng)與所在指令的缺省段寄存器
相符。如若不符,應(yīng)該把段地址直接表示出來(lái),這種表示方法,稱為跨段前綴。
跨段前綴可以用段寄存器或段名來(lái)表示。例如:
MOVAX,ES:[BX]
MOVAX,DATA:[DI]
4表達(dá)式
匯編程序允許使用表達(dá)式。然而,表達(dá)式并不是指令,它本身不能執(zhí)行。程序被
匯編時(shí),匯編程序?qū)Τ绦蛑械谋磉_(dá)式進(jìn)行相應(yīng)的運(yùn)算,其運(yùn)算結(jié)果是一個(gè)值。因
此,在程序被執(zhí)行時(shí),表達(dá)式本身已經(jīng)是一個(gè)有確定值的操作數(shù)。
變達(dá)式中的運(yùn)算有三類運(yùn)算符一一算術(shù)運(yùn)算符、邏輯運(yùn)算符和關(guān)系運(yùn)算符來(lái)表
/J、.O
(1)算術(shù)運(yùn)算符
有+,*,/,MOD五種算術(shù)運(yùn)算符,前面4種是最常見(jiàn)到的加、減、乘、除、
四則運(yùn)算符,而MOD是表示求兩個(gè)數(shù)相除以后的余數(shù)。例如,23M0D7其結(jié)果是
2,即23除以7,其余數(shù)是2。
算術(shù)運(yùn)算符用于數(shù)字表達(dá)式,其結(jié)果仍是數(shù)字。
算術(shù)運(yùn)算符也可以用于地址表達(dá)式,但其應(yīng)用范圍受到一定的限制,那就是地址
表達(dá)式的運(yùn)算必須有明確的物理意義,其運(yùn)算結(jié)果才有效,否則該地址表達(dá)式是
錯(cuò)誤的。
通常,地址表達(dá)式中使用加或者減運(yùn)算。地址加或者減一個(gè)數(shù)字量,表示對(duì)原地
址偏移該數(shù)字的若干個(gè)單元的地址。例如,VAR+2表示變量VAR的地址加上2
得到的和作為新的存儲(chǔ)單元的地址。同一段中兩個(gè)存儲(chǔ)單元地址之差,表示他們
之間的地址偏移量,或者有時(shí)表示這兩個(gè)存儲(chǔ)單元之間有多少個(gè)字節(jié)。而不同段
址的兩個(gè)偏移地址的加或者減是沒(méi)有物理意義的,兩個(gè)地址相乘或相除同樣也是
沒(méi)有物理意義的。例如,若要把字?jǐn)?shù)祖阿惹第九個(gè)字傳到AX寄存器,用指令可
以這樣表示:
MOVAX,VAR+(9T)*2
其中,VAR是該數(shù)組的首地址,(9T)*2是第9個(gè)字的地址與首地址的偏移量。
(2)邏輯運(yùn)算符
有AND,OR,NOT和XOR四種邏輯運(yùn)算符,邏輯運(yùn)算是按位操作的,邏輯運(yùn)算符
只能用于數(shù)字表達(dá)式,不能用于存儲(chǔ)器地址表達(dá)式。例如:
MOVAL,OADHANDOCCH
匯編時(shí),計(jì)算上式中右邊邏輯表達(dá)式,得到結(jié)果為8cH,這樣就轉(zhuǎn)化為指令
MOVAL,8CH
表達(dá)式VAROR80H是無(wú)效的,因?yàn)檫壿嬤\(yùn)算符不能用于地址表達(dá)式。
那么,指令OUTPORTANDFEH,AL是否有效呢?答案是肯定的,有效。因?yàn)镻ORT
是1個(gè)字節(jié)的數(shù)字,而不是一個(gè)變量,盡管它名義上是作為外設(shè)口的地址,實(shí)
際上匯編程序認(rèn)為它是一個(gè)數(shù)字,PORT是?個(gè)數(shù)字表達(dá)式,因此允許使用邏輯
運(yùn)算符。該指令在匯編時(shí),若PORT是偶數(shù),則表達(dá)式結(jié)果與原端口號(hào)相同,若
PORT是奇數(shù)時(shí),該指令的輸出端口為一偶數(shù),比PORT端口號(hào)小1。
這里需要提醒的是這些邏輯運(yùn)算符是用于數(shù)字表達(dá)式的運(yùn)算符,并不是邏輯運(yùn)算
指令的操作碼。前者是匯編程序在進(jìn)行匯編時(shí)處理的,而后者是在程序運(yùn)行時(shí)執(zhí)
行的。
(3)關(guān)系運(yùn)算符
有EQ,NE,LT,GT,LE,GE六種關(guān)系運(yùn)算符。這些關(guān)系運(yùn)算符分別表示兩個(gè)操
作數(shù)是否相等,不等,小于,大于,小于等于和大于等于。關(guān)系運(yùn)算的兩個(gè)操作
數(shù)必須都是數(shù)字或者都是同一段內(nèi)的存儲(chǔ)器地址。關(guān)系運(yùn)算的結(jié)果是一個(gè)邏輯
值,結(jié)果為真,邏輯值是OFFFFH;結(jié)果為假,值為0。例如:
MOVAX,VARIGTVAR2
如果VARI地址大于VAR2,則匯編結(jié)果應(yīng)該是:
MOVAX,OFFFFH
否則,匯編結(jié)果就成為:
MOVAX,0000H
數(shù)字表達(dá)式比較容易理解,而地址表達(dá)式比較復(fù)雜。
地址表達(dá)式由變量,標(biāo)號(hào),常量,基址,變址寄存器以及相關(guān)的運(yùn)算符組成,它
表示了存儲(chǔ)器的地址。地址表達(dá)式有三種屬性,即段值,偏移量,類型。地址表
達(dá)式的段值,偏移量即是其段地址和偏移地址。而類型則有字節(jié),字和雙字類型,
以及近(NEAR)和遠(yuǎn)(FAR)類型兩種,前者和數(shù)據(jù)的存儲(chǔ)單元相對(duì)應(yīng),后者與
程序轉(zhuǎn)移或調(diào)用的目標(biāo)地址相對(duì)應(yīng)。
和地址表達(dá)式有關(guān)的運(yùn)算符,除了前面所提及的,還有下面兩種操作符。
(1)類型操作符一一PTR程序中對(duì)變量或標(biāo)號(hào)定義后,變量或標(biāo)號(hào)的屬性便確
定了。也就是有它的段址,偏址和類型。但在實(shí)際使用時(shí),可能會(huì)出現(xiàn)與原先定
義的類型不匹配的情況,需要臨時(shí)加以調(diào)整。PTR操作符給地址表達(dá)式臨時(shí)賦予
一個(gè)新的類型,而地址表達(dá)式的斷值,偏移量屬性不便。其操作的格式如下:
類型地址表達(dá)式
其中的類型可以是或
例如,給已定義為字:
varidw?
那么,只能在字操作令中使用vari這個(gè)變量,如movax,varl時(shí)合法的。但是,
要把varl當(dāng)作字操作數(shù)來(lái)使用,便是非法的,指令
movvari,al
會(huì)出現(xiàn)類型不配的錯(cuò)誤,而指令
movbyteptrvarl,al
則合法的。操作符ptr產(chǎn)生了一個(gè)新的地址操作數(shù),該操作數(shù)的段地址和偏移地
址與varl相同,而類型為字節(jié)型,不是原先定義的字類型。
若標(biāo)號(hào)next原來(lái)定義是near類型,現(xiàn)在另一個(gè)段中的程序要轉(zhuǎn)移到此next處,
那么采用指令
jmpfarptrnext
來(lái)實(shí)現(xiàn)段間的轉(zhuǎn)移。
(2)樹(shù)枝返回操作符——segoffset有時(shí),并不希望對(duì)變量的內(nèi)容進(jìn)行處理,
而需要這個(gè)變量的地址以便量進(jìn)行操作;有時(shí),并不希望轉(zhuǎn)移到某個(gè)標(biāo)號(hào)定義
的目標(biāo)地址去,而是需要對(duì)這個(gè)標(biāo)號(hào)的地址進(jìn)行處理。在這兩種情況下,需要利
用seg和offset這兩個(gè)數(shù)值返回操作符,他的操作格式如下:
seg變量或標(biāo)號(hào)
offseg變量或標(biāo)號(hào)
seg操作符返回變量或者標(biāo)號(hào)的段址。而offseg操作符返回變量或者標(biāo)號(hào)的偏
移量。
例如:
movaxmsegvarname
movbx,offsegvarname
分別得到varname段址和對(duì)短起始地址的偏移量,傳送給ax和bx寄存器。
32指示性語(yǔ)句
指示性語(yǔ)句.偽操作語(yǔ)句。偽操作不是計(jì)算機(jī)指令系統(tǒng)的一部分,而是匯編程序
提供源程序的服務(wù)工具,用以完成會(huì)變得輔助性工作,諸如變量定義,符號(hào)賦值,
程序守為標(biāo)志等。Ibm宏匯編提供以下兒類操作語(yǔ)句:變量定義語(yǔ)句:符號(hào)賦值
語(yǔ)句;斷定義語(yǔ)句;過(guò)程定義語(yǔ)句;??於x語(yǔ)句。
下面對(duì)這兒類為操作的常用部分加以敘述。書中沒(méi)有涉及的偽操作,讀者需要是
可以查閱手冊(cè)。
3.2.1變量定語(yǔ)句
變量定義語(yǔ)句為變量分配若干個(gè)初值。這一類操作的格式為:
[變量名]助記符操桌數(shù)。?!僮罃?shù)[;注釋]
其中變量子段名用符號(hào)地址表示,分配的春儲(chǔ)單元的第一個(gè)字節(jié)的偏移地址是這
個(gè)變量名的值。這個(gè)變量名字段也可以沒(méi)有,表示只分配若干個(gè)存儲(chǔ)單元。
注釋子段用來(lái)對(duì)該偽朝作做一些說(shuō)明,如它的功能等。
超作數(shù)子段可以有若個(gè)個(gè)操捉數(shù),偽操作把這些數(shù)據(jù)存入指定的存儲(chǔ)單元。這里
操作數(shù)可以是指定的數(shù)值表達(dá)式、ASC字符穿、地址表達(dá)式。助記符字段是定義
變量的偽操作,常用的有DB,DW,DD等兒種。
DB偽操作用來(lái)定義字節(jié)形變量,其中的每個(gè)操作數(shù)都占有一個(gè)字節(jié)存儲(chǔ)單元,
每個(gè)操作數(shù)的值不操過(guò)255。
DW偽操作用來(lái)定義字形變量,其中的每個(gè)操作數(shù)都占有兩個(gè)字節(jié),字的低位字
節(jié)在第一個(gè)字節(jié)地址單元中,字的低位字節(jié)在第二個(gè)字節(jié)地址單元中,簡(jiǎn)單的說(shuō),
就是低位在前、高位在后、或低位低地址、高位高地址。
DD偽操作用來(lái)定義雙字型變量,其中的每個(gè)操作數(shù)都占有兩個(gè)字,雙字的最低
位字節(jié)在第一個(gè)字節(jié)地址單元中,次低位字節(jié)在第二個(gè)字節(jié)地址單元中,次高位
字節(jié)在第三個(gè)字節(jié)地址單元中,高位字節(jié)在第四個(gè)字節(jié)地址單元中。
例操作數(shù)是常數(shù)或者表達(dá)式。
BYTE_VARDB12,4,12H
WORD_VARDW100H,-2,10*6
DW_VARDDOFEFDH
匯編程序在匯編時(shí),根據(jù)表達(dá)式可以求得一個(gè)常數(shù),把數(shù)據(jù)結(jié)果存入存儲(chǔ)器,如圖
3-1.
例操作數(shù)可以是字符串,如:
STRINGDB'OK!'
CHARDB'AB'
WARDDW'AB'
匯編后,存儲(chǔ)器的存儲(chǔ)情況如圖3-2所示.
例操作數(shù)字段用符號(hào)?來(lái)表示,即保留存儲(chǔ)空間,不存入起始數(shù)值.操作數(shù)字段
也可以用復(fù)制操作符DUP復(fù)制某些數(shù)據(jù),如:
ARRAY1DB4DUP(?)
ARRAY2DB10DUP(0,1)
DUP前面的數(shù)據(jù)指定括號(hào)中的操作數(shù)的重復(fù)次數(shù),它可以是一個(gè)表達(dá)式.匯編后,
存儲(chǔ)器的存儲(chǔ)情況如圖3-3.
3.2.2符號(hào)賦值語(yǔ)句
程序中,有時(shí)多次出現(xiàn)同一個(gè)表達(dá)式,為了方便起見(jiàn),用賦值偽操作給表達(dá)式賦予
一個(gè)符號(hào)名,以后,凡用到該表達(dá)式的地方都可以用這個(gè)符號(hào)名來(lái)表示,這樣,意
義清楚,修改容易.格式如下:
符號(hào)名EQU表達(dá)式
其中表達(dá)式可以是任何有效的操作數(shù),可以是任何結(jié)果為常數(shù)的表達(dá)式,也可以
是助組記符.例如:
COUNTEQU256
BEQU[BP+8]
P8EQUDS:[BP+8]
LPNEQULP1+12H;給^^賦地址表達(dá)式
SSBEQUSTOSB
EQU語(yǔ)句的表達(dá)式中,如果有變量或符號(hào)出現(xiàn),則在該語(yǔ)句前后必須給出它們的
定義,表達(dá)式才有效,否則匯編程序?qū)⑻崾境鲥e(cuò).例中的第四個(gè)語(yǔ)句的LP1應(yīng)該在
次句前加以定義.
符號(hào)用EQU語(yǔ)句賦值后,不能重新賦值.除非用PURGE語(yǔ)句解除這些賦值關(guān)系,符
號(hào)才能賦新的值.PURGE語(yǔ)句的格式為:
PURGE符號(hào)1,符號(hào)2,…,符號(hào)n,
而另一個(gè)與EQU語(yǔ)句功能類似的語(yǔ)句,即=偽操作.=偽操作允許給符號(hào)賦一個(gè)常
量,或者結(jié)果是常數(shù)的表達(dá)式,并且允許對(duì)符號(hào)重新賦值.例如:
EMP=16
EMP=17
EMP=EMP+1
3.2.3段定義語(yǔ)句
前面我們已經(jīng)講過(guò),8086和8088的存儲(chǔ)器的物理地址由段地址和偏移地址組合
而成.程序運(yùn)行時(shí),程序的指令和變量都存在某個(gè)段內(nèi).因此,匯編程序按段來(lái)組
織程序和數(shù)據(jù),變量.與段有關(guān)的主要偽操作有SEGMENT;ENDS;ASSUME;ORG.
段定義的格式如下:
segnameSEGMENT
segnameENDS
每個(gè)段必須有一個(gè)名字,每個(gè)段定義由SEGMENT開(kāi)始,到ENDS結(jié)束,兩者少一不可,
并且其語(yǔ)句中的名字必須相同,否則,匯編程序無(wú)法辨認(rèn).省下的部分,數(shù)據(jù)段,附
加段和堆棧段來(lái)說(shuō),一般是變量,符號(hào)定義等偽操作,而對(duì)于代碼段則是指令及有
關(guān)偽操作.定義段之后,還需要用ASSUME偽操作語(yǔ)句,以確定段和段寄存器的關(guān)
系.其格式為:
ASSUMEseg-reg;segname[,,,,]
其中段寄存器名必須是CS,DS,ES,SS中的一個(gè),而段名是由SEGMENT和ENDS定
義的段中的段名.欲取消前面的ASSUME語(yǔ)句確定的段與段寄存器的關(guān)系,可采
用ASSUMENOTHING語(yǔ)句.例如:
datalSEGMENT
XIDB?
X2DW?
X3DD?
datalENDS
extralSEGMENT
ylDB?
y2DW?
y3DD?
extralENDS
stacklSEGMENT
DW100HDUP(?)
TopEQUTHISWORD;THIS是個(gè)運(yùn)算符,它建立一個(gè)新的存儲(chǔ)器地址操作數(shù),
stacklENDS;其地址為匯編時(shí)的當(dāng)時(shí)值,類型由THIS后的項(xiàng)指定.
CODESEGMENT
ASSUMECS:CODE,DS:datal,ES:extral,SS:stackl
BEGIN:MOVAX,datal
MOVDS,AX
MOVAX,extral
MOVES,AX
MOVAX,syackl
MOVSS,AX
CODEENDS
ENDBEGIN
ASSUME語(yǔ)句確定了短與段寄存器的對(duì)應(yīng)關(guān)系,供匯編時(shí)使用,而段地址裝入段寄
存器,即段寄存器的賦值,還需要代碼中的MOV指令來(lái)完成.不過(guò),碼段寄存器例
外,它是在程序初始化時(shí),由系統(tǒng)程序完成的,不需要也不允許用戶給CS賦值.用
戶程序模塊可以存放在一個(gè)或幾個(gè)碼段中,根據(jù)需要定.
SEGMENT偽操作還可以增加一些說(shuō)明,格式如下:
SegnameSEGMENT[align-type][combine-type][,class']
這三種類型說(shuō)明分別敘述如下:
(1)定位類型(align-type)
PARA該段的起始地址從段的邊界開(kāi)始,也就是段地址的最低位必定為0(十六進(jìn)
制數(shù)表示).通常隱含.
BYTE該段可以從任何有效地址開(kāi)始.
WORD該段的起始地址必須是偶數(shù),即從字的邊界開(kāi)始.
PAGE該段的起始地址從頁(yè)邊界開(kāi)始,即段地址最低兩個(gè)十六進(jìn)制數(shù)位為0(一頁(yè)
為256字節(jié)).
(2)組合類型(combine-type)
PUBLIC規(guī)定連接時(shí)該段要和其他具有相同的段名的段連接在一起,形成一個(gè)段,
連接的次序在調(diào)用LINK程序時(shí)由用戶指定.
COMMON規(guī)定連接時(shí)該段和其他同名段具有相同的起始地址.因而產(chǎn)生覆
蓋.COMMON的連接長(zhǎng)度是同名段中的最大長(zhǎng)度.
ATexpression規(guī)定表達(dá)式計(jì)算結(jié)果的16位二進(jìn)制值為段的起始地址.但不能用
于指定代碼段,而用于固定地址的數(shù)據(jù)段,如ROM中的數(shù)據(jù)區(qū),或存儲(chǔ)區(qū)中的向量
表.
STACK規(guī)定該段在運(yùn)行時(shí)是堆棧段的一部分.
MEMORY規(guī)定該段定在所有其他連接段的后面.
(3)類別('class')
它是一個(gè)名字,用于連接時(shí)組成同名段組.
偽操作指令ORG語(yǔ)句規(guī)定了程序段或數(shù)據(jù)塊在該段內(nèi)的起始地址,其格式為
ORGexpression
其中表達(dá)式expression的值即為段內(nèi)的起始地址或偏移地址,從此地址起連續(xù)
存放程序或數(shù)據(jù).
3.2.4過(guò)程定義語(yǔ)句
一個(gè)過(guò)程具有某一種功能,形成獨(dú)立的程序塊,它是匯編程序的基本單位.
過(guò)程定義的格式如下:
procedure-namePROC
RET
procedure-nameENDP
過(guò)程定義的偽操作PROC和ENDP必須成對(duì)出現(xiàn).在過(guò)程的首尾處,必須有過(guò)程名起
頭.過(guò)程結(jié)束處往往有RET語(yǔ)句,以返回調(diào)用它的程序處.有時(shí)RET語(yǔ)句也可以出
現(xiàn)在過(guò)程中間.過(guò)程至少有一個(gè)入口和出口,以供進(jìn)入和脫離該程序.
按上面定義,只能在該程序的同一碼段中被調(diào)用.過(guò)程應(yīng)賦予FAR的屬性,格式如
下:
procedure-namePROCFAR
procedure-nameENDP
調(diào)用過(guò)程和從過(guò)程返回有兩種情況:段內(nèi)的和短間的.
段內(nèi)的調(diào)用和返回指令執(zhí)行時(shí),推入堆棧和退出堆棧的僅僅是應(yīng)該返回處的段內(nèi)
的地址偏移量.
段間的調(diào)用和返回指令執(zhí)行時(shí),推入堆棧和退出堆棧的僅僅是應(yīng)該返回處的段地
址和段內(nèi)偏移量.
在定義時(shí),可以用NEAR屬性顯式地表示:
procedure-namePROCNEAR
procedure-nameENDP
3.2.5程序模塊定義
每一個(gè)程序模塊的開(kāi)始,往往要用NAME或TITLE為其取一個(gè)名字,模塊結(jié)束,則需
要用END偽操作來(lái)告知匯編程序,在遇到END語(yǔ)句時(shí)結(jié)束匯編.
NAME的格式為:
NAMEmodule-name
匯編程序把NAME后面的module-name作為模塊的名字,這個(gè)名字不允許使用保留
字,可以使用標(biāo)識(shí)符.
TIYLE的偽操作,格式是:
TITLEtext
它為清單的每一頁(yè)指定打印的標(biāo)題.text
中最多允許60個(gè)字符.若無(wú)NAME偽操作,則把text
中的前6個(gè)字符作為模塊名.若既無(wú)NAME又無(wú)TITLE偽操作,則就吧源文件名作
為模塊名.
知NAME和TITLE偽操作并不是必須的.
但每個(gè)模塊的結(jié)束,必須要有END偽操作,格式為:
END[label]
其中,可選的標(biāo)號(hào)指示程序開(kāi)始執(zhí)行的起始地址。如果若干個(gè)個(gè)程序??煜嗦?lián)接,
那么只有住程序模快需要使用帶入標(biāo)號(hào)的語(yǔ)句,而其他程序模塊是被調(diào)用的,
不能使用帶入標(biāo)號(hào)的語(yǔ)句,只需要。
下面是一個(gè)兩個(gè)數(shù)差的絕對(duì)值的程序。
Titledifference
Datasegment
Dumldw250h
Dum2dwla9h
Resultdw?
Dataends
Codesegment
Assumecs:code,ds:data
Mainprocfar
Start:movax,data
Movds,ax
Movax,numl
Subax,num2
Jnbstore
Negax
Store:movresult,ax
Movah,4ch
Int21h
Mainendp
Codeends
Ends
Endstart
這個(gè)有一個(gè)程序模快組成,他從為操作開(kāi)始,為操作結(jié)束。語(yǔ)句制定了該程
序的入口地址,此入口地址在程序在該程序中正好是第一條執(zhí)行指令的地址,這
個(gè)程序丁宜樂(lè)了一個(gè)數(shù)據(jù)段和一個(gè)媽段,碼段中紙包裹一個(gè)過(guò)程,過(guò)程結(jié)束時(shí),
通過(guò)調(diào)用的的功能,返回,程序結(jié)束運(yùn)行。
3.3匯編語(yǔ)言程序設(shè)計(jì)程序
第二章介紹了指令系統(tǒng),結(jié)合指令也給出了一些程序段例子,本章的第一二節(jié)由
介紹了紅會(huì)變得基本語(yǔ)法和偽指令。有了這些基礎(chǔ)知識(shí),就不難進(jìn)行匯編語(yǔ)言的
程序設(shè)計(jì)。
從下一節(jié)起,介紹匯編語(yǔ)言程序設(shè)計(jì)的主要方法。這里次先介紹與匯編語(yǔ)言程序
有關(guān)的問(wèn)題,以便在程序設(shè)計(jì)之前,引起大家的注意,少哦組一些彎路。
3.3.1程序的質(zhì)量標(biāo)準(zhǔn)
再編程序時(shí),首先要有一個(gè)質(zhì)量觀念,要編制質(zhì)量高的程序,而不僅僅是完成任
務(wù)。在進(jìn)行學(xué)習(xí)時(shí),要逐步養(yǎng)成良好的編程習(xí)慣。如同寫文章,撰寫的作品千只
百態(tài)一樣,用計(jì)算機(jī)敘述某個(gè)問(wèn)題,也即編程,同樣千差萬(wàn)別。衡量程序的質(zhì)量,
通稱有四個(gè)標(biāo)準(zhǔn):
(1)程序正確完整;
(2)程序易讀性;
(3)程序的執(zhí)行時(shí)間;
(4)程序所占內(nèi)存大小及程序行數(shù)。
其中,第一條是主要的,最基本的。往往有些程序基本功能是正確的,但隱藏著
一些問(wèn)題,或者在某些情況下執(zhí)行是正確的,而在另外的情況下程序運(yùn)行的結(jié)果
是不對(duì)的。程序的一讀性對(duì)軟件的維護(hù)和軟件設(shè)計(jì)的合作是大有裨益的,因此已
開(kāi)始就養(yǎng)成良好的編程習(xí)慣,編程思路要清楚,畫一個(gè)流程圖,在程序前部隊(duì)變
量和算法加以說(shuō)明,在程序中對(duì)有關(guān)語(yǔ)句加上注釋。程序的執(zhí)行時(shí)間對(duì)于實(shí)時(shí)處
理的問(wèn)題環(huán)重要的。程序所占內(nèi)存大小對(duì)于復(fù)雜的大程序來(lái)說(shuō),也不能等閑視之,
而考慮到軟件的開(kāi)發(fā)成本,程序的語(yǔ)句則是一個(gè)很重要的因素。
3.3.2
(1)把實(shí)際問(wèn)題抽象,提煉成數(shù)學(xué)模型。
(2)確定解決該數(shù)學(xué)模型的算法.
(3)程序模塊分析。在分析復(fù)雜的實(shí)際問(wèn)題時(shí),往往需要把它分成若干功能塊,畫
出層次圖,確定各塊間的通信。對(duì)于簡(jiǎn)單的問(wèn)題,僅僅一個(gè)模塊足以完成其任務(wù),
就無(wú)須模塊分析.
⑷畫出模塊程序圖.
⑸分配內(nèi)存工作單元和寄存器.
(6)根據(jù)流程圖編制程序.
(7)上機(jī)調(diào)試,進(jìn)行修改,最后檢測(cè)通過(guò).
編制過(guò)程的第一步,數(shù)學(xué)抽象,是很重要的一環(huán),它關(guān)系到全局,不可輕視.實(shí)際
工作中,因?yàn)槌橄蟛粶?zhǔn)確,以致返工的是屢見(jiàn)不鮮.確定算法亦是關(guān)鍵的一步,它
與程序質(zhì)量的高低密不可分,它決定了程序的復(fù)雜程度和執(zhí)行時(shí)間的長(zhǎng)短.其后
的模塊分析,編制流程圖和程序,也往往要通過(guò)調(diào)試進(jìn)行相應(yīng)的修正.
3.3.3程序流程圖
程序流程圖是一種算法表達(dá)工具,它根據(jù)算法,將結(jié)局問(wèn)題的思路和方法用字符
和圖形表示出來(lái),確定程序的結(jié)構(gòu)和程序的流向.
對(duì)于處學(xué)者,程序流程圖是比不可少的工具.對(duì)于熟練的編程者,在編制復(fù)雜的程
序時(shí),仍然少不了流程圖的支持。它便于編制程序,便于調(diào)試程序,有利于減少程
序的錯(cuò)誤,提高程序效率.
本書的流程圖,采用國(guó)際標(biāo)準(zhǔn),它與我國(guó)國(guó)標(biāo)也是基本一致的。所用主要的符號(hào)
如下:
(1)矩形框表示各種處理的功能,框中用簡(jiǎn)明的語(yǔ)言表明所完成的處理功能.例
如執(zhí)行一個(gè)加法操作.這種處理有一個(gè)入口和一個(gè)出口,有箭頭表示.
(2)菱形框表示判斷,框內(nèi)表明判斷的條件.它有一個(gè)入口,但可以有若干個(gè)出
口,分別用箭頭表示。在各個(gè)出口處表明該出口的條件,例如條件滿足用y表示,
條件不滿足時(shí)用n表示.
(3)特定的方框表示特定處理,通常表示子程序,模塊??騼?nèi)表明程序名或模塊名,
框縱邊為雙數(shù),形如
(4)端點(diǎn)框六邊形表示程序流程的起點(diǎn),扁圓形框表示程序的終點(diǎn).
(5)流線帶箭頭的直線,表示程序的流向,它連接程序的各個(gè)流程圖,新的圖表
正向流線不帶箭頭,反向流線帶箭頭.
3.4數(shù)據(jù)輸入和輸出
程序通常要對(duì)數(shù)據(jù)進(jìn)行處理,而后輸出結(jié)果.那么所需要的數(shù)據(jù)來(lái)自何處?他們可
能;來(lái)自:1程序的數(shù)據(jù)段,編程時(shí)預(yù)先設(shè)定;2磁盤,數(shù)據(jù)以數(shù)據(jù)文件的形式存在
盤上;3外設(shè),例如A/D轉(zhuǎn)換,把模擬信號(hào)轉(zhuǎn)成數(shù)字信號(hào),送入計(jì)算機(jī)內(nèi)存;4鍵盤
輸入,這里,我們只討論鍵盤輸入的情況,其他的可以參考有關(guān)資料.
-一般高級(jí)語(yǔ)言的數(shù)據(jù)輸入輸出多有相應(yīng)的語(yǔ)句或函數(shù)倆處理,而匯編語(yǔ)言無(wú)法用
一條指令解決問(wèn)題,他通過(guò)調(diào)用系統(tǒng)功能來(lái)完成這個(gè)任務(wù).調(diào)用系統(tǒng)功能猶如高
級(jí)語(yǔ)言中調(diào)用子程序,它需要先提供實(shí)際參數(shù)(又稱入口參數(shù))以及所調(diào)用的功
能號(hào).調(diào)用結(jié)果返回結(jié)果,即可得到出口參數(shù).
3.4.1輸入字符串
從鍵盤上輸入字符串,可以得到一串字符的ASCII.如果是數(shù)字符,通過(guò)變換和組
合,就可以得到數(shù)據(jù).
輸入字符串,通過(guò)調(diào)用dos功能的Oah號(hào)功能來(lái)實(shí)現(xiàn).它需要一個(gè)字符緩沖區(qū),
以便存儲(chǔ)讀入的字符串。緩沖區(qū)的第一個(gè)字節(jié)保存字符去長(zhǎng)度,它由用戶定義時(shí)
給出,不允許超過(guò)此限定數(shù).如果輸入的超過(guò)次數(shù),系統(tǒng)會(huì)拒絕接受,發(fā)出“嘟
嘟”聲,光標(biāo)也不再向右移動(dòng).
緩沖區(qū)的第二個(gè)字節(jié)是實(shí)際鍵入字符的個(gè)數(shù),鍵入完成后,系統(tǒng)程序會(huì)在那個(gè)單
元自動(dòng)填入鍵入字符的個(gè)數(shù),它不是由用戶確定的,它也不包括最后結(jié)束字符串
輸入的回車字符,雖然此回車符還占用字符區(qū)的一個(gè)字節(jié).
緩沖區(qū)的的三個(gè)字節(jié)起,便是存放字符串的字符區(qū),它按字存放.例如.在數(shù)據(jù)區(qū)
定義了一個(gè)緩沖區(qū)BUFFER,字符區(qū)長(zhǎng)度為20,可表示如下:
BUFFERDB20
REALENDB?
STRUNGDB20DUP(?)
調(diào)用A號(hào)功能的程序段如下:
LEADX,BUFFER;緩沖區(qū)首地址一WX
MOVAH,OAH;調(diào)用功能--aAH
INT21H;調(diào)用DOS的OAH功能
假如程序執(zhí)行時(shí),鍵入字符
Thisisastring
那么,緩沖區(qū)BUFFER中各存儲(chǔ)單元的內(nèi)容如下所示:
其中第一個(gè)單元的14H是字符區(qū)長(zhǎng)度,第二個(gè)單元的10H是實(shí)際鍵入字符的個(gè)數(shù),
字符區(qū)中是鍵入字符的ASCII串。ODH為回車符。
例從鍵盤上輸入一個(gè)字符串,并在串尾處加上字符串結(jié)束標(biāo)志。
;inputastringfromthekeyboard,
;thenwrite'$'attheendofthestring,asamark
?
DATASEGMENT
STRINGDB30,0,30DUP(?)
DATAENDS
CODESEGMENT
ASSUMECS:CODE,DS:DATA
KEYINPROCFAR
BEGINMOVAX,DATA
MOVDS,AX
MOVDS,AX
MOVDX,OFFSETSTRING
MOVAH,OAH
INT21H
MOVCL,STRING+1
XORCH,CH
ADDDX,2
ADDDX,CX
MOVBX,DX
MOVBYTEPTR[BX]
MOVAH,4CH
INT21H
KEYINENDP
CODEENDS
ENDBEGIN
3.4.2輸出字符串
內(nèi)存中的字符傳送到顯示器顯示,可以通過(guò)調(diào)用DOS功能的9號(hào)功能來(lái)實(shí)現(xiàn)。該
功能要求被現(xiàn)實(shí)的字符串必須是以ASCH碼。例如:
MESSAGEDB'THATISALL,GOODBYE!',13,10,f$'
但是其他的控制碼,不能出現(xiàn)在字符串中。顯示字符串的程序段為:
MOVAH,9
MOVDX,SEGMESSAGE
MOVDS,DX
LEADX,MESSAGE
INT21H
若要顯示數(shù)據(jù),必須先把他們轉(zhuǎn)換成ASCH碼,然后才能調(diào)用DOS的9號(hào)功能,
顯示他們。
3.5順序程序設(shè)計(jì)
順序城市最常見(jiàn)的,也是最基本的程序設(shè)計(jì)方法。這種程序在計(jì)算機(jī)內(nèi)村種執(zhí)行
時(shí),按照先后次序,逐句順序執(zhí)行。他沒(méi)有分支也沒(méi)有循環(huán),因此也成為線性程
序。下面是一個(gè)例子。
例兩個(gè)64位無(wú)符號(hào)數(shù)相加的程序。
在8086/8088CPU中,數(shù)據(jù)是16位的,他有8位和16位運(yùn)算指令,但是沒(méi)有32
位,64位這種16位以上的運(yùn)算指令。要進(jìn)行64位相加運(yùn)算可以利用16位加法
指令分別相加4次來(lái)實(shí)現(xiàn)。具體程序如下:
DATASEMENT
NUM1DW1357H,2468H,90BDH,0ACEH
NUM2DW9753H,8264H,0B09DH,OFAEH
SUBNDW5DUP(?)
DATAENDS
CODESEGMENT
ASSUMECS:CODE,DS:DATA
ADD64PROCFAR
BEGIN:MOVAX,DATA
MOVDS,AX
LEABX,NUM1
MOVAX,[BX]
ADDAX,[BX+8]
MOV[BX+1OH],AX
INCBX
INCBX
MOVAX,[BX]
ADCAX,[BX+8]
MOV[BX+1OH],AX
INCBX
INCBX
MOVAX,[BX]
ADCAX,[BX+8]
MOV[BX+1OH],AX
INCBX
INCBX
MOVAX,[BX]
ADCAX,[BX+8]
MOV[BX+1OH],AX
MOVAX,0
ADCAX,0
MOVW[BX+12H],AX
MOVAH,4CH
INT21H;
ADD64ENDP
CODEENDS
ENDBEGIN
3.6分支程序設(shè)計(jì)
在程序中,除了最基本的順序結(jié)構(gòu)以外,通常還有各種分支,以滿足不同情況作
不同處理的需要。分支結(jié)構(gòu)有兩種形式,一種是引出兩個(gè)分支的,另一種是引出
多個(gè)分支的。前者類似于高級(jí)語(yǔ)言中的IF——THEN--ELSE語(yǔ)句,后者類似于
高級(jí)語(yǔ)言中的CASE語(yǔ)句,分若嘎呢請(qǐng)昂,進(jìn)行不同的處理。程序在某種條件下
運(yùn)行時(shí),執(zhí)行其中一個(gè)分支。分支結(jié)構(gòu)如圖3—4所示。上述兩種結(jié)構(gòu)分別舉例
如下:
例從鍵盤上輸入兩個(gè)整數(shù),并求其和。
通過(guò)調(diào)用DOS功能,從鍵盤上輸入整數(shù)該數(shù)是以ASCII碼的形式存在內(nèi)存中的。
因此,需要把它轉(zhuǎn)化成二進(jìn)制數(shù),在進(jìn)行加法運(yùn)算。如果計(jì)算機(jī)以一個(gè)字來(lái)表示
一個(gè)整數(shù)的話,整數(shù)的范圍應(yīng)在-32768于32767之間程序流程如圖3-5和-6所
/J、.O
DATASEGMENT
STR1DB7,?7DUP(?)
STR2DB7,?7DUP(?)
NUMDW?,?
BUFFERDW0
OVERDB'OVERFLOW!',13,10,'$
DATAENDS
CODESEGMENT
ASSUMECS:CODE,DS:DATA
MAINPROCFAR
START:MOVAX,DATA
MOVDS,AX
MOVAH,OAH
LEAAX,STR1
INT21H
MOVAH,OAH
LEADXSTR2
INT21H
LEABX,STR1
LEADI,NUM
CALLCHANGE
LEABX,STR2
LEADI,NUM+2
CALLCHANGE
MOVAX,NUM
ADDAX,NUM+2
MOVBUFFER,AX
JNONEXT
LEADX,OVER
MOVAH,9
INT21H
NEXT:MOVAH,4CH
INT21H
MAINENDP
CHANGEPROC
MOVCL,[BX+1]
MOVCX,[BX+2]
MOVCH,AL
CMPAL/-<
JNZNEXT1
DECCL
INCBX
NEXT1:ADDBX,2
MOVAX,0
LP1:DECCL
JZNEXT2
MOVDH,0
MOVDL,[BX]
ANDDL,OFH
ADDAX,DX
MOVDX,.AX
ADDAX,AX
ADDAX,AX
ADDAX,DX
INCBX
JMPSHORTLP1
NEXT2:MOVDL,[BX]
ANDDL,OFH
MOVDH,0
ADDAX,DX
CMPCH,'-'
JNZNEXT3
NEGAX
NEXT3:MOV[DI],AX
RET
CHANGEENDP
CODEENDS
ENDSTART
例根據(jù)AL寄存器中的內(nèi)容,把程序轉(zhuǎn)移到不同的程序分支中去。
若AL中的內(nèi)容是1,則轉(zhuǎn)到ROUTINE1去執(zhí)行,若AL中的內(nèi)容是2,則轉(zhuǎn)到
R0UTINE2去執(zhí)行,。。。。。。。。這種設(shè)計(jì)發(fā)方法又稱為跳轉(zhuǎn)表法,在程序
設(shè)計(jì)中常見(jiàn)到,很有用。例如,以惡程序分成若干個(gè)功能塊,每個(gè)功能塊實(shí)現(xiàn)不
同的功能可以當(dāng)作一個(gè)分支程序,根據(jù)不同的情況,執(zhí)行不同的分支,完成相應(yīng)
的功能,之后再返回主程序。
TABLESEGMENT
BRATABLEDWROUTINE1,ROUTINE2,ROUTINES,ROUTINE4,ROUTINES,R0UTINE6
TABLEENDS
CODESEGMENT
ASSUMECS:CODE,DS:TABLE
MAINPROCFAR
BEGINMOVAX,TABLE
MOVDS,AX
MOVCH,6
MOVCL,0
NEXT:INCCL
CMPCL,AL
JZ,GORUN
INCBX
INCBX
DECCH
JNZNEXT
JMPCOUTINE
GORUN:JMPWORDPTR[BX]
ROUTINE1:
R0UTINE2:
ROUTINES:
?????????????,
R0UTINE4:
ROUTINE5:
R0UTINE6:
????????????
ROUTINE:
MOVAH,4CH
INT21H
MAINENDP
CODEENDS
ENDBEGIN
這個(gè)程序中,分支標(biāo)的首地址在中BX中,BX作為分支表的指針,分支號(hào)在CL
中隨著分支號(hào)的增加,BX的內(nèi)容也發(fā)生變化,紙箱下一個(gè)分支的地址,因此當(dāng)
AL中的內(nèi)容與CL的內(nèi)容相等時(shí),程序控制就轉(zhuǎn)到BX所致的那個(gè)分支去,從哪
兒在繼續(xù)執(zhí)行。各個(gè)分支執(zhí)行完后,轉(zhuǎn)向何處,可以有變成者根據(jù)需要來(lái)確定。
比如,讓此程序中的各個(gè)分支轉(zhuǎn)向CONTINUE,然后在結(jié)束。
3.7循環(huán)程序設(shè)計(jì)
循環(huán)程序也是程序的一種基本結(jié)構(gòu)。程序中,往往有的程序段需要重復(fù)執(zhí)行多次,
以實(shí)現(xiàn)某種功能,這樣,可以大大簡(jiǎn)化程序設(shè)計(jì)。循環(huán)程序通常有以下三部分組
成:
1.循環(huán)初始狀態(tài)循環(huán)過(guò)程中的工作單元,在循環(huán)開(kāi)始前,往往要給他們賦初
值,以保證循環(huán)能正常地進(jìn)行工作。循環(huán)初始狀態(tài)包括循環(huán)工作部分初態(tài)和循環(huán)
部分初態(tài)。例如:設(shè)某些標(biāo)志,懾地址指針。某些寄存器清零,某些變量付出
制,循環(huán)控制寄存器賦初值等等。
2.2o循環(huán)體這是循環(huán)程序重復(fù)執(zhí)行的部分,是循環(huán)的主體。循環(huán)體包括循
環(huán)的工作部分和循環(huán)的修改部分。循環(huán)的工作部分是實(shí)現(xiàn)程序功能的程序段,它
是循環(huán)的主要部分。循環(huán)的修改部分是修改部分是修改參加循環(huán)的信息的程序
段,循環(huán)每次執(zhí)行時(shí),有關(guān)信息能發(fā)生信息的相應(yīng)變化,確保循環(huán)程序正常循環(huán)。
3.循環(huán)控制循環(huán)能正常進(jìn)行和結(jié)束,循環(huán)控制是關(guān)鍵。循環(huán)控制條件不合理,
循環(huán)就無(wú)法按正常的預(yù)定進(jìn)行,甚至導(dǎo)致死循環(huán)。循環(huán)控制條件的選擇很靈活。
如果循環(huán)次數(shù)是確定的,可以選擇循環(huán)次數(shù)作為循環(huán)控制條件。如果循環(huán)次數(shù)未
知,那么可以跟具體情況選擇或其他條件作為控制條件。
循環(huán)程序有兩種結(jié)構(gòu)形式,一種是先執(zhí)行循環(huán)體,然后根據(jù)控制條件進(jìn)行判斷,
不滿足結(jié)束條件則繼續(xù)循環(huán)操作,滿足條件則退出循環(huán)。這一循環(huán)類似高級(jí)語(yǔ)言
中的repeat-until結(jié)構(gòu)。另一類類似while-do結(jié)構(gòu),先檢查是否滿足控制條件,
滿足循環(huán)條件就執(zhí)行循環(huán)體,否則就退出循環(huán)。這兩循環(huán)結(jié)構(gòu)如圖3-7所示。
下面舉例說(shuō)明。
例在一串?dāng)?shù)中找出其中的最大值和最小值,放在指定的存儲(chǔ)單元中。
尋找最大數(shù)和最小數(shù),可以用逐個(gè)比較來(lái)發(fā)現(xiàn),這就需要循環(huán)體來(lái)執(zhí)行,這一串
數(shù)的個(gè)數(shù)是確定的,很能夠想到以他作為循環(huán)控制條件。程序的流程圖如3-8。
通過(guò)這個(gè)程序,讀者不難確定這些數(shù)的類型和位數(shù)。
循環(huán)可以嵌套,形成多重循環(huán)結(jié)構(gòu)。多重循環(huán)程序設(shè)計(jì)的方法與單循環(huán)程序設(shè)計(jì)
大致相同。另外應(yīng)該注意的是各種循環(huán)的控制條件及循環(huán)主體不能混淆,交錯(cuò),
要層次分明。例如從外層循環(huán)進(jìn)入內(nèi)層循環(huán)時(shí),等于重新開(kāi)始一次新的內(nèi)循環(huán),
初始條件等內(nèi)循環(huán)參數(shù)必須重新的設(shè)置。下面,就我們以典型的起泡法分類排序
作為一個(gè)例子,加以說(shuō)明。
例有一個(gè)n個(gè)子的數(shù)組,要求變成使該數(shù)組的元素按從大到小的次序排列。
起泡算法是這樣實(shí)現(xiàn)排序的:從第一個(gè)數(shù)開(kāi)始,依次對(duì)相鄰兩個(gè)數(shù)輛輛進(jìn)行比較,
如果大小次序不對(duì),則是這兩個(gè)數(shù)交換為止,反之,則不交換。這樣這樣進(jìn)行了
第一遍比計(jì)較,最小的數(shù)被置于隊(duì)尾。進(jìn)行第二遍比較時(shí),只需進(jìn)行n-2次第三
遍比較,最多比較到nT遍就可以實(shí)現(xiàn)程序。
圖3-9是起泡算法的一個(gè)示例,圖3-10是其流程圖。
起泡排序的內(nèi)外循環(huán)次數(shù)是已知的外循環(huán)次數(shù)是確定的,為數(shù)組長(zhǎng)度減1,既
(n-1),
內(nèi)循環(huán)的次數(shù)安每次減1的的規(guī)律在變化。這種排序算法不管原來(lái)排序情況如
何,只要進(jìn)行nT次比較,總可以達(dá)到排序的目的。但實(shí)際上,常常不需要比較
n-1次就可以完成排序。因此對(duì)算法可以進(jìn)行改進(jìn),一旦完成排序,就不再進(jìn)行
比較。這里設(shè)立一個(gè)標(biāo)志位,如果進(jìn)行了比較,就該將該標(biāo)志位置1,如果進(jìn)行
一邊比較后,沒(méi)有交換,即該標(biāo)志位仍為零,說(shuō)明排序已經(jīng)完成,程序可以結(jié)束。
該今后的程序如下:
3.8字程序設(shè)計(jì)
解決實(shí)際問(wèn)題時(shí),變成通常都采用模塊化程序設(shè)計(jì)方法。這種方法把一個(gè)程序分
成多個(gè)具有任務(wù)的程序模塊,程序模塊進(jìn)一步分成獨(dú)立的子模塊,分別編成,調(diào)
試,然后連接在一起,形成一個(gè)完整的程序。模塊化設(shè)計(jì)的程序易于編程,調(diào)試,
修改,程序易讀性強(qiáng)。而子程序結(jié)構(gòu)是模塊化的程序設(shè)計(jì)的重要工具。
子程序在匯編語(yǔ)言中又稱為過(guò)程,它相當(dāng)于高級(jí)語(yǔ)言的過(guò)程,函數(shù)或子程序。
它具有獨(dú)立的功能,在程序需要的地方可以調(diào)用它。
子程序使用時(shí);要注意寄存器內(nèi)容的保護(hù)。由于CPU的寄存器的數(shù)量有限,子程
序使用的寄存器往往會(huì)和調(diào)用程序所用得寄存器發(fā)生沖突,破壞了調(diào)用程序中寄
存器的內(nèi)容影響從寄存器返回后的繼續(xù)處理。為了避免這種現(xiàn)象的發(fā)生,應(yīng)當(dāng)在
子程序入口八所用寄存器的內(nèi)容推入堆棧,保存起來(lái),而在退出子程序前恢復(fù)寄
存器的內(nèi)容。
子程序使用中,要解決的一個(gè)重要問(wèn)題是參數(shù)傳頌。在調(diào)用子程序時(shí),經(jīng)常要把
參數(shù)傳送給子程序,子程序在運(yùn)行以后,也常常要送回一些信息給調(diào)用程序,
報(bào)告子程序運(yùn)行狀態(tài)及結(jié)果等等。這種調(diào)用程序和子程序之間的信息傳送,成
為參數(shù)傳頌,也稱為變量傳送或者過(guò)程通信。
參數(shù)傳送可以通過(guò)以下幾種渠道進(jìn)行:寄存器,變量,地指表,堆棧等,下面分
別舉例說(shuō)明。
3.8.1寄存器傳送參數(shù)
例把十進(jìn)制ASCII字符轉(zhuǎn)換為壓縮的BCD碼數(shù)。
通常,從鍵盤上輸入的十進(jìn)制數(shù)字是ASCH字符,每個(gè)數(shù)值以逗號(hào)或分號(hào)間隔,
最后一回車結(jié)束。這里假定輸入的均是4位數(shù),轉(zhuǎn)換框圖如圖3T1程序如下:
DATASEGMENT
STRINGGB'12345678998123605031',13
ERRORDB'ERROR!',13,10,'$'
BUFERDB10DUP(?)
DATAENDS
CODESEGMENT
ASSUMECS:CODE,DS:DATA
MAIN:PROCFAR
BEGIN:MOVAX,DATA
MOVDS,AX
LEABX,STRING
LEADI,BUFFER
LP:MOVAH,[BX]
INCBX
CMPAX,'O'
JBNEXT1
CMPAH'9'
JANEXT1
MOVAL,[BX]
INCBX
CMPAL,'O'
JBNEXT2
CMPAL,'9'
JANEXT2
LP1:CALLSPE1
MOV[DI],AH
INC,DI
JMPLP
NEXT1:CMPAH,''
JZLP
CMPAH,'
JZLP
CMPAH,13
JZDONE
NEXT2:LEADX,ERROR
MOVAH,9
INT21H
DONE:MOVAH,4CH
INT21H
MAINENDP
SPE1PROC
ANDAH,OFH
MOVCL,4
SHLAH,CL
ANDAL,OFH
ORAH,CL
RET
SPE1ENDP
CODEENDS
ENDBEGIN
在主程序中,得到要轉(zhuǎn)換的ASCH符通過(guò)AX寄存器傳到子程序中,子程序完成
轉(zhuǎn)換后,結(jié)果存在寄存器AH中,參數(shù)結(jié)果又通過(guò)寄存器返回主程序,在傳送參
數(shù)少的時(shí)候,利用寄存器完成參數(shù)傳送是最方便,最快捷的。
3.8.2利用變量傳送參數(shù)
例確定字符串長(zhǎng)度,并顯示長(zhǎng)度值。
字符串的長(zhǎng)度不同于常用的整數(shù),系統(tǒng)并不規(guī)定于一個(gè)定值,在對(duì)字符串進(jìn)行操
作
時(shí),往往需要確定它的長(zhǎng)度。字符串常常以回車符CR或者美元符$作為結(jié)束標(biāo)志,
因此,
從頭開(kāi)始搜索字符串的結(jié)束標(biāo)志,統(tǒng)計(jì)搜索字符的個(gè)數(shù),便可以得到串長(zhǎng)。
這里,假定串長(zhǎng)最大不超過(guò)255。如果找不到串結(jié)束標(biāo)志,以至串長(zhǎng)超過(guò)255,
程序
不再繼續(xù)搜索,而給出提示信息。正常時(shí),通過(guò)DOS功能調(diào)用,顯示串長(zhǎng)度。圖
3-12是其
流程圖。其程序如下:
DATASEGMENT
STRINGDB'Thisisastring:',13,'$'
LENGTH1DW?
CRDB13
MESSAGEDB'Thisistoolong!'
DB13,10,'$'
DATAENDS
CODESEGMENT
ASSUMECS:CODE,DS:DATA
MAINPROCFAR
BEGINMOVAX,DATA
MOVES,AX
MOVDS,AX
CALLSTRLEN;確定字符串長(zhǎng)度
MOVDX,LENGTH1
CMPDX,1OOH
JBNEXT1;如(DX)<1OOH,
;轉(zhuǎn)去EXT1
LEADX,MESSAGE;如(DX)>=100H,顯示提示信息
MOVAH,9
INT21H
JMPNEXT2
NEXT1:MOVDH,DL;串長(zhǎng)暫存在DH
MOVCL,4
SHRDL,CL;取串長(zhǎng)高4位
CMPDL,9
JBELP
ADDDL,7
LP:ADDDL,30H;DL中的高4位變?yōu)锳SCH
MOVAH,6
INT21H;顯示這個(gè)ASCII符
MOVDL,DH
ANDDL,0FH
CMPDL,9
JBELP1
ADDDL,7
LP1:ADDDL,30H;DL中的低4位變?yōu)锳SCH
MOVAH,6
INT21H;顯示該ASCH符
MOVDL,'H'
MOVAH,6
INT21H
NEXT2:MOVAH,4CH
INT21H
MAINENDP
STRLENPROC
LEADI,STRING
MOVCX,OFFFFH;(CX)=-l
MOVAL,CR;(AL)=13
MOVAH,'$';(AH)='$'
CLD
AGAIN:INCCX;串長(zhǎng)加1
CMPCX,100H
JAEDONE;串長(zhǎng)超過(guò)255,則結(jié)束
CMP[DI],AH
JEDONE;遇'$'則結(jié)束
SCASB;搜索回車
JNEAGAIN;沒(méi)找到,返回繼續(xù)
DONE:MOVLENGTH1,CX
RET
STRLENENDP
CODEENDS
ENDBEGIN
這個(gè)程序中,主程序和子程序直接訪問(wèn)模塊中的變量,通過(guò)變量,實(shí)現(xiàn)調(diào)用程序
和子
程序之間的參數(shù)傳送。
3.8.3利用地址表傳送參數(shù)
這種傳送參數(shù)的辦法是建立一張地址表,把要傳給子程序的參數(shù)存放在地址表
中,調(diào)
用程序把地址表的首地址通過(guò)寄存器傳給子程序。子程序從該地址表獲得所需參
數(shù),也把
結(jié)果存入指定的存儲(chǔ)單元。下面是利用這種方法傳送參數(shù)的例子。
例求一個(gè)字符串的ASCII碼的和。
DATASEGMENT
STRINGDB'Thisisastring!),13
LENGTH1DB17
SUMDW?
TABLEDW3DUP(?);保留3個(gè)參數(shù)地址
DATAENDS
CODESEGMENT
ASSUMECS:CODE,DS:DATA
MAINPROCFAR
START:MOVAX,DATA
MOVDS,AX
MOVTABLE,OFFSETSTRING
MOVTABLE+2,OFFSETLENGTH1
MOVTABLE+4,OFFSETSUM
LEABX,TABLE
CALLFINDSUM
MOVAH,4CH
INT21H
MAINENDP
FINDSUMPROC
PUSHAX
PUSHCX
PUSHSI
PUSHDI
MOVSI,[BX]
MOVDI,[BX+2]
MOVCL,[DI]
MOVDI,[BX+4]
MOVAX,0
MOVCH,AL
AGAIN:ADDAL,[SI]
ADCAH,0
INCSI
LOOPAGAIN
MOV[DI],AX
POPDI
POPSI
POPCX
POPAX
RET
FINDSUMENDP
CODEENDS
ENDSTART
3.8.4利用堆棧傳送參數(shù)
這種方法是在調(diào)用程序內(nèi)把參數(shù)或參數(shù)地址保存到堆棧中,而在子程序里從堆棧
中
取出參數(shù)或參數(shù)地址,從而實(shí)現(xiàn)參數(shù)傳送。請(qǐng)看下面的例子。
例從一個(gè)字符串中刪去一個(gè)字符。
相應(yīng)的程序如下:
DATASEGMENT
STRINGDB'
LENGTH1DW$-STRING
KEYDB'x';這是某個(gè)將從串中刪去的字符
DATAENDS
CODESEGMENT
ASSUMECS:CODE,DS:DATA
MAINPROCFAR
START:MOVAX,DATA
MOVDS,AX
MOVES,AX
LEABX,STRING
LEACX,LENGTH1
PUSHBX
PUSHCX;STRING和LENGTH1地址入棧
MOVAL,KEY
CALLDELCHAR;調(diào)用刪一個(gè)字符子程序
MOVAH,4CH
INT21H
MAINENDP
DELCHAPROC
PUSHBP;保存BP
MOVBP,SP;BP指向當(dāng)前棧頂
PUSHSI
PUSHDI
PUSHCX
CLD
MOVSI,[BP+4];得到LENGTH1地址
MOVCX,[SI];得到長(zhǎng)度
MOVDI,[BP+6];得到STRING地址
REPNESCASB;重復(fù)搜索該字符
JNEDONE;沒(méi)找到,退出
MOVSI,[BP+4
溫馨提示
- 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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 新基建考試題及答案
- 廣告設(shè)計(jì)師證書考試信息設(shè)計(jì)解析題及答案
- 護(hù)士試題填空題及答案
- 宣傳誠(chéng)信面試題及答案
- 廣告設(shè)計(jì)師必考內(nèi)容解析試題及答案
- 廣告設(shè)計(jì)創(chuàng)意批評(píng)與改進(jìn)試題及答案
- 2024年助理廣告師考試注意細(xì)節(jié)試題及答案
- 初中安徽文綜試題及答案
- 2024年紡織考試的心理準(zhǔn)備技巧試題及答案
- 廣告設(shè)計(jì)師整合營(yíng)銷理論試題及答案
- 八年級(jí)期中英語(yǔ)試卷分析及整改措施
- 養(yǎng)老院藝術(shù)療愈活動(dòng)方案
- 《地理高考備考講座》課件
- 2024-2030年全球及中國(guó)雅思練習(xí)和考試平臺(tái)行業(yè)發(fā)展規(guī)模及未來(lái)前景預(yù)測(cè)報(bào)告
- TSG 07-2019電梯安裝修理維護(hù)質(zhì)量保證手冊(cè)程序文件制度文件表單一整套
- 2025深圳勞動(dòng)合同下載
- 《風(fēng)電施工流程》課件
- 水處理設(shè)備日常維護(hù)方案
- 河南省“極飛杯”無(wú)人機(jī)應(yīng)用技術(shù)技能大賽-無(wú)人機(jī)植保應(yīng)用-技術(shù)文件
- 2024年上海市交大附中高三語(yǔ)文期中考試作文題目解析及范文:松弛感
- 【碳足跡報(bào)告】新鄉(xiāng)市錦源化工對(duì)位脂產(chǎn)品碳足跡報(bào)告
評(píng)論
0/150
提交評(píng)論