庞大资源库的计算机教程网站!
设为首页
加入收藏
总编信箱
投稿或申请专栏请先 [登 陆]
首页 操作系统 程序设计 图形图像 媒体动画 机械电子 WEB开发 数 据 库 办公系列 路由技术 网络原理 网络应用
认证考试 安全技术
首页>程序设计>汇编语言>技巧教程>正文
资料搜索
Google搜索
Google
返回上级列表

推荐文章

快速保存网页中所有图片的方法
Windows中让光驱巧妙“隐身”技
防范非法用户入侵Win 2000/XP系
两款比较典型的ASP木马防范方法
有关表格边框的css语法整理
Windows XP中可以被禁用的服务
SQL Server导出导入数据方法
Javascript所有对象的属性的获
网页(HTML)中的特殊字符
与篮球共舞,尽显模式本色
QQ病毒的手工清除方法
Photoshop为极品美女打造性感睫
天衣无缝:IIS与PHP水火也相容
SQL Server存储过程编写和优化

5个DOS专用文件的6种io重定向,more实现管道原理

 作者:本站收集   日期:2005-8-1 15:50:28
字号选择〖 〗/ 双击滚屏 单击停止   

   1. 重定向
  
  以下a.asm,用含't'及回车13的txt,仿command.com,依masm命令行的arg符号值N,(如masm /Darg=0 a;),实现5个DOS打开专用文件(STD_)的6种io重定向:
  
  N=0:是STDIN句柄,先bin方式读1符,再从txt输't'到char
  N=1:是STDOUT句柄,输出char的'1'到txt
  N=2:是STDERR句柄,输出char的'2'到txt
  
  N=30,31:
  3是STDAUX句柄,N=30,从txt输't'到char;N=31,输出char的'3'到txt
  
  N=41:
  4是STDPRN句柄,输出char的'4'到txt
  
  asm调用如下功能:
  
  N=0时,44,读/写设备info,敲键符值入100h,其ascii/scan对,入106h,扩展键时,首对,入104h,次值,入101h.
  如1,得(31,31,2),ctl_c,得(3,3,2e),F1,得(0,0,3bh),(3bh,0,3bh)
  
  3d,依读写方式,打开txt,保存句柄到si
  45,保存STD_句柄的复制值到di
  46,将来访问(cx)句柄,变为访问(bx)=(si)句柄,开始重定向
  3f/40,用STD_输入/出,字符数1,偏置char
  46,将来访问(cx)句柄,变为访问(bx)=(di)句柄,结束重定向
  3e,关闭txt
  
  DEBUG行完a.com,对输入,见103h的char,变't',对输出,type txt,见1~4.
  
  ACT=2
  IFDEF arg
      IF arg GT 2
          IF arg EQ 30
              ACT=30
          ENDIF
  
          IF arg EQ 31
              ACT=31
          ENDIF
  
          IF arg EQ 41
              ACT=41
          ENDIF
  
          STD_=arg/10
      ELSE
          IF arg GE 0
              ACT=1
              STD_=arg
  
              IF arg EQ 0
                  ACT=0
              ENDIF
          ENDIF
      ENDIF
  ENDIF
  
  IF ACT EQ 2    无效
      %OUT /Darg=0|1|2|30|31|41
      .ERR
  ENDIF
  
  just    macro
          local    j
  
          mov    di,es:[26]    敲键,i9写低asc,高scan到[1Ch尾引字++],i16读[1Ah首引字++]到3f功能的ax
          sub    di,2
  
          cmp di,1ch    未重划键区,现在回头
          ja j
  
          mov di,3ch    刚才入尾
  
  j:        mov ax,es:[di]
          endm
  
  c    segment
      assume    cs:c,ds:c
  
      org    100h
  
  @:    jmp    @1
  
  char    db    '0'+STD_
  txt    db      'txt',0
  
  @1:    mov     ah,3dh        open
      mov    al,ACT and 1
            lea     dx,txt
          int     21h
  
      mov    si,ax        han
  
      mov    bx,ACT        stdin
      test    bx,63    >41    
      jnz    @3
  
      mov    ax,4400h    I/O,从/到fil\nul定向,dx=42h\80c4,否则80d3
      int    21h
  
      mov    ax,4401h
      or    dl,32        bin
      xor    dh,dh
      push    dx
      int    21h
  
      mov    ax,64        bios数据区seg,1E~3D是键区
      mov    es,ax
  
      mov    ah,3fh        不等回车读
      mov    cx,1        1符
      lea    dx,@        入256
      int    21h
  
      test    byte ptr cs:[256],255    测扩展
      jnz    @2
  
      just
      mov    word ptr txt,ax
  
      mov    ah,3fh        取真
      inc    dx
      int    21h
  
  @2:    just
      mov word ptr txt[2],ax
  
      mov    ax,4401h    复原
      pop    dx
      and    dx,not 32
      int    21h
  
  @3:    mov     ah,45h    duplica
      mov    bx,STD_
      int     21h
  
      mov    di,ax        han
  
      mov    ah,46h        force han
      mov    bx,si
      mov    cx,STD_
      int    21h
  
      mov    ah,3fh+ACT    r/w=3f/40
      mov    bx,STD_
      mov    cx,1
      lea    dx,char
      int    21h
  
      mov    ah,46h
      mov    bx,di
      mov    cx,STD_
      int    21h
  
      mov    ah,3eh        close
      mov    bx,si
      int    21h
  
      ret
  
  c    ends
      end    @
  
  2. 管道
  
  反汇编DOS_3.31_more,得[100,1e9]是代码区,[1ea,219]是数据区,初值为18/50的1ea/leb,记录屏幕配置行/列数,初值1/1的1ec/1ed,记录已处理行/列数.
  
  流程:
  
  (2.1) 100处,用功能30,取DOS主/次版本号al/ah,若非3/1f,就显1fc处的"MORE: Incorrect DOS version",用110处的int 20,退出
  
  (2.2) 置1ea=19,用int 10,ah=0f,得屏幕列数到1eb,如50
  
  (2.3) 用功能45,复制stdin(bx=0)句柄到bp,如5,用功能3e,关闭stdin句柄
  
  (2.4) 用功能45,复制stderr(bx=2)句柄(也可复制被@1的si句柄),必得刚关闭的句柄0,
  为看完满屏而读键盘一符时,从stderr或si读,而不移管道stdin指针.
  
  (2.5) 139处,用功能3f,打开bp句柄,字节数cx=1000,目的地21a,读stdin
  
  用|接入管道时,more不创建新进程.
  
  未接入时,将读键盘行,如读"135",此串及回车0d,换行0a,被存目的地,被存长度5返到ax,键入符数多于cx时,前面cx个字符被存目的地.对^Z单行,ax返回0.
  
  若ax=0,就用14a处的int 20退出,否则
  
  (2.6) 150处,读目的地每个字符到al
  
  读到^Z,则转14a退出
  
  读到0d,置列数1ed=1,转1ac
  
  读到0a,行数1ec加1,转1ac
  
  读到回退符08,当1ed=1,转1ac,否则列数减1后,转1ac
  
  读到制表符09,则1ed置为下个制表位置,转1ac
  
  读到响铃符07,则不占输出列,转1ac
  
  读到其它符,1ed加1,比较屏幕配置列数1eb,不大于则转1ac,否则
  
  1ec加1,再置1ed=1
  
  (2.7) 1ac处,
  
  用功能2,显出al到stdout,以再接管道
  
  若1ec小于屏幕配置行数1ea,则转1e1处,否则用功能09,显出1f0处的"-- More --",用功能0c,且al=08,清键盘输入后,内调功能08,无回显,从stderr读键盘一符
  
  输出2空行,再置1ed=1,1ec=1
  
  (2.8) 1e1处,
  
  cx减1,结果为0,转139,否则转150
  
  成文:
  
  BLKSZ=1000h
  
  c        segment
          assume cs:c;ds:c,es:c,ss:c
  
          org    100h
  @:        jmp    init
  
  cfg_r        db    19h
  cfg_c        db    50h
  cur_r        db    1
  cur_c        db    1
  
  buf        db    BLKSZ    dup    (0)
  msg        db    '-more-$'
  cr        db    13,10,36
  
  init:        xor    bx,bx
          mov    ah,45h
          int    21h
  
          mov    bp,ax
  
          mov    ah,3eh
          int    21h
  
          mov    bx,2
          mov    ah,45h
          int    21h
  
  read:        lea    dx,buf
          mov    cx,BLKSZ
          mov    bx,bp
          mov    ah,3fh
          int    21h
  
          or    ax,ax
          jnz    read1
  
  quit:        int    20h
  
  read1:        mov    cx,ax
          mov    si,dx
  
  nxtch:        lodsb
  
          cmp    al,1ah
          jz    quit
  
          cmp    al,13
          jnz    ?newlin
  
          mov    cur_c,1
          jmp    show
  
  ?newlin:    cmp    al,10
          jnz    ?back
  
          inc    cur_r
          jmp    show
  
  ?back:        cmp    al,8
          jnz    ?tab
  
          cmp    cur_c,1
          jz    show
  
          dec    cur_c
          jmp    show
  
  ?tab:        cmp    al,9
          jnz    ?bell
  
          mov    ah,cur_c    
          add    ah,7
          and    ah,0f8h
          inc    ah
          mov    cur_c,ah
          jmp    show
  
  ?bell:        cmp    al,7
          jz    show
  
          inc    cur_c
  
          mov    ah,cur_c
          cmp    ah,cfg_c
          jbe    show
  
          inc    cur_r
          mov    cur_c,1
  
  show:        mov    dl,al
          mov    ah,2        
          int    21h
  
          mov    ah,cur_r
          cmp    ah,cfg_r
          jb    ?endblk
  
          lea    dx,msg
          mov    ah,9
          int    21h
  
          mov    ax,0c08h
          int    21h
  
          lea    dx,cr
          mov    ah,9    1 cr
          int    21h
  
          mov    cur_c,1
          mov    cur_r,1
  
  ?endblk:    dec    cx
          jz    read@
          jmp    nxtch
  
  read@:        jmp    read
  
  c        ends
          end @
  

上一篇:仿FDISK及PQMAGIC列出分区逻辑盘符的prw.asm实现(1)    下一篇:MASM的反反汇编技术  
[发送给好友]  [关闭窗口]  [返回顶部]   转载请注明来源:www.it00.com   
特别声明: 本站除部分特别声明禁止转载的专稿外的其他文章可以自由转载,但请务必注明出处和原始作者。文章版权归文章原始作者所有。对于被本站转载文章的个人和网站,我们表示深深的谢意。如果本站转载的文章有版权问题请联系编辑人员,我们尽快予以更正。
责任编辑: 原点 投稿作者: 本站收集
信息来源: 网络 录入时间: 2005-8-1 15:50:28
关于我们 - 广告服务 - 版权申明 - 网站地图 - 联系方式 - 总编信箱 - 会员投稿