用汇编编写DOS下的内存驻留程序(5)

 

转自:http://www.x86asm.com/DisplayArticle.asp?BoardID=5&ArticleID=14

 

 五 键盘输入扩充程序
 有了前一节的基本驻留程序为基础,就可以建立起不同的应用程序.接下来,就写一个驻留程序,把用户敲入的字符,用一系列的字符来取代.这样可以减少用户的击键次数.
 首先,先复习一下前一节的驻留程序的格式,如下所示:
     cseg segment
      assume cs:cseg,ds:cseg
      org  100h
     start:
      jmp Initialize
     Old_Keyboard_IO dd ?
           ;Section 1
     new_keyboard_io proc far
      sti    
           ;Section 2
      pushf
      assume ds:nothing
      call  Old_Keyboard_IO
      nop
      iret
     new_keyboard_io endp
           ;Section 3
     Initialize:
      assume cs:cseg,ds:cseg
      mov bx,cs
      mov ds,bx
      mov al,16h
      mov ah,35h
      int 21h
      mov word ptr Old_Keyboard_IO,bx
      mov word ptr Old_Keyboard_IO[2],es
           ;End Section 3
      mov dx,offset new_keyboard_io
      mov al,16h
      mov ah,25h
      int 21h
      mov dx,offset Initialize
      int 27h
     cseg ends
      end start
 只要New_keyboard_IO这个程序,就可以把以上的程序变成许多不同的键盘应用程序.在开始设计之前,必须解决一些问题.
 首先,必须决定哪些键可以用来加以扩充.如果把一般的英文字母或是数目字做为扩充字符的话可能会出现一些问题.如果是对控制字符做扩充,应该不会有什么问题,但是DOS把某些控制字符视为特殊的功能.譬如Control_H,IBM PC本身有一组自己独有和增加字符(extended character),譬如:功能键(F1到F10),以及ALT键和其它组合所产生的字符等.这些增加字符通常都是使用在文书编辑程序中,这些字符比较适合用来作为扩充字符用.这组字符是由两个码组成,前面一个码永远是0,因此DOS可以很容易加以分辨.而且使用这些字符作为扩充字符对DOS的使用也不会产生太大的影响.下面是扩充字符组的第二个码大小:
 1    2 Paoudo_NULL 3    4    5
 6    7    8    9    10
 11    12    13    14    15        Shift_Tab 16 Alt_Q   17 Alt_W   18 Alt_E   19 Alt_R   20 Alt_T   21 Alt_Y   22 Alt_U   23 Alt_I   24 Alt_O   25 Alt_P   26    27    28    29    30 Alt_A
 31 Alt_S   32 Alt_D   33 Alt_F   34 Alt_G   35 Alt_H
 36 Alt_J   37 Alt_K   38 Alt_L   39    40
 41    42    43    44 Alt_Z   45 Alt_X
 46 Alt_C   47 Alt_V   48    49    50
 51    52    53    54    55
 56    57    58    59 F1   60 F2
 61 F3   62 F4   63 F5   64 F6   65 F7
 66 F8   67 F9   68 F10   69    70
 71 HOME   72 UpArrow  73 PgUp   74    75 LeftArrow
 76    77 RightArrow  78    79 End   80 DownArrow
 81 PgDn   82 Insert  83 Delete  84 Shift_F1  85 Shift_F2
 86 Shift_F3  87 Shift_F4  88 Shift_F5  89 Shift_F6  90 Shift_F7
 91 Shift_F8  92 Shift_F9  93 Shift_F10  94 Control_F1  95 Control_F2
 96 Control_F3  97 Control_F4  98 Control_F5  99 Control_F6  100 Control_F7
 101 Control_F8  102 Control_F9  103 Control_F10  104 Alt_F1  105 Alt_F2
 106 Alt_F3  107 Alt_F4  108 Alt_F5  109 Alt_F6  110 Alt_F7
 111 Alt_F8  112 Alt_F9  113 Alt_F10  114 Control_PrtSc 115   Control_LArrow
 116 Control_RArrow 117 Control_End  118 Control_PgDn 119 Control_Home 120 Alt_1
 121 Alt_2   122 Alt_3   123 Alt_4   124 Alt_5   125 Alt_6
 126 Alt_7   127 Alt_8   128 Alt_9   129 Alt_0   130 Alt_Hyphan
 131 Alt_Space  132 Control_PgUp
 接下来,需要决定把扩充字符扩充成什么样的字符串.譬如,所扩充的字符串以什么作结尾?有一个可能的选择是:回车键(Carriage Return,ASCII码0DH).这种选择很合乎逻辑,因为一般的指令都能是以回车键做结尾.但是,如果选择回车键名做扩充字符串的结尾,那么就很难表示许多行的扩充字符串.另外一个选择是使用$作为扩充字符串的结尾.但是,因为有些DOS的系统调用使用$作为字符结尾;因此如果采用$时,那么扩充字符串中就不能有$出现.
 C语言中都是采用ASCII码的0做为字符串的结尾,这种形式的字符串称为ASCII字符串(ASCII零结尾).使用ASCII字符串格式,就可以表示所有的可见字符和不可见字符,因为从键盘不可能输入ASCII码为0的字符.
 下面的例子中,把F1这个键(扩充码59)定义为DIR指令.也可以把F1定义成以下的指令:
     MASM MACRO;
     LINK  MACRO;
     EXE2BIN MACRO.EXE MACRO.COM;
 上面的指令中,每一行都是以回车键作结尾的.
 最后要做的是,解决将扩充的字符返回给DOS的问题.通常每当在键盘敲入一个键时,DOS就会从键盘输入队列取得一个字符.因此必须设法欺骗DOS,让它接受一连串的字符.
 DOS借检查键盘的状态来判断,是否有字符输入,ROM BIOS上的键盘输入功能在没有输入字符时就把ZF(Zero Flag)设定为1,否则就把ZF设定为0.如果可以控制这个功能,反复地欺骗DOS目前有字符要输入,然后把预的字符串传回给DOS,那么就可以让DOS接受任何数量的字符.
5.1 基本的扩充程序
 可以把上面的空的New_Keyboard_IO程序,改用以下的程序来代替.
 New_Keyboard_IO  proc far
  sti
  cmp ah,0    ;A read request?
  je ksread
  cmp ah,1    ;A status request?
  je ksstat
  assume ds:nothing   ;Let original routine
  jmp Old_Keyboard_IO   ;Do remaining subfunction
 ksRead:
  call keyRead    ;Get next char to return
  iret
 ksstat:
  call keyStat    ;GetStatus
  ret 2    ;It's important!!
 New_Keyboard_IO  endp
 上面的New_Keyboard_IO程序中,把0H(读取字符)和1H(取得键盘状态)这两项功能自行处理.这个程序很简单,但是其中有一个关键点.当我们处理取得键盘状态的功能时,因为原先的键盘中断处理程序是利用ZF返回键盘状态,因此程序包中也必须保有这种特性,如果使用IRET返回的话,那么设定好ZF就会因为CPU状态标志从堆栈中取出,而恢复成未中断前的状态.
 为了解决这个问题可以使用RET的参数来设置.这个参数是用来指示从堆栈中取出多少个字节.通常这是用在高级语言的子程序返回时,用来从堆栈中除去一些参数或是变数.在这里我们希望用来移去原先中断时堆栈的CPU状态,这样才有办法把改变的ZF传回,因此在这里使用了RET 2这个指令.
 上面的程序码中调用到Keyread和KeyStat这两个子程序,其内容如下所示:
  assume ds:nothing
  ;If expansion is in progress,return a fake status
  ;of ZF=0,indicatin gthat a character is ready to be
  ;read,If expansion is not in progress,then return
  ;the actual status from the keyboard
 KeyStat  proc
  cmp cs:current,0
  jne FakeStat
  pushf     ;Let original routine
  call Old_Keyboard_IO  ;get keyboard status
  ret
 FakeStat:
  mov bx,1    ;Fake a "char ready"
  cmp bx,0    ;by clearing ZF
 KeyStat  endp
  ;Read a character from the keyboard input queue,
  ;if not expanding or the expansion string.
  ;if expansion is in progress
 KeyRead  proc
  cmp cs:current,0
  jne ExpandChar
 ReadChar:
  mov cs:current,0  ;Slightly peculiar
  pushf     ;Let original routine
  call Old_Keyboard_IO  ;Get keyboard status
  cmp al,0
  je Extended
 ReadDone:
  ret
 Expanded:
  cmp ah,59    ;Is this character to expand?
  jne ReadDone   ;If not,then return it normally
       ;If so,then start expanding
  mov cs:current,offset string
 ExpandChar:
  push si
  mov si,cs:current
  mov al,cs:[si]
  inc cs:current
  pop si
  cmp al,0    ;Is this end of string?
  je ReadChar   ;If so,then read a real char?
  ret
 KeyRead  endp
  ;Pointer to where we are in the expansion string
   current dw 0
  ;String we will return when an F1 is typed
  ;0DH is ASCII carriage return
   string db 'DIR',0dh,0
 上面的程序中,使用了一个指针current,这个指针指向传给DOS的下一个字符.如果current等于0时,就表示扩充字符没了.如果current不等于0,那么current所指的字符就会被传回,除非所指到的字符是ASCII 0,如果current所指到的字符是ASCII 0,那么就必须把current设定成0.
 状态检查程序KeyStat和字符输入程序KeyRead都各有两个部分,一部分是当current等于0,另一部分则是当current等于0.
 如果current等于0,也就是没有扩充字符时,那么状态检查程序就需调用旧的键盘输入程序,来检查目前键盘输入队列的状态.如果current不等于0,ZF就必须设定成0,以表示目前有字符输入.ZF要设定成0或1,可以先执行某一运算让结果为0或非0即可.
 键盘输入程序是整个程序最复杂的部分.这个程序决定了下个送给DOS的字符是什么.如果扩充字符送完时,就调用旧的键盘输入程序取得下一个输入的字符.无论从键盘输入的字符是什么,都必须检查是否是希望扩充的字符.键盘输入程序是把输入的结果放在寄存器AL中.如果输入的字符是增加字符时(如F1),那么AL的内容是0,增加的字符码则放在AH中.
 如果读到的字符是希望扩充的字符F1,那么就必须开始进行扩充工作.这时候就必须把指针current指到扩充字符串的开头.大多数人常犯的一个错误是:使用mov cs:current,string而不是mov cs:current,offset string.这两者的差别在于前者是错误的,因为它的意思是把一个字节的内容移到一个字节之中,汇编器会强迫两者的形式吻合.后者则是正确的,因为 我们希望做的是把式string指向的地址值移到current之中.
 当我们在进行扩充时,就把指针current所指的字节内容移到AL中,只要AL的内容不是0,就不必管AH的内容是什么.如果AL是0的话,就表示已经到了扩充字符的结尾了.这表示不应该传回0,而必须重新调用Old_Keyboard_IO ,以便从键盘取得输入字符.
 在程序包KeyRead中有一行指令比较特殊,你也许注意到了,在进入KeyRead,当确定current为0时,接下来又把current设定成0.这样做虽然有些奇怪,却没有任何伤害;但是对于扩充字符串到达结尾时,却很有用.当我们到达扩充字符串的结尾时,current的内容将指到字符串结尾的下一个位置,而不是0.因此必把current设定为0,可以先跳到某一位置把current设定为0,然后再跳到ReadChar.而采取前面程序的做法时,只是浪费一行毫无伤害的指令,却可以使程序变得简明.
 在这个程序中,每次使用到内存的内容时,都必须牵涉到段值,这一点相当重要.当计算机的控制权转移到我们的程序中时,我们对于DS的内容是不知道的.但是有两件事可以确定:第一,DS的内容对我们的程序几乎没有任何用;第二,DS的内容对于被中断的程序可能很重要.因此我们必须保证每次使用到内存位置时,都是使用目前的段,亦即以目前的CS值为标准.必须要确定:如果使用到任何寄存器的话那么在程序结束前,必须恢复其值.
5.2 多键扩充程序
 上面的程序是把某一个特殊键扩充成一个字符串.如果要把一组特殊键扩充成其个别的扩充字符串,该如何做呢?
 一个比较常见的做法是,修改上面的程序,让它接受被扩充字符以被扩充字符串为参数.譬如,如果这个程序名为MACRO,那么可以在AUTOEXEC.BAT中定义以下的指令:
 ........
 MACRO F1 DIR
 MACRO F2 DIR/W
 MACRO F3 DIR *.ASM
 MACRO F4 DIR *.COM
 MACRO F5 DIR *.EXE
 ........
 这种做法是把MACRO这程序一个个留在内存中,至于每一个所做的扩充字符串则分别定义在AUTOEXEC.BAT中,因此可以AUTOEXEC.BAT以的内容.来改变扩充字符的意思.每当执行AUTOEXEC.BAT的MACRO时,就把一个新的键盘程序和BIOS中的键盘处理程序连结起来.第二次执行MACRO则是在新的键盘处理程序上加上第二层的键盘处理程序,以后依次类推.每一个输入字符都必须经过一层一层的键盘处理程序,以过滤出被扩充字符.
 这种键盘程序一层一层加上去的做法只能使用在希望被扩充字符不多时,因为 每一个希望被扩充字符需要将近一百个字节的驻留程序代码,如果要为128个功能键产生个别的扩充字符时,那么就要耗费13K字节的内存,显然可以采纳别的比较节省内存的方法.
 如果可以在一个小程序中辨认出一个字符,那么也应该可以辨认出一个以上的字符.然后使用所辨认出的字符转换成索引值.再从一个由字符串所组成的表格中,找出所扩充的字符串.
 一个字符串本身占用一个字节,而指到字符串的指针则占用两个字节,如果有128个字符需要扩充时,则总共需要284个字节.另外原先的程序大约需要增加50个字节.因此整个程序的大小就变成大约半K字节.假设每一个扩充字符串占用20个字节,那么128个扩充键就需2.5K字节,这和程序代码的0.5K字节加起来,总共也不过3K字节,还比前一种方法少10K字节.
 上面的单键扩充程序转换成多键扩充程序时,只要修改其中的KeyRead这个程序以及数据区的内容即可.以下就是修改后的内容:
  ;Read a character from the keyboard input queue,
  ;if not expanding or the expansion string.
  ;if expansion is in progress
 KeyRead  proc
  cmp cs:current,0
  jne ExpandChar
 ReadChar:
  mov cs:current,0  ;Slightly peculiar
  pushf     ;Let original routine
  call Old_Keyboard_IO  ;Get keyboard status
  cmp al,0
  je Extended
  jmp ReadDone
 Extended:
  cmp byte ptr cs:[si],0  ;Is this end of table?
  je ReadDone
  cmp ah,cs:[si]
  je StartExpand
  add si,3
  jmp NextExt
 StartExtend:
  push  bx
  add si,1
  mov bx,cs:[si]
  mov cs:current,bx   ;If so,start expanding 
 ExpandChar: 
  mov si,cs:current
  mov al,cs:[si]
  inc cs:current
  cmp al,0    ;Is this end of string?
  je ReadChar   ;If so,then read a real char?
 ReadDone:
  pop si
  ret
 KeyRead  endp 
   current dw 0
   KeyTab db 59
     dw dir_cmd
     db 60
     dw dir_wide
     db 61
     dw dir_asm
     db 62
     dw dir_com
     db 63
     dw dir_exe
     db 50
     dw make_macro
     db 0  ;This must be last in key table
   dir_cmp db 'DIR',0dh,0
   dir_wide db 'DIR/W',0dh,0
   dir_asm db 'DIR *.ASM',0dh,0
   dir_com db 'DIR *.COM',0dh,0
   dir_exe db 'DIR *.EXE',0dh,0
   make_macro db 'MASM MACRO;',0dh,0
     db 'LINK MACRO;',0dh,0
     db 'EXE2BIN MACRO.EXE MACRO.COM',0dh,0
 上面的程序是节省了一点的时间,但是对于和用户界面而言则变得比较不方便,因为把功能键的定义移到汇编语言的程序中.但是可以高法改写这个程序,让它在初次执行时从一个文件装载所定义的字符患上 .这样做并不会改变驻留程序代码的大小,因为装载文件的起始码可以在执行完后抛弃,因此不必占用驻留程序代码的位置.
5.3 单键扩充程序
 以下是单键扩充成命令字符串的程序内容:
 cseg segment
  assume cs:cseg,ds:cseg
  org 100h
 Start:
  jmp Initialize
 Old_Keyboard_IO dd ?
  assume ds:nothing
 New_Keyboard_IO proc far
  sti
  cmp ah,0     ;Is this call a read request?
  je ksRead
  cmp ah,1     ;Is it a status request?
  je ksStat    ;Let original routine
  jmp Old_Keyboard_IO   ;handle remianing subfunction
 ksRead:
  call KeyRead    ;Get next character to return
  iret
 ksStat:
  call KeyStat    ;Return appropriate status
  ret 2     ;Important!!!
 New_Keyboard_IO endp
 KeyRead Proc near
  cmp cs:current,0
  jne ExpandChar
 ReadChar:
  mov cs:current,0   ;Slightly peculiar
  pushf      ;Let original routine
  call Old_Keyboard_IO   ;Determine keyboard status
  cmp al,0
  je Extended
 ReadDone:
  ret
 Extended:
  cmp ah,59     ;Is this character to expand?
  jne ReadDone    ;If not,return it normally
        ;If so,start expanding
  mov cs:current,offset String
 ExpandChar:
  push si
  mov si,cs:current
  mov si,cs:[si]
  inc cs:current
  pop si
  cmp al,0     ;Is this end of string?
  je ReadChar    ;If so,then read a real char?
  ret
 KeyRead endp
 KeyStat proc near
  cmp cs:current,0
  jne FakeStat
  pushf      ;Let original routine
  call Old_Keyboard_IO   ;Determine keyboard
  ret
 FakeStat:
  mov bx,1     ;Fake a "Character ready" by clearing ZF
  cmp bx,0
  ret
 KeyStat  endp
 current  dw 0
 string  db 'masm macro;',0dh
    db 'link macro;',0dh
    db 'exe2bin macro.exe macro.com',0dh,0
 Initialize:
  assume cs:cseg,ds:cseg
  mov bx,cs
  mov ds,bx
  mov al,16h
  mov ah,35h
  int 21h
  mov word ptr Old_Keyboard_IO,bx
  mov word ptr Old_Keyboard_IO,es
  mov dx,offset New_Keyboard_IO
  mov al,16h
  mov ah,25h
  int 21h
  mov dx,offset Initialize
  int 27h
 cseg ends
  end Start
5.4 一般的键盘扩充程序Mactab.asm
  以下和程序可以把由表的查询,将任意娄的扩充键扩充成命令字符串:
 cseg segment
  assume cs:cseg,ds:cseg
  org 100h
 Start:
  jmp Initialize
 Old_Keyboard_IO dd ?
  assume ds:nothing
  cmp byte ptr cs:[si],0  ;end of table
  je ReadDone
  cmp ah,cs:[si]
  je StartExpand
  add si,3
  jmp NextExt
 StartExpand:
  add si,1
  push bx
  mov bx,cs:[si]
  mov cs:current,bx
  pop bx
 ExpandChar:
  mov si,cs:current
  mov al,cs:[si]
  inc cs:current
  cmp al,0    ;end of string 2
  je ReadChar   ;then read real char
 ReadDone:
  pop si
  ret 3
 KeyRead endp
   current dw 0
   KeyTab db 59
     dw dir_cmd
     db 60
     dw dir_wide
     db 61
     dw dir_asm
     db 62
     dw dir_com
     db 63
     dw dir_exe
     db 50
     dw make_macro
     db 0  ;This must be last in key table
   dir_cmp db 'DIR',0dh,0
   dir_wide db 'DIR/W',0dh,0
   dir_asm db 'DIR *.ASM',0dh,0
   dir_com db 'DIR *.COM',0dh,0
   dir_exe db 'DIR *.EXE',0dh,0
   make_macro db 'MASM MACRO;',0dh,0
     db 'LINK MACRO;',0dh,0
     db 'EXE2BIN MACRO.EXE MACRO.COM',0dh,0
 New_Keyboard_IO proc far
  sti
  cmp ah,0     ;Is this call a read request?
  je ksRead
  cmp ah,1     ;Is it a status request?
  je ksStat    ;Let original routine
  jmp Old_Keyboard_IO   ;handle remianing subfunction
 ksRead:
  call KeyRead    ;Get next character to return
  iret
 ksStat:
  call KeyStat    ;Return appropriate status
  ret 2     ;Important!!!
 New_Keyboard_IO endp
 KeyStat proc near
  cmp cs:current,0
  jne FakeStat
  pushf      ;Let original routine
  call Old_Keyboard_IO   ;Determine keyboard
  ret
 FakeStat:
  mov bx,1     ;Fake a "Character ready" by clearing ZF
  cmp bx,0
  ret
 KeyStat  endp
  ;Read a character from the keyboard input queue,
  ;if not expanding or the expansion string.
  ;if expansion is in progress
 KeyRead  proc
  cmp cs:current,0
  jne ExpandChar
 ReadChar:
  mov cs:current,0  ;Slightly peculiar
  pushf     ;Let original routine
  call Old_Keyboard_IO  ;Get keyboard status
  cmp al,0
  je Extended
 ReadDone:
  ret
 Expanded:
  cmp ah,59    ;Is this character to expand?
  jne ReadDone   ;If not,then return it normally
       ;If so,then start expanding
  mov cs:current,offset string
 ExpandChar:
  push si
  mov si,cs:current
  mov al,cs:[si]
  inc cs:current
  pop si
  cmp al,0    ;Is this end of string?
  je ReadChar   ;If so,then read a real char?
  ret
 KeyRead  endp
 Initialize:
  assume cs:cseg,ds:cseg
  mov bx,cs
  mov ds,bx
  mov al,16h
  mov ah,35h
  int 21h
  mov word ptr Old_Keyboard_IO,bx
  mov word ptr Old_Keyboard_IO,es
  mov dx,offset New_Keyboard_IO
  mov al,16h
  mov ah,25h
  int 21h
  mov dx,offset Initialize
  int 27h
 cseg ends
  end Start
                 未完待续......

内存驻留程序-实例程序 vodi setexterr(struct DOSERROR near *err)//设置扩展错误信息的函数。if((bioskey(2)&KEYMASK)==KEYMASK)//读取移位状态。//CTRL_BREAK中断。#define PSP_PARENT_PSP 0x16 //PSP中的父进程的PSP。//CTRL_C中断。 阅读详情

相关推荐

别光编译Hello World了!用DosBox+Masm6.15带你复现一个经典的DOS内存驻留程序(TSR)

本文通过DosBox和Masm6.15工具链,详细介绍了如何复现DOS时代的内存驻留程序(TSR)。从配置开发环境到编写热键触发的计算器TSR,深入解析了中断处理、内存管理等核心技术,帮助读者理解早期程序员在有限资源下的创造力。

weixin_30516243的博客 380

汇编编写DOS下的内存驻留程序.doc

汇编编写DOS下的内存驻留程序.doc

王爽《汇编语言》第三版实验全攻略:从CPU查看到中断处理实战

本文详细解析王爽《汇编语言》第三版中的关键实验,从CPU查看、内存操作到中断处理程序编写,提供DOSBox环境配置、DEBUG.EXE调试技巧等实用指南。通过现代开发环境集成和实战案例,帮助读者掌握汇编语言核心概念与编程技巧,实现从实验到实战的跨越。

weixin_33734785的博客 352

汇编编写DOS下的内存驻留程序

绪言 0.1 内存驻留与中断 内存驻留程序英文叫Terminate and S 绪言 0.1 内存驻留与中断 内存驻留程序英文叫Terminate and Stay Resident Program,缩写为TSR.这些程序加载进内存,执行完后,就驻留在内存里,当

forpersonal 7233

汇编编写DOS下的内存驻留程序(2)

  转自:http://www.x86asm.com/DisplayArticle.asp?BoardID=5&ArticleID=11     基本原理2.1 8086/8088 IBM PC中央处理单元(Central Processing Unit)是微处理器Inter 8088,8088是8086是小的版本.对于编写程序而言,两者几乎完全相同.两者之间的差别是在于:它们对外...

注重长远 天天积累 cqujsjcyj 221

内存驻留程序

学习DOS内存驻留程序的基本思想,了解与熟悉用汇编语言编写程序。本课程设计将完成一个小的.com程序,运行程序后,你的所有按键输入(指在DOS或Windows的DOS模式下)将不被接受,所有输入将被替换成特定的字符串(回车键除外)。 二、内存驻留程序的基本框架(framework of a TSR)   内存驻留程序的基本思想就是让程序一直停留在内存中,不断的执行特定的命令。但内存驻留如何被执行

IT is Alex.Net 3788

汇编编写DOS下的内存驻留程序(4)

转自:http://www.x86asm.com/DisplayArticle.asp?BoardID=5&ArticleID=13   四 基本的驻留程序4.1 一个基本的COM程序 DOS之下有两种形式的可执行文件,这两种文件分别是COM文件和EXE文件.其中,COM文件可以迅速地加载和执行,但是其大小不能超过64K字节,只能有一个段,代码段.而且起始地址为100H指令必须为程序的...

注重长远 天天积累 cqujsjcyj 854

汇编编写DOS下的内存驻留程序(5) ()

汇编编写DOS下的内存驻留程序(5) ()[@more@]五键盘输入扩充程序有了一节的基本驻留程序为基础,就可以建立起不同的应用程序.接下来,就写一个驻留程序,把用户敲入的字符,用一系列的字符来取代.这样可以减少用户...

csd3176的博客 300

汇编编写DOS下的内存驻留程序(1)

    转自:http://www.x86asm.com/DisplayArticle.asp?BoardID=5&ArticleID=10   绪言0.1 内存驻留与中断 内存驻留程序英文叫Terminate and Stay Resident Program,缩写为TSR.这些程序加载进内存,执行完后,就驻留在内存里,当满足条件时,调到台来执行。 内存驻留程序的常用形式有: ...

注重长远 天天积累 cqujsjcyj 878

Turbo C环境下内存驻留程序开发指南

内存驻留程序,亦称为 TSR(Terminate and Stay Resident)程序,是一种在DOS操作系统环境下开发的,能够在系统中常驻内存,并在需要时被激活的应用程序。它们允许用户在不退出当程序的情况下,通过调用特定中断或热键来运行其他程序或执行某些功能。在计算机中,中断是一种通知处理器暂停当任务并立即处理紧急事件的机制。当中断发生时,处理器会保存当任务的执行状态,然后跳转到一个预先定义好的中断服务程序(ISR),执行完中断处理后,再恢复之的状态继续执行被打断的任务。

weixin_35899324的博客 686

菜鸟的病毒分析3 内存驻留病毒

dos 内存驻留病毒下面这个病毒不像之的文件感染病毒那么简单了这是一个驻留内存病毒,所谓内存驻留病毒就是当程序结束之后还会有内存没有被释放,这就恐怖了可以利用这个修改中断让dos听你的话。为了能驻留内存就必须使程序结束后需要的内存不被释放这就要靠mcb这个内存管理控制块。mcb的相关概念查阅http://hi.baidu.com/dp282074009/blog/item/560e33...

abcd8080的博客 723

汇编编写DOS下的内存驻留程序(3)

  转自:http://www.x86asm.com/DisplayArticle.asp?BoardID=5&ArticleID=12   三 中断矢量3.1 IBM PC提供的中断 IBM PC有两种基本形态的中断.如果是由外围设备所产生的中断就叫做硬件中断(Hardware interrupt),譬如:键盘,磁盘机和时钟等外围设备都可以产生硬件中断.外围设备所产生的中断信号都连...

注重长远 天天积累 cqujsjcyj 322

Borland Turbo Assembler 5.0 经典汇编开发环境安装与实战指南

常用快捷键列表:快捷键功能对应菜单项F2保存文件F3打开文件F9编译并链接Ctrl+F9运行程序Run → RunAlt+F5查看输出偏好设置保存于TURBO.TPL或CONFIG.TAS文件中,包含字体颜色、缩进风格、自动备份等选项。可通过持久化当配置。在早期汇编器中,程序员需要手动声明代码段、数据段和堆栈段,使用如SEGMENTENDS等关键字进行显式划分。

weixin_42466857的博客 970

【硬核逆向】万字长文深度剖析:引导型病毒内存驻留逻辑、DOS 正常引导流程与中毒完整引导流程

📑 目录"引言:为什么2026年了,我们还要研究DOS病毒?""置知识:重返16位实模式与1MB内存布局""DOS 正常引导流程:全链路逐字节拆解""引导型病毒概述:分类与生命周期""引导型病毒的感染方法:它是如何“鸠占鹊巢”的?""核心剖析:引导型病毒内存驻留逻辑""核心武器:INT 13H 中断劫持与隐身术""中毒完整引导流程:一场发生在开机5秒的暗战""实战演练:用 DEBUG 手动诊断与清除引导型病毒""难点分析与常见误区(避坑指南)""现代演进:从 MBR 病毒到 UEFI Bootkit"

吾为热爱计科,致力于知识分享的践行者,此博客是我在这条道路上留下的足迹。 296

汇编推荐书籍

汇编的一些书籍推荐: 1.Intel汇编语言程序设计(第五版)[网上有]2.汇编语言(第2版) 王爽编[网上有]3.琢石成器:Windows环境下32位汇编语言程序设计(第3版)[网上有]4.汇编语言数据结构 王增才著[网上有]5.Turbo Assembler 汇编程序设计进阶教程6.80X86汇编语言程序设计教程[网上有]7.IBM PC XT AT系列机 高级程序员编程指南8.微型计算机高...

weixin_30512785的博客 870

68、MS DOS结构、TSR程序与设备驱动详解

本文深入解析了MS DOS的系统结构、启动过程及核心组件,涵盖从冷启动到显示DOS提示符的完整流程,详细介绍了CONFIG.SYS和AUTOEXEC.BAT的配置与作用。文章还探讨了TSR(终止并驻留程序的工作机制、激活方式及其对内存的影响,并讲解了DOS不可重入性问题及其解决方案。此外,全面阐述了设备驱动程序的分类、组成与功能,包括字符型和块型设备驱动,帮助读者理解DOS如何支持多样化硬件设备。通过实例汇编代码和流程图,增强了对底层操作机制的理解,适用于系统编程与旧系统维护的学习与参考。

lambda的博客 73

TPVO3783病毒分析:DOS文件型病毒逆向实战

计算机病毒通过感染可执行文件实现自我复制和传播,其核心技术包括中断劫持、内存驻留和文件感染。TPVO3783作为典型的DOS文件型病毒,通过修改21h中断向量监控文件操作,采用寄生方式感染.COM文件并添加3783字节标记。这类病毒分析技术至今仍具价值,现代恶意代码检测中的API钩子监控、特征码扫描等方法都源于早期病毒对抗经验。通过VirtualBox搭建FreeDOS虚拟环境,结合IDA Pro反汇编和DEBUG动态调试,可以深入理解病毒的内存驻留机制和感染流程,这种底层分析能力对应对新型勒索软件等威胁仍

weixin_30613433的博客 400
上一篇: 用汇编编写DOS下的内存驻留程序(4)
下一篇: XSS方式攻击
longxin5
博客等级 码龄15年 44粉丝 884原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值