为什么 VGA 端口 03CC 会以第 3 位设置而第 2 位不响应?

逆向工程 x86
2021-07-06 20:29:48

我正在对我在 90 年代中期编写的一些代码进行逆向工程,这些代码的来源早已丢失,而且我对我遇到的一些 VGA 代码感到有些困惑。我认为它可能来自库或 3rd 方代码,因为我当时只是在学习计算机,虽然我确实包含了一些与 VGA 交互的程序集,但并不是这样。

如果有帮助,该应用程序是一个 16 位 DOS 实模式 exe,原始源代码是由 Turbo Pascal 编译器(版本 6 或 7)编译的。

    ; function boilerplate
    push bp
    mov  bp,sp
    call 0EE2:0530  ; stack bounds check function

    ; probe vga port 03CCh
    sub  sp,0002    ; why?
    mov  dx,03CC
    in   al,dx
    and  al,0C      ; mask bits 3 & 2
    cmp  al,04      ; al == 00000100b
    mov  al,00      ; pre return value
    jne  jump_label ; return 0
    inc  ax         ; return 1
jump_label:
    ; store return value in [bp-01] as well, for.. reasons.
    mov  [bp-01],al
    mov  al,[bp-01]

    ; function boilerplate    
    mov  sp,bp
    pop  bp
    retf 0004 ; instance pointer?

所以问题是,这里的意图是什么?两个部分让我感到困惑:

首先根据我读过的 VGA 文档,第 2 位和第 3 位表示时钟选择,但是这些文档对涉及第 3 位时的含义的信息很清楚。例如,http://www.osdever.net/FreeVGA/vga/extreg.htm#3CCR3C2W将第 3 位设置为undefined的两个值声明为

当设置第 3 位而未设置第 2 位时,此函数似乎返回 0。但为什么?它试图确定硬件的什么?

其次,这是题外话,但什么是意图mov [bp-01],al之后mov al,[bp-01]这似乎是多余的!

1个回答

首先:如果设置了 25 或 28Mhz 时钟,代码仅检查第 2 位(位 0、1、2)

第二:也许它是多余的,但不能说没有原始代码 - 可能仍然是你的反汇编器的问题

retf 0004 ; instance pointer?

是从堆栈中弹出 4 个字节的远返回