在没有任何打印语句(如printf)的情况下,向0xb8000000写入内容可以在屏幕上输出。

7
#include <stdio.h>
#include <conio.h>

void main()
{
  char far *v = (char far*)0xb8000000;
  clrscr();

  *v = 'w';
  v += 2;
  *v = 'e';

  getch();
}

输出结果为:we

我不明白为什么没有任何printf或其他打印语句,输出就可以显示。


8
请正确格式化代码并提高你的接受率。(记录一下,在不到5分钟内进行9或10次编辑之前,这句话更有趣。) - San Jacinto
3
哇,向内存中的任意地址写入数据。这可能会导致程序崩溃或出现其他未定义的行为。 - EboMike
2
@Ebo 如果你要做一些愚蠢的事情,那么你最好在一个炫耀和段错误的火光中完成它。 - Maxpm
2
一分钟内进行了9次编辑!这是某种记录吗? - Andrew Clark
2
@Andrew:大约一分钟内进行了9次编辑!这是什么记录?多人尝试以不同的方式更正相同的文本,这就是所谓的竞争条件... :-) - paercebal
显示剩余6条评论
6个回答

23

这是一个 x86 实模式 IBM PC 程序,假设在默认内存位置(B800:0000)映射了 CGA/EGA/VGA 兼容的彩色文本模式图形适配器;它基本上来自于 MS-DOS 时代(1980年代/1990年代)。无论如何,它非常老派!

char far *v=(char far*)0xb8000000;

视频缓冲区的内存地址(在实模式下)(如果您使用旧的Hercules,请使用0xb0000000

clrscr();

清空屏幕

*v='w';

在第0行,第0列写入字符w

v+=2;

跳过2个字节(在字符模式下,缓冲区是交错的:1个字节用于字符,1个字节用于颜色。1位用于闪烁,3位用于背景0-74位用于前景0-15,以这种方式打包:前景+16*背景+128(如果您想要闪烁)

*v='e';

在第0行,1列写入字符e

getch();

等待按键

现在是一个关于CGA文本模式格式的链接,对于那些想要了解“旧一代”是如何做到的,在“Windows”(甚至在所有“Linux”之前)出现之前。啊...还有另一个链接(这次是维基百科),供那些仍然不知道REAL-MODE是什么的人参考。


@paercebal 如果你认为我的解释不够完整,下一次我会让你使用BIOS的INT 10h在屏幕上写字 :-) :-) :-) (http://en.wikipedia.org/wiki/INT_10H),但是请记住(引用维基百科)`INT 10h非常慢`! :-) (如果不清楚,这是一个笑话) - xanatos
我刚刚完成了关于实模式的文章,我的最终想法是“嘿,我太年轻了,没机会在这些环境下编码!”,所以我猜今晚我会跳过“INT 10h”... ^_^ ... - paercebal

9
他直接写入视频缓冲区,该缓冲区通常位于该地址处。
此外,这是非常老派的图形处理。

1

0

您没有指定平台,显然这不是一个会崩溃的恶意代码。

在传统的DOS平台上,0xb8000000是视频内存缓冲区,在文本模式下,您可以直接在那里写入字符。请参见此处:http://wiki.answers.com/Q/What_is_0xB8000000


0
首先,它获取视频缓冲区开头的地址。然后清除屏幕,并开始向缓冲区添加文本。

0

这是视频内存地址空间的开头。在这里写入的内容将显示在屏幕上。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接