为什么显卡在内存中的映射是0b8000H

本文详细介绍了显存基地址从16位时代至今的历史演变过程,包括早期IBM PC中显存地址的选择及其背后的原因,从单色显示模式到兼容彩色显示模式的变化,以及后续VGA模式的发展。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

作者:北极
链接:https://www.zhihu.com/question/269649445/answer/351632444
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

显存基地址虽然是人为确定的,但真要追究原因的话,还是可以找到一些原因的。
首先,16位时代8086的寻址范围是0000:0000~FFFF:000F,最早划给RAM的区域是640KB,范围0000:0000~9FFF:000F,这在第一代IBM x86 PC时代基本就定下来了。剩下的区域要划给BIOS和硬件使用。当时的设计思路是,BIOS的东西尽量往后放,所以BIOS的ROM代码被放到了F000段这里。
然后就是决定显存放在哪的问题。
可以使用的区域包括A000:0000,B000:0000,C000:0000,D000:0000,E000:0000这几大段内存。
先说看A000段:这段内存有一个问题,就是A000段会跟9FFF段有重叠,也就是9FFF:0010~9FFF:FFFF,可能是为了防止有内存重叠,设计的时候把显存往后挪一段,也就是B000这一段。
早期的显存基地址是B0000而不是B8000,早在1981年最早的IBM PC机出来的时候,显示器还是单色的,显存只有4KB(80*50),占用的内存范围是B0000~B0FFF。
这里需要特别提一句,显卡上是有RAM也有ROM的,RAM映射到了B000段上,ROM映射到C000段(实际范围是C0000~C7FFF),当时因为外设还不多(硬盘都属于罕见的设备),所以内存地址空间可以说是随便用,虽然显卡RAM只有4K,ROM只有8K,但各自占用了很大一段的地址空间。
到了1983年,显卡技术进一步发展,显示器可以显示彩色字符了,但考虑到兼容性的问题,需要兼容原来的单色显卡,而C000段已经被用掉了,B000段还有很多剩余空间,于是B000段被拆成了两部分,B000~B7FF段兼容单色显卡显存,B800~BFFF段留给彩色字符显存。
因为现在显卡已经默认工作在彩色字符模式下了,所以B800就成了默认的显存基地址了,实际上早期的基地址是B000而不是B800。事实上现在的很多显卡仍然能通过配置切换到单色模式,切换过去以后,显存的基地址就是B0000了。
再后来,显卡发展出VGA模式,显卡的显存也增长到了256KB,而这个时候因为BIOS的东西太多,硬件数量也变多了,已经把D000, E000都占了,此时可用的地址空间只剩下A000,所以A000就用来做VGA的图形模式的显存了。
至此,A0000以后的地址空间就基本确定下来了:
A0000~AFFFF: VGA图形模式显存空间
B0000~B7FFF: MDA单色字符模式显存空间
B8000~BFFFF: CGA彩色字符模式显存空间
C0000~C7FFF: 显卡ROM空间(后来被改造成多种用途,也可以映射显存)
C8000~FFFFE: 留给BIOS以及其它硬件使用(比如硬盘ROM之类的)。
<think>好的,用户问的是如何将内存单元的数据显示在显示器上,需要基于微机原理来解释。首先,我得回忆一下微机系统中内存和显示器的交互过程。显示器属于外部设备,需要通过I/O端口或者内存映射的方式与CPU通信。 首先,内存中的数据要显示出来,可能需要经过几个步骤。第一步,CPU从内存单元读取数据。这里可能需要确定内存地址,是具体的物理地址还是逻辑地址,这取决于微机的工作模式,比如实模式还是保护模式。不过用户可能只需要基础的解释,所以先简化,假设是实模式下直接访问内存地址。 然后,读取到的数据可能需要转换成ASCII码,因为显示器显示的是字符。例如,如果内存中的数据是二进制数值,比如0x41,对应的ASCII字符是'A'。这里需要考虑数据是字符还是需要转换成字符串的数字,比如十进制或十六进制的表示。如果数据本身就是ASCII码,那可以直接使用;如果是数值,就需要转换。 接下来,如何将转换后的字符发送到显示器。在微机系统中,通常有两种方式:通过BIOS中断或者直接操作显存。对于DOS环境,常用的方法是使用INT 10h的中断服务,比如AH=0Eh的Teletype输出功能,或者AH=13h的字符串输出。另一种方式是直接写入显存,通常显存在实模式下的地址是B8000h开始的区域,每个字符占用两个字节,一个是ASCII码,另一个是属性字节(颜色等)。 用户的问题可能更偏向于底层原理,所以可能需要详细说明这两种方法。比如使用BIOS中断的话,需要设置相应的寄存器参数,然后触发中断。而直接写显存则更高效,但需要了解显存的结构和当前位置的光标位置。 另外,需要考虑的是,显示数据可能需要处理多个字符,比如一个字符串,需要循环读取内存中的每个字节,并逐个输出。例如,内存中有一串字符数据,从地址DS:SI开始,逐个读取直到遇到结束符(如'$'或0),然后通过INT 21h的09h功能显示,但这属于DOS功能调用,可能超出了纯硬件的微机原理范围。 需要明确用户的问题是否涉及操作系统层面的调用,还是纯粹的硬件级操作。如果是微机原理课程内容,可能更倾向于使用BIOS中断或者直接操作显存,而不是DOS API。所以应该重点放在这两种方法上。 举个例子,假设内存地址2000H处存放了一个字符'A',即ASCII码41H。如果要显示它,可以通过MOV指令将数据取到AL寄存器,然后调用INT 10h的0Eh功能,这样就能在屏幕上显示出来。或者直接将该字符写入显存的当前光标位置对应的内存地址,比如B800:0000,接着更新光标位置。 不过显存的结构是每个字符两个字节,所以如果使用直接写入的方式,需要计算光标的位置,每个字符占两字节,属性字节比如07h是黑底白字。例如,第一个字符位置是B8000h,第二个是B8002h,依此类推。因此,写入时需要处理这两个字节,一个放ASCII码,一个放属性。 此外,还需要考虑光标的位置管理,每次显示一个字符后,光标需要移动到下一个位置,这可能涉及到读取和更新光标的位置,这又可能需要通过BIOS中断来实现,比如INT 10h的功能03h读取光标位置,功能02h设置光标位置。 总结下来,步骤大致如下: 1. 确定要显示的数据在内存中的地址。 2. 读取该地址的数据到CPU寄存器。 3. 将数据转换为对应的ASCII码(如果需要)。 4. 选择输出方式:BIOS中断或直接写入显存。 5. 若使用BIOS中断,设置相应参数并调用中断。 6. 若直接写入显存,计算显存地址,写入ASCII码和属性字节,并更新光标位置。 可能还需要处理不同数据类型的情况,比如显示十六进制数值,这时候需要将二进制值转换为ASCII字符,比如0-F的转换,并逐个显示每个字符。 在解释的时候,应该分步骤详细说明,并给出示例代码片段,比如使用汇编语言的例子,但要注意用户可能对汇编语法不熟悉,所以需要适当解释指令的作用。 同时,要注意内存单元的数据可能是字节、字或双字,需要根据具体情况处理。例如,一个字节的数据可以直接转换为两个十六进制字符显示。 最后,可能需要提到不同显示模式的区别,比如文本模式和图形模式,这里默认是文本模式,因为涉及到显存直接写入。 检查是否有遗漏的步骤,比如初始化显示模式、处理换行和光标移动等,但根据问题可能不需要过于深入,保持基础解释即可。</think>在微机系统中,将内存单元的数据显示到显示器需通过以下步骤实现: --- ### **一、数据读取与转换** 1. **定位内存单元** 假设待显示的数据存储在内存地址`2000H`,使用汇编指令读取数据: ```assembly MOV SI, 2000H ; 设置源地址 MOV AL, [SI] ; 读取数据到AL寄存器 ``` 2. **数据格式转换** - 若数据为二进制数值(如`41H`),需转换为ASCII字符(如`'A'`)。 - 若需显示十进制或十六进制,需额外编写转换程序(如拆分为高/低4位并转为ASCII)。 --- ### **二、显示输出方式** #### **方式1:通过BIOS中断(INT 10H)** - **功能调用:Teletype输出(AH=0EH)** ```assembly MOV AH, 0EH ; 功能号:显示字符 MOV AL, [SI] ; 待显示字符的ASCII码 INT 10H ; 调用BIOS中断 ``` - 特性:自动处理光标位置,支持换行(`0AH`)和回车(`0DH`)。 #### **方式2:直接写入显存** 1. **显存地址映射** - 文本模式下,显存起始地址为`B8000H`(彩色)或`B0000H`(单色)。 - 每个字符占用2字节:ASCII码(低位)+ 属性字节(颜色,高位)。 2. **写入显存示例** ```assembly MOV AX, 0B800H ; 显存段地址 MOV ES, AX MOV DI, 0 ; 初始偏移(第0行第0列) MOV AL, [SI] ; 待显示字符的ASCII码 MOV AH, 07H ; 属性(黑底白字) MOV ES:[DI], AX ; 写入显存 ``` - 更新光标:需通过BIOS中断`INT 10H`功能02H设置新位置。 --- ### **三、完整流程示例(显示字符串)** 1. **定义数据段** ```assembly DATA SEGMENT MSG DB 'Hello, World!$' ; 以$结尾的字符串 DATA ENDS ``` 2. **代码段实现** ```assembly CODE SEGMENT ASSUME CS:CODE, DS:DATA START: MOV AX, DATA MOV DS, AX ; 设置数据段 MOV SI, OFFSET MSG ; SI指向字符串首地址 MOV AH, 0EH ; BIOS功能号:显示字符 PRINT_LOOP: MOV AL, [SI] ; 读取字符 CMP AL, '$' ; 判断是否结束 JE EXIT INT 10H ; 调用中断显示字符 INC SI ; 指向下一字符 JMP PRINT_LOOP EXIT: MOV AH, 4CH ; 退出程序 INT 21H CODE ENDS END START ``` --- ### **四、关键概念** 1. **显存结构** - 文本模式分辨率通常为80×25,共2000字符,需计算偏移: $$偏移量 = (行号 \times 80 + 列号) \times 2$$ 2. **颜色属性** - 属性字节格式:`高4位背景色 + 低4位前景色`(如`07H`为黑底白字)。 3. **实模式与保护模式** - 实模式下可直接访问物理地址(如`B8000H`),保护模式需通过内存管理单元(MMU)映射。 --- 通过上述步骤,微机系统可将内存数据转换为可视字符并显示在屏幕上。实际应用中需结合硬件特性和编程环境(如DOS或嵌入式系统)选择最佳方法。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值