深入理解計算機系統(csapp)家庭作業——第三章程序機器級表示

  1. 如圖:
    在這裏插入圖片描述
long decode2(long x,long y,long z)
{
	y -= z;
	x *= y;
	int tmp = y;
	tmp = tmp << 63;
	tmp = tmp >> 63;
	tmp = x ^ tmp;
	return tmp;
}
  1. 如圖:
    在這裏插入圖片描述
    在這裏插入圖片描述
    A:x在%rid中,n在%esi中,result在%eax中,mask在%rdx中
    B:result初始值是0,mask初始值是1
    C:測試條件是判斷mask是否爲0
    D:mask每次左移n位
    E: result |= x & mask
    F:代碼填寫:
long loop(int x,int n)
{
	long result = 0;
	long mask;
	for(mask = 1;mask!=0;mask = mask<<n)
	{
		result != x & mask;
	}
	return result;
}
  1. 如圖:
    在這裏插入圖片描述
long cread_alt(long *xp)
{
	long tmp = 0;
	if(!xp)
		tmp = *xp;
	return tmp;
}
  1. 如圖:
    在這裏插入圖片描述
    在這裏插入圖片描述
long switch(long *p1,long *p2,mode_t action)
{
	long result = 0;
	swtich(action)
	{
		case MODE_A:
			result = *p2;
			int tmp = *p1;
			*p2 = tmp;
			break;
		case MODE_B:
			result = *p1;
			result += *p2;
			*p1 = result;
			break;
		case MODE_C:
			*p1 = 59;
			result = *p2;
			break;
		case MODE_D:  //之後落入E
			*p1 = *p2;
		case MODE_E: 
			result = 27;
			break;
		default:
			result = 12;
			break;
	}
	return result;
}
  1. 如圖:
    在這裏插入圖片描述
    在這裏插入圖片描述
long switch_prob(long x,long n)
{
	long result = x;
	switch(n)
	{
		case 0:
		case 2:
			result = 8x;
			break;
		case 3:
			result = x;
			result >> 3;
			break;
		case 4:
			result = x;
			result << 4;
			x -= x;
		case 5:
			x = x*x;
		case 1:
		default:
			result = x + 0x4b;
			break;
	}
	return result;
}
  1. 如圖:
    在這裏插入圖片描述
    A:A[i][j][k] = 首地址+L((ST)i+Sj+k)
    B:確定R、S和T的值。
    由彙編代碼,可以得出R
    ST8 = 3640(條件1)
    由彙編代碼,A[i][j][k]的位置的公式爲A + (65i + 13j + k)8,對照第一問得出的公式,可以得出T =13 ST = 65(條件2)
    綜合條件1,2,可以計算出R = 7 S = 5 T= 13。

  2. 如圖:
    在這裏插入圖片描述
    做這個題時應注意 數據對齊
    對齊的四個原則

      規則0:第一個數據成員應該爲1,或者是2的倍數
      規則1:結構體(struct)的數據成員,第一個數據成員放在offset爲0的地方,以後每個數據成員存放在offset爲該數據成員大小的整數倍的地方(比如int在32位機爲4字節,則要從4的整數倍地址開始存儲)。
      規則2:如果一個結構體B裏嵌套另一個結構體A,則結構體A應從offset爲A內部最大成員的整數倍的地方開始存儲。(struct B裏存有struct A,A裏有char,int,double等成員,那A應該從8的整數倍開始存儲。),結構體A中的成員的對齊規則仍滿足原則1、原則2。
      規則3:結構體的總大小,也就是sizeof的結果,必須是其內部最大成員的整數倍,不足的要補齊。
    
setVal:
    movslq  8(%rsi), %rax   #  5 <= B <= 8
    addq    32(%rsi), %rax  # 9<= A <= 10
    movq    %rax, 184(%rdi) # 180 <= A * B * 4 <= 184
    ret
  1. 如圖:
    在這裏插入圖片描述
    在這裏插入圖片描述

     <test>:
         mov    0x120(%rsi), %ecx        # ecx = *(bp + 288)
         add    (%rsi), %ecx             # ecx += *bp
                                         # 上兩行可推斷 288 是 last 與 first 的首地址之差
         lea    (%rdi, %rdi, 4), %rax    # rax = 5i
         lea    (%rsi, %rax, 8), %rax    # rax = bp + 40i
         mov    0x8(%rax), %rdx          # rdx = *(bp + 40i + 8)
         movslq %ecx, %rcx               # rcx = ecx(符號擴展)
                                         # ecx = n,將其符號擴展,賦值給 x 
                                         # 由此推斷 a_struct 中的 x 是長整型 long 的數組
         mov    %rcx, 0x10(%rax, %rdx, 8)# 8 * (*(bp + 40i + 8)) + bp + 40i + 16 = rcx
         retq
    

比較簡單的推斷在上圖中列出;
難點在mov 0x8(%rax), %rdx # rdx = (bp + 40i + 8)和mov %rcx, 0x10(%rax, %rdx, 8)# 8 * ((bp + 40i + 8)) + bp + 40i + 16 = rcx,bp + 8 + 40i 很容易猜出它是 b_struct 中 a[i] 的首地址,且 b_struct 八字節對齊,結構 a_struct 的字節數爲 40;
而 8 * ( *(bp + 40i + 8) ) 可以知道這是索引,進而推斷 a_struct 中 idx 排在 x 前面;
那麼 bp + 40i + 16 就可以寫成 bp + 8 + 40i + 8,前一個 8 是 first 的偏移,後一個 8 是 idx 的偏移;
A.
根據推斷,結構 a_struct 的字節數爲 40
CNT = (288 - 8)/40 = 7
B.

typedef struct {
    long idx;
    long x[4];
} a_struct;
  1. 如圖:
    在這裏插入圖片描述

     A:
     e1.p      0
     e1.y      8
     e2.x      0
     e2.next   8
     B:總共需要16個字節
    
C:
void proc(union ele *up)
{
	up->e2.x = *(up->e2.next->e1.p)-up->e2.next->e1.y;
}
  1. 如圖:
    在這裏插入圖片描述
#include<stdio.h>
#define MAX 10
void good_echo() {
	char buffer[MAX];
	while (fgets(buffer, MAX, stdin) != NULL) {
		printf("%s", buffer);
		if (ferror(stdin)) {
			printf("\nError\n");
			return;
		}
	}
}
  1. 如圖:
    在這裏插入圖片描述
    A.
    通過兩個連續的 xmm 寄存器,例如第一個複數參數以 %xmm0 和 %xmm1 傳遞,第二個以 %xmm2 和 %xmm3 傳遞,以此類推
    B.
    %xmm0 作爲返回值的實部, %xmm1 作爲返回值的虛部
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章