为什么主函数总是加载在相同的地址,而变量大多数时候有不同的地址?

2023-12-30

我今天写了这个小程序,结果令我震惊。这是程序


int main(int argc, char **argv)
{
 int a;
 printf("\n\tMain is located at: %p and the variable a is located at address: %p",main,&a;);
 return 0;
}

在我的机器上,主函数总是加载在地址“0x80483d4”处,并且变量的地址不断变化,这是怎么发生的?我在操作系统中读到,作为虚拟化方案的一部分,操作系统不断重新定位指令的地址。那么为什么每次我运行这个程序时 main 都会加载到相同的地址呢?

提前谢谢你们。


在 Linux 等 ELF 系统上,普通可执行文件(ELF 类型)的段地址ET_EXEC) 负载在编译时固定。共享对象(ELF类型ET_DYN),例如库被构建为与位置无关,其段可加载到地址空间中的任何位置(可能对某些体系结构有一些限制)。可以构建可执行文件,使其实际上ET_DYN-- 这些被称为“位置无关的可执行文件”(PIE),但不是一种常见技术。

你所看到的事实是你的main()函数位于已编译的可执行文件的固定地址文本段中。还尝试打印库函数的地址,例如printf()通过找到它之后dlsym()-- 如果您的系统确实支持并启用了地址空间布局随机化 (ASLR),那么您应该会看到该函数的地址在程序运行过程中发生变化。 (如果您只是通过将引用直接放入代码中来打印库函数的地址,那么您实际上可能得​​到的是该函数的过程查找表(PLT)蹦床的地址,该地址在可执行文件中的固定地址处静态编译.)

您看到的变量在每次运行时都会更改地址,因为它是在堆栈上创建的自动变量,而不是在静态分配的内存中。根据操作系统和版本的不同,即使没有 ASLR,堆栈基地址也可能在运行之间发生变化。如果将变量声明移动到函数之外的全局变量,您会发现它的行为方式与您的函数相同main()函数确实如此。

这是一个完整的例子——用类似的东西编译gcc -o example example.c -dl:

#include <stdio.h>
#include <dlfcn.h>

int a = 0;

int main(int argc, char **argv)
{
    int b = 0;
    void *handle = dlopen(NULL, RTLD_LAZY);
    printf("&main: %p; &a: %p\n", &main, &a);
    printf("&printf: %p; &b: %p\n", dlsym(handle, "printf"), &b);
    return 0;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么主函数总是加载在相同的地址,而变量大多数时候有不同的地址? 的相关文章

  • -ffast-math 可以安全地用于典型项目吗?

    在回答我建议的问题时 ffast math 有评论指出这是危险的 我个人的感觉是 在科学计算之外 是可以的 我还假设严肃的金融应用程序使用定点而不是浮点 当然 如果你想在你的项目中使用它 最终的答案是在你的项目上测试它 看看它有多大影响 但
  • C++ STL 映射,std::pair 作为键

    这就是我通过地图定义的方式 std map
  • 如何获取枚举数作为常量?

    From 枚举中定义的项目总数 https stackoverflow com questions 856154 total number of items defined in an enum 我发现我可以使用以下方法获取枚举数 Enum
  • 如何在 ASP.NET MVC 中处理会话数据

    假设我想存储一个名为language id在会议中 我想我也许可以做如下的事情 public class CountryController Controller WebMethod EnableSession true AcceptVer
  • 如何在建立上下文时设置连接超时-PrincipalContext

    using PrincipalContext ctx new PrincipalContext ContextType Domain Domain UserName Password UserPrincipal U new UserPrin
  • 以编程方式更新 Wifi 网络

    我正在尝试创建一个程序 当某个 wifi 网络在范围内时 该程序会连接到该网络 即使已经连接到另一个 wifi 也是如此 我在用着简单Wifi https github com DigiExam simplewifi 基本上效果很好 除了在
  • 图片框、双击和单击事件

    我有一个奇怪的问题 我有一个图片框双击事件以及单击事件 问题是即使我双击该控件 也会引发单击事件 如果我禁用单击事件 则双击事件正在工作 这个问题已经在这里讨论过 https stackoverflow com questions 1830
  • 在编译输出中添加程序集绑定 (app.config)

    如果我编译应用程序 则会在输出中自动添加程序集绑定 具体的程序集绑定不在app config在 Visual Studio 中但在创建的应用程序配置中 有什么办法可以检查为什么会自动添加程序集绑定吗 选项AutoGenerateBindin
  • 仅使用一个 #include 表达式一次包含多个头文件?

    是否有任何表达式可以使语法一次包含多个标头 而无需为每个新文件编写 include 表达式 例如 include
  • 我应该使用字节还是int?

    我记得曾在某处读到 即使您只需要字节 使用 Int32 更好 就性能而言 它 据说 仅适用于您不关心存储的情况 这是有效的吗 例如 我需要一个保存一周中某一天的变量 我是吗 int dayOfWeek or byte dayOfWeek E
  • .Net 支持柯里化泛型吗?

    假设我们有一个嵌套的泛型类 public class A
  • 对象变空似乎是 Hangfire 中的反序列化问题

    Hangfire 似乎无法反序列化我的原始版本Scheduler对象及其所有状态 我正在调用其 Execute 方法BackgroundJob Enqueue 如下所示 Scheduler new FileInFileOut FileIn
  • 括号内声明的对象的范围

    如果我声明一个这样的对象 void main myclass objectA anotherclass true true 0 即 我通过直接调用后者的构造函数来创建一个 objectA 和另一个对象 anotherclass anothe
  • Qt - 添加超链接到对话框

    有没有办法在 Qt 对话框中添加可点击的超链接 IE 它应该看起来像一个超链接 蓝色文本 当您单击它时 它应该在浏览器中打开该超链接 像这样的东西 Use QLabel setOpenExternalLinks bool 并在标签上设置文本
  • 在 OSX 上检测 Objective C 或 C++ 中的文件夹访问(如 fs_usage 命令)

    我正在 OSX 上开发实时病毒扫描程序 OSX 的命令行命令fs usage可以通过以下方式确定文件夹访问权限 并且只能以 root 用户身份运行 fs usage w f pathname grep Users Documents Use
  • TCP/IP 传输期间套接字数据损坏

    当我通过预连接的 TCP IP 套接字发送数据时 我发现数据已损坏 Example Station1 正在向 Station2 发送数据 我已经在发送之前 在 S1 和接收之后 在 S2 打印了数据 以下是消息 S1 发送的数据是ACKS2
  • 如何检查日期时间是否发生在今天?

    有没有比下面的代码更好的 net 方法来检查 今天 是否发生了 DateTime if newsStory WhenAdded Day DateTime Now Day newsStory WhenAdded Month DateTime
  • 在 C 中运行 setuid 程序的正确方法

    我有一个权限为4750的进程 我的Linux系统中存在两个用户 root 用户和 appz 用户 该进程继承以 appz 用户身份运行的进程管理器的权限 我有两个基本惯例 void do root void int status statu
  • asio::this_coro::executor 的实现是什么

    在协程函数中 我们可以添加auto ex co await asio this coro executor 获取该协程的执行者 但当我想了解它的定义时 我发现了这个 Awaitable type that returns the execu
  • 将“C# 友好类型”名称转换为实际类型:“int” => typeof(int)

    我想得到一个System Type给定一个string指定 原始 类型C 友好名称 基本上与 C 编译器读取 C 源代码时的方式相同 我觉得描述我所追求的最好方式是单元测试的形式 我希望存在一种通用技术 可以使以下所有断言通过 而不是尝试对

随机推荐