- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我通常不会花太多时间阅读汇编,所以下面的编译器输出让我有点困惑。
假设我在运行 OSX 10.6 的 Intel Core 2 Duo 上编译这段 C 代码:
while (var != 69) // var is a global variable
{
printf("Looping!\n");
}
“var != 69”比较的程序集如下所示:
cmpl $69, _var(%rip)
我知道它实际上意味着将值“69”与全局变量“var”的内容进行比较,但我很难理解“_var(%rip)”部分。通常,我希望有一个偏移值,比如引用堆栈中的局部变量(例如:-4($ebp))。但是,我不太了解如何使用“_var”声明偏移指令指针会给我全局变量“var”的内容。
那一行到底是什么意思?
谢谢。
最佳答案
这与使用 offset(%ebp)
寻址堆栈中的局部变量几乎相同。在这种情况下,链接器将该指令的偏移字段设置为 var
的地址与 %rip
的值之间的差异当该指令执行时会有。 (如果我没记错的话,那个值是下一条指令的地址,因为%rip
总是指向当前正在执行的指令之后 .) 因此,加法给出了 var
的地址。
为什么要这样做?这是 position-independent code 的标志.如果编译器生成了
cmpl $69, _var
并且链接器填入了var
的绝对地址,然后当您运行程序时,可执行镜像总是必须在一个特定的位置加载到内存中地址,以便所有变量都具有代码期望的绝对地址。通过这种方式,唯一需要固定的是代码和数据之间的距离;代码和数据(即完整的可执行镜像)可以加载到任何地址并且仍然可以工作。
... 何苦呢?为什么必须在一个特定地址加载可执行文件是不好的?不一定。共享库必须是位置无关的,否则你可能有两个库想要加载到重叠的地址,你不能在同一个程序中同时使用它们。 (一些系统通过保留所有库及其所需空间的全局注册表来处理这个问题,但显然这不能扩展。)使可执行文件位置无关主要是作为一种安全措施完成的:它是如果您不知道程序代码在内存中的位置(这称为 address space layout randomization),那么利用缓冲区溢出会有些困难。
关于c - X86 汇编指令指针寻址,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6488226/
我正在尝试提供即时转码的视频。不幸的是,这意味着寻求不起作用。我假设这是因为浏览器不知道视频有多长,因此无法正确显示搜索栏。 有谁知道是否可以对视频的时长进行硬编码? 我想到的另一个选择可能是创建我自
我是一名优秀的程序员,十分优秀!