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()制作远指针
Run Code Online (Sandbox Code Playgroud)#include <dos.h> void far *MK_FP(seg,off); unsigned seg; Segment unsigned off; Offset
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)
内存段地址取决于所使用的视频模式:
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 次 |
最近记录: |