assembly - 如何在 DOS/Asembler 中获取字母字符 (α)?

标签 assembly x86 dos bios codepages

我在上大学,几乎没有 Asembler 类(class)。我的老师给了我们下面的代码:

.286
.model small
.data
.stack 64h
.cide
main:
 MOV AX,0B800H
 MOV ES,AX
 MOV ES:[240], 7C03H
 MOV AH,1h
 INT 21h

 MOV AX,4C00H
 INT 21h
end main

它只是将红色的心放在屏幕上的灰色背景上。我的功课是把那颗心改成α。他还链接了这个网站:https://www.rapidtables.com/code/text/alt-codes.html在这个例子中。在那里,α 的代码是 224 (E0),但是当我将 7C03H 更改为 7CE0H 时,我得到的是 Ó 而不是 α。我已经尝试了从 0 到 255 的每个数字,但都没有用。据我所见,int 21h 和 int 10h 允许超过 1 个字节的字符。

我做了一些谷歌搜索,发现 DOS 使用的是代码页 852,它没有 α。

我能否以某种方式更改此程序中的代码页,或者是否无法获得 α?我的程序不需要看起来与示例完全一样。我可以使用其他中断,例如 10h、21h 或 16h。

最佳答案

更改代码页

斯拉夫语(拉丁语 II)代码页 852 不包含德语中使用的 ß(Beta)以外的希腊字符。
显示希腊字符的一种解决方案是使用 DOS 切换代码页。 DOS 标准代码页 437 确实包含一些希腊字符。

如果未安装 NLSFUNC:

  • 在命令提示符下,您可以使用 mode con cp select=437

如果安装了 NLSFUNC:

  • 在命令提示符下,您可以使用 chcp 437
  • 在应用程序中,您可以使用 DOS.SetGlobalCodePage 函数 6602h。

无论哪种方式,系统都需要正确的配置才能支持多个代码页。以下是我的配置文件包含的内容的摘录:

配置系统:

DEVICE=C:\DOS\DISPLAY.SYS CON=(EGA,850,2)
COUNTRY=032,850,C:\DOS\COUNTRY.SYS
INSTALL=C:\DOS\NLSFUNC.EXE

自动执行.BAT:

C:\DOS\MODE.COM CON CODEPAGE PREPARE=((437 850) C:\DOS\EGA.CPI)
C:\DOS\MODE.COM CON CODEPAGE SELECT=850
C:\DOS\KEYB.COM BE,850,C:\DOS\KEYBOARD.SYS

接下来是一个演示程序,展示了如何从应用程序中切换到代码页 437。该程序清楚地证明,如何将字符显示到屏幕上(通过 DOS、BIOS 或 VRAM)并不重要。切换立即生效,甚至屏幕上已经出现的字符也会相应改变。

; Changing code pages from within an application (c) 2021 Sep Roland
; ( With the intention to display Greek characters ... )
; Assemble with FASM

        ORG     256

; If NLSFUNC is not installed, changing code pages is not an option
        xor     bx, bx
        mov     ax, 1400h       ; NLSFUNC.CheckInstallationStatus
        int     2Fh             ; -> AL
        cmp     al, 0FFh
        jne     Print           ; Nlsfunc is NOT installed

; No need to change if Active Code Page is 437
        mov     ax, 6601h       ; DOS.GetGlobalCodePage
        int     21h             ; -> BX DX CF
        jc      Print
        cmp     bx, 437         ; Is Active Code Page == 437 ?
        je      Print

; Temporarily changing the Active Code Page to 437
        push    bx              ; (1)
        mov     bx, 437
        mov     ax, 6602h       ; DOS.SetGlobalCodePage
        int     21h             ; -> CF
        pop     bx              ; (1)
        jc      Print

; Test the character range from 224 to 239
        call    Greek

; Restore previous Active Code Page
        mov     ax, 6602h       ; DOS.SetGlobalCodePage
        int     21h             ; -> CF
        jmp     Exit

Print:  call    Greek

Exit:   mov     ax, 4C00h       ; DOS.TerminateWithReturnCode
        int     21h
; ------------------------------
Greek:  pusha

        mov     dx, .msg1
        mov     ah, 09h         ; DOS.DisplayString
        int     21h
        mov     dl, 224
.a:     mov     ah, 02h         ; DOS.DisplayOutput
        int     21h
        inc     dl
        cmp     dl, 240
        jb      .a

        mov     dx, .msg2
        mov     ah, 09h         ; DOS.DisplayString
        int     21h
        mov     al, 224
.b:     mov     ah, 0Eh         ; BIOS.Teletype
        int     10h
        inc     al
        cmp     al, 240
        jb      .b

        mov     dx, .msg3
        mov     ah, 09h         ; DOS.DisplayString
        int     21h
        mov     bh, 0
        mov     ah, 03h         ; BIOS.GetCursorPosition
        int     10h             ; -> CX, DL is Column, DH is Row
        mov     al, 160
        mul     dh
        mov     dh, 0
        add     ax, dx
        add     ax, dx
        mov     di, ax
        push    es              ; (1)
        mov     ax, 0B800h
        mov     es, ax
        mov     ax, 0EE0h       ; YellowOnBlack ASCII 224
.c:     stosw
        inc     al
        cmp     al, 240
        jb      .c
        pop     es              ; (1)

        mov     dx, .msg4
        mov     ah, 09h         ; DOS.DisplayString
        int     21h

        mov     ah, 00h         ; BIOS.GetKeyboardKey
        int     16h             ; -> AX

        popa
        ret
; - - - - - - - - - - - - - - - 
.msg1   db      13, 10, 'DOS  : $'
.msg2   db      13, 10, 'BIOS : $'
.msg3   db      13, 10, 'VRAM : $'
.msg4   db      13, 10, 'Press any key', 13, 10, '$'
; ------------------------------

不要删除 BIOS.GetKeyboardKey 调用。如果这样做,您将没有机会真正看到希腊字符...

关于assembly - 如何在 DOS/Asembler 中获取字母字符 (α)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67658842/

相关文章:

assembly - 比较指令无法正常工作

iOS汇编代码

assembly - LEA 指令的目的是什么?

c - shellcode执行/bin/sh但不执行./abcde

c++ - “lock cmpxchg”如何在汇编中工作?

c - 拆解二元炸弹第三阶段逻辑难理解

assembly - 在引导扇区中使用 INT 0x10 打印字符串

c - C 中的指针问题 - 我在这里做错了什么?

batch-file - DOS FOR/F 循环之后的任何内容都没有执行

batch-file - 如何在 DOSBox 的子程序中创建变量?