2바이트 이상의 문자를 문자를 저장하기 위해 wchar_t 변수를 사용한다.
물론 char * 로 저장할수도 있다.

wchar_t 는 typedef unsigned long (리눅스) 혹은 short(윈도우) 형이다.

리눅스에서는 4바이트이고 윈도우에서는 2바이트이다.

왜 wchar_t 를 사용하는가?

만약 char * 형으로 문자열(UTF-8 방식)을 저장한다고 하면,
"가" 란 글자는 EA B0 80 (16진수) 형태로 저장된다.
즉,
char *pHangul = "가"; 라고 선언하면,
pHangul[0] -> 0xEA;
pHangul[1] -> 0xB0;
pHangul[2] -> 0x80;

가 저장된다.

이 상태에서 만약 알파벳과 한글을 혼용하면, 영어는 1바이트 한글은 3바이트 이므로, 한글과 영어를 구분하여 사용하기가 상당히 난해한 상황이 온다.
일일이 최상위 비트를 검사해서 '1' 인지 확인한후 '1' 이면 뒤에 2바이트를 더 읽어들이는 작업을 해야 한다.
잘못 계산하면 3바이트중 엉뚱한 곳부터 시작하게 되면 엉뚱한 결과가 나오게 된다.

wchar_t 를 사용하면 한글과 영어에 상관없이 wchar_t 하나당 하나의 문자가 저장된다.
예를 들어 wchar_t *pw = L"ab가나"; 라고 하면 
pw[0] -> 'a';
pw[1] -> 'b';
pw[2] -> '가';
pw[3] -> '나';

이런식으로 저장이 된다. 그러므로 굳이 최상위 비트를 비교하지 않아도 된다.

char * 이런식으로 저장되는 형식을 Multi Byte String 이라고 하며
wchar_t 에 저장되는 형식을 Wide Character String 이라고 한다.

wchar_t 사용하기

wchar_t 는 일반적으로 유니코드 형식으로 저장된다.
문자열을 대입하기 위해서는 접두어 "L" 을 붙여준다.

wchar_t *str = L"한글";

이런식으로 사용한다.

wchar_t 를 다루는 표준함수가 있다.

기본적으로 C 의 char * 문자 관리 함수와 같다. 대신 str 대신 wcs 를 적어주면 된다.
strlen -> wcslen
strcpy -> wcscpy
...

wchar_t 를 출력하기위해서는 wprintf 또는 fputws 함수를 사용하면 된다.

리눅스에서는 wprintf 를 사용하면 printf 와 같이 사용할 수 없다.

wchar_t 와 char 변환

만약 소켓통신을 한다고 할때,
테이터를 wchar_t 로 받는 것보다 char * 로 받아서 형변환을 해주는게 손쉬울 것이다.
데이터를 전송할때도 wchar_t 를 char * 로 바꿔서 전송해주는것이 호환성을 위해 좋을 것이다.
(프로그램간에 프로토콜이 정해져 있으면, wchar_t 든 char 든 크게 상관은 없다.)

wchar_t 를 char 로 변환하려면 함수를 사용하면 된다.
char 를 wchar_t 로 변환하려면 mbstowcs 함수를 사용하면 된다.


리눅스 GCC vs VC++

리눅스에서 wchar_t 를 wprintf 로 출력하기 위해서는 몇가지 세팅이 필요하다.
리눅스에서는 여러가지 한글 인코딩을 사용할 수 있는데, 여기서는 utf8 을 기준으로 설명하도록 하겠다.

리눅스 콘솔 세팅이 UTF-8 로 되어 있는지 확인한다.
그리고 LANG 환경변수가 ko_KR.utf8 로 되어 있는지 확인한다.
ko_KR.eucKR 로 되어 있다면 ko_KR.utf8 로 바꿔준다.
바꾸게 되면 한글로 된 것들이 깨져 보일수 있다.
(어디까지나 UTF-8 테스트용이므로 그냥 넘어가도록 한다.)

그리고 wprintf(L"한글"); 을 이용해서 제대로 출력되는지 확인해 본다.
만약 제대로 나오지 않는다면,
setlocale(LC_ALL,"ko_KR.utf8); 을 추가해 준다.

VC++ 에서는 이상하게 wchar_t 로 선언된 "가나다" 란 문자열을 wcslen 으로 보면 길이가 6으로 나온다.

길이가 3으로 나오게 하려면
setlocale(LC_ALL,".949");
를 추가해 준다.

참고자료
[1] UTF-8  http://ko.wikipedia.org/wiki/UTF-8
[2] wchar_t http://www.killrain.net/channel/lab/?subject=C%2B%2B%EC%9D%98+%EB%8B%A4%EC%96%91%ED%95%9C+string+%ED%83%80%EC%9E%85&mode=view
[3] wprintf http://kldp.org/node/79934

0. Eclipse 설치

www.eclipse.org  에서 Eclipse IDE for Java Developers (92 MB) 를 다운받는다.

현재 버전은 3.4 이지만, 설명은 3.3 버전에서 하도록 하겠다.

1. SWT 설치
SWT(Standart Widget Toolkit) 은
http://www.eclipse.org/swt/ 여기서 다운받는다.
이것을 쓰는 이유는 Eclipse SWT GUI Plugins 가 마음에 들어서이다. 다른 이유는 없다.
http://www.eclipse.org/downloads/download.php?file=/eclipse/downloads/drops/R-3.4.2-200902111700/swt-3.4.2-win32-win32-x86.zip

설치법은 http://www.eclipse.org/swt/eclipse.php 여기에 나와있다.
 

2. SWT GUI Plugins 설치
Jigloo 라는 free swt gui plugins 가 있지만, 사용이 어려워서 WindowBuilder Pro 를 사용하도록 하겠다. 이것은 상용제품이다.

3. Fat Jar 설치
SWT 로 만든 프로그램을 jar 로 export 하기 위해 fat jar 이라는 플러그인을 사용한다.
[File] - [Export] 명령으로 해도 되지만 swt 로 만들면 이상하게 could not find main 이라는 에러 메세지가 뜬다.
http://fjep.sourceforge.net 
여기서 설치한다.

4. Project 생성
Eclipse 를 실행한다.
[File] - [New] - [Other ...] 를 선택


[Designer] - [SWT/JFace Java Project] 선택
*WindowBuilder Pro 가 설치되어야지 이 항목이 있다.
Project Name 입력 한다음 Finish

5. SWT Import
SWT 를 사용하려면 Import 를 해줘야 한다.
이 내용은  http://www.eclipse.org/swt/eclipse.php 나와있다.


6. 파일생성
우클릭 [New] - [Other] 선택

[Designer] - [SWT] - [Application Window] 선택
*WindowBuilder Pro 가 설치가 되어야지 이 항목이 있다.

Name 을 입력하고 public static main() method 를 선택

[Source] 탭과 [Design] 탭으로 나누어져 있으며 Design 탭에서 수정하면 Source 에 바로 반영된다.


7. 실행
Ctrl + F11 을 누르면 Design 한 창 모양이 뜬다.

8. Jar 만들기
우클릭 - [Build Fat Jar] 클릭
Main-Class 를 정해준다.

swt.jar 를 포함시켜준다.
모두 포함하면 프로그램의 크기가 커지게 된다.

.jar 파일이 생성된다.
더블클릭하면 실행이 되는것을 확인할 수 있다.

Type 에 대해서 설명하기에 앞서 먼저 bit와 byte 에 대해서 설명하도록 하겠다.

1. Bit
bit란, 0,1 로 표현되는 숫자를 말한다. 즉, 2진수(binary)로 나타냈을 때의 한자리(digit)이다.

bit 를 표기할때는 임의로 |0| 이렇게 표기하도록 하며, 이뜻은 1bit 를 의미한다.

8bit 는 |00000000| 이런식으로 표기가 되겠다.

1bit 로는 2가지 상태를 나타낼수 있다. (|0| 또는 |1|)

2bit 로는 4가지 상태를 나타낼수 있다.(|00|, |01|, |10|, |11|)

3bit 로는 몇가지? 답은 8가지 이다.

계산 하는 방법은
n 일때 만들수 있는 가지수는
2n 가지가 되겠다.

x86 이라는 얘기를 한번쯤은 들어봤을 것이다. 그리고 x86은 32bit 라는 말도 들어봤을것이다.

32bit 라면, |0000 0000 0000 0000 0000 0000 0000 0000| 를 나타낼수 있다는 것이다.

cpu 를 한번쯤이라도 본사람이면 cpu 에 핀이 많이 달려있는것을 볼수 있다. 그 핀 하나가 각 한 bit 를 가진다고 보면
32bit cpu 는 한번에 처리할수 있는것이 32bit 란 말이 된다.

2. Byte
byte 는 bit 가 8개 모인것이다. 즉, |00000000| 은 1byte 이다.
1byte 로 나타낼수 있는 가지수는 256가지이다. (28)
10진수로 나타내보면 0 ~255 가 될것이다.

그러면 32bit는 4byte 가 된다.

KiloByte 는 210byte 가 되고
MegaByte 는  210 Kilobyte 이런식으로 나타낸다.

그럼 32bit 로 나타낼수 있는 메모리는 각 메모리당 1byte 씩 저장한다고 하면, 232 = 4GigaByte 가 된다.

그러므로 32bit OS 에서 인식할수 있는 최대 메모리는 4GB 가 된다.

3. Hexadecimal
Hexadecimal 은 16진수이다.
0~9, A~F 16개를 가지고 수를 표현한다.
F 는 10진수로 15를 나타낸다.

2진수를 10진수로 16진수로 변환하는 설명은 생략하도록 한다.

16진수하나는 몇 비트가 필요할까?   정답은 4bit 이다. (0~15 는 16가지 이고 16가지를 나타낼려면 4bit 가 필요하다.)
4bit 를 다른말로 Nibble 이라고 한다. 16진수 한자리가 1 Nibble 이 된다.

1byte 는 2자리의 16진수로 이루어져 있다. 그래서 보통 0xFF 혹은 0xff 로 표기한다.

그래서 메모리 주소를 표기할때 0xbfffffa0 이런식으로 4byte 로 나타낸다.(32bit OS 에서 메모리는 4byte 이므로)

데이터가 저장될때는 바로 2진수로 표기가 된다.
이 저장된 데이터를 hex 코드로 보게 되면 aa ff bf 이런식으로 볼수 있게 된다.

이 데이터가 저장될때 영문자는 ascii code 형식으로 저장이 된다.(1byte 소모)
한글은 2byte code 나 utf8 형식으로 저장이 될것이다.

여기까지 알수 있다면

이제 다음에 설명할 Type 과 bit 연산에 대해서 별 어려움 없이 이해하리라 본다.




앞에서, Hello, World 를 출력하는 프로그램을 짜보았다.

이제 한줄 한줄 분석을 해보겠다.

Tutorial 이므로 간단하게 설명하도록 하겠다.

#include <stdio.h> 문장은 Standard IO 와 관련된 함수를 사용할 수 있게 해준다.
여기서는 printf 함수를 사용하기 위해 적었다. 당분간은 printf 를 사용하기 위해 이 문장을 사용한다고 생각해 하면 된다.

int main() 문장은 프로그램의 시작을 나타내는 함수이다.

C에서는 다양한 함수들이 존재하는데(i.e.. printf 함수)
그 중에서 프로그램을 실행시키면 젤 먼저 시작점을 알아야 되는데 이것이 main 함수이다.

즉, 모든 프로그램은 main 함수가 존재한다.

함수는 brace "{", " }" 안에 정의된다.

printf 는 괄호안의 " " 안의 문장을 화면에 출력해 주는 함수이다. 문장의 끝은 세미콜론 ';' 로 끝나야 한다.

printf 만으로 간단하게 화면에 출력해주는 프로그램을 만들수 있다.

마지막 return 문장은 함수가 종료될때 반환해주는 값이다. 나중에 차츰차츰 설명하도록 하겠다.

1. 설치
인터넷에서 MinGWStudioFullSetup-2.05.exe 파일을 다운받아서 설치한다.

구글에서 mingw developer studio 를 치면 다운받을수 있는곳이 나온다.

2. 실행
실행시킨후 [File]-[New] 를 선택한후 원하는 프로젝트를 선택한다.
콘솔에서 간단하게 Hello, World 를 찍을 것이므로, Win32 Console Application 을 선택한다.


왼쪽 View 에서 [Source Files] 위에서 마우스 우클릭을 한다음, [Add Source Files To Project] 를 선택한다.
원하는 파일명을 입력한뒤 열기 버튼을 누른다. 파일이 없어도 상관없다.
그다음 source files 에 등록된 파일을 더블클릭하면 새로만들겠냐는 메세지가 나오고 확인을 누르면 새로운 파일이 생성된다. 참고로 파일명은 *.c 로 하는것이 좋다. ( C 언어로 작성할 예정이므로)

창에 다음과 같이 입력한다.
코드에 대한 설명은 다음에 하기로 한다.

위와 같이 입력한후,
[ctrl]+[F5] 를 누르거나 , 느낌표 모양의 아이콘을 누른다.
소스코드에 아무런 에러가 없다면 콘솔창이 실행되면서 Hello, World 를 출력할 것이다.


Reference
Brian W.Kernighan., and Dennis M.Ritchie. "The C Programming Language, 2nd edition", Prentice Hall

들어가기 전에
내용은 위의 참고서적을 기반으로 하고 있다.
The C Programming Language 를 TCPL 로 줄여서 표기하도록 한다.

프로그래밍을 처음 접해보는 사람을 상대로 설명하는 글을 쓸 예정이다.
그렇다고 기초만 하는것이 아니라 TCPL 에 들어있는 모든 내용을 설명할 예정이다.

개발 환경
Windows XP, MinGWStudio 환경에서 설명할 것이다.
하지만, 내용은 TCPL 을 따르며 실행환경만 이것으로 한다.

Programming Language?

프로그래밍 언어란 쉽게 말해 컴퓨터가 실행할수 있는 언어 (혹은 프로그램)를 만드는 언어 (혹은 도구)라고 할 수 있겠다.

High-Level Language 가 있고 Low-Level Language 로 나눌수 있는데,

High-Level Language 는 인간이 알아보기 쉬운 언어이고,
Low-Level Language 는 컴퓨터가 알아보기 쉬운 언어이다.

C Programming Language 는 High-Level Language 에 속한다.
한마디로, C 언어는 인간이 알아보기 쉬운 언어이다. 하지만, 막상 해보면 인간이 이해하는것도 그렇게 만만하지가 않다는 것을 느낄수 있다.

Compiler?

컴파일러란, High-Level Language 로 짜여진 소스(source) 를 컴퓨터(기계)의 언어(실행파일)로 바꿔주는 도구이다.
이것은 OS 에 종속적이다.
소스(source) 는 OS 에 독립적이지만(완전히 독립적인 것은 아님) 컴파일러는 OS 에 따라 달라진다.
내가 설명하고자 하는것은 C Language(C 언어) 이고 이것을 컴파일 해주는 Compiler 는 GCC 가 되는 것이다.
MinGWStudio 는 소스와 컴파일을 쉽게 해주는 도구이다.

나중에 다시 설명하겠지만, printf("Hello, World"); 란 문장을 Compiler 가 번역하면
OS에 종속적인 실행파일이 만들어진다.
C Language 는 printf 의 기능만 명시되어 있을뿐 컴파일러가 어떻게 동작해야 된다고는 나와있지 않다.
때문에 printf 가 어떻게 동작하는지에 대해서는 알 필요가 없지만, 나중에 컴파일러를 만들고 싶다면 알아야 할 것이다.

주저리 주저리...

본인이 처음 프로그래밍을 접한것은 초등학교때이다.(286AT DOS 시절)
그당시 내가 좋아하는 게임이 하고 싶어서 게임을 만들어 볼 생각에 일단 게임만드는 책을 샀었다.
그 책에는 상당히 어려운 것들이 막 적혀져 있었는데, 예제 소스라고 나와져 있던것들을 어디에 적어야 하는지도 몰랐었다.
내가 읽을수 있는 말이라곤 표지에 적혀져 있는  'C언어를 이용한' 이란 말이었다.
그래서 C언어를 공부해볼꺼라고 PC통신 에서 C언어 강좌를 봤었다.
거기도 역시 이렇다할 설명없이 그냥 소스코드를 치고 ctrl+F5 인가 하면 실행이 된다는 얘기뿐이었다.

그래서 그당시 컴퓨터에 깔려있는 HWP 2.1 에 코드를 치고 저장을 .hwp 말고 .exe 로 하고 실행해 보기도 하였다.
그리고 그렇게 프로그래밍이란 말만 들어보고 접게 되었다.(책에 있는걸 해볼수 없으니)
그러다가 중3때 다시 인연이 되었는지 컴퓨터에 관심을 가지게 되었고, 리눅스란 놈을 시작해보다가
고등학교때 '안녕하세요 터보C' 란 책으로 입문하게 되었다.

컴퓨터 관련 책을 보면서 드는 생각인데, 입문자들은 언제나 불편하다. 책에 나와있는 환경과 조금이라도 틀리면 해볼수 없기 때문이다. 그렇다고 책에 자세히 나와있는 것도 아니다.

이 문제는 책을 쓰는 저자도 마찬가지 일것이다. 모든 환경을 고려하다보면 도입부분만 해도 엄청 방대해 질것이기 때문이다.
한가지 더,
책에서 사용되는 프로그램은 대부분 상용프로그램들이다.
독자들은 겨우 데모버전 가지고 실행해 보는것이 전부이다.
그래서 Free software 버전인 GCC, MinGWStudio 를 선택하였다.
방학을 맞이해서 Java 를 공부를 하기로 마음먹었다.

이것도 얼마나 갈지 잘 모르지만, 어쨌든 시작은 해본다.

참고로 본인은 Java 에 대해서 모른다. 객체지향적인 프로그램은 더더욱 모른다.

아마 이글을 보는 사람들은 프로그래밍을 다뤄본 사람들이겠지만, 기본적으로 프로그래밍을 모른다는 전제하에 작성하는 글임을 알아두길 바란다.(한마디로 누구나 보면 따라할수 있도록 작성하는 글)

*그러니, 이 글을 읽고도 모르는 부분이 있다면, 그건 모두 글쓴이의 탓입니다.
  저의 능력이 부족해서 쉽게 전달하지 못한 점에 미리 양해 부탁드립니다.

기본적으로 java 와 관련된 내용은 http://java.sun.com  여기서 찾는것이 가장 좋을 듯 하다.

NetBeans 는 http://java.sun.com/javase/downloads/index.jsp 여기서

JDK 6 Update 14 with NetBeans 6.5.1 를 받아서 사용하면 된다. (최신버전, 09년 6월 22일 현재)

더 상위 버전이 있으면 상위 버전을 받아서 사용하면 된다.

참고로 http://hallang.tistory.com/62  여기 글을 읽으면 쉽게 따라할 수 있으리라 생각된다.



설치를 하면 무엇을 설치할껀지를 묻는데 뭐 그냥 모르면 전부체크를 하고 설치하면 된다.

그리고 설치가 다 되면 NetBeans 프로그램을 실행한다.

NetBeans 로 C/C++ 작업도 할수 있지만, JAVA 만 설명하도록 한다.

다른 IDE 관련 프로그램을 사용해 봤으면, 어느정도 UI 는 익숙할 것이다.

하지만, 필자처럼 IDE 를 처음 보는 사람이면 무엇을 해야 될지를 모른다.

일단 무엇인가를 만들어야 하니까 메뉴에서 [File] 메뉴를 누른다.

프로젝트를 생성해야 하므로 [New Project] 를 선택한다.

본인도 처음에는 프로젝트의 개념을 잘 몰랐는데, 프로그래밍이란게 하나의 파일만 필요한게 아니므로, 프로젝트를 먼저 생성해서 거기에서 여러개의 파일을 만든다. 그리고 이 여러개의 파일을 종합해서 하나의 실행프로그램을 만드는 것이다.
(처음 C 를 배울때만 해도 file.c 하나만 달랑 만들어도 프로그램이 되었었는데...)

[New Project] 를 선택하면

다음과 같은 창이 뜰것이다.
각 항목별 설명의 밑에 Description 을 읽어보면 된다. 모르겠으면 Bold 체로 되어있는 부분만 읽어도 상관없을 듯 하다.
기본적으로는 Java 항목의 Java Application 을 선택하면 된다.

Java Desktop Application 은 기본적으로 Document 폼을 하나 만들어준다. 이것을 선택해서 바로 실행해보면 뭔가 심플한 창이 하나 뜰 것이다.

하지만 본인도 돌아가는 구조를 모르므로 넘어가고 Java Appliction  을 선택한다.

Next 를 누르면 프로젝트 이름과 경로를 설정하는 창이 나온다. 알아서 설정하고 Finish 를 누르면 뭔가가 만들어진다.

왼쪽에 다음과 같은 트리가 있는데, source packages 밑에 내려가다보면 *.java 파일이 있을것이다.

그 파일은 뭐라고 죽 적혀져 있을것이다.

*.java 파일에서 우클릭을 하면 다음과 같은 메뉴가 있는데 여기서 [Run File] 을 해보면 이 파일을 실행한다.

아마 아무것도 안나올 것이다.

보통의 Java 관련 책을 보면 컴포넌트 어쩌고 저쩌고 하면서 버튼이라던지 창 크기라던지 하는 부분을 전부 소스코드로 직접  쳐서 설명하고 있다.

21세기를 살면서 이런 좋은 IDE 를 가지고 직접 위치를 계산해서 그릴일은 별로 없을듯 한데 말이다.
다행히도 NetBeans IDE 에도 Swing Desinger 가 포함되어 있는 듯 하니, 그것을 이용하면 된다.

참고로 Java 에서 GUI Component 에는 여러가지가 있다.
AWT, Swing, SWT, SwingWT

AWT 는 Java 초기 버전이고 Swing 은 업그레이드 버전으로 생각하면 된다.
SWT 는 Eclipse IDE 에서 사용한다.

NetBeans 는 Swing 을 사용하면 된다. 불행히도 NetBeans 에서 SWT 를 사용하려고 하였으나 방법을 찾지 못하였다.
SWT 를 사용하려면 맘 편하게 Eclipse IDE 를 사용하면 된다.

*.java 의 상위 계층에서 우클릭 [New] 를  보면 뭔가가 많이 나온다.

만만한 JDialog Form 을 선택한다. (그냥 대화상자, 확인창, 메세지창 이 뜨는 폼이라고 생각하면 된다.)
(* JFrame 은 메뉴바가 있는것이다.)

그러면 뭔가가 생긴다.

NewDialog.java 파일이 생겼는데 여기는 특이하게 Source 와 Design 으로 나누어져 있다.

Designer 폼에서 오른쪽에서 Button 을 드래그해서 끌어다 놓으면 위의 그림처럼 Button1 이 하나 생성된다.

source 탭으로 오면 뭔가 이상한 소스들이 적혀져 있다.

이 소스가 Designer 와 연결해서 띄워주는 프로그램인 것이다.

먼저 생성된 Main.java 파일은 삭제 시킨다.

이것을 그냥 [Run File] 하면 창이 하나 뜨고 Button1 을 클릭해도 아무 반응이 없다.

Designer 에서 Button1 을 더블클릭하면 소스창으로 자동이동한다.

여기서

    private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {                                        
        // TODO add your handling code here:
        javax.swing.JOptionPane.showMessageDialog(null,"Hello, World");
 
    }   

이걸 입력하면 다시  [Run File] 한다음에 Button1 을 클릭하면 다음과 같이 실행된다.


이제 이것을 실행파일로 만들어야 되는데,
[Run] -> [Build Main Project] 를 실행한다.
그러면 project directory\dist 밑에 *.jar 파일이 생성된다.
이것을 더블클릭하면 실행되어야 하는데
error 창이 뜨는 경우가 발생한다. 그러면

[Run] -> [Set Project Configuration] -> [customize] 를 클릭한다.
새롭게 뜬 창에서 Main class 옆에 Browse 버튼을 누르면 Main Class 선택창이 나오는데
Class 를 선택하고 다시 [Build Main Project] 를 하면 *.jar 파일이 다시 생성된다.
이걸 실행하면 실행이 되는것을 확인할 수 있다. 배포는 이 *.jar 파일을 배포하면 된다.



쉽게 쓴다고 했는데 역시 안되는 것 같네요...^^;

Java 기본적인 문법과 Designer 사용법만 익히면 프로그램 만드는데 문제 없을 것 같습니다.

나머지는 API 관련 문서를 보시면 쉽게 접근할수 있을 것입니다.

http://java.sun.com/docs/books/tutorial/uiswing/components/index.html

1. VC++ 6.0

VC++ 6.0 (이하 VC++) 에서는 인라인 어셈블을 __asm 형식으로 사용한다.

여러개의 어셈블 명령어를 사용하려면 { } 로 묶어주면 된다.

2. GCC

GCC 에서는 asm( ); 형식을 사용하거나,
__asm__ ( ); 형식을 사용한다.

보통 __asm__ __volatile__ ( ); 형식으로 사용하라고 권한다.

GCC 는 (명령어 input output) 형태로 들어가게 된다.

자세한 사항은

http://www.ibiblio.org/gferg/ldp/GCC-Inline-Assembly-HOWTO.html 혹은
http://wiki.kldp.org/wiki.php/DocbookSgml/GCC_Inline_Assembly-KLDP

참고하면 된다.

3. 예제

변수의 overflow 를 체크하는 것을 만들어 보자.

변수가 overflow 가 발생했는지 알아보는 방법은 cpu의 flag 중 CF(carry flag) 가 세팅되어졌는지를 확인하는 것이다.
cpu flag 를 확인하는 방법은 어셈블을 사용할 수 밖에 없다.

flag 를 확인하는 방법 말고 다른 방법또한 존재하겠지만, 인라인 어셈블을 이용해서 확인을 해보도록 하자.
3.1 VC++

__asm {
      pushfd;          // eflags(32bit) 값을 스택에 넣는다.
      pop eax;        // eflags 값을 eax 에 넣는다.
      and eax,0x1;  //  0 bit (CF) 가 1인지 확인을 한다.
      mov i, eax;   // 그 값을 변수 i 에 넣는다.
}

이것을 매크로로 만들어도 된다.

#define CHECKOVERFLOW(x) __asm pushfd __asm pop eax __asm and eax,0x1 __asm mov x,eax

테스트 코드는 다음과 같다.
#include <stdio.h>
#define CHECKOVERFLOW(x) __asm pushfd __asm pop eax __asm and eax,0x1 __asm mov x,eax
int main(int argc, char* argv[])
{
 long l=0xFFFFFFF0;
 int sum;
 int flag;
 scanf("%d",&sum);
 l += sum;
 CHECKOVERFLOW(flag);
 if(flag){
  printf("over flow: %u\n",l);
 }
 else
  printf("not over flow:%u\n",l);
 
 return 0;
}

3.2 GCC

GCC 에서는 VC++ 과 다르게 C 내에서 선언한 변수를 쓸때에는 %0, %1 을 사용하여야 한다.
 asm ("mov %%eax, %0" :"=g"(flag));
여기서 %0 은 flag 란 변수를 뜻하는 말이다.

나머지는 VC++ 과 똑같다.

테스트 코드는 다음과 같다.
  1 #include <stdio.h>
  2
  3 int main()
  4 {
  5   long l=0xFFFFFFF0;
  6   int sum;
  7   int flag=0;
  8
  9   scanf("%d",&sum);
 10   l += sum;
 11
 12   asm ("pushf");
 13   asm ("pop %eax");
 14   asm ("and $0x1, %eax");
 15   asm ("mov %%eax, %0" :"=g"(flag));
 16
 17   if(flag)
 18     printf("overflow : %u\n",l);
 19   else
 20     printf("not overflow : %u\n",l);
 21   return 0;
 22 }



 


1. Basic Execution Program Registers

위 그림은 IA-32 Architectures Software Developer's Manual Volume:1 에서 가져온 그림이다.
(아래 내용들도 역시  IA-32 Architectures Software Developer's Manual Volume:1 여기서 가져온 내용이며, 한글설명은 본인의 생각이다.)
IA-32 에서 사용되고 있는 레지스터들을 보여주고 있다.

어셈블리 프로그래밍을 할때 최소한 이 레지스터들이 뭐하는 것들인지는 알고 있어야 프로그램이 가능하므로, 공부해보도록 하자.

1.1  General-Purpose Registers

  •  EAX : Accumulator for operands and results data. (그냥 산술 연산에 쓰이는 레지스터.  그냥 일반적으로 많이 쓰인다. )
  •  EBX: Pointer to data in the DS segment. ( Base 레지스터라고 알아두면 된다. 꼭 이 용도로만 사용되는 것은 아니다.)
  • ECX: Counter for string and loop operations. ( Loop 명령시 ecx 레지스터값을 보고 0 이 아니면 반복문을 실행한다.  왜 꼭 loop 를 돌때 ecx 를 참고하냐고?? intel 에서 그렇게 만들었으니까)
  • EDX: I/O pointer. ( destination 레지스터라고 알아두면 된다. 꼭 이 용도로만 사용되는 것은 아니다.)
  • ESI: Pointer to data in the segment pointed to by the DS register; source pointer for string operations.(source index 레지스터라고만 알아두자.)
  • EDI: Pointer to data (or destination) in the segment pointed to by the ES register; destination pointer for string operations.(destination index 라고 알아두자.)
  • ESP: Stack pointer (in the SS segment). ( 좀 중요하다 스택 push, pop 할때 자주 나오므로 알아두면 좋다. esp 값을 바꾸지 않아도 push, pop 명령으로 알아서 esp 값이 바뀐다.)
  • EBP: Pointer to data on the stack (in the SS segment). ( base pointer 로서 esp 값이 계속 바뀌므로 스택의 기준점을 정하기 위해 ebp 사용한다. 보통 push ebp , mov ebp,esp 명령을 내린다.)

 

'E' 가 붙은 것은 32bit 레지스터이고 ax,bx,cx,dx 는 16bit, ah,al ... 은 8bit 이다. 자세한 이해는 아래그림을 참고하면 된다.




나머지 레지스터들은 그렇게 비중이 있는 것은 아니니까 ... skip...
필요하면 언급하겠음.


MASM 이란?
Microsoft Macro Assembler 란 뜻으로
MS 에서 무료로 제공해 주는 어셈블러 이다.

어셈블러로 목적코드를 만들때 쓰는 프로그램은 ml 이고,
실행파일을 만들기 위한 링커는 link32 또는 link16 또는 link 이다.

믈론,  Visual Studio Express(무료) 버전을 설치해도 ml 과 link 는 제공된다.

MASM 설치하기

먼저 필요한것들로는

MASM 6.15 혹은 MASM 6.11 혹은 MASM32 SDK (v10)

이 세가지중 하나가 있으면 되겠다.

MASM 6.15 를 가지고도 win32 application 프로그래밍이 가능하지만, MASM32 가 대세인듯 하다.

모두 무료제공이니 인터넷에서 다운받아 설치하면 된다.

MASM 6.15 버전은
"Assembly Language For Intel-Based Computers, 4th" 의 책에서 제공되는 프로그램을 설치하면
Irvine32.inc 와 Irvine32.lib 이 같이 설치되고 make32.bat 파일로 바로 실행파일까지 만들어 준다.

만약 Irvine32.inc 와 Irvine32.lib 을 못구하면 역시 인터넷에서 다운받아 사용할수 있다.

Irvine32 파일은 여러가지 라이브러리를 제공해 주므로 가지고 있으면 여러므로 편하게 사용할 수 있다.

MASM with IDE

요즘 코딩은 IDE 가 없으면 상당히 불편하다. 이를 위해 WinAsm 이란 IDE 툴을 설치하면 작업하기 한결 편리하다.
WinAsm 의 라이센스 정책이 어떤지 모르겠으나 winasm.net 사이트에서 다운받아 사용할수 있다.

그리고 약간의 설정을 해준다면 MASM32 + WinAsm 으로 통합환경을 만들수 있다.
물론 Visual Studio 2005 나 Visual Studio 2008 로도 가능하지만,
Visual Studio 는 어디까지나 상용 버전이기 때문에 설명은 하지 않겠다.

물론 Express Edition 은 무료로 제공하고 있으니, Express Edition 으로 작업해도 무방할듯 하다.

WinAsm 설정

일단  WinAsm 압축파일을 다운받아 압축을 풀면 WinAsm 폴더가 생긴다. 이것을 자신이 원하는 곳으로 옮기면 설치는 끝난다. 따로 설치를 할 필요가 없다.
이것은 단지 Tool 이므로 세팅을 통해서 MASM 과 연결시켜야 한다.

MASM 과 연결시키는 방법은 다음과 같다.


실행 화면에서 [Tools] -> [Options] 를 선택한다.

[Options] 의 Files&Paths 탭 항목에서 MASM32 가 설치된 디렉토리의 각 경로게 맞게 설정해준다.

이렇게 하면 기본 설정은 끝이 난다.

Assembly & Linking &  Execute

설정이 끝났으면
[File] -> [New Project] 를 선택해서 프로젝트를 하나 생성한다.
Standard EXE 를 선택해도 되고 Console Application 을 선택해도 된다. 여기서는 Console Application 으로 해보겠다.

그리고 원하는 asm 코드를 작성하면 된다.

 


	INCLUDE	Irvine32.inc
	.data
	message		BYTE	"Hello, World! ",0dh,0ah,0
	
	.code
	main PROC
	mov			edx,OFFSET message
	call			WriteString
	call			WaitMsg
	exit
	main ENDP
END main



그 다음에 [Make] -> [Assemble] , [Make]->[Link] 를 해야 되는데
이상하게 Link 가 되지 않는다. WriteString , WaitMsg 함수 심벌을 못찾는다고 한다.

이 이유는 Irvine32 라이브러리 함수이기 때문에 이 링킹 옵션에 이 라이브러리를 추가시켜주어야 한다.
Irvine32.inc 파일은 include 폴더에 Irvine32.lib 은 lib 폴더에 복사해 주고

[Project] -> [Properties] 를 선택한 후

Debug 와  Release 탭의 Link 란에
irvine32.lib user32.lib kernel32.lib 을 추가해준다.

그리고 다시 assemble 과 link 를 실행하면 exe 파일이 생성된다.
그리고 [Make] -> [Execute] 를 하면

실행화면이 나타난다.


소스코드의 설명은 생략......

다음번엔 이런 자세한 설명은 없을 듯....

순전히 나의 공부를 위해서 !!!!

+ Recent posts