1. 程式人生 > >## CSAPP讀書日記-第三章-1

## CSAPP讀書日記-第三章-1

CSAPP讀書日記-第三章-1

第三章主要講程式是如何轉為彙編程式碼的。剛開始看這一章的時候一頭霧水,覺得跟現在的工作毫無關係,因為其就是引入了一堆非常使用者不友好的指令,將你的程式碼轉變為對記憶體或暫存器中的地址(間接)或值(直接)的操作。強行看了後,感覺有點說不清道不明的收穫。。。

先記一些知識點在下面,以作複習之用:
1.每個暫存器的容量非常之小,現在最大也就是64位,目前x86-64的CPU一共包含16個這樣的暫存器(開始我還以暫存器至少能存幾M的東西,現在看來,暫存器就是為了函式呼叫而設計的,將函式中關鍵的值或地址放到暫存器中)。
----這樣,你可能會想,我有的方法層層呼叫,這點暫存器怎麼夠用?
但然夠用啦,因為有個暫存器叫**%rsp**,其指向“棧”這個資料結構的頂部。所有的方法相關資訊都放在"棧"中。至於“棧”在哪?“棧“肯定在記憶體啊,那地方就大了~
這裡的設計精妙之處在於,“棧”是先進後出的,每次讀都是讀“棧”頂的元素,所以只要一個暫存器來儲存“棧”頂元素的地址,就能對“棧”中的資料進行有效的訪問了。

問題:----上面我雖然說“棧”是放方法的相關資訊,但我現在瞭解到的,每個地址存的都是一個具體的值,能存操作程式碼嗎?比如:leaq 2(%rax),%rax; 這種程式碼能存在"棧"中嗎?

值得注意的是**:leaq並沒有去讀地址,而是直接拿值,**上面的(%rax)並不是間接引用。。。(吐槽一下,細節太多,我差點給整暈了0.0)

16個暫存器的圖:

不知道怎麼旋轉圖片,我也很無奈~~~

2.暫存器有直接定址和間接定址之分。個人的理解就是,
----“直接定址”就是暫存器裡面存的是需要的資料
----"間接定址"就是暫存器裡面存了資料的記憶體地址,你還要在從記憶體裡找
再貼段程式碼圖:
在這裡插入圖片描述

上面的程式碼是C程式碼,然後引數裡有“*”號作為字首,就表明是“間接引用”,所以下面的賦值操作就對其加了括號(mov相當於複製源資料,再賦值給目標資料;而%rdi表明是第一個引數)。
而第2個引數 y,前面沒有星號,所以就是直接引用,movq %rsi,(%rdi) 就是把第二個引數的值覆蓋第一個引數引用的記憶體地址那的值。

這麼說吧,間接引用相當於一個key-value的結構,賦值的時候是覆蓋value,而%rdi這個暫存器本身所含有的key值並沒有變。