那麼有了上述三方面的基礎,我們就可以來逐一解讀那段「傳奇」的彙編**了。
初始化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的優化,我初次看到反彙編 時,還真汗了一把。不過定下心來細細品位還是可以看懂的,儘管正如原書所說,連語...