| [ CnUnix ] in KIDS 글 쓴 이(By): ddaeng (김 경 철) 날 짜 (Date): 1995년08월28일(월) 23시33분18초 KDT 제 목(Title): [re] 간단한 문제 > -------------------------------------------- > void > main(int ac, char **av) > { > char buf[10]; > char *ptr = buf + 2; > unsigned long lvar; > > lvar = *((long*)ptr); > > printf("%ld\n",lvar); > > } > -------------------------------------------- 아마 대부분의 risc 기계에서 위의 프로그램을 컴파일해서 돌리면, 특별한 컴파일러 옵션을 주지 않은이상 프로그램이 죽을겁니다. (적어도 sparc하고 hppa에서는요.) buf[2]..buf[5] 까지가 long으로 취급될꺼 같기는 한데. 실제로는 그게 그렇게 안되지요. long은 4 바이트 정수.. 인데, 대부분 4바이트 혹은 8바이트 정수는 그 기계의 특성에 따라, 어드레스가 모듈러 4 혹은 모듈러 8에 의해 나머지가 0이 되는 위치부터 시작하지 않으면 계산을 못하게 되어있 어요. align 되어 있느냐 아니냐 그 차이인데요.. 80x86계열은 align 되어 있지 않다 해도 하드웨어 적으로 두번 억세스를 해서 읽어 오도록 마이크로프로그램이 되어있는데, 리스크 칩 들은 그런걸 안해주지요. 복잡시럽고 불필요한거를 없애고 필요한거만 만들어 빨리 돌게 하자는게 리스크칩을 만든사람들의 철학이니까요. 그래서 그냥 위의 프로그램을 돌리면 죽을께 확실하고(bus error같은거로) 썬오에스 4.1.x의 cc의 경우 -misalign 옵션을 주면 되기야 되는데 비효율적으로 동작하는게 되지요. 4바이트 정수 하나 읽는데 두번 메모리 억세스를 해야 하니.. -misalign옵션을 주면 아에 라이브러리 루틴들이 원래의 거가 아닌 다른게 링크됩니다. 썬 같으면 /usr/lib/misalign.il, /usr/lib/misalign/*.o 이런것들이지요. 하드웨어가 두번 읽어오던것을 두 워드 따로따로 읽어서 쉬프트 시켜서 맞춰주는... 음. 예전에 뭐 포팅하다 보니, 똑같은것 가져다 썬오에스 4.1.3에서 하면 제대로 돌고, 4.1.2에서 하면 버스 에러로 죽고.. 그런일이 생기드라구요. 한번 따라가 봤더니, 그 패키지는 lex에서 만들어진 루틴을 이용하는데, 4.1.2에서 만들어진 lex.yy.c를 수행하다보면 위와같이 워드 얼라인이 되지 않은 char * 를 (int *)로 캐스팅 하는 부분이 있더군요. 그때는 디버거도 쓸수 없는 상황이라 어드레스 값을 전부다 프린트하게 해놓으면서 따라가다보니, 홀수 어드레스가 들어간 포인터 변수를 위의 프로그램처럼 캐스팅하는 경우가 생기드라구요. -- (김 경 철)Kim, Kyoung-chul ddaeng7@glory.kaist.ac.kr Computer System Lab. #1 +82-2-958-3385 Dept. of Infomation and Communication, KAIST, Seoul, Korea |