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

下載本文檔

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

文檔簡介

第3章

匯編語言程序設計主要內容:匯編語言源程序的結構匯編語言語句格式偽指令功能調用匯編語言程序設計13.1 匯編語言概述

1、機器語言——二進制數(shù)形式的指令和數(shù)據。

B064是什么意思?這就是機器語言。既不直觀,又不易理解和記憶.

2、匯編語言MOVAL,64H

;很容易記憶理解,這就是助記符。

助記符——用便于記憶的英語單詞表示的指令操作碼。它反映了指令的功能和主要特征,便于人們理解和記憶。

指令除了操作碼以外,還有一個操作數(shù)問題。操作數(shù)可能放在存儲器中,這就涉及操作數(shù)的地址。程序中遇到轉移指令或調用指令,也需要知道轉移地址,若采用具體地址就很不方便,一旦有錯,改動也很麻煩。于是人們采用標號或符號來代替地址。2

LP1:movax,VAR…loopLP1

匯編語言——指令助記符,符號地址,標號,偽指令等語言元素的集合以及這些元素使用的規(guī)則。用匯編語言編寫的程序叫匯編語言源程序。匯編源程序需翻譯成機器語言,變成可執(zhí)行文件,機器才能執(zhí)行,這個翻譯過程叫匯編?!呒壵Z言中稱該過程為“解釋”或“編譯”。執(zhí)行翻譯的程序稱為“匯編程序”。源程序的編譯程序匯編程序匯編語言源程序機器語言目標程序3匯編語言程序設計與執(zhí)行過程輸入匯編語言源程序源文件.ASM匯編(編譯)目標文件.OBJ鏈接可執(zhí)行文件.EXE調試最終程序小匯編:ASM宏匯編:MASM3、高級語言:通用性強。例:MATLAB、C、Pascal43.2匯編語言源程序的格式

匯編語言源程序通常由一個或幾個程序模塊組成,每個模塊一般由三個邏輯段組成:

數(shù)據段——存放數(shù)據、變量DATASEGMENTDATAENDS堆棧段——堆棧區(qū)域STACKSEGMENTSTACKENDS

代碼段——存放程序指令CODESEGMENT

CODEENDS3.2.1分段結構5一個基本的匯編語言程序框架如下:

stack

SEGMENTPARA‘stack‘DB100DUP(‘stack’)

stackENDS

dataSEGMENT

<數(shù)據、變量在此定義>

dataENDS

codeSEGMENT

ASSUMECS:code,DS:data,ES:data

start:MOVAX,dataMOVDS,AXMOVES,AX

<此處加入你自己的程序段>MOVAH,4CH

INT21H

code

ENDSEND

start

堆棧段數(shù)據段代碼段6例:將兩個五字節(jié)的16進制數(shù)相加DATASEGMENT;定義數(shù)據段DATA1DB0F8H,60H,0ACH,74H,3BH;變量一,字節(jié)DATA2DB0C1H,36H,93H,0D5H,20H;變量二,字節(jié)DATAENDS;數(shù)據段結束CODESEGMENT;定義代碼段

ASSUMECS:CODE,DS:DATASTART:MOVAX,DATAMOVDS,AX;初始化DS

MOVCX,5;置循環(huán)次數(shù)送CXMOVSI,0;(SI)=0CLC;(CF)=07LOOPER:MOVAL,DATA2[SI];取一個字節(jié)加數(shù)ADCDATA1[SI],AL;與被加數(shù)相加,帶進位加法INCSI;SI加1DECCX;CX減1JNZLOOPER;若(CX)不等于0,轉LOOPER

MOVAH,4CHINT21H;返回DOSCODEENDS;代碼段結束ENDSTART;源程序結束注:MOVAH,4CHINT21H;DOS功能調用,結束正在運行的程序,返回DOS83.2.2匯編語言語句的類型和組成匯編語言的語句有兩種:指令性語句——由8086指令助記符構成的語句指令性語句的格式為:

標號:

指令助記符

目的操作數(shù),源操作數(shù)

;注釋注:各部分之間至少要用一個空格作為分隔符。指令性語句由CPU執(zhí)行,每一條指令性語句都有一條機器碼指令與其對應指令性語句匯編時生成機器碼;例:LOOPER:MOVAL,DATA[SI]9匯編語言的語句有兩種:指示性語句——由偽指令構成的語句指示性語句的格式為:

名字

偽指令

操作數(shù)1,操作數(shù)2,…,操作數(shù)n

;注釋注:各部分之間至少要用一個空格作為分隔符。指示性語句由匯編程序執(zhí)行。它指出匯編程序應如何對源程序進行匯編,如何定義變量、分配存儲單元以及指示程序開始和結束等。指示性語句無機器碼指令與其相對應。

指示性語句匯編時不生成機器碼。例:DATADB0FBH,60H10標號有三個屬性:

段地址:即標號所在段的段地址;程序中引用一個標號,該標號的段地址應在CS中。

偏移量:標號所代表存儲單元的段內偏移地址;16位的無符號數(shù)

類型:NEAR或FAR:

NEAR—表示標號所在語句與轉移指令/調用指令在同一碼段內,跳轉時只需改變IP即可。

FAR—標號所在語句與轉移指令/調用指令不在同一代碼段內。

若沒有對類型進行說明,默認為NEAR。標號通常作為轉移指令或CALL指令的轉移地址。3.2.3名字11匯編語言的一個實例:hello.asm

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

ASSUME

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

LEADX,hello

;取字符串首地址

MOVAH,9INT21H ;顯示字符串MOVAH,4CHINT21H ;退回DOSprogENDSENDstart名字標號12

3.2.4助記符和偽操作助記符:8086、8088CPU指令的助記符,例如:MOV,ADD,MUL等偽操作指令:如DB、SEGMENT、ENDS、ASSUME、ENDS3.2.5操作數(shù)操作數(shù)包括常量、寄存器、標號、變量及表達式。1.常量二進制數(shù),以B結尾。如01001101B。十進制數(shù),如85。八進制數(shù),以Q結尾。如174Q。13

十六進制數(shù),以H結尾。第1個數(shù)字為A-F時,前面應加0,如0F160H。字符串:用引號括起來的1個或多個字符。如‘ERROR!’,’a’,匯編時被翻譯成對應的ASCII碼45H,52H,52H,4FH,52H,21H和61H。十進制科學計數(shù)法。如:8.75E-4十六進制實數(shù)。如:10A4E87R2、寄存器8位寄存器:AH、AL、BH、BL、CH、CL、DH、DL16位寄存器:AX、BX、CX、DX、SI、DI、BP、SP、DS、CS、SS、DS3、標號:代表一條指令的符號地址14

變量名——是存儲單元(數(shù)據區(qū))的符號地址或名字。變量也有三個屬性:段地址—變量所在段的段地址偏移量—變量單元地址與段首地址之間的位移量。類型—有BYTE、WORD和DWORD三種。變量在程序中作為存儲器操作數(shù)被引用。標號和變量名的使用規(guī)則組成:A-Z(不分大小寫),0-9,?@._$不能以數(shù)字開頭長度小于31個字符不能與保留字(指令助記符、偽指令、預定義符號等)重名不能重復定義例如:正確的:LP1,AGAIN,NEXT,_GO,OK_1

錯誤的:4M,LOOP,AAA,#HELP,+ONE4.變量即內存中的存儲單元或數(shù)據區(qū)。155.表達式表達式是常數(shù)、寄存器、標號、變量與運算符的組合。有數(shù)字表達式和地址表達式兩種。匯編時按優(yōu)先規(guī)則對表達式進行計算,計算出具體的數(shù)值或地址。運行時不能改變。表達式中的運算符有6類:算術、邏輯、關系、取地址、屬性、雜類。(1)算術運算符——+、-、*、/,MOD用于數(shù)字表達式,例:MOVAX,4*1024匯編后的形式為:

MOVAX,4096用于地址表達式,例:LEASI,TAB+3若TAB的偏移地址為1000H,則匯編后的形式為:LEASI,1003H16邏輯運算符只能用于數(shù)字表達式中。例:MOV CL,36HAND0FH

經匯編后:MOVCL,06H注意,不要把邏輯運算符與邏輯運算指令混淆:例:ANDAX,3FC0HAND0FF00H匯編后源操作數(shù)被翻譯為:3F00H,所以上述指令與ANDAX,3F00H等價。(2)邏輯運算符——AND、OR、XOR、NOT關系運算的結果是一個邏輯值:真或假關系為真,結果為全1;

關系為假,結果為全0例:MOVBX,PORTGT300H若PORT的值大于300H,則匯編后為:MOVBX,0FFFFH否則匯編后為:

MOVBX,0(3)關系運算符——EQ、NE、LT、GT、LE、GE17OFFSET:取變量/標號的偏移地址注意,以下指令的異同:

MOVBX,OFFSETVARLEABX,VAROFFSET只能取靜態(tài)的偏移地址;LEA指令即可取靜態(tài)的偏移地址,也可取動態(tài)的偏移地址。SEG:取變量/標號的段地址。例:MOVAX,SEGDATAMOVDS,AX;取變量DATA的段地址(4)分析運算符和合成運算符18TYPE取變量的類型(1,2,4)VARDW?;字ARRAYDD10DUP(?);雙字STRDB‘Thisisatest’;字節(jié)……MOVAX,TYPEVAR;(AX)=2MOVBX,TYPEARRAY;(BX)=4MOVCX,TYPESTR;(CX)=1LENGTH取所定義變量的長度(即變量中元素的個數(shù))未使用重復操作符DUP,變量個數(shù)為1;否則如上例中的變量ARRAY的個數(shù)為10;19SIZE取所定義存儲區(qū)的字節(jié)數(shù)(=TYPE*LENGTH)例:VARDW1,2,3,4,5則TYPEVAR=2,LENGTHVAR=5,SIZEVAR=10合成運算符PTR:用來指定地址操作數(shù)的類型格式:<類型>PTR<地址操作數(shù)> 類型∈{BYTE,WORD,DWORD,NEAR,FAR}BYTE、WORD、DWORD用于描述數(shù)據存儲單元(變量)地址NEAR、FAR用于描述轉移、調用的目的地址例:MOV BYTEPTR[DI],0;字節(jié)類型MOV WORDPTR[DI],0;字類型

MOV [DI],0B5H;類型不定20PTR也可用來進行強制類型轉換例:STR1DW?;STR1定義為字類型 MOVAX,STR1;合法MOV AL,STR1;非法MOVAL,BYTEPTRSTR1;合法合成運算符THIS:用來指定存儲器操作數(shù)的類型合成運算符SHORT:地址操作數(shù)21(5)其他運算符方括號[]:存儲器地址MOVCL,[BX];間址尋址MOVAL,[SI+5];變址尋址段超越運算符:MOVAX,ES:[DI]HIGH、LOW:獲取數(shù)值或地址表達式的高位和低位字節(jié)VAREQU0ABCDHMOVAH,HIGHVAR;(AH)=0ABHMOVAL,LOWVAR;(AL)=0CDH223.2.6注釋注釋——以分號開頭,可放在指令后,也可單獨一行。

注意注解的寫法。要寫指令(段)在程序中的作用,而不要寫指令的操作。例如:以下為同一條指令寫的注釋1)MOVCX,100;傳送100到CX2)MOVCX,100;循環(huán)計數(shù)器置初值顯然,第二種寫法要比第一種寫法要好。

233.3偽操作命令數(shù)據定義偽指令符號定義偽指令段定義和段寄存器指定偽指令過程定義偽指令結束偽指令

由匯編程序執(zhí)行的指令,它本身不被匯編成機器指令。常用的偽指令有:243.3.2數(shù)據定義偽指令

用于定義變量,即內存單元或數(shù)據區(qū)。數(shù)據定義偽指令的格式為:變量名數(shù)據定義偽指令操作數(shù),操作數(shù),…常用的數(shù)據定義偽指令有如下幾種:

DB定義字節(jié)、DW定義字、DD定義雙字、DQ定義八字節(jié)

DT定義十字節(jié)操作數(shù)可以是常數(shù)、變量或表達式例1:DATA_BDB10,5,10HDATA_WDW100H,-4DATA_DDD0FFFBH匯編后的內存分配情況如右圖所示。05H10H00H01HFCHFFHFBHFFH00H00H0AHDATA_BDATA_WDATA_D10510H0100H-40FFFBH25例2:DATADB100,0FFH;存入64H,0FFHEXPRDB2*3+7;存入0DH=13DSTRDB‘WELCOME!’;存入8個字符

ABDB‘AB’;存入41H,42HBADW‘AB’;存入42H,41HABDDDD‘AB’;存入42H,41H,00,00OFFABDWAB;存入變量AB的偏移地址ADRSDWTABLE,TABLE+5,TABLE+10;存入3個偏移地址TOTALDDTABLE;先存入TABLE偏移地址,再存段地址NUMDQ0011223344556677H;存入77H,66H,55H,44H,33H,22H,11H,00H,DECMLDT1234567890H;存入90H,78H,56H,34H,12H,00,00,00,00,00HEXTABDB01,02,03,04,05,06,07,08,09DB0AH,0BH,0CH,0DH,0EH,0FH

26例3:操作數(shù)可以是字符串,例如STRDB ‘HELLO’匯編后的情況如圖:注意下面兩個定義的不同之處:DB ‘AB’;41H在低字節(jié),42H在高字節(jié)DW‘AB’;42H在低字節(jié),41H在高字節(jié)STR‘H’‘E’‘L’‘L’‘O’48H45H4CH4CH4FH操作數(shù)?用來保留存儲空間,但不存入數(shù)據.例4:ABCDB0,1,2,3,4,’OK’,’$’RSVDW?,?,?,?,?,?,?,?27復制操作符DUP:重復的數(shù)據可以使用復制操作符DUP,如上面RSV亦可寫成:RSVDW8DUP(?)若操作數(shù)中若使用$,則表示的是地址計數(shù)器的當前值。例:TABLEDB10DUP(?)BUFFERDWTABLE,$+3設TABLE的偏移地址為0080H,則匯編后如下圖所示:BUFFER0080H80HTABLE...8FH00H0089H10Bytes283.3.3符號定義偽指令1、EQU格式:名字EQU表達式

把一個表達式用一個符號表示,以后凡出現(xiàn)該表達式的地方都可用這個符號表示。類似于C語言中的#define。用EQU定義的符號未清除前不能重新定義。清除EQU定義用PURGE偽指令。不占用存儲空間,僅是給符號賦值CREQUODH;常數(shù)AEQUASCII_TABLE;變量STREQU64*1024;數(shù)值表達式ADREQUES:[BP+DI+5];地址表達式CBDEQUAAM;指令助記符292、=格式:名字=表達式區(qū)別:可對同一名字重復定義不占用存儲空間,僅是給符號賦值例1:FIVEEQU5

COUNTEQUCX

TENEQU10

DIST=BYTEPTR[SI+BP]

GOTO=JMP…MOVAX,TENMOVCX,COUNTADDDIST,FIVE

DIST=WORDPTR[SI+BP+1]ADDDIST,AX

GOTOLABEL

定義引用30例2:COUNT=10MOVCX,COUNT;(CX)=10COUNT=COUNT-1MOVBX,COUNT;(BX)=9例3:COLUMNEQU80

ROWEQU25SCREENFUL

EQUCOLUMN*ROW3、LABEL格式:名字LABEL類型例:AREAWLABELWORD;AREAW類型為WORD313.3.4段定義偽操作1、SEGMENT/ENDS格式:

段名

SEGMENT[定位類型][組合方式][類別]

<匯編語言語句>段名

ENDS匯編語言程序是按段來組織程序和數(shù)據的。和存儲器的物理段相對應,匯編語言程序中的段稱為邏輯段。匯編連接后被映射到物理段中。SEGMENT語句后可以帶有可選參數(shù),用以規(guī)定邏輯段的其他一些屬性。321)定位類型說明如何確定邏輯段的邊界。有四種:PARA(Paragraph):邏輯段從一個節(jié)(16個字節(jié))的邊界開始。即段的起始地址應能被16整除,或這說段起始物理地址應為××××0H。——默認類型BYTE:

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

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

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

2)組合類型說明不同模塊中同名段的組合方式。PUBLIC :所有此類型的同名段組合成一個邏輯段,公用一個段地址,運行時裝入同一個物理段中。COMMON:所有此類型的同名段具有相同的起始地址(覆蓋),共享相同的存儲區(qū)域。AT<數(shù)值表達式>:按絕對地址定位,段地址就是表達式的值。STACK:專用于說明堆棧段,組合方式同PUBLIC34STACKSEGMENTSTACKDB100DUP(?)STACKENDSDATA1SEGMENTBYTESTRINGDB‘Thisisanexample!’DATA1ENDSDATA2SEGMENTWORDBUFFERDW40DUP(0)DATA2ENDS

35CODE1SEGMENTPAGE……CODE1ENDSCODE2SEGMENTPAGE……CODE2ENDS……START:MOVAX,STACK;MOVSS,AXCODE2ENDSENDSTART

36長度說明:STACK的長度為100*1=100D=64HDATA1的長度為19*1=19D=13HDATA2的長度為40*2=80D=50HCODE1的長度為13*1=13D=0DHCODE2的長度為52*1=52D=34H所占內存地址:STACK:00000H~00063H,占64H=100個字節(jié),從×××00H開始DATA1:00064H~00076H,占13H=19個字節(jié),從任何地址開始DATA2:00078H~000C7H,占50H=80個字節(jié),以偶數(shù)地址開始CODE1:00100H~0010CH,占0DH=13個字節(jié),從×××00H開始CODE2:00110H~00143H,占34H=52個字節(jié),從×××00H開始

372、ASSUME偽指令在代碼段中,還必須明確段和段寄存器的關系,這由ASSUME語句來指定。如ASSUMECS:code,DS:data,ES:data語句中的code和data為段名。這個語句說明:CS將指向名字為code的代碼段DS和ES將指向名字為data的數(shù)據段但要注意,ASSUME偽指令只是告知匯編程序有關段寄存器與段的關系,并沒有給段寄存器賦予實際的初值。故下面的語句

MOV AX,DATAMOV DS,AXMOV ES,AX將段基址裝入段寄存器。如果程序中用到堆棧段,則SS也需裝入實際的初值。代碼段基地址不需要程序員裝入CS寄存器,而由OS負責裝入。38例1:CODESEGMENT

ASSUMECS:CODE,DS:DATA1,SS:STACKMOVAX,DATA1MOVDS,AXMOVAX,STACKMOVSS,AX……CODEENDS39例2:.DOSSEG.MODELSMALL.STACK100H.DATAIVARDB5IARRAYDW50DUP(5)STRINGDB‘Thisisastring’

.CODE403.3.5過程定義偽指令PROC、ENDP

過程就是子程序。一個過程可以被其它程序所調用(用CALL指令),過程的最后一條指令一般是返回指令(RET)。過程定義偽指令的格式為

<過程名>

PROC[NEAR/FAR]…RET

<過程名>

ENDP

注意:PROC和ENDP必須成對出現(xiàn)。調用NEAR過程:先將IP內容壓入堆棧,再將入口地址傳送到IP(SP)←(SP)-2,((SP)+1:SP)←(IP)41調用FAR過程:先將CS內容壓入堆棧,再將IP內容壓入堆棧,最后將段地址送CS,偏移地址送IP(SP)←(SP)-2,((SP)+1:SP)←(CS);(SP)←(SP)-2,((SP)+1:SP)←(IP)(CS)←SEGfar_proc,(IP)←OFFSETfar_proc,例:NAME1PROCFARCALLNAME2RETNAME2PROCNEAR

RETNAME2ENDPNAME1ENDP

423.3.6模塊定義與連接偽操作1、NAME模塊名;NAME前面不允許加標號2、END[標號];END后面語句不予處理3、PUBLIC符號[,…];說明某些符號是公共的4、EXTRN名字:類型[,…]若為變量,類型可以是BYTE、WORD、DWORD例:EXTRNALPHA:BYTE,BETA:WORD若為過程,類型可以是NEAR、FAR例:EXTRNSBRT:FAR若為數(shù)值,類型可以是ABS433.4DOS系統(tǒng)功能調用介紹系統(tǒng)功能調用——由OS提供的一組實現(xiàn)特殊功能的子程序供程序員在程序中調用,以減輕編程工作量。系統(tǒng)功能調用有兩種,一種稱為DOS功能調用,另一種稱為BIOS功能調用。用戶程序在調用這些系統(tǒng)服務程序時,不是用CALL命令,而是采用軟中斷指令INTn來實現(xiàn)。n=5~1FH,調用BIOS中的服務程序;n=20~3FH,調用DOS中的服務程序;在DOS系統(tǒng)中,功能調用都是用軟中斷指令INT21H來實現(xiàn)的。44INT2lH功能大致可以分為四個方面:設備管理、目錄管理、文件管理和其它。D0S系統(tǒng)功能調用的使用方法如下:① AH←功能號;② 設置該功能所要求的其他入口參數(shù);③ 執(zhí)行INT21H指令;分析出口參數(shù)。以下介紹INT21H的幾個最常用的功能。關于數(shù)據輸入和輸出我們這里只討論鍵盤輸入和顯示輸出,調用系統(tǒng)功能需要提供入口參數(shù)及所調用的功能號,調用結束返回結果。451.DOS鍵盤功能調用(1)檢查鍵盤狀態(tài)(功能號=0BH)

MOVAH,0BHINT21H例1:

LOOP:……

MOVAH,OBHINT21HINCALJNELOOP;無鍵入則循環(huán)LOOPRET;有鍵入停止循環(huán)返回

46(2)單字符輸入一個字符(功能號=1)

MOVAH,1INT21H<AL中有鍵入的字符>例2:GET_KEY:MOVAH,1

;等待鍵入字符

INT21H

;結果在AL中

CMPAL,’Y’ ;是’Y’?JZYES ;是,轉YESCMPAL,’N’ ;是’N’?JZNO ;是,轉NOJMPGET_KEY ;否則繼續(xù)等待輸入YES: …

…NO: …47(3)輸入字符串(功能號=0AH)

此功能調用從鍵盤輸入一串字符并把它存入用戶指定的緩沖區(qū)中。

MOVAH,0AHLEADX,<字符串緩沖區(qū)首地址>INT21H用戶定義的輸入字符串的緩沖區(qū)格式

(預留的N1個字節(jié)的存儲單元)

0DHN2N1N1:緩沖區(qū)長度(最大鍵入字符數(shù))N2:實際鍵入的字符數(shù)(不包括回車符)

48例:DATASEGMENTBUFSIZEDB25ACTCHARDB?CHARTEXTDB25DUP(?)DB‘$’……CODESEGMENT……

MOVDX,OFFSETBUFSIZEMOVAH,0AHINT21H

49若用戶鍵入的字符數(shù)(包括回車)≥定義的N1,本功能調用將不再接收新的鍵入,且光標不再向右移動。例2:設在數(shù)據段定義鍵盤緩沖區(qū)如下:

STR1DB10,?,10DUP(?)

調用DOS功能的0AH號功能的程序段為:

LEADX,STR1MOVAH,0AHINT21H

此程序段最多從鍵盤接收10個按鍵(包括回車)。502.DOS顯示功能調用(1)在顯示器上顯示一個字符(功能號=2)

MOVAH,2

MOVDL,<要顯示的字符>INT21H

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

41HINT21H(2)顯示字符串(功能號=9)

MOVAH,9LEADX,<字符串>

INT21H;注意:被顯示的字符串必須以’$’結束。51附:BIOS功能調用BIOS:基本輸入輸出系統(tǒng),是固化在EPROM中的一組實現(xiàn)基本輸入輸出功能的子程序。BIOS調用通過多個軟中斷提供,調用方法為:

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

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

INT10H——屏幕顯示

INT13H——磁盤操作

INT14H——串行口操作

INT16H——鍵盤操作 INT17H——打印機操作 每類中斷由包含許多子功能,調用時通過功能號指定。

BIOS功能調用說明見附錄。523.5匯編語言程序設計舉例例1:源數(shù)據區(qū)與目標數(shù)據區(qū)地址可能重疊的數(shù)據塊傳送圖3.15

源數(shù)據區(qū)與目標數(shù)據區(qū)地址重疊示意圖53注1:若源數(shù)據區(qū)的起始地址低于目標數(shù)據區(qū)的起始地址,應從高地址開始傳送;否則應從低地址開始傳送。注2:數(shù)據塊的長度在CX中。54CODESEGMENTASSUMECS:CODEBLK_MOVPROCFARSTART:PUSHDS;DS壓入堆棧MOVAX,0PUSHAX;AX壓入堆棧MOVAX,SI;計算源數(shù)據區(qū)物理地址的高16位

SHRAX,1SHRAX,1SHRAX,1SHRAX,1;AX內容右移4位MOVDX,DS;段地址存入DXADDAX,DX;物理地址高16位存入AX中MOVDS,AX;結果送DSANDSI,0FH;源數(shù)據區(qū)物理地址低4位送SI55MOVBX,DI;計算目標數(shù)據區(qū)物理地址的高16位

SHRBX,1SHRBX,1SHRBX,1SHRBX,1;BX內容右移4位MOVDX,ES;段地址存入DXADDBX,DX;物理地址高16位存入BX中MOVES,BX;結果送ESANDDI,0FH;源數(shù)據區(qū)物理地址低4位送DI

CMPAX,BX;比較DS與ES的高16位JADOWN;若DS高,則轉移到DOWNJBUP;若ES高,則轉移到UP

56

CMPSI,DI;若相等,則比較低4位地址JADOWN;若SI高,則轉DOWNJBUP;若DI高,則轉UPJMPEXIT;若相等,則無條件退出UP:STD;(DF)=1,從高地址開始傳送MOVAX,CX;將數(shù)據段長度送AXDECAX;AX減1ADDSI,AX;(SI)←(SI)+(AX)ADDDI,AX;(DI)←(DI)+(AX)JMPTRANS57DOWN:CLD;(DF)=0,從低地址開始傳送TRANS:REPMOVSBEXIT:RETBLK_MOVEENDPCODEENDSENDSTRAT

思考題:1、如何獲得的物理地址?2、為什么不用SHRAX,CL?

58例2:將36位BCD數(shù)轉換為ASCII十進制數(shù)注1:前導的0可以不顯示;注2:全0時則只顯示一個0;59DATASEGMENTBCDBUFDB56H,34H,12H,90H,78H,56H,34H,12HDB90H,78H,56H,34H,12H,90H,78H,56H,34H,12HDATAENDSSTACKSEGMENTSTACKDB100DUP(?);定義100個存儲空間,但內容未知STACKENDSCODESEGMENTASSUMECS:CODE,DS:DATA,SS:STACKTRANSPROCFARSTRAT:PUSHDS;將DS壓入堆棧MOVAX,0PUSHAX;將AX壓入堆棧60

MOVAX,DATAMOVDS,AX

;數(shù)據段初始化MOVCX,18;字節(jié)數(shù)LEASI,BCDBUF;取BCDBUF的偏移地址ADDSI,17;(SI)=17MOVDH,0;(DH)=0LOAD:PUSHCX;將CX壓入堆棧MOVAL,[SI];取最后一個BCD數(shù)DECSI;SI減1MOVBL,AL;將AL內容送BL暫存MOVCL,4ROLAL,CL;AL內容左移4位,高4位與低4位交換61

ANDAL,0FH;取高4位BCDORDH,AL;判斷是否為前導0JZLAST;是的話,轉LAST

ADDAL,30H;轉換成ASCII碼MOVDL,ALMOVAH,02INT21H;輸出顯示LAST:POPCX;CX出棧CMPCX,1;判斷是否為最后一個字節(jié)JNZBCDL;否,則轉BCDLMOVDH,0FFH;若是,設置標志62BCDL:MOVAL,BL;取暫存在BL的內容ANDAL,0FH;取低4位BCDORDH,AL;判斷是否為前導0JZGOON;是的話,轉GOONADDAL,30H;轉換成ASCII碼

MOVDL,ALMOVAH,02INT21H

;輸出顯示GOON:LOOPLOADRETTRANSENDPCODEENDSENDSTRAT63例3:要求從鍵盤輸入一個小寫英文字母,將其轉換成大寫英文字母后屏幕上顯示出來。源程序設計如下:STACKSEGMENTSTACK ;定義堆棧段

DB100DUP(?) ;開辟100個存儲單元STACKENDS ;堆棧段結束CODESEGMENT;定義代碼段

ASSUMECS:CODE,SS:STACKSTART:MOVAH,01H;1號調用,從鍵盤輸入一字符存入ALINT21H

SUBAL,20H;將AL中字符的ASCII碼減去20H變成大寫字母

MOVDL,AL ;結果送DL

64

MOVAH,02H ;2號調用,在屏幕上顯示DL中的內容

INT21H

MOVAH,4CH ;返回DOS INT21H

CODEENDS

;代碼段結束

ENDSTART ;程序匯編結束

65

例4:試計算(S=(W-(X×Y+Z-340))/X)DATASEGMENT;定義數(shù)據段

WDW-245 ;變量初始化

XDW15YDW-32ZDW280RESULTDW2DUP(?) ;定義結果保存單元DATAENDS ;數(shù)據段結束CODESEGMENT ;定義代碼段

ASSUMECS:CODE,DS:DATA

START:MOVAX,DATA ;初始化DSMOVDS,AX

MOVAX,X ;取出被乘數(shù)X存入AX中

IMULY ;執(zhí)行X×Y操作

66MOVCX,AX;乘積的低位字轉存至CXMOVBX,DX;乘積的高位字轉存至BXMOVAX,Z;取出加數(shù)Z存入AX中CWD;將Z擴展成雙字ADDCX,AX;X×Y的低位字與Z的低位字相加ADCBX,DX;X×Y的高位字與Z的高位字及進位相加

SUBCX,340;X×Y+Z的低位字減340SBBBX,0;X×Y+Z的高位字減低位的借位67

MOVAX,W ;取出W存入AXCWD ;將W擴展成雙字

SUBAX,CX ;(W-(X×Y+Z)-340)低位運算

SBBDX,BX ;(W-(X×Y+Z)-340)高位運算

IDIVX ;(W-(X×Y+Z)-340)/X

MOVRESULT,AX;商存入RESULT單元

MOVRESULT+2,DX;余數(shù)存入RESULT+2單元

MOVAH,4CHINT21H ;返回DOS

CODEENDS ;代碼段結束

ENDSTART;匯編結束68例5:已知在內存中有一個字節(jié)單元X,存有帶符號數(shù)據,要求計算出它的絕對值后,放入RESULT單元中。分析:根據數(shù)學中絕對值的概念知道,一個正數(shù)的絕對值是它本身,而一個負數(shù)的絕對值是它的相反數(shù)加1;要計算一個數(shù)的相反數(shù),需要完成減法運算,即用0減去這個數(shù)。8086指令系統(tǒng)中有專門的取負求其補數(shù)的指令NEG。程序流程如圖所示。源程序設計如下:69程序段如下DATA SEGMENT

X DB-25 ;定義變量

RESULT DB? ;定義結果保存單元DATA ENDSCODE SEGMENTASSUMEDS:DATA,CS:CODESTART:MOV AX,DATA MOV DS,AX ;初始化DS

MOV AL,X;X取到AL中

TEST AL,80H;測試AL正負

JZ NEXT;為正,轉NEXT

NEG AL;否則AL求補NEXT: MOV RESULT,AL ;送結果

MOV AH,4CHINT 21H ;返回DOSCODE ENDS

END START ;匯編結束70例6:設變量X為帶符號整數(shù),試編寫一個程序,完成下面的分段函數(shù)計算:

題目分析:為了實現(xiàn)上述分段函數(shù)的計算,首先要利用上一個例題求出X的絕對值,然后根據X的絕對值判斷Y的取值。程序流程如圖所示。程序段如下(DOS下演示)

:71DATA SEGMENT

XDB-36YDB?DATAENDSCODESEGMENTASSUMECS:CODE,DS:DATASTART:MOVAX,DATA MOVDS,AX

MOVAL,X CMPAL,0JGENEXT ;為正,轉NEXT

NEGAL ;AL中的內容求補NEXT:CMPAL,5 ;|X|和5比較

JGEP1 ;≥5,轉P1

MOVAL,1 ;否則1送ALMOVBL,X ;X送BL中

SUBAL,BL ;結果送AL中

JMPEXIT ;轉EXITP1: MOVAL,0 ;0送AL中EXIT:MOVY,AL ;結果送Y單元

MOVAH,4CHINT21H ;返回DOSCODE ENDS

ENDSTART ;匯編結束

72

例7:編寫程序,完成下面的分段函數(shù)的計算(X為單字節(jié)帶符號數(shù)據)。題目分析:這是1個3路分支的程序設計,X為內存中的一個帶符號數(shù),首先判斷其正負,若為負,-1作為函數(shù)值;若為正,再判斷是否為0,如果為0,函數(shù)返回值為0,否則返回值為1,流程圖如圖所示。73

DATASEGMENTXDB-25YDB?DATAENDSCODESEGMENTASSUMECS:CODE,DS:DATA

START:MOVAX,DATA

MOVDS,AX;初始化DS

MOVAL,X;X取到AL中

CMPAL,0;AL和0比較

JGEBIG;≥0,轉BIGMOVBL,-1;否則-1送BLJMPEXIT;轉到結束位置

74BIG:JEEE;AL=0轉EEMOVBL,1;否則1送BLJMPEXIT;轉到結束位置

EE:MOVBL,0;0送BLEXIT:MOVY,BL;BL中內容送Y單元

MOVAH,4CHINT21H

CODEENDSENDSTART;匯編結束75例8:設計一個程序,統(tǒng)計在內存W單元保存的無符號字變量中有多少個二進制“1”,統(tǒng)計結果送內存N單元保存。分析:要統(tǒng)計內存W單元保存的無符號字變量中有多少個二進制“1”,可以將該數(shù)據送寄存器AX中,通過移位指令將AX中的每一位依次移入進位標志CF中,若CF=1則計數(shù)器CL的值加1,這樣就可以統(tǒng)計出AX中1的個數(shù)。設計源程序如下:DATASEGMENTWDW00FFH ;定義字數(shù)據NDB? ;定義結果保存單元DATAENDSCODESEGMENT ASSUMECS:CODE,DS:DATA76START:MOVAX,DATA ;初始化DSMOVDS,AX

MOVCL,0 ;計數(shù)器清零

MOVAX,W ;取數(shù)到AXAA: ANDAX,AX ;邏輯與,判AX=0?

JZCC ;結果為0轉移到CCSHLAX,1 ;邏輯左移1位

JNCBB ;無進位轉BB

INCCL ;有“1”則計數(shù)BB: JMPAA ;無條件轉AACC: MOVN,CL ;結果送N單元

MOVAH,4CH ;返回DOSINT21HCODEENDS

ENDSTART ;匯編結束77例9:編制程序完成求1~50之間的自然數(shù)中的奇數(shù)之累加和,結果送到RESULT單元中。該題屬于循環(huán)次數(shù)已知,即將50以內的25個奇數(shù)進行累加和計算,可采用遞增計數(shù)法來實現(xiàn)求累加和,程序設計如下:DATA SEGMENTRESULTDW? ;定義結果保存單元CNEQU25 ;定義計數(shù)次數(shù)變量DATA ENDSCODE SEGMENT

ASSUMEDS:DATA,CS:CODE78START:MOVAX,DATAMOVDS,AX ;初始化DS

MOVAX,0 ;循環(huán)初始化

MOVCX,CNMOVBX,1NEXT:ADDAX,BX ;求累加和

ADDBX,2 ;(BX)←(BX)+2LOOPNEXT ;(CX)-1≠0轉NEXT

MOVRESULT,AX ;計算完畢保存結果

MOVAH,4CHINT21H ;程序結束CODEENDS

ENDSTART ;匯編結束79

例10:編制程序完成求1+2+3+……+N的累加和,直到累加和超過1000為止。統(tǒng)計被累加的自然數(shù)的個數(shù)送CN單元,累加和送SUM單元。該題的循環(huán)次數(shù)預先是不確定的,只能按照循環(huán)過程中的某個特定條件來決定循環(huán)是否繼續(xù)執(zhí)行??赏ㄟ^測試條件是否成立來實現(xiàn)對循環(huán)的控制。程序設計如下:80DATA SEGMENT SUMDW? CNDW?DATA ENDSCODE SEGMENT

ASSUMECS:CODE,DS:DATASTART:MOVAX,DATA MOVDS,AX ;初始化DS

MOVAX,0 ;0送AX MOVBX,0 ;0送BXLP: INCBX ;BX加1 ADDAX,BX ;求累加和

CMPAX,1000 ;比較

JBELP ;結果≤1000轉LP

MOVSUM,AX MOVCN,BX ;送結果

MOVAH,4CH INT21H ;返回DOSCODE ENDS

ENDSTART ;匯編結束81例11:已知在內存中從TABLE單元起存放0~10的平方值。在X單元中有一個待查數(shù)據,用查表的方法求出X的平方值送到Y單元中。程序如下:DATA SEGMENT

TABLEDW0,1,4,9,16,25,36,49,64,81,100 X DB4 Y DW?DATA ENDSCODE SEGMENT

ASSUMEDS:DATA,CS:CODESTART:MOVAX,DATA MOVDS,AX ;初始化DS

82

MOVBX,OFFSETTABLE ;BX指向表格首地址

MOVAL,X ;X中內容取出送至AL中

MOVAH,0 ;X中的值擴展為字

SHLAX,1 ;計算X乘2

ADDBX,AX ;BX指向要查找的位置

MOVDL,[BX];取出要查找的內容的低位字節(jié)

MOVDH,[BX+1];取出要查找的內容的高位字節(jié)

MOVY,DX;結果保存到內存中

MOVAH,4CH INT21H

溫馨提示

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

評論

0/150

提交評論