




版權說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權,請進行舉報或認領
文檔簡介
第三章匯編語言程序設計概述匯編語言:匯編語言是一種面向計算機的符號語言。用指令的助記符、符號地址、標號、偽指令等書寫程序的語言。匯編語言源程序:用匯編語言書寫的源程序。匯編:將匯編語言源程序翻譯成機器語言程序的過程。匯編程序:完成匯編過程的系統(tǒng)程序。ASM和MASM
3.1匯編語言的基本元素在8086/8088匯編語言中,有兩類匯編語言指令。?一類是執(zhí)行性指令,稱為指令語句,匯編程序匯編后可產(chǎn)生機器指令代碼;?另一類是指示性語句,稱為偽指令,其作用僅僅是告訴匯編程序對源程序中的執(zhí)行性指令應該如何產(chǎn)生代碼,或分配存儲區(qū)。1.標號(標識符Identifiers)
標識符是由程序員定義的具有特定意義的字符序列,是給指令或某一存儲單元地址所起的名字。標識符可由下列字符組成:
字母:A~z;數(shù)字:0~9;特殊字符:?、·、@、_、$。標識符最多為31個字符。數(shù)字不能作標識符的第一個字符。當標識符后跟冒號時,表示是標號。它代表該行指令的起始地址。當標識符后不帶冒號時,表示變量。偽指令前的標識符不加冒號。
[標號]指令助記符[操作數(shù)][;注釋]2.指令助記符
(保留字Reservedwords)
是一類特殊的標識符,可以是8086/8088的指令助記符,也可以是偽指令。如果指令帶有前綴(如LOCK、REP、REPE/REPZ、REPNE/REPNZ),則指令前綴和指令助記符要用空格分開。
[標號]
指令助記符
[操作數(shù)][;注釋]
3.操作數(shù)
指令執(zhí)行的對象。例如:RET;無操作數(shù)
INCCX;一個操作數(shù)
MOVCX,DI;兩個操作數(shù)如果是偽指令,則可能有多個操作數(shù),例如:
COSTDB3,4,5,6,7;5個操作數(shù)當操作數(shù)超過1個時,操作數(shù)之間應用逗號分開。操作數(shù)可以是常數(shù)、寄存器名、標號、變量,也可以是表達式,例如:MOVAX,[BP+4];
[標號]指令助記符[操作數(shù)][;注釋]3.1.2匯編語言的運算符匯編語言運算符所指定的操作由匯編程序在匯編過程中完成,結果作為指令的目標代碼被保存,與程序執(zhí)行時CPU完成的可執(zhí)行指令是兩回事,故匯編語言運算符也稱為偽操作符。匯編語言的運算符有:
?算術運算符:+、–、×、/、MOD(取余數(shù));?邏輯運算符:AND、OR、NOT、XOR;?關系運算符:EQ、NE、LT、GT、LE、GE;?取值運算符和屬性運算符。1.算術運算符和邏輯運算符(1)
算術運算符:
+、–、×、/、MOD算術運算符只能用于數(shù)字量操作數(shù),結果也是數(shù)字量。用于存儲器操作數(shù)時,只有+、-運算符有意義。MOD取模是求數(shù)字量除法所得的余數(shù)。(2)
邏輯運算符:AND、OR、NOT、XOR邏輯運算符的操作只能是數(shù)字的,且結果也是數(shù)字的。存儲器操作數(shù)不能進行邏輯運算。邏輯運算作為運算符時,是在程序匯編時計算的;而作為指令助記符時,則是在程序執(zhí)行時計算的。
2.關系運算符
關系運算符:EQ、NE、LT、GT、LE、GE;相等
EQ(Equal)、不等
NE(NotEqual)、小于
LT(LessThan)、大于
GT(GreaterThan)、小于等于
LE(LessThanorEqual)、大于等于
GE(GreaterThanorEqual)關系運算符連接的兩個操作數(shù),必須都是數(shù)字的或是在同一段內(nèi)的存儲器地址。若關系為假(關系不成立),則結果為0H;若關系為真(關系成立),則結果為0FFFFH。
3.取值運算符(分析運算符)把存儲器地址操作數(shù)分解成它的組成部分。取值運算符有:SEG、OFFSET、TYPE、SIZE和LENGTH?SEG
給出一個變量或標號的段地址;
?OFFSET
給出一個變量或標號的16位偏移量;
?TYPE
返回表示存儲器操作數(shù)內(nèi)存變量和標號類型的數(shù)值。類型byteworddwordqwordtbyteNEARFAR類型值124810-1(FFH)-2(FEH)
?SIZE
取得并返回由DUP定義的內(nèi)存變量的字節(jié)數(shù)。
?LENGTH
取得并返回由DUP定義的內(nèi)存變量基本單元的個數(shù)。格式:SEG﹤符號名﹥OFFSET﹤符號名﹥TYPE﹤符號名﹥
SIZE﹤符號名﹥LENGTH﹤符號名﹥例如:MOVAX,SEGSLOT;將SLOT的段地址送入AX寄存器MOVAX,OFFSETSLOT;將SLOT的偏移地址送入AX寄存器,4.屬性運算符(合成運算符)
屬性運算符用來給指令中的操作數(shù)指定一個臨時屬性,而暫時忽略當前的屬性。
(1)合成運算符PTR
忽略當前操作數(shù)的類型(字節(jié)或字)及屬性(NEAR或FAR),而給出一個臨時的類型或屬性。一般格式如下:類型(或屬性)
PTR操作數(shù)表達式
PTR運算符建立一個存儲器地址操作數(shù),它與PTR右邊的存儲器地址操作數(shù)有相同的段地址與偏移量,其類型由左邊的操作數(shù)決定。
(2)合成運算符THIS
象PTR一樣可用來建立一個特殊類型的存儲器地址操作數(shù),新的存儲器地址操作數(shù)的段和偏移量部分就是下一個能分配的存儲單元的段和偏移量,即匯編程序進行匯編遇到THIS時的當前值。其類型在THIS運算符后面指定。例如:
MY_BYTEEQUTHISBYTEMY_WORDDW?將建立MY_BYTE具有字節(jié)類型,且與MY_WORD具有相同的段和偏移量。(3)段取代運算符
用于在一條指令中以新的段屬性取代舊的段屬性。有兩種格式:
①
段寄存器:地址表達式例如:ADDAX,ES:ALT
②
段名:地址表達式所用的段名事前必須通過ASSUME偽指令與一個段寄存器建立聯(lián)系。例如:
ASSUMEES:EXTRA_DATA
……ADD AX,EXTRA_DATA:ALT(4)短程運算符SHORT
僅用于無條件轉移指令。指出轉移的標號不僅是NEAR型的,并且是在下一條指令的-128~+127個字節(jié)范圍內(nèi)。運算符SHORT事先對標號作了說明,則會匯編成兩字節(jié)的轉移指令,既節(jié)省了單元又加快了執(zhí)行速度。例如:
JMPSHORTH2;H2:MOVAX,01.常數(shù)匯編語言語句中出現(xiàn)的常數(shù)有7種:①二進制數(shù)二進制數(shù)字后跟字母B,如01000001B。②八進制數(shù)八進制數(shù)字后跟字母Q或O,如202Q或202O。③十進制數(shù)十進制數(shù)字后跟D或不注,如85D或85。④十六進制數(shù)十六進制數(shù)字后跟H,如56H,0FFH。注意,當數(shù)字的第一個字符是A~F時,在字符前應添加一個數(shù)字0,以示和變量的區(qū)別。
⑤十進制浮點數(shù)浮點十進制數(shù)如25E-2。⑥十六進制實數(shù)十六進制實數(shù)后跟R,
數(shù)字的位數(shù)必須是8,16或20。在第一位是0的情況下,數(shù)字的位數(shù)可以是9,17或21。如0FFFFFFFFR。
以上第⑤、⑥兩種數(shù)字格式只允許在MASM中使用。⑦字符和字符串字符和字符串要求用單引號括起來,如‘BD’。
2.常量操作數(shù)
常量操作數(shù)是一個數(shù)值操作數(shù),一般是常量或者是常量的標識符。例如常量操作數(shù)有100,PORT,VAL等。數(shù)字常量操作數(shù)可采用二、八、十或十六進制等形式。操作數(shù)值的允許范圍為-65536~+65535。字符串常量操作數(shù)值為相應字符的ASCII碼。常量操作數(shù)是出現(xiàn)在程序中的確定值,它在程序的運行期間不會發(fā)生變化。存儲器操作數(shù)作為存儲單元的地址,有三個屬性:(1)段地址:存儲單元所在段的段地址;(2)偏移地址:存儲單元在所在段內(nèi)的偏移地址;(3)類型:變量的類型是存儲單元所存放數(shù)據(jù)項的字節(jié)數(shù);
標號的類型作為轉移或調用指令的目標操作數(shù)的尋址方式,即NEAR和FAR。標號的默認類型屬性為NEAR。4.常量表達式
常量表達式通常由常量操作數(shù)及運算符構成,在匯編時,產(chǎn)生一個常量。例如:PORT_VAL+1PORT_VALAND20H分析運算符作用于存儲器操作數(shù)所形成的表達式也是常量表達式。例如:
OFFSETSUMSEGSUMTYPECYCLE
1.編寫源程序
用文本編輯程序EDIT.EXE或EDLIN編寫匯編語言源程序,產(chǎn)生擴展名為.ASM的源文件。2.匯編
用匯編語言編寫的源程序經(jīng)過匯編程序MASM.EXE自動翻譯成目標程序,產(chǎn)生擴展名為.OBJ的目標文件;對源程序中使用了非法指令,標號重復,相對轉移超出轉移范圍等非邏輯性錯誤給出提示。8086的匯編程序為ASM-86,擴展后的宏匯編程序為MASM-86,增加了宏處理功能、條件匯編及某些偽指令,且可支持8087協(xié)處理器的操作。匯編程序的主要功能是:1、將匯編語言源程序翻譯成機器語言代碼;2、按程序指定,分配存儲區(qū)域(包括程序區(qū),數(shù)據(jù)區(qū),堆棧區(qū)等);3、將各種進位制數(shù)據(jù)轉換成二進制數(shù);4、把字符轉換成ASCII碼;5、計算出數(shù)值表達式的值;6、對源程序進行檢查,給出程序的語法錯誤信息,如非法格式,未定義的助記符、標號、漏掉操作數(shù)等。3.鏈接
用鏈接程序LINK.EXE將一個或多個.OBJ目標程序進行鏈接,生成擴展名為.EXE的可執(zhí)行程序。4.調試
經(jīng)過上述步驟所獲得的.EXE可執(zhí)行文件,在運行過程中可能出現(xiàn)邏輯錯誤,需對可執(zhí)行文件.EXE進行調試。調試匯編程序最常用的工具是動態(tài)調試程序DEBUG。其中從某地址運行程序、設置斷點、單步跟蹤等功能,可以支持對程序的調試。
3.2偽指令
偽指令語句也稱為指示性語句,是用來對程序的匯編過程進行控制,實現(xiàn)初始化存儲器、定義符號常數(shù)、列表、存儲空間分配等處理。根據(jù)功能的不同,偽指令可分為以下幾種類型:?數(shù)據(jù)定義偽指令?符號定義偽指令?段定義偽指令?過程定義偽指令?宏定義?模塊組織和多模塊連接3.2.1.數(shù)據(jù)定義偽指令該類偽指令用來定義存儲空間及其所存數(shù)據(jù)長度。?DB:定義字節(jié),即每個數(shù)據(jù)是1個字節(jié);?DW:定義字,即每個數(shù)據(jù)占1個字(2個字節(jié));?DD:定義雙字,即每個數(shù)據(jù)占2個字。低字部分在低地址,高字部分在高地址;?DQ:定義4字長,即每個數(shù)據(jù)占4個字;?DT:定義10個字節(jié)長,用于壓縮式十進制數(shù)。例:DATA1DB5,6,8,100,‘ABCD’表示從DATA1單元開始,連續(xù)存放5,6,8,100,共占4個字節(jié)地址。
DATA2DW7,287表示從DATA2單元開始,連續(xù)存放7,287兩個字,共占4個字節(jié)地址。定義一個存儲區(qū)時,也可以不放數(shù)據(jù),如 TABLEDB?;表示在TABLE單元中存放的內(nèi)容是隨機的。05H06H08H64H41H42H43H44H07H00H1FH01H42H41H44H43HDATA1DATA2DATA1DB5,6,8,100,‘ABCD’DATA2DW7,287,‘AB’,‘CD’DATA3DD‘ABCD’,‘CD’44H43H42H41H44H43H00H00HDATA3
當定義一個存儲區(qū)內(nèi)的每個單元要放置同樣的數(shù)據(jù)時,可用DUP操作符,一般格式為:COUNTDUP(?);COUNT為重復的次數(shù),?為要重復的數(shù)據(jù)。如:BUFFERDB100DUP(0);表示以BUFFER為首地址的100個字節(jié)中存放00H
BUFFER1DB100DUP(3,5,2DUP(10),35),24,‘NUM’表示以BUFFER1為首地址的區(qū)域存放(3,5,10,10,35)100次,和24,‘NUM’3.2.2
符號定義偽指令
?等值偽指令EQU
給左邊符號定義一個值。該值可以是任何有效的操作數(shù)表達式,如一個常數(shù)、另一個符號名或地址表達式,甚至一個指令助記符。在程序中,凡是出現(xiàn)該符號的地方,匯編時均用該值代替。如:TIMESEQU50 ;TIMES=50DATADBTIMESDUP(?)FIRSTEQUSECOND+1 ;FIRST=SECOND+1
ADD1EQUADD ;為ADD指定一個別名ADD1
?解除偽指令PURGE用于釋放由EQU偽指令定義的符號變量,這樣這些變量就可以被重新定義。EQU偽指令定義的符號在PURGE偽指令解除前,不能重新定義。
例:PURGE符號名1,符號名2,…符號名N?等號賦值偽指令“=”
功能與EQU相似,能對已定義的符號名重新定義而無須先釋放。
TIMES=50;FIRST=SECOND+1;
ADD1=ADD;
3.2.3段定義偽指令一個完整的匯編源程序由代碼段、堆棧段、數(shù)據(jù)段,有時還有附加段所組成。段定義偽指令可將源程序劃分成若干段,以便匯編和連接時將各同名段進行組合。
段定義偽指令一般格式為:段名SEGMENT[定位類型][組合類型][類別]
……;段體內(nèi)容,由指令及偽指令組成。段名ENDSSEGMENT和ENDS應成對使用,缺—不可。
①段名:段名是不可省略的,是給定義的段所起的名稱。例如:STACKSEGMENTSTACKDW20DUP(?)STACKENDS②定位類型:表示該段起始地址位于何處。字節(jié)型(BYTE),段起始地址可位于任何地方;字型(WORD),段起始地址必須位于偶地址;節(jié)型(PARA),即段起始地址必須能被16除盡;頁型(PAGE),即段起始地址可被256除盡;
缺省時,段起始地址便定位為PARA型的。
③組合類型:組合類型用于告訴連接程序,該段和其它段的組合關系。連接程序可以將不同模塊的同名段進行組合。組合類型有:
NONE——表明本段與其它段邏輯上不發(fā)生關系,省略時,便指定為這一組合類型。PUBLIC——與其它模塊中用PUBLIC說明的同名段按先后連接成一個邏輯段,使用同一個物理段地址。STACK——將具有STACK類型的同名段連接成一個大的堆棧,由各模塊共享。COMMON——與其它模塊中由COMMON說明的所有同名段連接時,被重疊放在一起,其長度是同名段中最長者的長度。
MEMORY——由MEMORY說明的段。在連接時,它被放在所裝載程序的最后存儲區(qū)(最高地址)。若幾個段都有MEMORY組合類型,則連接程序只認定首先遇到的段具有MEMORY組合類型,其它段則認為是COMMON類型,并被疊放在一起。AT表達式——段地址是表達式所給定的值。在程序中就可由用戶直接來定義段地址。但這種方式不適用于代碼段。④類別:是用單引號括起來的字符串,以表明該段的類別。如代碼段(CODE)、數(shù)據(jù)段(DATA),堆棧段(STACK)等。各模塊中同一類型的段可能具有不同的名字,連接時將同類別的段(但不一定同名)放在連續(xù)的存儲區(qū)內(nèi)。上述的組合類型便于多個模塊的連接。若程序僅有一個模塊,即只包括代碼段、數(shù)據(jù)段和堆棧段時,為了和其它段有區(qū)別,除了堆棧段用STACK說明外,其它段的組合類型、類別均可省略。例如有兩個模塊:模塊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
設定段寄存器偽指令ASSUME——段寄存器定義偽指令。用于建立段名和段寄存器之間的嚴格對應關系??赏ㄖ獏R編程序哪一個段寄存器是當前段的段寄存器,以便對使用變量或標號的指令匯編出正確的目的代碼。其格式為:ASSUME段寄存器:段名[,段寄存器:段名,…]ASSUME偽指令只是指明某一個段地址與段寄存器的聯(lián)系,沒有將段地址送入該寄存器的操作。因此要將段地址裝入段寄存器還需用匯編指令來實現(xiàn)。
例如:CODESEGMENTASSUMECS:CODE,DS:DATA,SS:STACKMOVAX,DATA;DATA段值送AXMOVDS,AX;AX內(nèi)容送DS,本指令執(zhí)行完之后,DS才為實際段值CODEENDS由于DOS的裝入程序負責把CS初始化成正確的代碼段地址,SS初始化為正確的堆棧段地址,在程序中就不必設置。但DS數(shù)據(jù)段或ES附加段必須MOV指令對DS和ES進行初始化,以裝入段地址。3.2.5ORG
偽指令
ORG:偽指令用于指定段內(nèi)程序或數(shù)據(jù)代碼存放的起始偏移地址,即用語句中表達式的值作為起始偏移地址,此后的程序或數(shù)據(jù)代碼將連續(xù)存放,除非遇到另一個新的ORG語句。一般格式為:
ORG<表達式>例如:DATA SEGMENT BUFF1 DB 23,56H,‘EOF’ ORG 2000H BUFF2 DB ‘STRING’ DATA ENDS3.2.6
定義過程的偽指令
具有一定功能的程序段作為一個過程(相當于一個子程序)??梢员粍e的程序調用(用CALL指令)或由JMP指令轉移到此執(zhí)行;也可以由程序順序執(zhí)行;或作為中斷處理程序,在中斷響應后轉此執(zhí)行。一個過程由偽指令PROC和ENDP來定義。其格式為:過程名PROC[類型](FAR/NEAR,缺省為NEAR)
………
RET過程名ENDP
過程體內(nèi)至少應有一條RET指令。過程可以嵌套,也可以遞歸使用,即過程可以調用過程或本身。過程體例如:延時100ms的過程,可定義如下:DELAYPROCPUSHBXPUSHCXMOVBL,10AGAIN:MOVCX,2801;延時10msWAI:LOOPWAIDECBLJNZAGAINPOPCXPOPBXRETDELAYENDPCODE1SEGMENTASSUMECS:CODE1FARPROCPROCFAR
……RETFARPROCENDPCODE1ENDS
CODE2SEGMENTASSUMECS:CODE2CALLFARPROC…...……CALLNEAR…………NEARPROCNEAR…………RETNEAR ENDPCODE2ENDS3.2.7宏指令
若程序段要多次使用,為了簡化程序書寫,該程序段可以用一條宏指令來代替,而匯編程序匯編到該宏指令時,仍會產(chǎn)生源程序所需的代碼。
宏指令的一般格式為:宏指令名MACRO[形式參量表]宏體
ENDM宏指令與子程序都是可完成某種功能的,供調用的程序模塊。定義后可多次調用。但子程序只形成一段目的代碼,調用時轉來執(zhí)行。而宏指令是將形成的目的代碼插到主程序調用的地方。例如:GADDMACROX,Y,ADD1MOVAX,XADDAX,YMOVADD1,AXENDM其中X,Y,ADD1都是形式參量。調用時,用下面宏指令書寫格式:
GADDDATA1,DATA2,SUM這里DATA1,DATA2,SUM是實參量。實際上與該宏指令對應的源程序為:
MOVAX,DATA1ADDAX,DATA2MOVSUM,AX3.2.8匯編結束偽指令
END偽指令表示源程序的結束。每個源程序模塊必須且只能用一條END偽指令指明結束位置,匯編程序遇到END時立刻停止匯編。其一般格式為:
END[表達式]其中表達式是可選項,表示該匯編程序模塊的啟動地址。例如:
ENDSTART則表明該程序的啟動地址為START。3.3匯編語言程序設計
程序設計是應用計算機解決實際問題的重要環(huán)節(jié)。一個優(yōu)秀的程序設計的標準為:?程序結構清晰合理,易于理解和維護;?程序執(zhí)行時間短;?源程序的語句行少;?程序存儲的字節(jié)數(shù)少;這些要求可通過選擇算法和優(yōu)化程序結構來實現(xiàn)。3.3.1匯編語言程序設計概述一、匯編語言程序的基本結構框架匯編語言源程序由可執(zhí)行的指令語句和指示性的偽指令組成。在匯編語言源程序至少包括三段:代碼段、數(shù)據(jù)段、堆棧段,必要時還有附加段。二、匯編語言程序設計的基本步驟
1.分析實際問題,建立解決問題的模型;2.確定解決問題的算法、方法和步驟;3.根據(jù)算法畫出程序流程圖,即將解決問題的思路用圖形表示。4.對程序中的數(shù)據(jù)的組織、存儲單元分配、寄存器使用規(guī)劃等進行統(tǒng)一考慮和安排。5.根據(jù)程序流程圖編寫程序;6.程序檢查、調試與修改;三、匯編語言程序的基本結構程序根據(jù)Boehm和Jacobi的結構定理,任何程序可以由三種最基本的結構程序構成,如下圖:順序結構程序分支結構程序循環(huán)結構程序每個結構程序只有一個入口和一個出口,通過三種結構的組合和嵌套可構成任何復雜的結構化程序。3.3.2順序結構程序設計
順序程序設計是沒有分支,沒有循環(huán)的直線運行程序,程序執(zhí)行按照IP自動增加的順序進行。例1:利用查表法計算平方值。已知0~9的平方值連續(xù)存在以SQTAB開始的存儲區(qū)域中,求SUR單元內(nèi)容X的平方值,并放在DIS單元中。假定0≤X≤9且為整數(shù)。解:(1)了解平方表的存放位置;
(2)根據(jù)X的值,找到X對應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;計算地址偏移 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,代碼段如下:結束用戶程序返回DOS的方法1.系統(tǒng)功能調用INT21H的4CH號子功能在用戶程序結束處用以下語句:
MOVAH,4CHINT21H2.利用RET指令上面的例子中所采用的方法。3.程序轉移到內(nèi)存中偏移量為0的地方
JMP04.利用中斷調用
INT20HBEGIN:MOVAX,DATA MOVDS,AX LEABX,SQTAB MOV AL,SUR;AL=X XLAT SQTAB MOV DIS,ALMOVAH,4CHINT21HCODEENDS END BEGIN利用系統(tǒng)功能調用INT21H的4CH號子功能返回DOS3.3.3分支結構程序設計
分支結構程序的基本思想是根據(jù)某些條件和狀態(tài)來控制程序下一步的走向。首先執(zhí)行能影響狀態(tài)的指令,如算術邏輯運算指令、移位指令或位操作指令,然后用條件轉移類指令對各種狀態(tài)標志進行判斷,進而轉移形成分支。設計分支結構程序一般有兩種方法:?比較/測試分支結構法;?跳轉表分支結構法;1.比較/測試分支結構法
采用比較指令CMP和測試指令TEST,產(chǎn)生相應的狀態(tài)標志,選擇適當?shù)臈l件轉移指令,實現(xiàn)不同情況的分支轉移。一條轉移指令產(chǎn)生兩路分支,n條轉移指令可產(chǎn)生n+1條分支。=0?BX=0BX=1BX=–1YY
>0?例1實現(xiàn)符號函數(shù)。1X>0Y=0X=0
–1X<0根據(jù)上述要求的程序段為:START: MOV AX,BUFFER;取變量X OR AX,AX;產(chǎn)生狀態(tài)標志 JE ZERO;X=0則轉移 JNS PLUS;X為正則轉移 MOV BX,0FFFFH;BX=–1 JMP CONT1;轉向出口ZERO: MOV BX,0 JMP CONT1PLUS: MOV BX,1CONT1:……2.跳轉表分支結構法
當分支數(shù)較多時,將各個分支的入口地址組成跳轉表,再根據(jù)某個變量的不同取值情況,從表中取出相應的入口地址,實現(xiàn)各分支轉移。例2:根據(jù)AL中各位被置位情況,控制轉移到8個子程序P1~P8其中之一。
條件1成立?P1P2Pn+1YY條件2成立?條件n成立?┇YPn子程序分支轉移跳轉表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
若跳轉表中的內(nèi)容由JMPOPRD轉移指令構成,則不能將跳轉表的內(nèi)容作為轉移的目標地址直接取出。先根據(jù)給定的參數(shù)值第一次跳轉到表中的對應項,然后執(zhí)行跳轉表中的JMPOPRD轉移指令,第二次跳轉到對應的子程序段。注意:?跳轉表中每一條跳轉指令占三個字節(jié)。?第一次跳轉的目標地址在BX中,JMPBX。
?跳轉表中是JMPOPRD轉移指令,故跳轉表在代碼段中。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;暫時保存SAL BX,1;左移乘二 ADD BX,AX;加上原數(shù),完成乘三
ADDBX,OFFSETTABLE;加上表首址JMP BX;第一次跳到跳轉表中的對應項TABLE:JMPSR0;JMPSR1;在代碼段中的跳轉表,JMPSR2;進行第二次跳轉,執(zhí)行跳轉表中
…………;的轉移指令。JMPSR7;SR0:…… JMP GETADSR1: …… JMP GETAD…………GETAD:MOV AH,4CHINT 21HCODE ENDS3.3.4循環(huán)結構程序設計在實際應用中,要求某個操作重復執(zhí)行多次,可利用循環(huán)程序結構,來減少源程序的長度。循環(huán)結構程序通常由以下幾個部分組成:1.循環(huán)初始化部分:地址指針、循環(huán)次數(shù)、相關寄存器及標志的清零和設置。2.循環(huán)體:循環(huán)體是要求重復執(zhí)行的程序段部分。3.循環(huán)控制部分:每進行一次循環(huán),由該部分修改并判斷控制循環(huán)的條件是否滿足。以決定是否繼續(xù)循環(huán)。4.循環(huán)結束部分:進行循環(huán)的后續(xù)處理,如保存循環(huán)運行結果等,這部分不是必須的。
循環(huán)程序有兩種結構形式:1.DO-WHILE結構,先判斷后執(zhí)行循環(huán)體。2.DO-UNTIL結構,先執(zhí)行循環(huán)體后判斷。
DO-WHILEDO-UNTIL滿足條件?
循環(huán)體工作部分循環(huán)體結束循環(huán)體修改部分循環(huán)初始化部分YN滿足條件?循環(huán)體結束循環(huán)體修改部分
循環(huán)體工作部分循環(huán)初始化部分YN例4設內(nèi)存BUFF開始的單元中依次存放著30個8位無符號數(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在給定個數(shù)的16位數(shù)串中,找出大于零、等于零和小于零的個數(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為字數(shù) MOVDX,0 MOVAX,0 LEA BX,BUFFAGAIN:CMPWORDPTR[BX],0 JAE PLU;大于等于0轉移到PLU INC AH;計小于0的個數(shù) JMP NEXTPLU: JZ ZER;等于0轉到ZER INC DL;計大于0的個數(shù) JMP NEXTZER: INC DH;計等于0的個數(shù)NEXT:INC BX;修改地址指針 INC BX LOOPAGAIN;循環(huá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的個數(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的個數(shù) MOV BX,ADDR;取Y的地址到BX MOV AX,[BX];取16位數(shù)YREPEAT: TEST AX,0FFFFH;結果是否為0 JZ EXIT;結果為0則結束 JNS SHIFT;最高位為0則轉左移1位 INC CX;最高位為1則計數(shù)一次SHIFT: SHL AX,1;左移1位準備下一循環(huán) JMP REPEATEXIT: MOV COUNT,CX; RETMAIN ENDPPROGRAM ENDS END START例7軟件延時程序(多重循環(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控制延時時間。如:假定DELAY是延時100ms程序,則延時10s的程序可寫為:MOV BX,100 CALL DELAY;延時10秒例8在DS所決定的數(shù)據(jù)段,從偏移地址BUFFER開始順序存放100個無符號16位數(shù),現(xiàn)要編寫程序將這100個字數(shù)據(jù)從大到小排序。氣泡排序算法(從大到小或從小到大)從第一個數(shù)開始依次對相鄰兩個數(shù)比較,若次序對時,則不做任何操作,如次序不對,則使這兩個數(shù)交換位置。這種算法稱為氣泡算法。 序號 數(shù) 第一遍第二遍第三遍第四遍1 8 8 16 3284 2 5 16 32 8432 3 16 32 84 16164 32 84 8 885 84 5 555
第一遍進行4(N-1次)比較,最小數(shù)已到最下面,第二遍進行3(N-2次)比較,依次類推,最多進行N-1遍即可完成排序。minSI指向首地址CL←比較次數(shù)AX←當前數(shù)[SI]→下一個數(shù)AX–[SI][SI–2]←[SI][SI]←AXAX>[SI]?一次排序結束?總排序結束?YNNYYAX[SI]程序如下:
LEA DI,BUFFER;取首地址 MOV BL,99;須經(jīng)N-1次排序NEXT0:MOV SI,DI;SI恢復指向首地址 MOV CL,BL;每次排序的比較次數(shù)NEXT3:MOV AX,[SI];當前16位數(shù)放在AX中 ADD SI,2;SI指向下一個16位數(shù) CMP AX,[SI];當前數(shù)與下一個數(shù)比較 JNC NEXT5;大于等于則不交換 MOV DX,[SI];小于則交換 MOV [SI–2],DX;可XCHG[SI],AX MOV [SI],AX;MOV[SI-2],AXNEXT5:DEC CL;計算比較次數(shù) JNZ NEXT3 DEC BL;每次排序的比較次數(shù)減一 JNZ NEXT0 HLTLEA DI,BUFFER;取首地址 MOV COUNT,100;排序元素的個數(shù)CLD;地址遞增排序NEXT1:MOV BX,1;交換標記DEC COUNT;每次排序的比較次數(shù)減一JZ EXIT;比較次數(shù)為0則結束MOV SI,DI;SI恢復指向首地址 MOV CX,COUNT;每次排序的比較次數(shù)NEXT2:LODSW;當前數(shù)→AX,SI→下一個數(shù) CMP AX,[SI];當前數(shù)與下一個數(shù)比較 JNC NEXT3;大于等于則不交換 XCHG [SI],AX;小于則交換 MOV [SI–2],AX;大數(shù)存入上一位置 XOR BX,BX ;有交換則交換標記清零NEXT3:LOOP NEXT2;一次排序是否結束? CMP BX,0;一次排序是否有交換? JE NEXT1;有交換則繼續(xù)EXIT:MOV AX,4C00H INT 21H3.3.5
子程序設計
子程序是常用的程序結構,將頻繁使用的功能寫成子程序的形式,可使源程序及目標程序縮短,提高效率和可靠性。在8086/8088中,子程序和過程的含義是一致的。?主程序可多次調用一個或多個子程序;?子程序可被多個主程序調用,也可再調用其他子程序;?子程序調用子程序,稱子程序嵌套;調用自己稱遞歸調用;?子程序調用時,CPU自動將調用時的斷點壓入堆棧保存;?子程序調用時,由程序將要用到寄存器內(nèi)容壓入堆棧保護;子程序返回前,將壓入堆棧的寄存器內(nèi)容彈出,恢復現(xiàn)場;
編寫子程序有以下幾點基本要求:1.子程序必須有一定的通用性,確定入口參數(shù)和出口參數(shù)。2.選用適當?shù)姆椒ㄟM行主程序和子程序間參數(shù)的傳遞。
①利用寄存器進行參數(shù)傳遞
。例9
②利用存儲單元按事先約定的規(guī)則進行參數(shù)傳遞
。
③利用堆棧進行參數(shù)傳遞。例103.注意現(xiàn)場信息的保護和恢復,最好在子程序中進行保護。4.正確使用堆棧。子程序嵌套較多時,使用堆棧要仔細。5.編制子程序文件,主要包括以下內(nèi)容:
①子程序的名稱;
②子程序的功能描述;
③子程序的入口參數(shù)和出口參數(shù)
;
④子程序所使用的寄存器和存儲單元列表,對其作用描述;
⑤本子程序所調用的其他子程序列表;
⑥子程序調用形式舉例;9例9兩個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;完成一個字節(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的值,轉換為4個ASCII碼表示的十六進制數(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…調用時IP低調用時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高調用時IP低調用時IP高NUMBER低NUMBER高STRING低STRING高原棧頂$AGAIN: AND AX,000FH;保留后四位 CALL HEXD;轉換成ASCII碼 STD;從后向前 STOSB;存串 PUSH CX;保存循環(huán)次數(shù) MOV CL,4 SHR DX,CL;對25AFH右移四位 MOV AX,DX; POP CX;恢復循環(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位加法,有兩個64位數(shù)相加,和放在BUFFER緩沖區(qū)中(不考慮進位)。參數(shù)放在存儲單元中。程序如下: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!=這是一個遞歸定義式,1在程序設計時,可采用子程序的的遞歸調用形式。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與高級語言的接口MASM與多種高級語言均可以混合編程,介紹一種TurboC調用匯編的過程,說明在匯編中應如何編寫程序,C中如何調用程序。一般來說,在高級語言中使用匯編語言主要有以下幾個原因:(1)為了提高程序某些關鍵部分的執(zhí)行速度,可以用匯編語言來使關鍵代碼段的時鐘周期最短;(2)完成一些高級語言中難以實現(xiàn)的功能,如高分辨率繪圖;(3)使用已經(jīng)開發(fā)的匯編語言模塊;
1.TurboC與匯編語言的接口方法當TurboC調用匯編語言程序時,匯編程序指令序列必須具備一定的順序,該順序可描述為:正文段描述;段模式;組描述;進棧;程序體;退棧;正文段結束。例設有一個TurboC程序從鍵盤上獲得兩個數(shù),并將其傳給匯編語言子程序ASMTC.ASM完成兩個數(shù)相乘并返回乘積,然后在TurboC程序中將結果顯示在屏幕上。
先建立一個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()是調用匯編語言子程序的函數(shù),該函數(shù)中包括三個參數(shù),前兩個為整型數(shù),第三個為長整型數(shù)指針。
由上述TurboC主程序調用的匯編語言ASMTC.ASM的子程序如下:
PUBLIC
asmtcTEXTSEGMENTBYTEPUBLIC‘CODE’DGROUPGROUPDATA,BSSDATASEGMENTWORDPUBLIC’DATA‘DATAENDSBSSSEGMENTWORDPUBLIC’BSS’BSSENDSASSUMECS:TEXT,DS:DOROUP,SS:DOROUPasmtcprocnear
pushbpmovbp,sppushsimovax,[bp+4];/*得到第一個參數(shù)i*/movbx,[bp+6];/*得到第二個參數(shù)j*/mulbx;/*兩數(shù)相乘*/
movsi,[bp+8];/*得到參數(shù)k的地址*/
mov[si],ax;/*送乘積的低位兩個字節(jié)*/
incsiincsimov[si],dx;/*送乘積的高位兩個字節(jié)*/popsipopbpRetasmtcendpTEXTENDSEND2.自動產(chǎn)生匯編語言的框架TurboC提供了一種自動產(chǎn)生匯編語言框架的方法。下面舉例說明。首先用TurboC寫一個與調用匯編程
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 重慶八中學、九十五中學等校2024-2025學年普通中考第一次適應性檢測試題物理試題含解析
- 新疆應用職業(yè)技術學院《企業(yè)與公司制度》2023-2024學年第二學期期末試卷
- 河北省滄州任丘市重點中學2024-2025學年初三考前全真模擬密卷化學試題試卷(1)含解析
- 山東省濰坊市寒亭達標名校2025屆初三省重點高中三校聯(lián)考語文試題試卷含解析
- 廈門大學《流行歌曲演唱》2023-2024學年第二學期期末試卷
- 西南交通大學希望學院《節(jié)奏訓練III》2023-2024學年第一學期期末試卷
- 浙江省金華市重點中學2025年高三下學期5月月考數(shù)學試題含解析
- 浙江東方職業(yè)技術學院《城市綠地系統(tǒng)規(guī)劃》2023-2024學年第二學期期末試卷
- 寧德職業(yè)技術學院《生物分離工(全英文)》2023-2024學年第二學期期末試卷
- 南陽理工學院《中國音樂史與作品欣賞》2023-2024學年第二學期期末試卷
- 提升應急管理能力課件
- 高一化學必修一測試試卷
- 軋機安裝施工方案
- 2021年赤峰龍韻城市建設有限公司招聘筆試試題及答案解析
- 引氣減水劑檢測結果
- 醫(yī)療器械培訓記錄
- 河長制培訓課件
- 同濟醫(yī)院檢驗科ISO15189體系文件15標本轉運操作指導書(運送人員培訓)
- 幼兒園中班故事《龜兔賽跑》教學課件
- DB65∕4349-2021 棉漿粕和粘膠纖維工業(yè)水污染物排放標準
- 《鐵道概論鐵路車站》PPT課件
評論
0/150
提交評論