匯編語言課后習題解答.doc
《匯編語言課后習題解答.doc》由會員分享,可在線閱讀,更多相關(guān)《匯編語言課后習題解答.doc(47頁珍藏版)》請在裝配圖網(wǎng)上搜索。
第1章 基礎知識 檢測點1.1(第9頁) (1)1個CPU的尋址能力為8KB,那么它的地址總線的寬度為13位。 (2)1KB的存儲器有1024個存儲單元,存儲單元的編號從0到1023。 (3)1KB的存儲器可以存儲8192(2^13)個bit,1024個Byte。 (4)1GB是1073741824(2^30)個Byte、1MB是1048576(2^20)個Byte、1KB是1024(2^10)個Byte。 (5)8080、8088、80296、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)從內(nèi)存中讀取1024字節(jié)的數(shù)據(jù),8086至少要讀512次,80386至少要讀256次。 (8)在存儲器中,數(shù)據(jù)和程序以 二進制形式存放。 解題過程: (1)1KB=1024B,8KB=1024B*8=2^N,N=13。 (2)存儲器的容量是以字節(jié)為最小單位來計算的,1KB=1024B。 (3)8Bit=1Byte,1024Byte=1KB(1KB=1024B=1024B*8Bit)。 (4)1GB=1073741824B(即2^30)1MB=1048576B(即2^20)1KB=1024B(即2^10)。 (5)一個CPU有N根地址線,則可以說這個CPU的地址總線的寬度為N。這樣的CPU最多可以尋找2的N次方個內(nèi)存單元。(一個內(nèi)存單元=1Byte)。 (6)8根數(shù)據(jù)總線一次可以傳送8位二進制數(shù)據(jù)(即一個字節(jié))。 (7)8086的數(shù)據(jù)總線寬度為16根(即一次傳送的數(shù)據(jù)為2B)1024B/2B=512,同理1024B/4B=256。 (8) 在存儲器中指令和數(shù)據(jù)沒有任何區(qū)別,都是二進制信息。 第2章 寄存器 檢測點2.1(第19頁) (1)寫出每條匯編指令執(zhí)行后相關(guān)寄存器中的值。 第一空:F4A3H 第二空:31A3H 第三空:3123H 第四空:6246H 第五空:826CH 第六空:6246H 第七空:826CH 第八空:04D8H 第九空:0482H 第十空:6C82H 第十一空:D882H 第十二空:D888H 第十三空:D810H 第十四空:6246H (2)只能使用目前學過的匯編指令,最多使用4條指令,編程計算2的4次方。 解答如下: mov ax,2 add ax,ax add ax,ax add ax,ax 檢測點2.2(第25頁) (1)00010H,1000FH (2)1001H,2000H 第2題說明: 因為段的起始地址要為16的倍數(shù)。所以當段地址小于1001H或大于2000H時CPU都無法尋到。 (1)解題過程: 物理地址=SA*16+EA EA的變化范圍為0h~ffffh 物理地址范圍為(SA*16+0h)~(SA*16+ffffh) 現(xiàn)在SA=0001h,那么尋址范圍為 (0001h*16+0h)~(0001h*16+ffffh) =0010h~1000fh (2)解題過程: 物理地址=SA*16+EA 20000h=SA*16+EA SA=(20000h-EA)/16=2000h-EA/16 EA取最大值時,SA=2000h-ffffh/16=1001h,SA為最小值 EA取最小值時,SA=2000h-0h/16=2000h,SA為最大值 這里的ffffH/16=fffh是通過WIN自帶計算器算的 按位移來算確實應該為fff.fh,這里小數(shù)點后的f應該是省略了 單就除法來說,應有商和余數(shù),但此題要求的是地址最大和最小,所以余數(shù)忽略了 如果根據(jù)位移的算法(段地址*16=16進制左移一位),小數(shù)點后應該是不能省略的 我們可以反過來再思考下,如果SA為1000h的話,小數(shù)點后省略 SA=1000h,EA取最大ffffh,物理地址為1ffffh,將無法尋到20000H單元 這道題不應看成是單純的計算題 檢測點2.3(第35頁) 答:CPU修改了4次IP的值。 情況如下: 第1次:執(zhí)行完mov ax,bx后 第2次:執(zhí)行完sub ax,ax后 ;該步執(zhí)行后,寄存器ax清零 第3次:讀入jmp ax后 第4次:執(zhí)行完jmp ax后 ;連續(xù)兩步ip均為0 最后IP的值為0 ;最后IP的值為0000H,因為最后ax中的值為0000H,所以IP中的值也為0000H 第3章 寄存器(內(nèi)存訪問) 檢測點3.1(第55頁) (1)(題目:略) 第一空:2662H 第二空:E626H 第三空:E626H 第四空:2662H 第五空:D6E6H 第六空:FD48H 第七空:2C14H 第八空:0000H 第九空:00E6H 第十空:0000H 第十一空:0026H 第十二空:000CH 提示:此題可在DEBUG中利用E命令在本機上按照題目中所給出的內(nèi)存單元及其數(shù)據(jù)進行相應地修改,然后再用A命令進行寫入(題目中所給出的)相應的匯編指令,最后再進行T命令進行逐步執(zhí)行,以查看相應結(jié)果。 (2) 指令序列如下: mov ax,6622h jmp 0ff0:0100 mov ax,2000h mov ds,ax mov ax,[0008] mov ax,[0002] 2.寫出CPU執(zhí)行每條指令后,CS、IP和相關(guān)寄存器中的數(shù)值。 指令序列↓ 寄存器→ CS IP DS AX BX 初始值→ 2000H 0000 1000H 0 0 mov ax,6622h 2000H 0003 1000H 6622H 0000 jmp 0ff0:0100 1000H 0000 1000H 6622H 0000 mov ax,2000h 1000H 0003 1000H 2000H 0000 mov ds,ax 1000H 0005 2000H 2000H 0000 mov ax,[0008] 1000H 0008 2000H C389H 0000 mov ax,[0002] 1000H 000B 2000H EA66H 0000 3.再次體會:數(shù)據(jù)和程序有區(qū)別嗎?如何確定內(nèi)存中的信息哪些是數(shù)據(jù),哪些是程序? 檢測點3.2(第70頁) (1)補全下面的程序,使其可以將10000H-1000FH中的8個字,逆序拷貝到20000H-2000FH中。 mov ax,1000H mov ds,ax mov ax,2000H mov ss,ax mov sp,10h (2)補全下面的程序,使其可以將10000H-1000FH中的8個字,逆序拷貝到20000H-2000FH中。 mov ax,2000H mov ds, ax mov ax,1000H mov ss, ax mov sp,0 檢測點6.1(第129頁) (1)下面的程序?qū)崿F(xiàn)依次用內(nèi)存0:0~0:15單元中的內(nèi)容改寫程序中的數(shù)據(jù),完成程序: assume cs:codesg codesg segment dw 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h start: mov ax,0 mov ds, ax mov bx,0 mov cx,8 s: mov ax,[bx] mov cs:[bx],ax add bx,2 loop s mov ax,4c00h int 21h codesg ends end start (2)下面的程序?qū)崿F(xiàn)依次用內(nèi)存0:0~0:15單元中的內(nèi)容改寫程序中的數(shù)據(jù),數(shù)據(jù)的傳送用棧來進行。??臻g設置在程序內(nèi)。完成程序: assume cs:codesg codesg segment dw 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h dw 0,0,0,0,0,0,0,0,0,0 ;10個字單元用作??臻g,所以??臻g的大小為10*2=20,化成16進制即為14 start: mov ax, codesg;或mov ax, cs mov ss ,ax mov sp, 24h ;或mov sp, 36 ;10h+14h=24h mov ax,0 mov ds, ax mov bx,0 mov cx,8 s: push [bx] pop cs:[bx] ;或 pop ss:[bx] ;關(guān)鍵在于cs與ss此時地址相同 add bx,2 loop s mov ax,4c00h int 21h codesg ends end start 檢測點9.1(第183頁) (1) 程序如下: assume cs:code data segment dw 2 dup (0) data ends code segment start: mov ax, data mov ds, ax mov bx,0 jmp word ptr [bx+1] code ends end start 若要使jmp指令執(zhí)行后,CS:IP指向程序的第一條指令,在data段中應該定義哪些數(shù)據(jù)? 答案①db 3 dup (0) 答案②dw 2 dup (0) 答案③dd 0 jmp word ptr [bx+1]為段內(nèi)轉(zhuǎn)移,要CS:IP指向程序的第一條指令,應設置ds:[bx+1]的字單元(2個字節(jié))存放數(shù)據(jù)應為0,則(ip)=ds:[bx+1]=0 簡單來說就是,只要ds:[bx+1]起始地址的兩個字節(jié)為0就可以了 (2) 程序如下: assume cs:code data segment dd 12345678h data ends code segment start: mov ax,data mov ds,ax mov bx,0 mov [bx], bx ;或mov [bx], word ptr 0 ;或mov [bx], offset start mov [bx+2], cs ;或mov [bx+2], cs ;或mov [bx+2], seg code jmp dword ptr ds:[0] code ends end start 補全程序,使用jmp指令執(zhí)行后,CS:IP指向程序的第一條指令。 第一格可填①mov [bx],bx ②mov [bx],word ptr 0 ③mov [bx],offset start等。 第二格可填①mov [bx+2],cs ②mov [bx+2],cs ③mov [bx+2],seg code等。 解析: jmp dword ptr ds:[0]為段間轉(zhuǎn)移,(cs)=(內(nèi)存單元地址+2),(ip)=(內(nèi)存單元地址),要CS:IP指向程序的第一條指令,第一條程序地址cs:0,應設置CS:IP指向cs:0 程序中的mov [bx],bx這條指令,是將ip設置為0 mov [bx+2],cs,將cs這個段地址放入內(nèi)存單元 執(zhí)行后,cs應該不變,只調(diào)整ip為0,(ip)=ds:[0]=0 (3)用Debug查看內(nèi)存,結(jié)果如下: 2000:1000 BE 00 06 00 00 00 ...... 則此時,CPU執(zhí)行指令: mov ax,2000h mov es,ax jmp dword ptr es:[1000h] 后,(cs)= 0006H,(ip)= 00BEH 解析: jmp dword ptr為段間轉(zhuǎn)移,高位存放段地址,低位存放偏移地址 (cs)=(內(nèi)存單元地址+2),(ip)=(內(nèi)存單元地址) 根據(jù)書P16,對于寄存器AX,AH為高位(前1字節(jié)為高位),AL為低位(后1字節(jié)為低位) 推算出(內(nèi)存單元地址)=00BEH,(內(nèi)存單元地址+2)=0006H 根據(jù)書P182,高位存放段地址(后2個字節(jié)為高位),低位存放偏移地址(前2個字節(jié)為低位) (cs)=(內(nèi)存單元地址+2),(ip)=(內(nèi)存單元地址) 推算出(cs)=0006H,(ip)=00BEH. 檢測點9.2(第184頁) 補全編程,利用jcxz指令,實現(xiàn)在內(nèi)存2000H段中查找第一個值為0的字節(jié),找到后,將它的偏移地址存儲在dx中。 assume cs:code code segment start: mov ax,2000h mov ds, ax mov bx,0 s: mov ch,0 mov cl,[bx] jcxz ok ;當cx=0時,CS:IP指向OK inc bx jmp short s ok: mov dx, bx mov ax ,4c00h int 21h code ends end start 檢測點9.3(第185頁) 補全編程,利用loop指令,實現(xiàn)在內(nèi)存2000H段中查找第一個值為0的字節(jié),找到后,將它的偏移地址存儲在dx中。 assume cs:code code segment start: mov ax,2000h mov ds, ax mov bx,0 s:mov cl,[bx] mov ch,0 inc cx ;只要保證cx>0,才能執(zhí)行l(wèi)oop循環(huán),切記! inc bx loop s ok: dec bx mov dx, bx mov ax,4c00h int 21h code ends end start 檢測點10.1(第191頁) 補全程序,實現(xiàn)從內(nèi)存1000:0000處開始執(zhí)行指令。 assume cs:code stack segment db 16 dup (0) stack ends code segment start: mov ax, stack mov ss, ax mov sp,16 mov ax, 1000h push ax mov ax, 0 push ax retf code ends end start 執(zhí)行reft指令時,相當于進行: pop ip pop cs 根據(jù)棧先進后出原則,應先將段地址cs入棧,再將偏移地址ip入棧。 檢測點10.2(第192頁) 下面的程序執(zhí)行后,ax中的數(shù)值為多少? 內(nèi)存地址 機器碼 匯編指令 執(zhí)行后情況 1000:0 b8 00 00 mov ax,0 ax=0 ip指向1000:3 1000:3 e8 01 00 call s pop ip ip指向1000:7 1000:6 40 inc ax 1000:7 58 s:pop ax ax=6 用debug進行跟蹤確認,“call標號”是將該指令后的第一個字節(jié)偏移地址入棧,再轉(zhuǎn)到標號處執(zhí)行指令。 檢測點10.3(第192頁) 下面的程序執(zhí)行后,ax中的數(shù)值為多少? 內(nèi)存地址 機器碼 匯編指令 執(zhí)行后情況 1000:0 b8 00 00 mov ax,0 ax=0, ip指向1000:3 1000:3 9a 09 00 00 10 call far ptr s pop cs,pop ip,ip指向1000:9 1000:8 40 inc ax 1000:9 58 s: pop ax ax=8h add ax,ax ax=10h pop bx bx=1000h add ax,bx ax=1010h 檢測點10.4(第194頁) 下面的程序執(zhí)行后,ax中的數(shù)值為多少? 內(nèi)存地址 機器碼 匯編指令 執(zhí)行后情況 1000:0 b8 06 00 mov ax,6 ax=6, ip指向1000:3 1000:3 ff d0 call ax pop ip, ip指向1000:6 1000:5 40 inc ax 1000:6 58 mov bp ,sp bp=sp=fffeh ;棧頂?shù)牡刂窚p去2,存放著05h add ax,[bp] ax=[6+ds:(fffeh)]=6+5=0bh 用debug進行跟蹤確認,“call ax(16位reg)”是先將該指令后的第一個字節(jié)偏移地址ip入棧,再轉(zhuǎn)到偏移地址為ax(16位reg)處執(zhí)行指令。 編譯無法通過,只能理論分析. 檢測點10.5(第195頁) (1) 下面的程序執(zhí)行后,ax中的數(shù)值為多少? assume cs:code stack segment dw 8 dup (0) stack ends code segment start: mov ax, stack mov ss, ax mov sp,16 mov ds, ax mov ax,0 call word ptr ds:[0eh] inc ax inc ax inc ax mov ax,4c00h int 21h code ends end start 當程序執(zhí)行call word ptr ds:[0EH]語句時,相當于進行: 1: PUSH IP(此時IP的值為CALL語句下一條語句的偏移地址,也就是INC AX的偏移地址) 2: JMP WORD PTR SS(因為DS等于SS):[0EH],此時程序跳轉(zhuǎn)到CS:SS:[OEH]處執(zhí)行,因為 SS:[0EH]的值為0,所以跳轉(zhuǎn)到CS:0處開始執(zhí)行,也就是程序的第一條語句MOV AX, STACK,當程序再一次執(zhí)行到call word ptr ds:[0EH]時,又進行上面的兩步,但是此時SS:[OEH]的值已經(jīng)不是0了,而是上一次執(zhí) 行PUSH IP時,壓入的IP的值,而這個IP正是CALL語句下一條語句的偏移地址,也就是INC AX的偏移地址.所以程序跳轉(zhuǎn)到語句INC AX處執(zhí)行,所以AX的值為3. (2) 下面的程序執(zhí)行后,ax和bx中的數(shù)值為多少? assume cs:codesg stack segment dw 8 dup(0) stack ends codesg segment start: mov ax, stack mov ss, ax mov sp,10h mov word ptr ss:[0],offset s ;(ss:[0])=1ah mov ss:[2],cs ;(ss:[2])=cs call dword ptr ss:[0] ;cs入棧,ip=19h入棧,轉(zhuǎn)到cs:1ah處執(zhí)行指令 ; ss:[0ch] = 19h ss:[0eh] = cs nop s: mov ax, offset s ;ax=1ah sub ax, ss:[0ch] ;ax=1ah-(ss:[0ch])=1ah-19h=1 mov bx, cs ;bx=cs=0c5bh sub bx, ss:[0eh] ;bx=cs-cs=0 mov ax,4c00h int 21h codesg ends end start 檢測點11.1(第216頁) 寫出下面每條指令執(zhí)行后,ZF、PF、SF、等標志位的值。 sub al,al al=0h ZF=1 PF=1 SF=0 mov al,1 al=1h ;mov 指令不改變標志位 ZF=1 PF=1 SF=0 push ax ax=1h ;push 指令不改變標志位 ZF=1 PF=1 SF=0 pop bx bx=1h ;pop 指令不改變標志位 ZF=1 PF=1 SF=0 add al,bl al=2h ;al = 00000010b ZF=0 PF=0 SF=0 add al,10 al=12h ;al = 00001010b ZF=0 PF=1 SF=0 mul al ax=144h ;ax = 10010000b ZF=0 PF=1 SF=0 檢測點11.2(第219頁) 寫出下面每條指令執(zhí)行后,ZF、PF、SF、CF、OF等標志位的值。 al CF OF SF ZF PF sub al, al 0h 0000 0000b 0 0 0 1 1 mov al,10h 10h 0010 0000b 0 0 0 1 1 add al,90h a0h 1010 0000b 0 0 1 0 1 mov al,80h 80h 1000 0000b 0 0 1 0 1 add al,80h 0h 0000 0000b 1 1 0 1 1 mov al,0fch 0fch 1111 1100b 1 1 0 1 1 add al,05h 1h 0000 0001b 1 0 0 0 0 mov al,7dh 7dh 1111 1101b 1 0 0 0 0 add al,0bh 88h 1000 1000b 0 1 1 0 1 檢測點涉及的相關(guān)內(nèi)容: CF是flag的第0位,進位標志位,記錄無符號運算結(jié)果是否有進/借位,結(jié)果有進/借位時,SF=1 OF是flag的第11位,溢出標志位,記錄有符號運算結(jié)果是否溢出,結(jié)果溢出時,OF=1 正數(shù)相加超出127,負數(shù)相加超出-128,兩種情況OF均置為1 SF是flag的第7位,符號標志位,記錄有符號運算結(jié)果是否為負數(shù),結(jié)果為負數(shù)時,SF=1 ZF是flag的第6位,零標志位,記錄指令執(zhí)行后結(jié)果是否為0,結(jié)果為0時,ZF=1 PF是flag的第2位,奇偶標志位,記錄指令執(zhí)行后結(jié)果二進制中1的個數(shù)是否為偶數(shù),結(jié)果為偶數(shù)時,PF=1 add、sub、mul、div、inc、or、and等運算指令影響標志寄存器 mov、push、pop等傳送指令對標志寄存器沒影響。 檢測點11.3(第229頁) (1) 補全下面的程序,統(tǒng)計F000:0處32個字節(jié)中,大小在[32,128]的數(shù)據(jù)個數(shù)。 mov ax,0f000h mov ds, ax mov bx,0 ;ds: bx指向第一個字節(jié) mov dx,0 ;初始化累加器 mov cx,32 s: mov al,[bx] cmp al,32 ;和32進行比較 jb s0 ;如果低于al轉(zhuǎn)到s0,繼續(xù)循環(huán) cmp al,128 ;和128進行比較 ja s0 ;如果高于al轉(zhuǎn)到s0,繼續(xù)循環(huán) inc dx s0: inc bx loop s (2) 補全下面的程序,統(tǒng)計F000:0處32個字節(jié)中,大小在(32,128)的數(shù)據(jù)個數(shù)。 mov ax,0f000h mov ds,ax mov bx,0 ;ds:bx指向第一個字節(jié) mov dx,0 ;初始化累加器 mov cx,32 s: mov al,[bx] cmp al,32 ;和32進行比較 jna s0 ;如果不高于al轉(zhuǎn)到s0,繼續(xù)循環(huán) cmp al,128 ;和128進行比較 jnb s0 ;如果不低于al轉(zhuǎn)到s0,繼續(xù)循環(huán) inc dx s0: inc bx loop s [32,128]是閉區(qū)間,包括兩端點的值 (32,128)是開區(qū)間,不包括兩端點的值 檢測點11.4(第233頁) 下面指令執(zhí)行后,(ax)= 45h mov ax,0 push ax popf ;將psw清零 mov ax,0fff0H add ax,0010h pushf ;將psw入棧,psw的值0000000 01000101,這里已經(jīng)講學過的標志位都標 識出來了,沒學過的全部都當作0分析了,結(jié)果應該也是對的 pop ax ;出棧ax的值就是00000000 01000101 and al,11000101B ;且運算 al:01000101 and ah,00001000B ;且運算 al:00000000 分析:這里面主要還是講解pushf和popf,就是psw的值入棧,psw16個字節(jié),我們學習了6個,但是df在本程序里面一直沒有賦值,所以是0,其他的標志位沒有學習,在下面的且運算的時候全部歸零了,所以最后的結(jié)果就是0045H,也就是最后我分析的00000000 01000101。 檢測點12.1(第238頁) (1)用debug查看內(nèi)存,情況如下: 0000:0000 68 10 A7 00 8B 01 70 00-16 00 9D 03 8B 01 70 00 則3號中斷源對應的中斷處理程序入口的偏移地址的內(nèi)存單位的地址為: 0070:018b (2) 存儲N號中斷源對應的中斷處理程序入口的偏移地址的內(nèi)存單元的地址為: 4N 存儲N號中斷源對應的中斷處理程序入口的段地址的內(nèi)存單元的地址為: 4N+2 檢測點涉及相關(guān)內(nèi)容: 一個表項存放一個中斷向量,也就是一個中斷處理程序的入口地址,這個入口地址包括段地址和偏移地址,一個表項占兩個字,高地址存放段地址,低地址存放偏移地址 檢測點13.1(第257頁) (1)7ch中斷例程如下: lp: push bp mov bp, sp dec cx jcxz lpret add [bp+2],bx lpret: pop bp iret (1)在上面的內(nèi)容中,我們用7ch中斷例程實現(xiàn)loop的功能,則上面的7ch中斷例程所能進行的最大轉(zhuǎn)移位移是多少? 最大位移是FFFFH,即棧底與棧頂之間的位移為最大轉(zhuǎn)移位移 可以轉(zhuǎn)移的范圍是 -32768~32767 (2)用7ch中斷例程完成jmp near ptr s指令功能,用bx向中斷例程傳送轉(zhuǎn)移位移。 應用舉例:在屏幕的第12行,顯示data段中以0結(jié)尾的字符串。 assume cs:code data segment db conversation,0 data ends code segment start: mov ax, data mov ds, ax mov si,0 mov ax,0b800h mov es, ax mov di,12*160 s: cmp byte ptr [si],0 je ok mov al,[si] mov es:[di],al inc si add di,2 mov bx ,offset s-offset ok int 7ch ok: mov ax,4c00h int 21h code ends end start jmp near ptr s指令的功能為:(ip)=(ip)+16位移,實現(xiàn)段內(nèi)近轉(zhuǎn)移 assume cs:code code segment start: mov ax, cs mov ds, ax mov si, offset do0 ;設置ds:si指向源地址 mov ax,0 mov es, ax mov di,200h ;設置es:di指向目標地址 mov cx, offset do0end-offset do0 ;設置cx為傳輸長度 cld ;設置傳輸方向為正 rep movsb mov ax,0 mov es ,ax mov word ptr es:[7ch*4],200h mov word ptr es:[7ch*4+2],0 ;設置中斷向量表 mov ax,4c00h int 21h do0: push bp mov bp, sp add [bp+2],bx ;ok的偏移地址+bx得到s的偏移地址 pop bp iret mov ax,4c00h int 21h do0end: nop code ends end start 檢測點13.2(第259頁) 判斷下面說法的正誤: (1)我們可以編程改變FFFF:0處的指令,使得CPU不去執(zhí)行BIOS中的硬件系統(tǒng)檢測和初始化程序。 答:錯誤,F(xiàn)FFF:0處的內(nèi)容無法改變。 (2)int 19h中斷例程,可以由DOS提供。 答:錯誤,先調(diào)用int 19h,后啟動DOS。 檢測點15.1(第282頁) (1) 仔細分析一下書中的in9中斷例程,看看是否可以精簡一下? 其實在我們的int 9中斷例程中,模擬int指令調(diào)用原int 9中斷例程的程序段是可以精簡的,因為在進入中斷例程后,IF和TF都已置0,沒有必要再進行設置了,對于程序段: pushf ;標志寄存器入棧 pushf pop bx and bh,11111100b ;IF和TF為flag的第9位和第8位 push bx popf ;TF=0,IF=0 call dword ptr ds:[0] ;CS、IP入棧;(IP)=ds:[0],(CS)=ds:[2] 可以精簡為: pushf ;標志寄存器入棧 call dword ptr ds:[0] ;CS、IP入棧;(IP)=ds:[0],(CS)=ds:[2] 兩條指令。 (2) 仔細分析程序中的主程序,看看有什么潛在的問題? 在主程序中,如果在設置執(zhí)行設置int 9中斷例程的段地址和偏移地址的指令之間發(fā)生了鍵盤中段,則CPU將轉(zhuǎn)去一個錯誤的地址執(zhí)行,將發(fā)生錯誤。 找出這樣的程序段,改寫他們,排除潛在的問題。 ;在中斷向量表中設置新的int 9中斷例程的入口地址 cli ;設置IF=0屏蔽中斷 mov word ptr es:[9*4],offset int9 mov es:[9*4+2],cs sti ;設置IF=1不屏蔽中斷 更改后的int 9中斷例程: ;功能:在屏幕中間依次顯示a~z,并讓人看清。在顯示過程中按下Esc鍵后,改變顯示的顏色。 assume cs:code stack segment db 128 dup (0) stack ends data segment dw 0,0 data ends code segment start: mov ax, stack mov ss, ax mov sp,128 ;將原來的int 9中斷例程的入口地址保存在ds:0、ds:2單元中 mov ax, data mov ds, ax mov ax,0 mov es, ax push es:[9*4] pop ds:[0] push es:[9*4+2] pop ds:[2] ;在中斷向量表中設置新的int 9中斷例程的入口地址 cli ;設置IF=0屏蔽中斷 mov word ptr es:[9*4],offset int9 mov word ptr es:[9*4+2],cs sti ;設置IF=1不屏蔽中斷 ;依次顯示a~z mov ax,0b800h mov es ,ax mov ah, a s: mov es:[160*12+40*2],ah ;第12行第40列 inc ah cmp ah, z jnb s ;將中斷向量表中int 9中斷例程的入口恢復為原來的地址 mov ax,0 mov es, ax push ds:[0] pop ss:[9*4] push ds:[2] pop es:[9*4+2] ;結(jié)束 mov ax,4c00h int 21h ;循環(huán)延時,循環(huán)100000h次 delay: push ax push dx mov dx,1000h mov ax,0 delay1: sub ax,1 sbb dx,0 ;(dx)=(dx)-0-CF cmp ax,0 jne delay1 cmp dx,0 jne delay1 pop dx pop ax ret ;以下為新的int 9中斷例程 int9: push ax push bx push es in al,60h ;從端口60h讀出鍵盤輸入 ;對int指令進行模擬,調(diào)用原來的int 9中斷例程 pushf ;標志寄存器入棧 call dword ptr ds:[0] ;CS、IP入棧;(IP)=ds:[0],(CS)=ds:[2] ;如果是ESC掃描碼,改變顯示顏色 cmp al,1 ;和esc的掃描碼01比較 jne int9ret ;不等于esc時轉(zhuǎn)移 mov ax,0b800h mov es, ax inc byte ptr es:[160*12+40*2+1] ;將屬性值+1,改變顏色 int9ret:pop es pop bx pop ax iret code ends end start 檢測點16.1(第289頁) 下面的程序?qū)ode段中a處的8個數(shù)值累加,結(jié)果存儲到b處的雙字節(jié)中,補全程序。 assume cs:code code segment a dw 1,2,3,4,5,6,7,8 ;高位在后,低位在前 b dd 0 start: mov si,0 mov cx,8 s: mov ax, a[si] add word ptr b[0],ax adc word ptr b[2],0 add si,2 loop s mov ax,4c00h int 21h code ends end start 檢測點16.2(第291頁) 下面的程序?qū)ata段中a處的8個數(shù)值累加,結(jié)果存儲到b處的雙字節(jié)中,補全程序。 assume cs: code, es: data data segment a db 1,2,3,4,5,6,7,8 b dw 0 data ends code segment start: mov ax, data mov es, ax mov si,0 mov cx,8 s: mov al, a[si] mov ah,0 add b, ax inc si loop s mov ax,4c00h int 21h code ends end start 檢測點17.1(第304頁) “在int 16h中斷例程中,一定有設置IF=1的指令?!边@種說法對嗎? 正確,當鍵盤緩沖區(qū)為空時,如果設置IF=0,int 9中斷無法執(zhí)行,循環(huán)等待會死鎖。- 1.請仔細閱讀文檔,確保文檔完整性,對于不預覽、不比對內(nèi)容而直接下載帶來的問題本站不予受理。
- 2.下載的文檔,不會出現(xiàn)我們的網(wǎng)址水印。
- 3、該文檔所得收入(下載+內(nèi)容+預覽)歸上傳者、原創(chuàng)作者;如果您是本文檔原作者,請點此認領(lǐng)!既往收益都歸您。
下載文檔到電腦,查找使用更方便
9.9 積分
下載 |
- 配套講稿:
如PPT文件的首頁顯示word圖標,表示該PPT已包含配套word講稿。雙擊word圖標可打開word文檔。
- 特殊限制:
部分文檔作品中含有的國旗、國徽等圖片,僅作為作品整體效果示例展示,禁止商用。設計者僅對作品中獨創(chuàng)性部分享有著作權(quán)。
- 關(guān) 鍵 詞:
- 匯編語言 課后 習題 解答
鏈接地址:http://www.820124.com/p-6559435.html