c++ 배열 문제입니다 조언 부탁드립니다

kws4679의 이미지

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 에 문제가 있겠지요..

--

대충 추측컨데,
0x03c9 는 16비트니까,
&table_rgb[15*3+2] 번지에 16bit 데이터를 카피하면서
할당되지 않은 table_rgb[16*3] 영역을 건드렸을 듯..

kws4679의 이미지

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바이트로 맞아떨어지지 않을런지... 틀릴게 없는데 ㅠ

ifree의 이미지

io_out8(int port, int data);
data 타입이 정수인데, 바이트 데이타를 그대로 넣어 버리면 al 에 원하는 값이 들어가지 않습니다.
4로 나누어서 넣으세요.

io_out8(0x03c9, rgb[i * 3] / 4);

하지만 어느 경우나 마지막 루프에서 배열 바깥의 데이타를 건드리게 되니 문제가 있네요.

emptynote의 이미지

주제에 벗어나지만 소스나 너무 유사해서 링크를 달아 봅니다.

윗글을 보니깐 "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

kws4679의 이미지

클래스만 제가 따로 만든것이고 내용은 OS제작 서적을 참고한 것입니다...

특별한건 없는 함수입니다

irondog의 이미지

alignment error가 원인이 아닐까 생각 됩니다.
특히 임베디드 프로그래밍시에 자주 겪게되는 오류인데요.
특정 주소에서 2바이트 이상의 데이터 타입을 패치 해오거나 할 때 생길 수 있습니다.

프로세서가 데이터를 fetch해 올때 32비트 프로세서는 4바이트 단위로 접근하게 되는데,
읽어 오려는 주소가 4바이트 단위에 정렬되어 있지 않은 상태에서 2바이트 이상의 읽기 접근을 시도하면
프로세서가 죽어 버리는 현상이 발생하기도 합니다.

struct에서 데이터를 선언하거나 함수 내에 로컬 변수들을 선언했을 때 이를 메모리 상태에서 보면
1바이트, 2바이트 데이터 타입이더라도 메모리 상에는 4바이트 단위로 위치해 있고, 빈 공간은 padding(채워넣기)
되어 있는 것을 발견 할 수 있습니다. - 이렇게 선언하는 것이 메모리 낭비인것 같지만 잘 생각해보면 동작 속도를
높이는데 더 큰 효과를 발휘 할 수 있습니다.

질문하신 배열을 보면 3바이트 단위로 접근을 하셔야 하는 것 같은데, 이 때 4바이트 읽기 접근을 해서 오류가
나는 것으로 판단이 됩니다. 3바이트 rgb데이터 선언후 null값의 char형을 하나씩 더 선언하시던지, 주소 접근시
int가 아닌 char단위로 하시는 것이 문제 해결에 도움이 될 것 같습니다.

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.