2013-04-22 114 views
1

我正試圖在我目前正在使用的項目中使用行內彙編。該項目是關於從頭開始構建一個簡單的操作系統。使用行內彙編來更新內部系統寄存器

我已經做到了我開始編寫內核代碼和屏幕驅動程序的部分。

問題出在屏幕驅動程序,我認爲這正是代碼保存/檢索屏幕光標(閃爍的)進/出內部寄存器。

這是在我的代碼中使用內聯彙編的地方。

爲了正確測試它的功能,我已將內嵌程序集部分與屏幕驅動程序分開放置在一個單獨的文件中。

這裏是有test1.c:

# include <stdio.h> 

// scree device I/O ports 
# define REG_SCREEN_CTRL 0x3D4  
# define REG_SCREEN_DATA 0x3D5 

unsigned char port_byte_in (unsigned short port) { 

    // A handy C wrapper function that reads a byte from the specified port 
    // "= a " (result) means : put AL register in variable RESULT when finished 
    // " d " (port) means : load EDX with port 
    unsigned char result ; 
    __asm__ ("in %%dx, %%al" : "=a" (result) : "d" (port)); 
    return result ; 

} 

void port_byte_out (unsigned short port , unsigned char data) { 
    // " a " (data) means : load EAX with data 
    // " d " (port) means : load EDX with port 
    __asm__ ("out %%al, %%dx" : :"a" (data) , "d" (port)); 
} 

unsigned short port_word_in (unsigned short port) { 
    unsigned short result ; 
    __asm__ ("in %%dx, %%ax" : "=a" (result) : "d" (port)); 
    return result ; 
} 

void port_word_out (unsigned short port , unsigned short data) { 
    __asm__ ("out %%ax, %%dx" : :"a" (data) , "d" (port)); 
} 

void main(){ 
    int i = 10; 

    printf("%d\n",i); 
    port_byte_out (REG_SCREEN_CTRL , 14); 
    port_byte_out (REG_SCREEN_DATA , (unsigned char)(i >> 8)); 
    port_byte_out (REG_SCREEN_CTRL , 15); 


    port_byte_out (REG_SCREEN_CTRL , 14); 
    int j = port_byte_in (REG_SCREEN_DATA) << 8; 
    printf("%d\n",j); 
    port_byte_out (REG_SCREEN_CTRL , 15); 
    j += port_byte_in (REG_SCREEN_DATA); 
    printf("%d\n",j); 
} 

運行test.c的它給了我:

10 
Segmentation fault (core dumped) 

我期待一定的價值,而不是分割故障。

任何幫助將不勝感激,謝謝。

回答

1

INOUT說明有特權。通常不能在Linux中通過用戶空間可執行文件調用它們。

您可以使用ioperm()iopl()系統調用爲您的可執行文件提供直接訪問I/O端口的權限。請注意,這些系統調用都需要您的可執行文件以root身份運行。

+0

感謝您的回答,但實際上我在啓動我的簡單操作系統的範圍中使用此代碼它自己..意味着在這種情況下,我擁有所有特權,我需要對嗎? – hshihab 2013-04-22 19:45:49

+0

您發佈的錯誤消息('Segmentation fault(core dumped)')表明您在基於UNIX的操作系統(可能是Linux)下運行此代碼,而不是在您的自定義操作系統內運行。 – duskwuff 2013-04-22 19:48:49

+0

和我試圖使用iopl(0)作爲超級用戶運行,它只打印「10」,然後正常退出 – hshihab 2013-04-22 19:51:18

相關問題