检测点12.1
1. 12.1
用 debug 查看内存, 情况如下:
----------0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
0000:0000 68 10 A7 00 8B 01 70 00-16 00 9D 03 8B 01 70 00
则 3 号中断源对应的中断处理程序入口的偏移地址的内存单位的地址为
0070:018b
CS: 3*4 + 2 = 第 14 字节 = 0070
IP: 3*4 = 第 12 字节 = 018b
2. 实验 12
assume cs:code,ss:stack,ds:data
; 0号中断的安装程序
data segment
db 128 dup (0)
data ends
stack segment stack
db 128 dup (0)
stack ends
; 0E34:0000 8CC8 MOV AX,CS
; 0E34:0002 8ED8 MOV DS,AX
; 0E34:0004 BE3D00 MOV SI,003D
; 0E34:0007 B80000 MOV AX,0000
; 0E34:000A 8EC0 MOV ES,AX
; 0E34:000C BF0002 MOV DI,0200
; 0E34:000F B93200 MOV CX,0032
; 0E34:0012 FC CLD
; 0E34:0013 F3 REPZ
; 0E34:0014 A4 MOVSB
; 0E34:0015 B80000 MOV AX,0000
; 0E34:0018 8EC0 MOV ES,AX
; 0E34:001A 26 ES:
; 0E34:001B C70600000002 MOV WORD PTR [0000],0200
; 0E34:0021 26 ES:
; 0E34:0022 C70602000000 MOV WORD PTR [0002],0000
; 0E34:0028 B8240E MOV AX,0E24
; 0E34:002B 8ED8 MOV DS,AX
; 0E34:002D B80001 MOV AX,0100
; 0E34:0030 B100 MOV CL,00
; 0E34:0032 F6F1 DIV CL
; 0E34:0034 B407 MOV AH,07
; 0E34:0036 CD21 INT 21
; 0E34:0038 B8004C MOV AX,4C00
; 0E34:003B CD21 INT 21
; 0E34:003D EB0D JMP 004C
; 0E34:003F 64 DB 64
; 0E34:0040 65 DB 65
; 0E34:0041 7669 JBE 00AC
; 0E34:0043 64 DB 64
; 0E34:0044 65 DB 65
; 0E34:0045 206572 AND [DI+72],AH
; 0E34:0048 726F JB 00B9
; 0E34:004A 7221 JB 006D
; 0E34:004C B80000 MOV AX,0000
; 0E34:004F 8ED8 MOV DS,AX
; 0E34:0051 BE0202 MOV SI,0202
; 0E34:0054 B800B8 MOV AX,B800
; 0E34:0057 8EC0 MOV ES,AX
; 0E34:0059 BFC207 MOV DI,07C2
; 0E34:005C B90D00 MOV CX,000D
; 0E34:005F 8A04 MOV AL,[SI]
; 0E34:0061 26 ES:
; 0E34:0062 8805 MOV [DI],AL
; 0E34:0064 46 INC SI
; 0E34:0065 83C702 ADD DI,+02
; 0E34:0068 E2F5 LOOP 005F
; 0E34:006A B8004C MOV AX,4C00
; 0E34:006D CD21 INT 21
; 0E34:006F 90 NOP
code segment
start:
mov ax,cs ; 让ds代表code段的段地址
mov ds,ax ; 以从code段复制中断处理程序
mov si,OFFSET do0 ; (si)=传送原始位置的起始偏移地址 => 003D
mov ax,0
mov es,ax ; (es)=0
mov di,200H ; (di)=200H,一段不会被使用的空间,用来存放中断处理程序
mov cx,OFFSET do0End-OFFSET do0 ; (cx)=要复制的中断处理程序的长度 => 006F - 003D = 0032
cld ; df标志位置零,正向传送
rep movsb ; 将cx个字节的内容从ds:si复制到es:di
; -d es:200
; 0000:0200 EB 0D 64 65 76 69 64 65-20 65 72 72 6F 72 21 B8 ..devide error!.
; 0000:0210 00 00 8E D8 BE 02 02 B8-00 B8 8E C0 BF C2 07 B9 ................
; 0000:0220 0D 00 8A 04 26 88 05 46-83 C7 02 E2 F5 B8 00 4C ....&..F.......L
; 0000:0230 CD 21 00 00 00 00 00 00-00 00 00 00 00 00 00 00 .!..............
; -u es:200
; 0000:0200 EB0D JMP 020F
; 0000:0202 64 DB 64
; 0000:0203 65 DB 65
; 0000:0204 7669 JBE 026F
; 0000:0206 64 DB 64
; 0000:0207 65 DB 65
; 0000:0208 206572 AND [DI+72],AH
; 0000:020B 726F JB 027C
; 0000:020D 7221 JB 0230
; 0000:020F B80000 MOV AX,0000
; 0000:0212 8ED8 MOV DS,AX
; 0000:0214 BE0202 MOV SI,0202
; 0000:0217 B800B8 MOV AX,B800
; 0000:021A 8EC0 MOV ES,AX
; 0000:021C BFC207 MOV DI,07C2
; 0000:021F B90D00 MOV CX,000D
; (将中断处理程序从cs段复制到0:200H处)
; 设置中断向量表
mov ax,0
mov es,ax ; (es)=0
mov word ptr es:[0*4],200H ; 设置0号中断的偏移地址为200H
mov word ptr es:[0*4+2],0 ; 设置0号中断的段地址为0
; -d es:0 F
; 0000:0000 00 02 00 00 BB 13 21 08-F4 00 70 00 B1 13 21 08 ......!...p...!.
; 测试新的0号中断
mov ax,data ;
mov ds,ax
mov ax,100H
mov cl,0
div cl
; 0E34:0032 F6F1 DIV CL
; -t
; AX=0100 BX=0000 CX=0000 DX=0000 SP=007A BP=0000 SI=006F DI=0232
; DS=0E24 ES=0000 SS=0E2C CS=0000 IP=0200 NV UP DI PL NZ NA PO NC
; 0000:0200 EB0D JMP 020F
; -t
; AX=0100 BX=0000 CX=0000 DX=0000 SP=007A BP=0000 SI=006F DI=0232
; DS=0E24 ES=0000 SS=0E2C CS=0000 IP=020F NV UP DI PL NZ NA PO NC
; 0000:020F B80000 MOV AX,0000
mov ah,07H ; 获取键盘输入(无回显), 获得显示结果用
int 21H
mov ax,4c00H
int 21H
; 0号中断处理程序
; 这是要复制到0:200H处的
; 以0:200H处的视角看待这段程序,而不要以code段的视角看待这段程序
do0:
jmp do0Start
db "devide error!" ; 要输出的字符串,存放在这里而不能存放在ds段,
; 因为可能被别的信息覆盖
do0Start:
mov ax,0 ; (ds)=0
mov ds,ax
mov si,202H ; ds:si指向字符串
; -d es:200
; 0000:0200 EB 0D 64 65 76 69 64 65-20 65 72 72 6F 72 21 B8 ..devide error!.
; -d es:202
; 0000:0200 64 65 76 69 64 65-20 65 72 72 6F 72 21 B8 devide error!.
mov ax,0b800H
mov es,ax ; (es)=显示缓冲区段地址
mov di,12*160+33*2 ; 屏幕的中间位置
mov cx,13 ; 字符串长度=13
s: ; 输出字符串
mov al,ds:[si] ; 字符=(al)=[si]
mov es:[di],al ; 输出到屏幕
inc si ; si+1,指向下一个字符
add di,2 ; di+2,指向屏幕的下一个位置
loop s ; 输出下一个字符
mov ax,4c00H ; 中断处理程序结束,返回dos
int 21H
do0End:
nop
code ends
end start
3. 中断的补充 TF
assume cs:code,ss:stack,ds:data
data segment
db 128 dup (0)
data ends
stack segment stack
db 128 dup (0)
stack ends
code segment
start:
mov ax,stack
mov ss,ax
mov sp,128 ; 跳过该条命令的情况 => 设置栈顶的特殊情况
; -u
; 0E34:0000 B82C0E MOV AX,0E2C
; 0E34:0003 8ED0 MOV SS,AX
; 0E34:0005 BC8000 MOV SP,0080
; 0E34:0008 B8004C MOV AX,4C00
; 0E34:000B CD21 INT 21
; -r
; AX=0000 BX=0000 CX=010D DX=0000 SP=0080 BP=0000 SI=0000 DI=0000
; DS=0E14 ES=0E14 SS=0E2C CS=0E34 IP=0000 NV UP EI PL NZ NA PO NC
; 0E34:0000 B82C0E MOV AX,0E2C
; -t
; AX=0E2C BX=0000 CX=010D DX=0000 SP=0080 BP=0000 SI=0000 DI=0000
; DS=0E14 ES=0E14 SS=0E2C CS=0E34 IP=0003 NV UP EI PL NZ NA PO NC
; 0E34:0003 8ED0 MOV SS,AX
; -t
; AX=0E2C BX=0000 CX=010D DX=0000 SP=0080 BP=0000 SI=0000 DI=0000
; DS=0E14 ES=0E14 SS=0E2C CS=0E34 IP=0008 NV UP EI PL NZ NA PO NC
; 0E34:0008 B8004C MOV AX,4C00
; 原因
; -d ss:0
; 0E2C:0000 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
; 0E2C:0010 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
; 0E2C:0020 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
; 0E2C:0030 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
; 0E2C:0040 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
; 0E2C:0050 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
; 0E2C:0060 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
; 0E2C:0070 00 00 00 00 00 00 2C 0E-00 00 08 00 34 0E 21 08 ......,.....4.!.
; 引发了一个中断
; 0E34:0008 => CS:IP
; 0821 => 还不知道 ???
; NV UP EI PL NZ NA PO NC => 溢出、方向、中断、符号、零号、辅助、奇偶、进位
; => 一 方 中 符, 0 辅 激 进
mov ax,4C00H
int 21H
code ends
end start