瑞星卡卡安全论坛技术交流区系统软件 【求助】一个dos汇编的位串插入程序帮忙看一下

1   1  /  1  页   跳转

【求助】一个dos汇编的位串插入程序帮忙看一下

【求助】一个dos汇编的位串插入程序帮忙看一下

我看的是《IBM-PC汇编语言程序》(第二版) ---沈美明 温冬婵 编著
第235页 例6.12,对其中的第二个子程序movstring看不明白,谁能帮忙分析一下:

书中的原文如下:共四个流程图附后。

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

《IBM-PC汇编语言程序》(第二版) ---沈美明 温冬婵 编著
第235页 例6.12

位串插入程序。程序要求把一个小于32位的位串插入存储器内的一个大位串中的任意位置中去。欲插入的位串存入在bitsg中,它是一个右对齐的位串,可称其为子串,其长度用bitsg_length为符号名的= 伪操作来说明。大位串存入在string中,并为要插入的子串准备了一个符号名为sg_end的双字单元。这里用双字来定义位串的原因在于双字处理位串可以获得更快的速度。

〖说明〗
这一程序主要由移动大位串位置和插入子程序这两个子程序组成,程序框图见图6.7,程序则见下面“例6.12位串插入程序”。主程序中除调用子程序外,主要是作进入子程序条件的判断。一是对子串长度的限制是:0 < 子串长度 < 32;二是测试子串插入的位偏移(即在大位串中子串插入的起始偏移位置)与大位串位位置关系。如果正好在大位串尾,则可直接把子串接在大位串之后;如果已超出大位串的范围,则退出程序不作处理;只有在大位串范围之内时,才调用子程序完成本程序所规定的任务。

移动大位串位置子程序要完成的任务是为了插入子串而移动大位串的位位置。这一工作分两步完成。
第一步,先移动好插入位偏移所在的双字之后的其余双字,这些双字应从尾部开始后移,其后移位数应等于插入串长度(参见图6.8)。这部分程序是在该子程序的LOOP指令之前。其中,要移动的双字数 = 大位串双字数 — 插入位偏移所在的双字地址。


第二步,移动插入位偏移所在汉字。这里要注意的是,插入位偏移之前的各位应保持原位置不变,而其后各位应后移插入串长度位。

在这一子程序中,多处用到双字长度位指令shld和shrd。应注意该指令执行完成后,目的寄存器提到所移入的新内容,而源寄存器则维持原状不变。

插入位串子程序的任务是按指定的插入位偏移插入子串。也就是,用指定的子串取代原有该位置的值。在程序中,先取出插入位偏移所在的双字与其相邻的高阶双字,然后用一串移位指令来达到既移入新子串,又不影响子串外原来的两个双字的内容。

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
例 6.12 位串插入程序

  .model small
            .386
            .stack 200h
            .data
  bitsg      dd  7fffh
  string    dd  12345678h,12345678h, 12345678h,12345678h
  sg_end    dd  ?
  bit_offset dd 58
            bitsg_length = 15
  .code
;------------------------------------------------------------------------------------------------------
  main    proc
        start:    mov    ax,@data
                    mov    ds,ax
                    mov    es,ax
;
                    mov    cx,bitsg_length
                    cmp    cx,0
                    je    exit
                    cmp    cx,32
                    jae    exit
                    mov    edi,bit_offset
                    mov    ecx,(sg_end-string)/4
                    shl    ecx,5
                    cmp    edi,ecx
                    ja    exit
                    jb    move
                    mov    esi,bitsg
                    mov    sg_end,esi
                    jmp    exit
    ;
          move:  call    mov_string
                  call    insert_bitsg
    ;
          exit:  mov    ax,4c00h
                  int    21h
    ;
          main    endp
;------------------------------------------------------------------------------------------------------------
    mov_string    proc
                  sub    eax,eax
                  std
                  mov    si,offset sg_end-4
                  mov    di,offset sg_end
                  mov    ecx,(sg_end-string)/4
                  mov    ebx,bit_offset
                  shr    ebx,5
                  sub    ecx,ebx
      next:      mov    ebx,[si]
                  shld    eax,ebx,bitsg_length
                  stosd
                  mov    eax,ebx
                  sub    si,4
                  loop    next
                  sub    ebx,ebx
                  sub    edx,edx
                  mov    ecx,bit_offset
                  and    cl,1fh
                  shrd    ebx,eax,cl
                  shld    edx,ebx,cl
                  shl    eax,bitsg_length
                  mov    ebx,-1
                  shl    ebx,cl
                  and    eax,ebx
                  or      eax,edx
                  mov    [edi],eax
                  ret
    mov_string    endp
;------------------------------------------------------------------------------------------------------------
    insert_bitsg  proc
                  mov    esi,bitsg
                  mov    edi,bit_offset
                  mov    ecx,edi
                  shr    edi,5
                  shl    edi,2
                  and    cl,1fh
                  mov    eax,string[edi]
                  mov    edx,string+4[edi]
                  mov    ebx,eax
                  shrd    eax,edx,cl
                  shrd    edx,ebx,cl
                  shrd    eax,esi,bitsg_length
                  rol    eax,bitsg_length
                  mov    ebx,eax
                  shld    eax,edx,cl
                  shld    edx,ebx,cl
                  mov    string[edi],eax
                  mov    string+4[edi],edx
                  ret
  insert_bitsg  endp
;------------------------------------------------------------------------------------------------------------
                  end      start

附件附件:

下载次数:0
文件类型:image/pjpeg
文件大小:
上传时间:2005-7-24 10:51:19
描述:



最后编辑2005-07-26 23:30:16
分享到:
gototop
 

不知楼主哪里不理解?

可以用调试程序跟踪看看.
gototop
 

两个地方:
一、mov_string子程序中的这几句:           
                  shl    eax,bitsg_length
                  mov    ebx,-1
                  shl    ebx,cl
                  and    eax,ebx
                  or      eax,edx
二、insert_bitsg子程序:
    insert_bitsg  proc
                  mov    esi,bitsg
                  mov    edi,bit_offset
                  mov    ecx,edi
                  shr    edi,5
                  shl    edi,2
                  and    cl,1fh
                  mov    eax,string[edi]
                  mov    edx,string+4[edi]
                  mov    ebx,eax
                  shrd    eax,edx,cl
                  shrd    edx,ebx,cl
                  shrd    eax,esi,bitsg_length
                  rol    eax,bitsg_length
                  mov    ebx,eax
                  shld    eax,edx,cl
                  shld    edx,ebx,cl
                  mov    string[edi],eax
                  mov    string+4[edi],edx
                  ret
  insert_bitsg  endp
gototop
 

因为本论坛中不能清晰的排版,所以我在另外一个地方也贴了一贴,看起来代码的层次十分清晰,可以看一下:
http://www.dxzm.com/bbs/Dispbbs.asp?boardid=6&ID=543&replyID=1820&skin=1
gototop
 

楼主可以用调试程序跟踪每条指令执行前后有关数据的变化看看

也可以手工画出内存数据状态图(二进制位的),按指令更新,看看。
gototop
 
1   1  /  1  页   跳转
页面顶部
Powered by Discuz!NT