将这段代码用于 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

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...