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
标签向下移动一条指令,看看是否能解决问题。
请原谅程序中的一些间距,我使用的编辑器显示的标签间距与此处显示的间距不同
当前正在尝试计算用户输入字符串的字符数。我已经在互联网上彻底搜索了帮助,但目前似乎没有太多关于 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
标签向下移动一条指令,看看是否能解决问题。