学习汇编已有两三月了,后面的东西已是渐渐看着比较吃力,花了点时间将书中的第十五章的实例进行了细致解读,并注释了一下,达到一目了然的效果,一来:为自己存一份,免得哪时又忘了!二来:可以为不懂的童鞋一个借鉴。

 

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   ;设置栈

         mov ax,data

         mov ds,ax

         mov ax,0

         mov es,ax

     ;-------将原int 9例程进行保存-----------

         push es:[9*4]    ;将原int 9中断例程地址的偏移地址压栈

         pop ds:[0]       ;将中断例程地址的偏移地址放入data段中

         push es:[9*4+2]  ;将原int 9中断例程地址的偏移地址入栈

         pop ds:[2]       ;将中断例程地址的段地址放入data段中

    ;-------在中断向量表中设置新的中断例程入口地址---------

         mov word ptr es:[9*4],offset int9

         mov es:[9*4+2],cs  ;在中断向量表中设置新的int 9中断例程的入口地址

     ;--------将a-z字母显示到屏幕中-------------

         mov ax,0b800h

         mov es,ax

         mov ah,'a'

       s:mov es:[160*12+80],ah

         call delay    ;进行循环100000h次,用于查看字符

         inc ah

         cmp ah,'z'

         jna s

    ;--------将原中断向量表复原--------------

         mov ax,0

         mov es,ax

         push ds:[0]

         pop es:[9*4]

         push ds:[2]

         pop es:[9*4+2]  ;将中断向量表中int 9中断例程的入口恢复为原来的地址

          

         mov ax,4c00h

         int 21h

   ;------将循环100000h次,以拖延程序的执行时间-----------

      delay: push ax  ;做程序的延迟,其中有人对为什么执行了1000000h次存在疑惑,详见附录

             push dx

             mov dx,1000h

             mov ax,0

         s1: sub ax,1

             sbb dx,0

             cmp ax,0

             jne s1

             cmp dx,0

             jne s1

             pop dx

             pop ax

             ret

  ;-------以下为新的int 9中断例程--------

         int9: push ax

               push bx

               push es   ;将要用到的寄存器先进行压栈

               

               in al,60h  ;取得键盘端口的数据


                pushf       ;将状态寄存器压栈

                pushf

                pop bx

                and bh,11111100b

                push bx           

                popf              ;将TF和IF置为0     

 call dword ptr ds:[0] ;对int指令进行模拟,调用原来的int9中断例程,实现检测输入按键的处理

                cmp al,1          ;检验是否为esc键

                jne int9ret       ;如果不是esc键,则返回,如果不是,则进行下一步操作!


                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



  附录:其中有人对为什么执行了1000000h次存在疑惑,我这;;儿大致讲解一下,因为ax为0,而执行sub ax,1后,ax就成了FFFFh了,所以等到ax再次为1的时候,它被执行了10000h次了,而s1程序实际是在执行两个循环,一个外一个内,刚才那是内循环执行了10000h次,外循环又执行了10h次,所以它们总共就执行了1000000h次。