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