如何解决将这段代码用于 scanf();功能工作? NASM 16 位
我有这个用于 ASM 的代码,它应该复制 scanf();
函数。
但是我有一种感觉,代码有问题。代码如下:
_scanf:
MOV DS,0
JMP .continue
RET
.continue
MOV AH,00h
INT 0x16
CMP AH,0Dh
JE .backspace
CMP AL,0x0D
JE .done
CMP AL,0x0A
JE .done
MOV CX,1
MOV BH,0
MOV AH,09h
INT 0x10
MOV AH,03h
INT 0x10
ADD DL,1
MOV AH,02h
INT 0x10
MOV WORD [DX+DS],AL
ADD DS,1
JMP .continue
.done:
RET
.backspace:
MOV WORD [DX+DS],0x00
MOV AH,03h
INT 0x10
SUB DL,02h
INT 0x10
MOV BH,0
MOV AL,0x00
MOV CX,09h
INT 0x10
JMP .continue
这是有效代码吗?还是 [DX+DS] 操作码是无效的段覆盖?
在 16 位代码中使用编译器 NASM。
解决方法
在“错误”类别中:
-
MOV DS,0
不允许用于段寄存器。 -
MOV WORD [DX+DS],AL
不是有效的寻址模式,而且“WORD”标记与 AL 的字节大小不匹配。 -
ADD DS,1
不允许用于段寄存器。 -
MOV WORD [DX+DS],0x00
不是有效的寻址模式。
在“眉毛”类别中,您有:
-
JMP .continue
后跟RET
使此RET
无法访问。 - 通过 BIOS.WriteCharacterAndAttribute 函数 09h 输出,但未在
BL
寄存器中指定实际属性。如果您不走运,您将不会在屏幕上看到任何内容。 - 退格而不检查是否有任何东西(左)可以退格。
在“挑剔”类别中:
- 当通过
AH
中存储的 ASCII 代码 8 执行此操作更短(更常见)时,通过AL
中的扫描码比较退格。 - 当您收到退格键时,在内存中写入一个字大小的 0。一个字节就足够了,什么也没有。
- 在屏幕上写入 ASCII 字符 0 以删除字符。 ASCII 码 32 是执行此操作的常规方法。
以下是您的代码的简化版本。确保您的程序中某处有一个缓冲区。使用类似 buffer times 80 db 0
的东西。
由于您似乎并不关心颜色属性,因此您也可以使用 Teletype 函数而不是自己更新光标。 Teletyping ASCII code 8,将光标向左移动,但你必须自己写空格字符。
_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
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。