【问题标题】:Inline assembly, out instruction内联汇编,输出指令
【发布时间】:2012-08-03 13:44:17
【问题描述】:

我正在尝试导出 .dll 文件并尝试在我的 c# 应用程序中使用它来将数据写入端口。在我的 .cpp 文件(创建 .dll)中,如果我使用“out”命令,它会给出“错误 C2415:不正确的操作数类型”错误消息。你知道为什么我不能使用这个“out”命令吗? (顺便说一句,“mov”命令运行良好)

请参阅下面的代码:

#include <stdio.h>

extern "C" __declspec(dllexport) void enableWatchDog()
    _asm {
          out 66,41
          out 62,4
    }
}

【问题讨论】:

  • 平台是什么?视窗?如果是这样,您是否正在编写驱动程序?如果没有,out 将永远无法工作,您的程序只会强制关闭。
  • 如果你尝试在Windows下创建定时器,请看How to create timer in WinApi

标签: c++ assembly io x86


【解决方案1】:

您的 C++ dll 使用什么目标平台?您需要编译为 x86 代码,而不是 CLR。​​

【讨论】:

  • 错误“错误 C2415:不正确的操作数类型”显然是关于 out 指令,而不是 CLR 与本机代码。
【解决方案2】:

out有六种形式:

  • out imm8, AL
  • out imm8, AX
  • out imm8, EAX
  • out DX, AL
  • out DX, AX
  • out DX, EAX

您的用法与它们都不匹配。也许这会起作用(未经测试):

mov al, 41
out 66, al
mov al, 4
out 62, al

我对 x86 上的 IO 端口没有太多经验,但据我所知,66 和 62 对我来说似乎有点可疑。他们不应该是 66h 和 62h 吗? 41h(可能是设置了两个标志,或 ASCII 'A')对我来说也比 41(一个相当随意的数字)更有意义。

【讨论】:

    【解决方案3】:

    Assembly 不是高级语言,您可以在其中插入任意表达式。 out 命令只能将Ax 寄存器作为第二个操作数,其中 Ax 表示 AL、AX 或 EAX。所以像这样重新制定:

    mov al, 41
    out 66, al
    mov al, 4
    out 62, al
    

    out 命令是特权的;它仅适用于 Windows 的内核级驱动程序,尝试在常规程序中执行此操作会导致“无效操作”错误。

    【讨论】: