读书人

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

发布时间: 2013-01-17 10:28:54 作者: rapoo

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。

读书人网 >C++

热点推荐