WEB开发网
开发学院软件开发汇编语言 汇编源码系列之dskwatch 阅读

汇编源码系列之dskwatch

 2008-04-29 09:33:41 来源:WEB开发网   
核心提示:这个都是过去DOS时代的汇编源码,虽然已经过去了,汇编源码系列之dskwatch,但是对于学习汇编还是有帮助的,汇编语言只是程序员一门基础语言

这个都是过去DOS时代的汇编源码,虽然已经过去了,但是对于学习汇编还是有帮助的,汇编语言只是程序员一门基础语言,大多人掌握即可,不一定要深入研究.......

; By Steve Holzner (from June 11, 1985 issue of PC Magazine)
interrupts  segment at 0h  ; This is where the disk interrupt
  org  13h*4    ; holds the address of its service routine
disk_int  label  dword
interrupts  ends
screen  segment at 0B000h  ; A dummy segment to use as the Extra
screen  ends      ; Segment so we can write to the display
code_seg  segment
  assume  cs:code_seg
  org  0100h    ; ORG = 100h to make this a .COM file
first:  jmp  load_watch  ; First time through jump to initialize routine
  msg_part_1  db  'Disk error: '  ; Here are the error messages
  msg_part_2  db  'No response Failed Seek NEC Error  '
      db  'Bad CRC SeenDMA Overrun Impos Sector'
      db  'No Addr MarkW. ProtectedErr Unknown '
  first_position  dw  ?    ; Position of 1st char on screen
  flags    dw  ?
  screen_seg_offset dw  0    ; 0 for mono, 8000h for graphics
  old_disk_int  dd  ?    ; Location of old disk interrupt
  ret_addr  label dword    ; Used in fooling around with
  ret_addr_word  dw 2 dup(?)    ;  the stack
disk_watch  proc  far  ; The disk interrupt will now come here
  assume  cs:code_seg
  pushf      ; First, call old disk interrupt
  call  old_disk_int
  pushf      ; Save the flags in memory location "FLAGS"
  pop  flags    ; (cunning name)
  jc  error    ; If there was an error, carry flag will have
  jmp  fin    ; been set by Disk Interrupt
error:  push  ax    ; AH has the status of the error
  push  cx    ; Push all used registers for politeness
  push  dx
  push  di
  push  si
  push  es
  lea  si,msg_part_1  ; Always print "Disk Error: " part.
  assume  es:screen  ; Use screen as extra segment
  mov  dx,screen
  mov  es,dx
  mov  di,screen_seg_offset  ; DI will be pointer to screen position
  add  di,first_position  ; Add to point to desired area on screen
  call  write_to_screen    ; This writes 12 chars from [SI] to [DI]
  mov  dx,80h      ; Initialize for later comparisons
  mov  cx,7      ; Loop seven times
e_loop:  cmp  ah,dh      ; Are error code and DH the same?
  je  e_found      ; If yes, Error has been found
  add  si,12      ; Point to next error message
  shr  dh,1      ; Divide DH by 2
  loop  e_loop      ; Keep going until matched DH = 0
  cmp  ah,3      ; Error code no even number; 3 perhaps?
  je  e_found      ; If yes, have found the error
  add  si,12      ; Err unknown; unknown error returned
e_found:call  write_to_screen    ; Write the error message to the screen
  pop  es    ; Restore the registers
  pop  si
  pop  di
  pop  dx
  pop  cx
  pop  ax
fin:  pop  ret_addr_word    ; Fooling with the stack. We want to
  pop  ret_addr_word[2]  ; preserve the flags but the old flags
  add  sp,2      ; are still on the stack. First remove
  push  flags      ; return address, then flags. Fill flags
  popf        ; from "FLAGS", return to correct addr.
  jmp  ret_addr
disk_watch  endp
write_to_screen  proc  near  ; Puts 12 characters on screen
  mov  cx,12    ; Loop 12 times
w_loop:  movs  es:byte ptr[di],cs:[si] ; Move to the screen
  mov  al,7    ; Move screen attribute into screen buffer
  mov  es:[di],al
  inc  di    ; Point to next byte in screen buffer
  loop  w_loop    ; Keep going until done
  ret
write_to_screen  endp
load_watch  proc  near  ; This procedure initializes everything
  assume  ds:interrupts  ; The data segment will be the interrupt area
  mov  ax,interrupts
  mov  ds,ax
  mov  ax,disk_int  ; Get the old interrupt service routine
  mov  old_disk_int,ax  ; address and put it into our location
  mov  ax,disk_int[2]  ; OLD_DISK_INT so we can call it.
  mov  old_disk_int[2],ax
  mov  disk_int,offset disk_watch ; Now load the address of DskWatch
  mov  disk_int[2],cs    ; routine into the disk interrupt
  mov  ah,15    ; Ask for service 15 of INT 10h
  int  10h    ; This tells us how display is set up
  sub  ah,25    ; Move to twenty five places before edge
  shl  ah,1    ; Mult. by two (char & attribute bytes)
  mov  byte ptr first_position,ah  ; Set screen cursor
  test  al,4    ; Is it a monochrome display?
  jnz  exit    ; Yes - jump out
  mov  screen_seg_offset,8000h  ; No, set up for graphics display
exit:  mov  dx,offset load_watch  ; Set up everything but this program to
  int  27h      ; stay and attach itself to DOS
load_watch  endp
  code_seg  ends
  end  first  ; END "FIRST" so 8088 will go to FIRST first.


Tags:汇编 源码 系列

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接