DS寄存器:
CS:当一段代码开始执行时,CS 指向代码段的起始地址,IP 则指向段内偏移,由 CS 和 IP 共同形成逻辑地址,处理器会自动根据当前指令的长度来改变 IP 的值,使它指向下一条指令。
DS:如果在指令的执行过程中需要访问内存中的数据,处理器将用 DS 的值和指令中提供的偏移地址相加,来形成访问内存所需的物理地址。
例如:
dog dw 0x1000
mov ax, dog;仅仅是把0x1000这个立即数放入ax,并不涉及内存操作
mov ax,[dog];这时cpu要访问内存,到地址为0x1000的地方取一个数据。但是,0x1000仅仅是偏移地址,cpu会自动把段地址和偏移地址加在一起。段地址在是什么呢?存在DS中,如果DS的值在某个过程或函数调用过程中被更改的话,cpu就会到一个错误的地址去取一个数据,程序会出现莫名其妙的错误。
显存:
8086 可以访问1MB内存。其中,0x00000~9FFFF(640k) 属于常规内存,由内存条提供;0xF0000~0xFFFFF(64k) 由主板上的一个芯片提供,即 ROM-BIOS。这样一来,中间还有一个320KB的空洞,即 0xA0000~0xEFFFF。传统上,这段地址空间由特定的外围设备来提供,其中就包括显卡。
文本模式下显存的起始物理地址是 0xB8000
320x200图形模式的起始物理地址是0xA0000
除了DS之外,也可以使用ES访问显存:
mov ax,0x0B8000
mov es,ax;处理器不允许将一个立即数传送到段寄存器,只能通过通用寄存器转一下
mov byte [es:0x00],'L';直接使用ES访问显存,一般情况下,如果没有附加任何指示,段地址默认在段寄存器 DS 中
“在 8086 处理器上,如果要用寄存器来提供偏移地址,只能使用 BX、SI、DI、BP,不能使用其他寄存器。”
需要注意的是,程序中用DB DW等伪指令定义的数据的内存地址绝大部分是段内的偏移地址,而不要定义成绝对物理地址,因为你无法确定系统会把你的程序加载到内存中的什么位置。
另外,jmp后面跟随的偏移量,而不是段内的偏移地址,更不是绝对地址。