6

Linux環境でNasmとGNUCインラインasmを扱ってきましたが、この機能はうまく機能しました...しかし、今はWindows環境に切り替えており、Masm(VS2008で)を使用したいのですが、取得できないようです。これが機能する...

void outportb (unsigned short _port, unsigned short _data)
{
  __asm__ __volatile__ ("outb %1, %0" : : "dN" (_port), "a" (_data));
}

私がこのようなものを書くとき...

void outportb (unsigned short _port, unsigned short _data)
{
  asm volatile ("outb %1, %0" : : "dN" (_port), "a" (_data));
}

asmが認識されなくなり、volatileが「string」というエラーをスローします。_asmvolatileを書き込もうとしましたが、「「opcode」にインラインアセンブラ構文エラーがあります。「datatype」が見つかりました」というエラーが表示されます。

4

1 に答える 1

8

x86コマンドセットについて話していると仮定すると、覚えておくべきことがいくつかあります。

  1. 命令「outb」は1バイトを出力します。これは、C /C++のタイプ「char」または「unsignedchar」に相当します。16ビット(「unsignedshort」を使用しているため)ワードを出力するには、「outw」を使用する必要があります。
  2. そうは言っても、Intelは(そしてVSが要求する)命令ニーモニック「out」を使用することを推奨しており、ポートサイズはオペランドサイズから認識されます。たとえば、「out dx、ax」は「outw」と同等であり、「out dx、al」は「outb」と同等です。
  3. x86では、「out」命令では、ポートと出力値をそれぞれ(e)dxレジスタと{eax / ax/al}レジスタに配置する必要があります。Nasmがあなたに代わってそれを行うかもしれませんが(私はコンパイラを手元に持っていないので、それを確認することはできません)、VSではCPUレベルで行われる方法でそれを行う必要があります。
  4. __asmで「volatile」キーワードを指定する理由はありません。インラインアセンブリ命令があると、VSコンパイラは読み取りキャッシュを無効にします(volatileキーワードの目的)

コードは次のとおりです(16ビットポートに書き込んでいると仮定します)。

void outportw(unsigned short port, unsigned short data)
{
    __asm  mov ax, data; 
    __asm  mov dx, port; 
    __asm  out dx, ax;
}

8ビットポートに書き込む場合、コードは次のようになります。

void outportb(unsigned short port, unsigned char data)
{
    __asm  mov al, data; 
    __asm  mov dx, port; 
    __asm  out dx, al;
}
于 2009-09-06T12:23:57.627 に答える