微機4-12上第2章已學(xué)匯編課件_第1頁
微機4-12上第2章已學(xué)匯編課件_第2頁
微機4-12上第2章已學(xué)匯編課件_第3頁
微機4-12上第2章已學(xué)匯編課件_第4頁
微機4-12上第2章已學(xué)匯編課件_第5頁
已閱讀5頁,還剩100頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

第2章

指令系統(tǒng)及匯編語言程序設(shè)計2.18088/8086的尋址方式2.28088/8086的指令系統(tǒng)2.3匯編語言匯編語言源程序格式偽指令匯編語言源程序結(jié)構(gòu)2.4匯編語言程序設(shè)計基本程序設(shè)計方法DOS功能調(diào)用順序程序設(shè)計分支程序設(shè)計循環(huán)程序設(shè)計子程序設(shè)計本次課內(nèi)容請大家復(fù)習(xí)《匯編語言》掌握本節(jié)內(nèi)容第二章復(fù)習(xí)小結(jié)下次課5.9匯編語言單元考試及講第3章2.3匯編語言匯編語言的特點匯編語言是一種以處理器指令系統(tǒng)為基礎(chǔ)的低級程序設(shè)計語言,它采用助記符表達指令操作碼利用匯編語言編寫程序的主要優(yōu)點是可以直接、有效地控制計算機硬件,因而容易創(chuàng)建代碼序列短小、運行快速的可執(zhí)行程序在有些應(yīng)用領(lǐng)域,匯編語言的作用是不容置疑和無可替代的匯編程序設(shè)計的過程是與其他高級語言程序設(shè)計大致相同什么是匯編語言以助記符形式表示計算機指令助記符(mnemonic)是便于人們記憶、并能描述指令功能和指令操作數(shù)的符號助記符是表明指令功能的英語單詞或其縮寫匯編格式指令以及使用它們編寫程序的規(guī)則就形成匯編語言(AssemblyLanguage)匯編語言程序:用匯編語言書寫的程序匯編程序:將匯編語言程序“匯編”成機器代碼目標模塊的程序匯編語言程序與匯編程序是兩個概念硬指令和偽指令匯編程序?qū)R編語言源程序翻譯成在機器上能執(zhí)行的機器語言程序(目的代碼程序硬指令---執(zhí)行性語句使CPU產(chǎn)生動作、并在程序執(zhí)行時才處理的語句,就是第2章學(xué)習(xí)的處理器指令與具體的處理器有關(guān)、與匯編程序無關(guān)。匯編后對應(yīng)一條指令代碼偽指令(Directive)---說明性語句不產(chǎn)生CPU動作、在程序執(zhí)行前由匯編程序處理的說明性語句,例如,數(shù)據(jù)說明、變量定義等等偽指令與具體的處理器類型無關(guān),但與匯編程序的版本有關(guān)本課程采用微軟宏匯編程序MASM6.15硬指令和偽指令采用易于記憶的符合表達,這就是助記符

MOVCX,0;傳送指令,具有2個操作數(shù)DELA: NOP

;空操作指令,沒有操作數(shù),帶有標號

LOOPDELA;循環(huán)指令,標號DELA說明轉(zhuǎn)移位置BUFDB1,2,3,4,5,6,7

;數(shù)據(jù)定義偽指令,在主存中開辟7個連續(xù)的字節(jié)單元,初值依次為1~7,BU表示首地址匯編語言語句實例一.匯編語言源程序格式(4部分)標號

硬指令的位置(邏輯地址),后加冒號:

名字

偽指令的位置或存儲單元名稱(變量名),后不加冒號:一般最多由31個字母、數(shù)字及規(guī)定的特殊符號(如_、$、?、@)組成不能以數(shù)字開頭(如1ABC錯),不能是保留字指令助記符

必須有,其它3部分可無偽指令助記符----偽指令硬指令助記符-----硬指令注釋語句中由分號“;”開始的部分為注釋內(nèi)容,用以增加源程序的可讀性必要時,一個語句行也可以由分號開始作為階段性注釋匯編程序在翻譯源程序時將跳過該部分,不對它們做任何處理標號: 硬指令助記符操作數(shù)1,操作數(shù)2

;注釋名字偽指令助記符參數(shù)1,參數(shù)2,…;注釋例:

硬指令

Done:moval,02h

偽指令Sumdb02h[標號]指令助記符[操作數(shù)][;注釋]

匯編語言源程序格式---操作數(shù)操作數(shù)常數(shù)、數(shù)值表達式、寄存器、標號、變量等數(shù)值表達式一般是指由運算符連接的各種常數(shù)所構(gòu)成的表達式匯編程序在匯編過程中計算表達式,最終得到一個確定的數(shù)值,所以也是常數(shù)常用的運算符是加減乘除(+-*/)

例:movax,3*4+5 ;等價于movax,17匯編語言源程序格式---操作數(shù)操作數(shù)常數(shù)、寄存器、標號、數(shù)值表達式、變量等常數(shù)匯編時已確定的數(shù)據(jù)如硬指令中立即數(shù)二進制數(shù)如MOVAL,10110101B十進制常數(shù)如MOVAL,181十六進制數(shù)常數(shù)以字母開頭的十六進制數(shù)前加“0”。例:MOVAL,0B5H字符和字符串常數(shù)例:MOVAX,’AB’;AX4142h

MOVAX,’1’;AX31h用單引號括起來的單個字符或多個字符,其數(shù)值是每個字符對應(yīng)的ASCII碼的值.例如:'d'=64H,'AB'=4142H符號常數(shù)用符號名表示一個常數(shù),可以提高程序的可讀性,同時更具有通用性符號定義偽指令格式等價EQU偽指令符號名EQU表達式例:XY EQU5等號=偽指令符號名=表達式例:XY=5例:XY EQU 5MOVAH,XY;等價于MOVAH,5符號定義

DosWriteCharequ2 CarriageReturn=13 CallDOSequ<int21h>符號應(yīng)用(左邊程序段等價右側(cè)的符號形式) movah,2 ;movah,DosWriteChar movdl,13 ;movdl,CarriageReturn int21h ;CallDOS符號常數(shù)實例2.變量定義偽指令(定義數(shù)據(jù)偽指令)變量定義偽指令為變量申請固定長度的存儲空間,同時將相應(yīng)存儲單元初始化(參數(shù)為?則不初始化)。格式為:變量名DB/DW/DD/DQ參數(shù)1,參數(shù)2,…DB(或BYTE)定義字節(jié)其后每個參數(shù)占1個字節(jié)存儲單元DW(或WORD)定義字其后每個參數(shù)占2個字節(jié)(先低字節(jié)后高字節(jié))存儲單元DD(或DWORD)定義雙字其后每個參數(shù)占4個字節(jié)存儲單元DQ(或QWORD)定義4個字其后每個參數(shù)占8個字節(jié)存儲單元多個存儲單元如果初值相同,可以用復(fù)制操作符DUP進行定義:

重復(fù)次數(shù)DUP(重復(fù)參數(shù))變量實質(zhì)指內(nèi)存單元的數(shù)據(jù),變量需要事先定義才能使用.定義后的變量可用變量名等引用其中的數(shù)據(jù),即變量的數(shù)值例:alpha byte 30h,2DUP(55H),34h,?mov cx,alpha;cx5530h mov bx,offsetalpha mov al,[bx+3] ;al34h變量定義偽指令最常使用定義字節(jié)單元偽指令DBDB偽指令用于分配一個或多個字節(jié)單元,并可以將它們初始化為指定值初值表中每個數(shù)據(jù)一定是字節(jié)量(Byte),存放一個8位數(shù)據(jù):可以是0~255的無符號數(shù)或是-128~+127帶符號數(shù)也可以是字符串常數(shù)字節(jié)變量定義實例;數(shù)據(jù)段Xdb61h,0fbhdb2dup(64h),?Ydb'ABC'應(yīng)用moval,XdecX+1movY,alASCII‘a(chǎn)’=61h’A’=41h‘B’=42h‘C’=43h;此處X表示它的第1個數(shù)據(jù),故AL←61h;對X為始的第2個數(shù)據(jù)減1,故為0fah;Y=al=61h,現(xiàn)在Y這個字符串成為'aBC'定義字單元偽指令DWDW偽指令用于分配一個或多個字單元,并可以將它們初始化為指定值初值表中每個數(shù)據(jù)一定是字量(Word),一個字單元可用于存放任何16位數(shù)據(jù):一個段地址一個偏移地址兩個字符

0~65535之間的無符號數(shù)-32768~+32767之間的帶符號數(shù)字變量定義實例;數(shù)據(jù)段count dw8000h,?,'AB'maxint equ64hnumber dwmaxintarray dwmaxintdup(0)ASCII’A’=41h‘B’=42h;數(shù)據(jù)段字變量和字常量的定義:WNUMEQU5678H;定義WNUM為常量COUNTDW20H;定義COUNT變量,假設(shè)在數(shù)據(jù)段的偏移地址為0010H;代碼段字變量和字常量的應(yīng)用:MOVAX,[BX+SI+WNUM] 等價于MOVAX,[BX+SI+5678H]

MOVAX,COUNT 等價于MOVAX,[0010H] ;AX0020HMOVAX,[SI+COUNT]等價于MOVAX,[SI+0010H]LEABX,COUNT 等價于LEABX,[0010H];BX0010HMOVBX,OFFSETCOUNT 等價于MOVBX,0010H;BX0010H字變量和字常量實例串操作類指令8088的串操作類指令能對主存中一個連續(xù)區(qū)域的數(shù)據(jù)(如數(shù)組、字符串等)進行傳送、比較等同樣操作。當DF=0地址自動增量,從低地址到高地址處理字符串;當DF=1地址減量指令有:傳送數(shù)據(jù)串:MOVS,STOS,LODS檢測數(shù)據(jù)串:CMPS,SCAS重復(fù)前綴:REP,REPZ,REPNZ源操作數(shù)----DS:[SI]目的操作數(shù)---ES:[DI]每執(zhí)行一次串操作指令,SI和DI將自動修改:±1(對于字節(jié)串)或±2(對于字串)執(zhí)行指令CLD后,DF=0,地址指針增1或2執(zhí)行指令STD后,DF=1,地址指針減1或2利用循環(huán)程序也可以實現(xiàn)串操作指令的功能例:MOVSB(movestringbyte)

;ES:[DI]←DS:[SI];當DF=0,SI←SI+1DI←DI+1當DF=1,SI←SI-1DI←DI-1例.數(shù)據(jù)復(fù)制和顯示 .modelsmall .stack .datasource db 33h,34h,35h,36h ;定義4個字符數(shù)據(jù)target db 80dup(?) ;分配數(shù)據(jù)空間4×20=80 .code .startup mov ax,ds mov es,ax ;data也作為附加段 cld mov si,offsetsource mov di,offsettarget mov cx,80

rep movsb

;串傳送 mov si,0 ;顯示 mov bx,offsettargetagain: mov dl,[bx+si] mov ah,2 int 21h inc si cmp si,80 jb again .exit0 end3.宏(Macro)命令偽指令為簡化程序編制,對多次使用的程序,既可用子程序也可用宏指令、宏匯編實現(xiàn)宏定義宏是具有宏命令名的一段匯編語句序列 宏命令名

MACRO[形參數(shù)1,參數(shù)2,…]

…… ;宏定義體(硬指令、偽指令)

ENDM

宏調(diào)用

宏命令名[實參數(shù)1,參數(shù)2,…]宏需要先定義,然后才可在程序中宏調(diào)用,形式上類似其他指令,常稱其為宏指令宏指令實際上是一段代碼序列的縮寫。在匯編時,宏指令被匯編程序用對應(yīng)的代碼序列替代,這就是宏展開因為是在匯編過程中實現(xiàn)的宏展開,所以常稱為宏匯編宏與子程序的比較比較僅是源程序級的簡化:宏調(diào)用在匯編時進行程序語句的展開,不需要返回;不減小目標程序,執(zhí)行速度沒有改變還是目標程序級的簡化:子程序調(diào)用在執(zhí)行時由CALL指令轉(zhuǎn)向、RET指令返回;形成的目標代碼較短,執(zhí)行速度減慢宏子程序定位偽指令定位偽指令控制數(shù)據(jù)的偏移地址ORG參數(shù)ORG偽指令是將當前偏移地址指針指向參數(shù)表達的偏移地址:ORG100h ;從100h處安排數(shù)據(jù)或程序ORG$+10;使偏移地址加10,即跳過10個字節(jié)空間MASM中,符號“$”表示當前偏移地址值EVEN ;從偶地址開始ALIGNn ;從n的整數(shù)倍地址開始 org$+10array db45,45h .code movax,segarray movds,ax movbx,offsetarray ;等價于leabx,array movcl,array+4 ;等效于movcl,array[4] movax,es:[2000h]地址操作符實例

加4個字節(jié)單元屬性運算符PTR對名字或標號的類型屬性進行設(shè)置

類型名PTR名字/標號類型名可以是BYTE、WORD、DWORD(依次表示字節(jié)、字、雙字)等,或者是NEAR、FAR(分別表示近、遠)定義的類型例:moval,byteptrvar ;var是一個字節(jié)變量jmpfarptrlabel ;label是一個標號decwordptr[di]incbyteptr[di]使用PTR操作符,可以臨時改變名字或標號的類型8088CPU的存儲格式--小端存儲方式D7D0字節(jié)D15D0字D31D0雙字00006H78H00005H56H00004H12H00003H34H00002H00001H00000H低地址LSBMSB00002H單元的內(nèi)容為:[00002H]=34H00002H“字”單元的內(nèi)容為:[00002H]=1234H00002H號“雙字”單元的內(nèi)容為:[00002H]=78561234H多字節(jié)數(shù)據(jù)在存儲器中占連續(xù)的多個存儲單元存放:低字節(jié)存入低地址,高字節(jié)存入高地址表達:用低地址表示多字節(jié)數(shù)據(jù)占據(jù)的地址空間同一個存儲器地址可以是字節(jié)單元地址、字單元地址、雙字單元地址等等設(shè)DS=000002H“雙字”單元MOVEAX,[0002H]00002H“字”單元MOVAX,[0002H]00002H單元

MOVAH,[0002H高地址存儲單元D7D0存儲器地址 .modelsmall .stack .datav_byte equthisbyte;v_byte是字節(jié)類型,與變量v_word的地址相同v_word dw3332h,3735h

;v_word是字類型的變量target dw5dup(20h)

;分配數(shù)據(jù)空間2×5=10字節(jié)crlf db0dh,0ah,'$'flag db0n_point dwoffsets_label

;取得標號s_label的偏移地址例3.4:屬性及其應(yīng)用-1/5例3.4:屬性及其應(yīng)用-2/5 .code .startup moval,byteptrv_word;用PTR改變v_word的類型,否則類型不匹配 decal movv_byte,al;對v_word的頭一個字節(jié)操作,原為32H、現(xiàn)為31Hn_label: cmpflag,1 jzs_label ;flag單元為1轉(zhuǎn)移 incflag jmpn_label ;進行短轉(zhuǎn)移例3.4:屬性及其應(yīng)用-3/5s_label: cmpflag,2 jznext ;flag單元為2轉(zhuǎn)移 incflag

jmpn_point;段內(nèi)的存儲器間接尋址,轉(zhuǎn)移到s_label標號處next: movax,typev_word ;匯編結(jié)果為movax,2 movcx,lengthoftarget ;匯編結(jié)果為movcx,5例3.4:屬性及其應(yīng)用-4/5 movsi,offsettargetw_again: mov[si],ax ;對字單元操作 incsi ;SI指針加2 incsi loopw_again ;循環(huán) movcx,sizeoftarget

;匯編結(jié)果為movcx,0ah moval,'?' movdi,offsettargetb_again: mov[di],al ;對字節(jié)單元操作 incdi ;DI指針加1 loopb_again ;循環(huán)例3.4:屬性及其應(yīng)用-5/5 movdx,offsetv_word ;顯示結(jié)果:1357?????????? movah,9 int21h .exit0 end四.匯編語言源程序結(jié)構(gòu)完整的匯編語言源程序由段組成一個匯編語言源程序可以包含若干個代碼段、數(shù)據(jù)段、附加段或堆棧段,段與段之間的順序可隨意排列需獨立運行的程序必須包含一個代碼段,并指示程序執(zhí)行的起始點,一個程序只有一個起始點所有的硬指令語句必須位于某一個代碼段內(nèi),偽指令語句可根據(jù)需要位于任一段內(nèi)通常,程序還需要一個堆棧段源程序由語句序列構(gòu)成匯編語言翻譯器(匯編程序,如MASM)對源程序有嚴格格式要求,才能將之翻譯成目的代碼段寄存器及邏輯段分配段寄存器及邏輯段分配8088CPU訪問內(nèi)存有20條地址線共220B=1MB個存儲單元FFFFFH,內(nèi)存地址00000H~FFFFFH8088CPU將1MB空間分成許多段,有4個16位段寄存器,對應(yīng)4種邏輯段.每個段最大限制為64KBCodeSegment代碼段StackSegment堆棧段DataSegment數(shù)據(jù)段ExtraSegment附加段8088有4個16位段寄存器CS(CodeSegmentRegister)指令SS(StackSegmentRegister)堆棧DS(DataSegmentRegister)數(shù)據(jù)ES(ExtraSegmentRegister)數(shù)據(jù)每個段寄存器用來確定一個邏輯段的起始地址,每種邏輯段均有各自的用途程序的指令序列必須安排在代碼段CS程序使用的堆棧一定在堆棧段SS程序中的數(shù)據(jù)默認是安排在數(shù)據(jù)段DS,也經(jīng)常安排在附加段ES,尤其是串操作的目的區(qū)必須是附加段匯編語言源程序格式源程序分別用兩種格式書寫第一種格式從MASM5.0開始支持簡化段定義格式第二種格式MASM5.0以前就具有完整段定義格式(一般了解)求較大值—兩無符號數(shù)AX、BX的較大值放入wmax例:程序功能簡單,要求掌握求較大值—兩無符號數(shù)AX、BX的較大值放入wmax

匯編語言程序?qū)嵗齱max dw 0 cmpax,bx ;比較AX和BX jncnext ;若AX≥BX,轉(zhuǎn)移 xchgax,bx ;若AX<BX,交換next: movwmax,ax簡化段定義格式

求較大值—兩無符號數(shù)AX、BX的較大值放入wmax

.modelsmall .data ;定義數(shù)據(jù)段wmax dw 0

.code ;定義代碼段start: movax,@data ;程序起始點,建立DS movds,ax cmpax,bx ;比較AX和BX jncnext ;若AX≥BX,轉(zhuǎn)移 xchgax,bx ;若AX<BX,交換next: movwmax,ax

.exit0 ;程序正常執(zhí)行結(jié)束 endstart ;匯編結(jié)束

程序數(shù)據(jù)定義匯編語言程序?qū)嵗齭tack segmentstack ;定義堆棧段 dw512dup(?) ;堆棧段有512字(1024字節(jié))空間stack ends ;堆棧段結(jié)束data segment ;定義數(shù)據(jù)段wmax dw0data endscode segment’code’ ;定義代碼段 assumecs:code,ds:data,ss:stackstart: movax,data ;建立DS段地址 movds,ax

cmpax,bx ;比較AX和BX jncnext ;若AX≥BX,轉(zhuǎn)移 xchgax,bx ;若AX<BX,交換next: movwmax,ax

movax,4c00h int21h ;利用功能調(diào)用返回DOScode ends ;代碼段結(jié)束 endstart ;匯編結(jié)束,同時指明程序起始點例:完整段定義格式完整段定義格式程序例題stack segmentstack dw512dup(?)stack endsdata segment …… ;數(shù)據(jù)定義(數(shù)據(jù)待填)data endscode segment’code’ assumecs:code,ds:data,ss:stackstart: movax,data movds,ax …… ;主程序(指令待填) movax,4c00h int21h

…… ;子程序(指令待填)code ends endstart完整段定義格式

MASM5.x支持源程序格式(一般了解)例題源程序格式(重點掌握)

.modelsmall;定義程序的存儲模式 .data ;定義數(shù)據(jù)段

…… ;在數(shù)據(jù)段定義數(shù)據(jù) .code ;定義代碼段

.startup;程序起始點,設(shè)置DS、SS

…… ;主程序(指令待填) .exit0 ;程序結(jié)束點,返回DOS

…… ;子程序(指令待填) end ;匯編結(jié)束溫馨提示:可以無數(shù)據(jù)段常用簡化段定義格式

MASM6.x支持例題或者源程序格式(重點掌握)

.modelsmall;定義程序的存儲模式 .data ;定義數(shù)據(jù)段

…… ;在數(shù)據(jù)段定義數(shù)據(jù) .code ;定義代碼段start: movax,@data;程序起始點,設(shè)置數(shù)據(jù)段段地址DS

movds,ax

…… ;主程序(指令待填) .exit0 ;程序結(jié)束點,返回DOS

…… ;子程序(指令待填) endstart ;匯編結(jié)束溫馨提示:可以無數(shù)據(jù)段常用簡化段定義格式

MASM6.x支持例題1.簡化段定義格式

(1)源程序格式數(shù)據(jù)段定義偽指令.DATA創(chuàng)建一個數(shù)據(jù)段代碼段定義偽指令.CODE創(chuàng)建一個代碼段堆棧段由Windows維護,用戶不必設(shè)置程序開始執(zhí)行的位置應(yīng)用一個標號(例如:START)匯編結(jié)束END指令的參數(shù)應(yīng)用程序執(zhí)行結(jié)束語句“EXIT0”將控制權(quán)交還操作系統(tǒng)提供給操作系統(tǒng)一個返回代碼通常用0表示執(zhí)行正確源程序匯編結(jié)束END語句執(zhí)行結(jié)束≠匯編結(jié)束;SampleA.ASM .modelsmall .stack .data

... ;在數(shù)據(jù)段定義數(shù)據(jù) .code .startup

... ;在代碼段填入指令序列 .exit0

...

;子程序代碼 end簡化段定義格式

MASM6.x支持;SampleC.ASM .modelsmall .stack .data ... ;在數(shù)據(jù)段定義數(shù)據(jù) .codestart:movax,@data movds,ax

... ;在代碼段填入指令序列 movax,4c00h int21h

...

;子程序代碼 endstart簡化段定義格式

MASM5.x支持.modelsmall;定義程序的存儲模式.data ;定義數(shù)據(jù)段.code ;定義代碼段 .exit0 ;程序結(jié)束點,返回DOSend ;匯編結(jié)束(2)簡化段定義格式偽指令存儲模式偽指令.MODEL存儲模式使用簡化段定義,必須有存儲模式偽指令.model語句必須位于所有段定義語句之前存儲模式?jīng)Q定一個程序的規(guī)模,確定進行子程序調(diào)用、指令轉(zhuǎn)移和數(shù)據(jù)訪問的缺省屬性MASM有7種不同的存儲模式:①TINY ②SMALL③COMPACT ④MEDIUM⑤LARGE ⑥HUGE⑦FLATSMALL小型模式一般的程序(例如本書的絕大多數(shù)程序示例和習(xí)題)都可用這種模式在小型模式下,一個程序至多只能有一個代碼段和一個數(shù)據(jù)段,每段不大于64KB這里的數(shù)據(jù)段是指數(shù)據(jù)段、堆棧段和附加段的總和,它們共用同一個段基址,總長度不可超過64KB;因此小模式下程序的最大長度為128KB訪問操作數(shù)或指令都只需要使用16位偏移地址;這意味著諸如指令轉(zhuǎn)移、程序調(diào)用以及數(shù)據(jù)訪問等都是近屬性(NEAR),即小型模式下的調(diào)用類型和數(shù)據(jù)指針缺省分別為近調(diào)用和近指針簡化段定義偽指令.STACK[大小] ;堆棧段開始.DATA ;數(shù)據(jù)段開始.CODE[段名] ;代碼段開始簡化段定義偽指令指明一個邏輯段的開始,同時自動結(jié)束前面的一個段采用簡化段定義偽指令前,需有.model語句使用簡化段定義,各段名稱和其他用戶所需的信息可以使用MASM預(yù)定義符號,例如:@data表示由.data等定義的數(shù)據(jù)段的段名堆棧段偽指令.STACK[大小]堆棧段偽指令.STACK創(chuàng)建一個堆棧段,段名是:stack它的參數(shù)指定堆棧段所占存儲區(qū)的字節(jié)數(shù),默認是1KB(=1024=400h字節(jié))數(shù)據(jù)段偽指令.DATA數(shù)據(jù)段偽指令.data創(chuàng)建一個數(shù)據(jù)段,段名是:_DATA。它用于定義具有初值的變量,當然也允許定義無初值的變量無初值變量可以安排在另一個段中,它用.data?偽指令創(chuàng)建,數(shù)據(jù)段名是:_BSS.const偽指令用于建立只讀的常量數(shù)據(jù)段(段名:CONST)代碼段偽指令.CODE[段名]代碼段偽指令.code創(chuàng)建一個代碼段,它的參數(shù)指定該代碼段的段名如果沒有給出段名,則采用默認段名:在TINY、SMALL、COMPACT和FLAT模式下,默認的代碼段名是:_TEXT在MEDIUM、LARGE和HUGE模式下,默認的代碼段名是:模塊名_TEXT程序開始偽指令.STARTUP按照CPU類型、存儲模式、操作系統(tǒng)和堆棧類型,產(chǎn)生程序開始執(zhí)行的代碼;同時還指定程序開始執(zhí)行的起始點在DOS下,還將設(shè)置DS值,調(diào)整SS和SP值movdx,dgroupmovds,dx ;設(shè)置DSmovbx,sssubbx,dxshlbx,1shlbx,1shlbx,1shlbx,1cli ;關(guān)中斷movss,dx ;調(diào)整SS和SPaddsp,bxsti ;開中斷movdx,@datamovds,dx 程序終止偽指令.EXIT[返回參數(shù)]產(chǎn)生終止程序執(zhí)行返回操作系統(tǒng)的指令代碼它的可選參數(shù)是一個返回的數(shù)碼,通常用0表示沒有錯誤。例如.exit0對應(yīng)的代碼是:movax,4c00hint21hDOS功能調(diào)用的4ch子功能(返回DOS):入口參數(shù):AH=4ch,AL=返回數(shù)碼匯編結(jié)束偽指令END[標號]指示匯編程序MASM到此結(jié)束匯編過程源程序的最后必須有一條END語句可選的標號用于指定程序開始執(zhí)行點,連接程序?qū)?jù)此設(shè)置CS:IP值采用了.startup偽指令就不需要再用“end標號”指明開始執(zhí)行點,但還要有end偽指令

————不要糊涂————程序終止和匯編結(jié)束是兩碼事;主程序

moval,04h ;提供參數(shù)AL callhtoasc ;調(diào)用子程序retp1:movbl,0fh;retp1為返回地址 hlt;子程序:將AL低4位的一位16進制數(shù)轉(zhuǎn)換成ASCII碼htoasc: andal,0fh ;只取al的低4位 oral,30h ;al高4位變成3 cmpal,39h ;是0~9,還是0Ah~0Fh jchtend addal,7 ;是0Ah~0Fh,加上7htend: ret ;子程序返回ASCII碼’0’=30h…‘9’=39h’A’=41h‘B’=42h…ACII碼轉(zhuǎn)換子程序調(diào)用程序 .modelsmall

;定義程序的存儲模式

.code ;定義代碼段start: movax,@data;程序起始點,建立DS

movds,ax

moval,04h ;提供參數(shù)AL callhtoasc ;調(diào)用子程序retp1: movbl,0fh ;retp1為返回地址 hlt .exit0 ;程序正常執(zhí)行結(jié)束htoasc: ;子程序?qū)L低4位轉(zhuǎn)換成ASCII碼 andal,0fh ;只取al的低4位 oral,30h ;al高4位變成3 cmpal,39h ;是0~9,還是0Ah~0Fh jchtend addal,7 ;是0Ah~0Fh,加上7htend: ret ;子程序返回 endstart ;匯編結(jié)束簡化段定義格式--例1ACII碼轉(zhuǎn)換子程序調(diào)用程序無數(shù)據(jù)段主程序子程序編程實現(xiàn)將sum開始的8個無符號數(shù)的和放至bpt開始的兩個存儲單元中;數(shù)據(jù)段sum db8dup(2)bpt dw? ;存放最大值;代碼段

mov cx,8 mov si,offsetsum;存放無符號數(shù)的存儲單元首地址賦給si xor ax,ax ;ax及進位CF清零done: add al,[si] adc ah,0 inc si;指向下一個無符號數(shù)的存儲單元地址loopdone;cx-1≠0轉(zhuǎn)向done

mov bx,offsetbpt;cx-1=0(8個無符號數(shù)已求完和)bxbpt偏移地址mov[bx],ax;則將此和放至bpt存儲單元 hlt 循環(huán)程序結(jié)構(gòu)loop循環(huán)指令循環(huán)指令用于控制程序的重復(fù)執(zhí)行,根據(jù)CX(存放循環(huán)次數(shù))決定循環(huán)(轉(zhuǎn)移至目標地址label)還是順序執(zhí)行(下一條指令)循環(huán)指令

LOOP

label

CX-1≠0,則轉(zhuǎn)移(首先CX←CX-1;然后判斷若CX≠0,轉(zhuǎn)移到label;否則,順序執(zhí)行)LOOPZ/LOOPE

label

CX-1≠0且ZF=1,則轉(zhuǎn)移LOOPNZ/LOOPNElabel

CX-1≠0且ZF=0,則轉(zhuǎn)移

JCXZlabelCX=0,則轉(zhuǎn)移CMPCX,0JZlabeldececxjnzlabel簡化段定義格式--例2

編程實現(xiàn)將sum開始的8個無符號數(shù)的和放至bpt開始的兩個存儲單元中

.modelsmall .data ;定義數(shù)據(jù)段sum db8dup(2)bpt dw? ;存放最大值 .code ;定義代碼段start: movax,@data ;程序起始點,建立DS

movds,ax

mov cx,8 mov si,offsetsum;存放無符號數(shù)的存儲單元首地址賦給si xor ax,ax ;ax及進位CF清零done: add al,[si] adc ah,0 inc si ;指向下一個無符號數(shù)的存儲單元地址 Loopdone ;cx-1≠0轉(zhuǎn)向done

mov bx,offsetbpt

;cx-1=0(8個無符號數(shù)已求完和)bxbpt偏移地址mov[bx],ax ;則將此和放至bpt存儲單元hlt.exit0 ;程序正常執(zhí)行結(jié)束 endstart ;匯編結(jié)束

程序數(shù)據(jù)定義完整段定義偽指令段名 segment 定位組合段字'類別' ... ;語句序列段名 ends完整段定義由SEGMENT和ENDS這一對偽指令實現(xiàn),SEGMENT偽指令定義一個邏輯段的開始,ENDS偽指令表示一個段的結(jié)束段定義指令后的4個關(guān)鍵字用于確定段的各種屬性,堆棧段要采用stack組合類型,代碼段應(yīng)具有‘code’類別,其他為可選屬性參數(shù)如果不指定,則采用默認參數(shù);但如果指定,注意要按照上列次序2.完整段定義格式

完整段定義利用SEGMENT和ENDS一對偽指令定義邏輯段同時需要配合ASSUME偽指令指明邏輯段是代碼段、堆棧段、數(shù)據(jù)段還是附加段程序設(shè)計中常將具有一定功能的程序設(shè)計成一個過程。代碼段中可有若干個過程指定段寄存器偽指令A(yù)SSUME段寄存器:段名[,段寄存器名:段名,...]通知MASM用指定的段寄存器來尋址對應(yīng)的邏輯段,即建立段寄存器與段的缺省關(guān)系在明確了程序中各段與段寄存器之間的關(guān)系后,匯編程序會根據(jù)數(shù)據(jù)所在的邏輯段,在需要時自動插入段超越前綴。這是ASSUME偽指令的主要功能ASSUME偽指令并不為段寄存器設(shè)定初值,連接程序LINK將正確設(shè)置CS:IP和SS:SP由于數(shù)據(jù)段通常都需要,所以在樣板源程序中,首先為DS賦值;如果使用附加段,還要賦值ESstack segmentstack dw512dup(?)stack endsdata segment …… ;在數(shù)據(jù)段定義數(shù)據(jù)data endscode segment’code’ assumecs:code,ds:data,ss:stackstart: movax,data movds,ax …… ;主程序(指令待填) movax,4c00h int21h

…… ;子程序(指令待填)code ends endstart完整段定義格式

MASM5.x支持源程序格式(一般了解)例題例:完整的匯編語言源程序?qū)嵗簩?500H開始的10個字節(jié)無符號數(shù)的和放至050AH、050BH單元中

mov cx,10 mov si,0500h;存放無符號數(shù)的存儲單元首地址賦給si xor ax,ax ;ax及進位CY清零done: add al,[si] adc ah,0 inc si;指向下一個無符號數(shù)的存儲單元地址loopdone;cx-1≠0轉(zhuǎn)向done

mov bx,050ah;cx-1=0(10個無符號數(shù)已求完和),bx050ahmov[bx],ax;則將此和放至050AH、050BH存儲單元完整的匯編語言源程序還需有以下處理:段定義過程匯編結(jié)束end

加過程處理

mov cx,10 mov si,0500h;存放無符號數(shù)的存儲單元首地址賦給si xor ax,ax ;ax及進位CY清零done: add al,[si] adc ah,0 inc si;指向下一個無符號數(shù)的存儲單元地址loopdone;cx-1≠0轉(zhuǎn)向done

mov bx,050ahmov[050ah],ax;和放至050AH、050BH存儲單元start proc farpush ds mov ax,0 push ax

retstartendp將0500H開始的10個無符號數(shù)的和放至050AH、050BH單元中過程定義偽指令程序設(shè)計中常將具有一定功能的程序設(shè)計成一個過程。過程語句格式過程名procnear或far(過程屬性)…過程名endp為了使程序結(jié)束后能返回DOS系統(tǒng),需:

過程名 proc far push ds mov ax,0 push ax … ret

過程名endp這樣當該過程的程序運行完畢,便執(zhí)行DS:0000H處的返回到DOS管理狀態(tài)的指令push書51ret子程序返回指令RET(reture)RET ;無參數(shù)返回RETi16 ;有參數(shù)返回,除執(zhí)行RET指令外還SP←SP+i16(16位立即數(shù))RET指令放子程序末尾,執(zhí)行時將堆棧中的返回地址出棧送IP(段內(nèi)和段間調(diào)用)和CS(僅段間調(diào)用),使子程序執(zhí)行完畢能返回主程序彈出CALL指令壓入堆棧的返回地址段內(nèi)返回——出棧偏移地址IPIP←SS:[SP],SP←SP+2段間返回——出棧偏移地址IP和段地址CSIP←SS:[SP],SP←SP+2CS←SS:[SP],SP←SP+2start proc far push ds mov ax,0

push ax

mov cx,10 mov si,0500h;存放無符號數(shù)的存儲單元首地址賦給si xor ax,ax ;ax及進位CY清零done: add al,[si] adc ah,0 inc si;指向下一個無符號數(shù)的存儲單元地址loopdone;cx-1≠0轉(zhuǎn)向done mov bx,050ahmov[bx],ax;和放至050AH、050BH存儲單元 retstartendp

sseg segment db 256dup(0)sseg ends

cseg segment assumecs:cseg,ds:dseg,ss:sseg加段定義代碼段堆棧段cseg ends

end start ;匯編結(jié)束

段定義完整的匯編語言源程序分為代碼段、數(shù)據(jù)段(可選)、堆棧段、附加段(可選),分別裝入CS、DS、SS、ES段寄存器指定的物理段段定義語句格式

段名segment…段名ends偽指令A(yù)SSUME指明各段和段寄存器之間的關(guān)系例:dseg segment

sum db 0 dseg ends

sseg segmentparastack‘sseg’ db 256dup(0) sseg ends;堆棧段

cseg segment

assumecs:cseg,ds:dseg,ss:sseg…

cseg

ends代碼段:硬指令、偽指令其它段:偽指令(存儲單元的定義、分配等)代碼段數(shù)據(jù)段堆棧段程序開始為了指明程序開始執(zhí)行的位置,需要使用一個標號(例題中采用了start標識符)連接程序會根據(jù)程序起始點正確地設(shè)置CS和IP值,根據(jù)程序大小和堆棧段大小設(shè)置SS和SP值連接程序沒有設(shè)置DS和ES值。程序如果使用數(shù)據(jù)段或附加段,必須明確給DS或ES賦值匯編結(jié)束匯編結(jié)束表示匯編程序到此結(jié)束將源程序翻譯成目標模塊代碼的過程源程序的最后必須有一條END偽指令

END[標號]可選的“標號”參數(shù)指定程序開始執(zhí)行點,連接程序據(jù)此設(shè)置CS和IP值(例題中采用了start標識符)

————不要糊涂————程序終止和匯編結(jié)束是兩碼事例題2.4匯編語言程序設(shè)計

一.匯編語言程序設(shè)計概述匯編語言程序設(shè)計步驟從實際問題抽象出數(shù)學(xué)模型,確定數(shù)學(xué)模型算法(如乘法用移位指令還是乘法指令)畫出程序流程圖編程思路,程序結(jié)構(gòu)和相互之間關(guān)系方框:工作框例:菱形:判斷框編程、調(diào)試形成文件判斷程序質(zhì)量程序執(zhí)行時間程序所占內(nèi)存字節(jié)數(shù)程序語句條數(shù)程序可讀性

結(jié)束

初始化

循環(huán)體

控制條件YN二.匯編語言程序設(shè)計的基本方法DOS功能調(diào)用匯編語言程序結(jié)構(gòu)順序程序設(shè)計分支程序設(shè)計循環(huán)程序設(shè)計子程序設(shè)計1.DOS功能調(diào)用(書105頁)DOS操作系統(tǒng)含很多I/O子程序,這些子程序已編號,可由匯編語言源程序調(diào)用。系統(tǒng)功能調(diào)用是程序設(shè)計的一個重要方面兩種功能調(diào)用高級功能調(diào)用(DOS功能調(diào)用)低級功能調(diào)用對BIOS中的功能子程序的調(diào)用重點掌握DOS功能調(diào)用:顯示一個字符,02H號功能調(diào)用顯示一個字符串,09H號功能調(diào)用中斷中斷(Interrupt)是又一種改變程序執(zhí)行順序的方法,分為硬中斷外部設(shè)備中斷請求信號INTR、NMI軟中斷程序指令請求8088CPU支持256個軟中斷,每個中斷用一個編號(中斷向量號)區(qū)別INTn軟中斷調(diào)用指令,產(chǎn)生n號中斷n為8位立即數(shù),表示中斷向量號掌握類似子程序調(diào)用指令CALL的中斷調(diào)用指令I(lǐng)NT,進而掌握系統(tǒng)功能調(diào)用

例:int21h ;產(chǎn)生21H號中斷中斷向量號0~255高級DOS功能調(diào)用高級DOS功能調(diào)用步驟

⑴AH系統(tǒng)功能調(diào)用號(子程序號)

⑵指定寄存器中設(shè)置入口參數(shù)

⑶用中斷指令I(lǐng)NT21h執(zhí)行功能調(diào)用

⑷根據(jù)出口參數(shù)分析功能調(diào)用執(zhí)行情況01H號DOS功能調(diào)用鍵盤輸入接收從鍵盤輸入的一個字符并在顯示器上顯示該字符。⑴功能調(diào)用號:AH=01H⑵入口參數(shù):無⑶功能調(diào)用:INT21H⑷出口參數(shù):AL=輸入字符例:顯示鍵盤輸入的一個字符并送in-buff存儲單元;在數(shù)據(jù)段定義要顯示的字符in-buffdb ?

;

在代碼段編寫程序movah,01h ;設(shè)置功能調(diào)用號int21h ;功能調(diào)用movin-buff,al ;緩存鍵盤輸入字符02H號DOS功能調(diào)用顯示一個字符⑴功能調(diào)用號:AH=02H⑵入口參數(shù):DL=欲顯示字符的ASCII碼⑶功能調(diào)用:INT21H⑷出口參數(shù):無例:顯示data中的一個字符;在數(shù)據(jù)段定義要顯示的字符datadb ‘a(chǎn)’

;

在代碼段編寫程序movah,02h ;設(shè)置功能調(diào)用號movdl,’a’ ;設(shè)置入口參數(shù)int21h ;功能調(diào)用09H號DOS功能調(diào)用顯示一個字符串⑴功能調(diào)用號:AH=09H⑵入口參數(shù):DS:DX=欲顯示字符串在內(nèi)存中的首地址 (字符串以ASCII碼形式保存,以“$”結(jié)尾,$并不顯示)⑶功能調(diào)用:INT21H⑷出口參數(shù):無例:顯示字符串“Pressanykeytocontiune”;在數(shù)據(jù)段定義要顯示的字符串msgkeydb ‘Pressanykeytocontiune’,’$’;

在代碼段編寫程序mov ah,9;設(shè)置功能調(diào)用號

;設(shè)置入口參數(shù)DX=字符串的偏移地址mov dx,offsetmsgkeyint21h;功能調(diào)用2.順序程序設(shè)計沒有分支、循環(huán)等轉(zhuǎn)移指令的程序,會按指令書寫的前后順利依次執(zhí)行,這就是順序程序順序結(jié)構(gòu)是最基本的程序結(jié)構(gòu)完全采用順序結(jié)構(gòu)編寫的程序并不多見書100頁例題2.1順序程序設(shè)計實例3.分支程序設(shè)計分支程序根據(jù)條件是真或假決定執(zhí)行與否判斷的條件是各種指令如CMP、TEST等執(zhí)行后形成的狀態(tài)標志轉(zhuǎn)移指令Jcc和JMP可以實現(xiàn)分支控制條件成立跳轉(zhuǎn),否則順序執(zhí)行分支語句體注意選擇正確的條件轉(zhuǎn)移指令和轉(zhuǎn)移目標地址Jcc條件滿足?分支語句體YN書100頁例題2.2、例題2.3課后讀此程序條件轉(zhuǎn)移指令Jcc條件轉(zhuǎn)移指令Jcc根據(jù)指定的條件確定程序是否發(fā)生轉(zhuǎn)移。其通用格式為:

Jcc

label

;條件滿足,發(fā)生轉(zhuǎn)移 ;IP←IP+8位位移量; ;否則,順序執(zhí)行l(wèi)abel是一個標號、一個8位位移量,表示Jcc指令后的那條指令的偏移地址,到目標指令的偏移地址的地址位移label只支持短轉(zhuǎn)移的相對尋址方式例:計算AX中有符號數(shù)的絕對值

cmpax,0

jnlnonneg ;條件滿足(AX≥0),轉(zhuǎn)移

negax ;條件不滿足,求補nonneg:

movresult,ax ;條件滿足

;不恰當?shù)姆种?/p>

cmpax,0

jlyesneg ;條件滿足(AX<0),轉(zhuǎn)移 jmpnonnegyesneg:

negax ;條件不滿足,求補nonneg:

movresult,ax ;條件滿足有符號數(shù)AB轉(zhuǎn)移有符號數(shù)AB轉(zhuǎn)移例:顯示BX的最高位方法一:分支程序設(shè)計

movdl,‘0’;DL←30H=‘0’

shlbx,1 ;BX最高位移入CF標志

jnctwo ;CF=0,即最高位為0,轉(zhuǎn)移 movdl,‘1’;CF=1,即最高位為1:DL←31H=‘1’two: movah,2 int21h ;顯示編寫分支程序,需留心分支的開始和結(jié)束例:顯示BX的最高位方法二:順序程序設(shè)計(無分支) movdl,0 shlbx,1 ;BX最高位移入CF標志

adcdl,30h ;CF=0,DL←0+30h+0=30H=‘0’ ;CF=1,DL←0+30h+1=31H=‘1’two: movah,2 int21h ;顯示邏輯左移指令SHL(shiftlogicalleft)

算術(shù)左移指令SAL(shiftalgebraicleft)SHL/SALreg/mem,1/CL ;reg/mem左移1或CL位 ;最低位補0,最高位進入CF演示4.循環(huán)程序設(shè)計循環(huán)程序結(jié)構(gòu)是滿足一定條件的情況下,重復(fù)執(zhí)行某部分程序循環(huán)結(jié)構(gòu)的程序通常有3個部分:關(guān)鍵

結(jié)束

初始化

循環(huán)體

修改部分控制條件YN

循環(huán)初始部分

為開始循環(huán)準備必要的條件,如循環(huán)次數(shù)、循環(huán)體需要的數(shù)值等

循環(huán)體部分

重復(fù)執(zhí)行的程序部分,包括對循環(huán)條件等的修改程序段循環(huán)控制部分

判斷循環(huán)條件是否成立,決定是否繼續(xù)循環(huán)。循環(huán)條件為:(1)循環(huán)次數(shù)(計數(shù)控制循環(huán))(2)特定條件(條件控制循環(huán))循環(huán)程序設(shè)計例題例:將0500H開始的10個字節(jié)無符號數(shù)的和放至050AH、050BH單元中

mov cx,10 mov si,0500h;存放無符號數(shù)的存儲單元首地址賦給si xor ax,ax ;ax及進位CY清零done: add al,[si] adc ah,0 inc si;指向下一個無符號數(shù)的存儲單元地址loopdone;cx-1≠0轉(zhuǎn)向done

mov bx,050ah;cx-1=0(10個無符號數(shù)已求完和),bx050ahmov[bx],ax;則將此和放至050AH、050BH存儲單元初始化:循環(huán)次數(shù)=需累加的字節(jié)個數(shù)循環(huán)體:逐個累加循環(huán)控制:加完所有數(shù)據(jù)計數(shù)控制循環(huán)計數(shù)控制循環(huán)利用循環(huán)次數(shù)作為控制條件易于采用循環(huán)指令LOOP和JCXZ實現(xiàn)初始化:將循環(huán)次數(shù)或最大循環(huán)次數(shù)置入CX循環(huán)體循環(huán)控制:用LOOP指令對CX減1、并判斷是否為0書102頁例題2.4循環(huán)程序設(shè)計實例循環(huán)指令循環(huán)指令用于控制程序的重復(fù)執(zhí)行,根據(jù)CX(存放循環(huán)次數(shù))決定循環(huán)(轉(zhuǎn)移至目標地址)還是順序執(zhí)行(下一條指令)循環(huán)指令

LOOPlabel;CX-1≠0,則轉(zhuǎn)移(首先CX←CX-1;然后判斷若CX≠0,轉(zhuǎn)移)LOOPZ/LOOPElabel;CX-1≠0且ZF=1,則轉(zhuǎn)移LOOPNZ/LOOPNElabel;CX-1≠0且ZF=0,則轉(zhuǎn)移

JCXZlabel;CX=0,則轉(zhuǎn)移labell只支持短轉(zhuǎn)移(當前代碼段內(nèi)±127范圍)deccxjnzlabel例:用二進制顯示BX內(nèi)容

movcx,16

;CX←8(循環(huán)次數(shù))again: shlbx,1 ;左移進CF,從高位開始顯示 movdl,0 ;MOV指令不改變CF adcdl,30h ;DL←0+30H+CF ;CF若是0,則DL←'0' ;CF若是1,則DL←'1' movah,2 int21h ;顯示

loopagain ;CX減1,如果CX未減至0,則循環(huán)計數(shù)控制循環(huán)先循環(huán)后判斷顯示BX的最高位sum dw? xorax,ax ;被加數(shù)AX清0 movcx,100again: addax,cx ;從100,99,...,2,1倒序累加

loopagain movsum,ax ;將累加和送入指定單元例求和SUM=1+2+3+…+99+100

計數(shù)控制循環(huán)循環(huán)次數(shù)固定初始化:循環(huán)次數(shù)=需累加的字節(jié)個數(shù)循環(huán)體:逐個累加循環(huán)控制:加完所有數(shù)據(jù)?SUM=SUM-1-2-3?SUM=2+3+4計數(shù)控制循環(huán)例題:初始化返回第2章計數(shù)控制循環(huán)例題:求數(shù)組元素的最大值;數(shù)據(jù)段主體部分buffer db-1,0,2,3,8,9,10,88h,-3,45h;這是一個有符號字節(jié)元素組成的數(shù)組count equ$-buffer;符號“$”表示當前偏移地址值max db? ;存放最大值;代碼段主體部分

初始化:循環(huán)次數(shù)=元素個數(shù)-1循環(huán)體:逐個比較求最大循環(huán)控制:比較完所有數(shù)據(jù)

mov cx,count

;取得元素個數(shù)

dec cx

;減1后是循環(huán)次數(shù)

lea bx,buffer

mov al,[bx]

;取出第一個元素給AL,AL用于暫存最大值

inc bxagain: cmp al,[bx] ;與下一個數(shù)據(jù)比較 jnl next ;≥轉(zhuǎn)移 mov al,[bx] ;AL取得更大的數(shù)據(jù)next: inc bx

loop again

;計數(shù)循環(huán) mov max,al ;保存最大值

初始化循環(huán)體例題改進:求數(shù)組元素的最大值和最小值,數(shù)組元素的第一個數(shù)據(jù)表示元素個數(shù)

;數(shù)據(jù)段主體部分array dw10;假設(shè)一個數(shù)組,其中第一個數(shù)據(jù)10表示元素個數(shù) dw-3,0,20,900,587,-632,777,234,-34,-56;這是一個有符號字量元素組成的數(shù)組maxay dw? ;存放最大值minay dw? ;存放最小值初始化:循環(huán)次數(shù)=元素個數(shù)-1循環(huán)體:逐個比較求最大、小值循環(huán)控制:比較完所有數(shù)據(jù)例題改進代碼段

;代碼段主體部分 leasi,array movcx,[si] ;取得元素個數(shù) deccx ;減1后是循環(huán)次數(shù) addsi,2 movax,[si]

;取出第一個元素給AX,AX用于暫存最大值 movbx,ax ;取出第一個元素給BX,BX用于暫存最小值初始化例題改進代碼段(續(xù))maxck: addsi,2 cmp[si],ax ;與下一個數(shù)據(jù)比較 jleminck ;<= movax,[si] ;AX取得更大的數(shù)據(jù) jmpnextminck: cmp[si],bx jgenext ;>= movbx,[si] ;BX取得更小的數(shù)據(jù)next: loopmaxck

;計數(shù)循環(huán) movmaxay,ax ;保存最大值 movminay,bx ;保存最小值循環(huán)體條件控制循環(huán)條件控制循環(huán)需要利用特定條件(條件轉(zhuǎn)移指令)判斷循環(huán)是否結(jié)束轉(zhuǎn)移指令可以指定目的標號來改變程序的運行順序,如果目的標號指向一個重復(fù)執(zhí)行的語句體的開始或結(jié)束,便構(gòu)成了循環(huán)控制結(jié)構(gòu)顯示以0結(jié)尾的字符串--循環(huán)程序設(shè)計

;數(shù)據(jù)段主體部分string db'Letushaveatry!',0 ;代碼段主體部分 movbx,offsetstringagain: movdl,[bx] cmpdl,0

jzdone

;為0結(jié)束 movah,2 ;不為0,顯示 int21h incbx ;指向下一個字符

jmpagaindone: ……條件控制循環(huán)先判斷后循環(huán)另解:用09號功能調(diào)用---順序程序設(shè)計 ;數(shù)據(jù)段主體部分string db'Letushaveatry!',‘$’ ;代碼段主體部分 movah,9;設(shè)置功能調(diào)用號 movds,seg string;入口參數(shù)DS=數(shù)據(jù)段地址

movdx,offsetstring;DX=字符串的偏移地址 int21h;功能調(diào)用

統(tǒng)計并顯示某個字節(jié)存儲單元中1的個數(shù)

;數(shù)據(jù)段主體部分number db11101111B

;代碼段主體部分 movbl,number xordl,dl;循環(huán)初值:DL←0again: cmpbl,0 jzdone;全部是0就可以退出循環(huán),減少循環(huán)次數(shù) shlbl,1 ;用指令shrbl,1也可以 adcdl,0;利用ADC指令加CF的特點進行計數(shù)

jmpagaindone: adddl,‘0’ ;顯示個數(shù) movah,2 int21h條件控制循環(huán)先判斷后循環(huán)5.子程序設(shè)計把功能相對獨立的程序段單獨編寫,作為一個相對獨立的模塊供程序使用,就形成子程序子程序可以實現(xiàn)源程序的模塊化,可簡化源程序結(jié)構(gòu),可以提高編程效率主程序(調(diào)用程序)需要利用CALL指令調(diào)用子程序(被調(diào)用程序)子程序需要利用RET指令返回主程序例:顯示data中的一個字符用子程序設(shè)計;在數(shù)據(jù)段定義要顯示的字符datadb ‘a(chǎn)’

;

在代碼段編寫程序movdl,data ;設(shè)置入口參數(shù)movah,02h ;設(shè)置功能調(diào)用號int21h ;功能調(diào)用;主程序 movdl,data ;主程序提供顯示字符

calldpchar

;調(diào)用子程序

;子程序:顯示AL中的字符dpchar proc

;過程定義,過程名為dpchar

pushax

;保護寄存器 movah,02h ;02H號DOS功能調(diào)用顯示一個字符功能 int21h

popax;恢復(fù)寄存器

ret ;子程序返回dpchar endp

;過程結(jié)束dseg segmentdata db ‘a(chǎn)’

dseg endssseg segment parastack‘stack’ db 256dup(0)sseg endscseg segment assume cs:cseg,ss:sseg,ds:dsegmain proc far push ds mov ax,0

push ax mov ax,dseg mov ds,ax

mov dl,data ;主程序提供顯示字符

call dpchar

;調(diào)用子程序 retmain endpdpchar proc ;子程序:顯示AL中的字符

push ax ;順序入棧,保護寄存器

mov ah,02h ;設(shè)置功能調(diào)用號 int 21h

;功能調(diào)用 popax ;恢復(fù)寄存器 ret ;子程序返回dpchar endp

;過程結(jié)束cseg ends ;代碼段結(jié)束 end main ;匯編結(jié)束

源程序主程序子程序子程序安排在主程序執(zhí)行終止后的位置完整段定義格式子程序編寫注意事項子程序要利用過程定義偽指令聲明子程序最后利用RET指令返回主程序,主程序執(zhí)行CALL指令調(diào)用子程序子程序中對堆棧的壓入和彈出操作要成對使用,保持堆棧的平衡子程序開始應(yīng)該保護使用到的寄存器內(nèi)容,子程序返回前相應(yīng)進行恢復(fù)例 ;主程序 movdl,data

calldpchar

;子程序dpchar proc

pushax

movah,02h int21h

popax

ret

dpchar endp

子程序應(yīng)安排在代碼段的主程序之外,最好放在主程序執(zhí)行終止后的位置(返回DOS后、匯編結(jié)束END偽指令前),也可以放在主程序開始執(zhí)行之前的位置處理好子程序與主程序間的參數(shù)傳遞問題多出口子程序;子程序HTOASC:十六進制數(shù)轉(zhuǎn)換為ASCII碼16進制數(shù):0~9的ASCII碼30H~39H

A~F的ASCII碼41H~46HHTOASC proc andal,0fh cmpal,10 jchtoasc1 ;<10,轉(zhuǎn)htoasc1 addal,37h ;是A~F,加37H ret ;子程序返回htoasc1: add,30h ;是0~9,加30H

ret ;子程序返回HTOASC endp含數(shù)據(jù)區(qū)的子程序;子程序HTOASC:十六進制數(shù)轉(zhuǎn)換為ASCII碼16進制數(shù):0~9的ASCII碼30H~39H

A~F的ASCII碼41H~46H;數(shù)據(jù)區(qū)ASCII db30h,31h,32h,33h,34h,35h,36h,37h,38h,39h db41h,42h,43h,44h,45h,46hHTOASC proc movbx,offsetASCII andal,0fh

xlat

;換碼:AL←[BX+AL]

retHTOASC endpXLAT指令的功能參數(shù)傳遞主程序與子程序間一個主要問題是參數(shù)傳遞入口參數(shù)(輸入?yún)?shù)):主程序調(diào)用子程序時,提供給子程序的參數(shù)出口參數(shù)(輸出參數(shù)):子程序執(zhí)行結(jié)束返回給主程序的參數(shù)參數(shù)的具體內(nèi)容傳數(shù)值:傳送數(shù)據(jù)本身傳地址:傳送數(shù)據(jù)的主存地址dpcharHTOASCdpchar子程序的參數(shù)傳遞(例:顯示data中的一個字符)

;主程序 movdl,data ;主程序提供顯示字符

calldpchar

;調(diào)用子程序

溫馨提示

  • 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)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論