2016-11-14 187 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; 
} 
相關問題