【问题标题】:Get a character from a screen position and put it in a string (not working)从屏幕位置获取字符并将其放入字符串中(不起作用)
【发布时间】:2021-05-06 08:21:51
【问题描述】:

我有一个 getchar 函数应该这样做:

它应该输出什么:

33

它实际输出的内容:

3

这是我目前的尝试:

char db 0
charcolor db 0
pos_x_2 db 0
pos_y_2 db 0
_getchar:
  MOV [pos_x_2], DL
  MOV [pos_y_2], DH
  MOV BH, 0
  MOV AH, 03h
  INT 0x10
  MOV [pos_x], DL
  MOV [pos_y], DH
  MOV DL, pos_x_2
  MOV DH, pos_y_2
  MOV AH, 02h
  INT 0x10
  MOV BH, 0
  MOV AH, 08h
  INT 0x10
  MOV [char], AL
  MOV [charcolor], AH
  RET

【问题讨论】:

  • 将 NASM 与 16 位代码一起使用。
  • 此代码不输出任何内容。它在指定位置读取当前字符/颜色。查看 definitions 了解各种 int 10h 函数。查看您输入的值 ah 以确定您调用的是哪些值。
  • 主代码应该输出两个字符。它只是文件的一个 sn-p。
  • 你为什么要发布不显示问题的代码?如果您不向我们显示当前代码,我们无法告诉您为什么当前代码显示“3”而不是“33”...

标签: assembly nasm x86-16 bios


【解决方案1】:
MOV DL, pos_x_2
MOV DH, pos_y_2

在 NASM 中,上述内容不会加载存储在 pos_x_2pos_y_2 变量中的值。相反,寄存器会加载这些变量地址的低字节。
您需要像在其余代码中那样使用方括号。

另外,如果您在阅读屏幕上的任何位置之前麻烦地保留光标的位置,您不应该在从例程返回之前恢复它吗?
请注意,您可以通过简单的push/pop 保留/恢复DLDH,而不是使用基于内存的变量。

; IN (dl,dh)
_getchar:
  push dx          ; On the stack is "Where we want to read from the screen"
  mov  bh, 0
  mov  ah, 03h     ; BIOS.GetCursor
  int  10h         ; -> CX DX
  pop  ax
  xchg ax, dx
  push ax          ; On the stack is "Where the cursor stood before"
  mov  ah, 02h     ; BIOS.SetCursor
  int  10h
  mov  ah, 08h     ; BIOS.ReadCharacterAndAttribute
  int  10h         ; -> AX
  mov  [char], ax  ; (*)
  pop  dx          ; Restore the cursor to where it stood before
  mov  ah, 02h     ; BIOS.SetCursor
  int  10h
  ret

  ...

char db 0
charcolor db 0

(*) 因为 charcharcolor 变量在内存中是相邻的并且顺序正确,所以您可以将 ALAH 中的值写入来自AX

【讨论】:

  • 我可能使用过pop ax / push dx / mov dx, ax,因此对于数据流向何处,需要遵循的思维步骤更少。 xchg 仍然可以用作大小优化而不是 2 字节 mov,如果您关心的是真正的 8086 上的速度而不是后来的 CPU 上的速度。 (尽管它主要由 int 成本控制,所以不妨考虑代码大小。)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多