检测点12.1

Tutorial: 汇编基础 Category: C语言 Published: 2026-04-07 13:58:26 Views: 20 Likes: 0 Comments: 0
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
Prev: 内中断 Next: int