C反彙編例項(詳細註解版)(二)

2021-05-23 17:07:45 字數 3186 閱讀 8190

那麼有了上述三方面的基礎,我們就可以來逐一解讀那段「傳奇」的彙編**了。

初始化i

00411a3e mov dword ptr [i],0

跳轉至條件判斷

00411a45 jmp myfunction+30h (411a50h)

迴圈表示式,對i每輪加1

00411a47 mov eax,dword ptr [i]

00411a4a add eax,1

00411a4d mov dword ptr [i],eax

條件判斷,若不滿足i < 3,則跳出迴圈

00411a50 cmp dword ptr [i],3

00411a54 jge myfunction+0aeh (411aceh)

j 的迴圈體結束

跳到j的expr

00411ac7 jmp myfunction+3fh (411a5fh)

} i的迴圈體結束

跳至i的expr

00411ac9 jmp myfunction+27h (411a47h)

以下我們再詳細分析下上面挖下來的陣列賦值的**。為了方便起見,再把c語句貼如下:

c[i][j] = a[i][0] * b[0][j] + a[i][1] * b[1][j] + a[i][2] * b[2][j]; ;

還記得前面所說的彙編訪問二維陣列的方式麼?忘記的話,再回過頭去看一下哈 ;

第i行,每行3個佔4位元組的int型別,所以乘以i×12(0ch),表示行偏移

00411a6e mov eax,dword ptr [i]

00411a71 imul eax,eax,0ch

;往暫存器送入一些變數

00411a74 mov ecx,dword ptr [a]

00411a77 mov edx,dword ptr [j]

00411a7a mov esi,dword ptr [b]

00411a7d mov eax,dword ptr [ecx+eax]

; ecx

已經含有a陣列的起始位址,這句相當於往

; eax

存入基址+i行偏移這個位址開始的int類 ;

型值,也就是a[i][0]

00411a80 imul eax,dword ptr [esi+edx*4]

;這句比較好理解,esi是b陣列起始位址

; edx * 4

表示列偏移,相當於eax * b[0][j], ;

也就是eax = a[i][0] * b[0][j]

; 同理,ecx獲得i行偏移量

00411a84 mov ecx,dword ptr [i]

00411a87 imul ecx,ecx,0ch

00411a8a mov edx,dword ptr [a]

; edx

儲存的a陣列基位址

00411a8d mov esi,dword ptr [j]

; esi = j

00411a90 mov edi,dword ptr [b]

; edi

儲存的b陣列基位址

00411a93 mov ecx,dword ptr [edx+ecx+4]

; edx

基址= a

; ecx

行偏移= 第i行

; 4

列偏移 = 第1列

; 綜上,ecx = a[i][1]

; edi b

的基址;esi = j,第j列;0ch,行偏移量,相當於是第1行 ;

綜上,ecx = ecx * b[1][j],即ecx = a[i][1] * b[1][j]

00411a97 imul ecx,dword ptr [edi+esi*4+0ch]

; 把第一項a[i][0] * b[0][j]和第二項相加存入eax,從這也可以看出 ;

其實eax就是用來儲存最後結果的,此時eax = a[i][0] * b[0][j] + a[i][1] * b[1][j]

00411a9c add eax,ecx

; 以下這段不用解釋了吧?依樣花葫蘆,到411ab6為止

; eax = a[i][0] * b[0][j] + a[i][1] * b[1][j] + a[i][2] * b[2][j]

00411a9e mov edx,dword ptr [i]

00411aa1 imul edx,edx,0ch

00411aa4 mov ecx,dword ptr [a]

00411aa7 mov esi,dword ptr [j]

00411aaa mov edi,dword ptr [b]

00411aad mov edx,dword ptr [ecx+edx+8]

00411ab1 imul edx,dword ptr [edi+esi*4+18h]

00411ab6 add eax,edx

; 首先是老規矩,通過ecx與edx找到了c[i][j]的記憶體位址,411ac4這句就是把 ;

前邊eax中的計算結果寫入到記憶體中代表c[i][j]這個元素的位置

00411ab8 mov ecx,dword ptr [i]

00411abb imul ecx,ecx,0ch

00411abe add ecx,dword ptr [c]

00411ac1 mov edx,dword ptr [j]

00411ac4 mov dword ptr [ecx+edx*4],eax

這樣就完成了a中第i行每個元素分別與b中第j列的每個元素的乘積儲存到c的第i行第j列元素中,這麼乙個操作,確實比較複雜。如果看不大懂,不要緊,回過頭多看幾遍,一定會明白的,如果說有些話我的表述不妥當,也請大俠指出,以免誤人子弟j

我的一些朋友問我,研究彙編,尤其研究c反彙編,到底有什麼用處?我的理解是,除非你是底層開發人員,否則我們的目的並非是學習如何運用彙編寫複雜的演算法程式,而是將它應用在排錯、效能優化等方面,如果你能看懂一些彙編**,那麼當你的客戶程式崩潰時,你開啟偵錯程式,就可以先簡要分析出出錯程式**的大致意思,這對你的除錯是相當有幫助的。而如果彙編懂得較深的話(我只是皮毛而已),那麼就可以對c目標程式進行有目的的修改以提高程式效能,因為有時候即便是release模式下的exe檔案,仍然有可以優化之處,只是這時一定要謹慎再謹慎,萬一撿了芝麻丟了西瓜就太不划算了。當然了還有另外某些用途,呵呵,比較**,就不點破了……總之希望本文能對大家有所幫助!

C反彙編例項(詳細註解版)(一)

呵,好久沒寫 csdn 文章了,來湊個熱鬧。最近我閱讀了楚狂人 wowocock 寫的 天書夜讀 試讀本,對 c反彙編感觸頗深,書中有一例演算法反彙編,其對彙編的閱讀確實富有挑戰,而該書中也未詳解,在此,我謹將此例詳細分析如下,幫助大家更好理解 c反彙編 若有任何錯誤,請大家批評指正!該例的要求是求...

C反彙編例項(詳細註解版)(三)

上次我分析了一下,debug 模式下反彙編後的演算法部分 天才的您可能覺得不算糟,想再搞點花樣,那麼本文就能滿足你的需求。天書夜讀上其實還貼出來了 release 模式下的 它經過 vc編譯器 o2的優化,我初次看到反彙編 時,還真汗了一把。不過定下心來細細品位還是可以看懂的,儘管正如原書所說,連語...

C反彙編例項(詳細註解版)(三)

上次我分析了一下,debug 模式下反彙編後的演算法部分 天才的您可能覺得不算糟,想再搞點花樣,那麼本文就能滿足你的需求。天書夜讀上其實還貼出來了 release 模式下的 它經過 vc編譯器 o2的優化,我初次看到反彙編 時,還真汗了一把。不過定下心來細細品位還是可以看懂的,儘管正如原書所說,連語...