Source Code
#include <stdio.h>
#define define_string "Hello World!"
#define define_same_string "Hello World!"
#define define_another_string "Defined String!"
const char char_array[] = "Hello World!"; //.rdata
const char const_char_array[] = "Hello World!"; //.rdata
static const char static_const_char_array[] = "Hello World!"; //.rdata
static const char* static_const_char_pointer = "Hello World!"; //.data
static const char* const static_const_char_pointer_const = "Hello World!"; //.rdata
int main()
{
#define PRINT_STR(v) printf("%s@%p: %s\n", #v, v, v)
const char local_char_array[] = define_string;
PRINT_STR(local_char_array);
PRINT_STR(char_array);
PRINT_STR(const_char_array);
PRINT_STR(static_const_char_array);
PRINT_STR(static_const_char_pointer);
PRINT_STR(static_const_char_pointer_const);
static_const_char_pointer = "Fang";
PRINT_STR(static_const_char_pointer);
printf("\n");
PRINT_STR(define_string);
PRINT_STR(define_same_string);
PRINT_STR(define_another_string);
getchar();
return 0;
}
Program Segmentation
.textbss 0000000000401000 0000000000411000 R W X . L para 0001 public CODE 32 0000 0000 0004 FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF
.text 0000000000411000 0000000000416000 R . X . L para 0002 public CODE 32 0000 0000 0004 FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF
.rdata 0000000000416000 0000000000419000 R . . . L para 0003 public DATA 32 0000 0000 0004 FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF
.data 0000000000419000 000000000041A000 R W . . L para 0004 public DATA 32 0000 0000 0004 FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF
.idata 000000000041A000 000000000041A1BC R . . . L para 0005 public DATA 32 0000 0000 0004 FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF
.00cfg 000000000041B000 000000000041C000 R . . . L para 0006 public DATA 32 0000 0000 0004 FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF
Partial assembly code(compiled by MS2015 on debug):
.text:00414D96 __is_c_termination_complete endp
.text:00414D96
.text:00414D96 ; ---------------------------------------------------------------------------
.text:00414D97 align 10h
.text:00414DA0
.text:00414DA0 ; =============== S U B R O U T I N E =======================================
.text:00414DA0
.text:00414DA0 ; Attributes: bp-based frame
.text:00414DA0
.text:00414DA0 ; int __cdecl main()
.text:00414DA0 _main proc near ; CODE XREF: j__main�j
.text:00414DA0
.text:00414DA0 var_DC = byte ptr -0DCh
.text:00414DA0 local_char_array= byte ptr -18h
.text:00414DA0 var_4 = dword ptr -4
.text:00414DA0
.text:00414DA0 push ebp
.text:00414DA1 mov ebp, esp
.text:00414DA3 sub esp, 0DCh
.text:00414DA9 push ebx
.text:00414DAA push esi
.text:00414DAB push edi
.text:00414DAC lea edi, [ebp+var_DC]
.text:00414DB2 mov ecx, 37h
.text:00414DB7 mov eax, 0CCCCCCCCh
.text:00414DBC rep stosd
.text:00414DBE mov eax, ___security_cookie
.text:00414DC3 xor eax, ebp
.text:00414DC5 mov [ebp+var_4], eax
.text:00414DC8 mov eax, dword ptr ds:aHell ; "Hell"
.text:00414DCD mov dword ptr [ebp+local_char_array], eax
.text:00414DD0 mov ecx, ds:dword_416B74
.text:00414DD6 mov dword ptr [ebp+local_char_array+4], ecx
.text:00414DD9 mov edx, ds:dword_416B78
.text:00414DDF mov dword ptr [ebp+local_char_array+8], edx
.text:00414DE2 mov al, ds:byte_416B7C
.text:00414DE7 mov [ebp+local_char_array+0Ch], al
.text:00414DEA lea eax, [ebp+local_char_array]
.text:00414DED push eax
.text:00414DEE lea ecx, [ebp+local_char_array]
.text:00414DF1 push ecx
.text:00414DF2 push offset aLocal_char_arr ; "local_char_array"
.text:00414DF7 push offset aS@PS ; "%s@%p: %s\n"
.text:00414DFC call j__printf
.text:00414E01 add esp, 10h
.text:00414E04 push offset char_array ; "Hello World!"
.text:00414E09 push offset char_array ; "Hello World!"
.text:00414E0E push offset aChar_array ; "char_array"
.text:00414E13 push offset aS@PS ; "%s@%p: %s\n"
.text:00414E18 call j__printf
.text:00414E1D add esp, 10h
.text:00414E20 push offset const_char_array ; "Hello World!"
.text:00414E25 push offset const_char_array ; "Hello World!"
.text:00414E2A push offset aConst_char_arr ; "const_char_array"
.text:00414E2F push offset aS@PS ; "%s@%p: %s\n"
.text:00414E34 call j__printf
.text:00414E39 add esp, 10h
.text:00414E3C push offset static_const_char_array ; "Hello World!"
.text:00414E41 push offset static_const_char_array ; "Hello World!"
.text:00414E46 push offset aStatic_const_c ; "static_const_char_array"
.text:00414E4B push offset aS@PS ; "%s@%p: %s\n"
.text:00414E50 call j__printf
.text:00414E55 add esp, 10h
.text:00414E58 mov eax, static_const_char_pointer
.text:00414E5D push eax
.text:00414E5E mov ecx, static_const_char_pointer
.text:00414E64 push ecx
.text:00414E65 push offset aStatic_const_2 ; "static_const_char_pointer"
.text:00414E6A push offset aS@PS ; "%s@%p: %s\n"
.text:00414E6F call j__printf
.text:00414E74 add esp, 10h
.text:00414E77 mov eax, ds:static_const_char_pointer_const
.text:00414E7C push eax
.text:00414E7D mov ecx, ds:static_const_char_pointer_const
.text:00414E83 push ecx
.text:00414E84 push offset aStatic_const_0 ; "static_const_char_pointer_const"
.text:00414E89 push offset aS@PS ; "%s@%p: %s\n"
.text:00414E8E call j__printf
.text:00414E93 add esp, 10h
.text:00414E96 mov static_const_char_pointer, offset aFang ; "Fang"
.text:00414EA0 mov eax, static_const_char_pointer
.text:00414EA5 push eax
.text:00414EA6 mov ecx, static_const_char_pointer
.text:00414EAC push ecx
.text:00414EAD push offset aStatic_const_2 ; "static_const_char_pointer"
.text:00414EB2 push offset aS@PS ; "%s@%p: %s\n"
.text:00414EB7 call j__printf
.text:00414EBC add esp, 10h
.text:00414EBF push offset asc_4171F8 ; "\n"
.text:00414EC4 call j__printf
.text:00414EC9 add esp, 4
.text:00414ECC push offset aHell ; "Hell"
.text:00414ED1 push offset aHell ; "Hell"
.text:00414ED6 push offset aDefine_string ; "define_string"
.text:00414EDB push offset aS@PS ; "%s@%p: %s\n"
.text:00414EE0 call j__printf
.text:00414EE5 add esp, 10h
.text:00414EE8 push offset aHell ; "Hell"
.text:00414EED push offset aHell ; "Hell"
.text:00414EF2 push offset aDefine_same_st ; "define_same_string"
.text:00414EF7 push offset aS@PS ; "%s@%p: %s\n"
.text:00414EFC call j__printf
.text:00414F01 add esp, 10h
.text:00414F04 push offset aDefinedString ; "Defined String!"
.text:00414F09 push offset aDefinedString ; "Defined String!"
.text:00414F0E push offset aDefine_another ; "define_another_string"
.text:00414F13 push offset aS@PS ; "%s@%p: %s\n"
.text:00414F18 call j__printf
.text:00414F1D add esp, 10h
.text:00414F20 mov esi, esp
.text:00414F22 call ds:__imp__getchar
.text:00414F28 cmp esi, esp
.text:00414F2A call j___RTC_CheckEsp
.text:00414F2F xor eax, eax
.text:00414F31 push edx
.text:00414F32 mov ecx, ebp ; frame
.text:00414F34 push eax
.text:00414F35 lea edx, v ; v
.text:00414F3B call j_@_RTC_CheckStackVars@8 ; _RTC_CheckStackVars(x,x)
.text:00414F40 pop eax
.text:00414F41 pop edx
.text:00414F42 pop edi
.text:00414F43 pop esi
.text:00414F44 pop ebx
.text:00414F45 mov ecx, [ebp+var_4]
.text:00414F48 xor ecx, ebp ; cookie
.text:00414F4A call j_@__security_check_cookie@4 ; __security_check_cookie(x)
.text:00414F4F add esp, 0DCh
.text:00414F55 cmp ebp, esp
.text:00414F57 call j___RTC_CheckEsp
.text:00414F5C mov esp, ebp
.text:00414F5E pop ebp
.text:00414F5F retn
.text:00414F5F ; ---------------------------------------------------------------------------
.text:00414F60 ; _RTC_framedesc v
.text:00414F60 v _RTC_framedesc <1, offset dword_414F68>
.text:00414F60 ; DATA XREF: _main+195�o
.text:00414F68 dword_414F68 dd 0FFFFFFE8h, 0Dh ; DATA XREF: _main:v�o
.text:00414F70 dd offset aLocal_char_a_0 ; "local_char_array"
.text:00414F74 aLocal_char_a_0 db 'local_char_array',0 ; DATA XREF: _main+1D0�o
.text:00414F74 _main endp
.text:00414F74
.text:00414F85 db 0D0Ch dup(0CCh)
.text:00415C91 align 200h
.text:00415E00 dd 80h dup(?)
.text:00415E00 _text ends
.text:00415E00
.rdata:00416000 ; Section 3. (virtual address 00016000)
.rdata:00416000 ; Virtual size : 00002035 ( 8245.)
.rdata:00416000 ; Section size in file : 00002200 ( 8704.)
.rdata:00416000 ; Offset to raw data for section: 00005200
.rdata:00416000 ; Flags 40000040: Data Readable
.rdata:00416000 ; Alignment : default
.rdata:00416000 ; ===========================================================================
.rdata:00416000
.rdata:00416000 ; Segment type: Pure data
.rdata:00416000 ; Segment permissions: Read
.rdata:00416000 _rdata segment para public 'DATA' use32
.rdata:00416000 assume cs:_rdata
.rdata:00416000 ;org 416000h
.rdata:00416000 ___xc_a db 0 ; DATA XREF: __scrt_common_main_seh+B4�o
.rdata:00416B2F db 0
.rdata:00416B30 ; char char_array[13]
.rdata:00416B30 char_array db 'Hello World!',0 ; DATA XREF: _main+64�o
.rdata:00416B30 ; _main+69�o
.rdata:00416B3D align 10h
.rdata:00416B40 ; char const_char_array[13]
.rdata:00416B40 const_char_array db 'Hello World!',0 ; DATA XREF: _main+80�o
.rdata:00416B40 ; _main+85�o
.rdata:00416B4D align 10h
.rdata:00416B50 ; char static_const_char_array[13]
.rdata:00416B50 static_const_char_array db 'Hello World!',0 ; DATA XREF: _main+9C�o
.rdata:00416B50 ; _main+A1�o
.rdata:00416B5D align 10h
.rdata:00416B60 ; const char *const static_const_char_pointer_const
.rdata:00416B60 static_const_char_pointer_const dd offset aHell ; DATA XREF: _main+D7�r
.rdata:00416B60 ; _main+DD�r
.rdata:00416B60 ; "Hell"
.rdata:00416B64 align 10h
.rdata:00416B70 aHell db 'Hell' ; DATA XREF: _main+28�r
.rdata:00416B70 ; _main+12C�o ...
.rdata:00416B74 dword_416B74 dd 6F57206Fh ; DATA XREF: _main+30�r
.rdata:00416B78 dword_416B78 dd 21646C72h ; DATA XREF: _main+39�r
.rdata:00416B7C byte_416B7C db 0 ; DATA XREF: _main+42�r
.rdata:00416B7D db 0
.rdata:00418FFF db ? ;
.rdata:00418FFF _rdata ends
.rdata:00418FFF
.data:00419000 ; Section 4. (virtual address 00019000)
.data:00419000 ; Virtual size : 00000594 ( 1428.)
.data:00419000 ; Section size in file : 00000200 ( 512.)
.data:00419000 ; Offset to raw data for section: 00007400
.data:00419000 ; Flags C0000040: Data Readable Writable
.data:00419000 ; Alignment : default
.data:00419000 ; ===========================================================================
.data:00419000
.data:00419000 ; Segment type: Pure data
.data:00419000 ; Segment permissions: Read/Write
.data:00419000 _data segment para public 'DATA' use32
.data:00419000 assume cs:_data
.data:00419000 ;org 419000h
.data:00419000 ; const char *static_const_char_pointer
.data:00419000 static_const_char_pointer dd offset aHell ; DATA XREF: _main+B8�r
.data:00419000 ; _main+BE�r ...
.data:00419000 ; "Hell"
.data:00419004 ; int _RTC_ErrorLevels
.data:00419004 ?_RTC_ErrorLevels@@3PAHA dd 1 ; DATA XREF: _RTC_Failure(void *,int)+B�r
.data:00419004
program output:
local_char_array@0040FA58: Hello World!
char_array@00DC6B30: Hello World!
const_char_array@00DC6B40: Hello World!
static_const_char_array@00DC6B50: Hello World!
static_const_char_pointer@00DC6B70: Hello World!
static_const_char_pointer_const@00DC6B70: Hello World!
static_const_char_pointer@00DC75D4: Fang
define_string@00DC6B70: Hello World!
define_same_string@00DC6B70: Hello World!
define_another_string@00DC74AC: Defined String!
As can be seen from the above,
- A string array always creates a copy. at global, placed in a section; at scoped, produce a copy code..
- A
#define
to a same string will be identical. - a variable modified by
const
will be placed in a readonly section, butchar* const
notconst char*
,const
right to*
.