TASM 8086 尝试对字符串的字符进行计数并将它们显示在 table 中

TASM 8086 Trying Count the characters of a string and display them in a table

请原谅程序中的一些间距,我使用的编辑器显示的标签间距与此处显示的间距不同

当前正在尝试计算用户输入字符串的字符数。我已经在互联网上彻底搜索了帮助,但目前似乎没有太多关于 8086 编码的帮助。这是我目前所知道的:

    .MODEL  small
    STACK   256

;************************************************************************
;* Equates Section                                                                  *
;************************************************************************

EOS     EQU 0       ;End of string
maxLen  EQU 255     ;Maximum entry string length
bell      EQU   7       ;Bell character -- <ctrl>G

;************************************************************************
;* Data Section                                                                       *
;************************************************************************
  .DATA
excode  db  0     ;DOS error code
enter1  db  'Enter a string: ',EOS          ;Prompt user for input
enter2  db  'Would you like to count another string?',EOS
                                            ;Prompt user for another string
buffer  db maxLen dup (?)                   ;input/output buffer
buffer1 db maxLen dup (?)                   ;input/output buffer

spaces  db  '   ',EOS                       ;Used for spacing
letter  db  'Letter ',EOS                   ;String used for first column
freq    db  'Frequency',EOS                 ;String used for second column
cBord1  db  '------ ',EOS                   ;String used to mark column border
cBord2  db  '---------', EOS                ;String used to makr column border

currLet dw  0
strLet  dw  0
side    db  0                               ;0=Left side, 1=Right side

count   db  0


exitProg db 'Exiting program',EOS           ;Exit message

;************************************************************************
;* Code Section                                                                       *
;************************************************************************
  .CODE

;************************************************************************
;* External procedures from BINASC.OBJ                                                                  *
;************************************************************************
    EXTRN AscToBin:proc, binToAscDec:proc
;************************************************************************
;* External proceduers from STRING.OBJ & STRIO.OBJ                      *
;************************************************************************
  EXTRN StrLength:proc, StrRead:proc
  EXTRN StrWrite:proc, Newline:proc


;************************************************************************
;* Main entry point of program                                          *
;************************************************************************
Start:
  mov ax, @data     ;Initialize DS to address
  mov ds, ax        ;  of data segment
  mov es, ax        ;make es = ds
;************************************************************************
;* Get user input and conver to uppercase                               *
;************************************************************************
First:
    call  Newline     ;Start new display line
    lea   di, enter1  ;Display message to enter a string
    call  StrWrite
    mov     si, 0

    lea   di, buffer    ;Get user input
    mov   cx, maxLen    ;Maximum string length
    call  StrRead           ;Get entry from keyboard
    lea   si, buffer  ;Move string into si

Back:
    mov   al, [si]    ;Move si location to al
    cmp   al, 'a'     ;Compare al to 'a'
    jb    Ahead       ;Jump if less than
    cmp   al, 'z'     ;Compare al to 'z'
    ja    Ahead       ;Jump if greater than

    and   al, 0DFh    ;Convert letter to uppercase
    mov   [si], al


Ahead:
    inc si          ;increment value of si
    loop Back       ;loop back to

;Display table head
    call Newline
    lea  di, buffer
    call StrWrite

    call Newline
    lea  di, letter
    call StrWrite
    lea  di, freq
    call StrWrite
    lea  di, spaces
    call StrWrite
    lea  di, letter
    call StrWrite
    lea  di, freq
    call StrWrite

    call Newline
    lea  di, cBord1
    call StrWrite
    lea  di, cBord2
    call StrWrite
    lea  di, spaces
    call StrWrite
    lea  di, cBord1
    call StrWrite
    lea  di, cBord2
    call StrWrite

    call Newline

    mov  si, 0        ;clear si

ploop:
    mov  ax, si       ;set ax register equal to si
    add  al, 'A'      ;Move 'A' into low bit of ax
    mov  currLet, ax  ;Move ax reigster into currLet

    mov  side, 0      ;set side to Left

sloop:
    mov  buffer1, al      ;Move current letter into buffer1
    mov  buffer1+1, EOS   ;clear end of buffer1
    lea  di, buffer1      ;Move letter into di
    call StrWrite         ;Write letter to screen

;Separate letters from their counts
    lea  di, spaces
    call StrWrite
    call StrWrite

    mov  count, 0      ;clear count
    mov cx, 0          ;clear cx register
    mov cx, maxLen     ;set cx to maxLen

    CntBack:
      lea  di, buffer      ;Move input string into di
      mov  bl, [di]        ;Move di location to bl
      mov  strLet, bx      ;Move current letter of string
      jmp CntFwrd
    CntUp:
       inc count
       inc di
       loop CntBack
    CntFwrd:
      mov  ax, strLet
      cmp  ax, currLet ;compare string letter and current letter
      je   CntUp
      inc  di
      loop CntBack

    mov  ax, 0
    mov  cx, 3
    mov  al, count
    lea  di, count
    call binToAscDec
    call StrWrite

    cmp  side, 1
    je   nextRow
    inc  side

    ;right side
    lea  di, spaces
    call StrWrite
    call StrWrite
    call StrWrite

    add  currlet, 13
    mov  ax, currlet
    jmp  sloop

nextRow:
    call Newline
    inc  si
    cmp  si, 13
    je   Exit
    jmp  ploop

;************************************************************************
;* Exit program                                                                     *
;************************************************************************
Exit:
    call    Newline
    call  Newline
    lea   di, exitProg      ;Call exit program message
    call  StrWrite
;************************************************************************
;* Program termination code                                                     *
;************************************************************************
    mov ah, 04Ch        ;DOS function Exit Program
    mov al, excode  ;Return exit code value
    int 21h             ;Call DOS. Terminate program
    END Start           ;  End of program/entry point

我认为我的问题出在这段代码中:

    CntBack:
      lea  di, buffer      ;Move input string into di
      mov  bl, [di]        ;Move di location to bl
      mov  strLet, bx      ;Move current letter of string
      jmp CntFwrd
    CntUp:
       inc count
       inc di
       loop CntBack
    CntFwrd:
      mov  ax, strLet
      cmp  ax, currLet ;compare string letter and current letter
      je   CntUp
      inc  di
      loop CntBack

如果我输入字符串 'hello',程序应该显示:

Letter Frequency   Letter Frequency
------ ---------   ------ ---------
A      000         N      000
B      000         O      001
C      000         P      000
D      000         Q      000
E      001         R      000
F      000         S      000
G      000         T      000
H      001         U      000
I      000         V      000
J      000         W      000
K      000         X      000
L      002         Y      000
M      000         Z      000

但我会在显示中收到类似这样的信息:

Letter Frequency   Letter Frequency
------ ---------   ------ ---------
A      000         N      000
B      000         O      000
C      000         P      000
D      000         Q      000
E      000         R      000
F      000         S      000
G      000         T      000
H      _

似乎代码没有计算整个输入字符串,而只是比较第一个 strLet,即字符串的第一个字母,与 currlet

CntBack 循环的顶部,您将 DI 设置为指向输入缓冲区的开头。在比较第一个字符并递增 DI 后,您循环回到 CntBack,这会将 DI 重置为指向输入缓冲区的相同第一个字符。

因此,您只是反复比较字符串的第一个字符,直到 CX 计数用完。尝试将 CntBack 标签向下移动一条指令,看看是否能解决问题。