程式設計正規化 史丹福大學 學習筆記《九》

2021-08-21 12:45:35 字數 2314 閱讀 9421

接下來的課程會涉及到計算機體系結構和組合語言,解釋c/c++**片段是如何編譯成彙編**的,記憶體模型,函式呼叫,函式返回的型別等。

4位元組變數的例子:

int i;

int j;

i=10;

j=i+7;

j++;

對應的彙編**:

m[r1+4]=10;//store operation(將棧段中某個區域的值進行了更新)

r2=m[r1+4];//load operation

r3=r2+7;//alu operation

m[r1]=r3;//store operation

r2=m[r1];

r2=r2+1;

m[r1]=r2;

注意:

1.大寫的m代表整個ram的名字,可以將整個ram看做乙個非常大的位元組陣列,m則是這個陣列的名字,r1儲存著基位址,4是偏移量。

2.不能直接進行m[r1]++操作,因為這裡的組合語言指令不允許任意記憶體位址作為alu運算操作的運算元,必須先使用load操作,然後使用暫存器的值作為運算元執行alu操作,然後再將結果寫回記憶體中。這樣的操作會令我們的組合語言更加簡單,並且當指令簡單時,時鐘頻率也會較快。

3.預設情況下load、store以及alu操作處理的都是4位元組的資料,因為在c\c++語言中指標和int型別是非常常用的型別,因此硬體對這種4位元組的記憶體的訪問進行了優化。

非4位元組變數的例子:

int i;

short s1;

short s2;

i=200;

s1=i;

s=s1+1;

對應的彙編**:

m[r1+4]=200;

r2=m[r1+4];

m[r1+2]=.2 r2;//將暫存器r2中最低的2個位元組的內容更新到m[r1+2]這個位址對應的記憶體

r2=.2 m[r1+2];

r3=r2+1;

m[r1]=.2 r3;

注意:

使用.2遮蔽掉預設處理4個位元組這個規則,因為預設的規則假定所有這類的指令都隱含乙個.4,當想要移動2個位元組或者1個位元組時就需要寫上.2或者.1。

int arr[4];

int i;

for(i=0;i<4;i++)

i--;

對應的彙編**:

m[r1]=0;

r2=m[r1];

bge(r2,4,pc+40)//40為該行**到跳出for迴圈的**的距離乘以4

r3=m[r1];

r4=r3*4;//r4儲存的是偏移量

r5=r1+4;//r5儲存的是整個陣列的基位址

r6=r4+r5;//r6儲存著在這次的迭代中array中應該賦值為0的位址

m[r6]=0;

r2=m[r1];

r2=r2+1;

m[r1]=r2;

jmp pc-40//跳到第2行**,相差10條指令,因此為10*4=40

//跳出for迴圈

r2=m[r1];

r2=r2-1;

m[r1]=r2;

注意:

1.分支指令(branch instructions)的縮寫:beq,bne,blt,ble,bgt,bge。

2.在所有的彙編**中都不能使用sizeof(int),必須手動計算c和c++中的型別所佔空間大小。

指令編碼:

r1=m[r2+4];//load指令

r1=1000;//立即數load指令

r3=r6*r10;//alu指令

m[r1-20]=r19;//store指令

這四條指令的用6為位元組表示opcode(也就是硬體能夠看懂的01機器碼)都不同,硬體會在時鐘週期的前一部分檢視前6位是什麼,然後再決定如何解釋剩下的26位。

struct fraction

struct fraction pi;

pi.num=22;

pi.denum=7;

((struct fraction*)&pi.denum)->denum=451;

對應的彙編**:

m[r1+8]=451

m[r1]=22;

m[r1+4]=7;

在生成的彙編**中是沒有與強制型別轉換相對應的指令,強制轉換作用是只是允許編譯器能夠產生彙編**。強制型別轉換讓編譯器允許繞過型別檢查的機制進而通過編譯生成**。

程式設計正規化 史丹福大學 學習筆記《三》

本課繼續講解了c語言的強制型別轉換,之後介紹了結構體,陣列以及結構體中的陣列。和 的技巧 例1 double d 3.1416 char ch char d 取出d的位址,並重新解釋為char型,然後解引用。由於double為8bytes,而char為1bytes,因此ch表示的是原來double中...

史丹福大學開放課程 程式設計正規化學習筆記《二》

史丹福大學開放課程 程式設計正規化學習筆記 二 本課講述了c c 關於int,float等資料的底層表示,以及賦值操作所進行的處理。本節內容比較簡單,應該屬於組成原理的基礎知識,各種碼的表示和底層實現,但是,講述還不錯,特別是為何要這樣形成補碼,比單純記憶強多了,這樣才理解了取反加1的原因,比當初上...

《程式設計方法學》史丹福大學

程式設計方法學 史丹福大學 網易公開課 感悟 1.for 語句,可以使用i,j,k 變數 不需該意使用有意名字的變數 顯示它只是 計算器 一自就明白 2.注釋 一定要加注釋 3.使用長量 列舉 不建議使用全域性變數 4.函式 函式中定義變數和外部變數同名時,內部函式有效 變數名相同,但函式外和函式內...