In the category "wrong" you have:
MOV DS, 0
not allowed on segment registers.
MOV WORD [DX+DS], AL
not a valid addressing mode and also a mismatch between the 'WORD' tag and the byte size of AL.
ADD DS, 1
not allowed on segment registers.
MOV WORD [DX+DS], 0x00
not a valid addressing mode.
In the category "eyebrow" you have:
JMP .continue
followed by RET
making this RET
unreachable.
- Outputting via BIOS.WriteCharacterAndAttribute function 09h without specifying an actual attribute in the
BL
register. If you're unlucky you won't see anything appear on the screen.
- Backspacing without checking if there's anything (left) to backspace over.
In the category "nit-picking" you have:
- Comparing for backspace via the scancode in
AH
when it's shorter (and more usual) to do this via the ASCII code 8 stored in AL
.
- Writing a word-sized 0 in memory when you receive a backspace. A byte would be enough and nothing at all would be fine too.
- Writing ASCII character 0 on the screen to remove a character. ASCII code 32 is the normal way to do this.
Below is a simplified version of your code. Make sure you have a buffer somewhere in your program. Use something like buffer times 80 db 0
.
Since you don't seem to care about the color attribute, you can just as well use the Teletype function and not update the cursor yourself. Teletyping an ASCII code 8, moves the cursor to the left, but you have to write the space character yourself.
_scanf:
mov bx, 0007h ; CONST DisplayPage and GraphicsColor
mov cx, 1 ; CONST ReplicationCount
mov di, buffer
.continue:
mov ah, 00h ; BIOS.WaitKey
int 16h ; -> AX
cmp al, 8
je .backspace
cmp al, 13
je .done
cmp al, 10
je .done
mov [di], al ; Write in buffer
inc di ; Add to buffer
mov ah, 0Eh ; BIOS.Teletype
int 10h
jmp .continue
.backspace:
cmp di, buffer
jna .continue
dec di ; Remove from buffer
mov ah, 0Eh ; BIOS.Teletype (backspace)
int 10h
mov ax, 0A20h ; BIOS.WriteCharacter (space)
int 10h
jmp .continue
.done:
mov byte [di], 0 ; Zero-terminate the string
ret
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…