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。