




版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
1、深入理解計算機系統(第二版) 家庭作業 第二章 2.55-2.57 略2.58int is_little_endian() int a = 1; return *(char*)&a);2.59(x&0xFF) | (y&0xFF)2.60unsigned replace_byte(unsigned x, unsigned char b, int i)
2、 return (x & (0xFF<<(i<<3) | (b << (i<<3);2.61A. !xB. !xC. !(x>>(sizeof(int)-1)<<3)D. !(x&0xFF)注意,英文版中C是最低字節,D是最高字節。中文版恰好反過來了。這里是按中文版來做的。2.62這里我感覺應該是英文版對的,int_shifts_are_arithmetic()int int_shifts_ar
3、e_arithmetic() int x = -1; return (x>>1) = -1;2.63對于sra,主要的工作是將xrsl的第w-k-1位擴展到前面的高位。這個可以利用取反加1來實現,不過這里的加1是加1<<(w-k-1)。如果x的第w-k-1位為0,取反加1后,前面位全為0,如果為1,取反加1后就全是1。最后再使用相應的掩碼得到結果。對于srl,注意工作就是將前面的高位清0,即xsra & (1<<
4、;(w-k) - 1)。額外注意k=0時,不能使用1<<(w-k),于是改用2<<(w-k-1)。 int sra(int x, int k) int xsrl = (unsigned) x >> k; int w = sizeof(int) << 3; unsigned z = 1
5、 << (w-k-1); unsigned mask = z - 1; unsigned right = mask & xsrl; unsigned left = mask & (z&xsrl) + z); return left | ri
6、ght;int srl(unsigned x, int k) int xsra = (int) x >> k; int w = sizeof(int)*8; unsigned z = 2 << (w-k-1); return (z -
7、0;1) & xsra;2.64int any_even_one(unsigned x) return !(x & (0x55555555);2.65int even_ones(unsigned x) x = (x >> 16); x = (x >> 8);
8、; x = (x >> 4); x = (x >> 2); x = (x >> 1); return !(x&1); x的每個位進行異或,如果為0就說明是偶數個1,如果為1就是奇數個1。那么可以想到折半縮小規模。最后一句也可以是 return (x1)&12.66根據提示想到利用或運算,將
9、最高位的1或到比它低的每一位上,忽然想如果x就是10000000.該如何讓每一位都為1。于是便想到了二進擴展。先是x右移1位再和原x進行或,變成1100000.,再讓結果右移2位和原結果或,變成11110000.,最后到16位,變成11111111.。int leftmost_one(unsigned x) x |= (x >> 1); x |= (x >> 2); &
10、#160; x |= (x >> 4); x |= (x >> 8); x |= (x >> 16); return x(x>>1);2.67A.32位機器上沒有定義移位32次。B.beyond_msb變為 2<<31。C.定義 a = 1<<15;
11、 a<<=15; set_msb = a<<1; beyond_msb = a<<2;2.68感覺中文版有點問題,注釋和函數有點對應不上,于是用英文版的了。個人猜想應該是讓x的最低n位變1。int lower_one_mask(int n) return (2<<(n-1) - 1;2.69unsigned rotate_right(unsigned x, int n) int
12、 w = sizeof(unsigned)*8; return (x>>n) | (x<<(w-n-1)<<1);2.70這一題是看x的值是否在 - 2(n-1) 到 2(n-1) - 1之間。如果x滿足這個條件,則其第n-1位就是符號位。如果該位為0,則前面的w-n位均為0,如果該位為1,則前面的w-n位均為1。所以本質是判斷,x的高w-n+1位是否為0或者為-1。int fits_bits(int x, int n)
13、160; x >>= (n-1); return !x | !(x);2.71A.得到的結果是unsigned,而并非擴展為signed的結果。B.使用int,將待抽取字節左移到最高字節,再右移到最低字節即可。int xbyte(unsigned word, int bytenum) int ret = word << (3 -
14、 bytenum)<<3); return ret >> 24;2.72A.size_t是無符號整數,因此左邊都會先轉換為無符號整數,它肯定是大于等于0的。B.判斷條件改為if(maxbytes > 0 && maxbytes >= sizeof(val)2.73請先參考2.74題。可知:t = a + b時,如果a,b異號(或者存在0),則肯定不會溢出。如果a,b均大于等于0,則t<0就是正溢出,如果a,b均小于0,則t>=0就是負溢出。于是,
15、可以利用三個變量來表示是正溢出,負溢出還是無溢出。int saturating_add(int x, int y) int w = sizeof(int)<<3; int t = x + y; int ans = x + y; x>>=(w-1);
16、 y>>=(w-1); t>>=(w-1); int pos_ovf = x&y&t; int neg_ovf = x&y&t; int novf = (pos_ovf|neg_ovf); return (pos_ovf &
17、 INT_MAX) | (novf & ans) | (neg_ovf & INT_MIN); 2.74對于有符號整數相減,溢出的規則可以總結為:t = a-b;如果a, b 同號,則肯定不會溢出。如果a>=0 && b<0,則只有當t<=0時才算溢出。如果a<0 && b>=0,則只有當t>=0時才算溢出。不過,上述t肯定不會等于0,因為當a,b不同號時:1) a!=b,因此a-b不會等于0。2) a-b <= abs(a) + abs(b) <=
18、 abs(TMax) + abs(TMin)=(2w - 1)所以,a,b異號,t,b同號即可判定為溢出。int tsub_ovf(int x, int y) int w = sizeof(int)<<3; int t = x - y; x>>=(w-1); y>>=(w-1);
19、; t>>=(w-1); return (x != y) && (y = t);順便整理一下匯編中CF,OF的設定規則(個人總結,如有不對之處,歡迎指正)。t = a + b;CF: (unsigned t) < (unsigned a) 進位標志OF: (a<0 = b<0) && (t<0 != a<0)t = a - b;CF: (a<0 && b>=0) | (a<0 = b<
20、;0) && t<0) 退位標志OF: (a<0 != b<0) && (b<0 = t<0)匯編中,無符號和有符號運算對條件碼(標志位)的設定應該是相同的,但是對于無符號比較和有符號比較,其返回值是根據不同的標志位進行的。詳情可以參考第三章3.6.2節。2.75根據2-18,不難推導, (x'*y')_h = (x*y)_h + x(w-1)*y + y(w-1)*x。unsigned unsigned_high_prod(unsigned x, unsigned y) &
21、#160; int w = sizeof(int)<<3; return signed_high_prod(x, y) + (x>>(w-1)*y + x*(y>>(w-1);當然,這里用了乘法,不屬于整數位級編碼規則,聰明的辦法是使用int進行移位,并使用與運算。即 (int)x>>(w-1) & y 和 (int)y>>(w-1) & x。注:不使用long long來實現sign
22、ed_high_prod(int x, int y)是一件比較復雜的工作,而且我不會只使用整數位級編碼規則來實現,因為需要使用循環和條件判斷。下面的代碼是計算兩個整數相乘得到的高位和低位。int uadd_ok(unsigned x, unsigned y) return x + y >= x;void signed_prod_result(int x, int y, int &h, int &a
23、mp;l) int w = sizeof(int)<<3; h = 0; l = (y&1)?x:0; for(int i=1; i<w; i+) if( (y>>i)&1 )
24、; h += (unsigned)x>>(w-i); if(!uadd_ok(l, x<<i) h+; l
25、160;+= (x<<i); h = h + (x>>(w-1)*y) + (y>>(w-1)*x);最后一步計算之前的h即為unsigned相乘得到的高位。sign_h = unsign_h - (x>>(w-1) & y) - (y>>(w-1) & x);sign_h = un
26、sign_h + (x>>(w-1) * y) + (y>>(w-1) * x);2.76A. K=5: (x<<2) + xB. K=9: (x<<3) + xC. K=30: (x<<5) - (x<<1)D. K=-56: (x<<3) - (x<<6)2.77先計算x>>k,再考慮舍入。舍入的條件是x<0&&x的最后k位不為0。int divide_power2(int x, int k)
27、60; int ans = x>>k; int w = sizeof(int)<<3; ans += (x>>(w-1) && (x&(1<<k)-1); return ans; 2.78這相當于計算(x<<2) + x) >> 3,當然,需要考慮x為負數時的舍入。
28、先看上述表達式,假設x的位模式為b(w-1), b(w-2), . , b(0),那么我們需要計算:b(w-1),b(w-2),b(w-3), . ,b(0), 0, 0+ b(w-1),b(w-2),.,b(2), b(1), b(0)最后需要右移3位。因此我們可以忽略下方的b(1),b(0)。于是就計算(x>>2) + x,再右移一位即是所求答案。不過考慮到(x>>2) + x可能也會
29、溢出,于是就計算(x>>3) + (x>>1),這個顯然是不會溢出的。再看看b(0)+b(2)會不會產生進位,如果產生進位,則再加一。最后考慮負數的舍入。負數向0舍入的條件是x<0 && (x<<2)+x 的后三位不全為0)。滿足舍入條件的話,結果再加1。容易證明,加法后三位不全為0可以等價為x后三位不全為0。 int mul5div8(int x) int b0 = x&1, b2 = (x>
30、;>2)&1; int ans = (x>>3) + (x>>1); int w = sizeof(int)<<3; ans += (b0&b2); ans += (x>>(w-1) && (x&7);
31、 return ans; 2.79不懂題意,感覺就是2.78。2.80A. 1w-n0n: (1<<n) - 1)B. 0w-n-m1n0m: (1<<n) - 1) << m2.81A. false,當x=0,y=TMin時,x > y,而-y依然是Tmin,所以-x > -y。B. true,補碼的加減乘和順序無關(如果是右移,則可能不同)。C. false,當x=-1, y=1時,x + y = 0xFFFFFFFE,而(x+y) = 0xFFFFFFFF。D.
32、true,無符號和有符號數的位級表示是相同的。E. true,最后一個bit清0,對于偶數是不變的,對于奇數相當于-1,而TMin是偶數,因此該減法不存在溢出情況。所以左邊總是<=x。2.82A. 令x為無窮序列表示的值,可以得到x*2k = Y + x。所以 x = Y/(2k - 1)。B. (a)1/7, (b)9/15 = 3/5, (c)7/63 = 1/92.83浮點數的一個特點就是,如果大于0,則可以按unsigned位表示的大小排序。如果小于0則相反。注意都為0的情況即可。所以條件是:(ux<<1)=0 && (uy<<1)=0)
33、| (!sx && sy) | (!sx && !sy && ux >= uy) |(sx && sy && ux <= uy);2.84A. 5.0,5表示為101,因此位數M就是1.01為1.25,小數f為0.01 = 0.25。指數部分應該為E=2,所以其指數部分位表示為e=(2(k-1)-1) + 2 = 2(k-1)+1。位表示三個部分分別是s-e-f,為0-10.01-0100.0。B.能被準確描述的最大奇數,那么其M=1.111.1,故f部分全為1,E應該為n。當然,這
34、個假設在2(k-1)>=n的情況下才能成立。這時,s=0,e=n+2(k-1)-1,f=11.1。值為2(n+1)-1。C.最小的規格化數為2(1-bias)即2(-2(k-1)+2),所以其倒數值V為2(2(k-1)-2),所以M為1.00000,f部分為全0,E=2(k-1)-2,e部分為2(k-1)-2 + bias = 2k - 3,即為11.101。位表示為0-11.101-00.0。2.85描述擴展精度值十進制最小的正非規格化數2(-63)*2(-214+2)3.6452e-4951最小的正規格化數2(-214+2)3.3621e-4932最大的規格化數(264-1)*2(2
35、14-1-63)1.1897e+49322.86描述HexMEV-00x80000-62-最小的值>10x3F01257/2560257*2(-8)2560x470018-最大的非規格化數0x00FF255/256-62255*2(-70)-inf0xFF00-Hex為0x3AA00x3AA0416/256-5416*2(-13)=13*2(-8)2.87格式A格式B位值位值1 01110 001-9/161 0110 0010-9/160 10110 1012080 1110 10102081 00111 110-7/10241 0000 0111-7/10240 00000 1016
36、/2170 0000 000001 11011 000-40961 1111 0000-inf0 11000 1007680 1111 0000inf沒有特別明白轉換成最接近的,然后又說向+inf舍入的含義。按理說,舍入到+inf就是向上舍入,而并不是找到最接近的。表格中是按最接近的進行舍入,并且如果超出范圍則認為是inf。如果都按+inf進行舍入,那么第四行格式B將是0 0000 0001。2.88A. false,float只能精確表示最高位1和最低位的1的位數之差小于24的整數。所以當x=TMAX時,用float就無法精確表示,但double是可以精確表示所有32位整數的。B. fals
37、e,當x+y越界時,左邊不會越界,而右邊會越界。C. true,double可以精確表示所有正負253以內的所有整數。所以三個數相加可以精確表示。D. false,double無法精確表示264以內所有的數,所以該表達式很有可能不會相等。雖然舉例子會比較復雜,但可以考慮比較大的值。E. false,0/0.0為NaN,(非0)/0.0為正負inf。同號inf相減為NaN,異號inf相減也為被減數的inf。2.89float的k=8, n=23。 bias = 27 - 1 = 127。最小的正非規格化數為2(1-bias-n) = 2-149。最小的規格化數為2(0-bias)*2 = 2-1
38、26。最大的規格化數(二的冪)為2(28-2 - bias) = 2127。因此按各種情況把區間分為TMin, -148 -149, -125 -126, 127 128, TMax。float fpwr2(int x) /* Result exponent and fraction */ unsigned exp, frac; unsigned u; if (x
39、;< -149) /* Too small. Return 0.0 */ exp = 0; frac = 0; else if (x < -126)
40、160; /* Denormalized result */ exp = 0; frac = 1<<(x+149); else if (x < 128)
41、60; /* Normalized result. */ exp = x + 127; frac = 0; else /* Too big. Return +oo */
42、160; exp = 255; frac = 0; /* Pack exp and frac into 32 bits */ u = exp << 23 | frac;
43、0;/* Return as float */ return u2f(u);2.90A.pi的二進制數表示為:0 10000000 10010010000111111101011,E=128-127=1,它表示的二進制小數值為:11.0010010000111111101011B.根據2.82,可知1/7的表示為0.001001001.,所以22/7為11.001001001001001001.C.從第9位開始不同。為了方便測試2.91-2.94,我寫了幾個公共函數。typedef unsigned float_bits;float
44、60;u2f(unsigned x) return *(float*)&x);unsigned f2u(float f) return *(unsigned*)&f);bool is_float_equal(float_bits f1, float f2) return f2u(f2) = f1;bool is_nan(float_bits f
45、b) unsigned sign = fb>>31; unsigned exp = (fb>>23) & 0xFF; unsigned frac = fb&0x7FFFFF; return exp = 0xFF && frac != 0;bool is_inf
46、(float_bits fb) unsigned sign = fb>>31; unsigned exp = (fb>>23) & 0xFF; unsigned frac = fb&0x7FFFFF; return exp = 0xFF && frac = 0;int
47、testFun( float_bits(*fun1)(float_bits), float(*fun2)(float) unsigned x = 0; do /test for all 232 value float_bits fb = fun1(x); f
48、loat ff = fun2(u2f(x); if(!is_float_equal(fb, ff) printf("%x errorn", x); return&
49、#160;0; x+; while(x!=0); printf("Test OKn"); return 1;最后的testFun是用來測試fun1和fun2是否對每種可能的輸入都輸出相同的值,fun1為題中所要求的函數,fun2為float版本。這個
50、函數大概會運行2到3分鐘,也可以寫多線程,利用多核處理器求解。 2.91float_bits float_absval(float_bits f) if(is_nan(f) return f; else return f & 0x7FFFFFFF;float float_absval_f(float f) if(is_nan(f2u(f) r
51、eturn f; else return fabs(f);測試即調用testFun(float_absval, float_absval_f);在測試的時候發現0x7F800001的時候不對了。后來debug了一下,發現u2f的時候,會篡改原值。即令x = 0x7F800001。則f2u(u2f(x)會變成0x7FC00001。奇怪的nan,第22位一定是1。我將f2u和u2f里用memcpy也同樣是不行。所以,我將testFun中的一個條件變成了:if(!is_float_equal(fb, ff) &&am
52、p; !is_nan(fb)這個bug實在是不知道怎么回事。想了想,這和高位低位排列是無關的。這個bug還是之后再找吧。也有可能是硬件本身的原因了。注:C庫中也提供了isnan()函數。2.92float_bits float_negate(float_bits f) if(is_nan(f) return f; else return f0x80000000;float float_negate_f(float f)
53、60; if(isnan(f) return f; return -f;就是將最高位反位。2.93float_bits float_half(float_bits f) unsigned sign = f>>31; unsigned exp = (f>>23) & 0xFF; u
54、nsigned frac = f&0x7FFFFF; if(exp = 0) return sign<<31 | (frac>>1) + (frac&1)&&(frac>>1)&1); else if(exp = 1) return sign<<31 | ( (1<<
55、22) | (frac>>1) + (frac&1)&&(frac>>1)&1) else if(exp != 255) return sign<<31 | (exp-1) << 23 | frac; else return f;float fl
56、oat_half_f(float f) if(!isnan(f) return (float)0.5*f; else return f;需要注意的是,舍入采用的是向偶數舍入。這也是我在測試的過程中發現的。(好吧,書上在浮點數位級編碼規則中說過了,眼殘沒看到)最后,非規格化的平滑效果讓exp=1時的程序變得比較簡潔。2.94float_bits float_twice(float_bits f) un
57、signed sign = f>>31; unsigned exp = (f>>23) & 0xFF; unsigned frac = f&0x7FFFFF; if(exp = 0) return sign<<31 | frac<<1; else if(exp&
58、#160;< 254) return sign<<31 | (exp+1)<<23 | frac; else if(exp = 254) return sign<<31 | 0xFF<<23; else return f;float float_twice_f(float f)
59、60; if(!isnan(f) return (float)2*f; else return f;比float_half簡單一些。對于非規格化的平滑,使用移位就可以了,對于規格化,只要exp+1即可,當然,如果exp=254,就要返回inf了。2.95float_bits float_i2f(int i) if(i = 0) return 0;
60、 unsigned x = i>0?i:-i; int sign = i>0?0:1; int w = sizeof(int)<<3; int j; for(j=w-1; j>=0; j-) /找到最高位 if(
61、 (x>>j) & 1) break; unsigned bias = 127; unsigned exp, frac; exp = bias + j; if(j <= 23) frac = x<<(23-j);
62、0; else frac = x>>(j-23); unsigned mask = (1<<(j-23) - 1; if( (x&mask) > (1<<(j-2
63、4) ) frac+; /需要舍入到大值 else if( (x&mask) = 1<<(j-24) && (frac&1) frac+; /舍入到偶數 if(frac = (1<<24) exp+;&
64、#160;/舍入到偶數超過(1<<24) - 1,指數需要再加1 return sign<<31 | exp<<23 | frac&0x7FFFFF;void test() int x = 0; do
65、60;float_bits fb = float_i2f(x); float ff = (float)x; if(!is_float_equal(fb, ff) printf("error in %d:
66、60;%x %xn", x, fb, f2u(ff); return; x+; while(x!=0); printf("Te
67、st OKn");無恥地使用了循環。我也是一點一點測試修改,才通過的。不過好在大方向都知道,所以沒有花多少時間,主要糾結點還是在舍入那塊。需要特別注意。2.96int float_f2i(float_bits f) unsigned sign = f>>31; int exp = (f>>23) & 0xFF; int frac = (f&
68、0x7FFFFF) | (1<<23); exp -= 127; if(exp < 0) return 0; if(exp >= 31) return 0x80000000; /絕對值不大于231(1<<31) if(exp >
69、60;23) frac <<= (exp - 23); else frac >>= (23 - exp); return sign? -frac : frac;void test2() int x = 0; do
70、60; int m = float_f2i(x); int n = (int)u2f(x); if(m != n) printf("error in %
71、x: %d %dn", x, m, n); return; x+; while(x!=0); printf(&qu
72、ot;Test OKn");在exp<0和>=31上犯了小錯誤。開始寫成<=0和>=32了。其實1這個整數就是exp=0的。而int絕對值不會超過231-1,因此1.0000.小數點右移不會到超過30次(否則就越界了),所以exp<=30。而這里剛好用TMin來表示越界,因此不用關心TMin的表示。深入理解計算機系統(第二版) 家庭作業 第三章 3.54int decode2(int x, int y, int z) int ret;
73、60; z -= y; /line 2 ret = z; /line 3 ret <<= 15;/line 4 ret >>= 15;/line 5 return ret*(zx);3.55大概算法如下:x的高32位為xh,低32位為xl。y的符號位擴展成32位之后為ys(ys
74、為0或者-1)。dest_h = (xl*ys)_l + (xh*y)_l + (xl*y)_hdest_l = (xl*y)_l注意,所有的乘法都是unsigned*unsigned。也就是說對于 1*(-1),如果存入兩個寄存器中,那么高32位是0,低32位是-1。 相當于 1*(UNSIGNED_MAX)。3.56注意n在這里是一個很小的數,用8位就能表示,也可以用n=n%256表示。寄存器 變量esi xebx nedi resultedx maskint loo
75、p(int x, int n) int result = 1431655765; int mask; for(mask = 1<<31; mask != 0; mask = (unsigned)mask)>>n) resul
76、t = (mask & x); return result;3.57xp?*xp:0這個語句是不能被編譯成條件傳送語句的。因為如果是條件傳送語句,那么不論xp為什么,*xp都會被計算。我們要寫一個和該功能完全一樣的能編譯成條件傳送語句的函數。于是,我們要想辦法不使用*xp,而使用一個替代的指向0的非空指針。int cread_alt(int *xp) int t =
77、160;0; int *p = xp?xp:&t; return *p;3.58MODE_A: result = *p1; *p1 = *p2; break;MODE_B: result = *p1 + *p2; *p2 = result; break;MODE_C: result = *p1; *p2 = 15; break;MODE_D:
78、60;*p2 = *p1;MODE_E: result = 17; break;default: result = -1; break;3.59int switch_prob(int x, int n) int result = x; switch(n) case&
79、#160;0x28: case 0x2a: result <<= 3; break; case 0x2b:
80、60; result >>= 3; break; case 0x2c: result <<= 3;
81、160;result -= x; case 0x2d: result *= result; case 0x29: /也可以不要
82、;default: result += 0x11; return result;中間有一句話沒明白,匯編第12行 lea 0x0(%esi), %esi3.60對于ARST,Aijk 的位置
83、是 A(,i*S*T+j*T+k,4)。由匯編代碼可知:S*T = 63;T = 9;R*S*T = 2772/4;所以得 R=11, S=7, T=9。3.61感覺可以用-j,而不是比較j和 var_prod_ele(int n, int Ann, int Bnn, int i, int k) int j = n-1; int result = 0; &
84、#160; for(; j!=-1; -j) result += Aij * Bjk; return result;但是這樣得到的結果仍然會使用到存儲器。按下面的代碼,循環里面貌似就沒有用到存儲器。但是用到了一個常量4,就是增加a的時候,會add 4。只需要result,a,e,b,4n這五個變量。int var_prod_ele(int n,
85、int Ann, int Bnn, int i, int k) int result = 0; int *a = &Ai0; int *b = &B0k; int *e = &Ain; for(;
86、a!=e;) result += *a * *b; b+=n; a+; return result;下面是其匯編代碼的循環部分
87、:edi是4*n,ebx和edx分別是b和a,esi是e,eax是result。ecx是用于存儲乘法的寄存器。L4:movl (%ebx), %ecximull (%edx), %ecxaddl %ecx, %eaxaddl %edi, %ebxaddl $4, %edxcmpl %edx, %esijneL4我怎么感覺前面那個程序,編譯器應該也會自動優化。3.62M = 76/4 = 19;i在edi中,j在ecx中;int transpose(int M, int AMM)
88、60; int i,j; for(i=0; i<M; +i) int *a = &Ai0; int *b = &A0i;
89、; for(j=0; j<i; +j) int t = *a; *a = *b; &
90、#160; *b = t; +a; b += M; 3.63E1(n)在esi中,
91、esi = 3n。E2(n)在ebx中,ebx = 4*E2(n) = 4*(2n-1)。所以E2(n) = 2n-1。3.64這道題比較考驗對知識的拓展應用能力。根據簡單的推測,我們可以知道,imull的兩個對象是 ebx和edx,最后edx移動到了(eax)中,所以ebx和edx一個是 *s1.p,一個是s1.v,并且word_sum的12行的eax是result的prod的地址,也就是result的地址。而eax只在第5行賦值,所以result的地址是在8(%ebp)中的。也就是說,結構體返回值實際上是利用類似參數的變量進行傳入(在8(%ebp)),而傳入的是返回結構體變量的地址。所以:
92、A. 8(%ebp)為result的地址。12(%ebp)為s1.p。16(%ebp)為s1.v。B.棧中的內容如下表,分配的20個字節用黃底展示(每一行為4個字節)yx返回地址保存的ebp(也是當前ebp的指向)ds1.vs1.p&s2 (word_sum的返回值地址)在匯編中,沒懂word_sum 15: ret $4以及diff 12: subl $4, %esp的意義何在。可能是為了清除那個result的返回地址。C.傳遞結構體參數就像正常的傳值。結構體的每一個變量可以看做是單獨的參數進行傳入。D.返回結構體的通用策略:將返回變量的地址看做第一
93、個參數傳入函數。而不是在函數中分配棧空間給一個臨時變量,因為eax確實存不下一個結構體,eax充當返回變量的指針的角色。3.65B取四的倍數的上整數 = 8。8+4+ (B*2)取四的倍數的上整數 = 28。所以B的可選值為8和7。2*A*B取四的上整數為44,所以A*B的可選值為21和22。所以 A=3, B=7。3.66我們用結構體A表示a_struct。首先,根據第11和12行,可以得到 CNT*size(A) = 196。根據13行,知道 ecx + 4*edx + 8為 ap->xap->idx的地址。ecx存儲的是bp(地址)。ap的地址是 bp + 4 + i*size(A)我們知道,ap->x0 的地址是 bp + 4 + i*size(A) + pos(x),pos(x)為結構體A中x的偏移。那么ap->xap->idx
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025至2030年星型L扳手項目投資價值分析報告
- 2025年西安外事學院單招職業技能考試題庫帶答案
- 2024年農產品市場動態試題及答案
- 輔導員考試面對面試的積極準備與技巧分享試題及答案
- 2025年貴州省六盤水市單招職業傾向性測試題庫完整版
- 2025年西安信息職業大學單招綜合素質考試題庫完美版
- 2025年西安工商學院單招職業適應性考試題庫完整
- 福建事業單位考試復習試題及答案
- 2025至2030年搪瓷茶壺項目投資價值分析報告
- 2025至2030年提花CVC剪毛布項目投資價值分析報告
- 鋼鐵是怎樣煉成的讀書分享
- YC/T 145.2-2012煙用香精相對密度的測定
- GB/T 16823.3-2010緊固件扭矩-夾緊力試驗
- 《生活中的會計學》課程教學大綱
- 2023年高考英語試題及答案(江蘇卷)(直接打印Word)無錯版
- 硬筆書法全冊教案共20課時
- 資源環境信息系統(gis)課件
- 股東身份證明
- 本科大學生勞動教育理論與實踐教程第三章 教學課件
- 近代以來廣州外貿產業的發展歷程
- 29《馬說》2022中考語文文言文閱讀復習精選真題匯編(原卷版+解析版)
評論
0/150
提交評論