为什么GCC不编译这段代码? [英] Why doesn't GCC compile this code?

查看:221
本文介绍了为什么GCC不编译这段代码?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是一个Java,Python程序员试图用C ++搞砸。我有以下代码片段 -

I am a Java, Python programmer trying to fiddle with C++. I have following code snippet -

#include <windows.h>

bool IsInsideVMWare()
{
  bool rc = true;

  __try
  {
    __asm
    {
      push   edx
      push   ecx
      push   ebx

      mov    eax, 'VMXh'
      mov    ebx, 0 // any value but not the MAGIC VALUE
      mov    ecx, 10 // get VMWare version
      mov    edx, 'VX' // port number

      in     eax, dx // read port
                     // on return EAX returns the VERSION
      cmp    ebx, 'VMXh' // is it a reply from VMWare?
      setz   [rc] // set return value

      pop    ebx
      pop    ecx
      pop    edx
    }
  }
  __except(EXCEPTION_EXECUTE_HANDLER)
  {
    rc = false;
  }

  return rc;
}

我得到以下编译错误 -

I am getting following compile error -


__ try'undeclared(首先使用此函数)
__ except'undeclared p>

__try' undeclared (first use this function) __except' undeclared (first use this function)

这个模糊消息是什么意思?因为try是undeclared我应该尝试使用它第一??

What does that vague message even mean? Because try is undeclared I should try to use it first??

编辑

IDE - Codeblocks

IDE - Codeblocks

编译器 - GCC

推荐答案

此代码RELIES关于Microsoft的 __ try __ except 的特定功能。没有其他方法来解决这个问题,因为从Windows中的用户模式进程执行 IN 指令通常会失败。在VMWare中,任何此类操作都由VMWare VMM(虚拟机监视器,有时也称为管理程序)拦截。然后它检查一些寄存器中的特殊值,并在 ebx 中用新值接受指令,以指示是的,我是VMWare系统。如果你在一个普通的老的Windows系统上运行它,它会得到一个通用保护故障,试图使用一个IO端口不可用的应用程序[一般来说,IO端口不可用于用户模式应用程序码]。

This code RELIES on the Microsoft specific functionality of __try and __except. There is no other way to solve this, as doing an IN instruction from a user-mode process in Windows will normally fail. In VMWare, any such operation is intercepted by the VMWare VMM (Virtual Machine Monitor, sometimes also called Hypervisor). It then checks the special values in some registers and "accepts" the instruction with a new value in ebx to indicate that "Yes, I'm a VMWare system". If you run this on a plain old Windows system, it will get an General Protection Fault for trying to use a IO-port that isn't available to the application [in general, IO ports aren't availbe to the user-mode application code].

您需要使用Microsoft编译器编译(并使用适当的启用异常处理标志设置 - 对不起,不记得该标志是什么,会告诉你,如果它不是在它的错误)。 GCC不支持此功能。

You need to compile this using a Microsoft compiler (and with the suitable "enable exception handling" flag set - sorry, can't remember what that flag is, but it will tell you if it's not on that it's wrong). GCC doesn't support this feature.

但是,您可以使用CPUID指令而不是使用 IN 来测试VMWare。这将在一个GCC编译器工作得更好,因为它不会错误的处理器,如果没有VM存在[对于脚本:只要处理器比一些版本的486从20世纪90年代]。相反,它将不会在寄存器中给出正确的值(不改变寄存器值)。你可能需要写一个 cpuid 内联汇编函数,但这不应该太难google上来。

However, you can test for VMWare using the CPUID instruction instead of using IN. This will work much better in a GCC compiler, as it will not fault the processor if there is no VM present [For the pedants: As long as the processor is later than some version of 486 from the 1990's]. Instead, it will just not give the right values in the registers (no change to the register values). You may need to write a cpuid inline assembler function, but that shouldn't be too difficult to google up.

请参阅VMwares网站上的这篇KB文章:
http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=1009458 < a>

See this KB-article on VMwares site: http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=1009458

或者,如果你真的坚持使用Windows结构化异常处理,你可以自己做:

Alternatively, if you really insist on using Windows Structured exception handling, you can do it yourself:

   push handler   // Save address of your handler. 
   push fs:[0]    // Save address of any previous handler
   mov  fs:[0], esp    // Save pointer to current exception record. 

   ...    // all the stuff setting registers, doing IN, etc. 

   jmp  cleanup

handler:
   mov  [rc], 0       // Set "rc= false". 

cleanup:
   pop  fs:[0]
   add  esp, 4   // Remove handler

(注意,我刚刚写了一个从谷歌搜索 - 这是一个长时间,因为我在Windows上使用任何东西,所以它可能不工作)

(Note, I just wrote that from a bit of googling - it's a LONG time since I used anything like that on Windows, so it may not work)

这篇关于为什么GCC不编译这段代码?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆