天天看點

3.61家庭作業與20135316合作

3.61

題中代碼在循環時會産生6個臨時的變量,故共需要六個寄存器在存放資料,但是由于處理器的六個寄存器中,%esp和%ebp不能用于存放臨時資料,而且另外一個寄存器還必須用來儲存乘法指令的結果。是以必須将循環中的值的數量減少到5個。

當沒有足夠多的寄存器來儲存臨時資料時,編譯器必須把一些局部變量放到存儲器中

由于在每次循環中代碼從存儲器中取出N的值進行檢查循環是否終止,是以我覺得可以去掉每次的減産環節,直接用立即數來控制循環結束。代碼如下:

int var_prod_ele(int n, int A[n][n], int B[n][n], int i, int k) {     int j = n-1;     int result = 0;     for(; j!=-1; --j)         result += A[i][j] * B[j][k];     return result; }

但是這樣得到的結果仍然會使用到存儲器。

按下面的代碼,循環裡面貌似就沒有用到存儲器。

但是用到了一個常量4,就是增加a的時候,會add 4。

隻需要result,a,e,b,4n這五個變量。

思路如下,先初始化A數組的行和B數組的列,記住他們的位址,同時記住A數組那一行最後一個元素的位址,之後循環每次用變換的A數組行位址和A數組最後一個元素位址進行比較來控制循環的結束。若沒有到達A數組行的最後一個元素,則A數組依次向後移動,B數組依次向下移動,直到最後達到最後一個元素。代碼如下:

int var_prod_ele(int n, int A[n][n], int B[n][n], int i, int k) {     int result = 0;     int *a = &A[i][0];     int *b = &B[0][k];     int *e = &A[i][n];     for(;a!=e;)     {         result += *a * *b;         b+=n;         a++;   }     return result; }

3.63

E1和E2是用#define聲明的宏表達式,用參數表示A矩陣的次元。

int sum_col(int n, int A[E1(n)][E2(n)],int j) {

       int i;

       int result = 0;

       for (i = 0; i < E1(n); i++)

           result += A[i][j];

       return result;

   }

1.分析通過資訊交換所得的觀察。

最常用于協定逆向工程,涉及使用總線分析器和資料包嗅探器。在接入計算機總線或網絡的連接配接,并成功截取通信資料後,可以對總線或網絡行為進行分析,以制造出擁有相同行為的通信實作。此法特别适用于裝置驅動程式的逆向工程。有時,由硬體制造商特意所做的工具,如JTAG端口或各種調試工具,也有助于嵌入式系統的逆向工程。對于微軟的Windows系統,受歡迎的底層調試器有SoftICE。

2.反彙編,即使用反彙編器,把程式的原始機器碼,翻譯成較便于閱讀了解的彙編代碼。這适用于任何的計算機程式,對不熟悉機器碼的人特别有用。流行的相關工具有OllyDebug和IDA。

3.反編譯,即使用反編譯器,嘗試從程式的機器碼或位元組碼,重制進階語言形式的源代碼。

E1(n)在esi中,esi = 3n。

E2(n)在ebx中,ebx = 4*E2(n) = 4*(2n-1)。

是以E2(n) = 2n-1。