我正在使用MSVC 2015。
我试图按照here提供的答案,并将该计划改编为以下内容:
#include <iostream>
#include <limits>
inline unsigned long long query_intel_x86_eflags(const unsigned long long query_bit_mask)
{
return __readeflags() & query_bit_mask;
}
int main(int argc,char **argv)
{
int x = std::numeric_limits<int>::max();
int y = std::numeric_limits<int>::max();
int z = x * y;
//auto g{__readeflags() & 0x801}; // sees overflow and carry flags
auto g{query_intel_x86_eflags(0x801)}; // doesn't see overflow and carry flags
std::cout << std::hex << g << '\n';
}
问题是在读取query_intel_x86_eflags()
寄存器之前调用EFL
期间会重置eflags寄存器。
发出以下程序集,它包含一条重置sub
寄存器的EFL
指令。
inline unsigned long long query_intel_x86_eflags(const unsigned long long query_bit_mask)
{
00007FF6396D1BF0 48 89 4C 24 08 mov qword ptr [rsp+8],rcx
00007FF6396D1BF5 55 push rbp
00007FF6396D1BF6 57 push rdi
00007FF6396D1BF7 48 81 EC C8 00 00 00 sub rsp,0C8h // changes the flags
00007FF6396D1BFE 48 8B EC mov rbp,rsp
00007FF6396D1C01 48 8B FC mov rdi,rsp
00007FF6396D1C04 B9 32 00 00 00 mov ecx,32h
00007FF6396D1C09 B8 CC CC CC CC mov eax,0CCCCCCCCh
00007FF6396D1C0E F3 AB rep stos dword ptr [rdi]
00007FF6396D1C10 48 8B 8C 24 E8 00 00 00 mov rcx,qword ptr [rsp+0E8h]
return __readeflags() & query_bit_mask;
00007FF6396D1C18 48 9C pushfq
00007FF6396D1C1A 58 pop rax
00007FF6396D1C1B 48 23 85 E0 00 00 00 and rax,qword ptr [query_bit_mask]
}
为什么编译器会生成最终重置寄存器的附加指令?