匯編語言-第二版-王爽-完整答案_第1頁
匯編語言-第二版-王爽-完整答案_第2頁
匯編語言-第二版-王爽-完整答案_第3頁
匯編語言-第二版-王爽-完整答案_第4頁
匯編語言-第二版-王爽-完整答案_第5頁
已閱讀5頁,還剩91頁未讀 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

./第1章基礎知識檢測點1.1

<1>1個CPU的尋址能力為8KB,那么它的地址總線的寬度為13.

<2>1KB的存儲器有1024個存儲單元.存儲單元的編號從0到1023.

<3>1KB的存儲器可以存儲1024*8個bit,1024個Byte.

<4>1GB、1MB、1KB分別是2^30、2^20、2^10Byte.<n^m的意思是n的m次冪>

<5>8080、8088、80286、80386的地址總線寬度分別是16根、20根、24根、32根,則它們的尋址能力分別為:64<KB>、1<MB>、16<MB>、4<GB>.

<6>8080、8088、8086、80286、80386的數(shù)據(jù)總線寬度分別為8根、8根、16根、16根、32根.則它們一次可以傳送的數(shù)據(jù)為:1<B>、1<B>、2<B>、2<B>、4<B>.

<7>從內存中讀取1024字節(jié)的數(shù)據(jù),8086至少要讀512次、80386至少要讀256次.

<8>在存儲器中,數(shù)據(jù)和程序以二進制形式存放.第2章寄存器答案檢測點2.1

<1>寫出每條匯編指令執(zhí)行后相關寄存器中的值.

movax,62627AX=F4A3H

movah,31HAX=31A3H

moval,23HAX=3123H

addax,axAX=6246H

movbx,826CHBX=826CH

movcx,axCX=6246H

movax,bxAX=826CH

addax,bxAX=04D8H

moval,bhAX=0482H

movah,blAX=6C82H

addah,ahAX=D882H

addal,6AX=D888H

addal,alAX=D810H

movax,cxAX=6246H<2>只能使用目前學過的匯編指令,最多使用4條指令,編程計算2的4次方.解:

movax,2

addax,ax

addax,ax

addax,ax檢測點2.2

<1>給定段地址為0001H,僅通過變化偏移地址尋址,CPU的尋址范圍為00010H到1000FH.

<2>有一數(shù)據(jù)存放在內存20000H單元中,先給定段地址為SA,若想用偏移地址尋到此單元.則SA應滿足的條件是:最小為1001H,最大為2000H.

檢測點2.3

下面的3條指令執(zhí)行后,CPU幾次修改IP?都是在什么時候?最后IP中的值是多少?

movax,bx

subax,ax

jmpax解:

修改4次;第一次在CPU讀取"movax,bx"后,第二次在CPU讀取"subax,ax"后,第三次在CPU讀取"jmpax"后,第四次在CPU執(zhí)行完"movax,bx"后;最后IP中的值為0.實驗1查看CPU和內存,用機器指令和匯編指令編程

1.略

2.

<1>略

<2>略

<3>查看內存中的內容.

PC機主板上的ROM中寫有一個生產日期,在內存FFF00H~FFFFFH的某幾個單元中,請找出這個生產日期并試圖改變它.解:內存FFF00H~FFFFFH為ROM區(qū),內容可讀但不可寫.<4>向內存從B8100H開始的單元中填寫數(shù)據(jù),如:

-eB810:00000101020203030404

請讀者先填寫不同的數(shù)據(jù),觀察產生的現(xiàn)象;在改變填寫的地址,觀察產生的現(xiàn)象.解:8086的顯存地址空間是A0000H~BFFFFH,其中B8000H~BFFFFH為80*25彩色字符模式顯示緩沖區(qū),當向這個地址空間寫入數(shù)據(jù)時,這些數(shù)據(jù)會立即出現(xiàn)在顯示器上.第3章寄存器〔內存訪問檢測點3.1

<1>在Debug中,用"d0:01f"查看內存,結果如下.

0000:00007080F030EF6030E2-0080801266202260

0000:00106226E6D6CC2E3C3B-ABBA000026066688

下面的程序執(zhí)行前,AX=0,BX=0,寫出每條匯編指令執(zhí)行完后相關寄存器的值.movax,1

movds,ax

movax,[0000]AX=2662H

movbx,[0001]BX=E626H

movax,bxAX=E626H

movax,[0000]AX=2662H

movbx,[0002]BX=D6E6H

addax,bxAX=FD48H

addax,[0004]AX=2C14H

movax,0AX=0000H

moval,[0002]AX=00E6H

movbx,0BX=0000H

movbl,[000C]BX=0026H

addal,blAX=000CH

<2>內存中的情況如圖3.6所示各寄存器的初始值:CS=2000H,IP=0,DS=1000H,AX=0,BX=0;①寫出CPU執(zhí)行的指令序列<用匯編指令寫出>.

②寫出CPU執(zhí)行每條指令后,CS、IP和相關寄存器中的數(shù)值.

③再次體會:數(shù)據(jù)和程序有區(qū)別嗎?如何確定內存中的信息哪些是數(shù)據(jù),哪些是程序?解:初始值:CS=2000H,IP=0,DS=1000H,AX=0,BX=0

①②

movax,6622HAX=6622H其他寄存器保持不變,以下同理

jmp0ff0:0100CS=0ff0H,IP=0100H

movax,2000HAX=2000H

movds,axDS=20000H

movax,[0008]AX=C389H

movax,[0002]AX=EA66H③沒有區(qū)別,被CS:IP指向的信息是程序;被傳送、運算等指令操作的是數(shù)據(jù).檢測點3.2

<1>補全下面的程序,使其可以將10000H~1000FH中的8個字,逆序復制到200000H~2000FH中.逆序復制的含義如圖3.17所示<圖中內存里的數(shù)據(jù)均為假設>.movax,1000H

movds,ax

movax,2000H

movss,ax

movsp,10H

push[0]

push[2]

push[4]

push[6]

push[8]

push[A]

push[C]

push[E]<2>補全下面的程序,使其可以將100000H~1000FH中的8個字,逆序復制到200000H~2000FH中.movax,2000H

movds,ax

movax,1000H

movss,ax

movsp,0

pop[E]

pop[C]

pop[A]

pop[8]

pop[6]

pop[4]

pop[2]

pop[0]

實驗2用機器指令和匯編指令編程

1.預備知識:Debug的使用

2.實驗任務

<1>使用Debug,將上面的程序段寫入內存,逐條執(zhí)行,根據(jù)指令執(zhí)行后的實際運行情況填空.movax,ffff

movds,axmovax,2200

movss,axmovsp,0100movax,[0];ax=58EA

addax,[2];ax=5CCA

movbx,[4];bx=30F0

addbx,[6];bx=6021pushax;sp=00FE;修改的內存單元的地址是220FE,內容為5CCA

pushbx;sp=00FC;修改的內存單元的地址是220FC,內容為6021

popax;sp=00FE;ax=6021

popbx;sp=0100;bx=5CCApush[4];sp=00FE;修改的內存單元的地址是220FE,內容為30F0

push[6];sp=00FC;修改的內存單元的地址是220FC,內容為2F31注:內存中的數(shù)據(jù)會因機器、環(huán)境而異<2>仔細觀察圖3.19中的實驗過程,然后分析:為什么2000:0~2000:f中的內容會發(fā)生改變?解:t命令為單步中斷,CPU會保護現(xiàn)場,即順序把標志寄存器、CS、IP入棧,此題是關于后面章節(jié)的中斷問題.第4章第一個程序實驗3編程、編譯、連接、跟蹤<1>將下面的程序保存為t1.asm,將其生成可執(zhí)行文件ti.exe.assumecs:codesgcodesgsegmentmovax,2000h

movss,ax

movsp,0

addsp,10

popax

popbx

pushax

pushbx

popax

popbxmovax,4c00h

int21hcodesgendsend

解:略

<2>用Debug跟蹤t1.exe的執(zhí)行過程,寫出每一步執(zhí)行后,相關寄存器中的內容和棧頂?shù)膬热?解:

<3>PSP的頭兩個字節(jié)是CD20,用Debug加載ti.exe,查看PSP的內容.解:第5章[BX]和loop指令實驗4[bx]和loop的使用

<1>編程,向內存0:200~0:23F依次傳送數(shù)據(jù)0~63<3FH>.解:

assumecs:codesgcodesgsegmentmovax,0

movds,ax

movbx,200H

moval,0movcx,64

s:mov[bx],al

incbx

incal

loopsmovax,4c00h

int21hcodesgendsend<2>編程,向內存0:200~0:23F依次傳送數(shù)據(jù)0~63<3FH>,程序中只能使用9條指令,9條指令中包括"movax,4c00h"和"int21h".解:

assumecs:codesgcodesgsegmentmovax,20h

movds,ax

movbx,0movcx,64

s:mov[bx],bl

incbx

loopsmovax,4c00h

int21hcodesgendsend<3>下面的程序的功能是將"movax,4c00h"之前的指令復制到內存0:200處,補全程序.上機調試,跟蹤運行結果.assumecs:codecodesegmentmovax,cs

movds,ax

movax,0020h

moves,ax

movbx,0

movcx,17hs:moval,[bx]

moves:[bx],al

incbx

loops

movax,4c00h

int21hcodeendsend第6章包含多個段的程序檢測點6.1

<1>下面的程序實現(xiàn)依次用內存0:0~0:15單元中的內容改寫程序中的數(shù)據(jù),完成程序:

assumecs:codesgcodesgsegmentdw0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987hstart:movax,0movds,axmovbx,0movcx,8s:movax,[bx]movcs:[bx],axaddbx,2loopsmovax,4c00hint21hcodesgendsendstart

<2>下面的程序實現(xiàn)依次用內存0:0~0:15單元中的內容改寫程序中的數(shù)據(jù),數(shù)據(jù)的傳送用棧來進行.??臻g設置在程序內.完成程序:assumecs:codesgcodesgsegmentdw0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987hdw0,0,0,0,0,0,0,0,0,0;10個字單元用??臻gstart:movax,csmovss,axmovsp,36movax,0movds,axmovbx,0movcx,8s:push[bx]popcs:[bx]addbx,2loopsmovax,4c00hint21hcodesgendsendstart實驗5編寫、調試具有多個段的程序<1>將下面的程序編譯連接,用Debug加載、跟蹤,然后回答問題

assumecs:code,ds:data,ss:stackdatasegment

dw0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h

dataendsstacksegment

dw0,0,0,0,0,0,0,0

stackendscodesegment

start:movax,stack

movss,ax

movsp,16movax,data

movds,axpushds:[0]

pushds:[2]

popds:[2]

popds:[0]movax,4c00h

int21h

codeends

endstart①CPU執(zhí)行程序,程序返回前,data段中的數(shù)據(jù)為多少?解:不變②CPU執(zhí)行程序,程序返回前,cs=155ch、ss=155bh、ds=155ah.<此題結果因環(huán)境而異,但相對差值不變>③設程序加載后,code段的段地址為X,則data段的段地址為X-2,stack段的段地址為X-1.

<2>將下面的程序編譯連接,用Debug加載、跟蹤,然后回答問題

assumecs:code,ds:data,ss:stackdatasegment

dw0123H,0456H

dataendsstacksegment

dw0,0

stackendscodesegment

start:movax,stack

movss,ax

movsp,16movax,data

movds,axpushds:[0]

pushds:[2]

popds:[2]

popds:[0]movax,4c00h

int21h

codeends

endstart①CPU執(zhí)行程序,程序返回前,data段中的數(shù)據(jù)為多少?解:不變②CPU執(zhí)行程序,程序返回前,cs=155ch、ss=155bh、ds=155ah.<此題結果因環(huán)境而異,但相對差值不變>③設程序加載后,code段的段地址為X,則data段的段地址為X-2,stack段的段地址為X-1.④對于如下定義的段:namesegment

nameends如果段中的數(shù)據(jù)占N個字節(jié),則程序加載后,這段實際占有的空間為<N/16+1>*16.<N/16為取整數(shù)部分><3>將下面的程序編譯連接,用Debug加載、跟蹤,然后回答問題

assumecs:code,ds:data,ss:stackcodesegment

start:movax,stack

movss,ax

movsp,16movax,data

movds,axpushds:[0]

pushds:[2]

popds:[2]

popds:[0]movax,4c00h

int21h

codeends

datasegment

dw0123H,0456H

dataendsstacksegment

dw0,0

stackendsendstart

①CPU執(zhí)行程序,程序返回前,data段中的數(shù)據(jù)為多少?解:不變②CPU執(zhí)行程序,程序返回前,cs=155ah、ss=155eh、ds=155dh.<此題結果因環(huán)境而異,但相對差值不變>③設程序加載后,code段的段地址為X,則data段的段地址為X+3,stack段的段地址為X+4.<4>如果將<1>、<2>、<3>題中的最后一條偽指令"endstart"改為"end"<也就是說不指明程序的入口>,則那個程序仍然可以正確執(zhí)行?請說明原因.解:<1>、<2>不能正確執(zhí)行〔入口默認為data段的第一條指令,<3>能正確執(zhí)行.如果不指明程序的入口,編譯器自動默認整個代碼的第一條指令為程序的入口.〔經(jīng)qingxh1指正,在此鳴謝<5>程序如下,編寫code段中的內容,將a段和b段中的數(shù)據(jù)依次相加,將結果存到c段中.assumecs:codeasegmentdb1,2,3,4,5,6,7,8aendsbsegmentdb1,2,3,4,5,6,7,8bendscsegmentdb0,0,0,0,0,0,0,0cendscodesegmentstart:

movax,a

movds,ax

movbx,0movcx,8

s:

moval,ds:[bx]

addal,ds:[bx+16]

movds:[bx+32],al

incbx

loopsmovax,4c00h

int21hcodeendsendstart<6>程序如下,編寫code段中的代碼,用push指令將a段中的前8個字型數(shù)據(jù),逆序存儲到b段中.assumecs:codeasegmentdw1,2,3,4,5,6,7,8,9,0ah,0bh,0ch,0dh,0eh,0fh,0ffhaendsbsegmentdw0,0,0,0,0,0,0,0bendscodesegmentstart:

movax,a

movds,ax

movbx,0movax,b

movss,ax

movsp,16movcx,8

s:

push[bx]

incbx

incbx

loopsmovax,4c00h

int21hcodeendsendstart第7章更靈活的定位內存地址的方法實驗6實踐課程中的程序

<1>略

<2>編程,完成問題7.9中的程序.編程,將datasg段中每個單詞的前4個字母改寫為大寫字母.assumecs:codesg,ss:stacksg,ds:datasgstacksgsegmentdw0,0,0,0,0,0,0,0stacksgendsdatasgsegmentdb'1.display'db'2.brows'db'3.replace'db'4.modify'datasgendscodesgsegmentstart:movax,stacksg

movss,ax

movsp,16movax,datasg

movds,ax

movbx,0movcx,4

s0:

pushcx

movsi,0movcx,4

s:

moval,[bx+si+3]

andal,11011111b

mov[bx+si+3],al

incsi

loopsaddbx,16

popcx

loops0movax,4c00h

int21hcodesgendsendstart第8章數(shù)據(jù)處理的兩個基本問題實驗7尋址方式在結構化數(shù)據(jù)訪問中的應用

編程,將data段中的數(shù)據(jù)按如下格式寫入到table段中,并計算21年中的人均收入<取整>,結果也按照下面的格式保存在table段中.

解:

assumecs:codesg,ds:data,es:tabledatasegmentdb'1975','1976','1977','1978','1979','1980','1981','1982','1983'db'1984','1985','1986','1987','1988','1989','1990','1991','1992'db'1993','1994','1995';以上是表示21年的21個字符串dd16,22,382,1356,2390,8000,16000,24486,50065,97479,140417,197514dd345980,590827,803530,1183000,1843000,2759000,3753000,4649000,5937000;以上是表示21年公司總收的21個dword型數(shù)據(jù)dw3,7,9,13,28,38,130,220,476,778,1001,1442,2258,2793,4037,5635,8226dw11542,14430,45257,17800;以上是表示21年公司雇員人數(shù)的21個word型數(shù)據(jù)dataendstablesegmentdb21dup<'yearsummne??'>tableendscodesgsegmentstart:

movax,data

movds,ax

movsi,0movax,table

moves,ax

movdi,0movcx,21

s:

movax,ds:[si];年份轉送

moves:[di],ax

movax,ds:[si+2]

moves:[di+2],axmovax,ds:[si+84];收入轉送

moves:[di+5],ax

movdx,ds:[si+84+2]

moves:[di+7],dxpushcx;保護cx

movcx,ds:[84+84+bx];雇員數(shù)轉送

moves:[di+0ah],cxdivcx;計算人均收入

popcxmoves:[di+0dh],ax;人均收入轉送addsi,4

addbx,2

adddi,16loopsmovax,4c00hint21hcodesgendsendstart第9章轉移指令的原理檢測點9.1

<1>程序如下.assumecs:codedatasegment

db0,0,0

dataendscodesegmentstart:movax,data

movds,ax

movbx,0

jmpwordptr[bx+1]codeends

endstart若要使程序中的jmp指令執(zhí)行后,CS:IP指向程序的第一條指令,在data段中應該定義哪些數(shù)據(jù)?

<2>程序如下.assumecs:code,ds:datadatasegment

dd12345678h

dataendscodesegmentstart:movax,data

movds,ax

movbx,0

mov[bx],bx

mov[bx+2],cs

jmpdwordptrds:[0]codeendsendstart補全程序,使jmp指令執(zhí)行后,CS:IP指向程序的第一條指令.

<3>用Debug查看內存,結果如下:2000:1000BE0006000000

則此時,CPU執(zhí)行指令:

movax,2000H

moves,ax

jmpdwordptres:[1000H]后,<CS>=?,<IP>=?解:CS=0006H,IP=00BEH檢測點9.2補全編程,利用jcxz指令,實現(xiàn)在內存2000H段中找查第一個值為為0的字節(jié),找到后,將它的偏移地址存儲在dx中.assumecs:code

codesegment

start:movax,2000H

movds,ax

movbx,0

s:movch,0movcl,[bx]

jcxzokincbx

jmpshorts

ok:movdx,bx

movax,4c00h

int21h

codeends

endstart檢測點9.3補全程序,利用loop指令,實現(xiàn)在內存2000H段中查找第一個值為0的字節(jié),找到后,將它的偏移地址存儲在dx中.

assumecs:code

codesegment

start:movax,2000h

movds,ax

movbx,0

s:movcl,[bx]

movch,0

inccx

incbx

loops

ok:decbx

movdx,bx

movax,4c00h

int21h

codeends

endstart實驗8分析一個奇怪的程序分析下面的程序,在運行前思考:這個程序可以正確返回嗎?運行后再思考:為什么是這種結果?通過這個程序加深對相關內容的理解.assumecs:codesgcodesgsegmentmovax,4c00h

int21hstart:movax,0

s:nop

nopmovdi,offsets

movsi,offsets2

movax,cs:[si]

movcs:[di],axs0:jmpshortss1:movax,0

int21h

movax,0s2:jmpshorts1

nop

codesgendsendstart解:可以正常返回,jmpshorts1的機器碼是EBF6,即使當前的IP=IP-10,將這條指令移動到s:處后,jmpshorts1不會指到s1了,而是指到相對當前位置<jmpshorts1的下一條指令>的-10的位置<movax,4c00h>,所以這個程序可以正常返回.實驗9根據(jù)材料編程編程:在屏幕中間分別顯示綠色、綠底紅色、白底藍色的字符串'welcometomasm!'.解:

assumecs:codedatasegment

db'welcometomasm!'

dataendscodesegmentstart:movax,data

movds,axmovax,0b800h

moves,axmovsi,0

movdi,10*160+80;第十行中間

movcx,16

s1:moval,ds:[si]

movah,00000010B;綠色

moves:[di],ax

incsi

incdi

incdi

loops1movsi,0

movdi,11*160+80;第十一行中間

movcx,16

s2:moval,ds:[si]

movah,00100100B;綠底紅色

moves:[di],ax

incsi

incdi

incdi

loops2movsi,0

movdi,12*160+80;第十二行中間

movcx,16

s3:moval,ds:[si]

movah,01110001B;白底藍色

moves:[di],ax

incsi

incdi

incdi

loops3movax,4c00h

int21h;如果要看到完整的顯示請輸入:"-g4c",即立即運行到此條指令codeendsendstart注:此程序如果利用后面所學知識,可以將三次顯示嵌套簡化為一次.第10章CALL和RET指令檢測點10.1

補全程序,實現(xiàn)從內存1000:0000處開始執(zhí)行指令.assumecs:codestacksegment

db16dup<0>

stackendscodesegment

start:movax,stack

movss,ax

movsp,16

movax,1000h

pushax

movax,0

pushax

retf

codeendsendstart檢測點10.2

下面的程序執(zhí)行后,ax中的數(shù)值為多少?內存地址機器碼匯編指令

1000:0b80000movax,0

1000:3e80100calls

1000:640incax

1000:758s:popax解:ax=6檢測點10.3

下面的程序執(zhí)行后,ax中的數(shù)值為多少?內存地址機器碼匯編指令

1000:0b80000movax,0

1000:39a09000010callfarptrs

1000:840incax

1000:958s:popax

addax,ax

popbx

addax,bx解:ax=1010h檢測點10.4

下面的程序執(zhí)行后,ax中的數(shù)值為多少?內存地址機器碼匯編指令

1000:0b80600movax,6

1000:2ffd0callax

1000:540incax

1000:6movbp,sp

addax,[bp]解:ax=11檢測點10.5

<1>下面的程序執(zhí)行后,ax中的數(shù)值為多少?

注:不能用單步中斷測試程序,中斷涉及堆棧操作,不能帶便CPU的真實執(zhí)行結果.assumecs:code

stacksegment

dw8dup<0>

stackends

codesegment

start:movax,stack

movss,ax

movsp,16

movds,ax

movax,0

callwordptrds:[0EH]

incax

incax

incax

movax,4c00h

int21h

codeendsendstart

解:ax=3

<2>下面的程序執(zhí)行后,ax中的數(shù)值為多少?

assumecs:code

stacksegment

dw8dup<0>

stackends

codesegment

start:movax,stack

movss,ax

movsp,16

movwordptrss:[0],offsets

movss:[2],cs

calldwordptrss:[0]

nop

s:movax,offsets

subax,ss:[0cH]

movbx,cs

subbx,ss:[0eH]

movax,4c00h

int21h

codeendsendstart解:ax=1,bx=0實驗10編寫子程序1.顯示字符串;名稱:show_str

;功能:在屏幕的指定位置,用指定顏色,顯示一個用0結尾的字符串

;參數(shù):〔dh=行號,〔dl=列號〔取值范圍0~80,〔cl=顏色,ds:si:該字符串的首地址

;返回:顯示在屏幕上assumecs:daima

shujusegment

db'fghfghf',0

shujuends

daimasegment

kaishi:

movdh,8

movdl,21

movcl,2

movax,shuju

movds,ax

movsi,0

callshow_str

movax,4c00h

int21h

;

show_str:

pushax

pushcx

pushdx

pushes

pushsi

pushdimovax,0b800h

moves,axdecdh

moval,160

muldh

adddl,dl

movdh,0;計算顯示在屏幕位置

addax,dx

movdi,axmovah,clx:

movcl,ds:[si]

movch,0

jcxzf

moval,cl

moves:[di],ax

incsi

incdi

incdi

jmpxf:

popdi

popsi

popes

popdx

popcx

popax

ret

;

daimaends

endkaishi2.解決除法溢出問題;名稱:divdw

;功能:除法,被除數(shù)32位,除數(shù)16位,商32位,余數(shù)16位,不會溢出

;參數(shù):〔dx=被除數(shù)高16位,〔ax=被除數(shù)低16位,〔cx=除數(shù)

;返回:〔dx=商高16位,〔ax=商低16位,〔cx=余數(shù)assumecs:daima

daimasegment

kaishi:

movax,2390

movdx,0

movcx,10

calldivdw

movax,4c00h

int21h

;

divdw:

pushbx

pushax

movax,dx

movdx,0

divcx

movbx,ax

popax

divcx

movcx,dx

movdx,bx

popbx

ret

;

daimaends

endkaishi3.數(shù)值顯示

;名稱:dtoc_word

;功能:將一個word型數(shù)轉化為字符串

;參數(shù):〔ax=word型的數(shù)據(jù),ds:si指向字符串的首地址

;返回:ds:[si]放此字符串,以0結尾

assumecs:daimashujusegment

db20dup<1>

shujuendsdaimasegment

kaishi:

movax,shuju

movds,ax

movax,10100

calldtoc_wordmovax,4c00h

int21h

;

dtoc_word:

pushax

pushbx

pushcx

pushdx

pushsimovbx,0

x:

movdx,0

movcx,10

divcx

movcx,ax

adddx,'0'

pushdx

incbx

jcxzf

jmpxf:

movcx,bx

x1:

popds:[si]

incsi

loopx1popsi

popdx

popcx

popbx

popaxret

;daimaendsendkaishi課程設計1任務:將實驗7中的Poweridea公司的數(shù)據(jù)按照圖10.所示的格式在屏幕上顯示出來.解:;注:函數(shù)中的標號為防止沖突,都加了本函數(shù)名為前綴

;在Debug中輸入"-g90”,直接運行到結束

assumecs:codedatasegmentdb'1975','1976','1977','1978','1979','1980','1981','1982','1983'db'1984','1985','1986','1987','1988','1989','1990','1991','1992'db'1993','1994','1995';以上是表示21年的21個字符串dd16,22,382,1356,2390,8000,16000,24486,50065,97479,140417,197514dd345980,590827,803530,1183000,1843000,2759000,3753000,4649000,5937000;以上是表示21年公司總收的21個dword型數(shù)據(jù)dw3,7,9,13,28,38,130,220,476,778,1001,1442,2258,2793,4037,5635,8226dw11542,14430,45257,17800;以上是表示21年公司雇員人數(shù)的21個word型數(shù)據(jù)dataendsagencysegmentdb8dup<0>agencyendscodesegmentstart:movax,0b800h

moves,ax

movdi,0

movcx,80*24

x:movbyteptres:[di],'';將屏幕清空

movbyteptres:[di+1],0

incdi

incdi

loopxmovax,data

moves,ax

movdi,0

movbx,0movax,agency

movds,ax

movsi,0movdh,4movcx,21

x1:pushcxmovax,es:[di]

movds:[si],ax

movax,es:[di+2]

movds:[si+2],ax

movbyteptrds:[si+4],0;顯示年份

movdl,0

movcl,2

callshow_strmovax,es:[84+di]

pushdx

movdx,es:[84+di+2]

calldtoc_dword;顯示收入

popdx

movdl,20

movcl,2

callshow_strmovax,es:[84+84+bx]

calldtoc_word

movdl,40;顯示雇員數(shù)

movcl,2

callshow_strmovax,es:[84+di]

pushdx

movdx,es:[84+di+2]

divwordptres:[84+84+bx];計算人均收入并顯示

calldtoc_word

popdx

movdl,60

movcl,2

callshow_stradddi,4

addbx,2

adddh,1popcx

loopx1movax,4c00h

int21h;名稱:show_str

;功能:在屏幕的指定位置,用指定顏色,顯示一個用0結尾的字符串

;參數(shù):〔dh=行號,〔dl=列號〔取值范圍0~80,〔cl=顏色,ds:si:該字符串的首地址

;返回:顯示在屏幕上

show_str:

pushax

pushcx

pushdx

pushes

pushsi

pushdimovax,0b800h

moves,axmoval,160

muldh

adddl,dl

movdh,0

addax,dx

movdi,axmovah,clshow_str_x:

movcl,ds:[si]

movch,0

jcxzshow_str_f

moval,cl

moves:[di],ax

incsi

incdi

incdi

jmpshow_str_xshow_str_f:

popdi

popsi

popes

popdx

popcx

popax

ret;名稱:dtoc_word

;功能:將一個word型數(shù)轉化為字符串

;參數(shù):〔ax=word型的數(shù)據(jù),ds:si指向字符串的首地址

;返回:ds:[si]放此字符串,以0結尾

dtoc_word:

pushax

pushbx

pushcx

pushdx

pushsimovbx,0

dtoc_word_x:

movdx,0

movcx,10

divcx

movcx,ax

adddx,'0'

pushdx

incbx

jcxzdtoc_word_f

jmpdtoc_word_xdtoc_word_f:

movcx,bx

dtoc_word_x1:

popds:[si]

incsi

loopdtoc_word_x1popsi

popdx

popcx

popbx

popaxret;名稱:dtoc_dword

;功能:將一個doubleword型數(shù)轉化為字符串

;參數(shù):<dx>=數(shù)的高八位,〔ax=數(shù)的低八位

;返回:ds:[si]放此字符串,以0結尾

;備注:會用到divdw函數(shù)

dtoc_dword:

pushax

pushbx

pushcx

pushdx

pushsimovbx,0

dtoc_dword_x:

movcx,10

calldivdw

pushcx

incbx

cmpax,0

jnedtoc_dword_x

cmpdx,0

jnedtoc_dword_xmovcx,bx

dtoc_dword_x1:

popds:[si]

addbyteptrds:[si],'0'

incsi

loopdtoc_dword_x1popsi

popdx

popcx

popbx

popaxret;名稱:divdw

;功能:除法,被除數(shù)32位,除數(shù)16位,商32位,余數(shù)16位,不會溢出

;參數(shù):〔dx=被除數(shù)高16位,〔ax=被除數(shù)低16位,〔cx=除數(shù)

;返回:〔dx=商高16位,〔ax=商低16位,〔cx=余數(shù)

divdw:

pushbx

pushax

movax,dx

movdx,0

divcx

movbx,ax

popax

divcx

movcx,dx

movdx,bx

popbx

retcodeendsendstart第11章標志寄存器檢測點11.1

寫出下面每條指令后,ZF、PF、SF等標志位的值.

ZFPFSF

subal,al110

moval,1110

pushax110

popbx110

addal,bl000

addal,10010

mulal010

檢測點11.2CFOFSFZFPF

subal,al00011

moval,10H00011

addal,90H00101

moval,80H00101

addal,80H11011

moval,0FCH11011

addal,05H10000

moval,7DH10000

addal,0BH01101檢測點11.3

<1>補全下面的程序,統(tǒng)計F000:0處32個字節(jié)中,大小在[32,128]的數(shù)據(jù)的個數(shù).movax,0f000h

movds,axmovbx,0

movdx,0

movcx,32

s:moval,[bx]

cmpal,32

jbs0

cmpal,120

jas0

incdx

s0:incbx

loops<2>補全下面的程序,統(tǒng)計F000:0處32個字節(jié)中,大小在<32,128>的數(shù)據(jù)的個數(shù).movax,0f000h

movds,axmovbx,0

movdx,0

movcx,32

s:moval,[bx]

cmpal,32

jnas0

cmpal,120

jnbs0

incdx

s0:incbx

loops檢測點11.4

下面的程序執(zhí)行后:<ax>=?movax,0

pushax

popf

movax,0fff0h

addax,0010h

pushf

popax

andal,11000101B

andah,00001000B解:<ax>=01000101B實驗11編寫子程序;名稱:letterc

;功能:將以0結尾的字符串中的小寫字母轉變成大寫字母

;參數(shù):ds:si開始存放的字符串

;返回:ds:si開始存放的字符串assumecs:codesgdatasgsegment

db"Beginner'sAll-purposeSymbolicInstructionCode.",0

datasgendscodesgsegmentbegin:

movax,datasg

movds,ax

movsi,0calllettercmovax,4c00h

int21hletterc:

pushsi

pushaxx:moval,ds:[si]

cmpal,0

jef

incsi

cmpal,'a'

jbx

cmpal,'z'

jax

addal,'A'-'a'

movds:[si-1],al

jmpxf:popax

popsi

retcodesgendsendbegin第12章內中斷檢測點12.1

<1>用Debug查看內存,情況如下:

0000:00006810A7008B017000-16009D038B017000

則3號中斷源對應的中斷處理程序的入口地址為:0070:018B.<2>存儲N號中斷源對應的中斷處理程序入口的偏移地址的內存單元的地址為:4N.

存儲N號中斷源對應的中斷處理程序入口的段地址的內存單元的地址為:4N+2.

實驗12編寫0號中斷的處理程序編寫0號中斷的處理程序,使得在除法溢出發(fā)生時,在屏幕中間顯示字符串"divideerror!",然后返回到DOS.解:assumecs:codecodesegmentstart:

movax,cs

movds,ax

movsi,offsetdomovax,0

moves,ax

movdi,200hmovcx,offsetdoend-offsetdo;安裝中斷例程

cld

repmovsbmovwordptres:[0],200h

movwordptres:[2],0;設置中斷向量表movdx,0ffffh

movbx,1;測試一下

divbxmovax,4c00h

int21hdo:jmpshortdostart

db'divideerror!'

dostart:

movax,0

movds,ax

movsi,202hmovax,0b800h

moves,ax

movdi,160*10+80movcx,13

s:

moval,ds:[si]

movah,2

moves:[di],ax

incsi

incdi

incdi

loopsmovax,4c00h

int21hdoend:nopcodeendsendstart第13章int指令檢測點13.1

<1>在上面的內容中,我們用7ch中斷例程實現(xiàn)loop的功能,則上面的7ch中斷例程能進行的最大轉移位移是多少?解:8000H~7FFFH即<-32768~32767><2>用7ch中斷例程完成jmpnearptrs指令的功能,用bx向中斷例程傳送轉移位移.應用舉例:在屏幕的第12行顯示data段中,以0結尾的字符串.

assumecs:codedatasegment

db'conversation',0

dataends

codesegmentstart:movax,cs

movds,ax

movsi,offsetjpmovax,0

moves,ax

movdi,200hmovcx,offsetjpend-offsetjp;安裝中斷例程

cld

repmovsbmovwordptres:[7ch*4],200h

movwordptres:[7ch*4+2],0;設置中斷向量表

movax,data

movds,ax

movsi,0

movax,0b800h

moves,ax

movdi,12*160

s:cmpbyteptr[si],0

jeok

moval,[si]

moves:[di],al

incsi

adddi,2

movbx,offsets-offsetok;測試int7ch

int7ch

ok:movax,4c00h

int21hjp:pushbp

movbp,sp

add[bp+2],bx;中斷例程

popbp

iret

jpend:nopcodeendsendstart檢測點13.2判斷下面說法的正誤:<1>我們可以編程改變FFFF:0處的指令,使得CPU不去執(zhí)行BIOS中的硬件系統(tǒng)檢測和初始化程序.

答:錯.因為該內存單元具有‘只讀’屬性.<2>int19h中斷例程,可以由DOS提供.

答:這種說法是錯誤的.因為int19h是在DOS啟動之前就被執(zhí)行的中斷例程,是由BIOS提供的.實驗13編寫、應用中斷例程<1>編寫并安裝int7ch中斷例程,功能為顯示一個用0結束的字符串,中斷例程安裝在0:200處.參數(shù):<dh>=行號,<dl>=列號,<cl>=顏色,ds:si指向字符串首地址.assumecs:codedatasegment

db'welcometomasm!',0

dataends

codesegmentstart:movax,cs

movds,ax

movsi,offsetdpmovax,0

moves,ax

movdi,200hmovcx,offsetdpend-offsetdp;安裝中斷例程

cld

repmovsbmovwordptres:[7ch*4],200h

movwordptres:[7ch*4+2],0;設置中斷向量表

movdh,10

movdl,10

movcl,2

movax,data

movds,ax;測試int7ch

movsi,0

int7chmovax,4c00h

int21hdp:

moval,160

muldh

adddl,dl

movdh,0

addax,dx

movdi,axmovax,0b800h

moves,ax

;中斷例程

s:

moval,ds:[si]

movah,0

cmpax,0

jef

movah,cl

moves:[di],ax

incsi

incdi

incdi

jmpsf:

iret

dpend:nopcodeendsendstart<2>編寫并安裝int7ch中斷例程,功能為完成loop指令的功能.參數(shù):<cx>=循環(huán)次數(shù),<bx>=位移assumecs:code

codesegmentstart:movax,cs

movds,ax

movsi,offsetlpmovax,0

moves,ax

movdi,200hmovcx,offsetlpend-offsetlp;安裝中斷例程

cld

repmovsbmovwordptres:[7ch*4],200h

movwordptres:[7ch*4+2],0;設置中斷向量表

movax,0b800h

moves,ax

movdi,160*12

movbx,offsets-offsetse

movcx,80

s:

movbyteptres:[di],'!';測試int7ch

adddi,2

int7ch

se:

nopmovax,4c00h

int21hlp:

pushbpdeccx

jcxzf

movbp,sp

add[bp+2],bx;中斷例程f:

popbp

iretlpend:nopcodeendsendstart<3>下面的程序,分別在屏幕的第2、4、6、8行顯示四句英文詩,補全程序.assumecs:codecodesegment

s1:db'Good,better,best,','$'

s2:db'Neverletitrest,','$'

s3:db'Tillgoodisbetter,','$'

s4:db'Andbetter,best.','$'

s:dwoffsets1,offsets2,offsets3,offsets4

row:db2,4,6,8

start:movax,cs

movds,ax

movbx,offsets

movsi,offsetrow

movcx,4

ok:movbh,0

movdh,[si]

movdl,0

movah,2

int10hmovdx,[bx]

movah,9

int21h

incsi

addbx,2

loopokmovax,4c00h

int21hcodeendsendstart第14章端口檢測點14.1

<1>編程:讀取CMOSRAM的2號單元的內容.解:

assumecs:codecodesegment

start:moval,2

out70h,al

inal,71hmovax,4c00h

int21hcodeendsendstart

<2>編程:向CMOSRAM的2號單元寫入0.

解:

assumecs:codecodesegmentstart:moval,2

out70h,al

moval,0

out71h,al

movax,4c00h

int21hcodeendsendstart檢測點14.2

編程:用加法和移位指令計算<ax>=<ax>*10

提示:<ax>*10=<ax>*2+<ax>*8解:

assumecs:codecodesegmentstart:

movax,2shlax,1

movbx,ax

shlax,1

shlax,1

addax,bxmovax,4c00h

int21hcodeendsendstart實驗14訪問CMOSRAM編程:以"年/月/日時:分:秒"的格式,顯示當前的日期、時間.解:

assumecs:codedatasegmenttimedb'yy/mm/ddhh:mm:ss$';int21h顯示字符串,要求以$結尾

tabledb9,8,7,4,2,0;各時間量的存放單元dataendscodesegment

start:

movax,data

movds,ax

movsi,offsettable

movdi,offsettimemovcx,6

s:

pushcx

moval,ds:[si];讀端口

out70h,al

inal,71hmovah,al

movcl,4

shrah,cl;將壓縮BCD碼分為兩個BCD碼

andal,00001111baddah,30h;變?yōu)樽址?/p>

addal,30hmovds:[di],ah

movds:[di+1],al;寫進timeincsi

adddi,3popcx

loopsmovah,0

movbh,0

movdh,10;置光標于10行40列

movdl,40

int10hmovdx,offsettime

movah,9;顯示字符串

int21hmovax,4c00h

int21hcodeendsendstart第15章外中斷檢測點15.1<1>仔細分析一下上面的int9中斷例程,看看是否可以精簡一下?其實在我們的int9中斷例程中,模擬int指令調用原int9中斷例程的程序段是可以精簡的,因為在進入中斷例程后,IF和TF都已經(jīng)置0,沒有必要再進行設置可.對于程序段:pushf

pushf

popax

andah,11111100b

pushax

popf

calldwordptrds:[0]可以精簡為:pushf

calldwordptrds:[0]兩條指令.<2>仔細分析上面程序中的主程序[第269頁],看看有什么潛在的問題?

在主程序中,如果在執(zhí)行設置int9中斷例程的段地址和偏移地址的指令之間發(fā)生了鍵盤中斷,則CPU將轉去一個錯誤的地址執(zhí)行,將發(fā)生錯誤.

找出這樣的程序段,改寫它們,排除潛在的問題.

提示:注意sti和cli指令的用法.解:將

movwordptres:[9*4],offsetint9

moves:[9*4+2],cs

擴充為:cli

movwordptres:[9*4],offsetint9

moves:[9*4+2],cs

sti實驗15安裝新的int9中斷例程安裝一個新的int9中斷例程,功能:在DOS下,按下"A"鍵后,除非不再松開,如果松開,就顯示滿屏幕的"A";其他的鍵照常處理.提示:按下一個鍵時產生的掃描碼稱為通碼,松開一個鍵產生的掃描碼稱為斷碼.斷碼=通碼+80H.解:assumecs:codecodesegmentstart:movax,cs

movds,ax;安裝自定義的int9中斷例程

movax,0

moves,ax

movsi,offsetint9

movdi,204h

movcx,offsetint9end-offsetint9

cld

repmovsb

pushes:[9*4]

popes:[200h]

pushe

溫馨提示

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

最新文檔

評論

0/150

提交評論