C
Register
Instruction Register 是用來放指令的,而 Data Register 就是用來放資料的(CPU內) 假設兩條指令進來要做 A + B = C 、C X D = E,這兩條指令就會先被放進 Instruction register 中,等解碼完之後, CPU 就會從 Memory 中去找到 A 和 B 的值,並將這兩個值分別放到 Data register 1 和 2 當中,並將 1 和 2 裡的內容相加,將其結果,也就是C,存到 register 1 裡,再去 Memory 中尋找 D 的值,並存到 register 2 裡,最後再把1 和 2 的內容相乘並輸出
Explain lvalue and rvalue
Lvalue: 就是一個運算式後還保留其狀態的一個物件 就是Lvalue; Rvalue: 就是一個運算式過後其狀態就不會被保留了, 也就是一個暫存的數值 ++x 是左值而 x++ 是右值呢
data size(sizeof)
sizeof(bool) 1(cpu can't read smaller than 1 byte) sizeof(char) 1 sizeof(wchar_t) 2 sizeof(short) 2 sizeof(int) 4 sizeof(long) 4 or 8 sizeof(long long) 8 sizeof(int*) 4 or 8 sizeof(float) 4 sizeof(double) 8 sizeof(long double) 16
static
static修飾字則會將變數由動態(dynamic)變數轉為靜態(static)變數,靜態變數的壽命(lifetime)與動態變數不同,靜態變數會一直存在,直到程式結束為止。 合用來做統計次數的功能,因為全部程式碼中相同名稱的static變數都會共用空間。
the value of v?
unsigned long v1 = 0x00001111; unsigned long v2 = 0x00001212; unsigned long v; v = v1 & (~v2); v = v | v2; v = 0x0001313;
Re-write typedef _____;
void(*(*papf)[3](char *); pf(*papf)[3]; typedef void (*pf)(char*);
不能用if 和 switch case , 請用你認為最快的方法實作main
void(*fptr[5])(void); fptr[0] = func1; fptr[1] = func2; fptr[2] = func3; fptr[3] = func4; fptr[4] = func5; if (n > 5) break; fptr[(n-1)]();
cache
一般普通MCU是沒有緩存的,一些強大的個人電腦或者手機芯片才會有緩存,緩存的一般用的是SRAM靜態隨機存儲器,速度很快。通常情況是電腦在工作時將從內存中讀入的用過的數據放入緩存,以便下次用時可以快速找到它。不過cpu一般不會直接訪問緩存,而是先將緩存放入寄存器,再操作。
什麼是OS
主管並控制電腦操作、運用和執行硬體、軟體資源和提供公共服務來組織用戶互動的相互關聯的系統軟體程式。
Stack Pointer
先進後出 First In Last Out SP
memory
內存。一般普通MCU也是沒有內存的,而且內存一般是外置的,而緩存與寄存器通常集成在cpu內部。內存一般使用DRAM動態隨機存儲器,速度稍慢。已經工作的cpu首先會到cache尋找自己想要的數據,如果沒有才會到內存讀。
shared memory
共享記憶體,允許兩個不相關的程序訪問同一個邏輯記憶體,共享記憶體是兩個正在執行的程序之間共享和傳遞資料的一種非常有效的方式。
logical shift
填0在shift位
Data Hazard
才將資料寫回 register,但是 and, or 卻在之前就想要去 register 拿資料 (add 則要看 register file 有沒有 internal forwarding,如果有那就可以拿到正確的資料) 解決方法: insert the NOPs => slow us down forwarding
#error
指示詞會在編譯時期發出使用者指定的錯誤訊息, 然後終止編譯。
避免 Race Condition
採用鎖定 (lock) 的方式,當我們執行共用變數的修改時,先進行鎖定,讓其他的線程無法同時修改該變數,等到修改完畢後解索後,其他的線程才能修改該變數,這樣就能避免掉競爭情況的問題了。 因為多線程的程式會有競爭情況,為了避免該情況而引入了鎖定機制,但是鎖定機制用得不好就會造成死結。
volatile
揮發的,表示此變數可能隨時會更改,所以停用編譯器優化,每次只要用到volatile標記的變數,就會重新至該變數的記憶體空間抓資料來用。 EX: c = a + b; //XXXX執行一段時間的程式碼,並且和a無關; d = a + c; 如上述,編譯器會自動將a佔存在快取中,並在d = a + c;調取上次讀取的a出來用,因此中間若有其他thread調用到a,使a數值改變的話,d = a + c;的結果將有誤。
Paging
是一種作業系統裡記憶體管理的一種技術,OS 會將 disk 中的資料分割成固定大小的區塊,稱為頁(pages)。當不需要時,將分頁由 memory 移到 disk ;當需要時再將資料取回載入 memory 中。分頁是磁碟和記憶體間傳輸資料塊的最小單位。
Binding
決定程式起始位置,即程式要在記憶體的哪個地方開始執行。Binding 有 3 個時期,compile time, load time 和 execution time。
extern
聲明變數會在其他地方定義過,所以會去外部尋找,如果都找不到,編譯器會報錯。
struct and union
自動給struct第個成員分配存儲空間,struct 可以存儲多個成員信息,而Union每個成員會用同一個存儲空間,只能存儲最後一個成員的信息。 Union大小取決於最大者。
const
表示該數據是只讀的,不可更改,所以當有任何程式碼對他的數值進行付值的時候編譯器就會報錯。
Pipeline Hazard
解釋:不同的 instruction 同時想要去用同一個資源。 解決方法:每個 intruction 要在相同的 stage 用特定的 resource。 例子:add 在第四個 stage 就已經算完可以準備 write back 了,但因為要避免 structure hazard,需要在第五個 stage 才能 write back
scope
變數範圍
set,clear,inverse the specific bit
#define SET_BIT(x, n) ( (x) |= (1<< (n)) ) #define CLR_BIT(x, n) ( (x) &= (~(1<< (n)))) #define CHK_BIT(x, n) ( ((x) & (1<< (n)))!=0 ) #define FLIP_BIT(x, n) ( (x) ^= (1<< (n)) ) #define INVERSE_BIT(x, y) ((x) = (x) ^ ((1)<<(y))) #define GET_BIT(x, y) ((x)>>(y) & 1)
dll工作基本原理
DLL(Dynamic Linkable Library)檔案,並可對它們單獨編譯和測試,在執行時,只有當EXE程式確實要呼叫這些DLL模組的情況下,系統才會將它們裝載到記憶體空間中。 當程序需要調用函數時需要先載入DLL,然後取得函數的地址,最後進行調用。使用DLL文件的好處是程序不需要在運行之初加載所有代碼,只有在程序需要某個函數的時候才從DLL中取出。另外,使用DLL文件還可以減小程序的體積。
Program /Process / Thread 的差別跟比較
Program:意旨軟體工程師在 IDE、editor等所寫的程式碼(code),也就是說還尚未load入記憶體的 code,我們稱之為Program。 Process:意旨已經執行並且 load 到記憶體中的 Program ,程序中的每一行程式碼隨時都有可能被CPU執行。 Process 是 Thread 的容器,在同一個 Process 中會有很多個 Thread ,每一個 Thread 負責某一項功能。
Big-Endian 與Little-Endian
Representation of 0x1A2B3C4D5E6F7080 in big-endian and little-endian.
解釋deadlock、Race conidtion
deadlock:兩個以上的運算單元,雙方都在等待對方停止執行,以取得系統資源,但是沒有一方提前退出時,就稱為死結。 Race conidtion:一個系統或者進程的輸出依賴於不受控制的事件出現順序或者出現時機。此詞源自於兩個訊號試著彼此競爭,來影響誰先輸出。
#define的陷阱題、與inline差別
inline 在編譯時便會把函數中的程式直接展開,但函式只能建議編譯器,建議不一定被採納,例如遞迴函式無法在呼叫點展開,數千行的函式也不適合在呼叫點展開,如果編譯器拒絕將函式展開,會視為一般函式進行編譯,inline 的建議會被忽略。 #define =>可建立巨集 Macro, 或宣告常用常數使用,是一種pre-compile header,會在程式編譯成機械語言前先編譯好
the value of *(a+1), *(p-1)?
int a[5] = {1, 2, 3, 4, 5}; int *p = (int*)(&a+1); *(a+1) = 2 *(p-1) = 5
Bit Count
int counter = 0; while ( input ) { counter++; input &= (input - 1); }