我正在查看一些编译器输出,当调用一个函数时,它通常会开始设置调用堆栈,如下所示:
PUSH EBP
MOV EBP, ESP
PUSH EDI
PUSH ESI
PUSH EBX
Run Code Online (Sandbox Code Playgroud)
因此,我们将调用例程的基指针保存在堆栈中,向上移动我们自己的基指针,然后将几个寄存器的内容存储在堆栈中.然后在例程结束时将它们恢复为原始值,如下所示:
LEA ESP, [EBP-0Ch]
POP EBX
POP ESI
POP EDI
POP EBP
RET
Run Code Online (Sandbox Code Playgroud)
到现在为止还挺好.但是,我注意到在一个例程中,设置调用堆栈的代码看起来有点不同.事实上,它看起来像这样:
IN AL, DX
PUSH EDI
PUSH ESI
PUSH EBX
Run Code Online (Sandbox Code Playgroud)
出于多种原因,这非常令人困惑.首先,方法结束代码与上面引用的另一种方法相同,特别是期望在堆栈上可以获得保存的EBP副本.
另一方面,如果我理解正确,该命令IN AL, DX读入AL寄存器,这与EAX寄存器相同,并且因为它发生了,这里的下一个命令是
XOR EAX, EAX
Run Code Online (Sandbox Code Playgroud)
因为程序想要将它在堆栈上分配的一些东西归零.
问题:我想知道这里到底发生了什么,我不明白.被翻译的机器代码IN AL, DX是单字节EC,而指令对PUSH EBP MOV EBP,ESP将对应于三个字节55 88 EC.反汇编程序是否以某种方式误读了这个?或者是依赖于我不理解的副作用的东西?
如果有人好奇,这个机器代码是由CLR的JIT编译器生成的,我正在用Visual Studio调试器查看它.这是C#中的最小再现:
class C {
string s = "";
public void f(string s) {
this.s = …Run Code Online (Sandbox Code Playgroud) I have a C++ program which I'd like to have output a certain text file at some point. Of course I could have it open, read, and output the text file, but then I have to keep the binary and the text file in sync and located together. I'd rather just compile the file in as a string in some part of my build process.
I've seen things like this done as parts of various IDEs. However I'm building from …
假设我有一个重载集,如下所示:
class C
{
public:
static void f(const A &);
static void f(const B &);
};
Run Code Online (Sandbox Code Playgroud)
我想做类似的事情
std::variant<A, B> v;
// ...
std::visit(C::f, v);
Run Code Online (Sandbox Code Playgroud)
但这不能编译。是否有某种方法可以获取重载集并将其视为或将其转换为访问者?
编辑:这个问题是基于GetType()返回一个字符串的误解.
我正在努力更好地处理C#的工作原理,所以这个问题更具理论性而非实际性.
据我了解,在值类型上调用GetType需要装箱,然后调用方法.但是由于值类型不能继承,但是类型在编译时是已知的,那么为什么编译器不能简单地用字符串文字替换对GetType()的调用?
或者这是可以完成的事情,但是认为没有必要,因为无论如何都不需要在未装箱的值类型上调用GetType?