⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pmstart8.asm

📁 保护模式下编程。通过陷阱门INT 0FEh进行字符串输出。通过任务状态段TSS进行任务切换
💻 ASM
📖 第 1 页 / 共 2 页
字号:
;----------------------------------------------------------------------------
;pmstart8.asm
;从实模式进入保护模式,进入主任务.
;通过陷阱门INT 0FEh进行字符串输出,提示用户操作
;通过任务状态段TSS进行任务切换
;通过8255的C口读开关量.K0=1返回实模式,K1=1时进入TaskA
;K2=1进入TaskB,K3=1时从TaskA或TaskB返回主任务
;TaskA:点阵扫描
;TaskB:七段数码管显示00-99
;接线:8255CS->0x288
;点阵的行选借280H,列选接290H
;PA0-PA6->七段数码管a-g,PB0-PB1->七段数码管S0-S1.PC0-PC3->K0-K3
;----------------------------------------------------------------------------
include pmstart.inc
.386p
;--------------------------
;全局描述符表GDT
GdtSeg segment para use16 'GDT'
gdt  LABEL  BYTE
     Dummy  Desc <>            
     
     NormalSel=$-gdt
     Normal Desc   <0ffffh,,,92h,,>
     
;视频缓冲区段描述符及选择子     
     VideoSel=$-gdt
     Video Desc <0ffffh,8000h,0bh,92h,,>

effgdt   LABEL BYTE 
;临时代码段描述符及选择子
     TempCodeSel=$-gdt
     TempCode   Desc <0ffffh,TempCodeSeg,,98H,,>
     
;主任务代码段描述符及选择子    
     SysCodeSel=$-gdt
     Syscode    Desc <SysCodeLen-1,SysCodeSeg,,98H,,>

;主任务状态段TSS描述符及选择子
     SysTssSel=$-gdt
     SysTss     Desc <SysTssLen-1,SysTssSeg,,89h,,>

;主任务LDT描述符及选择子     
     SysLdtSel=$-gdt
     SysLdt     Desc <SysLdtLen-1,SysLdtSeg,,82h,,>

;TaskA任务状态段TSS描述符及选择子         
     TaskATssSel=$-gdt
     TaskATss   Desc <TaskATssLen-1,TaskATssSeg,,89h,,>     

;TaskA任务LDT描述符及选择子       
     TaskALdtSel=$-gdt
     TaskALdt     Desc <TaskALdtLen-1,TaskALdtSeg,,82h,,>
     
     TaskBTssSel=$-gdt
     TaskBTss   Desc <TaskBTssLen-1,TaskBTssSeg,,89h,,>     
     
     TaskBLdtSel=$-gdt
     TaskBLdt     Desc <TaskBLdtLen-1,TaskBLdtSeg,,82h,,>
     
;显示陷阱处理程序代码段描述符及选择子
    EchoCodeSel=$-gdt
    EchoCode    Desc <EchoCodeLen-1,EchoCodeSeg,,98h,,>
     
     GdtNum=($-effgdt)/(size Desc)
     GdtLen  =$-gdt    
GdtSeg   ends
;----------------------------
;中断描述符表IDT
IdtSeg  segment 
idt  LABEL  BYTE
    REPT 254 
       GATE < >
    ENDM
;0FEh号陷阱门描述符(字符串输出)
INTFE  GATE  <EchoBegin,EchoCodeSel,,8fH,>
       GATE  < >
IdtLen=$-idt
IdtSeg  ends
;------------------------------------------------------
;主任务的局部描述符表段
SysLdtSeg   segment para  use16
syldt   LABEL BYTE
;主任务数据段描述符及选择子
     SysDataSel=$-syldt+TIL
     SysData    Desc <0ffffh,SysDataSeg,,92H,,>
     
主任务堆栈段的描述符及选择子
     SysStack0Sel=$-syldt+TIL
     SysStack   Desc <SysStack0Len-1,SysStack0Seg,,93h,,>

;主任务TSS段作为数据段的描述符及选择子
     ToSysTssSel=$-syldt+TIL
     ToSysTss   Desc    <SysTssLen-1,SysTssSeg,,92h,,>
SysLdtNum=($-syldt)/(size Desc)
SysLdtLen=$
SysLdtSeg    ends
;--------------------------------
;TaskA的局部描述符表段
TaskALdtSeg   segment para  use16
taldt   LABEL BYTE
     TaskACodeSel=$-taldt+TIL
     TaskACode  Desc <TaskACodeLen-1,TaskACodeSeg,,98h,,>
     
     TaskADataSel=$-taldt+TIL
     TaskAData    Desc <0ffffh,TaskADataSeg,,92H,,>
     
     TaskAStack0Sel=$-taldt+TIL
     TaskAStack   Desc <TaskAStack0Len-1,TaskAStack0Seg,,93h,,>

TaskALdtNum=($-taldt)/(size Desc)
TaskALdtLen=$
TaskALdtSeg    ends
;----------------------------------------- 
;TaskB的局部描述符表段
TaskBLdtSeg   segment para  use16
tbldt   LABEL BYTE
     TaskBCodeSel=$-tbldt+TIL
     TaskBCode  Desc <TaskBCodeLen-1,TaskBCodeSeg,,98h,,>
     
     TaskBDataSel=$-tbldt+TIL
     TaskBData    Desc <0ffffh,TaskBDataSeg,,92H,,>
     
     TaskBStack0Sel=$-tbldt+TIL
     TaskBStack   Desc <TaskBStack0Len-1,TaskBStack0Seg,,93h,,>

TaskBLdtNum=($-tbldt)/(size Desc)
TaskBLdtLen=$
TaskBLdtSeg    ends
;-----------------------------------------    
;0FEH号中断处理程序(显示程序)的代码段
EchoCodeSeg     SEGMENT PARA USE16
                ASSUME  CS:EchoCodeSeg
;ds:si指向显示字符串,es:di指向显示缓冲区                
EchoBegin:  pushad
            cld
            mov  ah,7
            mov  al,20h
            mov  cx,80
            push di
            rep  stosw     ;清所在显示行
            pop  di
Echo1:      lodsb
            or   al,al
            jz   Echo2
            stosw          ;显示指定字符串
            jmp  Echo1      
Echo2:      popad
            iretd

EchoCodeLen=$
EchoCodeSeg     ENDS
;---------------------------------------------------------
;TaskA的TSS段
TaskATssSeg segment para use16
              DD        0                   ; trlink。
              DD        ?                   ; esp0。
              DW        ?,0                 ; ss0。
              DD        ?                   ; esp1。
              DW        ?,0                 ; ss1。
              DD        ?                   ; esp2。
              DW        ?,0                 ; ss2。
              DD        0                   ; cr3。
              DW        taska,0             ; eip。          *入口地址
              DD        0                   ; psw。
              DD        0                   ; eax。
              DD        0                   ; ecx。
              DD        0                   ; edx。
              DD        0                   ; ebx。
              DW        TaskAStack0Len,0    ; esp。
              DD        0                   ; ebp。
              DD        0                   ; esi。
              DD        0                   ; edi。
              DW        NormalSel,0         ; es。
              DW        TaskACodeSel,0      ; cs。
              DW        TaskAStack0Sel,0    ; ss。
              DW        NormalSel,0         ; ds。
              DW        NormalSel,0         ; fs。
              DW        NormalSel,0         ; gs。
              DW        TaskALdtSel,0       ; ldt。
              DW        0
              DW        $+2                 ;指向I/0许可位图
              DB        0FFH                ;I/O许可位图结束标志
TaskATssLen=$
TaskATssSeg ends
;-------------------------------------------------------
;TaskA的堆栈段
TaskAStack0Seg   SEGMENT PARA USE16               ;0级堆栈
TaskAStack0Len=1024
                    DB      TaskAStack0Len  DUP(0)
TaskAStack0Seg   ENDS
;----------------
;TaskA的数据段
TaskADataSeg segment para use16
hiapm    db    '          Now it has entered TaskA!    ',0
TaskADataSeg ends
;------------------
;TaskA的代码段
TaskACodeSeg segment para use16
             assume  cs:TaskACodeSeg,ds:TaskADataSeg
taska:
          pushad
          push ds
          push es
          push fs
          push gs
          mov ax,VideoSel
          mov es,ax
          mov ax,TaskADataSel
          mov ds,ax
          lea si,hiapm                      ;进入TaskA  
          mov di,160*7    
          INT 0FEh
         
	        mov	al,0ffh
          mov   dx,0c400h
	        out	dx,al
	        mov	ah,01
	        mov	cx,0008h
agn1:     mov   dx,0c410h
	        mov	al,ah
	        out	dx,al                     ;红行亮
	        push	cx
          mov   cx,00fffh
d5:	      call	delay1
          loop    d5
          pop     cx
          shl     ah,01
          loop    agn1

          mov  dx,0c40bh
          mov  al,89h
          out  dx,al
          mov  dx,0c40ah
          in   al,dx
          test al,08h
          jne   returna              ;K3=1返回SysCodeSeg
          jmp  taska
returna:  pop gs
          pop fs
          pop es
          pop ds
          popad
          JUMP16 SysTssSel,0
          jmp  taska
          
delay1 proc                                 ;延迟
	        push	cx
	        mov	cx,0ffffh
ccc:	    loop	ccc
	        pop	cx
	        ret
delay1  endp 
TaskACodeLen=$
TaskACodeSeg ends 
;-----------------------------------------------------------
;TaskB的TSS段
TaskBTssSeg segment para use16
              DD        0                   ; trlink。
              DD        ?                   ; esp0。
              DW        ?,0                 ; ss0。
              DD        ?                   ; esp1。
              DW        ?,0                 ; ss1。
              DD        ?                   ; esp2。
              DW        ?,0                 ; ss2。
              DD        0                   ; cr3。
              DW        taskb,0             ; eip。          *入口地址
              DD        0                   ; psw。
              DD        0                   ; eax。
              DD        0                   ; ecx。
              DD        0                   ; edx。
              DD        0                   ; ebx。
              DW        TaskBStack0Len,0    ; esp。
              DD        0                   ; ebp。
              DD        0                   ; esi。
              DD        0                   ; edi。
              DW        NormalSel,0         ; es。
              DW        TaskBCodeSel,0      ; cs。
              DW        TaskBStack0Sel,0    ; ss。
              DW        NormalSel,0         ; ds。
              DW        NormalSel,0         ; fs。
              DW        NormalSel,0         ; gs。
              DW        TaskBLdtSel,0       ; ldt。
              DW        0
              DW        $+2                 ;指向I/0许可位图
              DB        0FFH                ;I/O许可位图结束标志
TaskBTssLen=$
TaskBTssSeg ends
;-------------------------------------------------------
;TaskB的堆栈段
TaskBStack0Seg   SEGMENT PARA USE16               ;0级堆栈
TaskBStack0Len=1024
                    DB      TaskBStack0Len  DUP(0)
TaskBStack0Seg   ENDS
;----------------
;TaskB的数据段
TaskBDataSeg segment para use16
led      db   3fh,06h,5bh,4fh,66h,6dh,7dh,07h,7fh,6fh ;段码
buffer1  db   0,0         ;存放要显示的十位和个位
bz       dw   ?           ;位码

hibpm    db    '          Now it has entered TaskB!    ',0
TaskBDataSeg ends
;------------------------
;TaskB的代码段
TaskBCodeSeg segment para use16
             assume  cs:TaskBCodeSeg,ds:TaskBDataSeg
taskb:        pushad
              push ds
              push es
              push fs
              push gs
              mov ax,VideoSel
              mov es,ax
              mov ax,TaskBDataSel
              mov ds,ax
              lea si,hibpm                      ;进入TaskA  
              mov di,160*9    
              INT 0FEh
         
	            mov dx,0c40bh               ;设置8255控制字
              mov al,89h
              out dx,al
dispnum:
              mov di,offset buffer1        ;设di为显示缓冲区
loop1:        mov cx,0300h                 ;循环次数
loop2:        mov bh,02
lll:          mov byte ptr bz,bh
	            push di
	            dec di
	            add di, bz
	            mov bl,[di]                  ;bl为要显示的数
	            pop di
	            mov bh,0
	            mov si,offset led            ;置led数码表偏移地址为SI
              add si,bx                    ;求出对应的led数码

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -