生活随笔
收集整理的這篇文章主要介紹了
利用BIOS 中断INT 0x10显示字符和字符串
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
注:以下程序系原創(chuàng),使用AT&T格式匯編來調(diào)用BIOS 0x10中斷,如有錯誤,歡迎指正。表達(dá)能力較差,寫的不好,但若能幫助一二訪客,幸甚。
使用BIOS 顯示服務(wù)(Video Service)--INT 10H,下面主要探究字符顯示模式。
BIOS中斷在保護(hù)模式下是不能用的,故不能在Linux中測試,所以寫了個簡單的boot loader,并在虛擬機(jī)中運(yùn)行程序。
1.以電傳的方式寫入字符串(AH=0x13)
[cpp] view plaincopyprint?
------------------------------------------------------------------??????????????INT?0x10功能0x13??--------------------------------------------------------------??描述:??????以電傳打字機(jī)的方式顯示字符串??接受參數(shù):??????AH??????????0x13??????AL??????????顯示模式??????BH??????????視頻頁??????BL??????????屬性值(如果AL=0x00或0x01)??????CX??????????字符串的長度??????DH,DL???????屏幕上顯示起始位置的行、列值??????ES:BP???????字符串的段:偏移地址??返回值:??????無??顯示模式(AL):??????0x00:字符串只包含字符碼,顯示之后不更新光標(biāo)位置,屬性值在BL中??????0x01:字符串只包含字符碼,顯示之后更新光標(biāo)位置,屬性值在BL中??????0x02:字符串包含字符碼及屬性值,顯示之后不更新光標(biāo)位置??????0x03:字符串包含字符碼及屬性值,顯示之后更新光標(biāo)位置??-------------------------------------------------------------------??
示例:
[cpp] view plaincopyprint?
#?A?bootsect,?which?print?a?string?by?BIOS?interrupt?video?services(int?0x10)????.section?.text??.global?_start??.code16????_start:??????movw????%cx,????%ax??????movw????%ax,????%ds??????movw????%ax,????%es????????movw????$msgstr,%bp??????movw????len,????%cx??????movb????$0x05,??%dh??????movb????$0x08,??%dl??????movb????$0x01,??%al??????movb????$0x13,??%ah??????movb????$0x01,??%bl??????movb????$0x00,??%bh????????int?????$0x10??1:??????jmp?????1b????msgstr:??????.asciz??"Hello?babyos(print?by?BIOS?int?0x10:0x13,?mode?0x01)!"??len:??????.int????.?-?msgstr????????.org????0x1fe,??0x90??????.word???0xaa55????makefile:??all:?boot.img????boot.o:?boot.s??????as?-o?$@?$<????boot:?boot.o??????ld?--oformat?binary?-N?-Ttext?0x7c00?-o?$@?$<????boot.img:?boot??????dd?if=boot?of=boot.img?bs=512?count=1????clean:??????rm?./boot?./boot.img?./boot.o??
運(yùn)行:
2.通過功能號0x09探究色彩控制
上面的顯示為什么是紅色呢?我們可以通過實(shí)驗(yàn)來看一下顏色控制。
[cpp] view plaincopyprint?
------------------------------------------------------------------------??????????????INT?0x10功能0x09??-------------------------------------------------------------------??描述:??????顯示字符并設(shè)置其屬性??接受參數(shù):??????AH??????????0x09??????AL??????????字符的ASCII碼??????BH??????????視頻頁??????BL??????????屬性值??????CX??????????重復(fù)次數(shù)??返回值:??????無??注意:??????在顯示字符之后并不前進(jìn)光標(biāo)。在文本和圖形模式下均可調(diào)用該功能??????顯示完字符后,如果還要繼續(xù)顯示字符,必須調(diào)用INT?0x10功能0x02前進(jìn)光標(biāo)??-------------------------------------------------------------------------????------------------------------------------------------------------------??????????????INT?0x10功能0x02??-------------------------------------------------------------------??描述:??????把光標(biāo)定位在選定視頻頁的特定行列位置??接受參數(shù):??????AH??????????0x02??????DH,DL???????行、列值??????BH??????????視頻頁??返回值:??????無??注意:??????在80x25模式下,DH范圍0~24,DL范圍0~79??-------------------------------------------------------------------------??
示例:
實(shí)現(xiàn)一個從第4行~7行,第8列~71列,顯示‘A’~‘Z’的程序,共顯示256個字符,使用BL(0~255)
C 偽代碼:
[cpp] view plaincopyprint?
cx?=?0x04;??bh?=?0x00;????dh?=?0x04;??dl?=?0x08;??al?=?'A';????for?(bl?=?0;?bl?<?256;?bl++)??{??????print_char();????????????al++;??????if?(al?==?'Z')??????????al?=?'A';????????????dl++;??????if?(dl?==?72)??????{??????????dh++;??????????dl?=?4;??????}????????????set_cursor();??}??
匯編代碼:
[cpp] view plaincopyprint?
#?A?bootsect,?which?print?a?colorful?chars?by?BIOS?INT?0x10,?0x09????.section?.text??.global?_start??.code16????_start:??????movw????%cx,????%ax??????movw????%ax,????%ds??????movw????%ax,????%es????????movw????$0x01,??%cx?????#?字符顯示重復(fù)次數(shù)??????movb????$0x00,??%bh?????#?視頻頁????????????movb????$0x04,??%dh?????#?顯示起始行??????movb????$0x08,??%dl?????#?顯示起始列????????????movb????$'A',???%al?????#?顯示字符??????movb????$0x00,??%bl?????#?屬性值????1:??????call????print_char??????incb????%al??????cmpb????$'Z',???%al??????jne?????2f??????movb????$'A',???%al??2:????????incb????%dl??????cmpb????$72,????%dl??????jne?????3f??????movb????$8,?????%dl??????incb????%dh??3:??????call????set_cursor??????incb????%bl??????cmp?????$256,???%bl??????jne?????1b??????jmp?????1f????print_char:??????movb????$0x09,??%ah??????int?????$0x10??????ret????set_cursor:??????movb????$0x02,??%ah??????int?????$0x10??????ret????1:??????jmp?????1b????????.org????0x1fe,??0x90??????.word???0xaa55??
結(jié)果:
可以顯式地驗(yàn)證色彩控制BL:
[cpp] view plaincopyprint?
7???????6???????5???????4???????3???????2???????1???????0??I???????R???????G???????B???????I???????R???????G???????B??閃爍????R?????G???????B???????I???????R???????G???????B??
如上圖所示,7~4位為背景色,I表示高亮,RGB表示紅綠藍(lán),若顯卡支持閃爍,則位7表示是否閃爍。
色彩混合:
[cpp] view plaincopyprint?
-----------------------------------------------------------??混合的三種基色?????不開啟亮度位??????開啟亮度位??-------------------------------------------------------??紅+綠+藍(lán)???????????淺灰??????????????白色??綠+藍(lán)?????????????青色??????????????淺青??紅+藍(lán)?????????????洋紅??????????????淺洋紅??紅+綠?????????????棕色??????????????黃色??無色彩?????????????黑色??????????????暗灰??-----------------------------------------------------------??
3.清屏
可以發(fā)現(xiàn)屏幕上有許多Bochs的打印信息,看著不爽,想辦法去掉它們。
利用0x06號功能,上卷全部行,則可清屏。
-----------------------------------------------------------
INT 0x10 功能0x06
------------------------------------------------------
描述:
上卷窗口
參數(shù):
AH 6
AL 上卷的行數(shù)(0表示全部)
BH 空白區(qū)域的視頻屬性
CH,CL 窗口左上角的行列位置
DH,DL 窗口右下角的行列位置
返回值:
無
------------------------------------------------------------
示例:
[cpp] view plaincopyprint?
#?A?bootsect,?which?print?a?colorful?chars?by?BIOS?INT?0x10,?0x09????.section?.text??.global?_start??.code16????_start:??????movw????%cx,????%ax??????movw????%ax,????%ds??????movw????%ax,????%es????????call????clear_screen????#?清屏????????movw????$0x01,??%cx?????#?字符顯示重復(fù)次數(shù)??????movb????$0x00,??%bh?????#?視頻頁????????????movb????$0x04,??%dh?????#?顯示起始行??????movb????$0x08,??%dl?????#?顯示起始列????????????movb????$'A',???%al?????#?顯示字符??????movb????$0x00,??%bl?????#?屬性值????1:??????call????print_char??????#?打印字符??????incb????%al?????????????#?下一個字符??????cmpb????$'Z',???%al?????#?是否該重新從‘A’開始??????jne?????2f??????movb????$'A',???%al??2:????????incb????%dl?????????????#?下一個位置??????cmpb????$72,????%dl?????#?是否到下一行??????jne?????3f??????movb????$8,?????%dl??????incb????%dh??3:??????call????set_cursor??????#?設(shè)置光標(biāo)位置??????incb????%bl?????????????#?下一種屬性??????cmp?????$0,?????%bl?????#?是否256種屬性用完??????jne?????1b??????jmp?????1f??????????????#?結(jié)束????clear_screen:???????????????#?清屏函數(shù)??????movb????$0x06,??%ah?????#?功能號0x06??????movb????$0,?????%al?????#?上卷全部行,即清屏??????movb????$0,?????%ch?????#?左上角行??????movb????$0,?????%ch?????#?左上角列????????movb????$24,????%dh?????#?右下角行??????movb????$79,????%dl?????#?右下角列??????movb????$0x07,??%bh?????#?空白區(qū)域?qū)傩??????int?????$0x10??????ret????print_char:??????movb????$0x09,??%ah?????#?功能號0x09??????int?????$0x10??????ret????set_cursor:??????movb????$0x02,??%ah?????#?功能號0x02??????int?????$0x10??????ret????1:??????jmp?????1b????????.org????0x1fe,??0x90??????.word???0xaa55??
結(jié)果:
4.直接寫顯存繪制字符串:
示例:
[cpp] view plaincopyprint?
#---------------------------------------------------------------??#?直接寫顯存顯示一些文字函數(shù):??#???顯示計(jì)算機(jī)當(dāng)前工作的顯示模式????draw_some_text:??????#?設(shè)置ES,DS的值??????movw????$VIDEO_SEG_TEXT,%ax??????movw????%ax,????????????%es??????xorw????%ax,????????????%ax??????movw????%ax,????????????%ds??????????#?計(jì)算字符顯示位置的顯存地址(目標(biāo)地址)??????movw????$((80*TEXT_ROW+TEXT_COL)?*?2),??%di????????????#?源字符串地址??????leaw????msgstr,?????????%si????????????movb????$TEXT_COLOR,????%al?????#?屬性值(顏色)??????movw????len,????????????%cx?????#?顯示的字符個數(shù)??????draw_a_char:??????????????????movsb??????stosb??????loop????draw_a_char??????????ret?
總結(jié)
以上是生活随笔為你收集整理的利用BIOS 中断INT 0x10显示字符和字符串的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。