Mac OSX在主函数中未初始化指针

时间:2013-02-12 10:23:02

标签: c++ c macos assembly

我有两个问题。

第一个问题。为什么以下代码实际上在mac上工作(用gcc编译)?

int main()
{
    int *p;
    *p = 1;
    return 0;
}

当拆卸线'* p = 1;'时变

mov rax, [rbp - 16]
mov qword [rax], 1

第二个问题。什么位于[rbp - 16]?

在问这个问题时我将操作数[rbp - 16]解释为[rbp + 16],这显然没有意义。我累了......

你回答我的问题。

3 个答案:

答案 0 :(得分:3)

您的代码有undefined behaviour。这意味着允许它做任何事情都是允许的。它不必崩溃。

当你的程序启动时,有一些代码在main()之前执行并且使用相同的堆栈。你的盒子上可能发生的事情是包含p的堆栈区域之前已被另一个保留有效指针的函数使用。你的main()偶然偶然发现了指针,已经取消引用它,并且正在腐蚀别人的记忆。

我尝试使用gcc编译代码并在OSX上运行它,但它确实崩溃了。

答案 1 :(得分:1)

我记得,如果没有明确指定其值,C中的变量会被先前用户在堆栈上留下的某些值初始化。所以,这个值绝对是 random ,而你的代码只是改变了随机存储区的值。如果你得到空指针,你的程序将失败。

答案 2 :(得分:0)

其他人已经充分涵盖了这种行为的不确定性。您的具体问题似乎是了解拆卸。这是一个有点冗长,但希望有用的演练:

第一条指示:mov rax, [rbp - 16]

RBP是“基指针寄存器”。这将地址保存在当前堆栈帧的内存中。正如评论者指出的那样,rbp - 16是当前堆栈框架中p的位置。它将是一个8字节的指针。如果您在int *q;之后立即声明了另一个本地变量p,那么它的地址可能会在rbp - 24。在这种情况下,RAX是通用寄存器。这会将8字节指针从位于rbp - 16堆栈的位置复制到RAX中。正如其他人所指出的那样,由于你没有初始化prbp - 16的值是内存中最后一个使用该内存的东西,或者是完全随机的东西。方括号括号表示操作数rbp - 16是指针,并且应复制地址rbp - 16处的内存内容,而不是表达式rbp - 16的字面结果。您可以将rbp - 16表达式视为具有int**类型。

第二条指令:mov qword [rax], 1

QWORD是“四字”的缩写。历史上,一个字节是一个字节,“字”是两个字节,“长”或“双字”(对于“双字”)是四个字节,当然,“四字”是8个字节。该指令将文字1(扩展为其八字节形式)复制到RAX指向的位置。方括号括号表示操作数RAX是一个指针,并且该文字将被操作数复制到指向的位置。如果指令是mov qword rax, 1,则将文字1(以其八字节形式)复制到RAX中。

正如其他人所说的那样,因为那个指针是垃圾(偶然发生在内存中),这种情况很好(但不能保证)会崩溃。