期中总结
一些好用的基本操作
打開終端的快捷鍵:ctrl+alt+t
正則表達式:
特殊符號:
man:
使用man -k passwd會找到很多和passwd相關的幫助頁
man -k
man -k k1 | grep k2 | grep 2 同時搜索k1,k2
man的8個區段:
1 一般命令
2 系統調用
3 庫函數,涵蓋了C標準函數庫
4 特殊文件(通常是/dev中的設備)和驅動程序
5 文件格式和約定
6 游戲和屏保
7 雜項
8 系統管理命令和守護進程
grep:
grep 可以對文件全文檢索,支持正則表達式
grep -nr xxx /usr/include 尋找一個宏<>系統庫文件
cheat:
提供顯示Linux命令使用案例,包括該命令所有的選項和簡短但尚可理解的功能。
find:查找一個文件在系統中的什么位置
find的重要參數
-atime 最后訪問時間
-ctime 創建時間
-mtime 最后修改時間
下面以-mtime參數舉例:
-mtime n: n 為數字,表示為在n天之前的”一天之內“修改過的文件
-mtime +n: 列出在n天之前(不包含n天本身)被修改過的文件
-mtime -n: 列出在n天之前(包含n天本身)被修改過的文件
newer file: file為一個已存在的文件,列出比file還要新的文件名
列出 home 目錄中,當天(24 小時之內)有改動的文件:
$ find ~ -mtime 0
列出用戶家目錄下比Code文件夾新的文件:
$ find ~ -newer /home/shiyanlou/Code
whereis
只能搜索二進制文件(-b),man幫助文件(-m)和源代碼文件(-s)
which
which本身是 Shell 內建的一個命令,我們通常使用which來確定是否安裝了某個指定的軟件,因為它只從PATH環境變量指定的路徑中去搜索命令:
$ which man
一些重要的工具
vim:
三種模式:
命令行模式,插入模式,底行模式
模式的切換 :
vim啟動進入普通模式,處于插入模式或命令行模式時只需要按Esc或者Ctrl+[(這在vim課程環境中不管用)即可進入普通模式。
普通模式->插入模式:普通模式中按i(插入)或a(附加)鍵都可以進入插入模式,
普通模式->命令行模式:普通模式中按:進入命令行模式。
退出:命令行模式中輸入wq回車后保存并退出vim
刪除信息:
dd 刪除整行
dw 刪除一個單詞(不適用中文)
d$或D 刪除至行尾
d^ 刪除至行首
dG 刪除到文檔結尾處
d1G 刪至文檔首部
*命令之前加上數字,表示一次刪除多行
快速跳轉(行間):
nG(n Shift+g) 游標移動到第 n 行(如果默認沒有顯示行號,請先進入命令模式,輸入:set nu以顯示行號)
gg 游標移動到到第一行
G(Shift+g) 到最后一行
小技巧:你在完成依次跳轉后,可以使用Ctrl+o快速回到上一次(跳轉前)光標所在位置,
復制(類似于刪除d):普通模式中使用y復制
gcc(是GNU項目中符合ANSI C標準的編譯系統)
預處理:gcc –E hello.c –o hello.i; gcc –E調用cpp
編 譯:gcc –S hello.i –o hello.s; gcc –S調用ccl
匯 編:gcc –c hello.s –o hello.o; gcc -c 調用as
鏈 接:gcc hello.o –o hello ; gcc -o 調用ld
=>./hello(./當前目錄)
gdb
程序保存退出后用gcc進行編譯,一定要記得加上選項“-g”這樣編譯出來的可執行代碼才包含調試信息
gcc -g test.c -o test
基本命令:
gdb programm (啟動GDB)
b 設斷點(要會設4種斷點:行斷點、函數斷點、條件斷點、臨時斷點)
run 開始運行程序
bt 打印函數調用堆棧
p 查看變量值
c 從當前斷點繼續運行到下一個斷點
n 單步運行
s 單步運行
quit 退出GDB
四種斷點
1.行斷點
b [行數或函數名] <條件表達式>
2.函數斷點
b [函數名] <條件表達式>
3.條件斷點
b [行數或函數名] <if表達式>
4.臨時斷點
tbreak [行數或函數名] <條件表達式>
靜態庫的創建:
(1)使用歸檔工具ar,將目標文件集成在一起
# gcc -c unusgn_pow.c
# ar rscv libpow.a unsgn_pow.o
a - unsgn_pow.o
(2) 編譯主程序來觀看一下結果
# gcc -o pow_test pow_test.c -L. -lpow
# ./pow_test 2 10
2.^10=1024
"-L dir" :在庫文件的搜索路徑中添加dir目錄
"-lname" 選項指示編譯時連接到庫文件libname.a或libname.so
動態庫的創建:
使用gcc的-fPIC選項為動態庫構造一個目標文件
gcc -fPIC -Wall -c unsgn_pow.c
2.使用-shared選項和已創建的位置無關目標代碼,生成動態庫libpow.so
# gcc -shared -o libpow.so unsgn.so
3.編譯程序(將鏈接到剛生成的動態庫lipow.so)
# gcc -o pow_test pow_test.c -L. -lpow
運行可執行程序前需要注冊動態庫的路徑名,有幾種方法,如下:
1.修改 /etc/ld.so.conf文件
2.修改 LD_LIBRARY_PATH環境變量
3.將庫文件直接復制到 /lib或者 /usr/lib 目錄下(這兩個都是系統默認的庫路徑名)
結果:
# cp libpow.so /lib
# ./pow_test 2 10
2 ^ 10 =1024
makefile:
一個makfile通常包含的內容:
需要有make工具創建的目標體(target),通常指目標文件和可執行文件
需要創建的目標所以依賴的文件(dependency_file)
創建每個目標體所需要運行的命令(command)這一行必須由制表符Tab開頭
格式:
target:dependency_files
commmand /*必須由制表符Tab開頭*/
例:test(目標文件): prog.o code.o(依賴文件列表)
tab(至少一個tab的位置) gcc prog.o code.o -o test(命令)
.......
make的 使用格式:make target
make允許makefile中創建和使用變量(用來代替文本字符串,該字符串成為該變量的值)
遞歸展開方式:
這種方式定義的變量,在引用變量時進行替換,如果有內嵌變量,將會一次性全部展開
缺點:不在變量后追加內容(可能造成無限循環)
格式:VAR=var
2.簡單方式:
此方式在定義處展開,并只展開一次。不包含對其他變量的引用,從而消除變量套用
格式:VAR:=var
make中的變量使用格式:
$(VAR)
*關于變量名:1.不包含“:”“#”“=”以及結尾空格的任何字符串
2.大小寫敏感(推薦使用小寫,大寫留做控制隱含規則參數/用戶重載命令選項參數的變量名)
make clean就會去執行rm -f *.o test這條命令,完成 clean 操作
第一章
位+上下文
查看源文件可以用od 命令 : od -tc -tx1 hello.c
存儲系統的核心思想:緩存
第二章
最重要的數字表示:
無符號(unsigned)編碼基于傳統的二進制表示法,表示
大于或者等于零的數字。
補碼(two’s-complement)編碼是表示有符號整數的最常見的方式,有 符號整數就是可以為正或者為負的數字。
浮點數(floating-point)編碼是表示實數的科學記數法 的以二為基數的版本。
整數運算
判斷無符號運算是否溢出,例如s=x+y(s、x、y均為無符號數),則唯一可靠的判斷標準就是
s<x或s<y
根據exp 的值,被編碼的值可以分成三種不同的情況(最后一種情況有兩
個變種)
規格化的值
非規格化的值
非規格化數有兩個用途:
(1)它們提供了一種表示數值0 的方法
(2)表示那些非常接近于0.0 的數。它們提供了一種屬性,稱為逐 漸溢出(gradual underflow),
特殊值
特殊值是當指階碼全為1 的時候出現的。當小數域全為0 時,得到的值表示無窮,當s = 0 時是+ ∞,或者當 s = 1 時是- ∞
對于浮點數,需要明白,可以表示的數并不是均勻分布的,在越靠近原點處越稠密。
舍入
默認的方 法是找到最接近的匹配,而其他三種可用于計算上界和下界
向偶數 舍入(round-to-even),也稱為向最接近的值舍入(round-to-nearest),(默認)
將數字向上或向下舍入,是的結果的最低有效數字為偶數。
向零舍入方式
把正數向下舍入,把負數向上舍入,
向下舍入方式
正數和負數都向下舍入。
向上舍入方式
正數和負數都向上舍入。
強制類型轉換
當在int、float 和double 格式之間進行強制類型轉換時,程序改變數值和位模式的原
則如下(假設int 是32 位的):
? 從int 轉換成float,數字不會溢出,但是可能被舍入。
? 從int 或float 轉換成double, 因為double 有更大的范圍( 也就是可表示值的范
圍),也有更高的精度(也就是有效位數),所以能夠保留精確的數值。
? 從double 轉換成float,因為范圍要小一些,所以值可能溢出成為+ ∞或- ∞。另外,
由于精確度較小,它還可能被舍入。
? 從float 或者double 轉換成int, 值將會向零舍入。例如,1.999 將被轉換成1,
而-1.999 將被轉換成-1。進一步來說,值可能會溢出。
第三章
gcc -S xxx.c -o xxx.s 獲得匯編代碼,也可以用objdump -d xxx 反匯編
操作數的三種類型:
1.立即數,也就是常數值。
2.寄存器
3.存儲器
根據計算出來的地址(有效地址)訪問某個存儲器的位置。
有效地址的計算方式: Imm(Eb,Ei,s) = Imm + R[Eb] + R[Ei]*s
區分MOV,MOVS,MOVZ :
MOV:將源操作數值復制到目的操作數中。
MOVS:將較小的源數據復制到一個較大的數據位置高位使用符號位擴展。
MOVZ:將較小的源數據復制到一個較大的數據位置高位使用零擴展
棧是一個數據結構,可以添加或者刪除數據,總是遵循“先進后出”原則。
指針就是地址。
指令類中的操作被分為四組:加載有效地址,一元操作數,二元操作數,移位。
條件碼寄存器:
它們描述了最近的算術或邏輯操作的屬性。
常用:CF,ZF,SF,OF
跳轉(jump)指令會導致執行切換到程序中的一個全新的位置。
直接跳轉:給出一個標號作為跳轉目標。(條件跳轉只能是直接跳轉。)
間接跳轉:‘*’的后面跟一個操作指示符。
在匯編代碼中,跳轉目標用符號標號書寫。
跳轉編碼方法:
1,PC相關的:將目標命令的地址與緊跟在跳轉指令后的那條指令的地址間的差作為編碼。
2.給出絕對地址,4字節直接指定目標。
當執行與PC相關的尋址時,程序計數器的值是跳轉命令后面的那條命令的地址,而不是跳轉指令本身的地址。
do while:
每次循環,程序會執行循環體里 的語句,然后執行測試表達式。如果測試為真,則回去再執行一次循環。
while
與do-while不同的是,它對test-expr求值,在第一次執行body-statement之前,循環就可能終止。
switch:
switch(開關)語句可以根據一個整數索引值進行多重分支。
這里使用到跳轉表:跳轉表是一個數組,表項i是一個代碼段的地址,這個代碼實現當開關索引值等于i時程序應該采取的動作。
跳轉表的優點:執行開關語句的時間與開關情況的數量無關。
為單個過程分配的那部分稱為棧幀。、最頂端棧幀以兩個指針來界定:寄存器%ebp為幀指針,而寄存器%esp為棧指針
Q會用棧幀來存放它調用的其他過程的參數。第一個參數放在相對于%ebp偏移量為8的位置處。剩下的參數存儲在后續的4字節塊中,所以參數i就在相對于%ebp的偏移量為4+4i的地方。
call指令
指明被調用過程起始的指令地址。(可以直接也可以間接)
指令效果是將返回地址入棧,并跳轉到被調用過程的起始處。
ret命令
從棧中彈出地址,并跳轉到這個位置。正確的使用這條命令,要使棧做好準備,棧指針要指向前面call指令存儲返回地址的位置。
寄存器%eax可以用來返回值。
程序寄存器是唯一能被所有過程共享的資源。
根據慣例
寄存器%eax,%edx,和%ecx被劃分為調用者保存寄存器,
寄存器%edx,%esi,和%edi被劃分為被調用者保存寄存器。
指針隱射機器代碼的關鍵原則。
每一個指針都對應一個類型。
每一個指針都有一個值。
指針用&運算符創建
數組與指針緊密聯系
將指針從一種類型強制轉換為另一種類型只改變它的類型而不改變它的值。
指針也可以指向函數
第四章
程序狀態的最后一部分狀態碼Stat,表明程序執行總體狀態。
Y86指令
指令編碼
每條指令的第一個字節表明指令的類型。
這個字節分為兩個部分:
高4位是代碼(code)部分,低四位是功能(function)部分。
指令集的一個重要性質就是字節編碼必須有唯一的解釋=>保證處理器可以無二義性地執行目標代碼程序。
一個數字系統需要三個主要的組成部分:
計算對位進行操作的函數的組合邏輯
存儲位的存儲器元素
控制存儲器元素更新的時鐘信號。
字級的組合電路和HCL整數表達式
多路復用函數是用情況表達式來描述的:
[
select_1 : expr_1;
select_2 : expr_2;
.
.
.
select_k : expr_k;
]
判斷集合關系的通用格式是:
iexpr in {iexpr1,iexpr2, ... ,iexprk}
將處理組織成階段
取指:從存儲器讀取指令字節,地址為程序計數器PC。
譯碼:從寄存器文件讀人最多兩個操作數,得到值valA和/或valB。
執行:ALU要么執行指令指明的操作,計算存儲器引用的有效地址,要么增加或減少棧指針。
訪存:可以將數據寫入存儲器,或者從存儲器讀出數據。
寫回:最多可以寫兩個結果到寄存器文件。
更新PC:將PC設置到下一條指令的地址。
第六章
分為兩類:靜態(SRAM)和動態(DRAM)
*靜態速度更快,更昂貴。
磁盤構造
磁盤容量,由以下三點決定:
記錄密度,磁道密度,面密度。
局部性
局部性原理:
一個編寫良好的計算機程序,更趨向于引用鄰近于其他最近引用過的數據項,或者最近引用過的數據本身。這種傾向性,被稱為~
局部性通常有兩種不同的形式:
時間局部性:有良好的時間局部性的程序中,被引用過一次的存儲器位置很可能被在不遠的將來再次被引用。
空間局部性:具有良好空間局部性的程序中,如果一個存儲器位置被引用一次,那么程序很可能在不遠的將來引用附近的一個存儲器位置。
存儲器層次結構
在一個典型的存儲器層次結構中,從高層往底層走,存儲設備變得更慢,更便宜,更大。
緩存命中/緩存不命中
當程序需要第k+1層的某個數據對象d時,它首先在當前存儲在第k層的一個塊中,查找d。如果d剛好緩存在第k層中,那么就是我們所說的緩存命中,不然就是緩存不命中。
覆蓋一個現存的塊的過程稱為替換,或者驅逐這個塊。這個被驅逐的塊稱為犧牲塊。決定該替換哪個塊是由緩存的替換策略來控制的。
緩存不命中的種類
強制性不命中(第k層緩存為空)
沖突不命中(有些對象會映射到同一個緩存塊,緩存會一直不命中)
中心思想:每層存儲設備都是下一層的“緩存”
高速緩存存儲器
高速緩存結構(S,E,B,m):高速緩存組、高速緩存行、塊
考慮一個計算機系統,其中每個存儲器地址有m位,形成M=2^m個不同的地址
高速huanc 被組織為一個有S=2^s個高速緩存組的數組。
每個組包含E個高速緩存行。
每行是由一個B=2^b字節的數據塊組成的,一個有效位指明這個行是否包含有意義的信息。
t=m-(b+s)個標記位,唯一標識存儲在這個高速緩存行中的塊。
高速緩存大小C=S*E*B
高速緩存確定一個請求是否命中,然后抽取被請求的字的過程,分三步:
1)組選擇
2)行匹配
3)字抽取
收獲:
把很多已經忘記了的知識點撿了起來,不能說已經全部學懂了,至少知道自己學過些什么。vim的使用方法,也又過了一遍。自己平時還是用的比較少,其實一開始不知道該怎么整理,前幾章就把筆記先粘貼上去,把不常用的知識點削減掉,再好好思考一下一章的核心內容是什么,這章本來最想講的東西是什么,每周的學習目標是什么,再削減掉一些知識點,把我覺得最核心的東西先記錄下來。
不足(要具體,有改進措施):
整理了之后,才知道自己學到的知識點有多松散,我對這些知識點完全沒有系統的感覺 很多知識點和第一次觸碰一樣生澀。對我來說,在之前的學習中看書帶給我的效果遠沒有做題來的效果好,因為總是最后犯懶,把題目都留到考試的前一天一起做完,如果老師沒有勾選題目給我做得話 ,恐怕自己學的東西更沒有什么實物,不太可取。實驗樓的實驗雖然做了但是沒能好好吸收進去,自己還是完成任務的態度太強烈。既然都要上課還是想多學一點東西。以后趁早開始寫學習報告,把學習的時間分給每一天,每一天把每一天的事情做完,別堆在一起,盡我所能去理解,在讀書的過程中把題目做完,在考試前好好看一遍。這樣還能乘早選題,效果會更好。
課程建議和意見(要有理由):
其實婁老師上課我挺能聽進去的,我學完一大章之后,其實還是對所學的內容不夠清晰,要是能在總結完了之后聽一下老師對這一章的見解啊,或者對難點部分的梳理就很贊了(雖然您可能要說我懶)。
總結
- 上一篇: 12306火车售票系统设计方案
- 下一篇: BizCharts 使用笔记