c变量分配在内存,指针上

时间:2022-12-24 16:49:20

How are variables are located in memory? I have this code

变量如何位于内存中?我有这个代码

int w=1;
int x=1;
int y=1;
int z=1;

int main(int argc, char** argv) {
    printf("\n  w %d",&w);
    printf("\n  x %d",&x);
    printf("\n  y %d",&y);
    printf("\n  z %d",&z);
    return (EXIT_SUCCESS);
}

and it prints this

并打印出来

w 134520852
x 134520856
y 134520860
z 134520864

We can see that when other integer is declare and assigned, the address is moved four positions (bytes I suppose, it seems very logic). But if we don't assign the variables, like in the next code:

我们可以看到,当声明并分配了其他整数时,地址被移动了四个位置(我认为是字节,看起来非常逻辑)。但是如果我们不分配变量,就像在下一个代码中一样:

int w;
int x;
int y;
int z;

int main(int argc, char** argv) {
    printf("\n  w %d",&w);
    printf("\n  x %d",&x);
    printf("\n  y %d",&y);
    printf("\n  z %d",&z);
    return (EXIT_SUCCESS);
}

it prints this

它打印出来

w 134520868
x 134520864
y 134520872
z 134520860

We can see there are four positions between addresses, but they are not in order. Why is this? How works the compiler in that case?

我们可以看到地址之间有四个位置,但它们不是有序的。为什么是这样?在这种情况下编译器如何工作?

In case you want to know why I'm asking this, it is because I'm starting to study some security and I'm trying to understand some attacks, for instance, how integer overflow attacks work, and I've been playing with pointers in C to modify other variables by adding more positions than the size of the variable and things like that.

如果你想知道我为什么这么问,那是因为我开始学习一些安全性而我正试图理解一些攻击,例如,整数溢出攻击如何工作,我一直在玩C中的指针通过添加比变量大小更多的位置来修改其他变量。

2 个解决方案

#1


2  

Your first example initialises variables, which generates different allocation code. By looking into the assembly file generated by gcc (gas) I get:

您的第一个示例初始化变量,生成不同的分配代码。通过查看gcc(gas)生成的汇编文件,我得到:

    .globl  _w
    .data
    .align 4
_w:
    .long   1
    .globl  _x
    .align 4
_x:
    .long   1
    .globl  _y
    .align 4
 _y:
    .long   1
    .globl  _z
    .align 4
 _z:
    .long   1

And this basically dictates the memory addresses.

这基本上决定了内存地址。

Your second example creates uninitialised variables, and as Jonathan said, those go into BSS. The assembler code is:

你的第二个例子创建了未初始化的变量,正如Jonathan所说,那些进入了BSS。汇编程序代码是:

.comm  _w, 4, 2
.comm  _x, 4, 2
.comm  _y, 4, 2
.comm  _z, 4, 2

And that means you can't guarantee the sequence in which those variables will be located in memory.

这意味着您无法保证这些变量在内存中的顺序。

#2


1  

The second set of numbers is also consecutive, just not ordered the same as in the source. I think the reason for this is simply that when you initialize the variables the compiler puts them in order because it maintains the order of initializations, in the second case you just get a random order.

第二组数字也是连续的,只是没有与源中的相同。我认为这样做的原因很简单,当你初始化变量时,编译器将它们按顺序排列,因为它维护了初始化的顺序,在第二种情况下,你只是得到一个随机顺序。

In any case this depends on the compiler; I get the same pattern (ordered, 4 bytes apart) in both cases.

无论如何,这取决于编译器;在两种情况下,我得到相同的模式(有序,相隔4个字节)。

#1


2  

Your first example initialises variables, which generates different allocation code. By looking into the assembly file generated by gcc (gas) I get:

您的第一个示例初始化变量,生成不同的分配代码。通过查看gcc(gas)生成的汇编文件,我得到:

    .globl  _w
    .data
    .align 4
_w:
    .long   1
    .globl  _x
    .align 4
_x:
    .long   1
    .globl  _y
    .align 4
 _y:
    .long   1
    .globl  _z
    .align 4
 _z:
    .long   1

And this basically dictates the memory addresses.

这基本上决定了内存地址。

Your second example creates uninitialised variables, and as Jonathan said, those go into BSS. The assembler code is:

你的第二个例子创建了未初始化的变量,正如Jonathan所说,那些进入了BSS。汇编程序代码是:

.comm  _w, 4, 2
.comm  _x, 4, 2
.comm  _y, 4, 2
.comm  _z, 4, 2

And that means you can't guarantee the sequence in which those variables will be located in memory.

这意味着您无法保证这些变量在内存中的顺序。

#2


1  

The second set of numbers is also consecutive, just not ordered the same as in the source. I think the reason for this is simply that when you initialize the variables the compiler puts them in order because it maintains the order of initializations, in the second case you just get a random order.

第二组数字也是连续的,只是没有与源中的相同。我认为这样做的原因很简单,当你初始化变量时,编译器将它们按顺序排列,因为它维护了初始化的顺序,在第二种情况下,你只是得到一个随机顺序。

In any case this depends on the compiler; I get the same pattern (ordered, 4 bytes apart) in both cases.

无论如何,这取决于编译器;在两种情况下,我得到相同的模式(有序,相隔4个字节)。