真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

MacOS環(huán)境-手寫操作系統(tǒng)-07-C語言繪制系統(tǒng)界面-創(chuàng)新互聯(lián)

C語言繪制系統(tǒng)界面

文章寫于兩年前的 MacBookAir(2015)
目前筆者為 MacBookPro M1 (抽查了部分 都運(yùn)行正常)
Github項(xiàng)目地址: https://github.com/wdkang123/MyOperatingSystem
MacOS X86架構(gòu)(x新版的arm架構(gòu)的我沒有 所以大家自行測(cè)試)
VirtualBox
C/C++環(huán)境 (Xcode必裝)

創(chuàng)新互聯(lián)公司長(zhǎng)期為千余家客戶提供的網(wǎng)站建設(shè)服務(wù),團(tuán)隊(duì)從業(yè)經(jīng)驗(yàn)10年,關(guān)注不同地域、不同群體,并針對(duì)不同對(duì)象提供差異化的產(chǎn)品和服務(wù);打造開放共贏平臺(tái),與合作伙伴共同營造健康的互聯(lián)網(wǎng)生態(tài)環(huán)境。為江蘇企業(yè)提供專業(yè)的成都做網(wǎng)站、成都網(wǎng)站制作,江蘇網(wǎng)站改版等技術(shù)服務(wù)。擁有10余年豐富建站經(jīng)驗(yàn)和眾多成功案例,為您定制開發(fā)。1.簡(jiǎn)介

我們的目標(biāo)是做出像windows那樣具備舒心的圖像用戶界面那樣的系統(tǒng),所以在這一節(jié),我們由字符模式切換入畫面模式,初步體驗(yàn)下,那些絢麗多彩的圖像界面是如何發(fā)展而成的。

2.代碼部分

要想由字符模式轉(zhuǎn)入圖形模式,我們需要操作硬件,特別是向顯卡發(fā)送命令,讓其進(jìn)入圖形顯示模式,就如同前面我們所做的,要操作硬件,一般需要使用BIOS調(diào)用,以下幾行就是打開VGA顯卡色彩功能的代碼:

mov  al, 0x13h
mov  ah, 0x00
int  0x10

其中al 的值決定了要設(shè)置顯卡的色彩模式,下面是一些常用的模式設(shè)置:
0x03, 16色字符模式
0x12, VGA圖形模式, 640 * 480 * 4位彩色模式,獨(dú)特的4面存儲(chǔ)模式
0x13, VGA圖形模式, 320 * 200 * 8位彩色模式,調(diào)色板模式
0x6a, 擴(kuò)展VGA圖形模式, 800 * 600 * 4彩色模式

我們采用的是0x13模式,其中3202008 中,最后的數(shù)值8表示的是色彩值得位數(shù),也就是我們可以用8位數(shù)值表示色彩,總共可以顯示256種色彩。

2.1 匯編內(nèi)核
%include "pm.inc"

org   0x9000

jmp   LABEL_BEGIN

[SECTION .gdt]
 ;                                  段基址          段界限                屬性
LABEL_GDT:          Descriptor        0,            0,                   0  
LABEL_DESC_CODE32:  Descriptor        0,      SegCode32Len - 1,       DA_C + DA_32
LABEL_DESC_VIDEO:   Descriptor        0B8000h,         0ffffh,            DA_DRW
LABEL_DESC_VRAM:    Descriptor        0,         0ffffffffh,            DA_DRW
LABEL_DESC_STACK:   Descriptor        0,             TopOfStack,        DA_DRWA+DA_32

GdtLen     equ    $ - LABEL_GDT
GdtPtr     dw     GdtLen - 1
           dd     0

SelectorCode32    equ   LABEL_DESC_CODE32 -  LABEL_GDT
SelectorVideo     equ   LABEL_DESC_VIDEO  -  LABEL_GDT
SelectorStack     equ   LABEL_DESC_STACK  -  LABEL_GDT
SelectorVram      equ   LABEL_DESC_VRAM   -  LABEL_GDT


[SECTION  .s16]
[BITS  16]
LABEL_BEGIN:
     mov   ax, cs
     mov   ds, ax
     mov   es, ax
     mov   ss, ax
     mov   sp, 0100h

     mov   al, 0x13
     mov   ah, 0
     int   0x10

     xor   eax, eax
     mov   ax,  cs
     shl   eax, 4
     add   eax, LABEL_SEG_CODE32
     mov   word [LABEL_DESC_CODE32 + 2], ax
     shr   eax, 16
     mov   byte [LABEL_DESC_CODE32 + 4], al
     mov   byte [LABEL_DESC_CODE32 + 7], ah

     ;set stack for C language
     xor   eax, eax
     mov   ax,  cs
     shl   eax, 4
     add   eax, LABEL_STACK
     mov   word [LABEL_DESC_STACK + 2], ax
     shr   eax, 16
     mov   byte [LABEL_DESC_STACK + 4], al
     mov   byte [LABEL_DESC_STACK + 7], ah

     xor   eax, eax
     mov   ax, ds
     shl   eax, 4
     add   eax,  LABEL_GDT
     mov   dword  [GdtPtr + 2], eax

     lgdt  [GdtPtr]

     cli   ;關(guān)中斷

     in    al,  92h
     or    al,  00000010b
     out   92h, al

     mov   eax, cr0
     or    eax , 1
     mov   cr0, eax

     jmp   dword  SelectorCode32: 0

     [SECTION .s32]
     [BITS  32]
     LABEL_SEG_CODE32:
     ;initialize stack for c code
     mov  ax, SelectorStack
     mov  ss, ax
     mov  esp, TopOfStack

     mov  ax, SelectorVram
     mov  ds,  ax

C_CODE_ENTRY:
     %include "write_vga.asm"


     io_hlt:  ;void io_hlt(void);
      HLT
      RET

SegCode32Len   equ  $ - LABEL_SEG_CODE32

[SECTION .gs]
ALIGN 32
[BITS 32]
LABEL_STACK:
times 512  db 0
TopOfStack  equ  $ - LABEL_STACK

LABEL_DESC_VRAM, 這個(gè)描述符對(duì)應(yīng)的內(nèi)存起始地址是0,長(zhǎng)度是0xffffffff,也就是我們把整個(gè)4G內(nèi)存當(dāng)做一段可讀可寫的內(nèi)存,有了這個(gè)設(shè)置后,我們?cè)贑語言里就可以隨意讀寫內(nèi)存的任何地方。

LABEL_DESC_STACK 這個(gè)描述符用來設(shè)置一段可讀可寫的內(nèi)存,它的起始地址是LABEL_STACK, 可以看到,程序通過語句:times 512 db 0 初始化了512字節(jié)的內(nèi)存

C語言的運(yùn)行,特別是函數(shù)調(diào)用時(shí),是需要一個(gè)堆棧來傳遞參數(shù)的,所以為其配置一個(gè)堆棧

切記后邊分配參數(shù)的時(shí)候 不可大于512 將會(huì)報(bào)錯(cuò)

void fun() {char buf[513];
}

語句%include write_vga.asm”, 表明,我們要開發(fā)的C代碼文件叫write_vga.c, 我們寫完C代碼后,會(huì)使用上一節(jié)的步驟將它編譯成匯編,然后include到我們當(dāng)前的匯編文件里,統(tǒng)一編譯成可執(zhí)行內(nèi)核。

下面的代碼是是進(jìn)入死循環(huán),HLT指令會(huì)讓系統(tǒng)進(jìn)入休眠狀態(tài)

io_hlt: ;void io_hlt(void);
HLT
RET
2.2 C語言

write_ram.c:

void CMain(void) {int i;
    char*p = 0;
    for (i = 0xa0000; i<= 0xaffff; i++) {p = i;
        *p = i & 0x0f;  
    }
    for(;;) {   io_hlt();
    }
}

將指針P指向地址0xa0000, 這個(gè)地址正好就是vga顯存地址,vga顯存地址從0xa0000開始,直到0xaffff結(jié)束,總共64k.接著語句:

*p = i & 0x0f 將一個(gè)數(shù)值寫入顯存,這個(gè)值可以是0-256中任意一個(gè)數(shù)值,我們代碼里是將i的最后4位作為像素顏色寫入顯存,這個(gè)值是任意的,大家可以隨意設(shè)置。

2.3 進(jìn)行編譯(我在mac環(huán)境上 不是烏班圖)

原課程老師是在烏班圖上編譯的(當(dāng)然你也可以選擇在烏班圖上編譯)

但我挑戰(zhàn)一下 在mac上編譯

這里 因?yàn)樵?6節(jié)上 我們已經(jīng)配置了 交叉編譯的環(huán)境

所以我就在mac本地配置了(我當(dāng)前是MacOS BigSur 11.1 )

下面我們一步一步來:(很重要??!)

首先 把C寫的程序gcc編譯走一波:

i386-elf-gcc -m32 -fno-asynchronous-unwind-tables -s -c -o write_vga.o write_vga.c

目錄下會(huì)生成write_vga.o二進(jìn)制文件 接著使用objconv(上節(jié)課里有 也可以自己編譯一個(gè)版本)進(jìn)行反匯編

把objconv拿到這個(gè)目錄下(項(xiàng)目里 我會(huì)打包的)

./objconv -fnasm write_vga.o write_vga.asm

反匯編后代碼如下:

; Disassembly of file: write_vga.o
; Thu Jan 28 14:44:02 2021
; Mode: 32 bits
; Syntax: YASM/NASM
; Instruction set: 80386


global CMain: function

extern io_hlt                                           ; near


SECTION .text   align=1 execute                         ; section number 1, code

CMain:  ; Function begin
        push    ebp                                     ; 0000 _ 55
        mov     ebp, esp                                ; 0001 _ 89. E5
        sub     esp, 24                                 ; 0003 _ 83. EC, 18
        mov     dword [ebp-10H], 0                      ; 0006 _ C7. 45, F0, 00000000
        mov     dword [ebp-0CH], 655360                 ; 000D _ C7. 45, F4, 000A0000
        jmp     ?_002                                   ; 0014 _ EB, 16

?_001:  mov     eax, dword [ebp-0CH]                    ; 0016 _ 8B. 45, F4
        mov     dword [ebp-10H], eax                    ; 0019 _ 89. 45, F0
        mov     eax, dword [ebp-0CH]                    ; 001C _ 8B. 45, F4
        and     eax, 0FH                                ; 001F _ 83. E0, 0F
        mov     dl, al                                  ; 0022 _ 88. C2
        mov     eax, dword [ebp-10H]                    ; 0024 _ 8B. 45, F0
        mov     byte [eax], dl                          ; 0027 _ 88. 10
        inc     dword [ebp-0CH]                         ; 0029 _ FF. 45, F4
?_002:  cmp     dword [ebp-0CH], 720895                 ; 002C _ 81. 7D, F4, 000AFFFF
        jle     ?_001                                   ; 0033 _ 7E, E1
?_003:  call    io_hlt                                  ; 0035 _ E8, FFFFFFFC(rel)
        jmp     ?_003                                   ; 003A _ EB, F9
; CMain End of function


SECTION .data   align=1 noexecute                       ; section number 2, data


SECTION .bss    align=1 noexecute                       ; section number 3, bss



這里還不能直接拿來用 需要處理一下

在上面代碼中去掉以section開始的指令 這些指令會(huì)影響我們把當(dāng)前匯編結(jié)合入內(nèi)核kerne.asm.
同時(shí)去掉開頭的兩句:

global CMain: function
extern io_hlt

處理后變成:(為了防止弄錯(cuò) 留個(gè)對(duì)照)

; Disassembly of file: write_vga.asm
; Thu Jan 28 14:37:46 2021
; Mode: 32 bits
; Syntax: YASM/NASM
; Instruction set: 80386

CMain:  ; Function begin
        push    ebp                                     ; 0000 _ 55
        mov     ebp, esp                                ; 0001 _ 89. E5
        sub     esp, 24                                 ; 0003 _ 83. EC, 18
        mov     dword [ebp-10H], 0                      ; 0006 _ C7. 45, F0, 00000000
        mov     dword [ebp-0CH], 655360                 ; 000D _ C7. 45, F4, 000A0000
        jmp     ?_002                                   ; 0014 _ EB, 16

?_001:  mov     eax, dword [ebp-0CH]                    ; 0016 _ 8B. 45, F4
        mov     dword [ebp-10H], eax                    ; 0019 _ 89. 45, F0
        mov     eax, dword [ebp-0CH]                    ; 001C _ 8B. 45, F4
        and     eax, 0FH                                ; 001F _ 83. E0, 0F
        mov     dl, al                                  ; 0022 _ 88. C2
        mov     eax, dword [ebp-10H]                    ; 0024 _ 8B. 45, F0
        mov     byte [eax], dl                          ; 0027 _ 88. 10
        inc     dword [ebp-0CH]                         ; 0029 _ FF. 45, F4
?_002:  cmp     dword [ebp-0CH], 720895                 ; 002C _ 81. 7D, F4, 000AFFFF
        jle     ?_001                                   ; 0033 _ 7E, E1
?_003:  call    io_hlt                                  ; 0035 _ E8, FFFFFFFC(rel)
        jmp     ?_003                                   ; 003A _ EB, F9
; CMain End of function

接著 我們通過nasm進(jìn)行編譯

nasm -o kernel.bat kernel.asm

運(yùn)行后生成了kernel.bat

這里我們注意 因?yàn)榇a變大了 所以我們?cè)谶\(yùn)行的java的時(shí)候發(fā)現(xiàn)(控制臺(tái)輸出):

Load file kernel.bat to floppy with cylinder: 1 and sector:2
Load file kernel.bat to floppy with cylinder: 1 and sector:3

發(fā)現(xiàn)一個(gè)扇區(qū)已經(jīng)不夠用了(此時(shí)在boot.asm中 我們只讀了一個(gè)扇區(qū))

所以要修改一下boot.asm

(下面是代碼片段)

readFloppy:
    mov          CH, 1        ;CH 用來存儲(chǔ)柱面號(hào)
    mov          DH, 0        ;DH 用來存儲(chǔ)磁頭號(hào)
    mov          CL, 2        ;CL 用來存儲(chǔ)扇區(qū)號(hào)

    mov          BX, LOAD_ADDR       ; ES:BX 數(shù)據(jù)存儲(chǔ)緩沖區(qū)

    mov          AH, 0x02      ;  AH = 02 表示要做的是讀盤操作
    mov          AL,  2        ; AL 表示要練習(xí)讀取幾個(gè)扇區(qū)
    mov          DL, 0         ;驅(qū)動(dòng)器編號(hào),一般我們只有一個(gè)軟盤驅(qū)動(dòng)器,所以寫死   
                               ;為0
    INT          0x13          ;調(diào)用BIOS中斷實(shí)現(xiàn)磁盤讀取功能
   
    JC           fin

    jmp          LOAD_ADDR

這里改成2

mov          AL,  2        ; AL 表示要練習(xí)讀取幾個(gè)扇區(qū)

接著nasm編譯一下boot.asm

最后運(yùn)行java程序 生成system.img

Load file boot.bat to floppy with cylinder: 0 and sector:1
Load file kernel.bat to floppy with cylinder: 1 and sector:2
Load file kernel.bat to floppy with cylinder: 1 and sector:3

這樣我們就完成了在mac上進(jìn)行編譯

而不用在ubuntu上

3.運(yùn)行

將img裝載運(yùn)行:

在這里插入圖片描述

你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機(jī)房具備T級(jí)流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級(jí)服務(wù)器適合批量采購,新人活動(dòng)首月15元起,快前往官網(wǎng)查看詳情吧


網(wǎng)頁標(biāo)題:MacOS環(huán)境-手寫操作系統(tǒng)-07-C語言繪制系統(tǒng)界面-創(chuàng)新互聯(lián)
分享URL:http://weahome.cn/article/dcsoei.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部