PIC 寄存器(%ebx)有什么作用?

发布于 2024-07-22 15:36:47 字数 639 浏览 2 评论 0原文

我用 C++ 编写了一个“危险”程序,它从一个堆栈帧来回跳转到另一个堆栈帧。 目标是从调用堆栈的最低级别跳转到调用者,执行某些操作,然后再次向下跳转,每次都会跳过其间的所有调用。

我通过手动更改堆栈基地址(设置 %ebp)并跳转到标签地址来实现此目的。 它完全可以与 gcc 和 icc 一起使用,根本没有任何堆栈损坏。 这工作的那天天气很凉爽。

现在我正在用 C 语言重新编写相同的程序,但它不起作用。 具体来说,它不适用于 gcc v4.0.1 (Mac OS)。 一旦我跳转到新的堆栈帧(堆栈基指针设置正确),就会执行以下指令,就在调用 fprintf 之前。 这里列出的最后一条指令崩溃,取消引用 NULL:

lea    0x18b8(%ebx), %eax
mov    (%eax), %eax
mov    (%eax), %eax

我已经做了一些调试,并且我发现通过在切换堆栈帧时手动设置 %ebx 寄存器(使用我之前观察到的值)首先保留该函数),我修复了该错误。 我读到这个寄存器处理 gcc 中的“位置无关代码”。

什么是位置无关代码? 位置无关代码如何工作? 这个寄存器指向什么?

I have written a "dangerous" program in C++ that jumps back and forth from one stack frame to another. The goal is to be jump from the lowest level of a call stack to a caller, do something, and then jump back down again, each time skipping all the calls inbetween.

I do this by manually changing the stack base address (setting %ebp) and jumping to a label address. It totally works, with gcc and icc both, without any stack corruption at all. The day this worked was a cool day.

Now I'm taking the same program and re-writing it in C, and it doesn't work. Specifically, it doesn't work with gcc v4.0.1 (Mac OS). Once I jump to the new stack frame (with the stack base pointer set correctly), the following instructions execute, being just before a call to fprintf. The last instruction listed here crashes, dereferencing NULL:

lea    0x18b8(%ebx), %eax
mov    (%eax), %eax
mov    (%eax), %eax

I've done some debugging, and I've figured out that by setting the %ebx register manually when I switch stack frames (using a value I observed before leaving the function in the first place), I fix the bug. I've read that this register deals with "position independent code" in gcc.

What is position independent code? How does position independent code work? To what is this register pointing?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

青衫负雪 2024-07-29 15:36:47

EBX 指向全局偏移表。 请参阅此关于 PIC 的参考i386。 该链接解释了什么是 PIC 以及如何使用 EBX

EBX points to the Global Offset Table. See this reference about PIC on i386. The link explains what PIC is an how EBX is used.

哑剧 2024-07-29 15:36:47

PIC 是加载时动态重定位的代码。 非 PIC 代码具有在链接时设置的跳转和调用地址。 PIC 有一个表,引用了此类值存在的所有位置,就像 .dll 一样。

加载图像时,加载器将动态更新这些值。 其他方案引用定义“基址”的数据值,并且通过对基址执行计算来确定目标地址。 底座通常由装载机重新设置。

最后,其他方案使用调用已知相对偏移量的各种蹦床。 相对偏移量包含由加载器更新的代码和/或数据。

选择不同方案的原因各不相同。 有些运行时速度很快,但加载速度较慢。 有些加载速度很快,但运行时性能较低。

PIC is code that is relocated dynamically when it is loaded. Code that is non-PIC has jump and call addresses set at link time. PIC has a table that references all the places where such values exist, much like a .dll.

When the image is loaded, the loader will dynamically update those values. Other schemes reference a data value that defines a "base" and the target address is decided by performing calculations on the base. The base is usually set by the loader again.

Finally, other schemes use various trampolines that call to known relative offsets. The relative offsets contain code and/or data that are updated by a loader.

There are different reasons why different schemes are chosen. Some are fast when run, but slower to load. Some are fast to load, but have less runtime performance.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文