Let's say that I have a code like below
#include <stdio.h>
int main(void)
{
char char_array[5] = {'a', 'b', 'c', 'd', 'e'};
int int_array[5] = {1, 2, 3, 4, 5};
int i;
char *char_ptr;
int *int_ptr;
char_ptr = char_array;
int_ptr = int_array;
for(i = 0; i < 5; i++){
printf("[char_ptr]For %p address pointing to %c value\n", char_ptr, *char_ptr);
char_ptr +=1;
}
for(i = 0; i < 5; i++){
printf("[int_ptr]For %p address pointing to %d value\n", int_ptr, *int_ptr);
int_ptr += 1;
}
return 0;
}
Then the output will be
[char_ptr]For 0xbf7fc37f address pointing to a value
[char_ptr]For 0xbf7fc380 address pointing to b value
[char_ptr]For 0xbf7fc381 address pointing to c value
[char_ptr]For 0xbf7fc382 address pointing to d value
[char_ptr]For 0xbf7fc383 address pointing to e value
[int_ptr]For 0xbf7fc368 address pointing to 1 value
[int_ptr]For 0xbf7fc36c address pointing to 2 value
[int_ptr]For 0xbf7fc370 address pointing to 3 value
[int_ptr]For 0xbf7fc374 address pointing to 4 value
[int_ptr]For 0xbf7fc378 address pointing to 5 value
My question here is why is the increasement of the address different in int_ptr even though I only added only 1 to the address? I know that is a int variable which is a size of 4 bytes but I'm wondering how the program added 4 to the address even though I only added one to it.
Thank you
+addition sorry for the confusion that I made from tagging reverse engineering, I was using gdb to look at some asm codes in order to answer my question.
0x00001199 <+0>: lea ecx,[esp+0x4]
0x0000119d <+4>: and esp,0xfffffff0
0x000011a0 <+7>: push DWORD PTR [ecx-0x4]
0x000011a3 <+10>: push ebp
0x000011a4 <+11>: mov ebp,esp
0x000011a6 <+13>: push ebx
0x000011a7 <+14>: push ecx
0x000011a8 <+15>: sub esp,0x30
0x000011ab <+18>: call 0x10a0 <__x86.get_pc_thunk.bx>
0x000011b0 <+23>: add ebx,0x2e50
0x000011b6 <+29>: mov DWORD PTR [ebp-0x19],0x64636261
0x000011bd <+36>: mov BYTE PTR [ebp-0x15],0x65
0x000011c1 <+40>: mov DWORD PTR [ebp-0x30],0x1
0x000011c8 <+47>: mov DWORD PTR [ebp-0x2c],0x2
0x000011cf <+54>: mov DWORD PTR [ebp-0x28],0x3
0x000011d6 <+61>: mov DWORD PTR [ebp-0x24],0x4
0x000011dd <+68>: mov DWORD PTR [ebp-0x20],0x5
0x000011e4 <+75>: lea eax,[ebp-0x19]
0x000011e7 <+78>: mov DWORD PTR [ebp-0x10],eax
0x000011ea <+81>: lea eax,[ebp-0x30]
0x000011ed <+84>: mov DWORD PTR [ebp-0x14],eax
0x000011f0 <+87>: mov DWORD PTR [ebp-0xc],0x0
0x000011f7 <+94>: jmp 0x1220 <main+135>
0x000011f9 <+96>: mov eax,DWORD PTR [ebp-0x10]
0x000011fc <+99>: movzx eax,BYTE PTR [eax]
0x000011ff <+102>: movsx eax,al
0x00001202 <+105>: sub esp,0x4
0x00001205 <+108>: push eax
0x00001206 <+109>: push DWORD PTR [ebp-0x10]
0x00001209 <+112>: lea eax,[ebx-0x1ff8]
0x0000120f <+118>: push eax
0x00001210 <+119>: call 0x1030 <printf@plt>
0x00001215 <+124>: add esp,0x10
0x00001218 <+127>: add DWORD PTR [ebp-0x10],0x1
0x0000121c <+131>: add DWORD PTR [ebp-0xc],0x1
0x00001220 <+135>: cmp DWORD PTR [ebp-0xc],0x4
0x00001224 <+139>: jle 0x11f9 <main+96>
0x00001226 <+141>: mov DWORD PTR [ebp-0xc],0x0
0x0000122d <+148>: jmp 0x1252 <main+185>
0x0000122f <+150>: mov eax,DWORD PTR [ebp-0x14]
0x00001232 <+153>: mov eax,DWORD PTR [eax]
0x00001234 <+155>: sub esp,0x4
0x00001237 <+158>: push eax
0x00001238 <+159>: push DWORD PTR [ebp-0x14]
0x0000123b <+162>: lea eax,[ebx-0x1fc8]
0x00001241 <+168>: push eax
0x00001242 <+169>: call 0x1030 <printf@plt>
0x00001247 <+174>: add esp,0x10
0x0000124a <+177>: add DWORD PTR [ebp-0x14],0x4
0x0000124e <+181>: add DWORD PTR [ebp-0xc],0x1
0x00001252 <+185>: cmp DWORD PTR [ebp-0xc],0x4
0x00001256 <+189>: jle 0x122f <main+150>
0x00001258 <+191>: mov eax,0x0
0x0000125d <+196>: lea esp,[ebp-0x8]
0x00001260 <+199>: pop ecx
0x00001261 <+200>: pop ebx
0x00001262 <+201>: pop ebp
0x00001263 <+202>: lea esp,[ecx-0x4]
0x00001266 <+205>: ret
Most modern CPUs are byte addressable. That means that each memory address refers to a single byte. Thus, for every char
(which occupies 1 byte) in memory, you only need one address.
If you're working with a contiguous array of int
s (which take up 4 bytes on most machines), however, your addresses will have to "hop" 4 by 4, because there are 4 bytes that memory needs to address and thus 4 memory addresses are taken.
In your example:
0xbf7fc368 refers to the first byte of the first `int`.
0xbf7fc369 refers to the second byte of the first `int`.
0xbf7fc36a refers to the third byte of the first `int`.
0xbf7fc36b refers to the fourth byte of the first `int`.
0xbf7fc36c refers to the first byte of the second `int`.
... and so on.
User contributions licensed under CC BY-SA 3.0