第05章匯編語言程序設(shè)計(jì)_第1頁
第05章匯編語言程序設(shè)計(jì)_第2頁
第05章匯編語言程序設(shè)計(jì)_第3頁
第05章匯編語言程序設(shè)計(jì)_第4頁
第05章匯編語言程序設(shè)計(jì)_第5頁
已閱讀5頁,還剩118頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

會(huì)計(jì)學(xué)1第05章匯編語言程序設(shè)計(jì)1.方式選擇偽指令(續(xù))以下三條偽指令是MASM6.12引入的:.686——用于匯編PentiumPro到Pentium4微處理器非特權(quán)(實(shí)模式)指令.686P——用于匯編PentiumPro到Pentium4微處理器保護(hù)方式在內(nèi)的所有指令.MMX——用于匯編MMX指令.K3D——用于匯編AMD微處理器3DNOW!指令。是MASM6.13引入的.XMM——用于匯編SSE和SSE2指令。是MASM6.15引入的2.完整的段定義使用完整的段定義偽指令來定義一個(gè)段,可具體控制匯編程序MASM和連接程序LINK在內(nèi)存中組織代碼和數(shù)據(jù)的方式。

整個(gè)邏輯段必須用段定義語句括起來。(1)SEGMENT——ENDS偽指令<段名>SEGMENT[定位類型][組合方式][段長(zhǎng)度][分類名]

{段體}<段名>ENDS每個(gè)邏輯段都以SEGMENT語句開頭,以ENDS語句結(jié)束;

兩語句前的段名作為邏輯段的標(biāo)識(shí)符,它必須是唯一的,確定該段在存儲(chǔ)器中的位置。

第1頁/共123頁(1)SEGMENT——ENDS偽指令(續(xù))段開始和結(jié)束語句之間部分是段的內(nèi)容——

對(duì)數(shù)據(jù)段、堆棧段和附加段而言,一般由存儲(chǔ)單元定義、分配等偽指令所組成,對(duì)代碼段,則主要是由可執(zhí)行指令以及某些偽指令組成。方括號(hào)中是定位類型、組合方式、分類名和段長(zhǎng)度等的說明,視情況可以省略。若對(duì)本邏輯段在內(nèi)存中的定位加以限定、或需與其它段相連接,則須按規(guī)定選擇這些項(xiàng)。定位類型(Align-type)規(guī)定該段的起始位置。有以下幾種選擇:

BYTE:段的起始地址可以從任何單元開始,段間不留空隙,存儲(chǔ)器利用率最高;

WORD:段的起始地址為偶數(shù),即從字的邊界開始;適合字類型的數(shù)據(jù)段定位;

DWORD:段的起始地址是4的整數(shù)倍,適合雙字類型的數(shù)據(jù)段定位;PARA:段的起始位置是16的整數(shù)倍,即從節(jié)(24=16為一節(jié))的邊界開始;

PAGE:段的起始地址必須是256的整數(shù)倍,即從頁(28=256為一頁)的邊界開始;

INPAGE:該段長(zhǎng)度不超過256個(gè)字節(jié)(一頁之內(nèi)),不允許跨頁存放。定位類型缺省時(shí)為PARA方式。第2頁/共123頁(1)SEGMENT——ENDS偽指令(續(xù))組合方式(Combinetype)又稱連接方式,規(guī)定連接程序LINK處理本段與其它邏輯段時(shí)如何進(jìn)行相互連接。可以有以下幾種:

NONE:本段與其它段無組合關(guān)系,這是缺省方式。也可用等價(jià)的關(guān)鍵字

PRIVATE。PUBLIC:在滿足定位的條件下,將本段與其它具有PUBLIC屬性的同名段連接

成一個(gè)連續(xù)的大邏輯段,公用一個(gè)段基址;連接次序由連接命令指定。

COMMON:本段和其它具有COMMON屬性的同名段重疊,對(duì)各段指定相同的

起始地址(即段基址),因而產(chǎn)生復(fù)蓋。COMMON連接后段的長(zhǎng)度是

各連接段中最大段的長(zhǎng)度。

STACK:把不同模塊中具有STACK屬性的同名段連接成一個(gè)連續(xù)的堆棧段,連

接后的堆??臻g是被連接的各個(gè)堆??臻g之和。LINK自動(dòng)將新段的段

基址送SS,將新段的長(zhǎng)度送SP;定義堆棧段時(shí)沒有將其說明為

STACK類型,就要在程序中用指令給SS和SP賦值;連接程序LINK在

連接時(shí)會(huì)給出一個(gè)警告信息。

MEMORY:早期版本的選項(xiàng),LINK不再單獨(dú)區(qū)分MEMORY類型,將其視為

PUBLIC類型,MASM允許它繼續(xù)使用,主要是為了與支持Intel

MEMORY類型的連接程序兼容。

AT<表達(dá)式>:定位本段在指定節(jié)的整數(shù)邊界上,節(jié)號(hào)由表達(dá)式給出。AT方式

不能用在代碼段中。使用AT方式的邏輯段中,用DB、DW預(yù)置

數(shù)據(jù)將失敗。第3頁/共123頁(1)SEGMENT——ENDS偽指令(續(xù))段長(zhǎng)度

對(duì)32位微處理器新增了USE屬性說明,又稱段字說明。

對(duì)16位CPU,默認(rèn)的段長(zhǎng)是16位,不使用USE選項(xiàng)。

對(duì)32位CPU,有兩種方式(默認(rèn)選項(xiàng)是USE32):USE16:表示邏輯段最大長(zhǎng)度為64K,訪問該邏輯段采用16位尋址方式。USE32:表示邏輯段最大長(zhǎng)度為4G,訪問該邏輯段采用32位尋址方式。分類名

用單引號(hào)括起來的長(zhǎng)度不超過40個(gè)字符的字符串。連接程序把不同模塊中分類名相同的段組織成一類,存放在連續(xù)的存儲(chǔ)區(qū)域。習(xí)慣上數(shù)據(jù)段/代碼段/堆棧段的分類名分別用’DATA’/’CODE’/’STACK’表示。第4頁/共123頁(2)段分配語句ASSUME段分配偽指令A(yù)SSUME用來通知匯編程序:CS、DS、SS、ES將被設(shè)置成那些段的段基址寄存器,這樣在匯編時(shí)就能知道語句中引用的變量和標(biāo)號(hào)是通過那些寄存器進(jìn)行訪問的。ASSUME<段寄存器名>:<邏輯段名>[,<邏輯段名>…];[<段寄存器名>:<邏輯段名>

[,<邏輯段名>…];…;[<段寄存器名>:NOTHING]]偽指令語句ASUMENOTHING將刪除所有已設(shè)置的段寄存器與段名之間的關(guān)聯(lián)。ASUME偽指令只是建立段名和段寄存器之間的關(guān)聯(lián),并未把各個(gè)段的段基址裝入相應(yīng)的段寄存器中。段基址的裝入通常采用程序方法。①DS和ES裝入:在程序中用指令經(jīng)通用寄存器間接裝入段基址。②SS裝入:有兩種方法——

◆一種是在SEGMENT語句的組合類型中選用STACK,在ASSUME語句中建

立堆棧段與SS的關(guān)聯(lián),則連接時(shí)LINK自動(dòng)給SS和SP賦予正確的初值;

◆另一種SEGMENT語句中組合類型未選用STACK參數(shù),或者程序中使用了

另一個(gè)堆棧段,可用傳送指令間接地給SS和SP賦初值(組合類型未選用

STACK參數(shù),連接時(shí)LINK會(huì)給出警告信息)。③

CS和IP裝入:對(duì)CS和IP,通常是按照結(jié)束偽指令END[<起始地址>]

指定的地址來自動(dòng)完成段基址和偏移地址裝入的。第5頁/共123頁(3)組定義偽指令GROUP當(dāng)用段定義語句SEGMENT—ENDS定義了若干個(gè)邏輯段而總?cè)萘坎怀^64K時(shí),就可把這些段用GROUP語句定義為一個(gè)“組”,格式如下:<組名>GROUP<段名1>[,段名2,……]GROUP把程序模塊中若干個(gè)不同名字的段組合成一個(gè)組,并賦予一個(gè)組名,組內(nèi)各段都裝在一個(gè)物理段中,使組內(nèi)各段間的跳轉(zhuǎn)都視作段內(nèi)跳轉(zhuǎn)。語句中的段名可以是表達(dá)式SEG<變量名>或SEG<標(biāo)號(hào)>,表達(dá)式的值是定義該變量或標(biāo)號(hào)的段號(hào)。語句中的段名可以是表達(dá)式SEG<變量名>或SEG<標(biāo)號(hào)>,表達(dá)式的值是定義該變量或標(biāo)號(hào)的段號(hào)。

組名是標(biāo)識(shí)組的起始地址的標(biāo)號(hào),表示該組的段基址。組中各個(gè)段內(nèi)的偏移地址都以這個(gè)基址為起點(diǎn),而不以本段原來的段基址為起點(diǎn)。組名的使用方法與段名相同。第6頁/共123頁3.定位語句(1)ORG語句匯編源程序時(shí),匯編程序?qū)⒍蚊钊攵伪恚樵摱闻渲靡粋€(gè)位置計(jì)數(shù)器(初值為0),該計(jì)數(shù)器依次累計(jì)段內(nèi)語句被匯編后所生成的目標(biāo)代碼的字節(jié)數(shù),跟蹤匯編過程。

偽指令ORG能改變這個(gè)位置計(jì)數(shù)器的值,從指定位置分配代碼或數(shù)據(jù)。格式:

ORG<數(shù)值表達(dá)式>數(shù)值表達(dá)式中可用“$”表示位置計(jì)數(shù)器的當(dāng)前值,表達(dá)式的值為正整數(shù);ORG語句把表達(dá)式的值賦給位置計(jì)數(shù)器。

在代碼段,ORG語句后的指令語句就從指定位置生成目標(biāo)代碼;

在數(shù)據(jù)段,ORG后的數(shù)據(jù)定義偽指令就從指定位置分配所定義的數(shù)據(jù)。(2)EVEN語句格式:

EVENEVEN語句使段內(nèi)位置計(jì)數(shù)器當(dāng)前值$與偶地址對(duì)齊。

遇到EVEN語句時(shí),若地址計(jì)數(shù)器值$為奇數(shù),在代碼段匯編程序自動(dòng)插入一條單字節(jié)空操作指令NOP,使$變?yōu)榕紨?shù);在數(shù)據(jù)段自動(dòng)將$值加1,使下面定義的數(shù)據(jù)從偶地址單元開始存放。第7頁/共123頁4.模塊開始與結(jié)束語句(1)模塊開始語句模塊開始語句Name表示源程序的開始并為模塊取名字,格式如下:

NAME<模塊名>匯編程序?qū)⒁哉Z句中的模塊名作為模塊的名字。

也可使用title語句,格式:

TITLE<標(biāo)題>title偽指令指定了在每一頁上打印的標(biāo)題,最多為60個(gè)字符。如果程序中沒有使用NAME偽指令,則匯編程序MASM將用title語句中標(biāo)題的前6個(gè)字符作為模塊名。如果程序中既無NAME語句,又無TITLE語句,則將用源文件名作為模塊名。(2)模塊結(jié)束語句ENDEND表示源程序到此結(jié)束,并可指出程序的啟動(dòng)地址。格式如下:

END[標(biāo)號(hào)/過程名]該語句一般放在源程序最后一行,程序中有且只能有一個(gè)END語句。其中標(biāo)號(hào)或過程名給出了程序開始執(zhí)行的啟動(dòng)單元地址,只有主模塊才可有此選項(xiàng)。◆當(dāng)連接的多個(gè)模塊中都沒有給出啟動(dòng)地址,將從代碼段的第一個(gè)字節(jié)

處開始執(zhí)行,

◆當(dāng)有多個(gè)模塊都指定了啟動(dòng)地址,將從最后一條帶標(biāo)號(hào)的END語句指

定的啟動(dòng)地址單元開始執(zhí)行。

這些都可能導(dǎo)致程序的錯(cuò)誤執(zhí)行,編程時(shí)應(yīng)予避免。

第8頁/共123頁5.返回操作系統(tǒng)方式

(1)使用功能號(hào)為4CH的DOS功能調(diào)用調(diào)用方式:

MOVAH,4CH ;功能號(hào)4CH送AH寄存器

INT21H ;DOS系統(tǒng)功能調(diào)用這是最有效且兼容性最好的返回DOS方式。(2)將主程序定義為遠(yuǎn)過程在代碼段中,將主程序定義為遠(yuǎn)過程,由RET語句返回。 <主過程名>

PROCFAR

…;{主程序}

RET <主過程名>

ENDP(3)利用20H號(hào)BIOS中斷調(diào)用這種方式只能用于擴(kuò)展名為.COM的可執(zhí)行文件。調(diào)用方式為:

INT20H(4)利用0號(hào)DOS系統(tǒng)功能調(diào)用該方式與INT20H一樣,只有在.COM類型的文件中才可使用。調(diào)用格式如下:

MOVAH,0 ;功能號(hào)送AHINT21H ;DOS系統(tǒng)功能調(diào)用第9頁/共123頁5.1.2段定義的簡(jiǎn)化

在MASM5.0及以上版本中,段的定義可以非常簡(jiǎn)單,方便了程序設(shè)計(jì)。使用簡(jiǎn)化段定義偽指令前,必須先說明用戶程序使用的內(nèi)存模式。1.內(nèi)存模式定義偽指令MODEL內(nèi)存模式指用戶程序的代碼和數(shù)據(jù)的存放格式,及他們占用內(nèi)存的大小。

.MODEL<存儲(chǔ)模式>[,語言類型][,操作系統(tǒng)類型][,堆棧類型]①

存儲(chǔ)模式:共有七種——TINY——微型模式。

程序中的代碼和數(shù)據(jù)放在同一個(gè)64KB段內(nèi),程序?yàn)?.COM型,該模式是MASM

6.0才引入的。SMALL——小型模式。

這是一般程序的默認(rèn)模式。程序中的代碼和數(shù)據(jù)各放入一個(gè)64KB的段內(nèi),數(shù)據(jù)段、

堆棧段和附加段一起共用一個(gè)段。對(duì)代碼和數(shù)據(jù)的訪問通過近程調(diào)用(NEAR)

來實(shí)現(xiàn)。MEDIUM——中型模式。

程序中代碼長(zhǎng)度大于64KB,可安排在不同的段內(nèi);數(shù)據(jù)存放在一個(gè)64KB的段內(nèi);

因此代碼訪問是遠(yuǎn)程(FAR)的,數(shù)據(jù)訪問是近程的。COMPACT——壓縮模式。

程序中所有代碼安排在一個(gè)64KB的段內(nèi),數(shù)據(jù)區(qū)可大于64KB,安排在不同的段

中(但任一數(shù)據(jù)段存儲(chǔ)空間不得超過64KB)。對(duì)代碼訪問是近程的,對(duì)數(shù)據(jù)訪問

是遠(yuǎn)程的。第10頁/共123頁1.內(nèi)存模式定義偽指令(續(xù))LARGE——大型模式。

程序中的代碼和數(shù)據(jù)都超過64KB,但靜態(tài)(常數(shù))數(shù)據(jù)限制在64KB之內(nèi);對(duì)代碼和數(shù)據(jù)的訪問默認(rèn)都是遠(yuǎn)程的。HUGE——巨型模式。

程序中的代碼和數(shù)據(jù)均大于64KB,靜態(tài)數(shù)據(jù)也可以超過64KB。對(duì)代碼、數(shù)據(jù)和數(shù)組的訪問都是遠(yuǎn)程的。FLAT——平展模式。

DOS下不能使用此模式。該模式用于創(chuàng)建32位的Windows程序,只能運(yùn)行在32位的80x86微處理器上。②語言類型子程序語言類型用來告訴匯編程序使用什么樣的標(biāo)識(shí)符命名風(fēng)格、子程序調(diào)用和返回約定等。語言類型說明可使匯編程序和其他語言程序共享。有效的語言類型為C、SYSCALL(系統(tǒng)調(diào)用)、STDCALL(標(biāo)準(zhǔn)調(diào)用)、BASIC、FORTRAN、PASCAL等。③操作系統(tǒng)類型OS_DOS是當(dāng)前唯一支持的選項(xiàng)也是該選項(xiàng)的缺省值。④堆棧類型堆棧類型有如下兩個(gè)選項(xiàng),不同選值主要影響偽指令.STARTUP所生成的指令序列。NEARSTACK——堆棧段和數(shù)據(jù)段是同一個(gè)段。這也是該選項(xiàng)的缺省值。FARSTACK——堆棧段和數(shù)據(jù)段是不同的段,且堆棧段不在段組DGROUP中。第11頁/共123頁2.簡(jiǎn)化的段定義

(1)簡(jiǎn)化段定義偽指令簡(jiǎn)化段定義偽指令在.MODEL<存儲(chǔ)模式>語句之后,如下所列。

每個(gè)簡(jiǎn)化段偽指令都可用來表示一個(gè)段的開始,同時(shí)也說明前一個(gè)段結(jié)束。.STACK[長(zhǎng)度] ;定義堆棧段,長(zhǎng)度缺省值為1KB.CODE[名字] ;定義代碼段.DATA ;定義數(shù)據(jù)段.DATA? ;定義數(shù)據(jù)段,初值不確定.FARDATA[名字] ;定義遠(yuǎn)調(diào)用數(shù)據(jù)段.FARDATA?[名字] ;定義遠(yuǎn)調(diào)用數(shù)據(jù)段,初值不確定.CONST ;定義只讀常數(shù)數(shù)據(jù)段.STARTUP ;程序起始點(diǎn),并初始化DS、SS.EXIT0 ;程序結(jié)束點(diǎn),返回操作系統(tǒng)上述簡(jiǎn)化段定義偽指令中帶方括號(hào)的項(xiàng)可省略。

偽指令.EXIT0相當(dāng)于MOVAX,4C00H和INT21H兩條指令。

第12頁/共123頁(2)缺省段名使用簡(jiǎn)化的段定義偽指令,每個(gè)段都有一個(gè)缺省的段名,如下表所示。第13頁/共123頁2.簡(jiǎn)化的段定義(續(xù))(3)等價(jià)段名MASM5.0宏匯編語言中規(guī)定了幾個(gè)代替真實(shí)段名的等價(jià)段名,允許用@代替簡(jiǎn)化段定義偽指令前的小數(shù)點(diǎn)。如@CODE代表.CODE定義的段名,@DATA代表.DATA、.DATA?、.CONST和.STACK共享的組名,@FARDATA代表.FARDATA定義的段名,等等。(4)定義段序偽指令MASM可以對(duì)匯編結(jié)果的目標(biāo)文件中各段的位置進(jìn)行排序。

定義段序的偽指令有三種。.SEG——按照段在程序中出現(xiàn)的順序?qū)χ判颉?/p>

這是完整段定義格式中的默認(rèn)順序。.ALPHA——按照字母順序?qū)Χ闻判颉?DOSSEG——按照DOS定義的標(biāo)準(zhǔn)段序。

即按代碼段、數(shù)據(jù)段、堆棧段的次序?qū)Χ闻判?。這是用.MODEL偽指令

的簡(jiǎn)化段定義格式中默認(rèn)的順序。

第14頁/共123頁3.源程序編程格式

(1).EXE文件編程格式該格式下源程序允許使用多個(gè)邏輯段,適合編寫大型程序,匯編-連接后生成擴(kuò)展名為.EXE的可執(zhí)行文件。

.EXE文件編程格式的源程序最少有一個(gè)代碼段。

代碼段的開始用一條ASUME語句設(shè)置段約定。在實(shí)模式下,每個(gè)邏輯段的目標(biāo)模塊最大64KB;

在保護(hù)模式下,80286不超過16MB,32位的80x86不超過4GB。.ASM源程序匯編、連接后生成可執(zhí)行文件.EXE,.EXE文件有重定位信息。

DOS裝入.EXE文件,再根據(jù)重定位信息完成對(duì)目標(biāo)模塊的重定位,然后在目標(biāo)程序的上方(低地址處)自動(dòng)生成256個(gè)字節(jié)的程序段前綴PSP(ProgramSegmentPrefix),DOS通過PSP管理用戶程序(如程序結(jié)束時(shí)返回DOS的途徑等)。DOS自動(dòng)使DS=ES=PSP的段基址,F(xiàn)S=GS=0,CS:IP指向用戶程序的啟動(dòng)地址,SS:SP指向用戶堆棧的棧頂。

然后DOS把控制權(quán)交給用戶程序。由于DOS給DS、ES、FS、GS所賦的初值不等于用戶程序數(shù)據(jù)段、附加段的段基址,因此用戶程序開始處必須對(duì)所用的段寄存器DS(及ES、FS、GS)等進(jìn)行初始賦值。第15頁/共123頁3.源程序編程格式(續(xù))(2).COM文件編程格式該格式只允許源程序設(shè)置一個(gè)代碼段(堆棧在代碼段內(nèi)),代碼段的目標(biāo)模塊要小于64KB,適合編寫中小程序。

在.MODELTINY偽指令定義的內(nèi)存模式下即可生成.COM結(jié)構(gòu)的源程序。程序中使用的數(shù)據(jù)可集中設(shè)置在代碼段的開始或末尾,程序的啟動(dòng)指令須設(shè)置在代碼段內(nèi)偏移量為100H的單元處。.COM文件沒有重定位信息,比.EXE文件要小得多。

DOS裝載.COM文件時(shí)也在用戶程序上方生成256個(gè)字節(jié)單元的程序段前綴PSP,PSP開始處存放一條中斷指令I(lǐng)NT20H(2個(gè)字節(jié))。

DOS自動(dòng)賦值使CS=DS=ES=SS=PSP的段基址、FS=GS=0,使IP=100H、SP=FFFEH,然后把控制權(quán)交給用戶程序,CPU從CS:100H處開始執(zhí)行用戶程序。DOS在裝入.COM文件時(shí)自動(dòng)在用戶區(qū)高端(高地址處)設(shè)置堆棧,.COM文件編程不需要設(shè)置堆棧。常見可執(zhí)行文件的執(zhí)行級(jí)別從高到低依次是.COM、.EXE、.BAT。

可用EXE2BIN.EXE軟件將匯編-連接生成的小于64K的.EXE文件轉(zhuǎn)換成.COM文件:

EXE2BIN<文件名[.EXE]><文件名.COM>前一個(gè)文件名后綴.EXE可省略,但后一個(gè)文件名的后綴.COM必須寫上,否則將生成.BIN文件(它不能裝入執(zhí)行)。用高版本匯編TASM.EXE匯編.ASM文件后,只需在連接(TLINK.EXE)時(shí)使用小寫的“t”做連接參數(shù)就可直接生產(chǎn).COM文件。

第16頁/共123頁5.2匯編語言語句

5.2.1匯編語言匯編語言是面向機(jī)器的程序設(shè)計(jì)語言,是為特定的計(jì)算機(jī)系列設(shè)計(jì)的,使用英文宿寫的指令助記符、符號(hào)地址及標(biāo)號(hào)等編寫程序語句。與其它程序類似,匯編語言源程序由語句行構(gòu)成。1.匯編程序匯編程序的種類很多,主要功能基本相同:把匯編語言源程序翻譯成二進(jìn)制代碼,但匯編的處理器指令集和偽指令語句集有所不同。

◆Microsoft公司的MASM宏匯編程序應(yīng)用最廣,有多種版本,版本越高

功能越全;

◆基本匯編程序ASM只能匯編8086/8088指令源程序,ASM是MASM的

一個(gè)子集,它不支持有關(guān)結(jié)構(gòu)、記錄、宏、條件匯編等偽指令和偽操

作符。

第17頁/共123頁2.語句分類

構(gòu)成匯編源程序的語句可分為兩大類:指令性語句和指示性語句。指令性語句就是指令語句,是CPU要執(zhí)行的語句部分。

指令語句由匯編程序匯編、翻譯成目標(biāo)代碼,一條指令語句對(duì)應(yīng)一條機(jī)器語言指令代碼,規(guī)定機(jī)器的一種操作。指示性語句不是計(jì)算機(jī)系統(tǒng)指令集提供的,因此又稱為偽指令。

每種匯編程序都有自己的偽指令集,偽指令主要作用是為匯編程序服務(wù),告訴匯編程序如何翻譯指令語句、以及如何分配內(nèi)存、定義數(shù)據(jù)、進(jìn)行各種有關(guān)的處理(替換、條件匯編、連接、列清單等等)。

偽指令匯編時(shí)由匯編程序執(zhí)行,不產(chǎn)生機(jī)器代碼。第18頁/共123頁3.語句結(jié)構(gòu)

指令性語句:[標(biāo)號(hào):] <助記符>[操作數(shù)][;注釋]

指示性語句:[名字] <定義符>[操作數(shù)][;注釋]<……>尖括號(hào)內(nèi)的為必選項(xiàng),[……]方括號(hào)內(nèi)的為可選項(xiàng)。(1)標(biāo)號(hào)和名字指令性語句中的標(biāo)號(hào)后一定要跟冒號(hào),而指示性語句中的名字后不能有冒號(hào),這是兩種語句在格式上的主要區(qū)別之一。標(biāo)號(hào)在代碼段中設(shè)置,表示本語句的符號(hào)地址,可作為轉(zhuǎn)移指令或Call指令的目標(biāo)地址,因而標(biāo)號(hào)只出現(xiàn)在作為目標(biāo)而被訪問的語句中。名字可以是變量名、段名、過程名、符號(hào)名等,語句中是否出現(xiàn)名字及出現(xiàn)什么名字取決于定義符的要求。標(biāo)號(hào)或名字可由下列字符組成:

英文字母(匯編程序一般不區(qū)分大小寫)、數(shù)字0~9以及_$.?@%等。

除數(shù)字外的字符都可以作為第一個(gè)字符出現(xiàn),若使用“.”符號(hào)則必須出現(xiàn)在開頭位置。

組成標(biāo)號(hào)或名字的字符可以有多個(gè),但只有前31個(gè)被匯編程序識(shí)別和承認(rèn)。第19頁/共123頁(2)助記符和定義符指令語句中的助記符表示該指令的操作碼類型,規(guī)定了語句的操作功能,如ADD、LOOP等。

偽指令中的定義符規(guī)定了該語句的偽操作功能,由匯編程序進(jìn)行處理。除了注釋語句外,助記符或定義符是匯編語句中必不可少的項(xiàng)目。(3)操作數(shù)操作數(shù)項(xiàng)可以是常數(shù)、寄存器、標(biāo)號(hào)、變量或者表達(dá)式。

操作數(shù)項(xiàng)的多少由指令或偽指令規(guī)定,在一項(xiàng)以上時(shí),各項(xiàng)之間用逗號(hào)分開。

對(duì)指令語句,操作數(shù)項(xiàng)通常給出操作數(shù)的地址,一般不超過2個(gè);

對(duì)偽指令語句,該項(xiàng)則給出所需的參數(shù),可以有多個(gè)。(4)注釋注釋以分號(hào)開始,用來對(duì)一段程序或某些指令在程序中的作用加以說明,增加程序的可讀性。注釋不被匯編程序匯編,也不被執(zhí)行。一條語句一般只占一行,超過一行要用續(xù)行符“&”指明。兩條語句不能寫在同一行上。匯編源程序語句最多由四個(gè)部分組成;書寫時(shí)各部分之間要留有一定數(shù)量的空格,以使各語句的相應(yīng)部分全部左對(duì)齊,使整個(gè)程序規(guī)范整齊,清晰明了。第20頁/共123頁5.2.2數(shù)據(jù)定義語句

1.變量定義語句用變量表示存儲(chǔ)器數(shù)據(jù),是匯編語言中普遍采用的方法。

變量名是存放數(shù)據(jù)的存儲(chǔ)單元符號(hào)地址,變量值是對(duì)應(yīng)存儲(chǔ)單元的內(nèi)容。(1)語句格式格式一:[變量名]<定義符><數(shù)據(jù)項(xiàng)表>[;注釋]格式二:[變量名]<定義符><常數(shù)表達(dá)式>DUP(<數(shù)據(jù)項(xiàng)表>)[;注釋]變量名是可選項(xiàng),表示符號(hào)地址,標(biāo)記該語句數(shù)據(jù)項(xiàng)表中第一個(gè)數(shù)據(jù)的偏移地址,變量的值就是該偏移地址單元的存儲(chǔ)內(nèi)容。定義符是必選項(xiàng),用來定義數(shù)據(jù)項(xiàng)的類型屬性,常用的有以下幾種:DB——定義字節(jié),項(xiàng)表的每個(gè)數(shù)據(jù)項(xiàng)為字節(jié),類型屬性為1;DW——定義字,項(xiàng)表的每個(gè)數(shù)據(jù)項(xiàng)為字(2個(gè)字節(jié)長(zhǎng)),類型屬性為2;DD——定義雙字,項(xiàng)表的每個(gè)數(shù)據(jù)項(xiàng)為雙字,類型屬性為4;DF——定義長(zhǎng)字,項(xiàng)表的每個(gè)數(shù)據(jù)項(xiàng)為三字(48位二進(jìn)位),類型屬性為

6,僅用于386CPU上的指針變量;DQ——定義四字,項(xiàng)表的每個(gè)數(shù)據(jù)項(xiàng)為四字,類型屬性為8;DT——定義十個(gè)字節(jié),項(xiàng)表的每個(gè)數(shù)據(jù)項(xiàng)為十字節(jié),類型屬性為10。

第21頁/共123頁(2)變量定義語句例舉

DBYTE DB10,-10,10HDWORD DW100,-100,100HDDW DD4*20,0FFFDH;變量匯編存儲(chǔ)結(jié)果見下圖左

MESSAGE0DB`HELLO'MESSAGE1DB`AB'MESSAGE2DW`AB‘;變量匯編存儲(chǔ)結(jié)果見下圖中

BUF1DB0,?,?,?,0;“?”操作數(shù)可預(yù)留空間,不存入數(shù)據(jù)BUF2DW?,36,?;變量匯編存儲(chǔ)結(jié)果見下圖右第22頁/共123頁用地址表達(dá)式定義變量地址表達(dá)式的運(yùn)算結(jié)果是一個(gè)地址(無符號(hào)數(shù)),指向某個(gè)存儲(chǔ)單元;該存儲(chǔ)單元若用來存放數(shù)據(jù),則為變量,若存放指令代碼,則為標(biāo)號(hào)。

可以用已有確定值的變量或標(biāo)號(hào)來定義一個(gè)新的變量顯然只能使用DW或DD來定義。

DW用來將已知變量或標(biāo)號(hào)的偏移地址定義為新變量,

DD用來將已知變量或標(biāo)號(hào)的偏移地址和段基址分別置入新變量的低位字和高位字中。設(shè)程序中已定義了變量V1和V2,代碼段中已定義了標(biāo)號(hào)FIRS和LLT,則可用它們來定義新變量如下:

NV1DW FIRS ;把標(biāo)號(hào)FIRS的偏移地址賦給字變量NV1NV2DD LLT ;把標(biāo)號(hào)LLT的偏移地址和段基址賦給雙字變量NV2NV3DW V1 ;把變量V1的偏移地址賦給字變量NV3NV4DD V2 ;把變量V2的偏移地址和段基址賦給雙字變量NV4格式二用復(fù)制操作符DUP(Duplicationoperator)來復(fù)制或重復(fù)定義變量;

其中<常數(shù)表達(dá)式>的值應(yīng)是一個(gè)正整數(shù),用來規(guī)定DUP后括號(hào)中數(shù)據(jù)項(xiàng)表的重復(fù)次數(shù)。

ARRAY1DB2DUP(0,10,10H,?);等價(jià)于ARRAY1DB0,10,10H,?,0,10,10H,?ARRAY2DW100DUP(?)DUP操作可以嵌套:TAB1DB2DUP(1,2,3DUP(10)) TAB2DW10DUP(5DUP(2DUP(1100H,2200H)))上面第一條語句定義了TAB1開始的10個(gè)字節(jié)單元,其內(nèi)容為1,2,10,10,10,1,2,10,10,10;

第二條語句定義了TAB2開始的200個(gè)(10×5×2×2)字單元,其內(nèi)容為1100H,2200H重復(fù)2次(4個(gè)字單元)、再重復(fù)5次(5×4=20個(gè)字單元)、再重復(fù)10次(20×10=200字單元),TAB2數(shù)組有200個(gè)字單元,占400個(gè)字節(jié)存儲(chǔ)空間。(3)變量類型屬性變量被定義后具有相應(yīng)的值,還具有類型屬性,變量表達(dá)式的類型屬性和變量相同。匯編程序用類型屬性來表明指令操作數(shù)的字節(jié)長(zhǎng)度。指令在執(zhí)行運(yùn)算時(shí),操作數(shù)作為參加運(yùn)算的對(duì)象,其類型屬性必須相同,否則出錯(cuò)。第23頁/共123頁2.標(biāo)號(hào)

標(biāo)號(hào)表示指令性語句的符號(hào)地址,作為轉(zhuǎn)移類指令的目標(biāo)操作數(shù),一目了然地確定程序轉(zhuǎn)移的目標(biāo)地址。(1)標(biāo)號(hào)屬性段屬性(SEG)

表示標(biāo)號(hào)所在段的段基址。偏移屬性(OFFSET)

表示標(biāo)號(hào)在段內(nèi)的偏移地址(從段基址到標(biāo)號(hào)位置之間的字節(jié)數(shù)),是16位或32位無符號(hào)數(shù)。距離屬性(TYPE)

也叫類型屬性,指出標(biāo)號(hào)被訪問的段別:

近程N(yùn)EAR——只允許在本段內(nèi)被訪問的標(biāo)號(hào),

指令性語句標(biāo)號(hào)之后必須有一個(gè)冒號(hào),這個(gè)標(biāo)號(hào)的默認(rèn)屬性為NEAR。遠(yuǎn)程FAR——允許其它段跨段訪問的標(biāo)號(hào)。標(biāo)號(hào)也可以作為過程定義語句的過程名,用作調(diào)用指令的目標(biāo)地址。(2)更改屬性的偽指令標(biāo)號(hào)和變量,其屬性可用PTR偽指令臨時(shí)指定,用THIS和TABLE偽指令另行指定。第24頁/共123頁2.標(biāo)號(hào)(續(xù))PTR屬性操作符格式:<類型>PTR<變量或標(biāo)號(hào)[±常數(shù)表達(dá)式]>其中變量類型可以是BYTE、WORD、DWORD等,標(biāo)號(hào)類型可以是NEAR或FAR。PTR臨時(shí)指定某個(gè)變量、標(biāo)號(hào)或地址表達(dá)式所指存儲(chǔ)單元的類型或距離屬性,使其具有語句左邊的<類型>屬性(與原定義的不同)。例: BUF3DB 1,2 BUF4DW3456H,7890H… MOVAX,BUF3+1 ;出錯(cuò),操作數(shù)類型不匹配

MOVBL,BUF4 ;出錯(cuò),操作數(shù)類型不匹配匯編程序在匯編這段程序時(shí),發(fā)現(xiàn)兩條MOV指令的類型屬性不同:第一條MOV指令A(yù)X為字類型而BUF3+1為字節(jié)類型,第二條MOV指令BL為字節(jié)類型而BUF4為字類型,因而出錯(cuò)并提示:(這兩條指令)操作數(shù)類型不匹配。用PTR運(yùn)算符改變它們的屬性,改正如下:

BUF3DB 1,2 BUF4DW 3456H,7890H … MOVAX,WORDPTRBUF3+1;5602H送AXMOVBL,BYTEPTRBUF4;56H送BL第25頁/共123頁2.標(biāo)號(hào)(續(xù))THIS屬性運(yùn)算符格式:

THIS<類型>THIS運(yùn)算符常與偽指令EQU、=連用,為當(dāng)前存儲(chǔ)單元定義一個(gè)指定類型的變量或標(biāo)號(hào)。THIS不分配新的存儲(chǔ)單元。例: BUF EQUTHISWORD POT EQUTHISFAR第一(或第二)條語句表示從本語句開始,變量BUF(或標(biāo)號(hào)POT)的類型屬性就定義為字(或FAR),而不管BUF(或POT)原來的類型是什么,直到遇到新的類型定義語句為止。LABLE偽指令LABEL語句用來給變量或標(biāo)號(hào)取一個(gè)別名,并可重新定義它的類型屬性。這使得同一個(gè)變量或標(biāo)號(hào)以不同的名字引用時(shí)具有不同類型的屬性。格式:<名字>LABEL<類型>被LABEL定義的名字,其位置與緊跟在該語句下面的指令(變量定義偽指令或帶標(biāo)號(hào)的指令)具有相同的段基址和偏移地址。例:BARRAY LABELBYTEDARRAY DW100DUP(?) MOVBRRAY+2,0 MOVDARRAY+2,0BARRAY和它下面的DARRAY的地址是相同的,它們指向同一數(shù)組。BARRAY被定義成字節(jié)型,第一條MOV指令把該數(shù)組的第3個(gè)字節(jié)置0;DARRAY被定義成字類型,第二條MOV指令把該數(shù)組的第3個(gè)字(即第4和第5個(gè)字節(jié))置0。第26頁/共123頁3.符號(hào)定義語句

為方便程序設(shè)計(jì),對(duì)程序中多次出現(xiàn)的同一個(gè)常量、字符串或表達(dá)式,可以用符號(hào)定義偽指令賦予一個(gè)符號(hào)名;也可給某些符號(hào)取新的名字并賦予新的類型屬性。符號(hào)定義語句不占用內(nèi)存。(1)等值語句EQU格式:<符號(hào)名>EQU<表達(dá)式>表達(dá)式可以是數(shù)值、地址、新類型屬性或其它符號(hào)名,

EQU將左邊的符號(hào)名賦給表達(dá)式,使它們完全等價(jià)。在程序中可方便地用符號(hào)名代替表達(dá)式。例:

PORT1EQU20HPORT2EQUPROT1+1BUF_SIZEEQUPORT2*2COUNTEQUCX;COUNT代表CX寄存器

B8EQU[BP+8];B8代表地址引用[BP+8]CHAREQU‘C’CBDEQUDAA;CBD代表指令助記符DAA

…DECCOUNT;將CX寄存器內(nèi)容減1第27頁/共123頁3.符號(hào)定義語句(續(xù))(2)等號(hào)語句=等號(hào)語句功能與EQU語句相同,但是等號(hào)語句定義的符號(hào)名在程序中可重新定義,并且表達(dá)式只能是數(shù)值表達(dá)式。例:

DAT=100 ;DAT定義為100 COUNT=DAT+10 ;COUNT定義為110 LLP=3 ┆ COUNT=COUNT-20 ;重新定義COUNT為90 DAT=200 ;重新定義DAT為200LABLE可定義新的符號(hào)并賦予不同的屬性;THIS、PTR可和EQU、=等偽指令連用,賦給新定義的符號(hào)以不同的屬性。第28頁/共123頁4.常量

常量又叫常數(shù),在匯編時(shí)有確定的值,一般在程序執(zhí)行過程中不再改變。常量主要用于偽指令語句中給變量賦值,也用做指令中的立即數(shù)或存儲(chǔ)器操作數(shù)的組成部分。常量可用數(shù)值形式直接寫在指令語句中,也可預(yù)先為它定義一個(gè)名字保存在存儲(chǔ)單元內(nèi)。數(shù)值常量——常用作語句操作數(shù)項(xiàng)中的常數(shù),可以是二、八、十六或十進(jìn)制數(shù),分別在數(shù)值末尾加“B”、“Q”(或“O”)、“H”和“D”標(biāo)記。

數(shù)尾不加標(biāo)記的,匯編程序默認(rèn)作十進(jìn)制數(shù)。偽指令RADEX可以把默認(rèn)的基數(shù)改變?yōu)?~16范圍內(nèi)的任何基數(shù):.RADIX<基數(shù)表達(dá)式>其中基數(shù)表達(dá)式的結(jié)果為2~16之間的十進(jìn)制整數(shù),用來表示基數(shù)值。下面兩組指令是等價(jià)的:

MOVBX,0FFH .RADIX16MOVCX,178 MOVBX,0FF MOVCX,178D第29頁/共123頁4.常量(續(xù))字符常數(shù)

是保存在單引號(hào)或雙引號(hào)內(nèi)的ASCII字符串。

定義多于2個(gè)字符的字符常數(shù),必須用DB偽指令;

僅有1或2個(gè)字符,用偽指令DW、DD、DQ、DT都行。浮點(diǎn)常數(shù)

用十進(jìn)制數(shù)科學(xué)計(jì)數(shù)法表示,如

SINEDD0.538E-1。十六進(jìn)制實(shí)常數(shù)

與十六進(jìn)制常數(shù)相似,但第一個(gè)字符必須是數(shù)字(0~9),數(shù)尾緊跟字母R,而且其位數(shù)必須是8、16或20。

HRNUMBDD0BAEF1234R5.表達(dá)式和運(yùn)算符

表達(dá)式:用運(yùn)算符連接變量、標(biāo)號(hào)、常量等數(shù)據(jù)形式的式子。

表達(dá)式可作為語句中的數(shù)據(jù)項(xiàng),由宏匯編程序進(jìn)行計(jì)算,將所得結(jié)果作為指令的操作數(shù),執(zhí)行指令所規(guī)定的操作。

表達(dá)式的計(jì)算在匯編時(shí)完成,指令的運(yùn)算在程序執(zhí)行過程中完成。表達(dá)式的結(jié)果是一個(gè)數(shù)值則稱為數(shù)值表達(dá)式,結(jié)果是一個(gè)存儲(chǔ)單元的地址時(shí)則稱為地址表達(dá)式。地址單元中存放的是數(shù)據(jù)則稱為變量,地址單元中存放的是指令則稱為標(biāo)號(hào)。第30頁/共123頁MASM宏匯編程序中的表達(dá)式由操作符和操作對(duì)象組成,允許使用的操作符有六種類型,可進(jìn)行算術(shù)運(yùn)算、邏輯運(yùn)算、關(guān)系運(yùn)算、回送運(yùn)算、修改類型屬性運(yùn)算與專用運(yùn)算等。如下表所示。第31頁/共123頁MASM對(duì)方括號(hào)的地址表達(dá)式有如下的規(guī)定:①只有基址寄存器BX、基址指針BP、變址寄存器SI和DI可以出現(xiàn)在[]內(nèi)。②BX或BP可單獨(dú)出現(xiàn)在[]內(nèi),也可單獨(dú)與SI或DI以及常數(shù)一起出現(xiàn)在[]內(nèi);但BX和BP不允許同時(shí)出現(xiàn)在[]內(nèi)。③SI或DI可單獨(dú)出現(xiàn)在[]內(nèi),也可單獨(dú)與BX或BP以及常數(shù)一起出現(xiàn)在[]內(nèi);但SI和DI不允許同時(shí)出現(xiàn)在[]內(nèi)。④一個(gè)[]內(nèi)含基址和變址寄存器時(shí),它們只能做加法運(yùn)算;相加的基址和變址寄存器可以寫在兩個(gè)相鄰的[]內(nèi)。⑤當(dāng)[]內(nèi)包含基址指針BP時(shí),約定的段基址由堆棧段寄存器SS提供,否則均隱含使用數(shù)據(jù)段寄存器DS。⑥相加的常數(shù)可以寫在[]之外。⑦方括號(hào)內(nèi)還可以是表達(dá)式,其值表示數(shù)組變量的下標(biāo)。第32頁/共123頁5.2.3結(jié)構(gòu)化數(shù)據(jù)定義

MASM宏匯編還支持有關(guān)結(jié)構(gòu)、記錄、聯(lián)合等有結(jié)構(gòu)的數(shù)據(jù)類型。1.結(jié)構(gòu)定義語句結(jié)構(gòu)是指一組相互關(guān)聯(lián)變量的組合,例如學(xué)生成績(jī)登記表中一個(gè)學(xué)生所登錄的各項(xiàng):學(xué)號(hào)、姓名、性別、課程名稱、考試成績(jī)等。

結(jié)構(gòu)類型變量可把類似上述一個(gè)學(xué)生的各項(xiàng)看成一個(gè)整體,定義、賦值、修改、引用都大為方便。

(1)結(jié)構(gòu)類型的定義格式:<結(jié)構(gòu)類型名>STRUC

…{數(shù)據(jù)定義偽指令序列} <結(jié)構(gòu)類型名>ENDS 例:為學(xué)生考試成績(jī)登記表定義一個(gè)結(jié)構(gòu)

STUDTABSTRUC NAME DB'WANGWEIHUA' ;姓名

SNO DD20020923H ;學(xué)號(hào)

SEX DB1 ;性別:0為女,1為男

COURSE DB'ASSEMBLER' ;課程名

SCORE DB90 ;成績(jī)

STUDTABENDS第33頁/共123頁(2)結(jié)構(gòu)變量的說明

格式:[結(jié)構(gòu)變量名]<結(jié)構(gòu)類型名><<[字段初值表]>>其中結(jié)構(gòu)變量名由用戶起,是可選項(xiàng),沒有它匯編程序照樣分配空間。結(jié)構(gòu)類型名是已定義的結(jié)構(gòu)類型;<字段初值表>用來給結(jié)構(gòu)變量的字段賦初值,它們的類型、順序必須與結(jié)構(gòu)類型名定義的一致,各初值之間以逗號(hào)隔開。

若某字段的初值采用結(jié)構(gòu)類型定義時(shí)的初值,可空缺不寫(但相應(yīng)逗號(hào)不可省),若所有字段全部采用定義時(shí)的初值,可只寫一個(gè)尖括號(hào)<>;

尖括號(hào)<>在任何時(shí)候都不可省。 例:利用已定義的STUDTAB結(jié)構(gòu)類型說明考試成績(jī)登記表中某學(xué)生的結(jié)構(gòu)變量。

STUDENT1STUDTAB<>;各字段初值全部采用結(jié)構(gòu)類型定義時(shí)的初值

STUDENT2STUDTAB<'ZHANGMING',20010907H,0,'PASCAL',85> ;各字段初值重新賦值

STUDENT3STUDTAB<'LIWEIDONG',20020918H,,'ENGLISH',> ;性別和成績(jī)字段采用結(jié)構(gòu)定義時(shí)的初值;

;下面說明一個(gè)50個(gè)學(xué)生的結(jié)構(gòu)數(shù)組,各字段初值采用結(jié)構(gòu)類定義時(shí)的初值。

CLASS2STUDTAB50DUP(<>)第34頁/共123頁(3)結(jié)構(gòu)變量字段值的修改

定義結(jié)構(gòu)類型時(shí)可為各字段設(shè)置初值,說明結(jié)構(gòu)變量時(shí)可對(duì)字段初值進(jìn)行修改,使用結(jié)構(gòu)變量時(shí)仍可對(duì)它們各個(gè)字段進(jìn)行修改。只有用DB、DW或DD加以說明的單項(xiàng)字段才能被修改字段值,

而用重復(fù)運(yùn)算符DUP說明的多重字段不能被修改。

對(duì)字符串類型的字段,修改后串的長(zhǎng)度不能超過定義結(jié)構(gòu)類型時(shí)的長(zhǎng)度。(4)結(jié)構(gòu)的使用結(jié)構(gòu)類型定義在先,一般定義在程序的開始部分,也可定義在數(shù)據(jù)段中;結(jié)構(gòu)變量說明在后,通常在數(shù)據(jù)段中加以說明;

最后在代碼段中對(duì)結(jié)構(gòu)變量及其字段加以引用,包括對(duì)它們的值進(jìn)行修改。對(duì)結(jié)構(gòu)變量的引用,與引用其它變量一樣,可以通過名字對(duì)結(jié)構(gòu)變量進(jìn)行存取。要引用結(jié)構(gòu)變量中的字段,可使用點(diǎn)運(yùn)算符,形式為:結(jié)構(gòu)變量名.結(jié)構(gòu)字段名例:取出結(jié)構(gòu)變量的字段MOVAL,STUDENT2.SCORE;取出學(xué)生結(jié)構(gòu)變量STUDENT2的成績(jī)字段值送AL下面兩條指令完成的操作與上面一條指令相同:

MOVBX,OFFSETSTUDENT2 MOVAL,[BX].SCORE第35頁/共123頁2.記錄定義語句

記錄用于處理按二進(jìn)制數(shù)位計(jì)算的數(shù)據(jù)信息。使用記錄,需要先定義記錄類型,再說明記錄變量,然后再使用記錄。(1)定義記錄類型格式:<記錄名>RECORD<字段名>:<寬度>[=表達(dá)式][,<字段名>:<寬度>…]

記錄名與字段名由用戶起,程序中記錄名不允許重名,同一記錄內(nèi)字段名不允許重名。寬度必須是常數(shù),表示該字段所占二進(jìn)位的位數(shù);表達(dá)式為可選項(xiàng),表示該字段的初值,未選時(shí)初值為0。一個(gè)記錄中可有多個(gè)字段,它們之間用逗號(hào)隔開。16位微處理器方式,所有字段寬度之和不得超過16。寬度之和超過8時(shí)占用2個(gè)字節(jié),匯編程序按字處理,否則按字節(jié)處理。若選用了386及以上方式,各字段寬度之和最多可達(dá)32;超過16位時(shí),占用4個(gè)字節(jié),按雙字存放和處理。例:定義一個(gè)表示學(xué)生情況的記錄,年齡占6位,性別占1位(0女,1男),健康狀況占一位(0健康,1不健康)

STATUSRECORDAGE:6=19,SEX:1,HEALTH:1 與結(jié)構(gòu)一樣,記錄類型定義時(shí)不分配存儲(chǔ)空間。(2)記錄變量說明格式:[記錄變量名]<記錄名><<[字段初值表]>>

記錄變量名由用戶定義,可以省略(照樣分配內(nèi)存),記錄名是已定義的記錄類型,字段初值表給各字段賦初值,各初值之間用逗號(hào)隔開,各項(xiàng)的順序應(yīng)與記錄類型定義時(shí)的順序一致;若某字段值采用記錄類型定義時(shí)的初值,則可省略,僅寫逗號(hào)即可;若全部字段都采用定義時(shí)的初值,則僅寫尖括號(hào)。尖括號(hào)在任何時(shí)刻都不能省略。第36頁/共123頁2.記錄定義語句(續(xù))例:用記錄類型STATUS定義記錄變量

ZHANG1STATUS<17,1,0> 被分配一個(gè)字節(jié)的記錄變量ZHANG1在內(nèi)存中的分配形式為01011110,即該記錄變量的值為5EH。

WANG3STATUS<,0,0> WANG3記錄變量前6位為011001(記錄類型定義的初值),后兩位為00,該記錄值為64H。STUDEN1STATUS<> 記錄變量STUDENT1為一個(gè)字節(jié),各字段值采用記錄類型定義時(shí)的初值,為67H。CLASS1STATUS50DUP(<18,1,0>) CLASS1是個(gè)記錄數(shù)組,共有50個(gè)元素,每個(gè)元素的三個(gè)字段初值分別為18、1、0,記錄值為62H。(3)記錄的使用可通過記錄變量名對(duì)記錄進(jìn)行訪問,記錄變量名可以像其它變量名一樣使用。 例: MOVAL,ZHANG1 ;AL←5EH(ZHANG1記錄的值)記錄變量可作為操作數(shù)(立即數(shù))使用。 例:MOVAH,STATUS<18,1,0> ;AH←62H記錄的字段名可在程序中直接使用,表示一個(gè)位移量,即該字段位移到記錄的最低位所需的移位次數(shù)。 例:MOVCL,SEX ;CL←1(SEX移到記錄最低位的次數(shù))第37頁/共123頁2.記錄定義語句(續(xù))給記錄變量(或記錄數(shù)組元素)的某字段賦值時(shí)不應(yīng)破壞其余字段上的值,先用AND指令對(duì)該字段清0,再用OR指令將相應(yīng)值設(shè)置在該字段上。對(duì)記錄數(shù)組元素的尋址與一般的字節(jié)、字或雙字的數(shù)組一樣,而對(duì)記錄數(shù)組元素的某一字段訪問與對(duì)記錄變量的字段訪問類似,只是將記錄變量名換為記錄數(shù)組元素的地址表達(dá)式。

例:把前面說明的記錄數(shù)組CLASS1的第三個(gè)元素的AGE字段設(shè)為18??上热〉玫谌齻€(gè)元素的起始地址,取出該元素字節(jié)值,將AGE字段清0,然后將字段值18送一個(gè)寄存器,并移位到高6位,再用OR指令置成相應(yīng)值。指令序列如下:

MOVSI,OFFSETCLASS1 ;記錄數(shù)組的起始地址送SI ADDSI,2 ;生成第三個(gè)元素的起始地址

MOVAL,[SI] ;AL←第三個(gè)元素的字節(jié)值

ANDAL,03H ;將AGE字段清0

MOVAH,18 ;AH←18 MOVCL,AGE ;CL←移位次數(shù)2

SHLAH,CL ;AH左移2位,使18與AGE字段對(duì)齊

ORAL,AH ;將18置在AGE字段上

MOV[SI],AL ;將修改后的結(jié)果送回第三個(gè)單元

第38頁/共123頁3.聯(lián)合定義語句

聯(lián)合UNION也是一種結(jié)構(gòu)性的數(shù)據(jù)類型,是MASM6.0新增的,實(shí)際上是對(duì)結(jié)構(gòu)STRUC的一個(gè)補(bǔ)充。(1)聯(lián)合類型定義格式:<聯(lián)合名>UNION

┆{聯(lián)合體,由數(shù)據(jù)定義語句構(gòu)成} <聯(lián)合名>ENDS

該語句定義了一個(gè)聯(lián)合類型,與STRUC類似,聯(lián)合體中的各字段由數(shù)據(jù)定義偽指令設(shè)置,但各字段的偏移地址與STRUC不一樣:STRUC中的字段在結(jié)構(gòu)中順序分配,而UNION中的字段在聯(lián)合中從起始地址處重疊分配,所以聯(lián)合中各個(gè)字段的偏移地址均為0。因此定義聯(lián)合時(shí)字段不賦初值。定義UNIMING的聯(lián)合類型: UNIMING UNION XA DB? XB DB? XC DW? XD DD? UNIMING ENDS第39頁/共123頁(2)聯(lián)合變量說明

格式: <變量名><聯(lián)合名><<字段值表>> 字段值表須用尖括號(hào)<…>括起來,有關(guān)規(guī)定與結(jié)構(gòu)變量相同。 定義一個(gè)聯(lián)合變量,分配存儲(chǔ)空間并給它的各個(gè)字段賦初值。 例:定義聯(lián)合變量

BIANLUNIMING<12345678H>后,

它的各個(gè)字段值如下:BIANL.XA=78HBIANL.XB=78H

BIANL.XC=5678HBIANL.CD=12345678H對(duì)聯(lián)合變量的字段訪問可用:聯(lián)合變量名.字段名。結(jié)構(gòu)和聯(lián)合的定義可互相嵌套,這類定義適用于面向?qū)ο蟪绦蛟O(shè)計(jì)的結(jié)構(gòu)和I/O端口的描述。

第40頁/共123頁5.2.4其它匯編技術(shù)

1.重復(fù)匯編重復(fù)匯編偽指令又稱重復(fù)塊偽指令,用來縮寫若干重復(fù)的語句,以便重復(fù)進(jìn)行多次。重復(fù)塊可看著是宏展開的一種特殊形式,在匯編時(shí)展開。重復(fù)塊也可帶有形式參數(shù),在匯編過程中被實(shí)際參數(shù)代替;但重復(fù)塊沒有名字,不能進(jìn)行調(diào)用,只在原處重復(fù)若干次。重復(fù)塊偽指令共有三種:REPT、FOR(或IRP)和FORC(或IRPC),它們都用ENDM偽指令來結(jié)束,區(qū)別只是設(shè)置重復(fù)次數(shù)的方法不同;括弧中的偽指令名字是MASM5.X版本中使用的,在后續(xù)版本中仍可使用。(1)按參數(shù)值重復(fù)匯編 格式:

REPT<表達(dá)式>

…{重復(fù)的語句序列}

ENDM 其中表達(dá)式的值為REPT與ENDM之間的語句序列重復(fù)展開的次數(shù)。例:

TABLELABLEBYTE ;等價(jià)于

TABLELABLEBYTEX=0 ;DB1REPT5 ;DB2X=X+1 ;DB3DBX ;DB4ENDM ;DB5第41頁/共123頁1.重復(fù)匯編(續(xù))(2)按參數(shù)個(gè)數(shù)重復(fù)匯編 格式:

FOR(或IRP)<形式參數(shù)>,<<實(shí)際參數(shù)表>>

…{重復(fù)的語句序列}

ENDM FOR(或IRP)與ENDM之間的語句對(duì)每個(gè)實(shí)際參數(shù)都執(zhí)行一次,重復(fù)次數(shù)為實(shí)際參數(shù)的個(gè)數(shù),實(shí)際參數(shù)必須用尖括弧括起來,在執(zhí)行過程中用當(dāng)前的實(shí)際參數(shù)去代替形式參數(shù)。 例

TABLELABELBYTE IRP X,<1,2,3,4,5>DB XENDM該段程序與上例是等價(jià)的。第42頁/共123頁1.重復(fù)匯編(續(xù))(3)按參數(shù)字符個(gè)數(shù)重復(fù)匯編 格式:

FORC(或IRPC)<形式參數(shù)>,<字符串>或<<字符串>>

…{重復(fù)的語句序列}

ENDM 重復(fù)執(zhí)行FORC(或IRPC)與ENDM之間的語句,每次都用當(dāng)前字符中的字符去取代形式參數(shù),重復(fù)的次數(shù)為字符串中字符的個(gè)數(shù)。如果字符串中包括空格、逗號(hào)或其它分隔符,則字符串必須用尖括號(hào)括起來。例:

TABLELABELBYTE IRPCX,12345 DBX ENDM該程序段與前2例是等價(jià)的。第43頁/共123頁2.條件匯編

條件匯編偽指令可根據(jù)條件對(duì)源程序塊有選擇地進(jìn)行匯編,從而把某段指令序列包含在匯編語言源程序內(nèi),或者不對(duì)某段指令序列進(jìn)行匯編。格式:

IF<條件> <語句序列1> [ELSE <語句序列2>]

ENDIF其中條件是偽指令助記符的一部分,

ELSE語句及其后的語句序列2是可選部分,

條件為真執(zhí)行語句序列1,

為假執(zhí)行語句序列2或者ENDIF之后的語句。

整個(gè)條件匯編以語句ENDIF結(jié)束。匯編條件有六組,見下表。

第44頁/共123頁第45頁/共123頁3.宏匯編

對(duì)程序中多次重復(fù)使用的指令序列,可給它取個(gè)名字,定義成一個(gè)宏,在源程序中書寫宏名就代表這個(gè)指令序列。匯編時(shí)把宏名展開成該指令序列,從而減少了程序的編寫量,使源程序更加簡(jiǎn)練、清晰。(1)宏定義格式:<宏名>MACRO[形式參數(shù)表]

…{宏體}

ENDM宏名必須唯一,宏調(diào)用時(shí)用來代替所定義的宏體(具體內(nèi)容),宏體由匯編語言所允許的任何語句(指令或偽指令)組成,它決定了宏的功能。

形式參數(shù)根據(jù)宏體需要可以沒有,或者有一個(gè)或多個(gè);有多個(gè)形式參數(shù)時(shí)相互之間要用逗號(hào)或空格或制表符分隔開。

調(diào)用宏時(shí)要依次用對(duì)應(yīng)的實(shí)參去取代。宏體中可以定義或調(diào)用另一個(gè)宏。定義一個(gè)宏,相當(dāng)于增加了一條偽指令,匯編時(shí)告訴匯編程序用宏體來代替該名字。宏要先定義,后調(diào)用。宏定義一般放在源程序文本的開始處,而不放在某一個(gè)段內(nèi)。第46頁/共123頁3.宏匯編(續(xù))例:定義一個(gè)宏,參數(shù)為0時(shí)執(zhí)行輸入的DOS功能調(diào)用,否則執(zhí)行輸出的DOS功能調(diào)用。

INOUTMACROP IFP MOVAH,2 INT21H;輸出DL中的字符

ELSE MOVAH,1INT21H;輸入的字符送ALENDIF ENDM第47頁/共123頁3.宏匯編(續(xù))(2)宏的調(diào)用與展開格式:<宏名>[實(shí)際參數(shù)表] 宏名必須是已定義的,實(shí)際參數(shù)表中參數(shù)的類型和順序應(yīng)與宏定義時(shí)的形式參數(shù)一一對(duì)應(yīng);實(shí)參個(gè)數(shù)多于形參時(shí),多余的實(shí)參被忽略;實(shí)參個(gè)數(shù)少于形參的,多余的形參用空串取代。匯編源程序時(shí),匯編程序要對(duì)源程序中所有的宏調(diào)用進(jìn)行展開,即將宏名所定義的指令序列插入到宏調(diào)用處。宏與子程序(即過程)有所不同。宏調(diào)用是把宏體展開,程序中有幾處宏調(diào)用就展開幾次,源程序代碼長(zhǎng),不節(jié)省存儲(chǔ)空間,但展開后執(zhí)行速度快,節(jié)省運(yùn)行時(shí)間;子程序調(diào)用不展開子程序代碼(子程序仍存儲(chǔ)在原處),但改變程序流程,由主程序調(diào)用處轉(zhuǎn)入子程序去執(zhí)行,執(zhí)行完畢再返回主程序調(diào)用處繼續(xù)執(zhí)行,子程序調(diào)用前后要保護(hù)和恢復(fù)現(xiàn)場(chǎng),因此執(zhí)行時(shí)間長(zhǎng),但節(jié)省存儲(chǔ)空間。第48頁/共123頁3.宏匯編(續(xù))(3)宏操作符

宏匯編程序MASM提供了相應(yīng)的宏操作符,用于宏參數(shù)的傳遞連接,如下表所示。(4)宏的刪除PURGE當(dāng)宏在程序中調(diào)用完之后而再也用不到時(shí),可用PURGE偽指令刪除之,以釋放它所占用的存儲(chǔ)空間。格式:PURGE<宏名>[,宏名…]第49頁/共123頁3.宏匯編(續(xù))(5)宏庫(kù)為避免重復(fù)定義的麻煩,可將通用的宏定義集中放在一個(gè)單獨(dú)的文件中,即放在后綴為.MAC的宏庫(kù)文件中,宏庫(kù)中可以有多個(gè)宏定義。可用任一個(gè)編輯程序像建立源程序那樣來建立宏庫(kù)。宏庫(kù)中的宏必須是通用的例行程序或程序段,對(duì)宏中使用的寄存器及狀態(tài)標(biāo)志要入棧保存,宏定義中的標(biāo)號(hào)要先用Local偽指令定義(限定只在宏內(nèi)使用)。在程序中可用INCLUDE偽指令將宏庫(kù)中的宏定義復(fù)制到該指令所在的位置:

INCLUDE[盤符:\路徑\]<文件名>[.擴(kuò)展名]

INCLUDE功能是通知匯編程序把指定的文件拷貝一份,插入到該語句下方,供匯編使用。如INCLUDEMLIB.MAC語句將宏庫(kù)中MLIB.MAC的全部宏定義復(fù)制出來。

一般INCLUDE偽指令也放在源程序的開始部分。為避免匯編程序兩次掃描都去重復(fù)讀宏庫(kù)文件,可用條件匯編IF1使宏庫(kù)文件只在第一遍掃描時(shí)讀入:

IF1 INCLUDEMLIB.MAC ENDIF

…第50頁/共123頁5.3匯編語言程序上機(jī)過程

匯編語言程序上機(jī)運(yùn)行的過程有以下幾個(gè)步驟:(1)

用編輯程序建立.ASM源文件;(2)

用宏匯編程序MASM等匯編源文件,生成.OBJ目標(biāo)碼文件;(3)

用連接程序LINK對(duì)目標(biāo)碼文件等模塊進(jìn)行連接,生成.EXE可執(zhí)行文件;(4)

鍵入可執(zhí)行文件名執(zhí)行該文件,分析執(zhí)行結(jié)果;(5)用DEBUG等工具調(diào)試.ASM源程序,再匯編、連接、運(yùn)行,直到得出正確結(jié)果。 為此,除了DOS系統(tǒng)軟件和編輯程序外,還需要備置如下程序:匯編程序

masm.exe或asm.exe或tasm.exe等連接程序

link.exe或tlink.exe等匯編調(diào)試程序

等交叉引用程序

cref.exe等

第51頁/共123頁5.3.1編輯源程序

可使用任何一種能建立ASCII文本文件的編輯程序來建立匯編源程序文件,擴(kuò)展名為.ASM。在使用各種文字編輯程序時(shí),被編輯的源文件(.ASM)中不應(yīng)有排版格式控制符。5.3.2匯編源程序編輯生成的.ASM源程序文件,須經(jīng)匯編程序進(jìn)行匯編,生成二進(jìn)制代碼的目標(biāo)文件。常見的匯編程序有行匯編和宏匯編兩種類型。

◆行匯編——常用DEBUG.EXE的A命令,生成的目標(biāo)代碼可作為.COM

文件存盤,也可在DEBUG環(huán)境下直接運(yùn)行。

行匯編簡(jiǎn)單直觀,生成的目標(biāo)程序所占用的內(nèi)存空間最??;但匯編按

絕對(duì)地址進(jìn)行,長(zhǎng)度限制在64KB范圍內(nèi),目標(biāo)程序沒有與其它程序模

塊連接的信息,要由用戶或安裝程序?qū)崿F(xiàn)各個(gè)目標(biāo)程序在內(nèi)存中的地

址分配,這樣既可能使各程序之間產(chǎn)生太大的空隙(造成浪費(fèi))、也

可能造成各程序的內(nèi)存存儲(chǔ)沖突。

◆宏匯編MASM——對(duì)匯編語言源程序*.ASM進(jìn)行匯編常用方法。第52頁/共123頁5.3.2匯編源程序(續(xù))對(duì)早期版本的宏匯編程序,在DOS操作系統(tǒng)提示符下鍵入MASM后,MASM宏匯編程序被調(diào)入運(yùn)行。屏幕上顯示版本信息之后,對(duì)需要輸入輸出的4個(gè)文件提問如下:

sourcefilename[.ASM]:EXAMobjectfilename[EXAM.OBJ]:Sourcelisting[NUL.LST]:EXAMCross-reference[NUL.CRF]:EXAM第一個(gè)詢問的是被匯編的源程序文件名,鍵入文件名(這里為EXAM,不必鍵入后綴),MASM即對(duì)其進(jìn)行匯編。匯編過程會(huì)產(chǎn)生三個(gè)文件,第一個(gè)是擴(kuò)展名為.OBJ的目標(biāo)文件,這是匯編的主要目的,在提示詢問后面直接按回車表示同意采用方括號(hào)內(nèi)的缺省文件名,否則鍵入目標(biāo)文件的新名字后再按回車。產(chǎn)生的第二個(gè)文件是擴(kuò)展名為.LST的列表文件。列表文件可不要,若不要?jiǎng)t在提示詢問后面直接按回車鍵,否則鍵入列表文件名(后綴不必鍵入)后再按回車。

.LIST列表文件是個(gè)文本文件,有兩部分:源程序列表和符號(hào)名表。

第一部分對(duì)源程序中的每條語句從左到右依次列出:段內(nèi)偏移地址、機(jī)器代碼、指令助記符;程序中若有語法錯(cuò)誤,則列出錯(cuò)誤信息。

第二部分列出程序中所定義的全部標(biāo)識(shí)符信息,如段的名稱、長(zhǎng)度,變量和標(biāo)號(hào)的名稱、類型、偏移地址等。這一文件可打印出來供檢查用。第53頁/共123頁5.3.2匯編源程序(續(xù))匯編產(chǎn)生的第三個(gè)文件是擴(kuò)展名為.CRF的交叉引用文件,也是可要可不要,回答的辦法同第二個(gè)列表文件。交叉引用文件是個(gè)二進(jìn)制文件,須經(jīng)交叉引用程序CREF將其轉(zhuǎn)換成交叉引用列表文件(后綴為.REF的ASCII文本文件)后方可顯示輸出,轉(zhuǎn)換方法為:

C:>CREF<文件名> 轉(zhuǎn)換后的交叉引用列表文件按字母順序列出了源程序中使用的所有符號(hào)的列表。4個(gè)問題回答完畢,MASM就對(duì)源程序進(jìn)行匯編。匯編中若發(fā)現(xiàn)源程序有語法錯(cuò)誤則列出錯(cuò)誤的語句和錯(cuò)誤的代碼,指出是什么性質(zhì)的錯(cuò)誤。最后列出警告錯(cuò)誤(WarningErrors)和嚴(yán)重錯(cuò)誤(SevereErrors)的總數(shù)。MASM軟件有許多版本,現(xiàn)在常用的MASM6.X功能很強(qiáng),包含有許多文件,最常用的是:匯編器ML.EXE、連接器

LINK.EXE、調(diào)試器CV.EXE等。匯編器ML.EXE(MasmandLink)能自動(dòng)調(diào)用LINK,實(shí)現(xiàn)對(duì)源程序的匯編和連接。使用ML命令進(jìn)行匯編連接的格式如下:ML[/<選項(xiàng)>…]<源文件列表>[/<連接選項(xiàng)>…]第54頁/共123頁5.3.2匯編源程序(續(xù))<源文件列表>中的多個(gè)文件以空格分隔,文件名必須完整,擴(kuò)展名.ASM不能省略;ML后的參數(shù)對(duì)大小寫

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 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)論