組合語言中PTR的含義及作用
mov ax,bx ;是把BX寄存器“裡”的值賦予AX,由於二者都是word型,所以沒有必要加“WORD”
mov ax,word ptr [bx];是把記憶體位址等於“BX寄存器的值”的地方所存放的資料,賦予ax。由於只是給出一個記憶體位址,不知道希望賦予ax的,是byte還是word,所以需要用word明確指出!
所以,當兩個運算元的寬度不一樣時,就要用到ptr。
也就是說
*p 用彙編表示就是:dword ptr [p]
*p是取p所指記憶體位址處的值。
int n = 100;<br />int *p = &n;<br />assert(*p == 100);<br />
*p == 100 為true
dword ptr [ebp-xx]是很常見的用法,常常用來擷取局部變數:
隨便寫一段代碼
Base *p = new Derive;<br />Base *d = p;<br />d->f();
反組譯碼代碼如下:
31: Base *d = p;<br />00401469 mov eax,dword ptr [ebp-18h]<br />0040146C mov dword ptr [ebp-1Ch],eax<br />32: d->f();<br />0040146F mov ecx,dword ptr [ebp-1Ch]<br />00401472 mov edx,dword ptr [ecx]//得到虛函數表指標<br />00401474 mov esi,esp<br />00401476 mov ecx,dword ptr [ebp-1Ch]//ecx即為this指標<br />00401479 call dword ptr [edx]//調用第一個虛函數,這裡就是f<br />0040147B cmp esi,esp<br />0040147D call __chkesp (00402750)<br />
再來看看C中的取地址符&如何處理的
27: int n;<br />28: int *pp = &n;<br />0040141D lea eax,[ebp-10h]<br />00401420 mov dword ptr [ebp-14h],eax<br />
lea指令我看到看雪論壇有人如此說:
LEA是INTEL頗為得意的一條指令(雖然大多數程式員並不以為然)。在INTEL OPTIMIZATION REFERFENCE MANUAL中,特別提到了這條指令的好處。
0.LEA指令具有單刻度,執行效率很高。
1.它是CPU地址產生單元參與運算的,而不是ALU參與運算的,所以在流水線上不會與內容相關的算術邏輯指令產生流水相關;
lea 不在 ALU 裡執行,而是在 AGU (address generation unit) 裡執行
ALU 與 AGU 是並行的整數運算單元,將巧妙地 lea 與 add 分開並存執行,很大程度提高輸送量。
2.INTEL指令集中不存在很多RISC機器所具有的三運算元算術運算指令,比如像ARM的"add r0,r1,r2",而LEA指令恰好提供了同樣的功能,以類比“三元算術邏輯指令”。
舉個例子,要計算兩個寄存器的和,但又不想破壞原來的值,那麼可以執行lea ebx ,[eax+edx], 這條指令,執行的就是 ebx = eax + edx 這條加法運算。如果用add指令,則不可能一條指令內完成。
3.在組合語言程式設計中,在需要取得一個變數地址時,使用LEA是很方便的。而MOV指令則常常出錯,因為在微軟MASM彙編文法中,label和variable是不同的。
看來可以多用lea。
總結一下:
取值:mov eax ,[ebp-18h] mov [ebp-1ch],eax 相當於 : int a= b;
取地址:lea ecx , [ebp-18h] mov [ebp - 1ch ] , ecx 相當於 : int *p= &b;
務必牢記。