亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

  免費(fèi)注冊 查看新帖 |

Chinaunix

  平臺 論壇 博客 文庫
最近訪問板塊 發(fā)新帖
查看: 1017 | 回復(fù): 0
打印 上一主題 下一主題

段機(jī)制輕松體驗(yàn)一 [復(fù)制鏈接]

論壇徽章:
0
跳轉(zhuǎn)到指定樓層
1 [收藏(0)] [報(bào)告]
發(fā)表于 2008-06-02 19:24 |只看該作者 |倒序?yàn)g覽
段機(jī)制輕松體驗(yàn)一
2007-07-24  09:09
段機(jī)制輕松體驗(yàn)
內(nèi)存尋址:
實(shí)模式下的內(nèi)存尋址:
讓我們首先來回顧實(shí)模式下的尋址方式
段首地址×16+偏移量 = 物理地址
為什么要×16?因?yàn)樵?086CPU中,地址線是20位,但寄存器是16位的,最高尋址64KB,它無法尋址到1M內(nèi)存。于是,Intel設(shè)計(jì)了這種尋
址方式,先縮小4位成16位放入到段寄存器,用到時候,再將其擴(kuò)大到20位,這也造成了段的首地址必須是16的倍數(shù)的限制。

公式:xxxx:yyyy
保護(hù)模式下分段機(jī)制的內(nèi)存尋址:
分段機(jī)制是利用一個稱作段選擇符的偏移量,從而到描述符表找到需要的段描述符,而這個段描述符中就存放著真正的段的物理首地址,再加上偏移量

一段話,出現(xiàn)了三個新名詞:
段選擇子
描述符表
段描述符
================================
我們現(xiàn)在可以這樣來理解這段話:
有一個結(jié)構(gòu)體類型,它有三個成員變量:
段物理首地址
段界限
段屬性

內(nèi)存中,維護(hù)一個該結(jié)構(gòu)體類型的數(shù)組。
而分段機(jī)制就是利用一個索引,找到該數(shù)組對應(yīng)的結(jié)構(gòu)體,從而得到段的物理首地址,然后加上偏移量,得到真正的物理地址。
公式:xxxx:yyyyyyyy
其中,xxxx也就是索引,yyyyyyyy是偏移量(因?yàn)?2位寄存器,所以8個16進(jìn)制)xxxx存放在段寄存器中。
================================
現(xiàn)在,我們來到過來分析一下那三個新名詞:
段描述符:一個結(jié)構(gòu)體,它有三個成員變量:
段物理首地址
段界限
段屬性

     描述符表:也就是一個數(shù)組,什么樣的數(shù)組呢?是一個段描述符組成的數(shù)組。
段選擇子:      也就是數(shù)組的索引,但這時候的索引不在是高級語言中數(shù)組的下標(biāo),而是我們將要找的那個段描述符相對于數(shù)組首地址(也就是全局描述表的首地址)偏移位置。
就這么簡單,如圖:

圖中,通過Selector(段選擇子)找到存儲在Descriptor Table(描述符表)中某個Descriptor(段描述符),該段描述符中存放有該段的物理首地址,所以就可以找到內(nèi)存中真正的物理段首地址Segment
Offset(偏移量):就是相對該段的偏移量
物理首地址 + 偏移量 就得到了物理地址    本圖就是DATA
但這時,心細(xì)的朋友就發(fā)現(xiàn)了一個GDTR這個家伙還沒有提到!
我們來看一下什么是GDTR
Global Descriptor Table Register(全局描述符表寄存器)
但是這個寄存器有什么用呢 ?
大家想一下,段描述符表現(xiàn)在是存放在內(nèi)存中,那CPU是如何知道它在哪里呢?所以,Iterl公司設(shè)計(jì)了一個全局描述符表寄存器,專門用來存放段描述符表的首地址,以便找到內(nèi)存中段描述符表。
這時,段描述符表地址被存到GDTR寄存器中了。
=================================
好了,分析就到這,我們來看一下正式的定義:
當(dāng)x86 CPU 工作在保護(hù)模式時,可以使用全部32根地址線訪問4GB的內(nèi)存,因?yàn)?0386的所有通用寄存器都是32位的,所以用任何一個通用寄存器來間接尋址,不比分段就可以訪問4G空間中任意的內(nèi)存地址。
但這并不意味著,此時段寄存器就不再有用了。實(shí)際上,段寄存器更加有用了,雖然再尋址上沒有分段的限制了,但在保護(hù)模式下,一個地址空間是否可以被寫入,
可以被多少優(yōu)先級的代碼寫入,是不是允許執(zhí)行等等涉及保護(hù)的問題就出來了。要解決這些問題,必須對一個地址空間定義一些安全上的屬性。段寄存器這時就派上
了用場。但是設(shè)計(jì)屬性和保護(hù)模式下段的參數(shù),要表示的信息太多了,要用64位長的數(shù)據(jù)才能表示。我們把著64位的屬性數(shù)據(jù)叫做段描述符,上面說過,它包含
3個變量:
段物理首地址、段界限、段屬性
80386的段寄存器是16位(注意:通用寄存器在保護(hù)模式下都是32位,但段寄存器沒有被改變)的,無法放下保護(hù)模式下64位的段描述符。如何解決這個
問題呢?方法是把所有段的段描述符順序存放在內(nèi)存中的指定位置,組成一個段描述符表(Descriptor
Table);而段寄存器中的16位用來做索引信息,這時,段寄存器中的信息不再是段地址了,而是段選擇子(Selector)?梢酝ㄟ^它在段描述符表
中“選擇”一個項(xiàng)目已得到段的全部信息。
那么段描述符表存放在哪里呢?80386引入了兩個新的寄存器來管理段描述符,就是GDTR和LDTR,(LDTR大家先忘記它,隨著學(xué)習(xí)的深入,我們會在以后學(xué)習(xí))。
這樣,用以下幾步來總體體驗(yàn)下保護(hù)模式下尋址的機(jī)制
1、段寄存器中存放段選擇子Selector
2、GDTR中存放著段描述符表的首地址
3、通過選擇子根據(jù)GDTR中的首地址,就能找到對應(yīng)的段描述符
4、段描述符中有段的物理首地址,就得到段在內(nèi)存中的首地址
5、加上偏移量,就找到在這個段中存放的數(shù)據(jù)的真正物理地址。
好的,那我們開始編碼,看看如何實(shí)現(xiàn)先前描述的內(nèi)容
=================================
首先,既然我們需要一個數(shù)組,全局描述符表,那我們就定義一塊連續(xù)的結(jié)構(gòu)體:
[SECTION .gdt]    ;為了代碼可讀性,我們將這個數(shù)組放到一個節(jié)中
;由一塊連續(xù)的地址組成的,不就是一個數(shù)組嗎?看下面代碼,^_^

段基地址    段界限 段屬性
GDT_BEGIN: Descriptor 0,       0,    0  
GDT_CODE32: Descriptor 0,    0,    DA_C

;上面,我定義了二個連續(xù)地址的結(jié)構(gòu)體,大家先認(rèn)為Descriptor就是一個結(jié)構(gòu)體類型,我們會在以后詳細(xì)講述
;第一個結(jié)構(gòu)體,全部是0,是為了遵循Interl規(guī)范,先記得就OK
;第二個定義了一個代碼段,段基地址和段界限我們暫且還不知道,先初始化為0,但是因?yàn)槭莻代碼段,代碼段具備執(zhí)行的屬性,那么DA_C就代表是一個可執(zhí)行代碼段,DA_C是一個預(yù)先定義好的常量,我們會在詳細(xì)講解段描述符中講解。
=================================
我們繼續(xù)來實(shí)現(xiàn),那么下面,我們就需要設(shè)計(jì)段選擇子了,因?yàn)樯厦娲a已經(jīng)包含了段描述符和全局描述符表
還記得選擇子是個什么東西嗎 ?
段選擇子:      也就是數(shù)組的索引,但這時候的索引不在是高級語言中數(shù)組的下標(biāo),而是我們將要找的那個段描述符相對于數(shù)組首地址(也就是全局描述表的首地址)偏移位置。
看我代碼怎么實(shí)現(xiàn),包含以上代碼不再說明:
[SECTION .gdt]
GDT_BEGIN: Descriptor 0, 0, 0
GDT_CODE32: Descriptor 0, 0, DA_C

;下面是定義代碼段選擇子,它就是相對數(shù)組首地址的偏移量
SelectorCode32 equ    GDT_CODE32 - GDT_BEGIN
;因?yàn)榈谝粋段描述符,不被使用,所以就不比設(shè)置段選擇子了。
=================================
偏移地址:
注意一點(diǎn),我們在程序中使用的都是偏移地址,相對于段的偏移地址,用上面的例子來說,象 GDT_CODE32 GDT_BEGIN 這些結(jié)構(gòu)體的首地址都是相對于數(shù)據(jù)段的偏移量。什么意思呢 ?
因?yàn)槲覀兊某绦虻降准虞d到內(nèi)存的哪個地方是不固定,不知道的,只需使用偏移地址操作就行了,如:
SelectorCode32 ,它本身就是一個偏移地址

但是SelectorCode32    equ GDT_CODE32 - GDT_BEGIN
怎么解釋呢 ?
GDT_CODE32是相對于數(shù)據(jù)段的偏移量,
GDT_BEGIN也是相對于數(shù)據(jù)段的偏移量,雖然它是數(shù)組的首地址,說的羅索一些,GDT_BEGIN是數(shù)組的首地址,但是它是相對于數(shù)據(jù)段的偏移量
那么兩個偏移量相減就是GDT_CODE32 相對于GDT_BEGIN的偏移量

所以,我們要時時刻刻記得,在程序中,我們永遠(yuǎn)使用的是偏移量,因?yàn)槲覀儾恢莱绦驅(qū)⒁患虞d內(nèi)存那塊地方。
好了,基礎(chǔ)也學(xué)的差不多了,下面我們要自己動手寫一段程序,實(shí)現(xiàn)實(shí)模式到保護(hù)模式之間的跳轉(zhuǎn)
=====================================================================
;實(shí)現(xiàn)從實(shí)模式到保護(hù)模式之間的跳轉(zhuǎn)
;參考:《自己動手寫操作系統(tǒng)》
----------------------------------------------------------------------
%include "pm.inc"

org 0100h
jmp LABEL_BEGIN

[SECTION .gdt]
GDT_BEGIN: Descriptor 0,    0,     0
GDT_CODE32: Descriptor 0,    LenOfCode32 - 1, DA_C + DA_32
GDT_VIDEO: Descriptor 0B8000H, 0FFFFH,     DA_DRW

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

;定義段選擇子
SelectorCode32 equ    GDT_CODE32 - GDT_BEGIN
SelectorVideo equ    GDT_VIDEO - GDT_BEGIN

[SECTION .main]
[BITS 16]
LABEL_BEGIN:
mov ax, cs
mov ds, ax
mov es, ax
mov ss, ax
;初始化32位代碼段選擇子
;我們可以在實(shí)模式下通過段寄存器×16 + 偏移兩 得到物理地址,
;那么,我們就可以將這個物理地址放到段描述符中,以供保護(hù)模式下使用,
;因?yàn)楸Wo(hù)模式下只能通過段選擇子 + 偏移量

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

;得到段描述符表的物理地址,并將其放到GdtPtr中
xor eax, eax
mov ax, ds
shl eax, 4
add eax, GDT_BEGIN
mov dword [GdtPtr + 2],eax
;加載到gdtr,因?yàn)楝F(xiàn)在段描述符表在內(nèi)存中,我們必須要讓CPU知道段描述符    表在哪個位置
;通過使用lgdtr就可以將源加載到gdtr寄存器中
lgdt [GdtPtr]

;關(guān)中斷
cli

;打開A20線
in al, 92h
or al, 00000010b
out 92h, al

;準(zhǔn)備切換到保護(hù)模式,設(shè)置PE為1
mov eax, cr0
or eax, 1
mov cr0, eax

;現(xiàn)在已經(jīng)處在保護(hù)模式分段機(jī)制下,所以尋址必須使用段選擇子:偏移量來    尋址
;跳轉(zhuǎn)到32位代碼段中
;因?yàn)榇藭r偏移量位32位,所以必須dword告訴編譯器,不然,編譯器將階段    成16位
jmp dword SelectorCode32:0;跳轉(zhuǎn)到32位代碼段第一條指令開始執(zhí)行


[SECTION .code32]
[BITS 32]
LABEL_CODE32:
mov ax, SelectorVideo
mov es, ax

xor edi, edi
mov edi, (80 * 10 + 10)

mov ah, 0ch
mov al, 'G'

mov [es:edi],ax
jmp $
LenOfCode32 equ $ - LABEL_CODE32
===================================
這段代碼的大概意思是:
先在16位代碼段,實(shí)模式下運(yùn)行,在實(shí)模式下,通過段寄存器×16+偏移量得到32位代碼的真正物理首地址,并將放入到段描述符表中,以供在保護(hù)模式下使
用,上面說過了,保護(hù)模式下尋址,是通過段選擇子,段描述符表,段描述符一起工作尋址的。所以在實(shí)模式下所做的工作就是初始化段描述符表里的所有段描述
符。
我們來看一下段描述符表,它有3個段:
GDT_BEGIN
GDT_CODE32
GDT_VIDEO

GDT_BEGIN,遵循Intel公司規(guī)定,全部置0
GDT_CODE32,32位代碼段描述符,供保護(hù)模式下使用
GDT_VIDEO,顯存段首地址,我們知道,顯存首地址是0B8000H.

回想一下,我們在實(shí)模式下往顯示器上輸出文字時,我們設(shè)置段寄存器為
0B800h,(注意后面比真正物理地址少一個0)。
而我們現(xiàn)在在保護(hù)模式下訪問顯存,那么0B8000h就可以直接放到段描述符中即可。因?yàn)槎蚊枋龇写娣诺氖嵌蔚恼嬲奈锢淼刂贰?/strong>
下面我們來逐行分析該代碼
org    0100h
這句話告訴加載器,將這段程序加載到偏移段首地址0100h處,即:偏移256字節(jié)處,為什么要加載到偏移256個字節(jié)處呢 ?這是因?yàn),在DOS中,需要留下256個字節(jié)和DOS系統(tǒng)進(jìn)行通信。
jmp    LABEL_BEGIN
執(zhí)行這句話就跳轉(zhuǎn)到LABEL_BEGIN處開始執(zhí)行。
好,我們看一下LABEL_BEGIN在那塊,也就是16位代碼段
[SECTION .main]
[BITS 16]
LABEL_BEGIN:
這樣程序就從.main節(jié)的第一段代碼開始執(zhí)行。
我們看一下上面的代碼,[BITS 16]告訴編譯器,這是一個16位代碼段,所使用的寄存器都是16位寄存器。
該代碼段初始化所有段描述符表中的段物理首地址

首先在實(shí)模式下計(jì)算出32位代碼段的物理首地址
對照    段值 × 16 + 偏移量    = 物理地址

1    mov ax,    cs
2    shl eax, 4    ;向左移動4位,不就是×16嗎?呵呵
;到現(xiàn)在為止,eax就是代碼段的物理首地址了,那么。。。看
3    add eax, LABEL_CODE32
;為eax (代碼段首地址)加上 LABEL_CODE32偏移量,得到的不就是LABEL_CODE32的真正物理地址了嗎 ?LABEL_CODE32在程序中,不就是32位代碼段的首地址嗎 ?

上面說過,代碼中,使用的變量,或者標(biāo)簽 都是相對程序物理首地址的偏移量。
OK,現(xiàn)在我們已經(jīng)知道了32位代碼段的物理首地址,那么將eax放入到段描述符中就行了
我們先假設(shè)Descriptor就是一個結(jié)構(gòu)體類型,(實(shí)際它是一個宏定義的數(shù)據(jù)結(jié)構(gòu),為了不影響整體思路,我們放到以后講)
看一下這個Descriptor段描述符的內(nèi)存模型:

; 高地址………………………………………………………………………低地址
; |     7     |     6     |     5     |     4     |     3     |     2     |     1     |     0      |
共 8 字節(jié)
; |--------========--------========--------========--------========|
; ┏━━━┳━━━━━━━┳━━━━━━━━━━━┳━━━━━━━┓
; ┃31..24┃     段屬性       ┃       段基址(23..0)      ┃ 段界限(15..0)┃
; ┃        ┃                ┃        |                 ┃                ┃
; ┃ 基址2┃               ┃基址1b│     基址1a       ┃      段界限1 ┃
; ┣━━━╋━━━┳━━━╋━━━━━━━━━━━╋━━━━━━━┫
; ┃     %6 ┃    %5    ┃    %4    ┃    %3    ┃       %2         ┃         %1       ┃
; ┗━━━┻━━━┻━━━┻━━━┻━━━━━━━┻━━━━━━━┛

由于歷史原因,段描述符的內(nèi)存排列不是按照 段基地址 段界限 段屬性 這樣的來排列的,所以我們現(xiàn)在要想一種辦法,把eax里所存放的物理首地址拆開,分別放到2,3,4,7字節(jié)處
那么很顯然,我們可以將eax寄存器中的ax先放到2,3字節(jié)處
mov    word [GDT_CODE32 + 2],ax
因?yàn)樵谄?個字節(jié)處,所以,首地址 + 2,才能定位到下標(biāo)為2的字節(jié)開頭處
而,word 告訴編譯器,我要一次訪問2個字節(jié)的內(nèi)存

好,簡單的搞定了,那么再看,我們現(xiàn)在要將eax高16字節(jié)分別放到下標(biāo)為4,7字節(jié)處。
雖然eax的ax代表低16位,但是Intel并沒有給高位一個名字定義,(不會是high ax,呵呵),所以,我們沒有辦法去訪問高位。但是我們可以將高16位放到低16位中,因?yàn)檫@時,低16位我們已經(jīng)不關(guān)心它的值了。
好,看代碼
shr    eax,    16
這句代碼就將eax向右移動16位,低位被拋棄,高位變成了低位。呵呵。。。

現(xiàn)在好辦了,低16位又可以分為al,和 ah,那么現(xiàn)在我們就將al放到4位置,ah放到7位置吧
mov    byte [GDT_CODE32 + 4], AL
mov    byte [GDT_CODE32 + 7], AH
不用我再解釋這段代碼了,自己去分析為什么吧。。。。

好了,32位代碼段描述符設(shè)置好了,其界限設(shè)置看代碼吧,為什么要那樣設(shè)置,很簡單的,界限 = 長度 - 1,段屬性:
DA_C: 98h      可執(zhí)行
DA_32: 4000h 32位代碼段
是個常量,換算成二進(jìn)制位,對照段描述符屬性位置去看吧,參考任意一本保護(hù)模式書。

段描述符設(shè)置好了,但是,先段描述符表,還在內(nèi)存中,我們必須想辦法放到寄存器中,這時,就用到了gdtr(Golbal Descriptor Table Register),使用一條指令
lgdtr [GdtPtr]

就可以將GdtPtr加載到gdtr中
而gdtr的內(nèi)存模型是:
高字節(jié)                                   低字節(jié)

但GdtPtr是什么呢 ?
就是我們定義的和這個寄存器內(nèi)存模型一摸一樣的結(jié)構(gòu)體:
GdtLen    equ    $ - LABEL_BEGIN
GdtPtr    dw    GdtLen - 1     ;界限
dd    0       ;真正物理地址
那現(xiàn)在我們就要計(jì)算GdtPtr第二個字節(jié) 也就是真正物理地址了
xor eax, eax
mov ax,    ds
shl eax, 4
add eax, GDT_BEGIN
mov dword [GdtPtr + 2],eax
自己分析吧,和計(jì)算32位段首地址基本一樣的,
搞定后,使用lgdt [GdtPtr]就將此加載到寄存器GDTR中了

然后關(guān)中斷
cli    實(shí)模式下的中斷和保護(hù)模式下的中斷處理不一樣,那就關(guān)吧,規(guī)矩
開啟A20線
in al, 92h
or al, 00000010b
out 92h, al
如果不開啟A20線,就無辦法訪問1M之上的內(nèi)存,沒辦法,開啟吧,規(guī)矩,想知道歷史了,去查吧

然后設(shè)置CR0的PE位
mov eax, cr0
or eax, 1
mov cr0, eax
這個簡單說一下,以后再詳細(xì)
CR0也是一個寄存器,其中有個PE位,如果為0,就說明為實(shí)模式,
如果置1,說明為保護(hù)模式,F(xiàn)在我們要進(jìn)入保護(hù)模式下工作,那么就要設(shè)置PE為1。

好了,看一下這個main節(jié)中的最后一個代碼
jmp    dword SelectorCode32 : 0
哈哈,現(xiàn)在已經(jīng)再保護(hù)模式下了,當(dāng)然要使用段選擇子 + 偏移量來尋址啊,這樣不就是尋址到了32位代碼段中去了嗎,偏移量為0不就說明從第一個代碼開始執(zhí)行。
不是嗎 ?呵呵,那dword了?
因?yàn)楝F(xiàn)在的代碼段是16位,編譯器只能將它編譯位16位,但處于保護(hù)模式下,它的偏移量應(yīng)該是32位,所以,要顯示告訴編譯器,我這里使用的是32位,把我這塊給編譯成32位的。。
如果不加dword,
jmp    SelectorCode32:0
這句話不會出什么問題,16位的0是0,32位的0還是0,但如果這樣呢?:
jmp    SelectorCode32:0x12345678
跳轉(zhuǎn)到偏移0x12345678中,這時就錯了
如果不將dword,編譯器就將該地址截?cái)喑?6位,取低位,變成了0x5678
你說對嗎 ?哈哈
所以我們必須這樣做:
jmp    dword SelectorCodde32:0x12345678

OKEY,我們繼續(xù)追擊,執(zhí)行完上面那個跳轉(zhuǎn)后,
代碼就跳到了32位代碼段的中,開始執(zhí)行第一條指令
mov ax, SelectorVideo
再看
mov es,ax
呵呵,實(shí)模式下,放的是16位的段值,而現(xiàn)在呢,不就是要將段選擇子放到段寄存器里嗎 ?然后通過段選擇子(偏移量)找到描述符表中對應(yīng)的段描述符的嗎 。。!
繼續(xù)看下面代碼
xor edi, edi
mov edi, (80 * 10 + 10)

mov ah, 0ch
mov al, 'G'
跟實(shí)模式下差不多,設(shè)置目標(biāo)10行10列
設(shè)置現(xiàn)實(shí)字符:G
mov [es:edi],ax
也和實(shí)模式下一樣,
只不過實(shí)模式是這樣來尋址 :
es×16 + edi
而保護(hù)模式下呢
es是一個偏移,根據(jù)這個偏移找到段描述符表中的對應(yīng)顯存段,然后這個顯存段里存放的就是0B8000h,然后在加上偏移 不就的了嗎。!
哈哈 。。。。程序分析完畢,細(xì)節(jié)之處,自己體會去

總結(jié):
1. 注意程序中使用的全部是偏移地址。注意兩種偏移地址

A 對于程序的起始地址來說,所有變量和標(biāo)簽都是相對于整個程序的偏移量
B 對于段中定義的代碼,有兩種偏移:
相對于程序起始地址的偏移
相對于段標(biāo)簽的偏移。

2.不管是實(shí)模式下的物理地址,還是保護(hù)模式下的物理地址,反正他們都是物理地址,呵呵,實(shí)模式下求的物理地址,也能在保護(hù)模式下使用,只是他們不同的是,如何尋址的方式不一樣。
3.一個程序中可以包含多個不同位的段,32位或者16位,他們之間也可以互相跳轉(zhuǎn),只是32位段用的是32位寄存器,16位代碼段用的是16位寄存器,如果要在16位段下使用32位寄存器,必須象高級語言中強(qiáng)制類型轉(zhuǎn)換一樣,顯示的定義 dword
參考:
《自動動手寫操作系統(tǒng)》
《Undocument Windows 2000 Secrets》
《Linux 內(nèi)核完全剖析》
文章源地址:   
http://hi.baidu.com/guoxiabin/blog/item/4f378258c04fed83810a18cc.html
   
               
               
               

本文來自ChinaUnix博客,如果查看原文請點(diǎn):http://blog.chinaunix.net/u2/62361/showart_724110.html
您需要登錄后才可以回帖 登錄 | 注冊

本版積分規(guī)則 發(fā)表回復(fù)

  

北京盛拓優(yōu)訊信息技術(shù)有限公司. 版權(quán)所有 京ICP備16024965號-6 北京市公安局海淀分局網(wǎng)監(jiān)中心備案編號:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年舉報(bào)專區(qū)
中國互聯(lián)網(wǎng)協(xié)會會員  聯(lián)系我們:huangweiwei@itpub.net
感謝所有關(guān)心和支持過ChinaUnix的朋友們 轉(zhuǎn)載本站內(nèi)容請注明原作者名及出處

清除 Cookies - ChinaUnix - Archiver - WAP - TOP