c - 关于地址值和指针增量的问题?

标签 c linux x86 reverse-engineering

假设我有如下代码

#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;
}

那么输出将是

[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

我的问题是,为什么 int_ptr 中的地址增加量不同,尽管我只向地址添加了 1?我知道这是一个 int 变量,大小为 4 个字节,但我想知道程序如何将 4 添加到地址,即使我只添加了 1。

谢谢

+添加 抱歉,我在标记逆向工程时造成了困惑,我正在使用 gdb 查看一些 asm 代码来回答我的问题。

  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    

最佳答案

大多数现代 CPU 都是字节寻址的。这意味着每个内存地址引用一个字节。因此,对于内存中的每个 char(占用 1 个字节),您只需要一个地址。

但是,如果您正在使用连续的 int 数组(在大多数计算机上占用 4 个字节),您的地址将必须 4 乘 4 进行“跳跃”,因为有内存需要寻址 4 个字节,因此占用了 4 个内存地址。

在您的示例中:

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.

关于c - 关于地址值和指针增量的问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59331984/

相关文章:

linux - 在 Linux 上启动时启动脚本的最佳方式是什么

linux - 字体不工作 - Vim Statusline

memory - 谁在启动期间加载 BIOS 和内存映射

c - 在 c 中使用标记化

c - 为什么我的程序在某些测试中可以正常工作,而在其他测试中却不能正常工作?

c - windows media time vs time.h 在实时系统中哪一个更可靠?

linux - 字、双字、四字

c - 设置对话框不可调整大小或创建另一个 gtk 窗口

python - 屏幕命令和python

assembly - 我的操作系统无法在 VMWare 中启动