使用内联汇编更新内部系统寄存器

时间:2013-04-22 19:31:11

标签: c inline-assembly

我想在我正在进行的项目中使用内联汇编。该项目是关于从头开始构建一个简单的操作系统。

我已经开始编写内核代码和屏幕驱动程序。

问题在于屏幕驱动程序,我认为它正好在代码中,它将屏幕光标(闪烁的光标)保存/检索到内部寄存器中。

这是我的代码中使用内联汇编的地方。

我已将内联汇编部分与屏幕驱动程序分开放在一个单独的文件中,以便正确测试其功能。

这是test.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 个答案:

答案 0 :(得分:1)

INOUT指令具有特权。通常,您无法从Linux中的用户空间可执行文件中调用它们。

您可以使用ioperm()iopl()系统调用为您的可执行文件提供直接访问I / O端口的权限。请注意,这些系统调用都要求您的可执行文件以root身份运行。