问题
I am newbie in assembly language. I am trying to get a string of numbers from user terminated by Enter or the length of the string reaching 20. When I executed the program it didn't show any error, but neither did it show any output nor did it terminate when the string exceeded the 20 characters limit.
My code is:
.model small
.stack 100h
.data
var1 db 100 dup('$')
.code
main proc
mov ax, @data
mov dx, ax
mov si, offset var1
l1:
mov ah, 1
int 21h
cmp al,20
je programend
mov [si], al
inc si
jmp l1
programend:
mov dx,offset var1
mov ah,9
int 21h
mov ah, 4ch
int 21h
main endp
end main
回答1:
mov ax, @data mov dx, ax
You want to initialize the DS segment register here but have erroneously written DX. Honest typo, but your code will have corrupted the Program Segment Prefix in this manner.
I am trying to get a string of numbers from user terminated by ENTER key or the length of string reaches 20
It's clear that you need a loop to do this and that you will need 2 tests to decide about when to stop!
- test the character in
ALto see if it is 13 - test a counter (e.g.
CX) to see if it reached 20
xor cx, cx ; Empty counter
mov si, offset var1
TheLoop:
mov ah, 01h ; DOS.GetCharacter
int 21h ; -> AL
cmp al, 13
je programend
mov [si], al
inc si
inc cx
cmp cx, 20
jb TheLoop
programend:
But wait, didn't the task say that it had to be a string of numbers? You need to make sure that the input is indeed a number.
Numbers "0" through "9" have ASCII codes 48 through 57.
xor cx, cx ; Empty counter
mov si, offset var1
TheLoop:
mov ah, 01h ; DOS.GetCharacter
int 21h ; -> AL
cmp al, 13
je programend
cmp al, 48
jb TheLoop ; Not a number
cmp al, 57
ja TheLoop ; Not a number
mov [si], al
inc si
inc cx
cmp cx, 20
jb TheLoop
programend:
Without using a separate counter and using the assembler's ability to translate characters into codes:
mov si, offset var1
TheLoop:
mov ah, 01h ; DOS.GetCharacter
int 21h ; -> AL
cmp al, 13
je programend
cmp al, "0"
jb TheLoop ; Not a number
cmp al, "9"
ja TheLoop ; Not a number
mov [si], al
inc si
cmp si, offset var1 + 20
jb TheLoop
programend:
回答2:
See the comments in the code below. Remember not to confuse the data read pair ds:si with dx:si. One could also argue that ds:di would be more appropriate here.
main proc
mov ax, @data
mov ds, ax
mov si, offset var1
xor cl, cl ; set CX to zero
l1:
mov ah, 1
int 21h
; AL now contains the character read
mov [si], al ; put the character into our variable
inc si ; move up the memory cursor
inc cl
cmp cl, 20
jl l1
; if the number of iterations is less than 20,
; do all of the above again
; otherwise proceed to program end
programEnd:
mov dx, offset var1
mov ah, 9
int 21h
; at this point we have printed the string read
mov ah, 4ch
int 21h
; and now we've terminated the program
main endp
end main
来源:https://stackoverflow.com/questions/63439566/cant-get-output-of-assembly-language-code