日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

利用BIOS 中断INT 0x10显示字符和字符串

發布時間:2025/6/15 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 利用BIOS 中断INT 0x10显示字符和字符串 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

注:以下程序系原創,使用AT&T格式匯編來調用BIOS 0x10中斷,如有錯誤,歡迎指正。表達能力較差,寫的不好,但若能幫助一二訪客,幸甚。


使用BIOS 顯示服務(Video Service)--INT 10H,下面主要探究字符顯示模式。

BIOS中斷在保護模式下是不能用的,故不能在Linux中測試,所以寫了個簡單的boot loader,并在虛擬機中運行程序。


1.以電傳的方式寫入字符串(AH=0x13)

[cpp] view plaincopyprint?
  • ------------------------------------------------------------------??
  • ????????????INT?0x10功能0x13??
  • --------------------------------------------------------------??
  • 描述:??
  • ????以電傳打字機的方式顯示字符串??
  • 接受參數:??
  • ????AH??????????0x13??
  • ????AL??????????顯示模式??
  • ????BH??????????視頻頁??
  • ????BL??????????屬性值(如果AL=0x00或0x01)??
  • ????CX??????????字符串的長度??
  • ????DH,DL???????屏幕上顯示起始位置的行、列值??
  • ????ES:BP???????字符串的段:偏移地址??
  • 返回值:??
  • ????無??
  • 顯示模式(AL):??
  • ????0x00:字符串只包含字符碼,顯示之后不更新光標位置,屬性值在BL中??
  • ????0x01:字符串只包含字符碼,顯示之后更新光標位置,屬性值在BL中??
  • ????0x02:字符串包含字符碼及屬性值,顯示之后不更新光標位置??
  • ????0x03:字符串包含字符碼及屬性值,顯示之后更新光標位置??
  • -------------------------------------------------------------------??

  • 示例:
    [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??

  • 運行:


    2.通過功能號0x09探究色彩控制

    上面的顯示為什么是紅色呢?我們可以通過實驗來看一下顏色控制。

    [cpp] view plaincopyprint?
  • ------------------------------------------------------------------------??
  • ????????????INT?0x10功能0x09??
  • -------------------------------------------------------------------??
  • 描述:??
  • ????顯示字符并設置其屬性??
  • 接受參數:??
  • ????AH??????????0x09??
  • ????AL??????????字符的ASCII碼??
  • ????BH??????????視頻頁??
  • ????BL??????????屬性值??
  • ????CX??????????重復次數??
  • 返回值:??
  • ????無??
  • 注意:??
  • ????在顯示字符之后并不前進光標。在文本和圖形模式下均可調用該功能??
  • ????顯示完字符后,如果還要繼續顯示字符,必須調用INT?0x10功能0x02前進光標??
  • -------------------------------------------------------------------------??
  • ??
  • ------------------------------------------------------------------------??
  • ????????????INT?0x10功能0x02??
  • -------------------------------------------------------------------??
  • 描述:??
  • ????把光標定位在選定視頻頁的特定行列位置??
  • 接受參數:??
  • ????AH??????????0x02??
  • ????DH,DL???????行、列值??
  • ????BH??????????視頻頁??
  • 返回值:??
  • ????無??
  • 注意:??
  • ????在80x25模式下,DH范圍0~24,DL范圍0~79??
  • -------------------------------------------------------------------------??

  • 示例:

    實現一個從第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?????#?字符顯示重復次數??
  • ????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??

  • 結果:


    可以顯式地驗證色彩控制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表示紅綠藍,若顯卡支持閃爍,則位7表示是否閃爍。
    色彩混合:
    [cpp] view plaincopyprint?
  • -----------------------------------------------------------??
  • 混合的三種基色?????不開啟亮度位??????開啟亮度位??
  • -------------------------------------------------------??
  • 紅+綠+藍???????????淺灰??????????????白色??
  • 綠+藍?????????????青色??????????????淺青??
  • 紅+藍?????????????洋紅??????????????淺洋紅??
  • 紅+綠?????????????棕色??????????????黃色??
  • 無色彩?????????????黑色??????????????暗灰??
  • -----------------------------------------------------------??

  • 3.清屏

    可以發現屏幕上有許多Bochs的打印信息,看著不爽,想辦法去掉它們。

    利用0x06號功能,上卷全部行,則可清屏。

    -----------------------------------------------------------
    INT 0x10 功能0x06
    ------------------------------------------------------
    描述:
    上卷窗口
    參數:
    AH 6
    AL 上卷的行數(0表示全部)
    BH 空白區域的視頻屬性
    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?????#?字符顯示重復次數??
  • ????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??????#?設置光標位置??
  • ????incb????%bl?????????????#?下一種屬性??
  • ????cmp?????$0,?????%bl?????#?是否256種屬性用完??
  • ????jne?????1b??
  • ????jmp?????1f??????????????#?結束??
  • ??
  • clear_screen:???????????????#?清屏函數??
  • ????movb????$0x06,??%ah?????#?功能號0x06??
  • ????movb????$0,?????%al?????#?上卷全部行,即清屏??
  • ????movb????$0,?????%ch?????#?左上角行??
  • ????movb????$0,?????%ch?????#?左上角列????
  • ????movb????$24,????%dh?????#?右下角行??
  • ????movb????$79,????%dl?????#?右下角列??
  • ????movb????$0x07,??%bh?????#?空白區域屬性??
  • ????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??

  • 結果:


    4.直接寫顯存繪制字符串:

    示例:
    [cpp] view plaincopyprint?
  • #---------------------------------------------------------------??
  • #?直接寫顯存顯示一些文字函數:??
  • #???顯示計算機當前工作的顯示模式????
  • draw_some_text:??
  • ????#?設置ES,DS的值??
  • ????movw????$VIDEO_SEG_TEXT,%ax??
  • ????movw????%ax,????????????%es??
  • ????xorw????%ax,????????????%ax??
  • ????movw????%ax,????????????%ds??
  • ??
  • ??
  • ????#?計算字符顯示位置的顯存地址(目標地址)??
  • ????movw????$((80*TEXT_ROW+TEXT_COL)?*?2),??%di??
  • ??????
  • ????#?源字符串地址??
  • ????leaw????msgstr,?????????%si??
  • ??????
  • ????movb????$TEXT_COLOR,????%al?????#?屬性值(顏色)??
  • ????movw????len,????????????%cx?????#?顯示的字符個數??
  • ??
  • ??
  • draw_a_char:??????????????
  • ????movsb??
  • ????stosb??
  • ????loop????draw_a_char??
  • ??
  • ??
  • ????ret?
  • 總結

    以上是生活随笔為你收集整理的利用BIOS 中断INT 0x10显示字符和字符串的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。