天天看點

深入了解計算機系統_3e 第三章家庭作業 CS:APP3e chapter 3 homework

這個題考察的是2.3.4和2.3.5節的一個定理:w比特長度的兩個數相乘,會産生一個2w長度的數,不管這兩個數是無符号數還是補碼表示的有符号數,把結果截取的低w比特都是相同的。

是以我們可以用無符号數乘法指令mulq實作有符号數乘法:先把數有符号擴充緻2w位,然後把這兩個2w位的數相乘,截取低2w位即可。

截取就是求模運算,即 mod 2^w。

A. x : %rdi n : %esi result : %rax mask : %rdx

B. result = 0 mask = 1

C. mask != 0

D. mask >>= n

E. result |= (x & mask)

這個地方也是很無語,在我的環境下必須将tmp的存儲類型設定為靜态存儲,并且将gcc的優化設定為O3,這樣才能生成使用conditional transfer的指令(才能讓gcc相信優化是值得的。。):

A. &A[i][j][k] = Xa + L(i*S*T + j*T + k)

B. R = 7,S = 5,T = 13

A. rdx (每次移位8,即按行移動)

B. rax(每次移位120 = 8 * 15,按列移動)

C. 由B,M = 15

NR(n)是數組的行數,是以我們找循環的次數,即rdi,得到rdi = 3n.

NC(n)是數組的列數,是以我們應該找每次循環更新時對指針增加的值,這個值等于sizeof(long) * NC(n),即r8,得到r8 = 8 * (4n + 1).

綜上,可知兩個宏定義:

A.

深入了解計算機系統_3e 第三章家庭作業 CS:APP3e chapter 3 homework

B. %rsp + 64

C. 通過以%rsp作為基位址,偏移8、16、24來擷取strA s的内容(由于中間夾了一個傳回位址,是以都要加8)

D. 通過傳進來的參數%rdi(%rsp + 64 + 8),以此作為基位址,偏移8、16、24來寫入strB r

E.

深入了解計算機系統_3e 第三章家庭作業 CS:APP3e chapter 3 homework

F. 我記得我在看《C語言程式設計: 現代方法 2rd》的時候,裡面說傳遞聚合類型的變量可以使用指針,這樣比傳遞整個資料結構要快一些(當然寫操作會改變實參)。這個題目裡面也都是讀操作,可以發現編譯器自動進行了優化——傳遞了基位址而非複制了整個資料結構。傳回就是在調用它的函數的棧幀中存入一個相關的資料結構。(這個題裡面process其實沒有棧幀,如果傳回位址算eval的話)

這題考察的是記憶體對齊。通過結構體成員的位置逐漸縮小範圍:

int t 為8(%rsi),是以4<B<=8

long u 為32(%rsi),是以24 < 8 + 4 + 2*a <= 32,得到6<A<=10

long y 為184(%rdi),是以176 < 4*A*B <= 184,得44 < A*B <=46。

是以AB = 45 或者AB = 46,結合A, B各自的範圍,隻可能為A = 9, B = 5.

A. 根據第4、5行的指令, idx的值為(bp + 40i + 8),由第1、2行指令,這裡的8是因為第一個int first整數和記憶體對齊的原因,是以每一個a_struct的大小為40位元組。

由于0x120 - 0x8 = 280位元組,是以CNT = 280/40 = 7.

B. 由第6、7行指令知,idx和x數組内元素都是signed long類型的。由于整個a_struct資料類型大小為40位元組,是以其内部應該為8*5 = 8 + 8*4:

e1.p : 0

e1.y : 8

e2.x : 0

e2.next : 8

B. 16 bytes

C.

A. andq $-16, X這條指令相當于将低4位置零,也就是使得rax中儲存的8n+30對16取整。是以s2-s1為8n+30對16取整的結果。

B. p的值為rsp(r8)-15對16取整的結果,確定了p數組的起始位址為16的整數倍。

C. 8n + 30對16取整有兩種可能:一種是8n本身就是16的整數倍即n = 2k,此時取整後為8n+16; 另一種是8n = 16k + 8即n = 2k + 1,此時取整後為8n + 24。由System V AMD64 ABI标準可知,s1的位址為16的整數倍(即結尾為0000),是以s2的位址也肯定是16的整數倍(結尾為0000)。又因p是由s2減15對16取整得到的結果,是以p和s2之間肯定相差2位元組,即e2 = 2 bytes. 是以e1最大為(n為奇數) :8n + 24 - 16 - 8n = 8 bit, 最小為(n為偶數):8n + 16 -16 - 8n = 0.(這個題我估計沒有考慮到ABI标準對于棧幀對齊的問題,s1的位址本來就應該是16的整數倍)

D. 由A B C可知,這種方法保證了s2 和 p的起始位址為16的整數倍,而且保證了e1最小為8n,能夠存儲p數組。

浮點數部分并未測試

A. 每一個複數變量使用兩個%xmm寄存器傳送。

B. 通過%xmm0和%xmm1傳回一個複數類型值。