《微計算機與單片機原理及應(yīng)用》第4章 80x86匯編語言程序設(shè)計_第1頁
《微計算機與單片機原理及應(yīng)用》第4章 80x86匯編語言程序設(shè)計_第2頁
《微計算機與單片機原理及應(yīng)用》第4章 80x86匯編語言程序設(shè)計_第3頁
《微計算機與單片機原理及應(yīng)用》第4章 80x86匯編語言程序設(shè)計_第4頁
《微計算機與單片機原理及應(yīng)用》第4章 80x86匯編語言程序設(shè)計_第5頁
已閱讀5頁,還剩113頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

第4章80x86匯編語言程序設(shè)計

本章重點:匯編語言的基本語法規(guī)則及其使用方法偽指令語句的格式、類別及功能簡化段定義結(jié)枸中常用的偽指令8086/8088匯編語言程序設(shè)計本章難點:匯編語言語句中使用的各種操作數(shù)、表達式、運算符、操作符匯編語言程序設(shè)計4.1匯編語言程序和匯編程序4.1.1匯編語言源程序和機器語言目標(biāo)程序使用匯編語言編寫的程序稱為匯編語言源程序(簡稱源程序)。把匯編語言源程序經(jīng)過翻譯,則可得到機器語言程序(目標(biāo)程序)。如圖所示:源程序的匯編過程圖

4.1.2匯編和匯編程序

1.匯編把源程序翻譯成機器語言目標(biāo)程序的過程,叫做匯編。

2.匯編程序(ASM)完成匯編任務(wù)的程序叫做匯編程序。

3.宏匯編程序(MASM)宏匯編則在基本匯編基礎(chǔ)上進一步擴展了功能。能夠把源程序中一組匯編語言語句序列定義為一條宏指令且能處理宏指令的匯編程序,叫做宏匯編程序。4.1.3匯編語言程序的語句類型一個匯編語言源程序?qū)嶋H上是為完成某一特定任務(wù)按一定語法規(guī)則組合在一起的語句序列。語句是匯編語言程序的基本組成單位。指令語句格式:一個語句行是由4個部分組成。

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

例句

Lop:MOVAL,25H1.標(biāo)號:指令語句的第一部分名字域叫做標(biāo)號。

2.助記符:這部分是語句中唯一不可缺省的。指令語句的助記符用規(guī)定指令語句的操作性質(zhì),并對應(yīng)8086指令系統(tǒng)中實際的操作碼。

3.操作數(shù):不同的語句要求有不同的參數(shù)。有些語句可以無操作數(shù)。

4.注釋:注釋由分號“;”開始,用來對語句功能加以說明,使程序更容易被理解和閱讀。4.28086/8088匯編語言中的標(biāo)識符、運算符及操作符4.2.1標(biāo)識符標(biāo)識符是由程序員自由建立起來的、有特定意義的字符序列。標(biāo)號和名字皆統(tǒng)一稱為標(biāo)識符。標(biāo)號和名字的命名規(guī)則如下:標(biāo)號和名字以字母開頭由大寫字母A~Z小寫字母a~z(匯編程序不區(qū)分大小寫)、數(shù)字(0~9)及4個特殊字符(?、@、$、和_等)組成的字符串表示。標(biāo)號和名字的字符串長度不能超過31個字符。標(biāo)號和名字的命名不能使用匯編語言中的保留字。凡是8086的指令助記符、偽指令、CPU內(nèi)部寄存器名等都是保留字。4.2.2運算符運算符用來實現(xiàn)對操作數(shù)的相關(guān)運算。MASM宏匯編中有3種運算符(算術(shù)、邏輯和關(guān)系運算符)。

1.算術(shù)運算符有+(加)、-(減)、*(乘)、/(除)、MOD(取余)、SHL(左移)、SHR(右移)共7種。算術(shù)運算符可用于數(shù)值表達式或地址表達式中。例:已知源程序指令格式如下:DAEQU300┆MOVAX,DA—80MOVBX,DAMOD100MOVCX,DA/100MOVDH,01100100BSHR2匯編后,計算表達式形成指令如下:DAEQU300

┆MOVAX,220MOVBX,0MOVCX,3MOVDH,19H2.邏輯運算符是按位操作的AND(與)、OR(或)、XOR(異或)、NOT(非),只適用于數(shù)值表達式。例:

MOVAL,NOT0FFHMOVBL,8CHAND73HMOVAH,8CHOR73H

MOVCH,8CHXOR73HANDCX,9ABCHANDFF73H匯編后,計算表達式形成指令為:MOVAL,0;

0FFH取反為0MOVBL,0;

MOVAH,0FFHMOVCH,0FFHANDCX,9A30H

3.關(guān)系運算符這類運算符有EQ、NE、LT、GT、LE和GE。關(guān)系運算符的兩個操作數(shù)必須同是數(shù)值或同是一個段內(nèi)的兩個存儲器地址。比較時,若關(guān)系成立(為真),則結(jié)果為全“1”,若關(guān)系不成立(為假),則結(jié)果為全“0”。其結(jié)果值在匯編時獲得。例:

MOVAX,10HGT16ADDBL,6EQ0110BMOVCX,((PORTLT5)AND100)

OR((PORTGE5)AND111)解:匯編時,形成指令MOVAX,0ADDBL,0FFHMOVCX,100;若滿足PORT<5,則PORTLT5邏輯取值為真,PORTGE5邏輯取值為假,即(111AND100)OR(000AND111)

100OR000;若滿足PORT>5或PORT=5,應(yīng)該怎么樣?4.2.3操作符

MASM宏匯編中有兩種操作符(即分析操作符和合成操作符)操作符完成對操作數(shù)屬性的定義、調(diào)用和修改。

1.分析操作符:又稱數(shù)值返回操作符,它的運算對象是存儲器操作數(shù),其功能為將存儲器操作數(shù)地址分解為段基址、偏移地址,將存儲器操作數(shù)的類型值分解為字節(jié)、字、近或者遠,而返回值是變量或者標(biāo)號的屬性值。分析操作符有SEG、OFFSET、TYPE、LENGTH、SIZE格式:操作符變量/標(biāo)號功能SEG回送變量/標(biāo)號的段地址值OFFSET回送變量/標(biāo)號的偏移地址TYPEVARIABLE/LABEL回送變量/標(biāo)號的類型值

LENGTH回送變量數(shù)據(jù)項總數(shù)

SIZE回送TYPE和LENGTH的乘積(變量分配的字節(jié)存儲單元總數(shù))例4-4:

MOVAX,SEGTABLEMOVDS,AXMOVBX,OFFSETTABLEBUF1DB100DUP(0)

BUF2DW200DUP(20H)

BUF3DD100DUP(13)則LENGTHBUF1=100SIZEBUF1=100LENGTHBUF2=200SIZEBUF2=400LENGTHBUF3=100SIZEBUF3=4002.合成操作符合成操作符又稱修改屬性操作符。常用的合成操作符有PTR、THIS、LABEL等。(1)PTR操作符用來指定或修改存儲器操作數(shù)的類型屬性(原有的段屬性和偏移地址屬性保持不變)。例句:

ARY1DB0,1,2,3,4;定義字節(jié)變量

ARY2DW0,1,2,3,4;定義字變量

MOVBX,WORDPTRARY1[3];將0403H→BXMOVCL,BYTEPTRARY2[6];將03H→CLMOVWORDPTR[SI],4;將0004H送至SI開始的字單元中例句:

DA—BYTEDB20HDUP(0);有32個字節(jié)單元為0DA—WORDDW30HDUP(0);有48個字單元為0┆MOVAX,WORDPTRDA—BYTE[10];按字單元操作ADDBYTEPTRDA—WORD[20],BL;按字節(jié)單元操作INCBYTEPTR[BX];用BX作指針SUBWORDPTR[SI],30H;用SI作指針JMPFARPTRSUB1;標(biāo)號SUB1不在本段范圍內(nèi)(2)

THIS操作符THIS操作符與EQU配合使用,可用來定義一個新的變量名或者標(biāo)號。格式:標(biāo)號/變量名EQUTHIS距離/類型例句:BWORDEQUTHISBYTE;ARY從新定義為字節(jié)類型可按40個字節(jié)的緩沖區(qū)使用

ARYDW20DUP(?);定義ARY為20個字的緩沖區(qū)4.3偽指令及其應(yīng)用

1.定義:偽指令語句即不是真正的指令語句,它是CPU不執(zhí)行的語句。在匯編后它本身不產(chǎn)生目標(biāo)代碼,只為匯編程序提供匯編時所需要的控制信息。偽指令的操作(稱作偽操作)在匯編過程中完成。

2.語句格式:名字 定義符 操作符;注釋常用偽指令大致有下列幾種類型:數(shù)據(jù)定義偽指令;符號定義偽指令;段定義偽指令;過程定義偽指令;定位偽指令;4.3.1數(shù)據(jù)定義偽指令用于定義一個變量的類型,給存儲器賦值,或者僅給變量分配存儲單元而不需賦值。一般格式

[變量名]數(shù)據(jù)定義符操作數(shù)[,操作數(shù)……];方括中為任選項

DBDWDD其中,DB(DefineByte)——定義該變量為字節(jié)類型,給變量分配字節(jié)單元或字節(jié)串,DW(DefineWord)——定義該變量為字類型,每個操作數(shù)占有一個字,即2個字節(jié),在內(nèi)存中低字節(jié)存低地址,高字節(jié)存高地址。

DD(Definedoubleword)——定義該變量為雙字類型,每個操作數(shù)占有兩個字。DQ——四個字變量;DT——十個字節(jié)變量2.操作數(shù)(表達式)的種類(1)常數(shù)表達式:例句:DA-BYTEDB50,50H,2*3+4

DA-WORDDW0A34H,4982H(2)問號表達式:表示定義的變量無確定初值?表示僅給變量預(yù)先保留相應(yīng)的存儲單元,而不賦予變量某個確定的初值例句:DA-BDB?;給DA-B分配一個字節(jié)單元空間,內(nèi)容未定

DA-WDW?;給DA-W分配一個字單元空間,內(nèi)容未定(3)字符串表達式:數(shù)據(jù)定義偽指令也可用于定義字符串。字符串必須放進引號內(nèi)。例句:STR1DB‘ABCD‘ 以上偽指令把’ABCD’中四個字符的ASCII碼值依次存放在STR1,STR+1,STR1+2,STR1+3的字節(jié)單元中。也可寫成STR1DB‘A’,‘B’,‘C’,‘D’STR2DW‘AB’,‘CD’;注意,這里與上式存放順序不同,是’BADC’STR3DD‘AB’,‘CD’(4)地址表達式:只適用DW和DD兩種偽指令。

例句:

ADRADWAB

;存入變量AB的偏移地址到ADRA字存儲單元。

ADRA1DWTAB,TAB+5,TAB+10

;存入以TAB為首的3個等距離的偏移地址到ADRA1開始的存儲單元。ADRA2DDTAB

;先存入TAB的偏移地址,再存其段基址,共占4個字節(jié)。(5)帶“DUP”的表達式:當(dāng)表中的操作數(shù)相同時,可用重復(fù)操作符來縮寫,“DUP”可以嵌套。指令格式:變量名{DB/DW/DD}表達式1DUP表達式2;其中:表達式1為重復(fù)次數(shù),表達式2為重復(fù)內(nèi)容。例:ALL-ZER0DB0,0,0,0,0可寫成ALL-ZER0DB5DUP(0)例:

D-B1DB20HDUP(?)

;D-B1分配20H(32)個字節(jié)單元,但未賦值

D-B2DB10DUP(‘ABCD’);重復(fù)存放10個字符串‘ABCD’,共占用40個字節(jié)

D-W1DW10HDUP(4)

;

D-B3DB10HDUP(4DUP(2),7)

D-B4

DB

10HDUP(12H)

D-W2DW10HDUP(1234H)例:試計算下列偽指令中各變量所分配的存儲單元字節(jié)數(shù)和總共占據(jù)的存儲空間

X1DW20X2DW8DUP(?),10,20X3DD10DUP(?)

X4DB3DUP(?,4DUP(0))

X5DB’HAPPYNEWYEAR!!’總共占據(jù)空間圖4.3.2符號定義偽指令常用的符號定義偽指令有EQU、“=”、LABEL分別對應(yīng)于賦值語句、等號語句和定義符號名語句。

(1)賦值語句EQU格式符號名EQU表達式例:CREQU0DH;將0DH賦予符號名CR

LFEQU0AH;

STREQU‘COMPUTER’;為字符串定義新的名字

COUNTEQUCX;為寄存器CX定義新的符號名COUNTLDEQUMOV;為指令MOV定義新的符號名

LD注意:

①用EQU定義是符號定義并不占據(jù)內(nèi)存單元。

②由EQU偽指令定義的符號不能使用匯編語言的保留字。

③同一源程序中,用EQU定義過的符號名,不能再重新定義。

(2)等號語句“=”該語句的功能與EQU的功能基本相同,區(qū)別在于可以對同一個符號名重復(fù)定義,用新的數(shù)值表達式重新賦值。格式:名字=表達式例句:COUNT=10MOVCX,COUNT;CX←10┆COUNT=COUNT+1MOVBX,COUNT;BX←11┆(3)定義符號名語句LABEL

格式:符號名LABEL類型例句:

AGAINFLABELFAR;定義標(biāo)號AGAINF的屬性為FARAGAIN:PUSHAX;標(biāo)號AGAIN的屬性為NEAR注:AGAIN標(biāo)號名可以不用定義直接出現(xiàn)并使用4.3.3段定義偽指令(SEGMENT/ENDS)在匯編語言源程序中用來定義邏輯段。1.常用的段定義偽指令為SEGMENT/ENDS和ASSUME等。(1)SEGMENT/ENDSSEGMENT偽指令位于一個邏輯段的開始,用來定義一個邏輯段,給該邏輯段賦予一個段名。ENDS偽指令則表示該邏輯段的結(jié)束。這兩條偽指令總是成對出現(xiàn),二者前面的段名必須一致。格式:段名SEGMENT[定位類型][組合方式][‘類別名’]┆

段名ENDS①定位類型:用來確定邏輯段的邊界在存儲器中的位置。定位類型下面僅列舉兩種:PAGE——

表示邏輯段從頁(PAGE)邊界開始。通常一頁為256字節(jié)。PARA——

表示邏輯段從一個節(jié)(PARAGRAPH)邊界開始,通常一個節(jié)包括有16個字節(jié)。如果定位類型為缺省項,則默認其為PARA。②組合方式:用于如何組合幾個不同的邏輯段。組合方式下面列舉4種:NONE——不組合的獨立段。即不同程序中具有相同類別名的邏輯段分別作為不同的邏輯段裝入內(nèi)存,不進行組合。PUBLIC——對于不同程序模塊中的邏輯段,只要具有相同的類別名,就把這些同名段順序連接成為單個連續(xù)的邏輯段裝入內(nèi)存。STACK——其含義與PUBLIC基本一樣,不過組合方式STACK僅限于作為堆棧區(qū)的邏輯段使用,在運行時就是堆棧段寄存器SS所指物理段,且SP指向該段的末地址加1。AT表達式——

表示本邏輯段根據(jù)表達式求值的結(jié)果定位段基址(與ORG配合使用)例如AT4A00H,表示本段的段基址為4A00H則本段從存儲器的物理地址4A000H開始裝入。

③‘類別名’:類別名是用單引號括起來的字符串。必須放在單引號‘’內(nèi)。(2)ASSUME

用來指定段寄存器與段的關(guān)系。格式:ASSUME段寄存器名:段名[,段寄存器名:段名[,…]]例句:CODESEGMENTASSUMECS:CODE,DS:DATA,SS:STACKASSUME使用方式基本不變,若沒有定義堆棧段就可以不要SS:STACK,沒有定義數(shù)據(jù)段就可以不要DS:DATA(3)END:END偽指令用在源程序的最后,用以表示整個源程序的結(jié)束。格式:END[表達式];表達式一般為過程名或者END[入口地址]4.3.4過程定義偽指令(PROC/ENDP)

PROC是過程定義偽指令,ENDP是過程結(jié)束偽指令。過程定義偽指令格式:過程名PROC[NEAR]/FAR┆RET過程名ENDP過程調(diào)用時用CALL過程名4.3.5當(dāng)前地址計數(shù)器($)符號$表示地址計數(shù)器的當(dāng)前值。例句:DATASEGMENTBUFDB10H,20H,30HCOUNTEQU$-BUF;常量COUNT的值就是當(dāng)前待分配的地址值減去變量BUF的地址值,本例中實際上是BUF數(shù)據(jù)單元的長度3。4.3.6定位偽指令(ORG)ORG的功能是將當(dāng)前地址計數(shù)器設(shè)置成數(shù)值表達式的值。也就是地址值重定位。格式:ORG數(shù)值表達式或者ORG$+表達式例:DATASEGMENTORG1000HXDB20H,30H;X的地址從1000H處開始分配ORG$+20H;當(dāng)前地址為1002HCONSTEQU0ABCDH;CONST的地址從1022H處開始分配4.4宏指令及其應(yīng)用一條宏指令可包括若干條指令語句或偽指令語句。宏指令一旦定義,可以像其他指令一樣使用。4.4.1宏定義由于宏指令不是指令系統(tǒng)提供的,所以必須先定義后才能使用,其一般格式為:宏指令名MACRO[形式參數(shù)1][,形式參數(shù)2]…┆

;宏指令體

ENDM

例:定義一條宏指令,用來實現(xiàn)將累加器AL內(nèi)容邏輯右移4次(位)。若宏指令引入兩個形式參數(shù),n和Reg,則宏定義格式如下:

SHIFTMACROn,Reg

;n表示移位次數(shù),應(yīng)>1

MOVCL,n;Reg

代表要移位的寄存器

SHRReg,CL

ENDM宏指令可以理解為整體替換。4.4.2宏調(diào)用例:MOVAL,06HSHIFT44.5DOS和BIOS功能調(diào)用4.5.1DOS功能調(diào)用DOS(DISKOPERATINGSYSTEM)是PC機的單任務(wù)、單用戶的磁盤操作系統(tǒng)。DOS常用的軟中斷指令主要有21H,功能調(diào)用幾乎包括了整個系統(tǒng)的功能。1.DOS功能調(diào)用的方法所有的DOS功能調(diào)用時必須有下列3個方面內(nèi)容:提供功能調(diào)用的入口參數(shù)和出口參數(shù);入口參數(shù)是指調(diào)用前要對相應(yīng)寄存器輸入指定的初始值,出口參數(shù)是指調(diào)用后的結(jié)果存放在相應(yīng)的寄存器中。將子程序功能號送入AH或AX;所有子程序從1號開始編號,成為DOS功能調(diào)用號。執(zhí)行軟中斷指令I(lǐng)NT21H。下面介紹INT21H類型中最常用的DOS功能調(diào)用(1)DOS鍵盤功能調(diào)用從鍵盤輸入單個字符(功能號01H、08H、06H、07H)

從鍵盤輸入字符串(功能號0AH)(2)DOS顯示功能調(diào)用顯示器上顯示單個字符(功能號02H、06H)顯示器上顯示字符串(功能號09H)(3)DOS打印功能調(diào)用(功能號05H)(4)日期與時間設(shè)置功能調(diào)用(功能號2BH、2AH、2DH、2CH)(5)結(jié)束程序返回操作系統(tǒng)功能調(diào)用(功能號4CH)2.常用DOS功能調(diào)用舉例例:編寫完成從鍵盤輸入字符串存至內(nèi)存緩沖區(qū)并顯示該字符串的匯編語言源程序。解:

DATASEGMENT;定義數(shù)據(jù)段

BUFDB5;輸入緩沖區(qū)長度最多可容納5個字符

DB?;實際輸入的字符個數(shù)

DB5DUP(?),‘$’DATAENDS

CODESEGMENT;定義代碼段

ASSUMECS:CODE,DS:DATA;START:MOVAX,DATA;初始化DSMOVDS,AX;

LEADX,BUF;要求DS:DX指向輸入緩沖區(qū)BUF處

MOVAH,0AH;將DOS功能號0AH裝入AH。

INT21HLEADX,BUF+2MOVAH,09H;將DOS功能號09H裝入AH,顯示以“$”結(jié)尾的字符串,字符串在DX中

INT21HMOVAH,4CH;程序結(jié)束,返回DOSINT21HCODEENDSENDSTART

4.5.2BIOS中斷調(diào)用常用的BIOS中斷類型,如:INT10H顯示器中斷調(diào)用(AH=00H~0FH)

INT14H串行通信口功能調(diào)用(AH=00H~03H)

AH=00H——通信口初始化

AH=01H——通信口輸出

AH=02H——通信口輸入INT16H鍵盤中斷調(diào)用(AH=00H~02H)

AH=00H——讀鍵盤輸入字符

AH=01H——檢測鍵盤是否輸入字符

AH=02H——讀鍵盤當(dāng)前狀態(tài)INT17H打印機中斷調(diào)用(AH=00H~02H)

AH=00H——打印一個字符(AL=打印字符的ASCII碼)1.BIOS程序的調(diào)用方法步驟如下:將功能號送入AH或AX中,查閱BIOS功能調(diào)用參數(shù)表,查得BIOS的中斷類型號,取得功能號。設(shè)置入口參數(shù)。執(zhí)行軟中斷指令I(lǐng)NTN2.常用BIOS中斷調(diào)用舉例例:要求在640*350且16色顯示方式下,畫一矩形框,框的左上角坐標(biāo)(100,50)和右下角坐標(biāo)(400,200)。解:CODESEGMENTASSUMECS:CODESTART:MOVAL,0FHMOVAH,00HINT21HMOVCX,100MOVDX,50LL0:MOVAH,0CHINT10HINCCXCMPCX,400JNZLL0INCDXCMPDX,200JNZLL0JMP$MOVAH,4CHINT21HCODEENDSENDSTART4.68086/8088匯編語言程序的基本結(jié)構(gòu)框架4.6.1匯編語言源程序基本結(jié)構(gòu)特點匯編語言源程序由若干邏輯段組成,各邏輯段都有一個段名。其中:代碼段——是程序的主體.存放源程序中CPU必須執(zhí)行的所有機器指令代碼。數(shù)據(jù)段——存放程序中各類數(shù)據(jù)。附加段——為數(shù)據(jù)段的補充,并非所有程序都有。堆棧段——程序中可以定義,也可以不定義,而利用系統(tǒng)中的堆棧段。以上各段的邏輯段基址分別存放在CS、DS、ES和SS四個段寄存器中。4.6.2匯編語言源程序的基本結(jié)構(gòu)框架目前較為常用是兩種格式:完整段定義格式;這是傳統(tǒng)的匯編語言源程序格式。簡化段定義格式;在完整段定義結(jié)構(gòu)的基礎(chǔ)上經(jīng)過簡化而得。1.完整的段定義格式(1)完整的段定義格式要求每個段有SEGMENT和ENDS這一對偽指令來實現(xiàn)。(2)堆棧段、數(shù)據(jù)段和代碼段的段名分別定義為STACK、DATA和CODE,并非一定必須如此,也可取用其它名稱,如:SEG1,SEG2,SEG3等。(3)使用ASSUME(段寄存器分配)偽指令用來指定某段分配給哪個段寄存器。由于偽指令不由CPU執(zhí)行,故它并不能把段地址裝入段寄存器中,尚需對段寄存器進行初始化。2.簡化的段定義格式

(1)定義內(nèi)存模式偽指令.MODEL在使用簡化段定義之前,必須首先利用.MODEL偽指令指明程序所使用的內(nèi)存模式。內(nèi)存模式是指程序中代碼段和數(shù)據(jù)段在存儲器中存放的方式。格式:.MODEL存儲模式(2)簡化段定義偽指令用來定義代碼段、數(shù)據(jù)段和堆棧段等。①.CODE[NAME]——定義代碼段NAME用于自定義段名。②.DATA——定義已初始化的數(shù)據(jù)段,默認的段名是—DATA。③.DATA?——定義未初始化的數(shù)據(jù)段。④.STACK[SIZE]——定義堆棧段,[]可以指定堆棧段的長度(字節(jié)數(shù))。默認的段名是STACK。⑤.STARTUP——指示程序開始偽指令并初始化DS、SS、SP的值。⑥.方式偽指令:指定該指令系統(tǒng)的類型。例如:.8086,.386,.386P,.486等⑦.EXIT——返回DOS系統(tǒng)偽指令。能終止程序執(zhí)行并返回DOS。⑧

END——匯編結(jié)束偽指令例:將存儲區(qū)BUF1中100字節(jié)的源數(shù)據(jù)串,搬移到存儲區(qū)BUF2的目的串中。解:源程序如下:

MODELSMALL;小型模式內(nèi)存

80386;80386方式

STACK100H.;堆棧段開始,棧長度為100HDATA;數(shù)據(jù)段開始

BUF1DB100DUP(12H);源數(shù)據(jù)串

BUF2DB100DUP(?);目的串?dāng)?shù)據(jù)

CODE;數(shù)據(jù)段結(jié)束,代碼段開始

STARTUPCLDMOVSI,OFFSETBUF1;設(shè)置源串指針

MOVDI,OFFSETBUF2;設(shè)置目的串指針

MOVCX,64H;設(shè)置計數(shù)初值

REPMOVSB;重復(fù)串傳送

EXIT0END4.6.3匯編語言源程序正確返回DOS操作系統(tǒng)的方法(1)在程序代碼段的開頭,設(shè)置下面3條語句:

PUSHDSMOVAX,0PUSHAX;壓入返回地址

┆然后在程序退出處安排一條RET(返回)指令,則可返回DOS.(2)在程序代碼段的結(jié)尾處,安排如下兩條指令:

MOVAH,4CH;(或MOVAX,4C00H)

INT21H4.780x86匯編語言程序設(shè)計匯編語言程序基本結(jié)構(gòu)形式有:順序結(jié)構(gòu)、分支結(jié)構(gòu)、循環(huán)結(jié)構(gòu)和子程序。

4.7.1順序結(jié)構(gòu)程序設(shè)計例;試編寫一個完整格式的匯編語言程序,要求在屏幕上顯示“UNIVERSITYOFELECTRONICSCIENCEANDTECHNOLOGYOFCHINA”。解:SSEGSEGMENTPARASTACK’STACK’DB40HDUP(0);

SSEGENDSDSEGSEGMENTPARAPUBLIC’DATA’MESSDB‘UNIVERSITYOFELECTRONICSCIENCEANDTECHNOLOGYOFCHINA,’DB‘ZHONGSHANINSTITUTE$’DSEGENDSCSEGSEGMENTPARAPUBLIC’CODE’STARTPROCFARSTARTPROCFARASSUM,EDS:DSEG,SS:SSEG,CS:CSEG,ES:DSEGPUSHDS;MOVAX,0;PUSHAX;MOVAX,DSEG;MOVDS,AX;MOVES,AX;MOVDX,OFFSETMESS;

MOVAH,9;INT21H;RET;STARTENDPCSEGENDSENDSTART例:從端口地址為0250H的I/O設(shè)備輸入80個字節(jié)數(shù)據(jù)存入到附加段的字節(jié)數(shù)組ARY中。

解:MODELSMALL;

386;設(shè)置32位的386匯編方式

STACK;定義堆棧段

DATA;定義數(shù)據(jù)段

ARYDD20DUP(?)CODE;定義代碼段

START:MOVAX,DATAMOVES,AXMOVDI,OFFSETARY;用DI尋址輸入的數(shù)據(jù)

MOVDX,0250H;尋址I/O設(shè)備

CLD;增址方向

MOVCX,20;裝入計數(shù)初值

REPINSD;輸入字節(jié)數(shù)據(jù)至字節(jié)數(shù)組ARYEXITENDSTART4.7.2分支結(jié)構(gòu)程序設(shè)計匯編語言中用條件轉(zhuǎn)移指令和無條件轉(zhuǎn)移指令來實現(xiàn)分支程序結(jié)構(gòu)。分支程序有:二分支、三分支或多分支等。1.利用比較/條件轉(zhuǎn)移指令實現(xiàn)兩分支

2.利用邏輯運算(AND、OR、TEST)指令影響標(biāo)志位實現(xiàn)三分支。例:編寫一個程序把三個無符號單字節(jié)數(shù)從大到小進行排列。解:排序算法中有三個分支結(jié)構(gòu),其排序程序流程圖如圖所示。三個分支結(jié)構(gòu)程序流程圖源程序如下:STACK1SEGMENTSTACK’STACK’

DW64HDUP(?)STACK1ENDSDATASEGMENTBUFDB84H,32H,56H;待排序數(shù)據(jù)DATAENDSCODESEGMENTASSUMECS:CODE,DS:DATA,SS:STACK1START:MOVAX,DATAMOVDS,AX;初始化DSMOVSI,OFFSETBUF;設(shè)置地址指針

MOVAL,[SI];將數(shù)據(jù)由內(nèi)存讀入寄存器

MOVBL,[SI+1]MOVCL,[SI+2]CMPAL,BL;比較AL與BLJAENEXT1;第1分支結(jié)構(gòu)XCHGAL,BL;AL內(nèi)容大NEXT1:CMPAL,;比較AL與CLJAENEXT2;第2分支結(jié)構(gòu)XCHGAL,CLNEXT2:CMPBL,CL;比較BL與CLJAENEXT3;第3分支結(jié)構(gòu)XCHGBL,CLNEXT3:MOV[SI],AL;存結(jié)果到內(nèi)存

MOV[SI+1],BL;

MOV[SI+2],CL;

MOVAH,4CHINT21HCODEENDSENDSTART3.利用跳轉(zhuǎn)表實現(xiàn)多分支例:設(shè)有8個子程序,已知其入口地址分別為SUB0,SUB1,…SUB7(同在一個段內(nèi))依次放在ADRTAB開始的地址表中.每個地址占兩個字節(jié)。低字節(jié)在低地址,高字節(jié)在高地址。當(dāng)鍵盤輸入0-7中任一數(shù)字i時,便可分支到相應(yīng)的子程序中執(zhí)行,實現(xiàn)多路分支。解:(1)首先建立一個跳轉(zhuǎn)表,表中存放每個子程序的入口地址。利用此表可找到存放子程序入口地址的位置(叫做查表地址)設(shè)地址表基地址為ADRTAB.

(2)根據(jù)鍵入的數(shù)字i計算查表地址:查表地址=跳轉(zhuǎn)表首地址+偏移地址=ADRTAB+2*i(i=0~7中任一值)子程序入口地址表

程序流程圖

源程序如下:

DSGSEGMENTADRTABDWSUB0,SUB1,SUB2,SUB3,SUB4,SUB5,SUB6,SUB7;定義入口地址表

KEYINDB?

DSGENDSSSGSEGMENTPARASTACK‘STACK’DW40DUP(?)

SSGENDSCSGSEGMENTASSUMECS:CSG,DS:DSG,SS:SSG

STARTPROCFARPUSHDSMOVAX,0PUSHAXMOVAX,DSGMOVDS,AXMOVAH,01;從鍵盤輸入0~7中的一個數(shù)

INT21H;鍵盤輸入的ASCⅡ碼在AL中COMPUT:MOVAH,0;2*i

ANDAL,0FHSHLAL,1MOVBX,OFFSETADRTABADDBX,AX;求查表地址

JMPWORDPTR[BX];轉(zhuǎn)入相應(yīng)入口地址SUB0:;8個例行子程序SUB1:┆SUB7:

RETSTARTENDPCSGENDSENDSTART4.7.3循環(huán)結(jié)構(gòu)程序設(shè)計當(dāng)要重復(fù)執(zhí)行一段程序時,利用循環(huán)指令LOOP,LOOPZ和LOOPNZ或條件轉(zhuǎn)移指令來實現(xiàn)重復(fù)操作。循環(huán)結(jié)構(gòu)可以簡化程序結(jié)構(gòu)。循環(huán)程序結(jié)構(gòu)通常由以下4個部分組成:

1.初始化部分:該部分工作是置循環(huán)初值(即為循環(huán)作準(zhǔn)備),包括設(shè)置循環(huán)計數(shù)器,地址指針初值和存放結(jié)果單元的初值等。2.循環(huán)體:要被重復(fù)執(zhí)行的程序段。是循環(huán)結(jié)構(gòu)程序的核心。3.循環(huán)修改部分:為執(zhí)行下一次循環(huán)而修改某些參數(shù)。如循環(huán)變量加一、地址指針和循環(huán)次數(shù)改變等。4.循環(huán)控制:根據(jù)給定的循環(huán)次數(shù)和循環(huán)條件判斷是否結(jié)束循環(huán)。若未結(jié)束則重復(fù)執(zhí)行循環(huán)體和修改部分,否則退出循環(huán)。循環(huán)程序基本結(jié)構(gòu)圖例:在顯示屏幕上連續(xù)輸出字符0-9。試編程實現(xiàn)。解:(1)使用DOS功能子程序2號,實現(xiàn)輸出一個字符,并把該字符的ASCII碼送至寄存器DL。(2)使用BL寄存器存放十進制數(shù),其初值為0,每循環(huán)一次BL內(nèi)容加1,增量后用DAA指令調(diào)整,以保證BL內(nèi)容始終為十進制數(shù)。(3)為了使輸出的字符間有間隔,在每次循環(huán)中輸出一個0-9的字符和一個空格。(4)程序流程圖如圖所示。此為“先執(zhí)行—后判斷”結(jié)構(gòu)。(5)源程序如下:STACK1SEGMENTPARASTACK’STACK’

DB50DUP(?)STACK1ENDSCSEGSEGMENT ASSUMECS:CSEG,SS:STACK1STARTPROCFARBEGIN:PUSHDS MOVAX,0 PUSHAX MOV BL,0 PUSHBXGOON:MOVDL,20H;顯示輸出空格字符

MOVAH,2 INT21H POPBX MOVAL,BL INCAL;增量后十進制調(diào)整

DAA ANDAL,0FH MOVBL,AL ORAL,30H MOVDL,AL;轉(zhuǎn)換為ASCII碼,輸出;一個0~9之間的字符MOVAH,2 INT21H MOVCX,0FFFFHAGN:DECCX;延時

JNEAGN JMPGOON;循環(huán)運行

RETSTARTENDPCSEGENDS ENDBEGIN 所謂邏輯尺是指存儲單元,其中每一位為0或為1,可用來作為判斷分支和循環(huán)的邏輯標(biāo)志,猶如尺子一樣。下面以兩分支為例,說明邏輯尺的具體應(yīng)用。例:有某溫度測量系統(tǒng),現(xiàn)已采集16次溫度參數(shù),存放于緩沖區(qū)BUF。每個溫度參數(shù)都與溫度標(biāo)稱值存在微小誤差Δ,則需進行加/減溫度補償即須執(zhí)行兩種溫度補償函數(shù):用COMP0實現(xiàn)“加1”,用COMP1實現(xiàn)“減1”計算,用加或者用減需由邏輯尺中的標(biāo)志位來確定。試編此程序。解:據(jù)題意,設(shè)總共溫度補償須循環(huán)16次。室溫25℃為標(biāo)準(zhǔn)值。其中第0,1,4,5,6,10,11,15次要求執(zhí)行COMP0(+1)計算,其余第2,3,7,8,9,12,13,14次要求執(zhí)行COMP1(-1)計算。則邏輯尺LOGIR的標(biāo)志位應(yīng)設(shè)置為0111001110001100B=738CH設(shè)i表示標(biāo)志位位序。源程序如下:DATA1SEGMENTBUFDB18H,18H,1AH,1AH,18H,18H,18H,1AH

;共16個溫度參數(shù)

DB1AH,1AH,18H,18H,1AH,1AH,1AH,18HRESDB16DUP(?)LOGIRDW738CHDATA1ENDSCODE1SEGMENT ASSUMECS:CODE1,DS:DATA1START:MOVAX,DATA1

MOVDS,AX LEASI,BUF

LEADI,RES MOVBX,LOGIR MOVCX,16AGA: LODSB SHLBX,1 JNCCOMP0COMP1:SUBAL.1

JMPNEXTCOMP0:ADDAL,1NEXT: STOSB LOOPAGA MOVAH,4CH INT21HCODE1ENDS ENDSTART

上例程序流程圖☆例:將內(nèi)存首地址為BUF1開始的10個帶符號字節(jié)數(shù),將其由小到大的次序排列。解:采用冒泡法實現(xiàn)排序。使用雙重循環(huán)結(jié)構(gòu)。內(nèi)循環(huán)完成前后兩個數(shù)兩兩比較,外循環(huán)控制比較輪數(shù)。源程序如下:

.MODEL SMALL.DATABUF1DB 34H,12H,89H,… .CODE STARTUP MOVDX,9X1:MOVCX,DX MOVSI,0X2: MOVAL,BYTEPTRBUF1[SI] CMPAL,BYTEPTRBUF1[SI+1]

JLE NEXT

XCHGAL,BUF1[SI+1]

MOVBUF1[SI],ALNEXT: INC SI

LOOPX2 DECDX JNZ X1 EXIT END3.多重循環(huán)程序設(shè)計

例:軟件延時程序執(zhí)行程序中的每條指令都有一定的執(zhí)行時間,因此利用軟件可以實現(xiàn)延時。試設(shè)計要求延時1S的延時程序。解:利用雙重循環(huán)實現(xiàn)。子程序如下:SOFTDLYPROC;指令執(zhí)行時間(時鐘周期數(shù))

MOVBL,100;4TDELAY:MOVCX,n;4T(內(nèi)循環(huán)延時10ms)WAIT:LOOPWAIT;17T或者5T

DECBL;3TJNZDELAY;16T或者4TRET;20TSOFTDLYENDPt內(nèi)=0.01=10ms=[17(n—1)+5+4]*T(8088CPU的時鐘周期≈210ns)∴n=2801(即內(nèi)循環(huán)CX的控制次數(shù))

t外=(BL)*t內(nèi)+(BL)*19T=100*(t內(nèi)+19T)≈1S可以看出:內(nèi)循環(huán)中CX由2801減至0(BL維持不變)由此可實現(xiàn)10ms的延時。外循環(huán)進行100次,共可實現(xiàn)1000ms的延時。4.7.4子程序結(jié)構(gòu)程序設(shè)計子程序又稱過程。是具有獨立功能的模塊。在程序設(shè)計中,為了使結(jié)構(gòu)盡量簡單,實現(xiàn)代碼復(fù)用,增強可讀性,提高編程效率而設(shè)計的一種程序結(jié)構(gòu)。子程序常采用模塊化的程序設(shè)計方法,即把程序中的某些具有獨立功能的部分編寫成獨立的子模塊,這種程序模塊稱為“子程序”或者“過程”。1.子程序概述對于無規(guī)律的重復(fù)執(zhí)行,如鍵盤輸入處理、數(shù)制轉(zhuǎn)換、代碼轉(zhuǎn)換等,為避免編制相同程序的重復(fù)性工作,節(jié)約存儲空間,可把它獨立出來,附加一些其它的指令,將其編制成可以反復(fù)調(diào)用的公用的獨立程序段,并通過適當(dāng)方法把該程序段與其它程序段連接起來。這種程序設(shè)計的方法稱為子程序設(shè)計,被獨立出來的程序段稱為子程序。調(diào)用子程序的程序稱為主程序或調(diào)用程序。主程序與子程序的連接關(guān)系(1)子程序的調(diào)用與返回子程序調(diào)用指令:CALL和返回指令:RET。(2)主程序與子程序間的參數(shù)傳遞。主程序與子程序相互傳遞的信息稱為參數(shù)。傳遞的參數(shù)可以是信息本身,也可以是信息的地址,其傳遞基本方法有如下3種:

①寄存器傳遞參數(shù)

②堆棧傳遞參數(shù):這是最重要的方法之一。

③存儲單元傳遞參數(shù):

(3)保護現(xiàn)場與恢復(fù)現(xiàn)場子程序不可避免地要使用一些寄存器,因為主程序和子程序是分別編寫的,所用的寄存器可能發(fā)生“撞車”。因此子程序執(zhí)行后,某些寄存器的內(nèi)容會發(fā)生變化,如果主程序在這些寄存器中已經(jīng)存放有用的信息,則從子程序返回主程序后,主程序運行勢必因原存信息被破壞而出錯。在使用這些寄存器之前,將其內(nèi)容推入堆棧保存起來,而在使用之后返回主程序之前退出,將堆棧內(nèi)容彈回寄存器,前者稱為保護現(xiàn)場,后者稱為恢復(fù)現(xiàn)場。保護現(xiàn)場與恢復(fù)現(xiàn)場的操作可以在主程序中完成,也可以在子程序中完成。一般情況下是在子程序中完成。保存和恢復(fù)操作可以通過進棧指令和出棧指令實現(xiàn)。2.子程序嵌套與遞歸子程序一個子程序也可作為主調(diào)程序去調(diào)用另一個子程序的過程,稱為子程序嵌套。一個子程序作為主調(diào)程序去調(diào)用自身的過程,稱為子程序遞歸。(1)子程序嵌套。主程序X調(diào)用子程序Y而子程序Y又調(diào)用子程序Z,因此,子程序Y對于主程序X來說是子程序,而對于子程序Z來說則是主程序。以上XYZ三個程序之間的調(diào)用和返回關(guān)系也稱為子程序嵌套。子程序的嵌套結(jié)構(gòu)子程序的遞歸結(jié)構(gòu)

(2)遞歸子程序。在子程序嵌套情況下,若一個子程序所調(diào)用的子程序就是它本身,這種調(diào)用稱為遞歸調(diào)用,該子程序稱為遞歸子程序。遞歸子程序往往用于數(shù)學(xué)領(lǐng)域內(nèi)的對函數(shù)的遞歸定義如求階乘及其它較復(fù)雜的運算。3.子程序設(shè)計舉例例:試用寄存器傳遞參數(shù)法編寫一個子程序,實現(xiàn)大寫字母到小寫字母的轉(zhuǎn)換。解:已知小寫英文字母a、b、c…x、y、z的ASCII碼與大寫英文字母A、B、C…X、Y、Z的ACSII碼相差十六進制常數(shù)20H,故要實現(xiàn)本題轉(zhuǎn)換必須加上20H。源程序如下:STATASEGMENTPARASTACK‘STACK’DW20HDUP(?);STATAENDSDATAASEGMENTSTR1DB‘A’,‘B’‘C’,‘D’‘E’,‘A’,‘B’LENEQU$—STR1STR2DBLENDUP(?);用來存放轉(zhuǎn)換后的小寫字母。DATAAENDSCODEESEGMENTASSUMECS:CODEE,DS:DATAA,SS:STATASTART:MOVAX,DATAAMOVDS,AXMOVBX,OFFSETSTR1MOVCX,LENAGN:MOVAL,[BX]CALLSUBRMOV[BX+LEN],ALINCBXLOOPAGNEXIT:MOVAH,4CHINT21HSUBRPROCNEARCMPAL,‘A’JBEXIT1CMPAL,’Z’JAEXIT1ADDAL,20HEXIT1:RETSUBRENDPCODEEENDSENDSTART例:試用堆棧傳遞參數(shù)法.編寫求某數(shù)據(jù)區(qū)中無符號字數(shù)據(jù)最大值的子程序及其調(diào)用程序。解:要求參數(shù)通過堆棧傳遞,先設(shè)定子程序存取參數(shù)都由BP寄存器間址.源程序如下:STACKKSEGMENTPARASTACK‘STACK’DW32DUP(0)STACKKENDSDATAASEGMENTBUF

溫馨提示

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

最新文檔

評論

0/150

提交評論