Error: variable-sized object may not be initialized?
Error: variable-sized object may not be initialized?
我正在为我的 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 [=11=], %eax" ); /* Moving 00 to EAX. */
__asm__ volatile( "int [=11=]x16 "); /*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];
scancode函数和getkey函数代码:
unsigned short scancodeget()
{
unsigned char ax = 0; /* int 0x16, AH=0 is get keystroke */
__asm__ __volatile__ ("int [=13=]x16\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 */
}
错误信息已经很清楚了。您不能初始化可变长度数组。改写
register int (ScanCode[strlen(ValEAX)-8]);
ScanCode[0] = 0x00;
或者您可以使用标准 C 函数 memset
,在 header <string.h>
中声明,将向量的所有元素设置为 0x00
。
例如
memset( ScanCode, 0x00, sizeof( ScanCode ) );
行
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;
}
很难说出您想要达到的目标。此例程 returns 从 BIOS interrupt 16h/AH=0h. It uses GCC extended assembler template using an input/output constraint 返回的原始扫描码将值为 0 的 AX 传递到汇编程序模板并检索 AX[ 中的值=31=] 之后。扫描码位于 ax
变量的高 8 位,因此我们将其右移 8 位。
#include <stdint.h>
uint8_t getchar_scancode()
{
uint16_t ax = 0; /* int 0x16, AH=0 is get keystroke */
__asm__ __volatile__ ("int [=10=]x16\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
并将uint8_t
替换为unsigned char
。
如果您需要将扫描码转换为 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 仅在实模式下有效。
我正在为我的 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 [=11=], %eax" ); /* Moving 00 to EAX. */
__asm__ volatile( "int [=11=]x16 "); /*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];
scancode函数和getkey函数代码:
unsigned short scancodeget()
{
unsigned char ax = 0; /* int 0x16, AH=0 is get keystroke */
__asm__ __volatile__ ("int [=13=]x16\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 */
}
错误信息已经很清楚了。您不能初始化可变长度数组。改写
register int (ScanCode[strlen(ValEAX)-8]);
ScanCode[0] = 0x00;
或者您可以使用标准 C 函数 memset
,在 header <string.h>
中声明,将向量的所有元素设置为 0x00
。
例如
memset( ScanCode, 0x00, sizeof( ScanCode ) );
行
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;
}
很难说出您想要达到的目标。此例程 returns 从 BIOS interrupt 16h/AH=0h. It uses GCC extended assembler template using an input/output constraint 返回的原始扫描码将值为 0 的 AX 传递到汇编程序模板并检索 AX[ 中的值=31=] 之后。扫描码位于 ax
变量的高 8 位,因此我们将其右移 8 位。
#include <stdint.h>
uint8_t getchar_scancode()
{
uint16_t ax = 0; /* int 0x16, AH=0 is get keystroke */
__asm__ __volatile__ ("int [=10=]x16\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
并将uint8_t
替换为unsigned char
。
如果您需要将扫描码转换为 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 仅在实模式下有效。