无法写入C中的屏幕内存

Amp*_*era 43 c x86 real-mode turbo-c x86-16

我是C的新手,它是继Java之后的第二种高级编程语言.我已经掌握了大部分基础知识,但无论出于何种原因,我无法将单个字符写入屏幕内存.

该程序使用Turbo C for DOS编译,运行速度为120mhz的Am486-DX4-100.该显卡是使用Trio32芯片的非常标准的VLB Diamond Multimedia Stealth SE.

对于操作系统,我运行的PC-DOS 2000加载了ISO代码页.我正在使用标准的MDA/CGA/EGA/VGA 80列文本模式运行.

这是我编写的程序:

#include <stdio.h>

int main(void) {
    unsigned short int *Video = (unsigned short int *)0xB8000;
    *Video = 0x0402;
    getchar();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

正如我所说,我对C很新,所以如果我的错误显而易见,我道歉,我无法找到一个可以理解的如何做到这一点的可靠来源.

据我所知,在x86平台上的实模式下,文本模式的屏幕内存从0xB8000开始.每个字符存储在两个字节中,一个用于字符,一个用于背景/前景.我的想法是将值0x0402(应该是一个红色的笑脸)写入0xB8000.这应该放在屏幕的左上角.

我已经考虑了屏幕可能滚动的可能性,因此在执行时会立即以两种方式删除我的角色.要解决此问题,我尝试过:

  • 使用循环重复写入此值
  • 再写下来吧.

我可以读取并打印我写入内存的值,所以它显然仍然在内存中,但无论出于何种原因,我都没有在屏幕上显示任何内容.我显然做错了,但我不知道会出现什么问题.如果需要任何其他细节,请询问.感谢您提供任何可能的帮助.

Mic*_*tch 55

在实模式中,为了满足第一个完整的1MiB存储器,使用一种称为20位段的机制:使用偏移寻址.0xb8000是物理内存地址.您需要使用一种称为far指针的东西,它允许您使用实模式分段来寻址内存.Stackoverflow Answer中描述了不同类型的指针

0xb8000可以表示为0xb800的段和0x0000的偏移量.获取物理地址的计算是段*16 +偏移.0xb800*16 + 0×0000 = 0xb8000.考虑到这一点,您可以包含dos.h并使用MK_FP C宏来初始化far指向给定段和偏移量的此类地址的指针.

文档 MK_FP定义为:

MK_FP()制作远指针

#include   <dos.h>

void       far *MK_FP(seg,off);
unsigned   seg;                         Segment
unsigned   off;                         Offset
Run Code Online (Sandbox Code Playgroud)

MK_FP()是一个宏,它从其组件段'seg'和偏移'off'部分产生远指针.

返回:远指针.

您的代码可以这样写:

#include <stdio.h>
#include <dos.h>
int main(void) {
    unsigned short int far *Video = (unsigned short int far *)MK_FP(0xB800,0x0000);
    *Video = 0x0402;
    getchar();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

  • 从理论上讲,它应该标记为不稳定. (3认同)
  • @PeterCordes:turboCand许多早期编译器没有“stdint.h”。您可以使用第 3 方标头。也就是说,指针的大小取决于内存模型(Tiny、Small、Medium 是 16 位指针)。使用这些模型,您不能随意将远指针或大指针(始终为 32 位)转换为 16 位指针。在紧凑和大型模型中,默认指针类型是“far”(并且 uintptr_t 的大小为 4)。Huge 的大小为 4。您可以将一个巨大的指针投射到 far,但反之则不然,除非远指针首先被规范化。 (2认同)

sta*_*ker 5

内存段地址取决于所使用的视频模式:

0xA0000 for EGA/VGA graphics modes (64 KB)
0xB0000 for monochrome text mode (32 KB)
0xB8000 for color text mode and CGA-compatible graphics modes (32 KB)
Run Code Online (Sandbox Code Playgroud)

要直接访问 vram,您需要一个 32 位指针来保存段和偏移地址,否则您会弄乱堆。这通常会导致未定义的行为。

char far *Video = (char far *)0xb8000000;
Run Code Online (Sandbox Code Playgroud)

另请参阅:什么是近、远和巨大的指针?


归档时间:

查看次数:

3667 次

最近记录:

5 年,11 月 前