gpt4 book ai didi

assembly - x86 eflags 位 18(对齐检查)如何工作? (与检查 386 与 486 及更高版本相关。)

转载 作者:行者123 更新时间:2023-12-02 19:16:17 41 4
gpt4 key购买 nike

我读到,如果可以修改 eflags 位 18(AC - 对齐检查),您就知道 CPU 是 486 或更新版本。在 386 上,该位无法修改。

我从 this site 中提取了以下汇编代码并添加了详尽的注释(保留奇怪的语法完整):

asm
mov bx,sx ; Save the stack pointer to bx (is sx a typo or a real register?).
and sp,$fffc ; Truncate the stack pointer to a 4-byte boundary.
pushfl ; Push the eflags register to the stack.
pop eax ; Pop it into eax.
mov ecx,eax ; Save the original eflags value into ecx.
xor eax,$40000 ; Flip bit 18 in eax.
push eax ; Push eax to the stack.
popfl ; Pop modified value into eflags.
pushfl ; Push eflags back onto the stack.
pop eax ; Pop it into eax.
xor eax,ecx ; Get changed bits from the original value.
setz al ; Set al register to 1 if no bits changed (0 otherwise).
and sp,$fffc ; Truncate the stack pointer to a 4-byte boundary.
push ecx ; Push ecx (original eflags) to stack.
popfl ; Pop it into eflags to restore the original value.
mov sp,bx ; Restore the original stack pointer.
end ['eax','ebx','ecx'];

如果 al 寄存器最后设置为 1(假设从一开始它并不旧),则 CPU 是 386,否则是 486 或更新版本。我理解这部分。

我不明白的是,为什么在进行标志修改测试之前必须将堆栈指针截断到4字节边界?我假设它是为了设置位 18,因为它毕竟是对齐位...但是与 0x40000 的异或将翻转该位,无论其值如何。换句话说,无论初始值如何,修改测试都应该得到相同的结果,对吧?

如果答案是否定的,我对“为什么”的最佳[未受过教育的]猜测是,“也许下面的入栈/出栈指令可以强制对齐?这将对齐之前未对齐的堆栈指针并导致对齐位从0到1本身。这样的话,修改成功就会显得不成功,反之亦然。” (编辑:这绝对是不正确的,因为对齐位是关于强制而不是跟踪对齐。另外,我怀疑 pop/push 无论如何都会在以前未对齐的堆栈上强制对齐。)

即使是这种情况,测试后再次对齐堆栈指针(在恢复原始 eflags 和堆栈指针之前)的目的是什么?之前不应该已经在 4 字节边界上了吗?如果不是,那么推送/弹出 4 字节值会如何改变?

总之,有些说明对我来说似乎是多余的,我觉得我一定错过了一些重要的东西。有谁能解释一下吗?

(附带问题:第一行将“sx”中的值复制到 bx 中。我从未在任何地方看到过对 sx 寄存器的引用。它确实存在,还是拼写错误?“x”键离“p”键很远,至少在美国键盘上是这样。)

编辑:现在这个问题已经得到解答,我决定从代码中的两个对齐行中删除不正确的注释。我最初假设对齐堆栈会设置对齐位,并将其写入我的评论中(问题的其余部分继续使用这个不正确的逻辑)。相反,对齐检查位实际上是关于强制对齐(而不是跟踪它),正如 flolo 关于 sigbus 的回答所表明的那样。我决定修复评论以避免让有类似问题的人感到困惑。

最佳答案

我的猜测很简单:代码不想使用 sigbus。如果未设置检查对齐,而您设置了它,则实际上启用了对齐检查(当设置它有效时)。当堆栈指针未与 4 字节边界对齐时,猜猜会发生什么?您进行了未对齐的内存访问,这会导致 sigbus。如果您不想让无效的内存访问发生(因为您只想更改位以进行测试),则必须注意测试时的所有访问都假设最坏的情况(即:您已启用它,并且您的堆栈在未对齐之前,因为它不需要,因为到目前为止检查已被禁用)。

关于assembly - x86 eflags 位 18(对齐检查)如何工作? (与检查 386 与 486 及更高版本相关。),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7531308/

41 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com