TASM 8086 Trying计算字符串的字符并将其显示在表格中

时间:2016-12-07 02:19:52

标签: x86-16 tasm

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

目前正在尝试计算用户输入字符串的字符数。我已经通过互联网彻底搜索了帮助,但似乎在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值进行比较

1 个答案:

答案 0 :(得分:0)

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

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