Global variables can be accessed and used by any function in a program. Local variables can be accessed only by the function in which they are defined. Both global and local variables are declared similarly in C, but they look completely different in assembly.
Following are two examples of C code for both global and local variables. Notice the subtle
difference between the two. The global example, Example 6-1, defines x
and y
variables outside the function. In the local example, Example 6-2, the variables are defined within the
function.
Example 6-1. A simple program with two global variables
int x = 1;
int y = 2;
void main() { x = x+y; printf("total = %d ", x); }
Example 6-2. A simple program with two local variables
void main() { int x = 1; int y = 2; x = x+y; printf("total = %d ", x); }
The difference between the global and local variables in these C code examples is small, and in this case the program result is the same. But the disassembly, shown in Example 6-3 and Example 6-4, is quite different. The global variables are referenced by memory addresses, and the local variables are referenced by the stack addresses.
In Example 6-3, the global variable x
is signified by dword_40CF60
, a
memory location at 0x40CF60. Notice that x
is changed in memory
when eax
is moved into dword_40CF60
at ❶. All subsequent functions
that utilize this variable will be impacted.
Example 6-3. Assembly code for the global variable example in Example 6-1
00401003 mov eax,dword_40CF60
00401008 add eax, dword_40C000 0040100E movdword_40CF60
, eax ❶ 00401013 mov ecx,dword_40CF60
00401019 push ecx 0040101A push offset aTotalD ;"total = %d " 0040101F call printf
In Example 6-4 and Example 6-5, the local variable x
is located on the stack at a constant offset relative to ebp
. In Example 6-4, memory location
[ebp-4]
is used consistently throughout this function to
reference the local variable x
. This tells us that ebp-4
is a stack-based local variable that is referenced only in the
function in which it is defined.
Example 6-4. Assembly code for the local variable example in Example 6-2, without labeling
00401006 mov dword ptr [ebp-4
], 1 0040100D mov dword ptr [ebp-8], 2 00401014 mov eax, [ebp-4
] 00401017 add eax, [ebp-8] 0040101A mov [ebp-4
], eax 0040101D mov ecx, [ebp-4
] 00401020 push ecx 00401021 push offset aTotalD ; "total = %d " 00401026 call printf
In Example 6-5, x
has been nicely labeled by IDA Pro Disassembler with the dummy name var_4
. As we discussed in Chapter 5, dummy names can be
renamed to meaningful names that reflect their function. Having this local variable named var_4
instead of -4
simplifies your
analysis, because once you rename var_4
to x
, you won’t need to track the offset -4
in your head throughout the function.
Example 6-5. Assembly code for the local variable example shown in Example 6-2, with labeling
00401006 mov [ebp+var_4
], 1 0040100D mov [ebp+var_8], 2 00401014 mov eax, [ebp+var_4
] 00401017 add eax, [ebp+var_8] 0040101A mov [ebp+var_4
], eax 0040101D mov ecx, [ebp+var_4
] 00401020 push ecx 00401021 push offset aTotalD ; "total = %d " 00401026 call printf