⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 asmcoun1.pas

📁 汇编源代码大全2
💻 PAS
📖 第 1 页 / 共 2 页
字号:
    Ctrl-O and Ctrl-N. These control codes may be nested. Processing
    proceeds identically to that of the ASCII counter, until a Ctrl-O is
    found.

    When a control code sequence is found, the Sprint counter enters
    another loop. The loop processes characters, keeping count of the
    depth of control codes, adding one each time a ^O is encountered,
    and subtracting one each time a ^N is found. When the count reaches
    zero, the control code is terminated and control returns to normal
    word-counting loop.
    ----------------------------------------------------------------------- }

  { -----------------------------------------------------------------------
    InitCount - The Sprint counter's InitCount performs the same functions
                as the ASCII InitCount, except that a special value is
                placed in the look-up table for Ctrl-O to indicate the
                start of control-code processing.
    ----------------------------------------------------------------------- }

  procedure SprintCountObj . InitCount;
  begin
    CountObj . InitCount;
    Table [ ^O ] := $FF;
  end;

  { -----------------------------------------------------------------------
    Count - Count the words in a Sprint file. Comments annotate differences
            between this and CountObj.Count.

    There are two pieces of code in this procedure which are kind of
    tricky. These were designed to speed and simplify processing, but
    they'll require some explanation.

     ------------------------------------------------------------------
       Previous char   Current char    AH   AL    Need to do
     ------------------------------------------------------------------
         separator       separator     01   01    nothing
         separator     non-separator   01   00    nothing
         separator        Ctrl-O       01   FF    process control code
       non-separator     separator     00   01    count a word
       non-separator   non-separator   00   00    nothing
       non-separator      Ctrl-O       00   FF    process control code
     ------------------------------------------------------------------

    This table shows how the main loop must handle different
    situations that will occur. The focus of this code is to maximum
    speed. Therefore, the codes for the table were carefully chosen so
    that the more common "do nothing" situations can be distinguighed
    from the others with a single comparison. Once it has been
    determined that something must be done, it can be determined without
    another comparison.

                   cmp AL, AH
                   ja  @CountOrControlCode
                   <...do-nothing processing...>

                 @CountOrControlCode:
                   js  <...control-code processing...>
                   <...count a word...>

    The other bit of tricky code is in the control code sequence processing
    loop. It is necessary to add one to a counter if character number 15
    is found, and to subtract one if character 14 is found. Then, the
    loop must be terminated if the count has reached zero. This task is
    performed by the following code. (BP holds the depth counter.):

                   sub   AL, 14
                   sub   AL, 1
                   adc   BP, 0
                   sub   AL, 1
                   sbb   BP, 0
                   jz    <...loop complete...>

    ----------------------------------------------------------------------- }

  procedure SprintCountObj . Count;
  var
    TempCount : longint;
  begin
    InitCount;

    asm
      cld

      mov   [ SaveBP ], BP     { When it comes time to process a control  }
                               {   code sequence, the depth counter is    }
                               {   stored in BP. The original value of BP }
                               {   must be restored later when the method }
                               {   is complete, and also before ReadBlock }
                               {   is called.                             }

      xor   DX, DX
      mov   DI, DX
      mov   AX, 0101h
      call  @CallReadBlock

    @ProcessNormalChar:
      mov   AH, AL
      seges lodsb
      xlat
    @Continue:
      cmp   AL, AH               { See comments above.                    }
      ja    @CountOrControlCode

      loop  @ProcessNormalChar
      call  @CallReadBlock
      jmp   @ProcessNormalChar

    @CountOrControlCode:
      js    @ControlCode

      add   DI, 1                { Count a word.                          }
      adc   DX, 0
      loop  @ProcessNormalChar
      call  @CallReadBlock
      jmp   @ProcessNormalChar

    @ControlCode:
      mov   BP, 1                { Process a control code sequence. A     }
      jmp   @EndControlCodeLoop  {   control sequence begins with ^O and  }
                                 {   ends with ^N. Control codes may be   }
                                 {   nested. Therefore it is necessary to }
                                 {   keep a depth counter. As ^O's are    }
                                 {   processed, the counter will be       }
                                 {   incremented. ^N's will decrement the }
                                 {   counter. When the counter reaches    }
                                 {   zero, the control code is complete.  }
                                 {   The depth counter will be stored in  }
                                 {   BP. Since a ^O has already been      }
                                 {   found, the counter is set to 1.      }

    @ProcessControlCodeChar:
      seges lodsb                { Get next character.                    }

      sub   AL, 14               { See comments above.                    }
      sub   AL, 1
      adc   BP, 0
      sub   AL, 1
      sbb   BP, 0
      jz    @ControlCodeDone

    @EndControlCodeLoop:
      loop  @ProcessControlCodeChar  { Process next char. }
      mov   AL, AH                   { This line is necessary to ensure   }
                                     {   correct processing should the    }
                                     {   end-of-file already be reached.  }
      call  @CallReadBlock
      jmp   @ProcessControlCodeChar

    @ControlCodeDone:
       mov  AL, 1                { Return to normal processing as if a    }
       jmp  @Continue            {   a separator had been found.          }

    @CallReadBlock:
      pushf
      push  AX
      push  DX
      push  DI
      push  BP                   { Save the depth counter, and restore BP }
      mov   BP, [ SaveBP ]       {   will ReadBlock is called.            }
    end; { asm }

    ReadBlock;

    asm
      pop   BP
      pop   DI
      pop   DX
      pop   AX
      popf

      mov   BX, offset Table
      les   SI, [ Block ]
      mov   CX, [ Actual ]
      jcxz  @EndOfFile
      retn

    @EndOfFile:
      pop   CX
      cmp   AL, 1
      jz    @Fini
      add   DI, 1
      adc   DX, 0

    @Fini:
      mov   BP, [ SaveBP ]       { Restore original BP.                   }

      mov   [ word ptr TempCount     ], DI
      mov   [ word ptr TempCount + 2 ], DX
    end; { asm }

    FiniCount;
    WordCount := TempCount;
  end;

  { -----------------------------------------------------------------------
    AmiPro control code sequences begin with '<', followed by one of '@',
    '+' or '-'. The sequence terminates with a '>'. AmiCountObj.Count
    processes characters the same as CountObj.Count except that it checks
    each character to see if it is a '<'. When a '<' is encountered,
    another character is read and checked against '@', '+' and '-'. If
    one of these is found, Count enters a loop looking for '>'.
    ----------------------------------------------------------------------- }

  procedure AmiCountObj . Count;
  var
    TempCount : longint;
  begin
    InitCount;

    asm
      cld

      xor   DX, DX
      mov   DI, DX

      mov   AX, 0101h

      call  @CallReadBlock

    @ProcessNormalChar:
      mov   AH, AL
      seges lodsb

      cmp   AL, '<'              { Check to see if character is '<'. If   }
      jz    @PerhapsControlCode  {  it is, a control code sequence may be }
                                 {  beginning.                            }

    @Continue:
      xlat
      cmp   AX, 0001h
      jz    @CountWord
      loop  @ProcessNormalChar
      call  @CallReadBlock
      jmp   @ProcessNormalChar

    @CountWord:
      add   DI, 1
      adc   DX, 0
      loop  @ProcessNormalChar
      call  @CallReadBlock
      jmp   @ProcessNormalChar

    @ProcessCharAfterLT:
      seges lodsb                { Read the character that follows '<'.   }
      cmp   AL, '@'              { Check to see if it is '@', '+' or '-'. }
      jz    @ProcessControlCode
      cmp   AL, '+'
      jz    @ProcessControlCode
      cmp   AL, '-'
      jz    @ProcessControlCode
      jmp   @Continue

    @PerhapsControlCode:
      loop  @ProcessCharAfterLT
      mov   AL, AH
      call  @CallReadBlock
      jmp   @ProcessCharAfterLT

    @ProcessControlCodeChar:
      seges lodsb                { A control code sequence has begun.     }
      cmp   AL, '>'              { Process characters until a '>' is      }
      jz    @Continue            {   found.                               }

    @ProcessControlCode:
      loop  @ProcessControlCodeChar
      mov   AL, AH
      call  @CallReadBlock
      jmp   @ProcessControlCodeChar

    @CallReadBlock:
      pushf
      push  AX
      push  DX
      push  DI
    end; { asm }

    ReadBlock;

    asm
      pop   DI
      pop   DX
      pop   AX
      popf

      mov   BX, offset Table
      les   SI, [ Block ]
      mov   CX, [ Actual ]
      jcxz  @EndOfFile
      retn

    @EndOfFile:
      add   SP, 2
      cmp   AL, 0
      jnz   @Fini
      add   DI, 1
      adc   DX, 0

    @Fini:
      mov   [ word ptr TempCount     ], DI
      mov   [ word ptr TempCount + 2 ], DX
    end; { asm }

    FiniCount;
    WordCount := TempCount;
  end;

{begin}
end.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -