匯編語言程序設計_第1頁
匯編語言程序設計_第2頁
匯編語言程序設計_第3頁
匯編語言程序設計_第4頁
匯編語言程序設計_第5頁
已閱讀5頁,還剩127頁未讀 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

第4章匯編語言程序設計匯編語言的特點:利用匯編語言可以設計出效率較高的核心底層程序,如設備驅(qū)動程序;用匯編語言編寫的程序一般比用高級語言編寫的程序執(zhí)行得快,且占內(nèi)存較少;匯編語言程序能夠直接有效地利用機器硬件資源,在一些實時控制系統(tǒng)中更是不可缺少和代替的;學習匯編語言是進行計算機應用系統(tǒng)設計的先決條件。匯編語言的應用70%以上的系統(tǒng)軟件是用匯編語言編寫的某些快速處理、位處理、訪問硬件設備等高效程序是用匯編語言編寫的某些高級繪圖程序、視頻游戲程序是用匯編語言編寫的匯編語言是我們理解整個計算機系統(tǒng)的最佳起點和最有效途徑主要內(nèi)容:匯編語言源程序的結(jié)構匯編語言的語句與格式偽指令功能調(diào)用匯編語言程序設計4.1匯編語言源程序了解:計算機的三種語言源程序的結(jié)構匯編語言語句格式計算機設計語言機器語言匯編語言高級語言面向機器的語言機器語言匯編語言高級語言面向算法、過程或?qū)ο蟮恼Z言匯編程序匯編語言源程序用助記符編寫源程序的編譯程序匯編程序匯編語言源程序機器語言目標程序匯編語言程序設計與執(zhí)行過程輸入?yún)R編語言源程序源文件.ASM匯編(編譯)目標文件.OBJ鏈接可執(zhí)行文件.EXE調(diào)試最終程序匯編語言上機過程YYYNNN有錯

?有錯?有錯

?結(jié)束匯編輸入(修改)源程序連接運行查錯開始用EDIT,NOTEPAD等任何文本編輯器。源程序存為.ASM文件用MASM宏匯編程序進行匯編。匯編后生成.OBJ目標文件。命令格式:MASM<源文件名.ASM>;用LINK連接程序進行連接。連接后生成.EXE可執(zhí)行文件。命令格式:LINK<目標文件名.OBJ>;用TD、DEBUG等調(diào)試程序進行調(diào)試。命令格式:TD<可執(zhí)行文件名.EXE>數(shù)據(jù)段名SEGMENT…數(shù)據(jù)段名ENDS附加段名SEGMENT…附加段名ENDS堆棧段名SEGMENT…堆棧段名ENDS代碼段名SEGMENT…代碼段名ENDSEND

4.1.1匯編語言源程序的結(jié)構

匯編語言的語句有兩種:指令性語句——由8086指令助記符構成的語句指示性語句——由偽指令構成的語句指令性語句的格式為:[標號:]

[前綴]

指令助記符

[目的操作數(shù),源操作數(shù)][;注釋]指示性語句的格式為:[名字]

偽指令

[操作數(shù)1,操作數(shù)2,…,操作數(shù)n][;注釋]

4.1.2匯編語言的語句與格式各部分之間至少要用一個空格作為分隔符指令性語句由CPU執(zhí)行,每一條指令性語句都有一條機器碼指令與其對應;

指示性語句由匯編程序執(zhí)行。它指出匯編程序應如何對源程序進行匯編,如何定義變量、分配存儲單元以及指示程序開始和結(jié)束等。指示性語句無機器碼指令與其相對應。

指令性語句匯編時生成機器碼;指示性語句匯編時不生成機器碼。語句的構成元素:標號——指令的符號地址,用來代表指令在存儲器中的地址。只能出現(xiàn)在指令性語句中,標號后應加上冒號。名字——段、過程、變量的名字,用來代表它們在存儲器中的地址。只能出現(xiàn)在指示性語句中,名字后不加冒號。指令助記符——8086助記符、偽指令操作數(shù)——即指令的操作對象對指令性語句——0,1,2個對指示性語句——根據(jù)需要而定操作數(shù)之間以逗號分隔操作數(shù)可以是:寄存器、存儲單元、常數(shù)或表達式

例如:AX,[DI+BX+10],200,16*8+TABLE,等等注釋——以分號開頭,可放在指令后,也可單獨一行。

注意注解的寫法。要寫指令(段)在程序中的作用,而不要寫指令的操作。

例如:以下為同一條指令寫的注釋

1)MOVCX,100;傳送100到CX2)MOVCX,100;循環(huán)計數(shù)器置初值顯然,第二種寫法要比第一種寫法要好。匯編語言的一個實例:hello.asm

dataSEGMENTHelloDB‘Hello,world!’,0DH,0AH,’$’dataENDSprogSEGMENTASSUME

CS:prog,DS:datastart:MOVAX,dataMOVDS,AX

LEADX,hello

;取字符串首地址

MOVAH,9INT21H ;顯示字符串

MOVAH,4CHINT21H ;退回DOSprogENDSENDstart名字標號寄存器存儲器單元常量變量或標號表達式4.1.3數(shù)據(jù)項與表達式常量數(shù)字常量字符串常量:用引號引起的字符或字符串例:‘A’,’ABCD’匯編時被譯成對應的ASCII碼41H,42H,43H,44H標號的屬性:

段地址:即標號所在段的段地址;

偏移量:標號所代表存儲單元的段內(nèi)偏移地址;

類型:NEAR或FAR:

NEAR—表示標號所在語句與轉(zhuǎn)移指令/

調(diào)用指令在同一碼段內(nèi),跳轉(zhuǎn)時只需改變IP即可。

FAR—標號所在語句與轉(zhuǎn)移指令/調(diào)用指令不在同一代碼段內(nèi)。

若沒有對類型進行說明,默認為NEAR。標號通常作為轉(zhuǎn)移指令或CALL指令的轉(zhuǎn)移地址。標號變量代表內(nèi)存中的數(shù)據(jù)區(qū),程序中視為存儲器操作數(shù)變量的屬性:段值變量所在段的段地址偏移量變量所在段的起始地址到變量地址之間的字節(jié)數(shù)類型字節(jié)型、字型和雙字型變量在程序中作為存儲器操作數(shù)被引用標號和變量名的使用規(guī)則組成:A-Z(不分大小寫),0-9,?@._$不能以數(shù)字開頭,圓點(.)只能作為首字符長度小于31個字符不能與保留字(指令助記符、偽指令、預定義符號等)重名不能重復定義例如:

正確的:LP1,AGAIN,NEXT,_GO,OK_1

錯誤的:4M,LOOP,AAA,#HELP,+ONE表達式表達式是常數(shù)、寄存器、標號、變量與運算符的組合。有數(shù)字表達式和地址表達式兩種。匯編時按優(yōu)先規(guī)則對表達式進行計算,計算出具體的數(shù)值或地址。運行時不能改變。表達式中的運算符有6類:算術、邏輯、關系、取地址、屬性、其它類。算術運算符邏輯運算符關系運算符取值運算和屬性運算符其它運算符用于數(shù)字表達式,例:

MOVAX,4*1024匯編后的形式為:MOVAX,4096用于地址表達式,例:LEASI,TAB+3若TAB的偏移地址為1000H,則匯編后的形式為:

LEASI,[1003H]算術運算符——+、-、*、/,MOD邏輯運算符只能用于數(shù)字表達式中。例:MOV CL,36HAND0FH

經(jīng)匯編后:MOVCL,06H注意,不要把邏輯運算符與邏輯運算指令混淆:例:ANDAX,3FC0HAND0FF00H

匯編后源操作數(shù)被翻譯為:3F00H,所以上述指令與ANDAX,3F00H等價。邏輯運算符——AND、OR、XOR、NOT關系運算的結(jié)果是一個邏輯值:真或假關系為真,結(jié)果為全1

關系為假,結(jié)果為全0例:MOVBX,PORTGT300H

若PORT的值大于300H,則匯編后為:

MOVBX,0FFFFH

否則匯編后為:

MOVBX,0關系運算符——EQ、NE、LT、GT、LE、GE取值運算符OFFSET取得其后變量或標號的偏移地址SEG取得其后變量或標號的段地址TYPE取變量的類型LENGTH取所定義存儲區(qū)的長度SIZE取所定義存儲區(qū)的字節(jié)數(shù)取值運算符例MOVAX,SEGDATAMOVDS,AXMOVBX,OFFSETDATA

LEABX,DATA等價于取值運算符例若BUFFER存儲區(qū)是用如下偽指令定義:

BUFFERDW200DUP(0)

則:

TYPEBUFFER 等于2LENGTHBUFFER 等于200SIZEBUFFER 等于400屬性運算符——PTR用來指定地址操作數(shù)的類型格式:<類型>PTR<地址操作數(shù)>

類型∈{BYTE,WORD,DWORD,NEAR,FAR}BYTE、WORD、DWORD

用于描述數(shù)據(jù)存儲單元(變量)地址NEAR、FAR

用于描述轉(zhuǎn)移、調(diào)用的目的地址例:MOV BYTEPTR[DI],0;字節(jié)類型

MOV WORDPTR[DI],0;字類型

MOV [DI],0B5H;類型不定PTR也可用來進行強制類型轉(zhuǎn)換例:STR1DW? ;STR1定義為字類型

MOV AX,STR1;合法

MOV AL,STR1;非法

MOVAL,BYTEPTRSTR1;合法其它運算符方括號

[]方括號中內(nèi)容為操作數(shù)的偏移地址段重設符:段寄存器名:[]用于修改默認的段基地址4.2偽指令由匯編程序執(zhí)行的“指令系統(tǒng)”用于定義變量、分配存儲區(qū)、定義邏輯段、指示程序開始和結(jié)束等常用偽指令數(shù)據(jù)定義偽指令符號定義偽指令段定義偽指令結(jié)束偽指令過程定義偽指令宏定義偽指令4.2.1數(shù)據(jù)定義偽指令用于定義數(shù)據(jù)區(qū)中變量的類型格式:[變量名]偽操作操作數(shù)[,…];注釋某些情況下可省略可選偽指令助記符DB定義的變量為字節(jié)型DW定義的變量為字類型(雙字節(jié))DD定義的變量為雙字型(4字節(jié))DQ定義的變量為四字型(8字節(jié))DT定義的變量為10字節(jié)型DATA1DB11H,22H,33H,44HDATA2DW11H,22H,3344HDATA3DD11H*2,22H,33445566H以上變量在內(nèi)存中的存放形式偽指令的性質(zhì)決定所定義變量的屬性定義字符串必須用DB偽指令例:

DATA1DB‘ABCD’,66H‘A’‘B’‘C’‘D’41H42H43H44H66H重復操作符DUP為一個數(shù)據(jù)區(qū)的各單元設置相同的初值格式:

[變量名]偽指令助記符nDUP(初值,…)例:

DW20DUP(0)

DB3DUP(22H,11H,?)隨機數(shù)用?預留存儲空間MEM1DB34H,’A’,?,?,?MEM2DW20DUP(?)預留40個字節(jié)單元例:DATA_BDB10,5,10HDATA_WDW100H,-4DATA_DDD0FFFBH匯編后的內(nèi)存分配情況如右圖所示。05H10H00H01HFCHFFHFBHFFH00H00H0AHDATA_BDATA_WDATA_D10510H100H-40FFFBH例:操作數(shù)可以是字符串,例如

STRDB ‘HELLO’匯編后的情況如圖:STR‘H’‘E’‘L’‘L’‘O’注意下面兩個定義的不同之處:DB ‘AB’ ;41H在低字節(jié),42H在高字節(jié)DW‘AB’;42H在低字節(jié),41H在高字節(jié)48H45H4CH4CH4FH例:TABLEDB10DUP(?)BUFFERDWTABLE,$+3設TABLE的偏移地址為0080H,則匯編后如下圖所示:BUFFER0080H80HTABLE008AH008BH008CH008DH...8FH00H00H0089H10Bytes4.2.2符號定義偽指令把一個表達式用一個符號表示,以后凡出現(xiàn)該表達式的地方都可用這個符號表示。符號定義偽指令有兩種:EQU,=用EQU定義的符號未清除前,不能重新定義。清除EQU定義可用PURGE偽指令。用”=”定義的符號可在任何時候進行重定義。二者均不占用存儲空間,僅是給符號賦值

例:FIVEEQU5

COUNTEQUCX

TENEQU10

DIST=BYTEPTR[SI+BP]GOTO=JMP…MOVAX,TENMOVCX,COUNTADDDIST,FIVEDIST=WORDPTR[SI+BP+1]ADDDIST,AX

GOTOLABEL定義引用4.2.3段定義偽指令說明邏輯段的起始和結(jié)束說明不同程序模塊中同類邏輯段之間的聯(lián)系形態(tài)匯編語言程序是按段來組織程序和數(shù)據(jù)的。和存儲器的物理段相對應,匯編語言程序中的段稱為邏輯段。匯編連接后被映射到物理段中。三類段:代碼(程序)、數(shù)據(jù)、堆棧段定義偽指令:SEGMENT、ENDS、ASSUME、ORG定義一個段的基本格式:

段名

SEGMENT

[定位類型][組合方式][類別]<匯編語言語句>

段名

ENDS這兩個偽指令總是成對出現(xiàn),二者前面的段名應一致。SEGMENT說明了一個段的開始,ENDS說明了一個段的結(jié)束。對數(shù)據(jù)段和堆棧段,段中的語句一般是變量定義。對代碼段則是指令語句。如:dataSEGMENT<指令語句>dataENDSSEGMENT和ENDS偽指令ASSUME偽指令在代碼段中,還必須明確段和段寄存器的關系,這由ASSUME語句來指定。如

ASSUMECS:code,DS:data,ES:data

語句中的code和data為段名。這個語句說明:

1.CS將指向名字為code的代碼段

2.DS和ES將指向名字為data的數(shù)據(jù)段但要注意,ASSUME偽指令只是告知匯編程序有關段寄存器與段的關系,并沒有給段寄存器賦予實際的初值。故下面的語句

MOV AX,DATAMOV DS,AXMOV ES,AX將段基址裝入段寄存器。如果程序中用到堆棧段,則SS也需裝入實際的初值。代碼段基地址不需要程序員裝入CS寄存器,而由OS負責裝入。SEGMENT語句后可以帶有可選參數(shù),用以規(guī)定邏輯段的其他一些屬性。1)定位類型說明如何確定邏輯段的邊界。有四種:PARA(Paragraph):

邏輯段從一個節(jié)(16個字節(jié))的邊界開始。即段的起始地址應能被16整除,或這說段起始物理地址應為××××0H?!J類型BYTE:

邏輯段從字節(jié)邊界開始,即段可以從任何地址開始。WORD:

邏輯段從字邊界開始。即段的起始地址必須是偶數(shù)。PAGE:

邏輯段從頁邊界開始。256字節(jié)稱為一頁,故段的起始物理地址應為×××00H。

2)組合類型說明不同模塊中同名段的組合方式。PUBLIC :

所有此類型的同名段組合成一個邏輯段,公用一個段地址,運行時裝入同一個物理段中。COMMON:

所有此類型的同名段具有相同的起始地址(覆蓋),共享相同的存儲區(qū)域。AT<數(shù)值表達式>:按絕對地址定位,段地址就是表達式的值。STACK:專用于說明堆棧段,組合方式同PUBLIC3)類別用單引號括起來的字符串。所有同類別的段被安排在連續(xù)的存儲區(qū)域中。如:在模塊1中有段定義:

seg1SEGMENTPARASTACK‘stack’…seg1ENDS

在模塊2中有段定義:

seg2SEGMENTPARASTACK‘stack’…seg2ENDS則連接時這兩個段被安排在一起。位置計數(shù)器$表示當前位置的計數(shù)器匯編程序每掃描一個字節(jié),位置計數(shù)器的值加1

如:TOPEQU$-STACKJMP$ORG規(guī)定了段內(nèi)的指令或數(shù)據(jù)存放的開始地址(偏移地址的初值),其格式為:

ORG<表達式>表達式的值即為開始地址,從此地址起連續(xù)存放程序或數(shù)據(jù)。例:ABCSEGMENTORG100Hbegin:……ABCENDS定位偽指令ORG指令從100H開始存放4.2.4匯編結(jié)束偽指令END匯編語言源程序的最后,要加匯編結(jié)束偽指令END,以使匯編程序結(jié)束匯編。格式:END

[表達式]END后跟的表達式通常就是程序第一條指令的標號,指示程序的啟動地址(要執(zhí)行的第一條指令的地址)。4.2.5過程定義偽指令用于定義一個過程體格式:過程名PROC[NEAR/FAR]

RET

過程名ENDP過程入口的符號地址過程的類型有兩種:

NEAR——(默認類型)表示段內(nèi)調(diào)用

FAR——表示段間調(diào)用

調(diào)用一個過程的格式為:

CALL

<過程名>4.2.6宏定義偽指令如果需要多次使用同一個程序段,可以將這個程序段定義為一個”宏指令”,然后在需要時,可簡單地用宏指令名來代替這個程序段。指令的格式為:<宏指令名>MACRO

[形參表]<宏定義體>

ENDM例:兩個數(shù)之和的宏定義和宏調(diào)用。宏定義為:DADDMACROX,Y,ZMOVAX,XADDAX,YMOVZ,AXENDMX、Y、Z是形式參數(shù)。調(diào)用宏DADD時可寫為:

DADD

DATA1,DATA2,SUMDATA1,DATA2,SUM是實際參數(shù),由它們替換定義中的X、Y、Z。宏調(diào)用與過程(子程序)調(diào)用都是一次定義,多次調(diào)用。它們之間的差別是:①執(zhí)行形式:宏命令偽指令由宏匯編程序在匯編過理中進行處理,而CALL、RET則是由CPU執(zhí)行的指令。②匯編結(jié)果:宏命令偽指令匯編后被展開。③執(zhí)行速度:宏命令執(zhí)行速度較快(因無調(diào)用轉(zhuǎn)移)④

占用內(nèi)存:宏指令簡化了源程序,但不能簡化目標程序,并不節(jié)省內(nèi)存單元。使用過程可以節(jié)省代碼占用的內(nèi)存空間。宏展開:匯編程序會把宏調(diào)用按宏定義展開。例如:宏定義為:

DISPLAYMACROstringLEADX,stringMOVAH,9INT21H

ENDM

程序中宏調(diào)用:

……DISPLAYERROR_MESSAGEDISPLAYEXIT_MESSAGE……

匯編后的結(jié)果:(帶有+號的指令為宏展開后的結(jié)果)……+LEADX,ERROR_MESSAGE+MOVAH,9+INT21H+LEADX,EXIT_MESSAGE+MOV AH,9+INT21H……一個完整源程序結(jié)構例DSEGSEGMENTDATA1DB1,2DATA2DW1234HDSEGENDSESEGSEGMENT

DB20DUP(?)ESEGENDSSSEGSEGMENT

STACK

‘STACK’

DB200DUP(?)SSEGENDSCSEGSEGMENT

ASSUMECS:CSEG,DS:DSEG,ES:ESEG,SS:SSEGSTART:MOVAX,DSEGMOVDS,AXMOVAX,ESEGMOVES,AXMOVAX,SSEGMOVSS,AX┇CSEGENDSENDSTART源程序代碼段寄存器賦初值習題1.下列語句在存儲器中分別為變量分配多少字節(jié)空間?并畫出存儲空間的分配圖。VAR1 DB 10,2VAR2 DW 5DUP(?),0VAR3 DB ‘HOWAREYOU?’,‘$’VAR4 DD -1,1,02.假定VAR1和VAR2為字變量,LAB為標號,試指出下列指令的錯誤之處。(1)ADD VAR1,VAR2 (2)SUB AL,VAR1(3)JMP LAB[SI] (4)JNZ VAR13.對于下面的符號定義,指出下列指令的錯誤。

A1 DB ?

A2 DB 10 K1 EQU 1024

(1)MOV K1,AX

(2)MOV A1,AX

(3)CMP A1,A2

(4)K1 EQU 20484.3功能調(diào)用DOS功能調(diào)用高級調(diào)用,操作系統(tǒng)提供BIOS功能調(diào)用低級調(diào)用DOS功能調(diào)用包含多個子功能的功能包,用軟中斷指令調(diào)用,中斷類型碼固定為21H各子功能采用功能號來區(qū)分調(diào)用格式:

MOVAH,功能號

<置相應參數(shù)>INT21HDOS系統(tǒng)功能調(diào)用的使用方法如下:① AH←功能號;② 設置該功能所要求的其他入口參數(shù);執(zhí)行INT21H指令;分析出口參數(shù)。1.DOS鍵盤功能調(diào)用(1)從鍵盤輸入一個字符(功能號=1)

MOVAH,1INT21H輸入的字符在AL中功能:等待從鍵盤輸入一個字符并將輸入字符的ASCII碼送入AL中,同時在顯示器上顯示該字符入口參數(shù):無出口參數(shù):AL=鍵入的ASCII碼字符單字符輸入例GET_KEY:MOV AH,1

INT 21H

CMP AL,’Y’ JZ YES CMP AL,’N’ JZ NO JNZ GET_KEY

YES:┇ NO:┇交互式應答程序(2)輸入字符串(功能號=0AH)MOVAH,

0AH

LEADX,<字符串緩沖區(qū)首地址>INT21H功能:從鍵盤輸入一串字符并把它存入用戶指定的緩沖區(qū)中入口參數(shù):DS:DX指向緩沖區(qū)首地址出口參數(shù):輸入的字符串及字符個數(shù)

DS:DX字符串在內(nèi)存中的存放地址定義字符緩沖區(qū)用戶自定義緩沖區(qū)格式:0DHN1N2整個緩沖區(qū)最大鍵入字符數(shù)實際鍵入字符數(shù)若用戶鍵入的字符數(shù)(包括回車)≥定義的N1,本功能調(diào)用將不再接收新的鍵入,且光標不再向右移動。例:設在數(shù)據(jù)段定義鍵盤緩沖區(qū)如下:

STR1DB10,?,10DUP(?)

調(diào)用DOS功能的0AH號功能的程序段為:

LEADX,STR1MOVAH,0AHINT21H

此程序段最多從鍵盤接收10個按鍵(包括回車)。2.DOS顯示功能調(diào)用(1)在顯示器上顯示一個字符(功能號=2)MOVAH,2MOVDL,<要顯示的字符>INT21H

例:在顯示器上顯示一個字符‘A’MOVAH,2MOVDL,’A’;或MOVDL,41HINT21H

DL=待顯示字符的ASCII碼

MOVAH,9LEADX,<字符串>INT21H功能:在顯示器上顯示以‘$’(24H)為結(jié)束符的字符串,若顯示的字符串要求回車換行,可在字符串中加入0DH,0AH控制碼入口參數(shù):DS:DX指向字符串首地址出口參數(shù):無(2)顯示字符串(功能號=9)被顯示的字符串必須以‘$’結(jié)束例:在屏幕上顯示:’HELLO,WORLD!’;在數(shù)據(jù)段定義字符串:

DATASEGMENTSTR1DB‘HELLO,WORLD!$’DATAENDS;在代碼段中進行顯示輸出

MOVAH,9LEADX,STR1INT21H完整的程序:HELLO.ASM附:BIOS功能調(diào)用BIOS:基本輸入輸出系統(tǒng),是固化在EPROM中的一組實現(xiàn)基本輸入輸出功能的子程序。BIOS調(diào)用通過多個軟中斷提供,調(diào)用方法為:

MOVAH,<功能號> <設置入口參數(shù),一般將參數(shù)放在寄存器中> INT <中斷類型>

BIOS中的幾個主要中斷類型如下:

INT10H——屏幕顯示

INT13H——磁盤操作

INT14H——串行口操作

INT16H——鍵盤操作

INT17H——打印機操作 每類中斷由包含許多子功能,調(diào)用時通過功能號指定。4.4匯編語言程序設計4.4.1概述1.程序質(zhì)量(P170)2.匯編語言程序設計的步驟:

1-根據(jù)實際問題抽象出數(shù)學模型,確定算法

2-畫出程序框圖(流程圖)3-分配內(nèi)存工作單元和寄存器

4-根據(jù)框圖編寫源程序,存成.ASM文件

5-對源程序匯編,生成.OBJ目標文件

6-把.OBJ文件連接成.EXE執(zhí)行文件

7-運行、調(diào)試3.源程序的基本結(jié)構:順序、分支、循環(huán)、過程

(1)用方框表示工作框,框中用簡明語言標明要完成的功能(2)用菱形框表示判斷框

框中標明比較、判斷和條件如何繪制程序框圖(流程圖)?NY?(4)各框之間用直線連起來表示程序走向??蛑袠嗣髯映绦蛎?入口參數(shù)等)(3)用

框表示調(diào)用子程序或過程。4.4.2順序程序設計順序結(jié)構是最常見、最基本的程序結(jié)構CPU按照指令的排列順序逐條執(zhí)行。語句A語句B語句C程序的執(zhí)行順序就是指令的編寫順序例實現(xiàn)C=A+B,設A,B,C均為字變量。DATASEGMENTADW5F73HBDW98CDHCDW?DATAENDSCODESEGMENTASSUMECS:CODE,DS:DATASTART:MOVAX,DATAMOVDS,AXMOVAX,AADDAX,BMOVC,AXMOVAH,4CHINT21HCODEENDSENDSTART標號:條件滿足?語句A4.4.3分支程序設計分支結(jié)構是指包含條件轉(zhuǎn)移或無條件跳轉(zhuǎn)指令的程序。分支結(jié)構具體分為單分支、雙分支、多分支結(jié)構NYIF…THEN結(jié)構程序結(jié)構:

測試/比較指令(TEST/CMP)

條件轉(zhuǎn)移指令(Jx

標號)

處理體

標號:其他指令

…單分支程序結(jié)構:

TEST/CMP指令

Jx

標號1

處理體P1JMP標號2標號1:

處理體P2標號2:其他指令

…條件滿足?語句A語句B標號1:標號2:條件1條件2IF…THEN…ELSE結(jié)構雙分支若條件成立,則執(zhí)行A,否則執(zhí)行B標號1:條件1成立?P1NYCASE結(jié)構程序結(jié)構:

…TEST/CMP指令(測試條件1)

Jx

標號1;不滿足轉(zhuǎn)標號1

處理體P1…JMP標號n+1標號1:TEST/CMP指令(測試條件2)

Jx

標號2;不滿足轉(zhuǎn)標號2

處理體P2…JMP標號n+1標號2:TEST/CMP指令(測試條件3)

Jx

標號3;不滿足轉(zhuǎn)標號3

處理體P3…JMP標號n+1標號3:TEST/CMP指令(測試條件4)

……標號n+1:(公共出口)條件2成立?條件n成立?…Pn+1標號2:標號n:標號n+1:P2PnNNYY例:將1字節(jié)的二進制數(shù)以十六進制數(shù)顯示出來

DATASEGMENTADW5FHDATAENDSCODESEGMENT

ASSUMECS:CODE,DS:DATASTART:MOVAX,DATAMOVDS,AXMOVDL,AMOVCL,4SHRDL,CLADDDL,30H;0~9加30H,A~F加37HCMPDL,’9’JBENEXT1ADDDL,7NEXT1:MOV

AH,2

INT21H

MOVDL,AANDDL,0FHADDDL,30HCMPDL,’9’JBENEXT2ADDDL,7NEXT2:INT21HMOVAH,4CHINT21HCODEENDS

ENDSTART單分支程序設計例:在某串中查找某個特定字符,找到顯示’Y’,未找到顯示’N’

REPNESCASBJZFOUND

MOVDL,’N’JMPDISPFOUND:MOV

DL,’Y’DISP:MOVAH,2INT21H

MOVAH,4CHINT21HCODEENDS

ENDSTARTDATASEGMENTSTRINGDB‘Howareyou!welcometochina!’NEQU$-STRINGDATAENDSCODESEGMENT

ASSUMECS:CODE,ES:DATASTART:MOVAX,DATAMOVES,AXLEADI,STRINGMOVCX,NCLDMOVAH,1INT21H雙分支程序設計4.4.4循環(huán)程序設計1.DO…UNTIL<條件>結(jié)構先執(zhí)行,再判斷條件。工作部分至少執(zhí)行一次。初始化循環(huán)體循環(huán)控制繼續(xù)循環(huán)?YN包含循環(huán)執(zhí)行某一段指令序列的程序2.DOWHILE<條件>結(jié)構先判斷條件,再執(zhí)行。工作部分有可能一次都不執(zhí)行。初始化循環(huán)體循環(huán)控制繼續(xù)循環(huán)?YN循環(huán)結(jié)構的組成部分:循環(huán)初始化部分—初始化循環(huán)控制變量、循環(huán)體所用到變量;循環(huán)體部分—循環(huán)結(jié)構的主體,即要求重復執(zhí)行得程序段部分,包括循環(huán)工作部分和循環(huán)控制部分;循環(huán)結(jié)束條件—在循環(huán)程序中必須給出循環(huán)結(jié)束條件,否則就會進入死循環(huán)。循環(huán)結(jié)束條件:用計數(shù)器控制循環(huán)按問題的條件控制循環(huán)用開關量控制循環(huán)有些情況下,在循環(huán)體內(nèi)又嵌套了循環(huán),這種結(jié)構成為多重循環(huán)。多重循環(huán)常用于軟件延時程序或二維數(shù)組處理例:統(tǒng)計字變量VAL中0和1的個數(shù),并將統(tǒng)計結(jié)果分別送字單元X和Y中。

MOVCX,16MOVSI,0MOVDI,0MOVAX,VALAGAIN:SHLAX,1JCNOZEROINCSIJMPNEXTNOZERO:INCDINEXT:LOOPAGAINMOVX,SIMOVY,DI掌握以下幾點:調(diào)用子程序用CALL指令,返回調(diào)用程序用RET指令。子程序允許嵌套調(diào)用。進入子程序后首先要保護主程序的運行狀態(tài)(標志位)和使用的寄存器內(nèi)容(稱為保護現(xiàn)場),退出子程序前要恢復現(xiàn)場。調(diào)用前要預先確定子程序中要使用哪些寄存器,并定義入口參數(shù)和出口參數(shù)。參數(shù)傳遞可利用寄存器、存儲單元或堆棧(要用BP尋址)。4.4.5子程序設計對于一個子程序,應該注意它的入口參數(shù)和出口參數(shù)。入口參數(shù)—由主程序傳給子程序的參數(shù)出口參數(shù)—子程序運算完傳給主程序的結(jié)果參數(shù)傳遞的方法:利用寄存器。把所需傳遞的參數(shù)直接放在主程序的寄存器中傳遞給子程序。利用存儲單元。主程序把參數(shù)放在公共存儲單元,子程序則從公共存儲單元取得參數(shù)。利用堆棧。主程序?qū)?shù)壓入堆棧,子程序運行時則從堆棧中取參數(shù)。例:編寫一個將單字節(jié)的二進制數(shù)轉(zhuǎn)換成BCD碼數(shù)的程序,再將對應的十進制數(shù)轉(zhuǎn)換成ASCII碼字符串,在顯示器上顯示出來。分析:設單字節(jié)二進制數(shù)存放在NUMBIN單元。利用除法實現(xiàn)轉(zhuǎn)換:將該數(shù)除以100,商即為BCD碼數(shù)的百位,保留第一步所得余數(shù)。將①所得余數(shù)再除以10,商即為BCD碼數(shù)的十位,余數(shù)即為BCD碼數(shù)的個數(shù)將BCD碼數(shù)的百位、十位和個位分別加上30H,即為它們的ASCII碼將ASCII碼字符串存入一個緩沖區(qū),然后調(diào)用DOS功能調(diào)用INT21H的09H號功能即可顯示該字符串。程序如下:DATASEGMENTNUMBINDB0E7H;待轉(zhuǎn)換的單字節(jié)二進制數(shù)STRINGDB10DUP(20H);定義顯示緩沖區(qū),初值全為空格20HDB0DH,0AH;定義回車換行符

DB$;定義結(jié)束符DATAENDSSTACKSEGMENTPARASTACK‘STACK’DB100DUP(?)STACKENDSCODESEGMENTASSUMECS:CODE,DS:DATA,SS:STACKSTARTPROCFARBEGIN:PUSHDS;DS中包含的是程序段前綴的起始地址

MOVAX,0PUSHAX;設置返回至DOS的段值和偏移量

MOVAX,DATAMOVDS,AX;置段寄存器初值

LEADI,STRINGXORAH,AH;AH清零

MOVAL,NUMBINMOVBL,100DDIVBL;AX除以BL,商在AL中,余數(shù)在AH中

CALLBCDTOASC;調(diào)用轉(zhuǎn)換程序,入口參數(shù):AL=BCD數(shù)

MOVAL,AH;取余數(shù)送ALXORAH,AHMOVBL,10DDIVBL

CALLBCDTOASCMOVAL,AHCALLBCDTOASCCALLDISPASC;調(diào)用顯示程序

RETSTARTENDPBCDTOASCPROC;BCD碼到ASCII碼轉(zhuǎn)換程序

ADDAL,30HMOV[DI],AL;保存ASCII字符

INCDI;指向下一個單元

RETBCDTOASCENDPDISPASCPROC;顯示子程序

LEADX,STRING

MOVAH,09HINT21HRETDISPASCENDPCODEENDSENDBEGIN1.碼制轉(zhuǎn)換十、二進制數(shù)、ASCII碼之間的互相轉(zhuǎn)換。①BCD數(shù)→二進制數(shù)算法:Dn-1*10n-1+……+D0*100

=(…(Dn-1*10+Dn-2)*10+…)*10+D0=(…((0*10+Dn-1)*10+Dn-2)*10+…)*10+D0

即:新的中間結(jié)果=中間結(jié)果*10+本位數(shù)字

(中間結(jié)果初值為0)4.5常見程序設計舉例例:將≤65535的非壓縮BCD數(shù)轉(zhuǎn)換成二進制數(shù)。

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

mydataSEGMENT

decnumDB5,3,0,1,9;BCD數(shù)53019

binnumDW?

mydataENDSprogSEGMENT

ASSUMECS:prog,DS:mydatabegin: MOVAX,mydata MOVDS,AX

MOVSI,OFFSETdecnum MOVCX,5;5位BCD數(shù)

MOVBX,10

XORAX,AX;中間結(jié)果初始值為0Next: MULBX;中間結(jié)果*10+本位數(shù)字

ADDAL,[SI]ADCAH,0

INCSI;指向下位BCD數(shù)

LOOPnextMOVbinnum,AX;保存結(jié)果

MOVAH,4CHINT21Hprog ENDS

ENDbegin例:把≤255的非壓縮BCD數(shù)轉(zhuǎn)換成2進制數(shù)

decnumDB1,5,9;BCD數(shù)159

binnumDB? ……MOVAX,decnumXCHGAH,AL;百位在AH,十位在ALAAD;百位數(shù)*10+十位數(shù)

MOVAH,AL;中間結(jié)果送AHMOVAL,decnum+2AAD;中間結(jié)果*10+個位數(shù)

MOVbinnum,AL……例:從鍵盤輸入兩個整數(shù),并求其和。因鍵入為整數(shù),故要進行如下轉(zhuǎn)換:

ASCII→BCD→二進制數(shù)

ASCII→BCD碼很簡單,高4位清零即可得到非壓縮的BCD碼。

BCD→二進制數(shù)在本例中采用用以下方法:

((((0+千位數(shù))*10+百位數(shù))*10)+十位數(shù))*10+個位數(shù)②ASCII碼→二進制數(shù)(用于輸入)第一次中間結(jié)果第二次中間結(jié)果第三次中間結(jié)果最終結(jié)果開始兩個數(shù)分別轉(zhuǎn)換成二進制數(shù)鍵入兩個數(shù)相加結(jié)束返回DOS如有溢出則提示開始取第一個ASCII碼是負號嗎?數(shù)字符個數(shù)-1,指針+1指針定位字符個數(shù)-1=0?取數(shù)字,與中間結(jié)果相加,再乘以10指向下一個數(shù)字字符加個位數(shù)是負數(shù)則求補存結(jié)果結(jié)束NYYN轉(zhuǎn)換子程序程序如下:DATA SEGMENTSTR1 DB10,?,10DUP(?);第1個數(shù)的輸入緩沖區(qū)

STR2 DB10,?,10DUP(?);第2個數(shù)的輸入緩沖區(qū)

NUM DW?,? ;存轉(zhuǎn)換后的二進制數(shù)SUM DW0 ;存和OVER DB‘Overflow!’,13,10,’$’DATA ENDS;CODE SEGMENT ASSUMECS:CODE,DS:DATAMAIN PROC FARSTART:MOV AX,DATA MOV DS,AX MOV AH,0AH LEA DX,STR1 INT 21H ;輸入第一個數(shù)字串(設為26) MOV AH,0AH LEA DX,STR2 INT 21H ;輸入第二個數(shù)字串(設為33) LEA BX,STR1;串1的首地址送BX LEA DI,NUM;存二進制首地址送DI CALL CHANGE;將串1ASCII碼→二進制

LEA BX,STR2;串2的首地址送BX

LEA DI,NUM+2 ;指向

CALL CHANGE ;將串2ASCII碼→二進制

MOV AX,NUM;(AX)=[NUM]=001AH ADD AX,NUM+2 ;兩數(shù)相加,(AX)=003BH MOV SUM,AX ;存和

JNO NEXT ;無溢出,轉(zhuǎn)NEXT LEA DX,OVER MOV AH,9 INT 21H ;顯示’Overflow!’NEXT: MOV AH,4CH INT 21H ;返回DOS MAIN ENDPCHANGE PROC MOV CL,[BX+1] ;實際字符數(shù)送CL MOV AL,[BX+2] ;第一個字符送AL MOV CH,AL ;暫存在CH CMP AL,’-’ ;第一個字符是負號嗎? JNZ NEXT1 ;不是,轉(zhuǎn)NEXT1 DEC CL ;字符數(shù)減1 INC BXNEXT1:ADD BX,2 ;指向第一個數(shù)字字符

MOV AX,0 ;清零AX,存二進制數(shù)LP1:DEC CL JZ NEXT2 ;若(CL)=0,轉(zhuǎn)NEXT2 MOV DL,[BX];取字符

AND DL,0FH ;轉(zhuǎn)換成BCD碼

ADDAL,DL;加到中間結(jié)果上

ADCAH,0

MOVDX,10MULDX;*10INCBX;指向下一個字符

JMPSHORTLP1NEXT2:MOVDL,[BX];取個位數(shù)

ANDDL,0FH;個位ASCII→未組合BCDADDAX,DX;加個位數(shù),(AX)=001AHCMPCH,’-’;是’-’?JNZNEXT3;該數(shù)非負,轉(zhuǎn)NEXT3NEGAX;若為負,求補NEXT3:MOV[DI],AX;存二進制結(jié)果

RETCHANGEENDP;CODEENDSENDSTART020A32360D…020A33330D…001A21003B00STR1STR2NUMSUM10個10個‘O’……OVER??040A313234…STR1若鍵入‘1234’330D‘1’‘2’‘3’‘4’…設鍵入第1個數(shù)為26,第2個數(shù)為33,則在內(nèi)存各變量分配如下:重點掌握:

如何從鍵盤輸入一個字符串

ASCII→未組合BCD→二進制有符號數(shù)的運算,對負數(shù)和溢出如何處理方法1

計算二進制數(shù)中所包含的1000的個數(shù)、100的個數(shù)、10的個數(shù)和1的個數(shù)。方法2

除10取余。下面舉例介紹第一種方法。流程圖如下:③二進制數(shù)→BCDYN二進制數(shù)

AX令(DL)=0(AX)-1000<0?(DL)+1(AX)+1000(AX)DL存至緩沖區(qū)令(DL)=0YN(AX)-10<0?(DL)+1(AX)+10(AX)存DL存AL返回DOS求100的個數(shù),結(jié)構同上A匯編程序如下:DATA SEGMENTBNUM DB 270FHDNUM DB 4DUP(?);存放BCD碼的緩沖區(qū)DATA ENDSCODE SEGMENT ASSUMECS:CODE,DS:DATABINBCD PROC FARBEGIN:MOV AX,DATA MOV DS,AX MOV AX,BNUM;取二進制數(shù)

LEA BX,DNUM;BCD碼緩沖區(qū)首地址送BX

;計算百位的個數(shù)

MOVDL,0;千位的個數(shù)計數(shù)器AGAIN1:SUBAX,1000;(AX)-1000JCNEXT1;若≤0,則退出循環(huán)

INCDL;(DL)+1JMPAGAIN1NEXT1:ADDAX,1000;(AX)←(AX)+1000 MOV[BX],DL;存千位的個數(shù)

;計算百位的個數(shù)

MOVDL,0;百位的個數(shù)計數(shù)器AGAIN2:SUBAX,100;(AX)-100JCNEXT2INCDLJMPAGAIN2NEXT2:ADDAX,100MOV[BX+1],DL;存百位的個數(shù)

MOVDL,0;十位的個數(shù)計數(shù)器AGAIN3:SUBAX,10;(AX)-10JCNEXT3INCDL JMPAGAIN3NEXT3:ADDAX,10MOV[BX+2],DL;存十位的個數(shù)

MOV[BX+3],AL;存?zhèn)€位的個數(shù)

MOVAH,4CHINT21HBINBCDENDP;CODEENDS ENDBEGIN④BCD→ASCII

⑤二進制串轉(zhuǎn)換為ASCII碼一個二進制位串若要送顯示或打印,需把串中每一位(0或1)化為ASCII碼。思路:先將目標串全部預置為30H,再把每個二進制位逐位左移至CF,然后判CF=0?若是,取下一位;若不是,將31H送此單元。

流程圖如下:初始化用’0’填滿串取要轉(zhuǎn)換的數(shù)左移1位存入‘1’結(jié)束CF=1?轉(zhuǎn)換完?調(diào)整指針NN匯編程序如下:DATA SEGMENTNUM DW 6F78HSTRING DB 16DUP(?)DATA ENDS;CODE SEGMENT ASSUMECS:CODE,DS:DATABINCA PROC FARBEGIN: MOV AX,DATA MOV DS,AX MOV ES,AX CLD LEA DI,STRING MOV CX,16;串的長度

溫馨提示

  • 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. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論