計算機《匯編語言》講稿_第1頁
計算機《匯編語言》講稿_第2頁
計算機《匯編語言》講稿_第3頁
計算機《匯編語言》講稿_第4頁
計算機《匯編語言》講稿_第5頁
已閱讀5頁,還剩99頁未讀 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

《匯編語言》課件

第5章[bx]和loop指令

■5.1[bx]

■5.2Loop指令

■5.3在Debug中跟蹤用loop指令實現(xiàn)的循環(huán)程序

■5.4Debug和匯編編譯器Masm對指令的不同處理

■5.5loop和[bx]的聯(lián)合應(yīng)用

-5.6段前綴

■5.7一段安全的空間

-5.8段前綴的使用

[bx]和內(nèi)存單元的描述

-[bx]是什么呢?

和[0]有些類似,[0]表示內(nèi)存單元,它

的偏移地址是0。

[bx]和內(nèi)存單元的描述

-我們要完整地描述一個內(nèi)存單元,需要兩

種信息:

■(1)內(nèi)存單元的地址;

■(2)內(nèi)存單元的長度(類型)。

■我們用[0]表示一個內(nèi)存單元時,0表示單

元的偏移地址,段地址默認在ds中,單元

的長度(類型)可以由具體指令中的其他

操作對象(比如說寄存器)指出。

[bx]和內(nèi)存單元的描述

■[bx]同樣也表示一個內(nèi)存單元,它的偏移

地址在bx中,比如下面的指令:

■movax,[bx]

■moval,[bx]

loop

■英文單詞“l(fā)oop”有循環(huán)的含義,顯

然這個指令和循環(huán)有關(guān)。

描述性符號"()

■為了描述上的簡潔,在以后的課程中,我們

將使用一個描述性的符號“()”來表示一個

寄存器或一個內(nèi)存單元中的內(nèi)容。

描述性符號"()

■我們看一下(X)的應(yīng)用,比如:

-(1)ax中的內(nèi)容為0010H,我們可以這樣來

描述:(ax)=0010H;

-(2)2000:1000處的內(nèi)容為0010H,我們可

以這樣來描述:(21000H)=0010H;

-(3)對于movax,[2]的功能,我們可以這樣

來描述:(ax)=((ds)*16+2);

-(4)對于mov[2],ax的功能,我們可以這樣

來描述:((ds)*16+2)=(ax);

描述性符號“()”

-(5)對于addax,2的功能,我們可以

這樣來描述:(ax)=(ax)+2;

-(6)對于addax,bx的功能,我們可以

這樣來描述:(ax)=(ax)+(bx);

-(7)對于pushax的功能,我們可以這

樣來描述:

(sp)=(sp)-2

((ss)*16+(sp))=(ax)

描述性符號"()

■(8)對于popax的功能,我們可以

這樣來描述:

(ax)=((ss)*16+(sp))

(sp)=(sp)+2

約定符號idata表示常量

■我們在Debug中寫過類似的指令:

movax,[0],表示將ds:O處的數(shù)據(jù)送

入ax中。指令中,在“[…了里用一個

常量0表示內(nèi)存單元的偏移地址。以后,

我們用idata表示常量。

■比如

約定符號idata表示常量

■比如:

■movax,[idata]B^^movax,[l]>mov

ax,[2]>movax,[3]等。

■movbx,idata就代表movbx,Lmovbx,2、

movbx,3等。

■movds,idata就代表movds,1、movds,2等,

它們都是非法指令。

5.1[bx]

-我們看一看下面指令的功能:

■movax,[bx]

功能:bx中存放的數(shù)據(jù)作為一個偏移地

址EA,段地址SA默認在ds中,將

SA:EA處的數(shù)據(jù)送入ax中。

即:(ax)=(ds*16+(bx));

5.1[bx]

■mov[bx],ax

功能:bx中存放的數(shù)據(jù)作為一個偏移地

址EA,段地址SA默認在ds中,將ax中

的數(shù)據(jù)送入內(nèi)存SA:EA處。

即:

(ds*16+(bx))=(ax)o

5.1[bx]

■問題5.1

程序和內(nèi)存中的情況如下圖所示,寫出程序

執(zhí)行后,21000H~21007H單元中的內(nèi)容。

BE21000H

oo"

■思考后看分析。21001H

21002H

21003H

21004H

21005H

21006H

21007H)制作提供

BE21000H

0021001H

5.1[bx]21002H

?21003H

問題5.1分析21004H

21OO5H

■(1)先看一下程序的前三

條指令:21006H

21007H

movax,2000H

movds,ax

movbx,lOOOH

這三條指令執(zhí)行后

ds=2000H,

bx=lOOOH;

BE21000H

0021001H

:.5,1[bx]21002H

21003H

弋問題5.1分析(續(xù))

21004H

21OO5H

?(2)再看第4條指令:

21006H

movax,[bx]21007H

指令執(zhí)行前:

ds=2000H,bx=lOOOH,則

movax,[bx]將把內(nèi)存2000:1000

處的字型數(shù)據(jù)送入ax中。

該指令執(zhí)行后:

ax=00beHo

BE21000H

0021001H

5.1[bx]21002H

21003H

問題5.1分析(續(xù))21004H

21OO5H

?(3)再看第5、6條指令:

21006H

incbx21007H

incbx

指令執(zhí)行前:

bx=1000Ho

執(zhí)行后:

bx=0002Ho

5.1[bx]

■問題5」分析(續(xù))

-(4)再看第7條指令:

mov[bx],ax

指令執(zhí)行前:

ds=2000H,bx=1002H,則

mov[bx],ax將把ax中的數(shù)據(jù)

送入內(nèi)存2000:1002處。

指令執(zhí)行后:

2000:1002單元的內(nèi)容為BE,

2000:1003單元的內(nèi)容為00。

21000H

21001H

5.1[bx]21002H

21003H

問題5.1分析(續(xù))21004H

21OO5H

■(5)再看第8、9條指令:21006H

incbx21007H

incbx

指令執(zhí)行前:

bx=1002Ho

執(zhí)行后:

bx=0004Ho

>5.1[bx]

問題5.1分析(續(xù))

?(6)再看第10條指令:

mov[bx],ax

指令執(zhí)行前:

ds=2000H,bx=1004H,則

mov[bx],ax將把ax中的數(shù)據(jù)

送入內(nèi)存2000:1004處。

指令執(zhí)行后:

2000:1004單元的內(nèi)容為BE,

2000:1005單元的內(nèi)容為00。

BE21000H

叵21001H

1.5,1[bx]BE21002H

叵21003H

-問題5.1分析(續(xù))BE21004H

0021OO5H

再看第條指令:

-(7)1121006H

incbx21007H

指令執(zhí)行前:

bx=1004Ho

執(zhí)行后:

bx=0005Ho

5.1[bx]

問題5.1分析(續(xù))

■(8)再看第12條指令:

mov[bx],al

指令執(zhí)行前:

ds=2000H,bx=1005H,則

mov[bx],ax將把al中的數(shù)據(jù)送

入內(nèi)存2000:1005處。

指令執(zhí)行后:

2000:1005單元的內(nèi)容為BE。

5.1[bx]

■問題5」分析(續(xù))

■(9)接下來是第13條指令:

incbx

指令執(zhí)行前:

bx=1005H,

指令執(zhí)行后:

bx=0006Ho

5.1[bx]

問題5.1分析(續(xù))

■(10)再看第12條指令:

mov[bx],al

指令執(zhí)行前:

ds=2000H,bx=1006H,則

mov[bx],ax將把al中的數(shù)據(jù)

送入內(nèi)存2000:1006處。

指令執(zhí)行后:

2000:1006單元的內(nèi)容為BE。

5.2Loop指令

■指令的格式是:loop標號,CPU執(zhí)行

loop指令的時候,要進行兩步操作:

■①(cx)=(cx)-l;

■②判斷CX中的值,不為零則轉(zhuǎn)至標號處

執(zhí)行程序,如果為零則向下執(zhí)行。

5.2Loop指令

■從上面的描述中,我們可以看到,CX

中的值影響著loop指令的執(zhí)行結(jié)果。

■通常(注意,我們說的是通常)我們

用loop指令來實現(xiàn)循環(huán)功能,CX中存

放循環(huán)次數(shù)。

5.2Loop指令

■這里我們講解loop指令的功能,關(guān)于loop

指令如何實現(xiàn)轉(zhuǎn)至標號處的細節(jié),將在后

面的課程中講解。下面我們通過一個程序

來看一下loop指令的具體應(yīng)用:

-任務(wù)1:編程計算2八2,結(jié)果存放在ax中。

任務(wù)1分析

-任務(wù)2:編程計算2八3。

任務(wù)2分析

-任務(wù)3:編程計算2八12o

任務(wù)3分析

5.2Loop指令

■任務(wù)1:編程計算2八2,結(jié)果存放在ax中。

分析:

設(shè)(ax)=2,可計算:(ax)=(ax)*2,最

后(ax)中為2八2的值。N*2可用N+N實現(xiàn)。

程序代碼

5.2Loop指令

■任務(wù)1:編程計算2八2,結(jié)果存放在ax中。

程序代碼:

assumecs:code

codesegment

movax,2

addax,ax

movax,4c00h

int21h

codeends

end

5.2Loop指令

■任務(wù)2:編程計算2八3。

分析:

2A3=2*2*2,若設(shè)3x)=2,可計算:

(ax)=(ax)*2*2,最后(ax)中為2八3的值。

N*2可用N+N實現(xiàn)。

程序代碼

5.2Loop指令

■任務(wù)2:編程計算2八3。

程序代碼:

assumecs:code

codesegment

movax,2

addax,ax

addax,ax

movax,4c00h

int21h

codeends

end

5.2Loop指令

任務(wù)3:編程計算2八12。

分析:

2A12=2*2*2*2*2*2*2*2*2*2*2*2,若

設(shè)(ax)=2,可計算:'

(ax)=(ax)*2*2*2*2*2*2*2*2*2*2*2,

最后(ax)中為2八12的值。N*2可用N+N

實現(xiàn)。

程序代碼

5.2Loop指令

■任務(wù)3:編程計算2八12。

程序代碼:

assumecs:code

codesegment

movax,2

;做11次addax,ax

movax,4c00h

int21h

codeends

end

按照我們的算法,計算2八12需要11條重復(fù)的指令

addax,ax。我們顯然不希望這樣來寫程序,這里,

可用loop來簡化我們的程序

5.2Loop指令

■任務(wù)3:編程計算2八12。

程序代碼:

assumecs:code

codesegment

movax,2

movex,11

s:addax,ax

loops

movax,4c00h

int21h

codeends

end

編程計算2A12。

程序代碼:

assumecs:code

5.2Loop指令codesegment

movax,2

movex,11

■程序分析:s:addax,ax

loops

(1)標號

在匯編語言中,標號代表一個地址,此程序

中有一個標號So它支際上標識了一個地址,movax,4coOh

這個地此處看一條指令:addax,ax。int21h

codeends

(2)loopsend

CPU執(zhí)行l(wèi)oops的時候,要進行兩步操作:

①(cx)=(cx)-l;

②判斷CX中的值,不為。則轉(zhuǎn)至標號S所標

識的地址處執(zhí)行(這里的指令是“addax,ax),

如果為零則執(zhí)行下一條指令(下一條指令是

movax,4c00h)o

編程計算2A12。

程序代碼:

assumecs:code

、5.2Loop指令codesegment

movax,2

movex,11

■程序分析(續(xù)):s:addax,ax

loops

(3)以下三條指令

movCX,11movax,4coOh

s:dddax,axint2ih

loopScodeends

執(zhí)行l(wèi)oops時,首先要將(2)減1,然后若(CX)end

東為0,則向前轉(zhuǎn)至s處執(zhí)行addax,ax。一痂以,

莪彳]可以利用ex來控制addax,ax而執(zhí)行次數(shù)。

■下面我們詳細分析一下這段程序的中行過程,

隊中稱會如彳可用ex和loops相配合莢現(xiàn)循環(huán)功

能。

5.2Loop指令

-程序的執(zhí)行過程:

movcxzl1

s:addax,ax

loops

(1)執(zhí)行movex,11,設(shè)置(cx)=ll;

(2)執(zhí)行addax,ax(第1次);

(3)執(zhí)行l(wèi)oops將(ex)減1,(cx)=10,(ex)不為0,所以轉(zhuǎn)至s處;

(4)執(zhí)行addax,ax(第2次);

(5)執(zhí)行l(wèi)oops將(ex)減1,(ex)=9,(ex)不為0,所以轉(zhuǎn)至s處;

5.2Loop指令

-程序的執(zhí)行過程:

movcxzl1

s:addax,ax

loops

(6)執(zhí)行addax,ax(第3次);

(7)執(zhí)行l(wèi)oops將(ex)減1,(cx)=8,(ex)不為0,所以轉(zhuǎn)至s處;

(8)執(zhí)行addax,ax(第4次);

(9)執(zhí)行l(wèi)oops將(ex)減1,(cx)=7,(ex)不為0,所以轉(zhuǎn)至s處;

5.2Loop指令

■程序的執(zhí)行過程:

movcx,ll

s:addax,ax

loops

(10)執(zhí)行addax,ax(第5次);

(11)執(zhí)行l(wèi)oops將(ex)減1,(ex)=6,(ex)不為0,所以轉(zhuǎn)至s處;

(12)執(zhí)行addax,ax(第6次);

(13)執(zhí)行l(wèi)oops將(ex)減1,(cx)=5,(ex)不為0,所以轉(zhuǎn)至s處;

5.2Loop指令

-程序的執(zhí)行過程:

movcx,ll

s:addax,ax

loops

(14)執(zhí)行addax,ax(第7次);

(15)執(zhí)行l(wèi)oops將(ex)減1,(cx)=4,(ex)不為0,所以轉(zhuǎn)至s處;

(16)執(zhí)行addax,ax(第8次);

(17)執(zhí)行l(wèi)oops將(ex)減1,(cx)=3,(ex)不為0,所以轉(zhuǎn)至s處;

5.2Loop指令

I

-程序的執(zhí)行過程:

movex,11

s:addax,ax

loops

(18)執(zhí)行addax,ax(第9次);

(19)執(zhí)行l(wèi)oops將(ex)減1,(cx)=2,(ex)不為0,所以轉(zhuǎn)至s處;

(20)執(zhí)行addax,ax(第10次);

(21)執(zhí)行l(wèi)oops將(ex)減1,(cx)=l,(ex)不為0,所以轉(zhuǎn)至s處;

5.2Loop指令

?程序的執(zhí)行過程:

movcxzll

s:addax,ax

loops

(22)執(zhí)行addax,ax(第11次);

(23)執(zhí)行l(wèi)oops將(ex)減1,(cx)=0,(ex)為2所以向下執(zhí)行。

(結(jié)束循環(huán))

5.2Loop指令

■從上面的過程中,我們可以總結(jié)出用

CX和loop指令相配合實現(xiàn)循環(huán)功能的

三個要點:

-(1)在CX中存放循環(huán)次數(shù);

■(2)loop指令中的標號所標識地址要

在前面;

■(3)要循環(huán)執(zhí)行的程序段,要寫在標號

和loop指令的中間。

5.2Loop指令

■用ex和loop指令相配合實現(xiàn)循環(huán)功能

的程序框架如下:

movex,循環(huán)次數(shù)

S:

循環(huán)執(zhí)行的程序段

loopS

5.2Loop指令

■問題5.2

■用加法計算123x236,結(jié)果存在ax中。

■思考后看分析。

■分析:

可用循環(huán)完成,將123加236次??上仍O(shè)

(ax)=0,然后循環(huán)做236次(ax)=(ax)+123。

-程序代碼

5.2Loop指令

■問題5.2程序代碼

assumecs:code

codesegment

movax,0

movcx,236

s:addax,123

loops

movax,4coOh

int21h

codeends

end

5.2Loop指令

■問題53

改進問題5.2程序,提高123x236的計算速

度。

■思考后看分析。

-分析:

問題5.2程序做了236次加法,我們可以將236力口123次。

可先設(shè)(ax)=0,然后循環(huán)做123次(ax)=(ax)+236,這樣

可以用123次加法實現(xiàn)相同的功能。

-程序代碼請自行實現(xiàn)。(參考代碼)

5.3在Debug中跟蹤用loop指令

u實現(xiàn)的循環(huán)程序

-JI---------------------------

■考慮這樣一個問題,計算ffff:0006單元中

的數(shù)乘以3,結(jié)果存儲在dx中。我們分析

一下:

-(1)運算后的結(jié)果是否會超出dx所能存儲

的范圍?

ffff:0006單元中的數(shù)是一個字節(jié)型的數(shù)據(jù),

范圍在0~255之間,則用它和3相乘結(jié)果不

會大于65535,可以在dx中存放下。

5.3在Debug中跟蹤用loop指令

實現(xiàn)的循環(huán)程序

■分析:

-(2)我們用循環(huán)累加來實現(xiàn)乘法,用哪個

寄存器進行軍力口?

友們將ffff:0006單元中的數(shù)賦值給ax,用dx

進行累加。先設(shè)(dx)=0,然后做3次

(dx)=(dx)+(ax)o

■(3)ffff:0006單元是一個字節(jié)單元,ax是

一個16位寄存器,數(shù)據(jù)長度不一樣,如何

賦值?

5.3在Debug中跟蹤用loop指令

實現(xiàn)的循環(huán)程序

■注意,

.我們說的是“賦值”,就是說,讓ax中的

數(shù)據(jù)的值(數(shù)據(jù)的大?。┖颓?0006單元

中的數(shù)據(jù)的值(數(shù)據(jù)的大?。┫嗟取?/p>

■8位數(shù)據(jù)01H和16位數(shù)據(jù)0001H的數(shù)據(jù)長度

不一樣,但它們的值是相等的。

5.3在Debug中跟蹤用loop指令

實現(xiàn)的循環(huán)程序

■那么我們?nèi)绾钨x值?

■設(shè)ffff:0006單元中的數(shù)據(jù)是XXH,若要ax中的值和

ffff:0006單元中的相等,ax中的數(shù)據(jù)應(yīng)為00XXH。

所以,若實現(xiàn)ffff:0006單元向ax賦值,我們應(yīng)該令

(ah)=0,(al)=(ffff6H)o

-實現(xiàn)計算ffff:0006單元中的數(shù)乘以3,結(jié)果存儲在dx

中的程序代碼。

5.3在Debug中跟蹤用loop指令

實現(xiàn)的循環(huán)程序

assumecs:code

codesegment■注意程序中的第一條指令

movax,OffffhmovaxOffffho

movds,axz

movbx,6■我們知道大于9FFFH的十六

moval,[bx]進制數(shù)據(jù)A000H、

movah,0AOOCH、……、C000H、

movdx,0C001H、……、FFFEH、

FFFFH等,在書寫的時候都

movex,3是以字母開頭的。

s:adddx,ax-而在匯編源程序中,數(shù)據(jù)不

loops能以字母開頭,所以要在前

面加0。

movax,4coOh

int21h

codeends

end

5.3在Debug中跟蹤用loop指令

實現(xiàn)的循環(huán)程序

■下面我們對程序的執(zhí)行過程進行跟蹤。

■首先,我們將它編輯為源程序文件,

文件名定為p3.asm;對其進行編譯

連接后生成p3.exe;然后再用Debug

對p3.exe中的程序進行跟蹤。

■源程序u3.asm

5.3在Debug中跟蹤用loop指令

實現(xiàn)的循環(huán)程序

■上面,我們通過對一個循環(huán)程序的跟

蹤,更深入一步地講解了loop指令實

現(xiàn)循環(huán)的原理。

■下面,我們將前面的程序改一下,計

算ffff:0006單元中的數(shù)乘以123,結(jié)

果存儲在dx中。

■更改程序:只要將尋循環(huán)次數(shù)改為

123o

5.3在Debug中跟蹤用loop指令

實現(xiàn)的循環(huán)程序

■程序源碼Debug加載跟蹤

C:\masm>debugp4.exe

pi*

AX=0000BX=0000CX=001BDX=0000SP=0000BP=0000S1=0000DI=0000

DS=0B2DES=0B2DSS=0B3DCS=0B3D1P=0000NUUPEIPLNZNAPONC

0B3D:0000B8FFFFMOUAX,FFFF

r-u0b3d:0

0B3D:0000B8FFFFMOUfiX,FFFF

0B3D:00038ED8MOUDS,AX

0B3D:0005BB0600MOUBX,0006

0B3D:00088A07MOUAL,[BX]

0B3D:000AB400MOUAH,00

0B3D:000CBA0000MOUDX,0000

0B3D:000FB97B00MOUCX,007B

0B3D:001203D0ADDDX,AX

0B3D:0014E2FCLOOP0012

0B3D:0016B8004CMOUAX.4c00

0B3D:0019CD21INT21

0B3D:001BE83E0DCALL0D5C

0B3D:001E83C404ADDSP,+04

5.3在Debug中跟蹤用loop指令

,實現(xiàn)的循環(huán)程序

■JI--------------------------

■Debug執(zhí)行“g0012”后,CS:0012前的

程序段被執(zhí)行,從各個相關(guān)的寄存器中

的值,我們可以看出執(zhí)行的結(jié)果:

—g0012

AX=0034BX=0006CX=007BDX=0000SP=0000BP=0000SI=0000DI=0000

DS=FFFFES=0B2DSS=0B3DCS=0B3DIP=0012NUUPEIPLNZNAPONC

0B3D:001203D0ADDDX.AX

5.3在Debug中跟蹤用loop指令

實現(xiàn)的循環(huán)程序

■我們跟蹤了兩次循環(huán)的過程,可以確定循

環(huán)程序段在邏輯上是正確的。

■我們不想再繼續(xù)一步一步的觀察循環(huán)的過

程了,因為還要進行121((cx)=79h)次

循環(huán),我們希望將循環(huán)一次執(zhí)行完,顯然

T命令不可行,我們可以使用P命令來達到

目的。

■再次遇到loop指令時,使用P命令來執(zhí)行。

Debug就會自動重復(fù)執(zhí)行循環(huán)中的指令,

直到(cx)=0為止。

5.4Debug和匯編編譯器Masm

對指令的不同處理

■本節(jié)只試點為下面刻成的順利進行提供一

點預(yù)備知識。

■我們在Debug中寫過類似的指令:

movax,[0]

表示將ds:O處的數(shù)據(jù)送入al中。

■但是在匯編元程序中,指令“movax,⑼”

被編譯器當作指令"movax,0”處理。

■示例

5.4Debug和匯編編譯器Masm

對指令的不同處理

■示例任務(wù):將內(nèi)存2000:0、2000:1>

2000:2、2000:3單元中的數(shù)據(jù)送入al,bl,

cl,dl中。

■(1)在Debug中編程實現(xiàn)

■(2)匯編程序?qū)崿F(xiàn)

■兩種實現(xiàn)的實際實施情況

5.4Debug和匯編編譯器Masm

對指令的不同處理

■在Debug中編程實現(xiàn):

movax,2000h

movds,ax

moval,[0]

movbl,[l]

movcl,[2]

movdl,[3]

5.4Debug和匯編編譯器Masm

對指令的不同處理

■匯編程序?qū)崿F(xiàn):

assumecs:code

codesegment

movax,2000h

movds,ax

moval,[0]

movbl,[l]

movclz[2]

movdl,[3]

movax,4coOh

int21h

codeends

end

5.4Debug和匯編編譯器Masm

對指令的不同處理

■Debug中的情況:

:Xnasn>debug

-a

0AE8:0100ROUaxv2000

0AE8:0103nouds’ax

0AE8:0105noual?[0]

0AE8:0108noublv[1]

0AE8:010Cnoucl,[2]

0AE8:0110moudl,[3]

0AE8:0114

-u

0AE8:0100B80020MOUAX.2000

0AE8:01038ED8MOUDS.AX

0AE8:0105A00000MOUAL,[0000]

0AE8:01088A1E0100MOUBL,[00011

0AE8:010C8A0E0200MOUCL,(00023

0AE8:01108Al60300MOUDL.[0003]

5.4Debug和匯編編譯器Masm

對指令的不同處理

將匯編源程序存儲為compare.asm

用masm、link生成compare.exe,用

debug力口載compare.exe,如圖:

C:\nasn>debugconpare.exe

-r

AX=0000BX=0000CX=0012DX=0000SP=0000BP=0000SI=0000DI=0000

DS=0B2D]ES=0B2DSS=0B3DCS=0B3DIP=0000NUUPEIPLNZNAPONC

0B3D:0000B80020MOUAX,2000

-u0b3d:0000

0B3D:0000B80020MOUAX.2000

0B3D:00038ED8MOUDS,AX

0B3D:0005B000MOUAL,00

0B3D:000?B301MOUBL,01

0B3D:0009Bl02MOUCL,02

0B3D:000BB203MOUDL,03

0B3D:000DB8004cMOUAX,4c00

0B3D:0010CD21INT21

5.4Debug和匯編編譯器Masm

對指令的不同處理

■比如我們可以這樣訪問2000:0單元:

movax,2000h

movds,ax

moval,ds:[O]

5.5loop和[bx]的聯(lián)合應(yīng)用

■考慮這樣一個問題:

計算單元中的數(shù)據(jù)的和,

結(jié)果存儲在dx中。

■我們還是先分析一下

5.5loop和[bx]的聯(lián)合應(yīng)用

■計算單元中的數(shù)據(jù)的和,結(jié)

果存儲在dx中。

■分析:

(1)運算后的結(jié)果是否會超出dx所能

存儲的范圍?

?內(nèi)存單元中的數(shù)據(jù)是字節(jié)型

數(shù)據(jù),范圍在。?255之間,12個這樣的

數(shù)據(jù)相加,結(jié)果不會大于65535,可以

在dx中存放下。

5.5loop和[bx]的聯(lián)合應(yīng)用

■計算單元中的數(shù)據(jù)的和,結(jié)

果存儲在dx中。

■分析:

(2)我們是否將而:0?中的數(shù)據(jù)

直接累加到dx中?

當然不行,因為仟仟:0?中的數(shù)據(jù)是

8位的,不能直接加到16位寄存器dx中。

5.5loop和[bx]的聯(lián)合應(yīng)用

■計算單元中的數(shù)據(jù)的和,結(jié)

果存儲在dx中。

■分析:

(3)我們能否將而:0?中的數(shù)據(jù)

累加到dl中,并設(shè)置(dh=O,從而實現(xiàn)

累加到dx中的目標?

這也不行,因為dl是8位寄存器,能容納

的數(shù)據(jù)的范圍在小255之間,ffff:。?

中的數(shù)據(jù)也都是8位,如果僅向dl

中累加12個8位數(shù)據(jù),很有可能造成進

位丟失。

5.5loop和[bx]的聯(lián)合應(yīng)用

■計算而單元中的數(shù)據(jù)的和,

結(jié)果存儲在dx中。

-分析:

(4)我們到底怎樣將用?

中的8位數(shù)據(jù),累加到16位寄存器dx

中?

5.5loop和[bx]的聯(lián)合應(yīng)用

■從上面的分析中,我們可以看到,這里面有

兩個問題:類型的匹配和結(jié)果的不超界。

■具體的說,就是在做加法的時候,我們有兩

種方法:

(dx)=(dx)+內(nèi)存中的8位數(shù)據(jù):

(dl)=(dl)+內(nèi)存中的8位數(shù)據(jù);

第一種方法中的問題是兩個運算對象的類型

不匹配,第二種方法中的問題是結(jié)果有可能

起界。

5.5loop和[bx]的聯(lián)合應(yīng)用

■計算單元中的數(shù)據(jù)的和,

結(jié)果存儲在dx中。

-分析:

怎樣解決這兩個看似矛盾的問題?

目前的方法(在后面的課程中我們還

有別的方法)就是我們得用一個16位

寄存器來做中介。

5.5loop和[bx]的聯(lián)合應(yīng)用

■我們將內(nèi)存單元中的8位數(shù)據(jù)賦值到

一個16位寄存器ax中,再將ax中的數(shù)

據(jù)加到dx上,從而使兩個運算對象的

類型匹配并且結(jié)果不會超界。

想清楚以上的問題之后,我們編寫程

序代碼。

5.5loop和[bx]的聯(lián)合應(yīng)用

■問題5.4

應(yīng)用loop指令,改進程序5.5,使它

的指令行數(shù)讓人能夠接受。

思考后看分析。

5.5loop和[bx]的聯(lián)合應(yīng)用

■分析:

可以看出,在程序中,有12個相似的程序

段,我們將它們一般化地描述為:

moval,ds:[x]

movah,0

adddx,ax

我們可以看到,12個相似的程序段中,只

有moval,ds:jx]指令中的內(nèi)薦單兀的偏移

地址是不同的,其他都一樣。

5.5loop和[bx]的聯(lián)合應(yīng)用

■分析:(續(xù))

而這些不同的偏移地址是可在OWXWObH

的范圍內(nèi)遞增變化的。

我們可以用數(shù)學(xué)語言來描述這個累加的運

Obh

sum=Z(Offffhx10h+x)

x=0

5.5loop和[bx]的聯(lián)合應(yīng)用

■分析:(續(xù))

從程序?qū)崿F(xiàn)上,我們將循環(huán)做:

(al)=((ds)*16+X)

(ah)=0

(dx)=(dx)+(ax)

一共循環(huán)12次,在循環(huán)開始前(dx)=Offffh,

X=0,ds:X指向第一個內(nèi)存單元。每次循環(huán)

后,X遞增,ds:X指向下一個內(nèi)存單元。

5.5loop和[bx]的聯(lián)合應(yīng)用

■分析:(續(xù))完整的算法描述

初始化:

(ds)=Offffh

X=0

(dx)=0

循環(huán)12次:

(al)=((ds)*16+X)

(ah)=0

(dx)=(dx)+(ax)

X=X+1

5.5loop和[bx]的聯(lián)合應(yīng)用

■分析:(續(xù))

可見,表示內(nèi)存單元偏移地址的X應(yīng)

該是一個變量,因為在循環(huán)的過程中,

偏移地址必須能夠遞增。

這樣,在指令中,我們就不能用常量

來表示偏移地址。我們可以將偏移地

址放到bx中,用[bx]的方式訪問內(nèi)存

單元。

5.5loop和[bx]的聯(lián)合應(yīng)用

■分析:(續(xù))

在循環(huán)開始前設(shè)(bx)=0,每次循環(huán),將

bx中的內(nèi)容加1即可。

最后一個問題是,如何實現(xiàn)循環(huán)12次?

我們的loop指令該發(fā)揮作用了。

更詳細的算法描述。

5.5loop和[bx]的聯(lián)合應(yīng)用

■分析:(續(xù))更詳細的算法描述初

始化

(ds)=Offffh

(bx)=0

(dx)=0

(ex)=12

循環(huán)12次:

s:(al)=((ds)*16+(bx))

(ah)=0

(dx)=(dx)+(ax)

(bx)=(bx)+l

loops

■寫出程序

5.5loop和[bx]的聯(lián)合應(yīng)用

■在實際編程中,經(jīng)常會遇到,用同一

種方法處理地址連續(xù)的內(nèi)存單元中的

數(shù)據(jù)的問題。

■我們需要用循環(huán)來解決這類問題,同

時我們必須能夠在每次循環(huán)的時候按

即同一種方法來改變要訪問的內(nèi)存單

元的地址。

5.5loop和[bx]的聯(lián)合應(yīng)用

■這時,我們就不能用常量來給出內(nèi)存單

元的地址(比如[0]、[1]、[2]中,0、1、

2是常量),而應(yīng)用變量。

■“moval,[bx『中的bx就可以看作一個代

表內(nèi)存單元地址的變量,我們可以不寫

新的指令,僅通過改變bx中的數(shù)值,改

變指令訪問的內(nèi)存單元。

5.6段前綴

■指令"movax,[bx『中,內(nèi)存單元的偏

移地址由bx給出,而段地址默認在ds

中。

■我們可以在訪問內(nèi)存單元的指令中顯

式地給出內(nèi)存單元的段地址所在的段

寄存器。

5,6段前綴

■這些出現(xiàn)在訪問內(nèi)存單元的指令中,

用于顯式地指明內(nèi)存單元的段地址的

“ds:"、“cs:"、"ss:”或“es:",在

匯編語言中稱為段前綴。

5.7一段安全的空間

■在8086模式中,隨意向一段內(nèi)存空間

寫入內(nèi)容是很危險的,因為這段空間

中可能存放著重要的系統(tǒng)數(shù)據(jù)或代碼。

-比如下面的指令:

movax,1000h

movds,ax

moval,0

movds:[O],al

5.7一段安全的空間

■我們以前在Debug中,為了講解上的方便,

寫過類似的指令。

■但這種做法是不合理的,因為之前我們并

沒有論證過1000:0中是否存放著重要的系

統(tǒng)數(shù)據(jù)或代碼。

■如果1000:0中石放著重要的系統(tǒng)數(shù)據(jù)或代碼,

“movds:[0],al”將其改寫,將引發(fā)錯誤。

■比如程序

5.7一段安全的空間

AX=0000BX=00116位IS-DOS子系統(tǒng)兇DI=0000

DS=0B2DES=0B:PONC

0B3D:0000B800I命令提示符-debugp7.exe

HTVBMCPU遇到無效的指令“

CS:OOOOIP0460OPOfOc00d403選擇“關(guān)閉”終止應(yīng)用程序.

AX=0000BX=001DI=0000

二:去阻二:斗忽略①

DS=0B2DES=0B:?PONC

0B3D:00038ED8

rt

AX=0000BX=0080CX=000DDX=0000SP=0000BP=0000SI=0000DI=0000

DS=0000ES=0B2DSS=0B3DCS=0B3DIP=0005NUUPEIPLNZNAPONC

0B3D:0005A32600MOU[0026LAXDS:0026=0214

-t

■上圖是在Windows2000的DOS方式中,在Debug里執(zhí)

行“mov[0026],ax”的結(jié)果。如果在實模式(即純

DOS方式)下執(zhí)行程序p7.exe,將會引起死機。

產(chǎn)生這種結(jié)果的原因是0:0026處存放著重要的系統(tǒng)數(shù)

據(jù),而

溫馨提示

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

評論

0/150

提交評論