2016-11-14 94 views
1

我想提出一个键盘驱动程序我的OSDev OS和我在我的kbd.c一个问题:错误:可变大小的对象可能未被初始化?

kbd.c: In function 'scancoderec': 
kbd.c:56:2: error: variable-sized object may not be initialized 
register int (ScanCode[strlen(ValEAX)-8]) = 0x00; /* Remove last 8 bits from the value we gathered from EAX to get AH and make that the scancode. */ 

这里是包含的代码失败行的功能:

int scancoderec() { 
    __asm__ volatile("movl $0, %eax"); /* Moving 00 to EAX. */ 
    __asm__ volatile("int $0x16 "); /*int 0x16 */ 
    register int ValEAX asm("eax"); /* Let's get eax */ 
    register int (ScanCode[strlen(ValEAX)-8]) = 0x00; /* Remove last 8 bits from the value we gathered from EAX to get AH and make that the scancode. */ 
} 

为什么这是否发生?

编辑:我仍然有这个“ax”是未定义的,这次,在另一个函数中。

kbd.c:65:27: error: 'ax' undeclared (first use in this function) 
register int Key = kbdus[ax]; 

扫描码功能和信息getKey功能的代码:

unsigned short scancodeget() 
    { 
     unsigned char ax = 0; /* int 0x16, AH=0 is get keystroke */ 
     __asm__ __volatile__ ("int $0x16\n\t" 
          : "+a"(ax)); 
     ax = ax >> 8;  /* Shift top 8 bits of ax to lower 8 bits */ 
         /* ax now is the scancode returned by BIOS */ 
     return (unsigned short)ax; /* Return the lower 8 bits */ 
} 

int getkey() { /*This could be used as a keyboard driver. */ 
     scancoderec(); /*Get our scancode! */ 
     int Key = kbdus[ax]; /*Use our kbdus array which i copied from a website since i seriously don't want to make an gigantic array */ 
} 
+1

编译器认为你正在声明一个名为'ScanCode'的数组。坦率地说,我不知道你要在代码中做什么。 – user3386109

+0

评论说:“从值中删除最后8位...” - >看起来像“删除最后8个字节...” – chux

+0

嗯,如果'strlen(ValEAX)<= 8',代码肯定会有麻烦。 – chux

回答

1

很难说出您要实现的目标。此例程返回从BIOS interrupt 16h/AH=0h返回的原始扫描代码。它使用GCC extended assembler template使用input/output constraint将值为0的AX传递到汇编程序模板,并在之后检索AX中的值。扫描码位于ax变量的高8位,因此我们将其右移8位。

#include <stdint.h> 
uint8_t getchar_scancode() 
{ 
    uint16_t ax = 0; /* int 0x16, AH=0 is get keystroke */ 
    __asm__ __volatile__ ("int $0x16\n\t" 
         : "+a"(ax)); 
         /* +a is an input and output constraint using EAX register */ 
         /* The contents of the 'ax' variable will be transferred */ 
         /* into EAX register upon entry, and the value of EAX register */ 
         /* will be transferred into variable 'ax' when finished */ 
    ax = ax >> 8;  /* Shift top 8 bits of ax to lower 8 bits */ 
         /* ax now is the scancode returned by BIOS */ 
    return (uint8_t)ax; /* Return the lower 8 bits */ 
} 

如果没有stdint.h也可用来定义uint16_t你可以用unsigned short取代它与unsigned char取代uint8_t

如果您需要扫描码转换为可以使用的附加功能,以提供该功能的ASCII字符:

unsigned char kbdus[128] = 
{ 
    0, 27, '1', '2', '3', '4', '5', '6', '7', '8', /* 9 */ 
    '9', '0', '-', '=', '\b',       /* Backspace */ 
    '\t',            /* Tab */ 
    'q', 'w', 'e', 'r',        /* 19 */ 
    't', 'y', 'u', 'i', 'o', 'p', '[', ']', '\n',  /* Enter key */ 
    0,            /* 29 - Control */ 
    'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', /* 39 */ 
    '\'', '`', 0,         /* Left shift */ 
    '\\', 'z', 'x', 'c', 'v', 'b', 'n',    /* 49 */ 
    'm', ',', '.', '/', 0,       /* Right shift */ 
    '*', 
    0,            /* Alt */ 
    ' ',            /* Space bar */ 
    0,            /* Caps lock */ 
    0,            /* 59 - F1 key ... > */ 
    0, 0, 0, 0, 0, 0, 0, 0, 
    0,            /* < ... F10 */ 
    0,            /* 69 - Num lock*/ 
    0,            /* Scroll Lock */ 
    0,            /* Home key */ 
    0,            /* Up Arrow */ 
    0,            /* Page Up */ 
    '-', 
    0,            /* Left Arrow */ 
    0, 
    0,            /* Right Arrow */ 
    '+', 
    0,            /* 79 - End key*/ 
    0,            /* Down Arrow */ 
    0,            /* Page Down */ 
    0,            /* Insert Key */ 
    0,            /* Delete Key */ 
    0, 0, 0, 
    0,            /* F11 Key */ 
    0,            /* F12 Key */ 
    0, /* All other keys are undefined */ 
}; 

uint8_t getchar() 
{ 
    return (kbdus[getchar_scancode()]); 
} 

BIOS中断不会在保护模式下运行,并可能会故障的机器。 INT 16h/AH = 0仅适用于实模式。

+0

我的确有uint16_t/uint8_t。谢谢您的回答。 – KC104

+0

但我如何使用像'int Key = kbdus [ax]'这样的东西来制作一个键呢?它给了我没有定义的ax,即使它在相同的函数中调用getchar_scancode();. – KC104

+0

'ax'是一个像任何其他变量名称。你应该能够像'int key = kbdus [getchar_scancode()]'做一些事情,或者做'uint8_t scancode = getchar_scancode(); int key = kbdus [scancode];' –

1

错误消息是清楚。您不可以初始化一个可变长度数组。写,而不是

register int (ScanCode[strlen(ValEAX)-8]); 
ScanCode[0] = 0x00; 

或者你可以使用标准的C函数memset,在头<string.h>宣布向量的所有元素设置为0x00

例如

memset(ScanCode, 0x00, sizeof(ScanCode)); 
0

线

register int (ScanCode[strlen(ValEAX)-8]) = 0x00; 

声明一个VLA和试图初始化它,这是不允许的。将其更改为:

// Declare 
int size = strlen(ValEAX)-8 
register int ScanCode[size]; 

// Set values. 
for (int i = 0; i < size; ++i) 
{ 
    ScanCode[i] = 0x00; 
} 
相关问题