我想在一个项目中使用内联汇编,我目前正在工作。这个项目是关于从头开始构建一个简单的操作系统。
我已经完成了开始编写内核代码和屏幕驱动程序的部分。
问题是在屏幕驱动程序中,我认为它正是在代码中保存/检索屏幕光标(闪烁的一个)进入/从内部寄存器。
这是我的代码中使用内联汇编的地方。
我将内联汇编部分与屏幕驱动程序分开放在一个单独的文件中,以便正确地测试它的功能。
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("%dn",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("%dn",j);
port_byte_out ( REG_SCREEN_CTRL , 15);
j += port_byte_in ( REG_SCREEN_DATA );
printf("%dn",j);
}
通过运行test.c得到:
10
Segmentation fault (core dumped)
我在等待某个值,而不是分割错误。
IN
和OUT
指令具有特权。在Linux中,通常不能从用户空间可执行文件中调用它们。
您可以使用ioperm()
或iopl()
系统调用来赋予可执行程序直接访问I/O端口的权利。请注意,这些系统调用都要求您的可执行文件以root身份运行。