2014-10-17 97 views
0

我是一名新的學習者,我不會用英語寫得很好。我從很多來源讀到,爲了在程序中訪問局部變量,首先使用[ebp-4]訪問本地變量。我讓這個程序顯示EAX,並且只有一個數據(string)在本地。 [ebp-4]發生了什麼不起作用。我改成了[ebp-8],它工作。爲什麼這樣?通過EBP訪問本地字符串

 mov  eax,0x0ffffc345 
     push eax 
     call Disp_EAX 
     call exit 

Disp_EAX: 
     push ebp 
     mov  ebp,esp 
     sub  esp,12 ;for string to display EAX 
     cld 
     lea  edi,[ebp-8] ;why can't [ebp-4]? 
     mov  esi,8 
     mov  edx,[ebp+8] 
     mov  eax,0 
extract: 
     shld eax,edx,4 
     add  al,0x30 
     cmp  al,0x39 
     jle  continue 
     add  eax,7 
continue: 
     stosb 
     dec  esi 
     cmp  esi,0 
     je  done 
     rol  edx,4 
     xor  al,al 
     jmp  extract 
done: 
     mov  eax,0 
     stosb 
     lea  esi,[ebp-8] 
     cinvoke printf,esi 
     add  esp,12 
     mov  esp,ebp 
     pop  ebp 
     ret 

希望你能幫助我理解。

此外:如果我使用[ebp-4],我的程序會持續循環但正確顯示。我很困惑。

回答

0

堆棧在x86上向下增長。如果您設置了標準堆棧幀,則ebp指向本地變量末尾的一個,其起始地址爲當前值esp。因此,您有ebp - esp字節的當地人。

您使用sub esp, 12分配12個字節,因此該塊的地址爲ebp-12。在循環中使用該塊的8個字節。如果您從ebp-8開始,您正在編寫ebp-8ebp-1,並且一切正常,那就是您的當地居民。如果使用ebp-4,則表示從ebp-4ebp+3這是不好的,因爲最後4個字節不在爲塊分配給本地變量。您將覆蓋保存在push ebp的堆棧中的ebp,這將導致無法預料的問題。

+0

謝謝你的好解釋Jester。所以這意味着訪問本地數據並不總是從[ebp-4]開始。從一些網絡資料看,這非常令人困惑。那就是這樣說。或者只是讓我完全錯誤。 – kent 2014-10-17 10:25:50

+0

本地數據以'ebp'結尾。第一個本地,如果它是一個4字節的整數,在'ebp-4'處,但第二個在'ebp-8'處,隨着堆棧的增長而下降。當地人佔據一個以'ebp'結尾的內存區域,從'esp'開始,這是'ebp'的一些負偏移量(所有本地人的大小)。 – Jester 2014-10-17 10:44:24

+0

是的。我發現大多數參考都假設本地數據是4字節的。非常罕見我發現ee我發現使用一些更大的字符串的例子。我認爲這是造成混亂的原因。 4字節就像堆棧實例的事實標準一樣。再次感謝 – kent 2014-10-17 11:19:50