控制显卡
文章目錄
- 1 顯卡和顯存
- 1.1 顯卡和顯存
- 1.2 顯存的顯示模式
- 1.3 8086中顯存的地址
- 2 控制顯卡顯示內容
- 2.1 需求分析
- 2.2 匯編代碼實現
- 2.3 更精簡的代碼實現
1 顯卡和顯存
1.1 顯卡和顯存
先搞清楚如下幾個概念:
顯卡: 為顯示器提供內容。
顯示器: 將顯卡所提供的內容呈現在屏幕上。
集成顯卡: 集成在主板上,和主板是一體的。
獨立顯卡: 獨立生產和銷售的一個獨立的部件。
顯示存儲器: 簡稱“顯存”,每個顯卡都有自己的存儲器。
1.2 顯存的顯示模式
圖形模式:
文本模式:
實際上還包含屬性字節:
屬性字節的含義:
1.3 8086中顯存的地址
2 控制顯卡顯示內容
2.1 需求分析
我們需要在屏幕上顯示一個標號的地址,顯示內容類似:“label offset:256”。
顯示標號的步驟如下:
2.2 匯編代碼實現
匯編代碼如下:
mov ax,0xb800 ;將b800傳送到ax寄存器中 mov es,ax ;將ax寄存器中的值,也就是b800傳送到附加段寄存器es中 ;為什么不寫成 mov es,b800 ? ;因為intel處理器不允許,它只允許:mov 段寄存器,通用寄存器/內存單元 ;b800這個數是干什么用的?---顯存的段地址 ;----------------------------------------------------------------- mov byte [es:0x00],'L' ;將"字符L的ASCII碼"存儲到顯存的第1個存儲單元中 ;mov byte [es:0x00],0100 1100b / 76 / 0x4C ;地址必須使用方括號括起來 ;byte/word:明確的告訴編譯器這條指令的數據寬度 ;不需要修飾:Mov [00],AL / Mov AX,[00] mov byte [es:0x01],0x07 ;將"字符L的屬性"存儲到顯存的第2個存儲單元中 ;屬性值07:黑底白字、無閃爍、無加亮mov byte [es:0x02],'a' mov byte [es:0x03],0x07mov byte [es:0x04],'b' mov byte [es:0x05],0x07mov byte [es:0x06],'e' mov byte [es:0x07],0x07mov byte [es:0x08],'l' mov byte [es:0x09],0x07mov byte [es:0x0a],' ' mov byte [es:0x0b],0x07mov byte [es:0x0c],"o" mov byte [es:0x0d],0x07mov byte [es:0x0e],'f' mov byte [es:0x0f],0x07mov byte [es:0x10],'f' mov byte [es:0x11],0x07mov byte [es:0x12],'s' mov byte [es:0x13],0x07mov byte [es:0x14],'e' mov byte [es:0x15],0x07mov byte [es:0x16],'t' mov byte [es:0x17],0x07mov byte [es:0x18],':' mov byte [es:0x19],0x07 ;----------------------------------------------------------------- mov ax,number ;將"標號"存儲到ax寄存器中,作為下面除法運算的:被除數的低16位 ;編譯器在編譯的時候會將number替換為其所對應的的匯編地址 mov dx,0 ;將0存儲到dx寄存器中,作為下面除法運算的:被除數的高16位 mov bx,10 ;將10,也就是二進制的1010存儲到bx寄存器中,作為下面除法運算的:除數 ;以上三條指令為第2個步驟的除法運算做好了準備工作 ;----------------------------------------------------------------- mov cx,cs ;將代碼段寄存器cs中的值,也就是0x000,傳送到cx寄存器中 mov ds,cx ;將cx寄存器中的值,也就是0x000傳送到數據段寄存器ds中 ;ds寄存器中存儲的是本程序在內存中的段地址 ;----------------------------------------------------------------- div bx ;對應第1次除法運算 ;商存儲在ax寄存器中,作為下次運算的被除數 ;余數,也就是標號的個位上的值存儲在dx寄存器中 mov [0x7c00+number+0x00],dl ;將第1次除法運算所得到的標號個位上的值 ;存入了我們使用db所聲明的第1個存儲單元中 xor dx,dx ;異或指令:對兩個數進行異或運算,并將結果存儲到目的操作數中 ;異或運算的特點:相同為0,不同為1 ;這條指令的作用:將dx寄存器中的值清零 ;為第2次除法運算做準備 div bx ;對應第2次除法運算 mov [0x7c00+number+0x01],dl ;將第2次除法運算所得到的標號十位上的值 ;存入了我們使用db所聲明的第2個存儲單元中xor dx,dx ;為第3次除法運算做準備 div bx ;對應第3次除法運算 mov [0x7c00+number+0x02],dl ;將第3次除法運算所得到的標號百位上的值 ;存入了我們使用db所聲明的第3個存儲單元中 ;----------------------------------------------------------------- mov al,[0x7c00+number+0x02] ;將標號百位上的數值傳送給al寄存器 add al,0x30 ;獲得標號百位上數值的ASCII碼 mov [es:0x1a],al ;將標號百位上數值的ASCII碼存入顯存 mov byte [es:0x1b],0x04 ;將0x04存入顯存中偏移地址為0x1b的存儲單元 ;字符屬性04:黑底、紅字、無閃爍、無加亮mov al,[0x7c00+number+0x01] ;將標號十位上的數值傳送給al寄存器 add al,0x30 ;獲得標號十位上數值的ASCII碼 mov [es:0x1c],al ;將標號十位上數值的ASCII碼存入顯存 mov byte [es:0x1d],0x04mov al,[0x7c00+number+0x00] ;將標號個位上的數值傳送給al寄存器 add al,0x30 ;獲得標號個位上數值的ASCII碼 mov [es:0x1e],al ;將標號個位上數值的ASCII碼存入顯存 mov byte [es:0x1f],0x04mov byte [es:0x20],'D' ;將字符D的ASCII碼存入顯存 mov byte [es:0x21],0x07 ;字符屬性07:黑底白字、無閃爍、無加亮 ;----------------------------------------------------------------- infi jmp near infi ;無限循環 ;----------------------------------------------------------------- number db 0,0,0,0,0 ;標號:number = 匯編地址 = 0x0100 ;書寫規范:以字母開頭 ;db:聲明并初始化數據 ;聲明數據的本質就是:在內存中占用一塊空間 ;初始化數據的本質就是:給這個空間賦予一個值 ;在內存中占用了5個字節的空間,這5個字節的值都是0 ;----------------------------------------------------------------- times 249 db 0 ;讓編譯器重復生成db 0 ---- 249次 db 0x55,0xaa ;硬盤主引導扇區的有效標志2.3 更精簡的代碼實現
jmp near start;跳過下面的數據區 mytext db 'L',0x07,'a',0x07,'b',0x07,'e',0x07,'l',0x07,' ',0x07,'o',0x07,\'f',0x07,'f',0x07,'s',0x07,'e',0x07,'t',0x07,':',0x07number db 0,0,0,0,0;-------------------------------------------------------------------- start: mov ax,0x07c0 mov ds,axmov ax,0xb800 mov es,ax;--------------------------------------------------------------------cld;作用:將方向標志位清0 :正向 ;std指令:將方向標志位置1:反向 mov si,mytext;所要傳送的數據,它的偏移地址 mov di,0 ;所要傳送的位置,它的偏移地址 mov cx,(number-mytext)/2 ;所要傳送的次數 rep movsw ;--------------------------------------------------------------------mov ax,number;AX:被除數的低16位;目的:讓它參與運算,以得到標號各個數位上的值 mov bx,ax;目的,將來存儲計算所得到的標號各個數位上的值mov cx,5 ;運算的次數 mov si,10 ;除數 ;-------------------------------------------------------------------- digit: xor dx,dxdiv simov [bx],dl;[bx]:指向了第2條DB指令所聲明的第1個存儲單元 inc bx;將bx寄存器中的值+1 ;目的:下一個循環中,讓[bx]指向第2條DB指令所聲明的第2個存儲單元 ;Dec:將bx寄存器中的值-1 loop digit;循環 ;--------------------------------------------------------------------mov bx,number;bx:基址寄存器 mov si,4 ;SI:源變址寄存器 show:mov al,[bx+si];第1次循環,將標號萬位上的值存儲到了al寄存器中;第2次循環,將標號千位上的值存儲到了al寄存器中add al,0x30 ;獲取標號各個數位值的ASCII碼 mov ah,0x04 ;0x04:字符屬性 mov [es:di],ax ;將標號的ASCII碼及其屬性存入顯存中;第1次循環-->萬位 第2次循環-->千位 add di,2;為我們后面的循環,存儲標號數位上值的ASCII碼及其屬性做準備 dec si;為我們后面的循環,訪問標號各個數位的值做準備 jns show ;jns:條件轉移指令 SF=0跳轉 SF=1不跳轉 ;--------------------------------------------------------------------mov word [es:di],0x0744;高字節07:字符屬性 低字節44:字符D的ASCII碼 jmp near $ ; == $ jmp near $;執行效果 == infi jmp near infi ;$:當做標號來用 times 510-($-$$) db 0 ; == $ times 510-($-$$) db 0 ;$ = 當前指令的匯編地址;$$ = 當前段($$所在的段)的起始匯編地址 ;510-($-$$) = 為保證0x55和0xaa的位置,所需要添加的字節數 db 0x55,0xaa參考資料:
總結
- 上一篇: 数组的本质分析
- 下一篇: 数据库与数据库管理系统的基本概念