0.段寄存器属
注意:我使用vs2019调试出现了许多奇奇怪怪的错误,如果你出现了与我同样的情况,请打开xp虚拟机中的vc6进行调试(如果是C++工程请不要包含任何C++头文件)
首先,段寄存器是96位的
GS寄存器 当中断执行完成之后会被置零,windows并没有使用这个寄存器
1.论证Attribute位的存在
执行下面的代码,因为ss寄存器中的attribute属性是可读可写的,所以可以顺利执行
int var = 0;
int main() {
_asm {
mov ax, ss
mov ds, ax //将ds寄存器的值修改为ss寄存器的值
mov dword ptr ds:[var], eax
}
return 0;
}
执行结果
修改部分代码,重新执行,会出错
int var = 0;
int main() {
_asm {
mov ax, cs //将ss修改为cs
mov ds, ax
mov dword ptr ds:[var], eax
}
return 0;
}
至此证明了段寄存器的attribute限制了我们写入这个地址
2.证明base的存在
众所周知,向 0 (NULL)地址写入是会报错的(NULL 是 C 中定义的宏)
所以设计如下代码
int main() {
__asm {
mov ax, fs
mov es, ax
mov eax, dword ptr es:[0]
}
return 0;
}
这个代码是能正常运行的,查上表得知,原来我们访问的地址是 gs.base + 0 = 0x7FFDE000
这个代码不能执行到结束,因为es的值被改掉了,下一次用到es寄存器的时候是会出错的
3.验证Limit存在
下面这段代码会会在mov eax, dword ptr gs:[1000]
执行出错
int main() {
__asm {
mov ax, fs
mov gs, ax
mov eax, dword ptr gs:[0x1000] //如果将这个数改成0x0 - 0x999就不会出错
}
}
都看到这里了,不如把代码复制下来,自己调试试试,加深印象,千万别做个代码观察师哦