程序是怎樣跑起來(lái)的

第一章 對(duì)程序員來(lái)說CPU是什么

  • CPU四個(gè)構(gòu)成部分


    image.png
  • 寄存器種類


    image.png
  • 程序計(jì)數(shù)器 PC
    保存下一條要執(zhí)行的命令的內(nèi)存地址

  • 標(biāo)志寄存器處理?xiàng)l件分支(if else)和循環(huán)機(jī)制(for(;;i<100))


    image.png
  • 棧寄存器實(shí)現(xiàn)函數(shù)調(diào)用機(jī)制


    image.png
  • 基址寄存器和變址寄存器實(shí)現(xiàn)數(shù)組功能


    image.png
  • 機(jī)器語(yǔ)言指令種類


    image.png

第二章 數(shù)據(jù)是用二進(jìn)制表示的

  • IC的所有引腳只有直流電壓0V或5V兩個(gè)狀態(tài),這個(gè)特性決定了計(jì)算機(jī)只能使用二進(jìn)制


    image.png
  • 負(fù)數(shù)的二進(jìn)制表示:補(bǔ)數(shù) 取反加一


    image.png
  • 邏輯右移 空出來(lái)的位置補(bǔ)0


    image.png
  • 算數(shù)右移 空出來(lái)的位置用移位前符號(hào)位的值

  • 邏輯左移,算數(shù)左移都是補(bǔ)零

  • 邏輯運(yùn)算


    image.png

計(jì)算機(jī)進(jìn)行小數(shù)運(yùn)算時(shí)出錯(cuò)的原因

  • 將0.1累加100次的結(jié)果不是10,因?yàn)槭M(jìn)制的0.1在二進(jìn)制中是無(wú)限循環(huán)小數(shù)0.0001100110011001100(無(wú)數(shù)個(gè)1100),類似十進(jìn)制的1/3=0.3333333


    image.png
  • 什么是單精度浮點(diǎn)數(shù) float
    由下面三部分組成,占位32位

    | 符號(hào)位 | 指數(shù)位(8 bit) | 尾數(shù)位(23 bit) | 
    | :-:   | :-:           | :-:           |
    

    符號(hào)位(1位)

    1 : 表示負(fù)數(shù)
    0 : 表示正數(shù)
    

    指數(shù)位(8位) 使用EXCESS系統(tǒng)表現(xiàn),值域位[-127,128]


    image.png

    尾數(shù)位(24位)
    先把小數(shù)轉(zhuǎn)成二進(jìn)制小數(shù),比如11.1875的二進(jìn)制小數(shù)為1011.0011


    image.png

    值域表示區(qū)間為
    正數(shù): [1.401298 * 10^-45, 3.402823 * 10^38]
    負(fù)數(shù): [-3.402823 * 10^38, -1.401298 * 10^-45]
    
  • 什么是雙精度浮點(diǎn)數(shù) double
    跟float類似,占64位

    | 符號(hào)位 | 指數(shù)位(11 bit) | 尾數(shù)位(52 bit) | 
    | :-:   | :-:           | :-:           |
    

    值域表示區(qū)間為

    正數(shù): [4.94065645841247 * 10^-324, 1.79769313486232 * 10^308]
    負(fù)數(shù): [-1.79769313486232 * 10^308, -4.94065645841247 * 10^-324]
    

第四章 熟練使用有棱有角的內(nèi)存

  • 內(nèi)存的物理機(jī)制


    image.png
  • 數(shù)組的內(nèi)存模型


    image.png

第五章 內(nèi)存和磁盤的親密關(guān)系

  • 虛擬內(nèi)存把磁盤作為部分內(nèi)存來(lái)使用
  • 靜態(tài)鏈接
    從目標(biāo)文件中抽對(duì)應(yīng)代碼出來(lái)放到應(yīng)用程序的目標(biāo)文件,多個(gè)應(yīng)用則會(huì)有多份同樣的代碼,浪費(fèi)內(nèi)存


    image.png
  • 動(dòng)態(tài)鏈接 DLL
    同一個(gè)DLL文件的內(nèi)容運(yùn)行時(shí)可以被多個(gè)應(yīng)用共有,內(nèi)存利用率高,修改dll文件無(wú)需重新編譯應(yīng)用


    image.png
  • 磁盤物理結(jié)構(gòu)
    Windows采用扇區(qū)方式劃分磁盤,扇區(qū)是磁盤進(jìn)行物理讀寫的最小單位,Windows對(duì)磁盤進(jìn)行邏輯讀寫的最小單位是簇,1簇=n*扇區(qū),也就是一次讀寫多個(gè)扇區(qū)增加性能


    image.png

第六章 親自嘗試壓縮數(shù)據(jù)

  • RLE(Run Length Encoding 行程長(zhǎng)度算法)
    常用于壓縮傳真的圖像,黑白的圖像,不適用于重復(fù)性不高的文本

    AAAAAABBCDDEEEEEF  17字節(jié)
    =>
    A6B2C1D2E5F1  12字節(jié)
    壓縮率: 12/17=70%
    
  • 哈夫曼編碼
    AAAAAABBCDDEEEEEF先按頻率高到低排列的順序整理


    image.png

    這個(gè)編碼方案有問題,C(100) 和 BA(10 0)沒有間隔符分不清楚,需要換一種編碼方式


    image.png

    哈夫曼算法能夠大幅提升壓縮比率
    image.png
  • 可逆壓縮和不可逆壓縮
    BMP格式(bitmap)是完全未壓縮的,JPEG,TIFF,GIF都會(huì)用一些技法對(duì)數(shù)據(jù)進(jìn)行壓縮,與前面說的RLE算法,哈夫曼算法不同的是,BMP壓縮成JPEG,TIFF,GIF之后沒辦法還原成原來(lái)同等的質(zhì)量,對(duì)圖片來(lái)說是可以接受的,這叫不可逆壓縮

  • 壓縮算法千萬(wàn)種,沒有最好用的壓縮算法,只有最合適的壓縮算法

第七章 程序是在何種環(huán)境中運(yùn)行的

  • Intel的處理器是按照8086,80286,80386,80486,Pentium這樣的順序不斷升級(jí)的,所以總稱x86
  • 以前的寫軟件要針對(duì)不同的廠商不同的機(jī)器分別寫一套,Windows解決了這個(gè)問題


    image.png
  • MS-DOC應(yīng)用大多都是直接控制硬件的,而WINDOWS應(yīng)用則是通過操作系統(tǒng)的系統(tǒng)調(diào)用完成對(duì)硬件的控制
  • 不同的操作系統(tǒng),系統(tǒng)調(diào)用API不同
  • JAVA的跨平臺(tái)是通過先編譯成字節(jié)代碼(byte code),運(yùn)行的時(shí)候通過不同操作系統(tǒng)專用的JAVA虛擬機(jī)(JVM)逐行轉(zhuǎn)換成本地代碼運(yùn)行


    image.png
  • BIOS(Basic Input/Output System)存儲(chǔ)在ROM中,除了鍵盤,磁盤,顯卡等基本控制程序外,還有啟動(dòng)引導(dǎo)程序的功能,開機(jī)后,BIOS確認(rèn)硬件是否正常,然后啟動(dòng)引導(dǎo)程序把在硬盤的操作系統(tǒng)加載到內(nèi)存中運(yùn)行,此后就沒BIOS什么事了

第八章 從源文件到可執(zhí)行文件

  • 計(jì)算機(jī)只能運(yùn)行本地代碼,還要是符合CPU指令集的本地代碼


    image.png
  • 交叉編譯器
    生成和運(yùn)營(yíng)環(huán)境的CPU不同的CPU所使用的代碼,比如在ARM的計(jì)算器生成X86架構(gòu)的本地代碼

  • 編譯生成本地文件之后,需要進(jìn)行鏈接(link)之后才能生成可執(zhí)行文件
    C語(yǔ)言編譯生成.obj目標(biāo)文件(本地代碼),需要通過鏈接器鏈接生成exe文件

  • 靜態(tài)鏈接庫(kù)
    當(dāng)WINDOWS系統(tǒng)程序調(diào)用到靜態(tài)鏈接庫(kù)的代碼時(shí),比如sprintf(),需要在cw32.lib把sprintf的代碼單獨(dú)抽出來(lái),放進(jìn)程序的本地代碼中
    Unix系統(tǒng)sprintf()函數(shù)在stdio.h庫(kù)里

  • DLL (Dynamic Link Library) 文件是程序運(yùn)行時(shí)動(dòng)態(tài)結(jié)合的文件,這種動(dòng)態(tài)文件一般都由操作系統(tǒng)加載在內(nèi)存里面
    (@todo沒太搞清楚動(dòng)態(tài)鏈接具體做了什么,后面回來(lái)補(bǔ))

  • 鏈接機(jī)制


    image.png
  • 可執(zhí)行文件內(nèi)容分為再配置信息,變量組,函數(shù)組
    當(dāng)可執(zhí)行文件加載到內(nèi)存之后會(huì)增加堆,棧兩個(gè)組
    再配置信息用來(lái)設(shè)置程序起始虛擬內(nèi)存地址
    棧用來(lái)實(shí)現(xiàn)函數(shù)調(diào)用的,棧操作由編譯器生成,全程無(wú)需程序員參與
    堆用來(lái)存儲(chǔ)程序運(yùn)行時(shí)的任意數(shù)據(jù)及對(duì)象的內(nèi)存,程序員可以編寫程序申請(qǐng)分配或者釋放堆內(nèi)存

第九章 操作系統(tǒng)和應(yīng)用的關(guān)系

  • 操作系統(tǒng)發(fā)展史
    沒有操作系統(tǒng)的年代:用機(jī)器語(yǔ)言編寫程序,使用開關(guān)輸入程序
    監(jiān)控程序:先啟動(dòng)監(jiān)控程序,按需求把各種程序一次性加載到內(nèi)存中運(yùn)行,后來(lái)鍵盤輸入,顯示器輸出等共通的部分追加到監(jiān)控程序中
    編譯器:監(jiān)控程序運(yùn)行的程序里面出現(xiàn)了編譯器

  • 計(jì)算機(jī)中都安裝有保存日期和時(shí)間的實(shí)用時(shí)鐘(Real-time clock)

  • time()printf() 都使用了系統(tǒng)調(diào)用,涉及到硬件基本都涉及到系統(tǒng)調(diào)用

  • 同樣的源代碼在不同的操作系統(tǒng)編譯生成本地代碼使用的系統(tǒng)調(diào)用不一樣


    image.png
  • WYSIWYG (What You See Is What You Get) 是一種顯示器看到的文本和圖形可以原樣打印到打印機(jī)的技術(shù)

  • WIN32 API WIN64 API 不一樣,但都是通過 DLL(動(dòng)態(tài)鏈接庫(kù))提供的。

  • 多任務(wù)功能是通過時(shí)鐘分割技術(shù)實(shí)現(xiàn)的

  • Windows還具有以程序中的函數(shù)為單位來(lái)進(jìn)行時(shí)鐘分割的多線程功能

第十章 通過匯編語(yǔ)言了解程序的實(shí)際構(gòu)成

  • 匯編和反匯編


    image.png
  • 從本地代碼反匯編成匯編語(yǔ)言很簡(jiǎn)單,從匯編語(yǔ)言反編譯完全還原到原始的源代碼不太可能,因?yàn)閺脑创a到本地代碼經(jīng)歷了各種優(yōu)化,這種優(yōu)化也沒記錄到本地代碼中,與不可以壓縮的原理差不多

  • 基本的操作碼


    image.png
  • X86系列主要的寄存器,32位CPU開頭都帶了一個(gè)字母e(extended),區(qū)別于16位CPU,ax,bx,cx,dx等,64位CPU開頭都帶了R,RAX,RBX...


    image.png
  • 簡(jiǎn)單的MOV指令

mov ebp, esp  //esp寄存器的值存儲(chǔ)到ebp寄存器
mov eax, dword ptr [ebp+8] //ebp+8的值被當(dāng)成內(nèi)存地址(指針)存到eax寄存器中
  • 32位X86系列的CPU中,進(jìn)行1次PUSH/POP即可處理32位的數(shù)據(jù)
    @todo 參數(shù)是1個(gè)字節(jié)的字符 或者結(jié)構(gòu)體怎么運(yùn)作
  • 函數(shù)調(diào)用
    函數(shù)的參數(shù)是通過棧傳遞的(寄存器多了之后也有通過寄存器傳值,性能好一點(diǎn)),返回值是通過寄存器來(lái)返回的,這里是eax寄存器保存AddNum函數(shù)的返回值
_MyFunc proc near
push    ebp         ; 保存當(dāng)前函數(shù)的基址指針
mov     ebp, esp    ; 將當(dāng)前棧指針賦值給基址指針

push    456         ; 將值456壓入棧
push    123         ; 將值123壓入棧
call    _AddNum     ; 調(diào)用_AddNum函數(shù),跳轉(zhuǎn)到下面

add     esp, 8     ; 調(diào)整棧指針痰腮,釋放之前壓入的參數(shù)
pop     ebp        ; 恢復(fù)之前保存的基址指針
ret                 ; 返回調(diào)用方

_MyFunc endp
_AddNum proc near
push ebp                ; 保存當(dāng)前函數(shù)的基址指針
mov  ebp, esp           ; 將當(dāng)前棧指針賦值給基址指針

mov  eax, dword ptr [ebp+8]    ; 將偏移為8的位置的值(第一個(gè)參數(shù))賦給寄存器eax
add  eax, dword ptr [ebp+12]   ; 將偏移為12的位置的值(第二個(gè)參數(shù))加到eax寄存器上

pop  ebp                ; 恢復(fù)之前保存的基址指針
ret                     ; 返回調(diào)用方

_AddNum endp
  • 全局變量
    已初始化的全局變量在_DATA段,未初始化的全局變量在_BSS段,雖然段不同,內(nèi)存空間在程序初始都分配好的,所以其他函數(shù)隨時(shí)可以引用全局變量
    局部變量在寄存器空閑時(shí)存在寄存器,寄存器空間不足的話就使用棧,寄存器訪問速度比內(nèi)存快得多多,只要寄存器有空間,編譯器就會(huì)拼命壓榨它
    不只是形參存在棧里,函數(shù)里面定義的局部變量也存在棧里
int a1 = 1, a2 = 2, a3 = 3, a4 = 4, a5 = 5;
int b1, b2, b3, b4, b5;

void MyFunc()
{
    int c1 = 1, c2 = 2, c3 = 3, c4 = 4, c5 = 5, c6 = 6, c7 = 7, c8 = 8, c9 = 9, c10 = 10;
    a1 = c1; a2 = c2; a3 = c3; a4 = c4; a5 = c5;
    b1 = c6; b2 = c7; b3 = c8; b4 = c9; b5 = c10;
}

以上C語(yǔ)言代碼的匯編代碼如下

_DATA segment dword public use32 'DATA'
_a1 label dword   ; 定義一個(gè)名為_a1的標(biāo)簽曹锨,表示一個(gè)32位整數(shù)變量
    dd 1          ; 初始化_a1變量為值1
_a2 label dword   ; 定義一個(gè)名為_a2的標(biāo)簽,表示一個(gè)32位整數(shù)變量
    dd 2          ; 初始化_a2變量為值2
_a3 label dword   ; 定義一個(gè)名為_a3的標(biāo)簽山宾,表示一個(gè)32位整數(shù)變量
    dd 3          ; 初始化_a3變量為值3
_a4 label dword   ; 定義一個(gè)名為_a4的標(biāo)簽龙誊,表示一個(gè)32位整數(shù)變量
    dd 4          ; 初始化_a4變量為值4
_a5 label dword   ; 定義一個(gè)名為_a5的標(biāo)簽缰儿,表示一個(gè)32位整數(shù)變量
    dd 5          ; 初始化_a5變量為值5
_DATA ends

_BBS segment dword public use32 'BSS'
_b1 label dword   ; 定義一個(gè)名為_b1的標(biāo)簽瓦糟,表示一個(gè)32位整數(shù)變量
    db 4 dup(?)   ; 分配4字節(jié)的空間伶选,但未初始化
_b2 label dword   ; 定義一個(gè)名為_b2的標(biāo)簽敢课,表示一個(gè)32位整數(shù)變量
    db 4 dup(?)   ; 分配4字節(jié)的空間着饥,但未初始化
_b3 label dword   ; 定義一個(gè)名為_b3的標(biāo)簽诅愚,表示一個(gè)32位整數(shù)變量
    db 4 dup(?)   ; 分配4字節(jié)的空間李破,但未初始化
_b4 label dword   ; 定義一個(gè)名為_b4的標(biāo)簽,表示一個(gè)32位整數(shù)變量
    db 4 dup(?)   ; 分配4字節(jié)的空間垫蛆,但未初始化
_b5 label dword   ; 定義一個(gè)名為_b5的標(biāo)簽盔腔,表示一個(gè)32位整數(shù)變量
    db 4 dup(?)   ; 分配4字節(jié)的空間,但未初始化
_BBS ends


_TEXT segment dword public use32 'CODE'

_MyFunc proc near
push ebp              ; 保存當(dāng)前函數(shù)的基址指針
mov ebp, esp         ; 將當(dāng)前棧指針賦值給基址指針
add esp, -20         ; 分配20個(gè)字節(jié)的椩氯欤空間

push ebx              ; 保存ebx寄存器
push esi              ; 保存esi寄存器

mov eax, 1            ; 將值1賦給eax寄存器
mov edx, 2            ; 將值2賦給edx寄存器
mov ecx, 3            ; 將值3賦給ecx寄存器
mov ebx, 4            ; 將值4賦給ebx寄存器
mov esi, 5            ; 將值5賦給esi寄存器

mov dword ptr [ebp-4], 6    ; 將值6存儲(chǔ)到基址指針減4的位置
mov dword ptr [ebp-8], 7    ; 將值7存儲(chǔ)到基址指針減8的位置
mov dword ptr [ebp-12], 8   ; 將值8存儲(chǔ)到基址指針減12的位置
mov dword ptr [ebp-16], 9   ; 將值9存儲(chǔ)到基址指針減16的位置
mov dword ptr [ebp-20], 10  ; 將值10存儲(chǔ)到基址指針減20的位置

mov dword ptr [_a1], eax    ; 將eax寄存器的值存儲(chǔ)到_a1變量中
mov dword ptr [_a2], edx    ; 將edx寄存器的值存儲(chǔ)到_a2變量中
mov dword ptr [_a3], ecx    ; 將ecx寄存器的值存儲(chǔ)到_a3變量中
mov dword ptr [_a4], ebx    ; 將ebx寄存器的值存儲(chǔ)到_a4變量中
mov dword ptr [_a5], esi    ; 將esi寄存器的值存儲(chǔ)到_a5變量中

mov eax, dword ptr [ebp-4]   ; 將基址指針減4位置的值存儲(chǔ)到eax寄存器
mov dword ptr [_b1], eax     ; 將eax寄存器的值存儲(chǔ)到_b1變量中
mov edx, dword ptr [ebp-8]   ; 將基址指針減8位置的值存儲(chǔ)到edx寄存器
mov dword ptr [_b2], edx     ; 將edx寄存器的值存儲(chǔ)到_b2變量中
mov ecx, dword ptr [ebp-12]  ; 將基址指針減12位置的值存儲(chǔ)到ecx寄存器
mov dword ptr [_b3], ecx     ; 將ecx寄存器的值存儲(chǔ)到_b3變量中
mov eax, dword ptr [ebp-16]  ; 將基址指針減16位置的值存儲(chǔ)到eax寄存器
mov dword ptr [_b4], eax     ; 將eax寄存器的值存儲(chǔ)到_b4變量中
mov edx, dword ptr [ebp-20]  ; 將基址指針減20位置的值存儲(chǔ)到edx寄存器
mov dword ptr [_b5], edx     ; 將edx寄存器的值存儲(chǔ)到_b5變量中

pop esi               ; 恢復(fù)保存的esi寄存器
pop ebx               ; 恢復(fù)保存的ebx寄存器

mov esp, ebp          ; 恢復(fù)之前保存的棧指針
pop ebp               ; 恢復(fù)之前保存的基址指針
ret                   ; 返回調(diào)用方

_MyFunc endp

_TEXT ends
  • 棧清理
    先把esp存在ebp,函數(shù)返回之后,再把ebp的值存回esp,完成棧清理


    image.png
  • xormov 處理速度更快,編譯器會(huì)自動(dòng)優(yōu)化

xor ebx ebx     ;將ebx寄存器清0,效率更高
mov ebx 0       ;將ebx寄存器清0
  • 循環(huán)語(yǔ)句轉(zhuǎn)匯編
void MySub(){}
void MyFunc(){
  int i;
  for (i =0; i< 10; i++) {
    MySub();
  }
}
xor ebx, ebx      ; 將 ebx 寄存器的值設(shè)置為零(相當(dāng)于 ebx = 0)
@4:
call _MySub       ; 調(diào)用名為 _MySub 的子程序(函數(shù))
inc ebx           ; 將 ebx 寄存器的值加一(相當(dāng)于 ebx = ebx + 1)
cmp ebx, 10       ; 比較 ebx 的值和 10
jl short @4       ; 如果 ebx 小于 10,則跳轉(zhuǎn)到標(biāo)簽 @4 處(繼續(xù)執(zhí)行循環(huán))
  • 線程不安全的原因
    下面一條C語(yǔ)言代碼轉(zhuǎn)換成三行匯編代碼,沒有原子性,線程1把counter*2的值讀出來(lái)沒來(lái)得及寫入,線程2把counter原來(lái)的值讀出來(lái),這個(gè)時(shí)候就會(huì)出現(xiàn)大家都不想見到的情況
counter *= 2;    

mov eax, dword ptr[_counter];
add eax,eax
mov dword ptr[_counter], eax;

硬件控制方法

  • 現(xiàn)代高級(jí)編程語(yǔ)言很少能直接控制硬件,都是通過操作系統(tǒng)的系統(tǒng)調(diào)用控制硬件

  • 主機(jī)背后附帶了用來(lái)連接顯示器,鍵盤等外圍設(shè)備的連接器,連接器的內(nèi)部有用來(lái)和計(jì)算機(jī)交換數(shù)據(jù)的IO控制器,IO控制器中有用于臨時(shí)保存輸入輸出數(shù)據(jù)的內(nèi)存,這個(gè)內(nèi)存就叫端口(port),比如鍵盤輸入的內(nèi)容都會(huì)暫存在鍵盤線和主機(jī)的連接處(IO控制器)中,然后才被CPU讀取,端口的地址也成為IO地址,WINDOWS的IN/OUT命令使用IO地址進(jìn)行通訊


    image.png
  • 蜂鳴器啟動(dòng)和停止
    計(jì)算機(jī)里面有個(gè)蜂鳴器,端口地址為61H(十六進(jìn)制),這個(gè)地址大概存儲(chǔ)一個(gè)字節(jié)(8位),其中低2位為1時(shí)發(fā)出蜂鳴,為0時(shí)停止蜂鳴,匯編代碼如下,這段代碼只能在Windows98以下的操作系統(tǒng)運(yùn)行,之后Windows禁止了直接操作硬件的方式

; 啟動(dòng)
IN EAX, 61H     ; 從端口61H讀取數(shù)據(jù)并存儲(chǔ)到寄存器EAX中
OR EAX, 03H     ; 將寄存器EAX的值與00000011進(jìn)行按位或運(yùn)算瓢喉,并將結(jié)果存儲(chǔ)回EAX寄存器
OUT 61H, EAX    ; 將寄存器EAX的值輸出到端口61H

; 停止
IN EAX, 61H     ; 從端口61H讀取數(shù)據(jù)并存儲(chǔ)到寄存器EAX中
AND EAX, 0FCH   ; 將寄存器EAX的值與11111100進(jìn)行按位與運(yùn)算宁赤,并將結(jié)果存儲(chǔ)回EAX寄存器
OUT 61H, EAX    ; 將寄存器EAX的值輸出到端口61H
  • IRQ (Interrupt Request) 中斷請(qǐng)求
    主程序運(yùn)行中,CPU收到硬件的中斷請(qǐng)求,比如鍵盤鼠標(biāo)輸入,會(huì)保存好主程序的各個(gè)寄存器,把控制權(quán)交給硬件的中斷處理程序
    外圍設(shè)備的中斷請(qǐng)求會(huì)使用不同于IO端口地址的中斷編號(hào)
    中斷控制器的功能是緩沖多個(gè)外圍設(shè)備同時(shí)進(jìn)行中斷請(qǐng)求,使每個(gè)中斷請(qǐng)求有序地傳遞給CPU

    image.png

    操作系統(tǒng)和BIOS都有提供響應(yīng)中斷編號(hào)的程序

  • 中斷請(qǐng)求的順序


    image.png
  • DMA (Direct Memory Access)
    DMA指的是主存和外圍設(shè)備不通過CPU進(jìn)行直接數(shù)據(jù)傳送的技術(shù),磁盤也用到了這個(gè)機(jī)制,估計(jì)是虛擬內(nèi)存這塊用到
    通過DMA,節(jié)省了CPU作為中間商賺差價(jià)的時(shí)間,大量數(shù)據(jù)可以短時(shí)間從外圍設(shè)備的IO控制器傳輸?shù)街鞔嬷?br> 使用了DMA的外圍設(shè)備資源塊會(huì)顯示

    image.png

    假如多個(gè)外圍設(shè)備都設(shè)定成同樣的端口號(hào),IRQ,DMA通道,計(jì)算機(jī)就無(wú)法正常工作并出現(xiàn)設(shè)備沖突的提示

  • 顯示器中顯示的信息一直都存儲(chǔ)在VRAM(Video RAM)內(nèi)存中,需要借助中斷程序往VRAM寫入數(shù)據(jù),然后在顯示器顯示出來(lái)
    MS-DOC時(shí)代,VRAM是主存的一部分,A0000地址以后是VRAM區(qū)域,文字和圖形的顏色最多只能16種,現(xiàn)代計(jì)算機(jī)把VRAM從主存獨(dú)立出來(lái),仍集成在主板上的叫集顯,獨(dú)立出去的叫獨(dú)顯

    image.png

  • GPU (Graphics Processing Unit)
    VRAM獨(dú)立出來(lái)后,因?yàn)镃PU的指令集處理圖形運(yùn)算效率太低,,GPU則被設(shè)計(jì)用于高并行的計(jì)算任務(wù)栓票,特別擅長(zhǎng)處理大規(guī)模圖形數(shù)據(jù)和復(fù)雜的計(jì)算操作决左。
    顯卡是由GPU和獨(dú)立出來(lái)的VRAM組成的

讓計(jì)算機(jī)思考

這章就算了

附錄

  • 數(shù)據(jù)類型


    image.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市走贪,隨后出現(xiàn)的幾起案子佛猛,更是在濱河造成了極大的恐慌,老刑警劉巖坠狡,帶你破解...
    沈念sama閱讀 212,686評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件继找,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡逃沿,警方通過查閱死者的電腦和手機(jī)婴渡,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,668評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)凯亮,“玉大人边臼,你說我怎么就攤上這事〖傧” “怎么了柠并?”我有些...
    開封第一講書人閱讀 158,160評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我臼予,道長(zhǎng)鸣戴,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,736評(píng)論 1 284
  • 正文 為了忘掉前任瘟栖,我火速辦了婚禮葵擎,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘半哟。我一直安慰自己酬滤,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,847評(píng)論 6 386
  • 文/花漫 我一把揭開白布寓涨。 她就那樣靜靜地躺著盯串,像睡著了一般。 火紅的嫁衣襯著肌膚如雪戒良。 梳的紋絲不亂的頭發(fā)上体捏,一...
    開封第一講書人閱讀 50,043評(píng)論 1 291
  • 那天,我揣著相機(jī)與錄音糯崎,去河邊找鬼几缭。 笑死,一個(gè)胖子當(dāng)著我的面吹牛沃呢,可吹牛的內(nèi)容都是我干的年栓。 我是一名探鬼主播,決...
    沈念sama閱讀 39,129評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼薄霜,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼某抓!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起惰瓜,我...
    開封第一講書人閱讀 37,872評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤否副,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后崎坊,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體备禀,經(jīng)...
    沈念sama閱讀 44,318評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,645評(píng)論 2 327
  • 正文 我和宋清朗相戀三年流强,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了痹届。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,777評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡打月,死狀恐怖队腐,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情奏篙,我是刑警寧澤柴淘,帶...
    沈念sama閱讀 34,470評(píng)論 4 333
  • 正文 年R本政府宣布迫淹,位于F島的核電站,受9級(jí)特大地震影響为严,放射性物質(zhì)發(fā)生泄漏敛熬。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,126評(píng)論 3 317
  • 文/蒙蒙 一第股、第九天 我趴在偏房一處隱蔽的房頂上張望应民。 院中可真熱鬧,春花似錦夕吻、人聲如沸诲锹。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,861評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)归园。三九已至,卻和暖如春稚矿,著一層夾襖步出監(jiān)牢的瞬間庸诱,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,095評(píng)論 1 267
  • 我被黑心中介騙來(lái)泰國(guó)打工晤揣, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留桥爽,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,589評(píng)論 2 362
  • 正文 我出身青樓昧识,卻偏偏與公主長(zhǎng)得像聚谁,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子滞诺,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,687評(píng)論 2 351

推薦閱讀更多精彩內(nèi)容

  • CPU是英文Central Processing Unit(中央處理器) CPU和內(nèi)存是由許多晶體管組成的電子部件...
    HikariCP閱讀 497評(píng)論 0 1
  • 前言:我們?cè)谙硎苓@些方便的同時(shí)也付出了代價(jià)。雖然擁有一定的編程能力环疼,卻無(wú)法進(jìn)一步提高自身技能习霹;知識(shí)應(yīng)用能力的不足導(dǎo)...
    Gen_閱讀 584評(píng)論 0 0
  • 加載到內(nèi)存中的機(jī)器語(yǔ)言程序,由CPU進(jìn)行解析和運(yùn)行炫隶,進(jìn)而計(jì)算機(jī)系統(tǒng)整體的控制和數(shù)據(jù)運(yùn)算也開始運(yùn)行淋叶。 寄存器 可用來(lái)...
    邱杉的博客閱讀 1,241評(píng)論 0 51
  • 程序是怎樣跑起來(lái)的 本文主要學(xué)習(xí)自 《c程序是怎樣跑起來(lái)》一書,再添加了一些自己的理解和注釋伪阶,請(qǐng)各位觀者支持原版 ...
    Mjericho閱讀 572評(píng)論 0 2
  • 開篇補(bǔ)充 這篇文章大概寫于兩三個(gè)月前煞檩,但一直忘記發(fā)布文章。今天用了半小時(shí)把這篇文章大概瀏覽了下栅贴,依然感覺能學(xué)到很多...
    ZhengYaWei閱讀 3,522評(píng)論 3 32