2013年10月22日 星期二

解讀declaration時:
Read
     *  as "pointer to"   
     []  as "array of"   
     ()  as "function returning"
 
優先權和一般運算相同 

2013年10月16日 星期三

對電腦而言資料並沒有資料型態之分,int, double等等在電腦眼裡全都是二進位
指定資料型態的功用是告訴電腦這個資料的大小,以及怎麼對這筆資料做運算


資料型態 = 空間大小 + 運算方式

變數或函數名稱的本質

不管是什麼程式語言,變數名稱或函數名稱本質上只是一個reference,指向記憶體中的某個位址

例子1:
C語言裡
int x = 1;
int y = 2;
x = y;
執行x = 1時,C會在記憶體裡分配空間,存入1,然後讓x成為指向該記憶體位址的reference
執行y=2的過程也一樣。
至於x = y為什麼在C裡面不是解釋成"讓x指向y所指向的地方"呢?
那是因為C定義"等於"這個「運算」在兩個int型態的reference上的功能是:將y所指向的位址裡所存的值,複製到x所指向的位址。因此,變數名稱本質上只是一個reference。

例子2:
void func(int x)
    printf("%d", x);
C語言會將這個函數的程式碼放入記憶體的某個位址,然後讓"func"這個函數名稱reference到程式碼第一行的記憶體位址。所以函數名稱本質上也只是個reference

2013年7月6日 星期六

多執行緒(不確定觀念對不對)

基本原則:
1. 不要假設有順序
2. 執行緒任何時候都有可能被中斷
3. 注意共用資源

volatile:
1. 從記憶體拿,存記憶體,而不是暫存器。亦即該變數的讀寫"必須照順序確實執行"
2. 修改變數的執行緒會在修改變數後從其他函數返回,或是呼叫其他函數,該變數就不會被放在暫存器中

區間鎖定式函數和所有同步功能都會設立記憶體藩籬(記憶體藩籬內對記憶體的讀寫"必須照code上的順序確實執行",而且在離開藩籬之前所有的讀寫都會完成)

volatile是禁止compiler的reordering optimizations
memory barrier是禁止CPU的out-of-order execution,並保證不同顆CPU的cache會一致

總結:
volatile是禁止compiler的優化,確保CPU每次都從記憶體取值、寫入記憶體,而非從暫存器取值、寫入暫存器
記憶體藩籬是禁止CPU的優化,確保不同顆CPU的cache一致,並讓變數寫入記憶體

2013年6月10日 星期一

extern是用來告訴編譯器:「這個變數/函數的定義是在外部的(external identifier),請對這個external identifier先做特殊處理,好讓連結器知道在處理這個檔案的obj檔時要記得去解決這個external identifier的reference問題」

2013年5月23日 星期四

C的calling convention

C的calling convention:
假設在main()裡面有下面這一行C程式碼
string_copy(s, d, len);

這行C程式碼對應到的組合語言為:
push len
push d
push s    (反向push)
call string_copy
pop       (caller要負責clean up the stack,換句話說,asm裡面並不需要將參數pop出堆疊)
pop
pop

此外,回傳值會被存在eax暫存器

結論:
(1) 參數會以由右到左的順序push進堆疊
(2) 回傳值會被存在eax暫存器
(3) caller要負責clean up the stack

2013年3月22日 星期五

Verilog

1. 所有的程式碼都是在positive edge的那一瞬間執行
2. registers的值會在該positive edge結束後馬上更新

2013年3月10日 星期日