c++ 배열 문제입니다 조언 부탁드립니다
VGA 프로그래밍중에 이상한 현상을 발견했습니다
void View::InitPalette(void)
{
const unsigned char table_rgb[16 * 3 + 1] = {
0x00, 0x00, 0x00, /* 0:흑*/
0xff, 0x00, 0x00, /* 1:밝은빨강*/
0x00, 0xff, 0x00, /* 2:밝은초록*/
0xff, 0xff, 0x00, /* 3:밝은황색*/
0x00, 0x00, 0xff, /* 4:밝은파랑*/
0xff, 0x00, 0xff, /* 5:밝은보라색*/
0x00, 0xff, 0xff, /* 6:밝은물색*/
0xff, 0xff, 0xff, /* 7:흰색*/
0xc6, 0xc6, 0xc6, /* 8:밝은회색*/
0x84, 0x00, 0x00, /* 9:어두운빨강*/
0x00, 0x84, 0x00, /* 10:어두운초록*/
0x84, 0x84, 0x00, /* 11:어두운황색*/
0x00, 0x00, 0x84, /* 12:어두운파랑*/
0x84, 0x00, 0x84, /* 13:어두운보라색*/
0x00, 0x84, 0x84, /* 14:어두운물색*/
0x84, 0x84, 0x84 /* 15:어두운회색*/
};
SetPalette(0, 15, table_rgb);
return;
}
// 팔레트 설정
void View::SetPalette(int start, int end, const unsigned char *rgb)
{
int i = 0, eflags = 0;
eflags = io_load_eflags();
io_cli();
io_out8(0x03c8, 0);
for(i = start; i <= end; i++){
io_out8(0x03c9, rgb[i * 3]);
io_out8(0x03c9, rgb[i * 3 + 1]);
io_out8(0x03c9, rgb[i * 3 + 2]);
};
io_store_eflags(eflags);
return;
}
위와 같은 소스인데요 중요한건 InitPalette 에서 table_rgb 의 배열 크기 문제인데요
현재 os 만드는중이라 커널내부에 위와같은 소스를 넣고 팔레트를 초기화 시켰을때
table_rgb 의 배열 크기를 정확하게 16 * 3 으로 잡으면 vmware상에서 cpu 가 정지하더군요
반면에 16 * 3 +1 정도로 한개만 크게해줘도 잘 돌아갑니다.... 왜 그런지 궁금하네요
io_out8 에 문제가 있겠지요.. -- 대충
io_out8 에 문제가 있겠지요..
--
대충 추측컨데,
0x03c9 는 16비트니까,
&table_rgb[15*3+2] 번지에 16bit 데이터를 카피하면서
할당되지 않은 table_rgb[16*3] 영역을 건드렸을 듯..
io_out8 은
io_out8 은 포트번호로 데이터를 out 하기위한 어셈블리 함수입니다
_io_out8:
mov edx, [esp+4] ; port
mov al, [esp+8] ; data
out dx, al
ret
port 4바이트, 데이터 4바이트 이며
이대로라면 unsigned char 로 설정된 rgb table 도 4바이트로 맞아떨어지지 않을런지... 틀릴게 없는데 ㅠ
io_out8(int port, int
io_out8(int port, int data);
data 타입이 정수인데, 바이트 데이타를 그대로 넣어 버리면 al 에 원하는 값이 들어가지 않습니다.
4로 나누어서 넣으세요.
io_out8(0x03c9, rgb[i * 3] / 4);
하지만 어느 경우나 마지막 루프에서 배열 바깥의 데이타를 건드리게 되니 문제가 있네요.
주제에 벗어나지만 혹시나 해서 링크 달아 봅니다.
주제에 벗어나지만 소스나 너무 유사해서 링크를 달아 봅니다.
윗글을 보니깐 "io_out8" 함수 선언을 추적하면 단서가 있겠다 해서 검색해 보다 찾은 사이트입니다.
-----인용-------
void io_out8(int port, int data);
---------------------
http://code.google.com/p/etcos/source/browse/branches/floppy/img/bootpack.c?spec=svn30&r=30
네 위 코드는
클래스만 제가 따로 만든것이고 내용은 OS제작 서적을 참고한 것입니다...
특별한건 없는 함수입니다
얼라인먼트 오류..
alignment error가 원인이 아닐까 생각 됩니다.
특히 임베디드 프로그래밍시에 자주 겪게되는 오류인데요.
특정 주소에서 2바이트 이상의 데이터 타입을 패치 해오거나 할 때 생길 수 있습니다.
프로세서가 데이터를 fetch해 올때 32비트 프로세서는 4바이트 단위로 접근하게 되는데,
읽어 오려는 주소가 4바이트 단위에 정렬되어 있지 않은 상태에서 2바이트 이상의 읽기 접근을 시도하면
프로세서가 죽어 버리는 현상이 발생하기도 합니다.
struct에서 데이터를 선언하거나 함수 내에 로컬 변수들을 선언했을 때 이를 메모리 상태에서 보면
1바이트, 2바이트 데이터 타입이더라도 메모리 상에는 4바이트 단위로 위치해 있고, 빈 공간은 padding(채워넣기)
되어 있는 것을 발견 할 수 있습니다. - 이렇게 선언하는 것이 메모리 낭비인것 같지만 잘 생각해보면 동작 속도를
높이는데 더 큰 효과를 발휘 할 수 있습니다.
질문하신 배열을 보면 3바이트 단위로 접근을 하셔야 하는 것 같은데, 이 때 4바이트 읽기 접근을 해서 오류가
나는 것으로 판단이 됩니다. 3바이트 rgb데이터 선언후 null값의 char형을 하나씩 더 선언하시던지, 주소 접근시
int가 아닌 char단위로 하시는 것이 문제 해결에 도움이 될 것 같습니다.
댓글 달기