2009-09-06 23 views
5

我一直在處理Nasm Linux環境一段時間,這個功能工作得很好......但現在我切換到Windows環境,我想用Masm(與VS2008)我不能似乎得到這個工作...轉換問題:__asm__ __volatile__

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是沒有更多的認可和揮發性拋出一個錯誤說「串」,我也嘗試過寫_asm易失性,但我得到一個錯誤說:「內聯彙編語法錯誤'操作碼';發現'數據類型'‘

回答

8

假設你正在談論的x86指令集,這裏有幾件事情要記住:

  1. 指令‘OUTB’輸出一個字節,這相當於輸入‘字符’或’無符號字符「在C/C + +。爲了輸出一個16位(因爲你使用的是「無符號短」),一個人需要使用「outw」
  2. 說了這一點,英特爾推薦你使用指令助記符「 out「,並且端口大小從操作數大小中識別。例如,「出DX,」將等同於「outw」,而「出DX,」等同於「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; 
} 
+1

此外,您也可以使用__asm {這裏說明}更清晰的語法,這可能是值得一提的,是內聯彙編不會在x64上工作,所以這個架構將不得不寫入asm cod e獨立代碼。 – 2009-09-06 12:31:43

+0

好吧,現在它有意義了一點,最少得到沒有錯誤..所以相當於inportb?我知道你寫的是「in」而不是「out」,可能會把ax改爲al?還是比這更復雜? – Fredrick 2009-09-06 12:42:51

+0

試試吧,它不應該受到傷害。請記住,VS使用{operation} {destination},{source}命令,因此讀取端口將是: __asm in al,dx; 然後您需要將結果存儲在您的變量中: __asm mov data,al; 並從函數中返回: 返回數據; – Rom 2009-09-06 12:53:32