亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

  免費注冊 查看新帖 |

Chinaunix

  平臺 論壇 博客 文庫
最近訪問板塊 發(fā)新帖
查看: 6949 | 回復(fù): 7
打印 上一主題 下一主題

[C] gcc中關(guān)于函數(shù)局部變量,棧地址問題 [復(fù)制鏈接]

論壇徽章:
1
子鼠
日期:2013-08-23 16:36:37
跳轉(zhuǎn)到指定樓層
1 [收藏(0)] [報告]
發(fā)表于 2013-08-21 13:37 |只看該作者 |倒序瀏覽
本帖最后由 float001 于 2013-08-21 15:09 編輯

按照gcc中正常情況來說,局部變量緊挨著ebp向低地址排列(不考慮對齊補齊問題),如下代碼:

  1. int func(int a, int b)
  2. {
  3.     int i=0, j=0, k=0;
  4.    
  5.     return 0;
  6. }
復(fù)制代碼
對應(yīng)的匯編代碼如下:
  1.          
  2.         push   %ebp
  3.            mov    %esp,%ebp
  4.            sub    $0x10,%esp
  5.         movl   $0x0,-0x4(%ebp)    // i=0
  6.         movl   $0x0,-0x8(%ebp)    // j=0
  7.         movl   $0x0,-0xc(%ebp)    // k=0
  8.         mov    $0x0,%eax
  9.         leave  
  10.         ret   
復(fù)制代碼
i的地址是 ebp-4 , j的地址是ebp-8  , k的地址是 ebp-12

但是在函數(shù)中增加printf打印 ,則i,j,k的地址減少了8字節(jié),如下代碼:

  1. int func(int a, int b)
  2. {
  3.     int i=0, j=0, k=0;

  4.     printf("123\n");
  5.    
  6.     return 0;
  7. }
復(fù)制代碼
對應(yīng)的匯編代碼如下:

  1. push   %ebp
  2. mov    %esp,%ebp
  3. sub    $0x28,%esp
  4. movl   $0x0,-0xc(%ebp)    // i=0
  5. movl   $0x0,-0x10(%ebp)  // j=0
  6. movl   $0x0,-0x14(%ebp)  // k=0
  7. movl   $0x8048510,(%esp)
  8. call   0x8048318 <puts@plt>
  9. mov    $0x0,%eax
  10. leave  
  11. ret  
復(fù)制代碼
此時i的地址是 ebp-12 , j的地址是ebp-16  , k的地址是 ebp-20

不知道是什么原因,與printf有關(guān)么 ,請各位幫忙解答一下,謝謝。


VC++6.0中沒有出現(xiàn)這種情況,應(yīng)該是gcc編譯器的問題, 誰能解答一下呢??????

論壇徽章:
5
雙魚座
日期:2013-11-26 17:56:26獅子座
日期:2013-11-29 15:41:32處女座
日期:2014-02-21 11:59:07技術(shù)圖書徽章
日期:2014-03-06 15:33:53技術(shù)圖書徽章
日期:2014-03-06 15:39:30
2 [報告]
發(fā)表于 2013-08-21 13:59 |只看該作者
誒。。這個能把那段地址的值打印下看看是什么嗎?

論壇徽章:
1
子鼠
日期:2013-08-23 16:36:37
3 [報告]
發(fā)表于 2013-08-21 14:57 |只看該作者
回復(fù) 2# bottles


    輸出的 ebp - 4 = 0xB779F080
             ebp - 8 = 0x8049FF4

感覺 0x8049FF4 像是一個地址 所以找到了以下代碼:
  1. Disassembly of section .got.plt:

  2. 08049ff4 <_GLOBAL_OFFSET_TABLE_>:
  3. 8049ff4:        20 9f 04 08 00 00            and    %bl,0x804(%edi)
  4. 8049ffa:        00 00                        add    %al,(%eax)
  5. 8049ffc:        00 00                        add    %al,(%eax)
  6. 8049ffe:        00 00                        add    %al,(%eax)
  7. 804a000:        26 83 04 08 36               addl   $0x36,%es:(%eax,%ecx,1)
  8. 804a005:        83 04 08 46                  addl   $0x46,(%eax,%ecx,1)
  9. 804a009:        83 04 08 56                  addl   $0x56,(%eax,%ecx,1)
  10. 804a00d:        83                           .byte 0x83
  11. 804a00e:        04 08                        add    $0x8,%al
復(fù)制代碼
不知道這8個字節(jié)存放這什么東西?????

論壇徽章:
5
雙魚座
日期:2013-11-26 17:56:26獅子座
日期:2013-11-29 15:41:32處女座
日期:2014-02-21 11:59:07技術(shù)圖書徽章
日期:2014-03-06 15:33:53技術(shù)圖書徽章
日期:2014-03-06 15:39:30
4 [報告]
發(fā)表于 2013-08-21 15:42 |只看該作者
我用gcc編譯了下,好像木有這個問題。我用gcc version 4.3.1 (GCC) 。會不會是對齊之類原因?要不把printf換成一個調(diào)用空的函數(shù),沒有參數(shù),也沒有返回值的那種試試?

論壇徽章:
17
處女座
日期:2013-08-27 09:59:352015亞冠之柏太陽神
日期:2015-07-30 10:16:402015亞冠之薩濟拖拉機
日期:2015-07-29 18:58:182015年亞洲杯之巴勒斯坦
日期:2015-03-06 17:38:17摩羯座
日期:2014-12-11 21:31:34戌狗
日期:2014-07-20 20:57:32子鼠
日期:2014-05-15 16:25:21亥豬
日期:2014-02-11 17:32:05丑牛
日期:2014-01-20 15:45:51丑牛
日期:2013-10-22 11:12:56雙子座
日期:2013-10-18 16:28:17白羊座
日期:2013-10-18 10:50:45
5 [報告]
發(fā)表于 2013-08-21 16:13 |只看該作者
回復(fù) 1# float001


    關(guān)健的應(yīng)該是movl   $0x8048510,(%esp),為了給printf傳參所以多出的空間是為printf做準備,地址變化和$0x8048510的值有關(guān)。其實不光不同的編譯器有差異,不同版本的gcc生成的代碼在這方面應(yīng)該也有差異,深究這個可就麻煩了

論壇徽章:
1
子鼠
日期:2013-08-23 16:36:37
6 [報告]
發(fā)表于 2013-08-21 16:43 |只看該作者
本帖最后由 float001 于 2013-08-21 16:54 編輯

    這個問題很糾結(jié),還需要查看gcc的更多的說明,剛才共64位服務(wù)器上看了下,沒有8個字節(jié)的分隔(gcc 版本 4.1.2 ),如下匯編
  1. push   %rbp
  2. mov    %rsp,%rbp
  3. sub    $0x20,%rsp
  4. mov    %edi,-0x14(%rbp)
  5. mov    %esi,-0x18(%rbp)
  6. mov    %edx,-0x1c(%rbp)
  7. mov    %ecx,-0x20(%rbp)
  8. movl   $0x0,-0xc(%rbp)
  9. movl   $0x0,-0x8(%rbp)
  10. movl   $0x1,-0x4(%rbp)
  11. mov    -0x14(%rbp),%eax
  12. mov    %eax,-0xc(%rbp)
  13. mov    $0x400618,%edi
  14. callq  0x400398 <puts@plt>
  15. mov    -0xc(%rbp),%eax
  16. leaveq
  17. retq   
復(fù)制代碼
但是64為的函數(shù)參數(shù)和局部變量在棧中的存儲方式又不同于32位 ,追究的越深發(fā)現(xiàn)越來越多的東西難以理解,我得繼續(xù)看書去解決這些問題了,謝謝大家的回復(fù)
出現(xiàn)8字節(jié)空間的gcc版本:gcc version 4.4.3

論壇徽章:
0
7 [報告]
發(fā)表于 2013-08-21 20:18 |只看該作者
棧幀的分配情況完全由編譯器自主決定,甚至ebp也可能不被用于定位局部變量(gcc參考--omit-framepointer),變量是由低地址到高地址排列等等,不一而足,甚至是包含在同一次編譯也存在不同之處。

論壇徽章:
0
8 [報告]
發(fā)表于 2013-08-22 11:20 |只看該作者
具體原因估計要翻文檔了,不過有多分配較多的棧空間原因: GCC 堅持Linux IA-32 的一個慣例是確保每個棧幀的所有長度都是16字節(jié)的整數(shù)倍, 包括調(diào)用時的 push %ebp 和 返回值共8個字節(jié)。 調(diào)用printf的函數(shù), esp 減去了 0x28, 加上壓棧的ebp和call printf前壓棧的返回地址, 總共48個字節(jié)。
您需要登錄后才可以回帖 登錄 | 注冊

本版積分規(guī)則 發(fā)表回復(fù)

  

北京盛拓優(yōu)訊信息技術(shù)有限公司. 版權(quán)所有 京ICP備16024965號-6 北京市公安局海淀分局網(wǎng)監(jiān)中心備案編號:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年舉報專區(qū)
中國互聯(lián)網(wǎng)協(xié)會會員  聯(lián)系我們:huangweiwei@itpub.net
感謝所有關(guān)心和支持過ChinaUnix的朋友們 轉(zhuǎn)載本站內(nèi)容請注明原作者名及出處

清除 Cookies - ChinaUnix - Archiver - WAP - TOP