gpt4 book ai didi

visual-studio - 编译器在设置调用堆栈时生成了意外的 `IN AL, DX`(操作码 `EC`)

转载 作者:行者123 更新时间:2023-12-04 23:39:31 24 4
gpt4 key购买 nike

我正在查看一些编译器输出,当一个函数被调用时,它通常会像这样开始设置调用堆栈:

PUSH EBP
MOV EBP, ESP
PUSH EDI
PUSH ESI
PUSH EBX

所以我们将调用例程的基指针保存在栈上,将自己的基指针上移,然后将几个寄存器的内容存入栈中。然后在例程结束时将它们恢复为原始值,如下所示:
LEA ESP, [EBP-0Ch]
POP EBX
POP ESI
POP EDI
POP EBP
RET

到现在为止还挺好。但是,我注意到在一个例程中,设置调用堆栈的代码看起来有些不同。事实上,它看起来像这样:
IN AL, DX
PUSH EDI
PUSH ESI
PUSH EBX

由于多种原因,这非常令人困惑。一方面,方法结束代码与上面引用的另一种方法的代码相同,特别是似乎期望 EBP 的保存副本在堆栈中可用。

另一方面,如果我正确理解命令 IN AL, DX读入 AL寄存器,与 EAX 相同注册,当它发生时,这里的下一个命令是
XOR EAX, EAX

因为程序想要将它在堆栈上分配的一些东西归零。

问题:我想知道这里到底发生了什么,我不明白。机器码被翻译为 IN AL, DX是单字节 EC , 而这对指令
推EBP
MOV EBP、ESP
将对应三个字节 55 88 EC .反汇编器是否以某种方式误读了这个?还是依赖于我不明白的副作用?

如果有人好奇,这个机器代码是由 CLR 的 JIT 编译器生成的,我正在使用 Visual Studio 调试器查看它。这是 C# 中的最小复制:
class C {
string s = "";
public void f(string s) {
this.s = s;
}
}

然而 ,请注意,这似乎是不确定的;有时我似乎得到了 IN AL, DX版本,而其他时候有 PUSH EBP后跟一个 MOV EBP, ESP .

编辑 :我开始强烈怀疑一个反汇编程序错误——我刚刚遇到另一种情况,它显示 IN AL, DX (操作码 EC)和内存中的前两个字节是 55 88 .所以也许反汇编器只是对方法的入口点感到困惑。 (虽然我仍然想知道为什么会发生这种情况!)

最佳答案

听起来您正在使用 VS2015。你的结论是正确的,它的调试引擎有很多错误。是的,地址错误。不是唯一的问题,它不能正确恢复断点,您很容易看到代码中仍然存在 INT3 指令。当抖动重新生成代码并替换 stub 调用时,它无法正确刷新反汇编。你不能相信你看到的任何东西。

我建议您使用工具 > 选项 > 调试 > 常规并勾选“使用托管兼容模式”复选框。这迫使调试器使用较旧的调试引擎 VS2010 Vintage。它要稳定得多。

您将失去此引擎的一些功能,例如返回值检查和 64 位编辑+继续。做这种调试时不会错过。但是,您将看到假代码地址,这在以前很常见,因此所有 CALL 地址都是错误的,您无法轻松识别对 CLR 的调用。来回翻转引擎是一种解决方法,但当然是一个很大的烦恼。

这也没有得到解决,我在更新中没有看到任何改进。但毫无疑问,他们有一个很大的错误列表需要处理,VS2015 在完成之前就发布了。希望 VS2017 更好,我们很快就会发现。

关于visual-studio - 编译器在设置调用堆栈时生成了意外的 `IN AL, DX`(操作码 `EC`),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42308113/

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