【发布时间】:2014-05-03 09:55:32
【问题描述】:
似乎我听说 x86 和 x86_64 ABI 中的所有数据段都是相同的。但是ss注册也是?我正在写内核,我想检测堆栈溢出。为此,要求ss段选择器不等于其他段寄存器...
【问题讨论】:
-
您可能需要阅读堆栈金丝雀/堆栈保护器(例如 google 的 x86_64 堆栈保护器)。
似乎我听说 x86 和 x86_64 ABI 中的所有数据段都是相同的。但是ss注册也是?我正在写内核,我想检测堆栈溢出。为此,要求ss段选择器不等于其他段寄存器...
【问题讨论】:
SS 与其他段寄存器不同,尤其是与隐式不同 用过的(CS、DS)不是个好主意。
大多数(几乎所有)x86 ABI 都规定了平面地址模型,即在地址内 一个进程的空间,一个 64 位地址指的是同一个内存位置,不管是哪个 指令使用该地址来访问该内存位置。
这意味着 RSP 的内容可以移动到通用寄存器(比如 R9)并且 使用 PUSH、POP(隐式使用 SS)和 MOV(隐式使用 DS)可以使用相同的地址访问相同的内存位置。
反之亦然。
拥有不同的段寄存器基数将需要为指针类型使用更多内存(以存储段和偏移量),并可能产生别名(有几个不同的位序列表示相同的内存位置)。
考虑一下:
void foo(int *ptr) {
*ptr = 0;
}
void bar() {
int x;
foo(&x);
}
int y;
void baz() {
foo(&y);
bar();
}
如果 SS 与 DS 不同,则两者之一(非详尽列表)
指针类型也应该包含段寄存器,或者
编译器在获取地址时应该执行一些地址转换 局部变量
这两者都会带来一些(时间或空间)开销。
【讨论】: