【问题标题】:Why cursor doesn't move vertically on real hardware but does on a virtual machine?为什么光标在真实硬件上不会垂直移动,但在虚拟机上会垂直移动?
【发布时间】:2019-05-29 04:58:47
【问题描述】:

我想在我的操作系统中使用键来实现光标移动。我试过这段代码来做到这一点:

mouse:
mov ah,0h
int 16h

    cmp al, 107
    je Down


    cmp al, 105
    je Up


    cmp al, 106
    je Left


    cmp al, 108
    je Right

    jmp mouse

    Right:
        add dl, 1
        call SetCursor
        jmp mouse
        ret

    Left:
      sub dl, 1
      call SetCursor
      jmp mouse
      ret

   Up:
     sub dh, 1
     call SetCursor
     jmp mouse
     ret

   Down:
      add dh, 1
      call SetCursor
      jmp mouse
      ret

   SetCursor:
       mov ah, 02h
       mov bh, 00
       int 10h
       ret

引导加载程序(它的一小部分):

%include "stage2info.inc"

STAGE2_LOAD_SEG  equ STAGE2_ABS_ADDR>>4

.stage2_loaded:
    mov ax, STAGE2_RUN_SEG      
    mov ds, ax
    mov es, ax
    jmp STAGE2_RUN_SEG:STAGE2_RUN_OFS

TIMES 510-($-$$) db  0
dw 0xaa55

为什么光标在真实硬件上不垂直移动,而在虚拟机上却可以? 我试图改变钥匙,但没有,同样。 为什么代码在真实硬件上不起作用? 我的代码错了吗?

【问题讨论】:

  • 这个程序在哪里运行?这是你的全部代码吗?它是否在 DOS 中运行?
  • 它可以启动。是的,整个代码都是我的。
  • @fsdfff 这可能是问题所在。大多数 BIOS 不喜欢从没有启动签名的介质启动。
  • @fsdfff 请发布包含引导签名的更新代码。
  • 它只适用于上键、左键和右键。在真实硬件上的向下键它仍然不起作用。

标签: assembly nasm x86-16 bootloader osdev


【解决方案1】:

问题和问题:

  • 要检查箭头键,您需要查看 AH 中的 scancodes,而不是 AL 中的 ASCII 字符。扫码为0x50向下,0x48向上,0x4b向左,0x4d向右
  • 在进入鼠标循环之前,您没有初始化 DHDL。在进入循环之前用Int 10h/AH=3h检索当前坐标
  • 您不会测试超出屏幕顶部、左侧、右侧和底部边缘的边界,因此如果光标超出边界,可能会发生意外情况
  • jmp mouse 之后您有不必要的ret 指令,这些指令永远无法到达。
  • 您可以使用 INCDEC 指令对寄存器进行加减运算,而不是使用 ADDSUB em> 值为 1。
  • 对于查看问题的人,正在使用的引导加载程序是我在此 Stackoverflow Answer 中汇总的模板。

这段代码应该可以工作:

%include "stage2info.inc"
ORG STAGE2_RUN_OFS

BITS 16

MAX_ROW equ 25                  ; 80x25 screen extents
MAX_COL equ 80

mouse:
    mov ah, 3                   ; Get cursor BIOS call
    mov bh, 0                   ; Page number is zero
    int 10h                     ; DH and DL will be set to current coordinates.

    mov ah,0h
    int 16h

    cmp ah, 0x50
    je Down

    cmp ah, 0x48
    je Up

    cmp ah, 0x4b
    je Left

    cmp ah, 0x4d
    je Right

    jmp mouse

    Right:
      inc dl
      cmp dl, MAX_COL           ; Test for right edge.
      jl right_bound_ok
      mov dl, MAX_COL-1
    right_bound_ok:
      call SetCursor
      jmp mouse

    Left:
      dec dl
      jge left_bound_ok         ; Test for left edge (<0?)

      mov dl, 0
    left_bound_ok:
      call SetCursor
      jmp mouse

    Up:
      dec dh
      jge up_bound_ok           ; Test for upper edge (<0?)

      mov dh, 0
    up_bound_ok:
      call SetCursor
      jmp mouse

    Down:
      inc dh
      cmp dh, MAX_ROW           ; Test for bottom edge
      jl down_bound_ok
      mov dh, MAX_ROW-1
    down_bound_ok:
      call SetCursor
      jmp mouse

    SetCursor:
      mov ah, 02h
      mov bh, 00
      int 10h
      ret

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-24
  • 1970-01-01
相关资源
最近更新 更多