時(shí)隔很多年,,重新學(xué)一遍匯編,。覺(jué)得這個(gè)大灰狼學(xué)匯編的視頻很好。
仔細(xì)的聽(tīng),,仔細(xì)的做了筆記,、實(shí)驗(yàn)。感覺(jué)很不錯(cuò),!
繼續(xù)加油?。?/p>
-------------------12-----------------------------
;;;;;;;;;;;;;boot.asm;;;;;;;;;;;;;;;;;;
;我們的啟動(dòng)程序?qū)崿F(xiàn)很簡(jiǎn)單的功能,,在屏幕中央打印一行字符串即可
org 07c00h ;org指令明確告訴編譯器我程序的段地址是7C00h,,而不是原來(lái)的0000
;int匯編指令 “int 10h”調(diào)用bois里的中斷程序:顯示字符串
mov ax,cs
mov es,ax
mov bp,msgstr ;es:bp 指向的內(nèi)容就是我們要顯示的字符串地址了
mov cx,12 ;顯示的字符串長(zhǎng)度
mov dh,12 ;顯示的行號(hào)
mov dl,36 ;顯示的列號(hào)
mov bh,0 ;顯示的頁(yè)數(shù)
mov al,1 ;顯示的是串結(jié)構(gòu)
mov bl,0ch ;顯示的字符屬性
mov ah,13h ;明確調(diào)用13h子程序
msgstr: db "hello my os!"
int 10h
times 510-($-$$) db 0 ;重復(fù)n次每次填充值為0
dw 55aah
jmp $ ;不斷跳轉(zhuǎn)到當(dāng)前位置,是個(gè)死循環(huán)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
/////////////////write_image.c//////////////////////
#include <stdio.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
int main(int argc,char *argv[])
{
int fd_source;
int fd_dest;
int read_count=0;
char buffer[512]={0};
fd_source=open("boot.bin",O_RDONLY);
if(fd_source<0)
{
perror("open boot.bin error:");
return 0;
}
fd_dest=open("v1.vfd",O_WRONLY);
while((read_count=read(fd_source,buffer,512))>0)
{
write(fd_dest,buffer,read_count);
memset(buffer,0,512);
}
printf("write image ok!");
return 0;
}
////////////////////////////////////////////
-----------------13--------------------------------
主要內(nèi)容
實(shí)模式概念
保護(hù)模式概念
選擇子
段描述符
系統(tǒng)地址寄存器
實(shí)模式概念
計(jì)算機(jī)加電后,,cpu就默認(rèn)屬于real-model(實(shí)模式)下
實(shí)模式只能訪問(wèn)地址在1M以下的內(nèi)存稱為常規(guī)內(nèi)存,,我們把地址在1M以上的內(nèi)存稱為擴(kuò)展內(nèi)存。
seg:offset 20位地址,,只能訪問(wèn)1M空間
通過(guò)這種組合指向的內(nèi)存地址就是實(shí)際的物理內(nèi)存地址
32位cpu
intel退出32位cpu時(shí)完全兼容了16位cpu,。
所謂兼容其中很重要的一點(diǎn)就是可以繼續(xù)使用16位的內(nèi)存尋址方式。
大家都知道16cpu內(nèi)存尋址是通過(guò)段寄存器:通用寄存器來(lái)表示實(shí)際的內(nèi)存地址,。
32位cpu地址線32根,,最大內(nèi)存為4GB,如何利用原來(lái)的seg:offset(實(shí)現(xiàn)20根地址線)表示方式,,來(lái)表示32根地址線,?
保護(hù)模式
在保護(hù)模式下cpu依然使用段寄存器和通用寄存器來(lái)表示內(nèi)存地址,但如何用20位地址來(lái)實(shí)現(xiàn)32位地址線尋址能力?
有張表,,紀(jì)錄段地址 開(kāi)始地址 大?。ǘ谓缦蓿?屬性
16位段寄存器紀(jì)錄表的【【索引】】
新的內(nèi)容訪問(wèn)思路
在實(shí)模式下,我們把內(nèi)存分成一個(gè)個(gè)內(nèi)存段來(lái)表示,,那么在保護(hù)模式下內(nèi)存也被分為一個(gè)個(gè)內(nèi)存段表示,。
那么我們就把實(shí)現(xiàn)分好的內(nèi)存段信息存入一張表格中,然后段寄存器中保存你要訪問(wèn)內(nèi)存段所在的這張表格的索引,。
保存表中索引的段寄存器,,我們稱為段選擇子。
表中每個(gè)表示32位內(nèi)存段信息我們稱之為段描述符,。
整張表稱之為【【段描述符表】】,。
段選擇子
段選擇子16位(段寄存器16位),其中高13位存放描述符表中的索引,,其低3位用來(lái)表示段描述符表中所指向的段描述符的屬性,。
因此表中段描述符最大個(gè)數(shù)為2^13=8096個(gè)。
TI(Table Indicator):用來(lái)表示是從全局描述符表中讀取描述符還是從局部描述符表中讀取描述符,。
RPL(Request Priviledge Level):用于特權(quán)檢查.
形成物理地址
段寄存器-(索引號(hào))-->段描述符表--->段描述符A--->線性地址空間(物理地址) 不考慮分頁(yè)時(shí),,線性地址=物理地址
段描述符結(jié)構(gòu)
既然段描述符包含了段的開(kāi)始地址和段的界限,那么了解該結(jié)構(gòu)至關(guān)重要
段描述符共8個(gè)字節(jié),,每個(gè)字節(jié)都具有具體含義
段界限(segment limit)20位被分為兩個(gè)部分,第一部分保存在1,,2字節(jié)中,,第二部分保存在7
段基地址(segment base)32位被分成兩個(gè)部分,第一部分23個(gè)字節(jié)被存放在3,,4,,5字節(jié)中,第二部分放在8
段屬性(attributes)包含了該段屬性和段界限的第二部分
段基地址剩余部分(base)包含了段界限剩余的8位
內(nèi)存分配
由于我們現(xiàn)在編寫的在裸機(jī)上編寫程序,,因此內(nèi)存必須我們自己在4GB內(nèi)存中進(jìn)行分配
-----------------14--------------------------
段屬性
段屬性位于段描述符的第6和第7個(gè)字節(jié),,用來(lái)描述該段是數(shù)據(jù)段還是代碼段或者堆棧段,對(duì)于數(shù)據(jù)段或者堆棧段來(lái)說(shuō)是否可讀是否可寫,,
對(duì)于代碼段來(lái)說(shuō)是否可執(zhí)行以及段描述符所指定的內(nèi)存段在物理內(nèi)存中是否存在,。
從左往右
0~3 TYPE :說(shuō)明存儲(chǔ)段描述符所描述的存儲(chǔ)段的具體屬性。是屬于代碼段還是數(shù)據(jù)段,,可讀可寫還是可執(zhí)行,。
4 DT :說(shuō)明了該描述符所指定的系統(tǒng)端描述符海華絲存儲(chǔ)段描述符。
5~6 DPL :表示描述符特權(quán)級(jí)別,。
7 P :表示描述符對(duì)地址的轉(zhuǎn)換是否有效,。
第二個(gè)字節(jié)
0~3 Limit :段界限第二部分剩余的4位。
4 AVL :軟件可利用完,80386對(duì)該位未做規(guī)定
5 :0
6 D :表示如果該段是代碼段,,是否是16位還是32位代碼段,,如果該段是數(shù)據(jù)段是否是16還是32位,1表示32位
7 G :段界限粒度位G=0表示段邊界64k,,G=1表示段邊界4GB
段界限
我們既然分了8M的內(nèi)存段,,那么段界限就是8M,那么8M占用多少字節(jié),,怎樣用16進(jìn)制表示并爭(zhēng)取填充到段描述符中呢,?
8M=2^23=800000H
不能直接把800000這個(gè)16進(jìn)制直接寫段描述符的相應(yīng)位置中,并且20位的段界限 23位二進(jìn)制數(shù)如何解決,?
段界限公式
段界限=limit*4k+0FFFH
800000=limit*4k+0FFFH
limit就是要填寫到段描述符中的段界限位置
limit=(800000-0FFFH)/4k=7FFH
段描述符的填寫
我們的偏移地址都是通過(guò)8M通過(guò)公式得出段界限為7FF
我們第一個(gè)內(nèi)存的段從內(nèi)存00000處開(kāi)始,,所以段基地址全為0
那么我們創(chuàng)建的段位數(shù)據(jù)段并且是可讀可寫的,那么就必須在attributes字段中填寫相應(yīng)的數(shù)據(jù),。
base attributes segment base segment limit
0000 000000000000 07FF
TYPE :我們定義的是數(shù)據(jù)段并且我們要求該段可讀可寫那么tpye值填為0010,,如果我們創(chuàng)建的是代碼段可讀可執(zhí)行,那么為1010
DT :DT用來(lái)區(qū)別系統(tǒng)段還是存儲(chǔ)段,,我們這邊都是存儲(chǔ)段,。
DPL :表示內(nèi)存段的權(quán)限,這里為00表示
P :表示描述符對(duì)地址轉(zhuǎn)換是否有效,,1表示有效
Limit:表示剩余4位段界限描述符 0000
AVL :保留為0
D :1 我們編寫的是保護(hù)模式,,32位
G :1
數(shù)據(jù)段描述符
根據(jù)以上內(nèi)容我們可以定義符合數(shù)據(jù)段描述符的匯編代碼
dw 07FFh ;段界限
dw 0h ;段基地址0~18位
db 0h ;段基地址19~23位
db 10010010b ;段描述符的第6個(gè)字節(jié)屬性(數(shù)據(jù)段可讀可寫)
db 11000000b ;段描述符的第7個(gè)字節(jié)屬性
db 0 ;段描述符的最后一個(gè)字節(jié)也就是段基地址的第二部分
代碼段描述符
代碼段描述符和數(shù)據(jù)段描述符基本一致,不同在于段基地址和段屬性
dw 07FFh ;段界限(保持不變)
dw 1h ;段基地址0~18位