王爽--アセンブリ言語課程設計2いくつかの問題記録


全体プログラムは、19番割り込みルーチンを書き換えることによって実現される.19番割り込みルーチンで異なるサブルーチンを呼び出し、異なる機能を実現する.
1.時間を動的に表示するサブルーチン
cmos中の時間情報をループ読み出して動的表示時間を実現する.また、表示中には、F 1キーとescキーの動作も実現される.ただし,16 h番割り込みで対応するキーを取得し,対応する動作を行うことはできない.時間を動的に表示するには、cmosの時間をループして読み込む必要があります.ループに読み取りキーボード入力を入れた16 h割り込みは、キーボード入力バッファが空の場合、16 h割り込みはブロックされ、ダイナミック表示の効果は得られません.したがって,9番割り込み応答キーボード割り込みによりキーボード入力を処理する.9番割り込み処理プログラムを書き換え、F 1とESCキーを押したときの動作を定義します.
このサブルーチンでは、9番割り込みを書き換えるには、ハードウェアに関連する問題を呼び出す必要があるため、元の9番割り込みのエントリアドレスを保存することに注意します.上記表示時間の部分には、予め設定されたbhを用いて表示の色属性値、blを用いて文字のASCIIコードを格納し、bh値を変更すれば時間表示の色を変更することができる.そこで9番割り込みでF 1キーを押したと判断したらbhを直接修正します.9番割り込みがcmosサイクル読み出し時間に戻って表示されるプログラムセグメントに戻ると、bh値が新しくなり、表示の色も変わりました.escキーでは,まずescを押下した後に無限ループ読み出しを飛び出して時間を表示するプログラムセグメントを実現する.どうやって飛び出しますか?9番割り込み中なので、最後にIRETを使って引き返します.返されるアドレスは、割り込み処理がスタックに格納されているCS:IPが指すアドレスである.したがって、スタック内でCS:IPを変更することによって、IRETが所望のアドレスに戻ることを実現することができる.私たちが望むアドレスは,ループ表示時間のプログラムセグメントの下のアドレスshowover(表示終了)である.CS部分はIPを修正するだけで修正する必要はありません.したがって,このサブルーチンにはescジャンプの宛先IPも予め保存しておく.ESCの処理には、元の処理プログラムアドレスを9番で中断する復元も含まれる.サブルーチンの準備が完了します.
2つのバグ:
(1)時間をループ表示する場合,表示する文字と画面上に表示する位置をsiとdiでそれぞれ位置決めする.ループが始まる前に2つの値を初期化しました.loopループでは、この2つの値が変更されます.したがって、次回のリフレッシュ時間には、2つの値を再初期化する必要があります.これにより、同じ位置に表示され、表示内容が正しいことが保証されます.以前はsiとdiの値を表示するたびにスタックを使用して保存し、一度の表示が終了した後、popでsiとdiの初期値を復元し、次回のループ表示を実行していました.ここでの問題は,escキーボードの割り込みが発生した場合,スタックのpushとpop操作がペアで発生することを保証できず,エラーを招くことである.たとえば、表示時間のプログラムセグメントが表示月まで実行されたばかりで、スタックにはsiとdiを初期化するための値が保存されています.ESCを押すと、キーボード割り込みが発生し、フラグレジスタ、CS、IPが保存され、9番キーボード割り込みに入ります.我々が定義したESCキーボード割り込み処理は,割り込みが返されたアドレスを直接修正し,元の保存したアドレスには戻らない.showoverに戻ったとき、問題が発生しました.showoverは主にいくつかのレジスタの復元とサブプログラムの戻りをします.しかし、以前に押し込まれたsiとdiはスタックにあり、必然的にエラーを引き起こす.この問題は、BH値を変更しただけで、割り込み時のアドレスで表示時間を継続するプログラムセグメントを返すため、F 1キーボード割り込みには存在しない.
この中には実はウィンドウの問題があります.ESC割り込みについては,最後のpopが終了して次のループ表示の準備が完了した場合にもプログラムにエラーは発生しない.しかし、この確率はかなり小さく、エラーを起こさないウィンドウは小さすぎます.
(2)新たな9番割り込みは,元の19 H割り込みで発生して処理される.最初に発生した19 h割込みはIFを0にし、すなわち19 h割込み中に他のシールド可能割込みの発生を許さない.ほとんどの割り込みは遮断可能な割り込みであり、9番の割り込みはそのうちの1つである.したがって,9番割り込みを機能させるには,このサイクル表示時間のサブプログラムでIFを1にし,ESCを押した後にshowoverにジャンプしてサブプログラム準備を終了する必要がある.このときIFを0にリセットする.
19 h割り込みハンドラインストールコード:
assume cs:code
code segment
    start:mov ax,0
          mov es,ax
          mov di,200h

          mov ax,cs
          mov ds,ax
          mov si,offset int19
          mov cx,offset int19_e - offset int19

          mov ax,offset rst - offset int19
          add ax,200h
          mov [si+2],ax
          mov ax,offset stt - offset int19
          add ax,200h
          mov [si+4],ax

          mov ax,offset showt - offset int19
          add ax,200h
          mov [si+6],ax
          mov ax,offset sett - offset int19
          add ax,200h
          mov [si+8],ax

          cld
          rep movsb

          cli
          mov word ptr es:[19h*4],200h
          mov word ptr es:[19h*4+2],0
          sti

          mov ax,4c00h
          int 21h

    int19:jmp short s
       dw 0,0,0,0   ;       
       dw 0,0ffffh  ;             
       dw 7c00h,0   ;           
        s:push bx
          push ds

          mov bl,ah
          mov bh,0
          add bx,bx

          mov ax,cs
          mov ds,ax
          call word ptr [bx+202h]

          pop ds
          pop bx
          iret

      rst:jmp dword ptr ds:[20ah]
          ret
      stt:mov ax,0
          mov es,ax
          mov bx,7c00h
          mov al,1
          mov ch,0
          mov cl,1
          mov dh,0
          mov dl,80h
          mov ah,2
          int 13h
          jmp dword ptr ds:[20eh]
          ret

    showt:jmp short showst
          db 9,8,7,4,2,0
          db '// ::',0
          dw  0,0       ;    9                
          dw  0         ;esc ,        
   showst:push ax       ;             F1  esc      ,        
          push bx       ;    9         。                  
          push cx
          push si
          push di
          push ds
          push es

          mov ax,cs  ;cs=0
          mov ds,ax  ;ds=0
          mov ax,0b800h
          mov es,ax
          mov bh,42h
          mov di,720h
          mov si,offset showt- offset int19
          add si,202h

          mov ax,si
          add ax,12
          mov bp,ax    ;bp       9          

          push ds:[36]    ;    9            
          pop ds:[bp]
          push ds:[38]
          pop ds:[bp+2]

          push cs     ;    9         
          pop ds:[38]
          mov ax,offset int9 - offset int19
          add ax,200h
          mov ds:[36],ax

          mov ax,offset showover - offset int19
          add ax,200h
          mov ds:[bp+4],ax        ;  esc        

          pushf            ;  IF  ,      19h   ,if=0,          
          pop ax
          or ax,0200h
          push ax
          popf

 refresht:mov si,bp    ;     ,    F1 ,   ,                    。
          sub si,12
          mov di,720h    ;   esc             。             iret       IP
          mov cx,6  ;             ,           push si push di    
      lpt:mov al,[si] ;       esc  ,        showover   。         si di  
          out 70h,al ;  ,                。       ,         int19     
          in al,71h  ;    ,  push pop        。    :       si di。
          push ax
          push cx
          mov cl,4
          shr al,cl
          pop cx
          add al,30h
          mov bl,al
          mov es:[di],bx
          pop ax
          and al,0fh
          add al,30h
          mov bl,al
          mov es:[di+2],bx

          mov bl,[si+6]
          mov es:[di+4],bx

          inc si
          add di,6
          loop lpt
          jmp short refresht

 showover:pushf         ;        ,    IF
          pop ax
          and ax,0fdffh
          push ax
          popf
          pop es
          pop ds
          pop di
          pop si
          pop cx
          pop bx
          pop ax

          ret

    int9:push ax
         push bp
         in al,60h

         pushf
         call dword ptr ds:[bp]

         cmp al,3bh  ;F1 
         je sf1
         cmp al,1    ;esc 
         je sesc
         jmp short int9ok
     sf1:inc bh
         jmp short int9ok
    sesc:push ds:[bp]
         push ds:[bp+2]
         pop ds:[38]
         pop ds:[36]

         mov ax,ds:[bp+4]

         mov bp,sp
         mov [bp+4],ax
  int9ok:pop bp
         pop ax
         iret

     sett:ret

  int19_e:nop

code ends
end start

メインプログラム:
assume cs:code,ds:data,ss:stack
data segment
   table dw hint,reset,boot,clock,set_c
   hint db 'pls select the program you want to run','$'
   reset db 'reset pc ------- 0','$'
   boot  db 'start system ----1','$'
   clock db 'clock -----------2','$'
   set_c db 'set clock -------3','$'
data ends
stack segment
     dw 64 dup (0)
stack ends
code segment
    start:mov ax,stack
          mov ss,ax
          mov sp,128

          mov ax,data
          mov ds,ax

          mov ax,0b800h
          mov es,ax

          mov bh,0
          mov dh,6
          mov dl,16
          mov cx,5
          mov bp,0

        s:push dx
          mov ah,2  ;   
          int 10h

          mov dx,table[bp]  ;     
          mov ah,9
          int 21h

          pop dx
          inc dh
          add bp,2
          loop s

          mov ah,2
          int 10h   ;   ,    

          push dx   ;                dx,    ,     
          mov al,160
          mul dh
          mov dh,0
          add dx,dx
          add ax,dx
          mov di,ax
          pop dx

    getch:mov ah,0
          int 16h
          cmp ah,0bh
          je rst
          cmp ah,2
          je stt
          cmp ah,3
          je showt
          cmp ah,4
          je sett
          jmp short getch
      rst:mov ah,0
          jmp short ok
      stt:mov ah,1
          jmp short ok
    showt:mov ah,2
          jmp short ok
     sett:mov ah,3
       ok:push ax
          mov ah,42h
          mov es:[di],ax
      e_b:mov ah,0
          int 16h
          cmp ah,1ch  ;  
          je int19
          cmp ah,0eh  ;  
          jne short e_b
          mov ah,2
          int 10h
          mov al,0
          mov ah,01110111b
          mov es:[di],ax
          pop ax
          jmp short getch

    int19:pop ax
          int 19h

          mov ax,4c00h
          int 21h
code ends
end start