首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ >

C++两个紧邻局部char变量在栈中的地址差距

2013-01-17 
C++两个相邻局部char变量在栈中的地址差距VS2005上运行以下程序:#include stdafx.h#include iostream#

C++两个相邻局部char变量在栈中的地址差距
VS2005上运行以下程序:
#include "stdafx.h"
#include <iostream>
#include <Windows.h>
using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
char cFirst = '1';
char cSecond = '2';
char cNum[1024*4];
cNum[0] = '3';
printf("%x\n",&cFirst);    //输出地址值:0x0018ff27
printf("%x\n",&cSecond);   //输出地址值:0x0018ff1b
printf("%x\n",&cNum[0]);
printf("%x\n",&cNum[1]);
    Sleep(100000);
return 0;
}
由于cFirst和cSecond是局部变量,所以使用的是栈空间,原本以为&cFirst和&cSecond应该是相邻的,但是调试发现不相邻,相差12个地址空间。

然后查看VS2005生成的汇编与反汇编:
int _tmain(int argc, _TCHAR* argv[])
{
00414100  push        ebp  
00414101  mov         ebp,esp 
00414103  mov         eax,10E4h 
00414108  call        @ILT+585(__chkstk) (41124Eh) 
0041410D  push        ebx  
0041410E  push        esi  
0041410F  push        edi  
00414110  lea         edi,[ebp-10E4h] 
00414116  mov         ecx,439h 
0041411B  mov         eax,0CCCCCCCCh 
00414120  rep stos    dword ptr es:[edi] 
00414122  mov         eax,dword ptr [___security_cookie (419004h)] 
00414127  xor         eax,ebp 
00414129  mov         dword ptr [ebp-4],eax 
char cFirst = '1';
0041412C  mov         byte ptr [ebp-9],31h      //存放cFirst在ebp-9的地址处
char cSecond = '2';
00414130  mov         byte ptr [ebp-15h],32h    //很奇怪,这里为什么不是 mov byte ptr [ebp-0Ah],32h?                        
char cNum[1024*4];
cNum[0] = '3';
00414134  mov         byte ptr [ebp-1020h],33h 
printf("%x\n",&cFirst);
0041413B  mov         esi,esp 
0041413D  lea         eax,[ebp-9] 
00414140  push        eax  
00414141  push        offset string "iNum:" (4176FCh) 
00414146  call        dword ptr [__imp__printf (41A3F0h)] 
0041414C  add         esp,8 
0041414F  cmp         esi,esp 
00414151  call        @ILT+410(__RTC_CheckEsp) (41119Fh) 
printf("%x\n",&cSecond);
00414156  mov         esi,esp 


00414158  lea         eax,[ebp-15h] 
0041415B  push        eax  
0041415C  push        offset string "iNum:" (4176FCh) 
00414161  call        dword ptr [__imp__printf (41A3F0h)] 
00414167  add         esp,8 
0041416A  cmp         esi,esp 
0041416C  call        @ILT+410(__RTC_CheckEsp) (41119Fh) 
printf("%x\n",&cNum[0]);
00414171  mov         esi,esp 
00414173  lea         eax,[ebp-1020h] 
00414179  push        eax  
0041417A  push        offset string "iNum:" (4176FCh) 
0041417F  call        dword ptr [__imp__printf (41A3F0h)] 
00414185  add         esp,8 
00414188  cmp         esi,esp 
0041418A  call        @ILT+410(__RTC_CheckEsp) (41119Fh) 
printf("%x\n",&cNum[1]);
0041418F  lea         eax,[ebp-101Fh] 
00414195  mov         esi,esp 
00414197  push        eax  
00414198  push        offset string "iNum:" (4176FCh) 
0041419D  call        dword ptr [__imp__printf (41A3F0h)] 
004141A3  add         esp,8 
004141A6  cmp         esi,esp 
004141A8  call        @ILT+410(__RTC_CheckEsp) (41119Fh) 
    Sleep(100000);
004141AD  mov         esi,esp 
004141AF  push        186A0h 
004141B4  call        dword ptr [__imp__Sleep@4 (41A240h)] 
004141BA  cmp         esi,esp 
004141BC  call        @ILT+410(__RTC_CheckEsp) (41119Fh) 
return 0;
004141C1  xor         eax,eax 
}

[解决办法]
这个带源代码.


; Listing generated by Microsoft (R) Optimizing Compiler Version 16.00.30319.01 



TITLED:\cc\t.cc

.686P

.XMM

include listing.inc

.modelflat





PUBLIC??_C@_03OJFKKOIN@?$CFx?6?$AA@; `string'

EXTRN_printf:PROC

;COMDAT ??_C@_03OJFKKOIN@?$CFx?6?$AA@

CONSTSEGMENT

??_C@_03OJFKKOIN@?$CFx?6?$AA@ DB '%x', 0aH, 00H; `string'



CONSTENDS

PUBLIC_main

EXTRN__chkstk:PROC

; Function compile flags: /Ogtpy

; File d:\cc\t.cc

;COMDAT _main

_TEXTSEGMENT

_cSecond$ = -4098; size = 1

_cFirst$ = -4097; size = 1

_cNum$ = -4096; size = 4096

_mainPROC; COMDAT



; 5    : {



moveax, 4100; 00001004H

call__chkstk



; 6    :  char cFirst = '1';

; 7    :  char cSecond = '2';

; 8    :  char cNum[1024*4];

; 9    :  cNum[0] = '3';

; 10   :  printf("%x\n",&cFirst);



leaeax, DWORD PTR _cFirst$[esp+4100]

pusheax

pushOFFSET ??_C@_03OJFKKOIN@?$CFx?6?$AA@

movBYTE PTR _cFirst$[esp+4108], 49; 00000031H

movBYTE PTR _cSecond$[esp+4108], 50; 00000032H

movBYTE PTR _cNum$[esp+4108], 51; 00000033H

call_printf



; 11   :  printf("%x\n",&cSecond);



leaecx, DWORD PTR _cSecond$[esp+4108]

pushecx

pushOFFSET ??_C@_03OJFKKOIN@?$CFx?6?$AA@

call_printf



; 12   :  printf("%x\n",&cNum[0]);



leaedx, DWORD PTR _cNum$[esp+4116]

pushedx

pushOFFSET ??_C@_03OJFKKOIN@?$CFx?6?$AA@

call_printf



; 13   :  printf("%x\n",&cNum[1]);



leaeax, DWORD PTR _cNum$[esp+4125]

pusheax

pushOFFSET ??_C@_03OJFKKOIN@?$CFx?6?$AA@

call_printf



; 14   :  return 0;



xoreax, eax



; 15   : }



addesp, 4132; 00001024H

ret0

_mainENDP

_TEXTENDS

END


[解决办法]
引用:
引用:不一定相邻。
嗯,基本上可以肯定这个是又编译器决定的,只是想弄明白自己的VS2005为什么会相差了12地址空间?有没有其他同学用VS2005试过?

debug版嘛 安插一些调试用的数据不是很正常么。
[解决办法]
另外,还有安全方面的考虑吧,编译器会在栈中插入一些 Cookie。

热点排行