问题描述
它应该输出什么:
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,08h
INT 0x10
MOV [char],AL
MOV [charcolor],AH
RET
解决方法
MOV DL,pos_x_2
MOV DH,pos_y_2
在 NASM 中,上述不会加载存储在 pos_x_2 和 pos_y_2 变量中的值。相反,寄存器加载了这些变量地址的低字节。
您需要像在其余代码中一样使用方括号。
另外,如果你在阅读屏幕上的任何地方之前不厌其烦地保留光标的位置,你不应该在从例程返回之前恢复它吗?
请注意,您可以通过简单的 DL
/DH
而不是使用基于内存的变量来保留/恢复 push
和 pop
。
; 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
(*) 因为 char 和 charcolor 变量在内存中相邻且顺序正确,所以您可以写入 AL
和 {{ 1}} 一次从 AH
开始。