# 2018q3 Homework1
contributed by < `Winnie1230` >
## [現代處理器設計](http://hackfoldr.org/cpu/)
### Instruction Execution in 5-stage pipeline

>中英文字請空白隔開
>[name=課程助教][color=red]
目的是為了讓CPU在每個時間都有事情可以做
1. **IF** : Instruction Fetch 提取指令
- **PC**(Program Counter; ARM) or **IP**(Instruction Pointer; Intel)
- PC決定接下來要執行的指令,也就是說只要改變PC即可改變程式執行的流程
:::info
ARM的PC會指向下兩道指令
:::
2. **ID** : Instuction Decode
- 處理的不是instruction而是microOP
3. **EX** : Execution
- microOP
- 如何提升microOP執行的平行度?如何有效調度microOP?
:::warning
:question:
要如何執行?要如何有效的執行?
:::
4. **MEM** : memory
5. **WB** : Write Back
:::info
[AMD](https://zh.wikipedia.org/zh-tw/%E8%B6%85%E5%A8%81%E5%8D%8A%E5%AF%BC%E4%BD%93) 與 [Intel](https://zh.wikipedia.org/wiki/%E8%8B%B1%E7%89%B9%E5%B0%94)
在指令集部份會交叉授權
:::
### Microarchitecture

## [Bit-wise operations](https://hackmd.io/s/By0MltO_m)
### Bit-wise operators
1. **<<** : shift left , **>>** : shift right
```C
5 << 1 = 10 //00000101整個往左移動1個bit
5 << 2 = 20
5 >> 1 = 2
5 >> 2 = 1
```
:::info
向左移動一個bit,整個數值會是原本的兩倍
向右移動一個bit,整個數值會是原本的1/2倍
:::
:::warning
「整個數值會是原本的 ? 倍」的陳述不精準,因為可能會遇到 shift 導致某些 bit(s) 被捨棄,自然新數值就不是倍數關係
:notes: jserv
:::
>謝謝老師 :smile:
> [name=劉育如]
2. **|** : bit-wise OR
3. **^** : bit-wise XOR
4. **~** : bit-wise NOT
### operations
1. Set a bit(僅設定一個位元)
```C
unsigned char a |= (1 << n);
```
2. Clear a bit
```C
unsigned char b &= ~(1 << n);
```
3. Toggle a bit(轉換指定位置的位元)
```C
unsigned char c ^= (1 << n);
```
4. Right/Left most bytes
assuming 16 bit, 2-byte short integer:
```C
unsigned char right = val & 0xff; /* right most (least significant) byte */
unsigned char left = (val >> 8) & 0xff; /* left most (most significant) byte */
```
:::info
0xff = 0000000011111111 , 0xff的意思是只去後面8個bits
0x3039(即Hex)=12345 (Dec)
:::
5. sign bit
assuming 16 bit, 2-byte short integer, two’s complement:
```C
bool sign = val & 0x8000; // sign bit
```
:::info
表示有號數(signed numbers)時,第一位若是1則表示此數為負數,若是0則表示此數為正數
:::
#### 參考資料
[程式札記](http://puremonkey2010.blogspot.com/2011/05/c-bitwise-operation.html)
## [「你所不知道的C語言」系列講座](https://hackmd.io/s/HJpiYaZfl)
### 開發工具與規格標準
:::info
C語言最早是用來開發Unix系統
:::
#### 為什麼不探討C++?
1. C++所涵蓋的範圍太廣,內建太多機制
- 上個世紀的C++ 被稱為「物件導向的程式語言」,這個世紀探討的C++ 應該稱為Metalanguage比較恰當,其包含[Object Oriented Programming](https://zh.wikipedia.org/wiki/%E5%85%83%E8%AA%9E%E8%A8%80)及[Genertic Programming](https://zh.wikipedia.org/zh-tw/%E6%B3%9B%E5%9E%8B)
- STL(generic programming)
2. 發展及擴張速度太快
- 從C++ 14到C++ 17增加了Parallelism TS, Networking TS...等等
3. 要面對編譯器不相容的問題
- 現釋出最新的GCC是GCC8.2(release 2018/07/19)
:::info
GCC 7.1是個具備工業強度的編譯器,**重要的特徵是支援C++ 17**
:::
:::success
**glibc(grub libc)**
- 常用的C語言的程式庫
- 授權條款是LGPL(當你在撰寫程式時,僅把libc當作「動態連結的函式庫」且應用程式內容並沒有參照到GPL的source code的話,授權條款是相對比較寬鬆的)
[稍稍鬆綁的堅持-LGPL](https://www.openfoundry.org/tw/legal-column-list/519--lgpl)
**musl libc**
- 另一個C語言的程式庫
- 授權條款是MIT License(只要**不要把作者的名字塗掉**,不論以binary code的形式輸出或是以source code的形式輸出都可以)
- 本質上與glibc是相同的
其他的授權條款:
[BSD License](https://zh.wikipedia.org/wiki/BSD%E8%AE%B8%E5%8F%AF%E8%AF%81)
:::
:::info
C語言本質上是高階語言,但卻具備很多低階語言的特性
e.g. 毀滅者戰士的開發者 John Carmack 表示:c語言是一個wysiwyg(what you see is what you get)的語言(因為c語言程式碼對應到的組合語言、二進位,基本上都符合預期)
:::
:::info
Linux Kernel是一個高度物件導向開發的專案,堅持用c語言開發
:::
#### 延伸閱讀
- 第一個 C 語言編譯器是怎樣編寫的?
:::success
[compiler bootstrapping](https://en.wikipedia.org/wiki/Bootstrapping_(compilers))
:::
### ISO/IEC 9899 (簡稱 “C99”)
c++ 一開始只是class extensions to c language,一直到c99(c語言在1999年規範),c語言與c++開始分道揚鑣
:::warning
In C, everything is representation!!!
在C語言中,所有東西都是一個「明確的空間」。之所以會有**型態**,是因為可以去宣告它資料的大小
:::
#### ISO與IEC
- ISO(International Organization for Standardization,國際標準化組織)
- IEC(International Electrotechnical Commission,國際電工委員會)
- 這兩個單位常常會一起合作推出新的標準
e.g. C語言的標準即ISO/IEC 9899
e.g. [ISO/IEC 646](https://en.wikipedia.org/wiki/ISO/IEC_646)是與鍵盤輸入有關的標準
:::info
==e.g.== 是拉丁文 exempli gratia 的縮寫,意思是「舉個例子,比如」,等同與 "for example"
ex- 是「前」的意思,不要用錯
:notes: jserv
:::
#### [規格書](http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf)
1. C99是在1999年定案的規格稱為C99,但是C99本身會有微調
2. 規格書可以澄清很多誤解
e.g. &可能是AND, bit-wise AND, 用於指標操作時則稱為「address-of operator」
e.g. * 可能是multiplication,用於指標操作時則稱為「indirection operator」或「value-of operator」
e.g. [ ] 稱為「array subscripting operator」
* 可參考[Operators in C and C++](https://en.wikipedia.org/wiki/Operators_in_C_and_C%2B%2B)
:::info
事實上,C語言沒有真正的array,它最終都會轉換成**同等功能的指標**
:::
3. C++ 與C語言對**lvalue**的解釋意思不相同,lvalue在C99中的解釋 **l** 並不代表「left」,而是表示「locate」
4. 以下程式碼:
```C
int main()
{
char *ptr;
char str[] = "Hello World";
ptr = str;
}
```
在 **ptr = str**這一行,必須先了解: (在64bits下)
| | ptr | str |
| ------- | ------- | --- |
| 資料型態 | char* | char[ ] |
|sizeof()代表的意義|指標本身的大小|strlen(str)|
|sizeof()|sizeof(ptr)=8bytes|strlen(str)=11|
:::warning
既然儲存空間不同,自然就不會相同!!!
規格書就是來釐清這樣誤解
:::
:::info
"Hello World"這種宣告方式是**string literal**
而字串後有一個**null terminator(空字符)**
strlen(string)所計算的字串長度並**不包含**空字符,但是真正的儲存空間是有包含空字符的,也就是說sizeof(string)所得到的結果是有包含空字符的!!!
```C
#include<stdio.h>
#include<string.h>
int main(){
char s[]="Hello World";
printf("%d %d\n",strlen(s),sizeof(s));
}
```
執行結果:
```C
11 12
```
:::
5. sizeof() 不是一個function而是一個**operator**(規格書6.5.3.4)
6. 以下程式碼:
(1)
```C
#include<stdio.h>
struct A{
int x,y;
};
int main(){
struct A a; //建立一個struct A的物件a
printf("%d %d\n",sizeof(struct A),sizeof(&a)); //&a指pointer的大小
}
```
執行結果:
```C
8 8
```
:::warning
:question:
不太了解sizeof(&a)為什麼是指pointer的大小?
如果把上述程式碼寫成:
```C
#include<stdio.h>
struct A{
int x,y;
};
int main(){
struct A *a; //建立一個struct A的指標a
printf("%d %d\n",sizeof(struct A),sizeof(a));
```
指的是相同的意思嗎?還有sizeof(&a)跟sizeof(a)的差異在哪裡呀?
:::
(2)
```C
#include<stdio.h>
struct A{
int x,y;
};
struct B; //no definition=>forward declaration
int main(){
struct A a;
struct B *b;
printf("%d %d\n",sizeof(struct A),sizeof(struct B));
}
```
執行結果:
```C
invalid application of ‘sizeof’ to incomplete type ‘struct B’
printf("%d %d\n",sizeof(struct A),sizeof(struct B));
```
:::info
sizeof operator 遇到incomplete type
:::
7. **wchar** 在IEC61131中有規範
8. C99具有**designated initializer**,但C++ 是不支援的,因為C++有constructor
:::success
**designated initializer**
- 讓struct , array , union初始化變得更方便
- array 初始化:
```C
int a[10] = {[1]= 1, [8 ... 9]=10}; //僅初始化a[1],a[8],a[9],其餘數值等於0
```
上述程式碼相當於:
```C
int a[10] = {0, 1, 0, 0, 0, 0, 0, 0, 10, 10};
```
- struct初始化(也可用於union)
```C
struct point {
int x;
int y;
};
struct point p = { .y = 1, .x = 10 };
```
上述程式碼相當於:
```C
struct point p = { 10, 1 };
```
- [index]和 .fieldname稱為**designator**
- 使用這個特性就可以按照**任意順序**初始化array,struct和union中的成員
:::
9. 沒有「雙重指標」,只有「**指標的指標**」
在C語言中,沒有什麼double pointer,只有pointer to...(e.g. 指標的指標:pointer to pointer)
### 函式呼叫篇
1. [History of C](https://en.cppreference.com/w/c/language/history)
- C語言還是一個持續在改變的語言
- 從C11開始加入了很多現代處理器的特徵(尤其專注在concurrency、新的浮點數的支援、執行序與作業系統界面的釐清)
- C17之後又更專注在平行程式設計的部份