如下小結純屬小菜自學過程產生的dump,大神請飄過!c++
彙編是一門龐大複雜的學問,在計算機的世界裏差很少無所不入。不少編程領域都會或多或少跟彙編打交道。本人不是科班出身的程序員,因此不少基礎都爲零,學歷也很低。所以學習彙編的難度可想而知。不過仍是憑本身的耐力,掌握了少量的知識。下面作個小小的總結,分享給和我同樣想入門彙編的朋友們。程序員
1.參數直接傳值和傳入數值變量的區別編程
void SetX(int x) { x = 6; } int _tmain(int argc, _TCHAR* argv[]) { SetX(7);//1.直接傳數值 int x = 7; SetX(x);//2.傳一個有初始值的變量 return 0; }
這兩種狀況運行的結果沒有任何區別,可是彙編代碼卻有些細微的區別:緩存
第一種狀況:ide
push 7 call SetX (01011E5h) //1.直接傳值 add esp,4 //棧指針向下移動
第二種狀況多了一個將及時數緩存於內存x的步驟:函數
mov dword ptr [x],7 //首先將及時數7傳入雙字型內存地址爲x的內存中 mov eax,dword ptr [x] //而後再將x裏的值傳到eax寄存器裏 push eax //開始壓入參數值 call SetX (01011E5h) add esp,4 //棧指針向下移動,清除變量 xor eax,eax //清空eax的值
2.有返回值與沒返回值的區別
在c++或其餘高級語言,咱們能夠一眼看出返回值和返回類型。可是彙編裏貌似有些亂。在上面的例子裏,Call完SetX以後,後面就緊跟着開始清除變量值。這個還不能說明有沒有返回值。再來看一個例子就能明顯分辨有沒有返回值了。學習
int SetX(int x) { x = 6; return x; } int _tmain(int argc, _TCHAR* argv[]) { SetX(7);//1.有返回值,可是沒有引用 int x=SetX(7);//2.有返回值,而且引用了 return 0; }
這個例子裏,第一個函數調用沒有賦值的動做,且看對應的彙編代碼:編碼
push 7 call SetX (012811EAh) add esp,4
這個狀況看起來就若是自己就不帶返回值的狀況。看起來無法這樣分辨了,可是其實若是是這樣調用,不就個沒帶返回值效果是同樣的了。判別有沒有返回值已經沒有意義了。spa
push 7 call SetX (012811EAh) add esp,4 mov dword ptr [x],eax xor eax,eax
上面的第二種狀況,則明顯多了一個mov指令。在調用完函數以後,立馬來個mov,顯然是返回了一個值存於eax,須要當即保存在地址x的內存裏。很明顯是帶返回值的。指針
3.參數傳遞中值傳遞和引用傳遞的區別
void SetX(int x) { x++; } void SetY(int &y) { y++; } int _tmain(int argc, _TCHAR* argv[]) { int x = 0; int y = 0; SetX(x);//1.值傳遞,x的值不會變 SetY(y);//2.引用傳遞,y的值會產生變化 return 0; }
在彙編碼裏,更容易看出兩個函數的不一樣
對於第一個函數:
mov eax,dword ptr [x] push eax call SetX (01611F4h) add esp,4
明顯是將地址爲x的內存裏的值傳入eax,再經由eax傳給函數。而對於第二個函數,先是用lea取一塊有效的內存區域用於存儲計算過程當中生成的結果。而後將這個剛剛創建的內存區域的地址傳給eax,以即可以直接操做y區域的內存。
lea eax,[y] push eax call SetY (01611EFh) add esp,4 xor eax,eax
這幾個小細節在彙編,甚至反彙編的時候很是有使用價值。