微機(jī)原理第三章魏課件_第1頁(yè)
微機(jī)原理第三章魏課件_第2頁(yè)
微機(jī)原理第三章魏課件_第3頁(yè)
微機(jī)原理第三章魏課件_第4頁(yè)
微機(jī)原理第三章魏課件_第5頁(yè)
已閱讀5頁(yè),還剩130頁(yè)未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

第三章匯編語言程序設(shè)計(jì)概述匯編語言:匯編語言是一種面向計(jì)算機(jī)的符號(hào)語言。用指令的助記符、符號(hào)地址、標(biāo)號(hào)、偽指令等書寫程序的語言。匯編語言源程序:用匯編語言書寫的源程序。匯編:將匯編語言源程序翻譯成機(jī)器語言程序的過程。匯編程序:完成匯編過程的系統(tǒng)程序。ASM和MASM

3.1匯編語言的基本元素在8086/8088匯編語言中,有兩類匯編語言指令。?一類是執(zhí)行性指令,稱為指令語句,匯編程序匯編后可產(chǎn)生機(jī)器指令代碼;?另一類是指示性語句,稱為偽指令,其作用僅僅是告訴匯編程序?qū)υ闯绦蛑械膱?zhí)行性指令應(yīng)該如何產(chǎn)生代碼,或分配存儲(chǔ)區(qū)。1.標(biāo)號(hào)(標(biāo)識(shí)符Identifiers)

標(biāo)識(shí)符是由程序員定義的具有特定意義的字符序列,是給指令或某一存儲(chǔ)單元地址所起的名字。標(biāo)識(shí)符可由下列字符組成:

字母:A~z;數(shù)字:0~9;特殊字符:?、·、@、_、$。標(biāo)識(shí)符最多為31個(gè)字符。數(shù)字不能作標(biāo)識(shí)符的第一個(gè)字符。當(dāng)標(biāo)識(shí)符后跟冒號(hào)時(shí),表示是標(biāo)號(hào)。它代表該行指令的起始地址。當(dāng)標(biāo)識(shí)符后不帶冒號(hào)時(shí),表示變量。偽指令前的標(biāo)識(shí)符不加冒號(hào)。

[標(biāo)號(hào)]指令助記符[操作數(shù)][;注釋]2.指令助記符

(保留字Reservedwords)

是一類特殊的標(biāo)識(shí)符,可以是8086/8088的指令助記符,也可以是偽指令。如果指令帶有前綴(如LOCK、REP、REPE/REPZ、REPNE/REPNZ),則指令前綴和指令助記符要用空格分開。

[標(biāo)號(hào)]

指令助記符

[操作數(shù)][;注釋]

3.操作數(shù)

指令執(zhí)行的對(duì)象。例如:RET;無操作數(shù)

INCCX;一個(gè)操作數(shù)

MOVCX,DI;兩個(gè)操作數(shù)如果是偽指令,則可能有多個(gè)操作數(shù),例如:

COSTDB3,4,5,6,7;5個(gè)操作數(shù)當(dāng)操作數(shù)超過1個(gè)時(shí),操作數(shù)之間應(yīng)用逗號(hào)分開。操作數(shù)可以是常數(shù)、寄存器名、標(biāo)號(hào)、變量,也可以是表達(dá)式,例如:MOVAX,[BP+4];

[標(biāo)號(hào)]指令助記符[操作數(shù)][;注釋]3.1.2匯編語言的運(yùn)算符匯編語言運(yùn)算符所指定的操作由匯編程序在匯編過程中完成,結(jié)果作為指令的目標(biāo)代碼被保存,與程序執(zhí)行時(shí)CPU完成的可執(zhí)行指令是兩回事,故匯編語言運(yùn)算符也稱為偽操作符。匯編語言的運(yùn)算符有:

?算術(shù)運(yùn)算符:+、–、×、/、MOD(取余數(shù));?邏輯運(yùn)算符:AND、OR、NOT、XOR;?關(guān)系運(yùn)算符:EQ、NE、LT、GT、LE、GE;?取值運(yùn)算符和屬性運(yùn)算符。1.算術(shù)運(yùn)算符和邏輯運(yùn)算符(1)

算術(shù)運(yùn)算符:

+、–、×、/、MOD算術(shù)運(yùn)算符只能用于數(shù)字量操作數(shù),結(jié)果也是數(shù)字量。用于存儲(chǔ)器操作數(shù)時(shí),只有+、-運(yùn)算符有意義。MOD取模是求數(shù)字量除法所得的余數(shù)。(2)

邏輯運(yùn)算符:AND、OR、NOT、XOR邏輯運(yùn)算符的操作只能是數(shù)字的,且結(jié)果也是數(shù)字的。存儲(chǔ)器操作數(shù)不能進(jìn)行邏輯運(yùn)算。邏輯運(yùn)算作為運(yùn)算符時(shí),是在程序匯編時(shí)計(jì)算的;而作為指令助記符時(shí),則是在程序執(zhí)行時(shí)計(jì)算的。

2.關(guān)系運(yùn)算符

關(guān)系運(yùn)算符:EQ、NE、LT、GT、LE、GE;相等

EQ(Equal)、不等

NE(NotEqual)、小于

LT(LessThan)、大于

GT(GreaterThan)、小于等于

LE(LessThanorEqual)、大于等于

GE(GreaterThanorEqual)關(guān)系運(yùn)算符連接的兩個(gè)操作數(shù),必須都是數(shù)字的或是在同一段內(nèi)的存儲(chǔ)器地址。若關(guān)系為假(關(guān)系不成立),則結(jié)果為0H;若關(guān)系為真(關(guān)系成立),則結(jié)果為0FFFFH。

3.取值運(yùn)算符(分析運(yùn)算符)把存儲(chǔ)器地址操作數(shù)分解成它的組成部分。取值運(yùn)算符有:SEG、OFFSET、TYPE、SIZE和LENGTH?SEG

給出一個(gè)變量或標(biāo)號(hào)的段地址;

?OFFSET

給出一個(gè)變量或標(biāo)號(hào)的16位偏移量;

?TYPE

返回表示存儲(chǔ)器操作數(shù)內(nèi)存變量和標(biāo)號(hào)類型的數(shù)值。類型byteworddwordqwordtbyteNEARFAR類型值124810-1(FFH)-2(FEH)

?SIZE

取得并返回由DUP定義的內(nèi)存變量的字節(jié)數(shù)。

?LENGTH

取得并返回由DUP定義的內(nèi)存變量基本單元的個(gè)數(shù)。格式:SEG﹤符號(hào)名﹥OFFSET﹤符號(hào)名﹥TYPE﹤符號(hào)名﹥

SIZE﹤符號(hào)名﹥LENGTH﹤符號(hào)名﹥例如:MOVAX,SEGSLOT;將SLOT的段地址送入AX寄存器MOVAX,OFFSETSLOT;將SLOT的偏移地址送入AX寄存器,4.屬性運(yùn)算符(合成運(yùn)算符)

屬性運(yùn)算符用來給指令中的操作數(shù)指定一個(gè)臨時(shí)屬性,而暫時(shí)忽略當(dāng)前的屬性。

(1)合成運(yùn)算符PTR

忽略當(dāng)前操作數(shù)的類型(字節(jié)或字)及屬性(NEAR或FAR),而給出一個(gè)臨時(shí)的類型或?qū)傩?。一般格式如下:類?或?qū)傩?

PTR操作數(shù)表達(dá)式

PTR運(yùn)算符建立一個(gè)存儲(chǔ)器地址操作數(shù),它與PTR右邊的存儲(chǔ)器地址操作數(shù)有相同的段地址與偏移量,其類型由左邊的操作數(shù)決定。

(2)合成運(yùn)算符THIS

象PTR一樣可用來建立一個(gè)特殊類型的存儲(chǔ)器地址操作數(shù),新的存儲(chǔ)器地址操作數(shù)的段和偏移量部分就是下一個(gè)能分配的存儲(chǔ)單元的段和偏移量,即匯編程序進(jìn)行匯編遇到THIS時(shí)的當(dāng)前值。其類型在THIS運(yùn)算符后面指定。例如:

MY_BYTEEQUTHISBYTEMY_WORDDW?將建立MY_BYTE具有字節(jié)類型,且與MY_WORD具有相同的段和偏移量。(3)段取代運(yùn)算符

用于在一條指令中以新的段屬性取代舊的段屬性。有兩種格式:

段寄存器:地址表達(dá)式例如:ADDAX,ES:ALT

段名:地址表達(dá)式所用的段名事前必須通過ASSUME偽指令與一個(gè)段寄存器建立聯(lián)系。例如:

ASSUMEES:EXTRA_DATA

……ADD AX,EXTRA_DATA:ALT(4)短程運(yùn)算符SHORT

僅用于無條件轉(zhuǎn)移指令。指出轉(zhuǎn)移的標(biāo)號(hào)不僅是NEAR型的,并且是在下一條指令的-128~+127個(gè)字節(jié)范圍內(nèi)。運(yùn)算符SHORT事先對(duì)標(biāo)號(hào)作了說明,則會(huì)匯編成兩字節(jié)的轉(zhuǎn)移指令,既節(jié)省了單元又加快了執(zhí)行速度。例如:

JMPSHORTH2;H2:MOVAX,01.常數(shù)匯編語言語句中出現(xiàn)的常數(shù)有7種:①二進(jìn)制數(shù)二進(jìn)制數(shù)字后跟字母B,如01000001B。②八進(jìn)制數(shù)八進(jìn)制數(shù)字后跟字母Q或O,如202Q或202O。③十進(jìn)制數(shù)十進(jìn)制數(shù)字后跟D或不注,如85D或85。④十六進(jìn)制數(shù)十六進(jìn)制數(shù)字后跟H,如56H,0FFH。注意,當(dāng)數(shù)字的第一個(gè)字符是A~F時(shí),在字符前應(yīng)添加一個(gè)數(shù)字0,以示和變量的區(qū)別。

⑤十進(jìn)制浮點(diǎn)數(shù)浮點(diǎn)十進(jìn)制數(shù)如25E-2。⑥十六進(jìn)制實(shí)數(shù)十六進(jìn)制實(shí)數(shù)后跟R,

數(shù)字的位數(shù)必須是8,16或20。在第一位是0的情況下,數(shù)字的位數(shù)可以是9,17或21。如0FFFFFFFFR。

以上第⑤、⑥兩種數(shù)字格式只允許在MASM中使用。⑦字符和字符串字符和字符串要求用單引號(hào)括起來,如‘BD’。

2.常量操作數(shù)

常量操作數(shù)是一個(gè)數(shù)值操作數(shù),一般是常量或者是常量的標(biāo)識(shí)符。例如常量操作數(shù)有100,PORT,VAL等。數(shù)字常量操作數(shù)可采用二、八、十或十六進(jìn)制等形式。操作數(shù)值的允許范圍為-65536~+65535。字符串常量操作數(shù)值為相應(yīng)字符的ASCII碼。常量操作數(shù)是出現(xiàn)在程序中的確定值,它在程序的運(yùn)行期間不會(huì)發(fā)生變化。存儲(chǔ)器操作數(shù)作為存儲(chǔ)單元的地址,有三個(gè)屬性:(1)段地址:存儲(chǔ)單元所在段的段地址;(2)偏移地址:存儲(chǔ)單元在所在段內(nèi)的偏移地址;(3)類型:變量的類型是存儲(chǔ)單元所存放數(shù)據(jù)項(xiàng)的字節(jié)數(shù);

標(biāo)號(hào)的類型作為轉(zhuǎn)移或調(diào)用指令的目標(biāo)操作數(shù)的尋址方式,即NEAR和FAR。標(biāo)號(hào)的默認(rèn)類型屬性為NEAR。4.常量表達(dá)式

常量表達(dá)式通常由常量操作數(shù)及運(yùn)算符構(gòu)成,在匯編時(shí),產(chǎn)生一個(gè)常量。例如:PORT_VAL+1PORT_VALAND20H分析運(yùn)算符作用于存儲(chǔ)器操作數(shù)所形成的表達(dá)式也是常量表達(dá)式。例如:

OFFSETSUMSEGSUMTYPECYCLE

1.編寫源程序

用文本編輯程序EDIT.EXE或EDLIN編寫匯編語言源程序,產(chǎn)生擴(kuò)展名為.ASM的源文件。2.匯編

用匯編語言編寫的源程序經(jīng)過匯編程序MASM.EXE自動(dòng)翻譯成目標(biāo)程序,產(chǎn)生擴(kuò)展名為.OBJ的目標(biāo)文件;對(duì)源程序中使用了非法指令,標(biāo)號(hào)重復(fù),相對(duì)轉(zhuǎn)移超出轉(zhuǎn)移范圍等非邏輯性錯(cuò)誤給出提示。8086的匯編程序?yàn)锳SM-86,擴(kuò)展后的宏匯編程序?yàn)镸ASM-86,增加了宏處理功能、條件匯編及某些偽指令,且可支持8087協(xié)處理器的操作。匯編程序的主要功能是:1、將匯編語言源程序翻譯成機(jī)器語言代碼;2、按程序指定,分配存儲(chǔ)區(qū)域(包括程序區(qū),數(shù)據(jù)區(qū),堆棧區(qū)等);3、將各種進(jìn)位制數(shù)據(jù)轉(zhuǎn)換成二進(jìn)制數(shù);4、把字符轉(zhuǎn)換成ASCII碼;5、計(jì)算出數(shù)值表達(dá)式的值;6、對(duì)源程序進(jìn)行檢查,給出程序的語法錯(cuò)誤信息,如非法格式,未定義的助記符、標(biāo)號(hào)、漏掉操作數(shù)等。3.鏈接

用鏈接程序LINK.EXE將一個(gè)或多個(gè).OBJ目標(biāo)程序進(jìn)行鏈接,生成擴(kuò)展名為.EXE的可執(zhí)行程序。4.調(diào)試

經(jīng)過上述步驟所獲得的.EXE可執(zhí)行文件,在運(yùn)行過程中可能出現(xiàn)邏輯錯(cuò)誤,需對(duì)可執(zhí)行文件.EXE進(jìn)行調(diào)試。調(diào)試匯編程序最常用的工具是動(dòng)態(tài)調(diào)試程序DEBUG。其中從某地址運(yùn)行程序、設(shè)置斷點(diǎn)、單步跟蹤等功能,可以支持對(duì)程序的調(diào)試。

3.2偽指令

偽指令語句也稱為指示性語句,是用來對(duì)程序的匯編過程進(jìn)行控制,實(shí)現(xiàn)初始化存儲(chǔ)器、定義符號(hào)常數(shù)、列表、存儲(chǔ)空間分配等處理。根據(jù)功能的不同,偽指令可分為以下幾種類型:?數(shù)據(jù)定義偽指令?符號(hào)定義偽指令?段定義偽指令?過程定義偽指令?宏定義?模塊組織和多模塊連接3.2.1.?dāng)?shù)據(jù)定義偽指令該類偽指令用來定義存儲(chǔ)空間及其所存數(shù)據(jù)長(zhǎng)度。?DB:定義字節(jié),即每個(gè)數(shù)據(jù)是1個(gè)字節(jié);?DW:定義字,即每個(gè)數(shù)據(jù)占1個(gè)字(2個(gè)字節(jié));?DD:定義雙字,即每個(gè)數(shù)據(jù)占2個(gè)字。低字部分在低地址,高字部分在高地址;?DQ:定義4字長(zhǎng),即每個(gè)數(shù)據(jù)占4個(gè)字;?DT:定義10個(gè)字節(jié)長(zhǎng),用于壓縮式十進(jìn)制數(shù)。例:DATA1DB5,6,8,100,‘ABCD’表示從DATA1單元開始,連續(xù)存放5,6,8,100,共占4個(gè)字節(jié)地址。

DATA2DW7,287表示從DATA2單元開始,連續(xù)存放7,287兩個(gè)字,共占4個(gè)字節(jié)地址。定義一個(gè)存儲(chǔ)區(qū)時(shí),也可以不放數(shù)據(jù),如 TABLEDB?;表示在TABLE單元中存放的內(nèi)容是隨機(jī)的。05H06H08H64H41H42H43H44H07H00H1FH01H42H41H44H43HDATA1DATA2DATA1DB5,6,8,100,‘ABCD’DATA2DW7,287,‘AB’,‘CD’DATA3DD‘ABCD’,‘CD’44H43H42H41H44H43H00H00HDATA3

當(dāng)定義一個(gè)存儲(chǔ)區(qū)內(nèi)的每個(gè)單元要放置同樣的數(shù)據(jù)時(shí),可用DUP操作符,一般格式為:COUNTDUP(?);COUNT為重復(fù)的次數(shù),?為要重復(fù)的數(shù)據(jù)。如:BUFFERDB100DUP(0);表示以BUFFER為首地址的100個(gè)字節(jié)中存放00H

BUFFER1DB100DUP(3,5,2DUP(10),35),24,‘NUM’表示以BUFFER1為首地址的區(qū)域存放(3,5,10,10,35)100次,和24,‘NUM’3.2.2

符號(hào)定義偽指令

?等值偽指令EQU

給左邊符號(hào)定義一個(gè)值。該值可以是任何有效的操作數(shù)表達(dá)式,如一個(gè)常數(shù)、另一個(gè)符號(hào)名或地址表達(dá)式,甚至一個(gè)指令助記符。在程序中,凡是出現(xiàn)該符號(hào)的地方,匯編時(shí)均用該值代替。如:TIMESEQU50 ;TIMES=50DATADBTIMESDUP(?)FIRSTEQUSECOND+1 ;FIRST=SECOND+1

ADD1EQUADD ;為ADD指定一個(gè)別名ADD1

?解除偽指令PURGE用于釋放由EQU偽指令定義的符號(hào)變量,這樣這些變量就可以被重新定義。EQU偽指令定義的符號(hào)在PURGE偽指令解除前,不能重新定義。

例:PURGE符號(hào)名1,符號(hào)名2,…符號(hào)名N?等號(hào)賦值偽指令“=”

功能與EQU相似,能對(duì)已定義的符號(hào)名重新定義而無須先釋放。

TIMES=50;FIRST=SECOND+1;

ADD1=ADD;

3.2.3段定義偽指令一個(gè)完整的匯編源程序由代碼段、堆棧段、數(shù)據(jù)段,有時(shí)還有附加段所組成。段定義偽指令可將源程序劃分成若干段,以便匯編和連接時(shí)將各同名段進(jìn)行組合。

段定義偽指令一般格式為:段名SEGMENT[定位類型][組合類型][類別]

……;段體內(nèi)容,由指令及偽指令組成。段名ENDSSEGMENT和ENDS應(yīng)成對(duì)使用,缺—不可。

①段名:段名是不可省略的,是給定義的段所起的名稱。例如:STACKSEGMENTSTACKDW20DUP(?)STACKENDS②定位類型:表示該段起始地址位于何處。字節(jié)型(BYTE),段起始地址可位于任何地方;字型(WORD),段起始地址必須位于偶地址;節(jié)型(PARA),即段起始地址必須能被16除盡;頁(yè)型(PAGE),即段起始地址可被256除盡;

缺省時(shí),段起始地址便定位為PARA型的。

③組合類型:組合類型用于告訴連接程序,該段和其它段的組合關(guān)系。連接程序可以將不同模塊的同名段進(jìn)行組合。組合類型有:

NONE——表明本段與其它段邏輯上不發(fā)生關(guān)系,省略時(shí),便指定為這一組合類型。PUBLIC——與其它模塊中用PUBLIC說明的同名段按先后連接成一個(gè)邏輯段,使用同一個(gè)物理段地址。STACK——將具有STACK類型的同名段連接成一個(gè)大的堆棧,由各模塊共享。COMMON——與其它模塊中由COMMON說明的所有同名段連接時(shí),被重疊放在一起,其長(zhǎng)度是同名段中最長(zhǎng)者的長(zhǎng)度。

MEMORY——由MEMORY說明的段。在連接時(shí),它被放在所裝載程序的最后存儲(chǔ)區(qū)(最高地址)。若幾個(gè)段都有MEMORY組合類型,則連接程序只認(rèn)定首先遇到的段具有MEMORY組合類型,其它段則認(rèn)為是COMMON類型,并被疊放在一起。AT表達(dá)式——段地址是表達(dá)式所給定的值。在程序中就可由用戶直接來定義段地址。但這種方式不適用于代碼段。④類別:是用單引號(hào)括起來的字符串,以表明該段的類別。如代碼段(CODE)、數(shù)據(jù)段(DATA),堆棧段(STACK)等。各模塊中同一類型的段可能具有不同的名字,連接時(shí)將同類別的段(但不一定同名)放在連續(xù)的存儲(chǔ)區(qū)內(nèi)。上述的組合類型便于多個(gè)模塊的連接。若程序僅有一個(gè)模塊,即只包括代碼段、數(shù)據(jù)段和堆棧段時(shí),為了和其它段有區(qū)別,除了堆棧段用STACK說明外,其它段的組合類型、類別均可省略。例如有兩個(gè)模塊:模塊1

STACK SEGMENTSTACK DW300DUP(?)STACK ENDSDATA SEGMENT COMMONDATA ENDSCODE SEGMENT PUBLICCODE ENDS模塊2

STACK SEGMENTSTACK DW30DUP(?)STACK ENDSDATA SEGMENTCOMMONDATA ENDSCODE SEGMENTPUBLICCODE ENDS END3.2.4

設(shè)定段寄存器偽指令A(yù)SSUME——段寄存器定義偽指令。用于建立段名和段寄存器之間的嚴(yán)格對(duì)應(yīng)關(guān)系??赏ㄖ獏R編程序哪一個(gè)段寄存器是當(dāng)前段的段寄存器,以便對(duì)使用變量或標(biāo)號(hào)的指令匯編出正確的目的代碼。其格式為:ASSUME段寄存器:段名[,段寄存器:段名,…]ASSUME偽指令只是指明某一個(gè)段地址與段寄存器的聯(lián)系,沒有將段地址送入該寄存器的操作。因此要將段地址裝入段寄存器還需用匯編指令來實(shí)現(xiàn)。

例如:CODESEGMENTASSUMECS:CODE,DS:DATA,SS:STACKMOVAX,DATA;DATA段值送AXMOVDS,AX;AX內(nèi)容送DS,本指令執(zhí)行完之后,DS才為實(shí)際段值CODEENDS由于DOS的裝入程序負(fù)責(zé)把CS初始化成正確的代碼段地址,SS初始化為正確的堆棧段地址,在程序中就不必設(shè)置。但DS數(shù)據(jù)段或ES附加段必須MOV指令對(duì)DS和ES進(jìn)行初始化,以裝入段地址。3.2.5ORG

偽指令

ORG:偽指令用于指定段內(nèi)程序或數(shù)據(jù)代碼存放的起始偏移地址,即用語句中表達(dá)式的值作為起始偏移地址,此后的程序或數(shù)據(jù)代碼將連續(xù)存放,除非遇到另一個(gè)新的ORG語句。一般格式為:

ORG<表達(dá)式>例如:DATA SEGMENT BUFF1 DB 23,56H,‘EOF’ ORG 2000H BUFF2 DB ‘STRING’ DATA ENDS3.2.6

定義過程的偽指令

具有一定功能的程序段作為一個(gè)過程(相當(dāng)于一個(gè)子程序)??梢员粍e的程序調(diào)用(用CALL指令)或由JMP指令轉(zhuǎn)移到此執(zhí)行;也可以由程序順序執(zhí)行;或作為中斷處理程序,在中斷響應(yīng)后轉(zhuǎn)此執(zhí)行。一個(gè)過程由偽指令PROC和ENDP來定義。其格式為:過程名PROC[類型](FAR/NEAR,缺省為NEAR)

………

RET過程名ENDP

過程體內(nèi)至少應(yīng)有一條RET指令。過程可以嵌套,也可以遞歸使用,即過程可以調(diào)用過程或本身。過程體例如:延時(shí)100ms的過程,可定義如下:DELAYPROCPUSHBXPUSHCXMOVBL,10AGAIN:MOVCX,2801;延時(shí)10msWAI:LOOPWAIDECBLJNZAGAINPOPCXPOPBXRETDELAYENDPCODE1SEGMENTASSUMECS:CODE1FARPROCPROCFAR

……RETFARPROCENDPCODE1ENDS

CODE2SEGMENTASSUMECS:CODE2CALLFARPROC…...……CALLNEAR…………NEARPROCNEAR…………RETNEAR ENDPCODE2ENDS3.2.7宏指令

若程序段要多次使用,為了簡(jiǎn)化程序書寫,該程序段可以用一條宏指令來代替,而匯編程序匯編到該宏指令時(shí),仍會(huì)產(chǎn)生源程序所需的代碼。

宏指令的一般格式為:宏指令名MACRO[形式參量表]宏體

ENDM宏指令與子程序都是可完成某種功能的,供調(diào)用的程序模塊。定義后可多次調(diào)用。但子程序只形成一段目的代碼,調(diào)用時(shí)轉(zhuǎn)來執(zhí)行。而宏指令是將形成的目的代碼插到主程序調(diào)用的地方。例如:GADDMACROX,Y,ADD1MOVAX,XADDAX,YMOVADD1,AXENDM其中X,Y,ADD1都是形式參量。調(diào)用時(shí),用下面宏指令書寫格式:

GADDDATA1,DATA2,SUM這里DATA1,DATA2,SUM是實(shí)參量。實(shí)際上與該宏指令對(duì)應(yīng)的源程序?yàn)椋?/p>

MOVAX,DATA1ADDAX,DATA2MOVSUM,AX3.2.8匯編結(jié)束偽指令

END偽指令表示源程序的結(jié)束。每個(gè)源程序模塊必須且只能用一條END偽指令指明結(jié)束位置,匯編程序遇到END時(shí)立刻停止匯編。其一般格式為:

END[表達(dá)式]其中表達(dá)式是可選項(xiàng),表示該匯編程序模塊的啟動(dòng)地址。例如:

ENDSTART則表明該程序的啟動(dòng)地址為START。3.3匯編語言程序設(shè)計(jì)

程序設(shè)計(jì)是應(yīng)用計(jì)算機(jī)解決實(shí)際問題的重要環(huán)節(jié)。一個(gè)優(yōu)秀的程序設(shè)計(jì)的標(biāo)準(zhǔn)為:?程序結(jié)構(gòu)清晰合理,易于理解和維護(hù);?程序執(zhí)行時(shí)間短;?源程序的語句行少;?程序存儲(chǔ)的字節(jié)數(shù)少;這些要求可通過選擇算法和優(yōu)化程序結(jié)構(gòu)來實(shí)現(xiàn)。3.3.1匯編語言程序設(shè)計(jì)概述一、匯編語言程序的基本結(jié)構(gòu)框架匯編語言源程序由可執(zhí)行的指令語句和指示性的偽指令組成。在匯編語言源程序至少包括三段:代碼段、數(shù)據(jù)段、堆棧段,必要時(shí)還有附加段。二、匯編語言程序設(shè)計(jì)的基本步驟

1.分析實(shí)際問題,建立解決問題的模型;2.確定解決問題的算法、方法和步驟;3.根據(jù)算法畫出程序流程圖,即將解決問題的思路用圖形表示。4.對(duì)程序中的數(shù)據(jù)的組織、存儲(chǔ)單元分配、寄存器使用規(guī)劃等進(jìn)行統(tǒng)一考慮和安排。5.根據(jù)程序流程圖編寫程序;6.程序檢查、調(diào)試與修改;三、匯編語言程序的基本結(jié)構(gòu)程序根據(jù)Boehm和Jacobi的結(jié)構(gòu)定理,任何程序可以由三種最基本的結(jié)構(gòu)程序構(gòu)成,如下圖:順序結(jié)構(gòu)程序分支結(jié)構(gòu)程序循環(huán)結(jié)構(gòu)程序每個(gè)結(jié)構(gòu)程序只有一個(gè)入口和一個(gè)出口,通過三種結(jié)構(gòu)的組合和嵌套可構(gòu)成任何復(fù)雜的結(jié)構(gòu)化程序。3.3.2順序結(jié)構(gòu)程序設(shè)計(jì)

順序程序設(shè)計(jì)是沒有分支,沒有循環(huán)的直線運(yùn)行程序,程序執(zhí)行按照IP自動(dòng)增加的順序進(jìn)行。例1:利用查表法計(jì)算平方值。已知0~9的平方值連續(xù)存在以SQTAB開始的存儲(chǔ)區(qū)域中,求SUR單元內(nèi)容X的平方值,并放在DIS單元中。假定0≤X≤9且為整數(shù)。解:(1)了解平方表的存放位置;

(2)根據(jù)X的值,找到X對(duì)應(yīng)X2在表中位置。STACKSEGMENT DB100DUP(?)STACKENDSDATASEGMENT SURDB? DISDB?

SQTABDB0,1,4,9,16,25,36,49,64,81DATAENDSCODESEGMENT ASSUMECS:CODE,DS:DATA,

SS:STACK,ES:DATABEGIN:PUSHDS MOVAX,0 PUSHAX MOVAX,DATA MOVDS,AX LEABX,SQTAB;取平方表基地址 MOV AH,0 MOV AL,SUR;AL=X ADD BX,AX;計(jì)算地址偏移 MOV AL,[BX];取出X的平方值 MOV DIS,ALRETCODEENDS END BEGINBEGIN:PUSHDS MOVAX,0 PUSHAX MOVAX,DATA MOVDS,AX LEABX,SQTAB MOV AL,SUR;AL=X XLAT SQTAB MOV DIS,ALRETCODEENDS END BEGIN為使程序精練,可采用換碼指令XLAT,代碼段如下:結(jié)束用戶程序返回DOS的方法1.系統(tǒng)功能調(diào)用INT21H的4CH號(hào)子功能在用戶程序結(jié)束處用以下語句:

MOVAH,4CHINT21H2.利用RET指令上面的例子中所采用的方法。3.程序轉(zhuǎn)移到內(nèi)存中偏移量為0的地方

JMP04.利用中斷調(diào)用

INT20HBEGIN:MOVAX,DATA MOVDS,AX LEABX,SQTAB MOV AL,SUR;AL=X XLAT SQTAB MOV DIS,ALMOVAH,4CHINT21HCODEENDS END BEGIN利用系統(tǒng)功能調(diào)用INT21H的4CH號(hào)子功能返回DOS3.3.3分支結(jié)構(gòu)程序設(shè)計(jì)

分支結(jié)構(gòu)程序的基本思想是根據(jù)某些條件和狀態(tài)來控制程序下一步的走向。首先執(zhí)行能影響狀態(tài)的指令,如算術(shù)邏輯運(yùn)算指令、移位指令或位操作指令,然后用條件轉(zhuǎn)移類指令對(duì)各種狀態(tài)標(biāo)志進(jìn)行判斷,進(jìn)而轉(zhuǎn)移形成分支。設(shè)計(jì)分支結(jié)構(gòu)程序一般有兩種方法:?比較/測(cè)試分支結(jié)構(gòu)法;?跳轉(zhuǎn)表分支結(jié)構(gòu)法;1.比較/測(cè)試分支結(jié)構(gòu)法

采用比較指令CMP和測(cè)試指令TEST,產(chǎn)生相應(yīng)的狀態(tài)標(biāo)志,選擇適當(dāng)?shù)臈l件轉(zhuǎn)移指令,實(shí)現(xiàn)不同情況的分支轉(zhuǎn)移。一條轉(zhuǎn)移指令產(chǎn)生兩路分支,n條轉(zhuǎn)移指令可產(chǎn)生n+1條分支。=0?BX=0BX=1BX=–1YY

>0?例1實(shí)現(xiàn)符號(hào)函數(shù)。1X>0Y=0X=0

–1X<0根據(jù)上述要求的程序段為:START: MOV AX,BUFFER;取變量X OR AX,AX;產(chǎn)生狀態(tài)標(biāo)志 JE ZERO;X=0則轉(zhuǎn)移 JNS PLUS;X為正則轉(zhuǎn)移 MOV BX,0FFFFH;BX=–1 JMP CONT1;轉(zhuǎn)向出口ZERO: MOV BX,0 JMP CONT1PLUS: MOV BX,1CONT1:……2.跳轉(zhuǎn)表分支結(jié)構(gòu)法

當(dāng)分支數(shù)較多時(shí),將各個(gè)分支的入口地址組成跳轉(zhuǎn)表,再根據(jù)某個(gè)變量的不同取值情況,從表中取出相應(yīng)的入口地址,實(shí)現(xiàn)各分支轉(zhuǎn)移。例2:根據(jù)AL中各位被置位情況,控制轉(zhuǎn)移到8個(gè)子程序P1~P8其中之一。

條件1成立?P1P2Pn+1YY條件2成立?條件n成立?┇YPn子程序分支轉(zhuǎn)移跳轉(zhuǎn)表SR0子程序的P1入口地址SR1子程序的P2入口地址SR2子程序的P3入口地址………………SR6子程序的P7入口地址SR7子程序的P8入口地址STACKSEGMENT DB100DUP(?)STACKENDSDATA SEGMENTBASE DWSR0,SR1,SR2,SR3,SR4,SR5,SR6,SR7VALXDB?DATA ENDS解:具體程序如下:CODE SEGMENTASSUMECS:CODE,DS:DATA,SS:STACKBEGIN:PUSH DS XOR AX,AX PUSH AX MOV AX,DATA MOV DS,AX MOV CX,8 LEA BX,BASE IN AL,PORTGETBIT:RCR AL,1 JC GETAD INC BX INC BX LOOP GETBIT RETGETAD:JMP WORDPTR[BX]CODE ENDSCODE SEGMENTASSUMECS:CODE,DS:DATA,SS:STACKBEGIN:MOV AX,DATA MOV DS,AXMOV AL,VALXMOV AH,0DEC AXSAL AX,1 LEA BX,BASEADD BX,AXJMP WORDPTR[BX]SR0:…… JMP GETADSR1: …… JMP GETAD…………GETAD:MOV AH,4CHINT 21HCODE ENDS

若跳轉(zhuǎn)表中的內(nèi)容由JMPOPRD轉(zhuǎn)移指令構(gòu)成,則不能將跳轉(zhuǎn)表的內(nèi)容作為轉(zhuǎn)移的目標(biāo)地址直接取出。先根據(jù)給定的參數(shù)值第一次跳轉(zhuǎn)到表中的對(duì)應(yīng)項(xiàng),然后執(zhí)行跳轉(zhuǎn)表中的JMPOPRD轉(zhuǎn)移指令,第二次跳轉(zhuǎn)到對(duì)應(yīng)的子程序段。注意:?跳轉(zhuǎn)表中每一條跳轉(zhuǎn)指令占三個(gè)字節(jié)。?第一次跳轉(zhuǎn)的目標(biāo)地址在BX中,JMPBX。

?跳轉(zhuǎn)表中是JMPOPRD轉(zhuǎn)移指令,故跳轉(zhuǎn)表在代碼段中。STACKSEGMENT DB100DUP(?)STACKENDSDATA SEGMENTVALXDB?DATA ENDSCODE SEGMENTASSUMECS:CODE,DS:DATA,SS:STACKBEGIN:MOV AX,DATA MOV DS,AXMOV BL,VALX;取控制參數(shù)MOV BH,0DEC BX;控制參數(shù)減一MOV AX,BX;暫時(shí)保存SAL BX,1;左移乘二 ADD BX,AX;加上原數(shù),完成乘三

ADDBX,OFFSETTABLE;加上表首址JMP BX;第一次跳到跳轉(zhuǎn)表中的對(duì)應(yīng)項(xiàng)TABLE:JMPSR0;JMPSR1;在代碼段中的跳轉(zhuǎn)表,JMPSR2;進(jìn)行第二次跳轉(zhuǎn),執(zhí)行跳轉(zhuǎn)表中

…………;的轉(zhuǎn)移指令。JMPSR7;SR0:…… JMP GETADSR1: …… JMP GETAD…………GETAD:MOV AH,4CHINT 21HCODE ENDS3.3.4循環(huán)結(jié)構(gòu)程序設(shè)計(jì)在實(shí)際應(yīng)用中,要求某個(gè)操作重復(fù)執(zhí)行多次,可利用循環(huán)程序結(jié)構(gòu),來減少源程序的長(zhǎng)度。循環(huán)結(jié)構(gòu)程序通常由以下幾個(gè)部分組成:1.循環(huán)初始化部分:地址指針、循環(huán)次數(shù)、相關(guān)寄存器及標(biāo)志的清零和設(shè)置。2.循環(huán)體:循環(huán)體是要求重復(fù)執(zhí)行的程序段部分。3.循環(huán)控制部分:每進(jìn)行一次循環(huán),由該部分修改并判斷控制循環(huán)的條件是否滿足。以決定是否繼續(xù)循環(huán)。4.循環(huán)結(jié)束部分:進(jìn)行循環(huán)的后續(xù)處理,如保存循環(huán)運(yùn)行結(jié)果等,這部分不是必須的。

循環(huán)程序有兩種結(jié)構(gòu)形式:1.DO-WHILE結(jié)構(gòu),先判斷后執(zhí)行循環(huán)體。2.DO-UNTIL結(jié)構(gòu),先執(zhí)行循環(huán)體后判斷。

DO-WHILEDO-UNTIL滿足條件?

循環(huán)體工作部分循環(huán)體結(jié)束循環(huán)體修改部分循環(huán)初始化部分YN滿足條件?循環(huán)體結(jié)束循環(huán)體修改部分

循環(huán)體工作部分循環(huán)初始化部分YN例4設(shè)內(nèi)存BUFF開始的單元中依次存放著30個(gè)8位無符號(hào)數(shù),求它們的和并放在SUM單元中。程序如下:MOV SI,BUFFMOV CX,30XOR AX,AXAGAIN:ADD AL,[SI] ADC AH,0 INC SI DEC CX;可用LOOPAGAIN JNZ AGAIN MOV SUM,AX

例5在給定個(gè)數(shù)的16位數(shù)串中,找出大于零、等于零和小于零的個(gè)數(shù),并緊跟著原串存放。程序如下:DATA SEGMENTBUFF DWX1,X2,X3,……,XnCOUNTEQU$-BUFF;求字節(jié)數(shù)SIZEBUFFPLUS DB?ZERODB?MINUSDB?DATA HENDSCODE SEGMENTASSUME CS:CODE,DS:DATA,SS:STACKBEGIN:MOVAX,DATA MOVDS,AX MOVCX,COUNT;或MOVCX,LENGTHBUFF SHRCX,1;CX/2為字?jǐn)?shù) MOVDX,0 MOVAX,0 LEA BX,BUFFAGAIN:CMPWORDPTR[BX],0 JAE PLU;大于等于0轉(zhuǎn)移到PLU INC AH;計(jì)小于0的個(gè)數(shù) JMP NEXTPLU: JZ ZER;等于0轉(zhuǎn)到ZER INC DL;計(jì)大于0的個(gè)數(shù) JMP NEXTZER: INC DH;計(jì)等于0的個(gè)數(shù)NEXT:INC BX;修改地址指針 INC BX LOOPAGAIN;循環(huán)控制轉(zhuǎn)移

MOV PLUS,DL MOV ZERO,DH MOV MINUS,AH MOV AX,4C00H INT 21HCODE ENDS END BEGIN例6在ADDR單元中存放著16位數(shù)Y的地址,試編寫一程序,把Y中1的個(gè)數(shù)存入COUNT單元中。DATA SEGMENTADDR DW NUMBERNUMBER DW YCOUNT DW ?DATA ENDSPROGRAM SEGMENTMAIN PROC FARASSUME CS:PROGRAM,DS:DATASTART: PUSH DS MOV AX,0 PUSH AX MOV AX,DATA MOV DS,AX MOV CX,0;CX為Y中1的個(gè)數(shù) MOV BX,ADDR;取Y的地址到BX MOV AX,[BX];取16位數(shù)YREPEAT: TEST AX,0FFFFH;結(jié)果是否為0 JZ EXIT;結(jié)果為0則結(jié)束 JNS SHIFT;最高位為0則轉(zhuǎn)左移1位 INC CX;最高位為1則計(jì)數(shù)一次SHIFT: SHL AX,1;左移1位準(zhǔn)備下一循環(huán) JMP REPEATEXIT: MOV COUNT,CX; RETMAIN ENDPPROGRAM ENDS END START例7軟件延時(shí)程序(多重循環(huán))DELAY PROCTIME: MOV DX,3FFHTIME1: MOV AX,0FFFFHTIME2: DEC AX; NOP; JNZ TIME2;內(nèi)層循環(huán) DEC DX JNZ TIME1;外層循環(huán) DEC BX JNZ TIME;最外層循環(huán) RETDELAY ENDPBX是入口參數(shù),可由BX控制延時(shí)時(shí)間。如:假定DELAY是延時(shí)100ms程序,則延時(shí)10s的程序可寫為:MOV BX,100 CALL DELAY;延時(shí)10秒例8在DS所決定的數(shù)據(jù)段,從偏移地址BUFFER開始順序存放100個(gè)無符號(hào)16位數(shù),現(xiàn)要編寫程序?qū)⑦@100個(gè)字?jǐn)?shù)據(jù)從大到小排序。氣泡排序算法(從大到小或從小到大)從第一個(gè)數(shù)開始依次對(duì)相鄰兩個(gè)數(shù)比較,若次序?qū)r(shí),則不做任何操作,如次序不對(duì),則使這兩個(gè)數(shù)交換位置。這種算法稱為氣泡算法。 序號(hào) 數(shù) 第一遍第二遍第三遍第四遍1 8 8 16 3284 2 5 16 32 8432 3 16 32 84 16164 32 84 8 885 84 5 555

第一遍進(jìn)行4(N-1次)比較,最小數(shù)已到最下面,第二遍進(jìn)行3(N-2次)比較,依次類推,最多進(jìn)行N-1遍即可完成排序。minSI指向首地址CL←比較次數(shù)AX←當(dāng)前數(shù)[SI]→下一個(gè)數(shù)AX–[SI][SI–2]←[SI][SI]←AXAX>[SI]?一次排序結(jié)束?總排序結(jié)束?YNNYYAX[SI]程序如下:

LEA DI,BUFFER;取首地址 MOV BL,99;須經(jīng)N-1次排序NEXT0:MOV SI,DI;SI恢復(fù)指向首地址 MOV CL,BL;每次排序的比較次數(shù)NEXT3:MOV AX,[SI];當(dāng)前16位數(shù)放在AX中 ADD SI,2;SI指向下一個(gè)16位數(shù) CMP AX,[SI];當(dāng)前數(shù)與下一個(gè)數(shù)比較 JNC NEXT5;大于等于則不交換 MOV DX,[SI];小于則交換 MOV [SI–2],DX;可XCHG[SI],AX MOV [SI],AX;MOV[SI-2],AXNEXT5:DEC CL;計(jì)算比較次數(shù) JNZ NEXT3 DEC BL;每次排序的比較次數(shù)減一 JNZ NEXT0 HLTLEA DI,BUFFER;取首地址 MOV COUNT,100;排序元素的個(gè)數(shù)CLD;地址遞增排序NEXT1:MOV BX,1;交換標(biāo)記DEC COUNT;每次排序的比較次數(shù)減一JZ EXIT;比較次數(shù)為0則結(jié)束MOV SI,DI;SI恢復(fù)指向首地址 MOV CX,COUNT;每次排序的比較次數(shù)NEXT2:LODSW;當(dāng)前數(shù)→AX,SI→下一個(gè)數(shù) CMP AX,[SI];當(dāng)前數(shù)與下一個(gè)數(shù)比較 JNC NEXT3;大于等于則不交換 XCHG [SI],AX;小于則交換 MOV [SI–2],AX;大數(shù)存入上一位置 XOR BX,BX ;有交換則交換標(biāo)記清零NEXT3:LOOP NEXT2;一次排序是否結(jié)束? CMP BX,0;一次排序是否有交換? JE NEXT1;有交換則繼續(xù)EXIT:MOV AX,4C00H INT 21H3.3.5

子程序設(shè)計(jì)

子程序是常用的程序結(jié)構(gòu),將頻繁使用的功能寫成子程序的形式,可使源程序及目標(biāo)程序縮短,提高效率和可靠性。在8086/8088中,子程序和過程的含義是一致的。?主程序可多次調(diào)用一個(gè)或多個(gè)子程序;?子程序可被多個(gè)主程序調(diào)用,也可再調(diào)用其他子程序;?子程序調(diào)用子程序,稱子程序嵌套;調(diào)用自己稱遞歸調(diào)用;?子程序調(diào)用時(shí),CPU自動(dòng)將調(diào)用時(shí)的斷點(diǎn)壓入堆棧保存;?子程序調(diào)用時(shí),由程序?qū)⒁玫郊拇嫫鲀?nèi)容壓入堆棧保護(hù);子程序返回前,將壓入堆棧的寄存器內(nèi)容彈出,恢復(fù)現(xiàn)場(chǎng);

編寫子程序有以下幾點(diǎn)基本要求:1.子程序必須有一定的通用性,確定入口參數(shù)和出口參數(shù)。2.選用適當(dāng)?shù)姆椒ㄟM(jìn)行主程序和子程序間參數(shù)的傳遞。

①利用寄存器進(jìn)行參數(shù)傳遞

。例9

②利用存儲(chǔ)單元按事先約定的規(guī)則進(jìn)行參數(shù)傳遞

。

③利用堆棧進(jìn)行參數(shù)傳遞。例103.注意現(xiàn)場(chǎng)信息的保護(hù)和恢復(fù),最好在子程序中進(jìn)行保護(hù)。4.正確使用堆棧。子程序嵌套較多時(shí),使用堆棧要仔細(xì)。5.編制子程序文件,主要包括以下內(nèi)容:

①子程序的名稱;

②子程序的功能描述;

③子程序的入口參數(shù)和出口參數(shù)

;

④子程序所使用的寄存器和存儲(chǔ)單元列表,對(duì)其作用描述;

⑤本子程序所調(diào)用的其他子程序列表;

⑥子程序調(diào)用形式舉例;9例9兩個(gè)6字節(jié)數(shù)相加。程序如下:DATA SEGMENTADD1 DB 0FEH,86H,7CH,35H,68H,77HADD2 DB 45H,0BCH,7DH,6AH,87H,90HSUM DB6DUP(0)COUNTDB 6DATA ENDSSTACKSEGMENT DB 100DUP(?)STACKENDSCODE SEGMENTASSUMECS:CODE,DS:DATA,SS:STACKMADD:MOV AX,DATA MOV DS,AX MOV AX,STACK MOV SS,AX

MOV SI,OFFSET ADD1 MOV DI,OFFSET ADD2 MOV BX,OFFSETSUM MOV CX,COUNT CLCAGAIN: CALL SUBADD LOOPAGAIN MOV AX,4C00H INT 21HSUBADD PROC;完成一個(gè)字節(jié)相加

PUSH AX;入口參數(shù):SI,DI,BX MOV AL,[SI];出口參數(shù):SI,DI,BX ADC AL,[DI] MOV [BX],AL INC SI ; INC DI ; INC BX ; POP AX RETSUBADD ENDPCODE ENDS ENDMADD例10把內(nèi)存中的字變量NUMBER的值,轉(zhuǎn)換為4個(gè)ASCII碼表示的十六進(jìn)制數(shù)碼串,串的起始地址為STRING。DATA SEGMENTNUMBER DW 25AFHSTRING DB 4DUP(?),

‘$’DATA ENDSCODE SEGMENTASSUME CS:CODE,DS:DATA,ES:DATABEGIN: MOV AX,DATA MOV DS,AX MOV ES,AX LEA BX,STRING PUSH BX PUSH NUMBER CALL BINHEXLEA DX,STRING MOV AH,9 INT 21H…調(diào)用時(shí)IP低調(diào)用時(shí)IP高NUMBER低NUMBER高STRING低STRING高原棧頂BINHEXPROC PUSH BP MOV BP,SP PUSH AX PUSH DI PUSH CX PUSH DX PUSHF MOV AX,[BP+4]; MOV DI,[BP+6];STRING ADD DI,LENGTHSTRING-1; MOV DX,AX;DX=25AFH MOV CX,4…

BP低

BP高調(diào)用時(shí)IP低調(diào)用時(shí)IP高NUMBER低NUMBER高STRING低STRING高原棧頂$AGAIN: AND AX,000FH;保留后四位 CALL HEXD;轉(zhuǎn)換成ASCII碼 STD;從后向前 STOSB;存串 PUSH CX;保存循環(huán)次數(shù) MOV CL,4 SHR DX,CL;對(duì)25AFH右移四位 MOV AX,DX; POP CX;恢復(fù)循環(huán)次數(shù) LOOP AGAIN;未完則繼續(xù) POPF POP DX POP CX POP DI POP AX POP BP RET 4;返回且使SP指向原棧頂BINHEX ENDPHEXD PROC CMP AL,0AH; JL ADDZ;小于0AH則加30H ADD AL,‘a(chǎn)’-‘0’-0AH;大于等于則加37HADDZ: ADD AL,‘0’

RETHEXD ENDPCODE ENDS EDN BEGIN例1164位加法,有兩個(gè)64位數(shù)相加,和放在BUFFER緩沖區(qū)中(不考慮進(jìn)位)。參數(shù)放在存儲(chǔ)單元中。程序如下:DATA SEGMENTVAL1 DD 01H,12345678HVAL2 DD 02H,65AB0788HBUFFER DD ?,?DATA ENDSSTACK SEGMENT DB 100DUP(?)STACK ENDSCODE SEGMENTASSUME CS:CODE,DS:DATA,ES:DATA,SS:STACKSTART PROC FARBEGIN: PUSH DS XOR AX,AX PUSH AX MOV AX,DATA MOV DS,AX MOV ES,AX MOV AX,STACK MOV SS,AX CALL ADD64NUM1 DW OFFSETVAL1,SEGVAL1NUM2 DW OFFSETVAL2,SEGVAL2RESULT DW OFFSETBUFFER,SEGBUFFER RETSTART ENDPADD64PROC PUSH BP MOV BP,SP PUSHF PUSH AX PUSH BX PUSH CX

PUSH SI PUSH DI MOV BX,[BP+2] LDS SI,DWORDPTRCS:[BX] ADD SI,LENGTHVAL1 LDS DX,DWORDPTR CS:[BX+4] ADD DX,LENGTHVAL2 LES DI,DWORD PTRCS:[BX+8] ADD DI,LENGTHBUFFER XCHG DX,BX MOV CX,4 STD XOR AXAGAIN: LODSW ADC AX,[BX] STOSW DEC BX DEC BX LOOP AGAIN MOV BX,[BP+2] ADD BX,0CH MOV [BP+2],BX POP DI POP SI POP CX POP BX POP AX POPF POP BP RETADD64 ENDPCODE ENDS END BEGIN例12數(shù)的階乘n*(n–1)!按照階乘的定義n!=這是一個(gè)遞歸定義式,1在程序設(shè)計(jì)時(shí),可采用子程序的的遞歸調(diào)用形式。DATA SEGMENTNUM DB5FNUM DW?DATA ENDSSTACK SEGMENT

DB 100DUP(?)STACK ENDSCODE SEGMENTASSUME CS:CODE,DS:DATA,SS:STACKBEGIN: PUSH DS MOV AX,0 PUSH AX MOV CX,1 PUSH CX

MOV AH,0 MOV AL,NUM

CALL FACTOR MOV FNUM,AX POP CX MOV AX,4C00H INT 21HFACTOR PROC CMP AX,0 JNZ IIA MOV DL,1 RETIIA: PUSH AX DEC AL CALL FACTORIIA1: POP CX MUL CL;CALLMULTIIA2: MOV DX,AX RETFACTOR ENDPCODE ENDS END BEGIN3.3.5

MASM與高級(jí)語言的接口MASM與多種高級(jí)語言均可以混合編程,介紹一種TurboC調(diào)用匯編的過程,說明在匯編中應(yīng)如何編寫程序,C中如何調(diào)用程序。一般來說,在高級(jí)語言中使用匯編語言主要有以下幾個(gè)原因:(1)為了提高程序某些關(guān)鍵部分的執(zhí)行速度,可以用匯編語言來使關(guān)鍵代碼段的時(shí)鐘周期最短;(2)完成一些高級(jí)語言中難以實(shí)現(xiàn)的功能,如高分辨率繪圖;(3)使用已經(jīng)開發(fā)的匯編語言模塊;

1.TurboC與匯編語言的接口方法當(dāng)TurboC調(diào)用匯編語言程序時(shí),匯編程序指令序列必須具備一定的順序,該順序可描述為:正文段描述;段模式;組描述;進(jìn)棧;程序體;退棧;正文段結(jié)束。例設(shè)有一個(gè)TurboC程序從鍵盤上獲得兩個(gè)數(shù),并將其傳給匯編語言子程序ASMTC.ASM完成兩個(gè)數(shù)相乘并返回乘積,然后在TurboC程序中將結(jié)果顯示在屏幕上。

先建立一個(gè)TurboC主程序EXAM3-1.C如下:

include<stdio.h>intasmtc(int,int,long*);main(){inti,j;longk;printf("Pleaseinputi,j=?");scanf("%d,%d",&i,&j);asmtc(i,j,&k);printf("the%dtimes%dis%ld\n",i,j,k);getch();};其中asmtc()是調(diào)用匯編語言子程序的函數(shù),該函數(shù)中包括三個(gè)參數(shù),前兩個(gè)為整型數(shù),第三個(gè)為長(zhǎng)整型數(shù)指針。

由上述TurboC主程序調(diào)用的匯編語言ASMTC.ASM的子程序如下:

PUBLIC

asmtcTEXTSEGMENTBYTEPUBLIC‘CODE’DGROUPGROUPDATA,BSSDATASEGMENTWORDPUBLIC’DATA‘DATAENDSBSSSEGMENTWORDPUBLIC’BSS’BSSENDSASSUMECS:TEXT,DS:DOROUP,SS:DOROUPasmtcprocnear

pushbpmovbp,sppushsimovax,[bp+4];/*得到第一個(gè)參數(shù)i*/movbx,[bp+6];/*得到第二個(gè)參數(shù)j*/mulbx;/*兩數(shù)相乘*/

movsi,[bp+8];/*得到參數(shù)k的地址*/

mov[si],ax;/*送乘積的低位兩個(gè)字節(jié)*/

incsiincsimov[si],dx;/*送乘積的高位兩個(gè)字節(jié)*/popsipopbpRetasmtcendpTEXTENDSEND2.自動(dòng)產(chǎn)生匯編語言的框架TurboC提供了一種自動(dòng)產(chǎn)生匯編語言框架的方法。下面舉例說明。首先用TurboC寫一個(gè)與調(diào)用匯編程

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝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ù)覽,若沒有圖紙預(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)論