问题
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
AL
to 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