Skip to content

Instantly share code, notes, and snippets.

@ssfang
Last active May 24, 2016 04:07
Show Gist options
  • Save ssfang/703a44a625076333fe6cdaf2e1144dae to your computer and use it in GitHub Desktop.
Save ssfang/703a44a625076333fe6cdaf2e1144dae to your computer and use it in GitHub Desktop.
How does the compiler place strings?
// ConstString.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h" // #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;
}
/*
0414F60 ; DATA XREF: _main+195o
.text:00414F68 dword_414F68 dd 0FFFFFFE8h, 0Dh ; DATA XREF: _main:vo
.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+1D0o
.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+B4o
.rdata:00416001 db 0
.rdata:00416002 db 0
.rdata:00416003 db 0
.rdata:00416B2F db 0
.rdata:00416B30 ; char char_array[13]
.rdata:00416B30 char_array db 'Hello World!',0 ; DATA XREF: _main+64o
.rdata:00416B30 ; _main+69o
.rdata:00416B3D align 10h
.rdata:00416B40 ; char const_char_array[13]
.rdata:00416B40 const_char_array db 'Hello World!',0 ; DATA XREF: _main+80o
.rdata:00416B40 ; _main+85o
.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+9Co
.rdata:00416B50 ; _main+A1o
.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+D7r
.rdata:00416B60 ; _main+DDr
.rdata:00416B60 ; "Hell"
.rdata:00416B64 align 10h
.rdata:00416B70 aHell db 'Hell' ; DATA XREF: _main+28r
.rdata:00416B70 ; _main+12Co ...
.rdata:00416B74 dword_416B74 dd 6F57206Fh ; DATA XREF: _main+30r
.rdata:00416B78 dword_416B78 dd 21646C72h ; DATA XREF: _main+39r
.rdata:00416B7C byte_416B7C db 0 ; DATA XREF: _main+42r
.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+B8r
.data:00419000 ; _main+BEr ...
.data:00419000 ; "Hell"
.data:00419004 ; int _RTC_ErrorLevels
.data:00419004 ?_RTC_ErrorLevels@@3PAHA dd 1 ; DATA XREF: _RTC_Failure(void *,int)+Br
.data:00419004 ; __RTC_SetErrorType+Br ...
*/

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, but char* const not const char*, const right to * .
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment