彙編語言十二

assume cs:code,ss:stack

stack segment
    db 128 dup (0)
stack ends

code segment
start:
    mov ax,cs                        ;開始安裝 0 號中斷的中斷處理程序
    mov ds,ax                        ;所謂的安裝, 就是將do0子程序代碼複製到一段內存區域, 這段內存區域是徹底安全的
    mov si,offset do0                ;設置 ds:si 指向要複製的子程序的起始地址
    mov ax,0
    mov es,ax
    mov di,200h                     ;設置 es:di 指向該中斷處理程序在內存中的起始地址
    mov cx,offset do0end-offset do0 ;計算要複製的中斷處理程序有多長
    cld                             ;設置複製方向爲正
    rep movsb                       ;進行代碼的賦值

    mov word ptr es:[0*4],200h      ;將中斷處理程序的首地址註冊在中斷向量表的對應表項中, 將中斷例程安裝在 0:200h 是由編程人員決定的
    mov word ptr es:[0*4+2],0


    mov dx,152                      ;一個檢測程序
    mov ax,0
    mov cx,2
    div cx                          ;執行後, 發生除法溢出, 從而進行中斷相關的工做

# 要注意的是下面的中斷處理程序在本程序執行的時候並不會執行
# 只有在發生中斷的時候纔會執行, 而且執行的也不是這段代碼
# 而是執行已經通過上面的代碼複製到 0:200h 處的中斷處理程序
# 因此下面的這一片只是爲了複製而用的

do0:jmp short do0start               ;由於下一段代碼只是數據的定義, 不是 CPU 可以識別的指令, 因此須要跳過
    db 'divide error!'
do0start:    
    mov ax,cs                        ;由於 do0 已經被安裝到了 0:200h 處, 因此 cs 中的值應爲 0 
    mov ds,ax
    mov si,202h                      ;由於 do0 標號處的指令佔有 2 字節, 因此 ds:[202h] 指向字符串的開始位置 
    
    mov ax,0b800                    
    mov es,ax
    mov di,160*12+34*2               ;設置字符串要顯示的目的地址(顯示緩衝區的一段空間)
    
    mov cx,13                        ;循環 13 次
  dnext:
    mov al,[si]
    mov es:[di],al                   ;移動字符自己
    mov es:[di+1],81h                ;設置第二個字節, 即字符顯示的顏色
    inc si                           ;源字符的偏移量一次增長一個字節
    add di,2                         ;目的字符的偏移量一次增長兩個字節, 由於還有一個顏色屬性字節
    loop dnext

    mov ah,4c                        ;返回 DOS
    int 21h
do0end:nop
code ends
end start
相關文章
相關標籤/搜索