UNION 사용하기, 매크로란? 매크로 정의하기, 매크로 호출하기 LABEL
UNION은 흔히 공용체라고 부르기도 한다. 구조체와 생김새는 비슷하지만 한 가지 다른 점은 모든 멤머가 같은 메모리 공간을 사용한다는 것이다. 즉, UNION에 세 개의 필드가있다고 할 때, 이 세 가지 중 한가지만 사용할 수 있다는 것이다. 따라서 UNION의 크기는 세 필드중 사이즈가 가장 큰 필드의 크기와 같다. 다음과 같이 정의하면 된다.
| 유니온이름 UNION 필드들... 유니온이름 ENDS |
또한 구조체의 필드중 몇몇의 필드만 묶어서 UNION으로 정의할 수 있다.
| 구조체이름 STRUCT 구조체필드들... UNION 유니온필드이름 유니온필드들... ENDS 구조체이름 ENDS |
약간 복잡해 보이지만 사실은 '유니온필드들'만 유니온으로 감쌌을 뿐이다. 유니온필드에 접근할 때는 '구조체이름.유니온필드이름.유니온필드' 로 접근하면 된다. 지금까지 언급한 특징만 다를 뿐이지, 사용하는 방법에 있어서 유니온과 구조체는 차이점이 없다. 위와같이 하는 것이 헷갈린다면 먼저 유니온을 정의한 후, 구조체 필드에 유니온 변수를 선언하면 된다. 그리고 하는 일은 두 가지 방법이 완전히 같다.
몇몇 독자는 UNION을 과연 어디에 쓰게 될지 궁금해 하실지 모르겠다. 작성하는 프로그램이 메모리를 매우 적게 차지해야하는 경우, 구조체의 멤버 중 동시에 쓰이지 않는 멤버를 유니온으로 묶어서 사용하면 메모리를 절약할 수 있다. 이와는 달리 유니온만의 특성을 이용한 예가 있다. 바로 IP주소에 대한 것이다. 소켓 프로그래밍을 해보신 분은 알겠지만 IPv4에서 IP주소는 4바이트이다. 우리가 눈으로 볼 때는 이 4바이트의 IP주소를 1바이트씩 잘라 읽어야 편리하다는 것을 잘 알고 있을 것이다. (우리가 잘 알고 있는 203.253.21.151의 형태) 이러한 경우 UNION을 유용하게 써먹을 수 있다.
| IP UNION inDword DWORD 0 inByte BYTE 0 0 0 0 IP ENDS |
매크로란, 어셈블리 구문들을 하나로 묶어놓은 것이다. 겉으로 보기엔 프로시져와 매우 유사한 형태를 갖고 있다. 하지만 C에서의 매크로 함수와 같아서, 스택에 수많은 push와 pop을 해가며 함수를 호출하는 것이 아니라, 단지 코드가 덧씌워질 뿐이다. 따라서 속도는 매우 빠른 장점을 지닌 반면, 조심해서 사용하지 않으면 코드가 덧씌워지기 때문에 프로그램의 크기가 매우 커질 것이다. 다음과 같은 매크로가 정의되어있다고 하자.
| NewLine MACRO call Crlf ENDM |
이 매크로는 단지 화면에 개행문자(텍스트 에디터에서 엔터를 누른 것과 같은 효과)를 찍는 일만 수행한다. 매크로를 어떻게 정의하는지 대한 정확한 설명은 다음 단락에 이어질 것이다.
| .code NewLine |
위와 같은 코드는 전처리기(어셈블러가 컴파일하기 전에 수행된다)에 의해 다음과 같이 바뀐다.
| .code call Crlf |
매크로는 소스코드의 어느 부분에서도 정의될 수 있다. 하지만 매크로는 소스코드에서 정의되기 이전에 호출될 수는 없다.
| 매크로이름 MACRO 파라미터1, 파라미터2, ... 구문들 ENDM |
다음은 인자로 넘어온 문자를 화면에 찍어주는 일을 하는 매크로이다.
| mPutchar MACRO char push eax mov al, char call WriteChar pop eax ENDM |
매크로를 호출하려면 다음과 같이 사용한다.
| 매크로이름 인자1, 인자2,... |
| mPutchar 'A' |
| push eax mov al, 'A' call WriteChar pop eax |
사실 LABEL디렉티브는 구조체나 매크로와는 그다지 관련이 있지 않다. 하지만 이 디렉티브를 언급하는 이유는 나중에 나올 링크드 리스트 예제에 이것이 나오기 때문이다. 크게 어려운 내용이 아니니 부담없이 읽어주기 바란다.
4회에서 나왔던 내용이지만, 다시한번 변수에 대한 이야기를 해 보겠다. .data에 선언된 변수의 이름은 레이블이다. 우리가 흔히 '라벨'이라고 부르는 것을 떠올리면 레이블의 역할이 뭔지 알 수 있을 것이다. 우리가 선언한 데이터들은 데이터 세그먼트에 들어가게 되고 이 데이터 세그먼트의 시작부분으로부터 선언된 데이터가 존재하는 곳 까지의 거리(Offset)를 통해서 그 데이터에 접근하게 된다. 여기서 '거리'라고 하는 것은 숫자이기 때문에 사람이 기억하기가 어렵다. 따라서 각각의 '거리'에 대한 레이블을 하나씩 만들어놓은 것이 데이터 레이블인 것이다.
LABEL디렉티브는 데이터 세그먼트에 이미 존재하는 변수에 또 하나의 이름과 타입을 지정해주는 데 이용된다. 다음의 사용예를 보아라.
| .data val16 LABEL WORD val32 DWORD 12345678h .code mov ax, val16 ; AX = 5678h mov dx, val16 + 2 ; DX = 1234h |
- CPU 레지스터 (0)2007/03/15
- 반복 출력, REPEAT 디렉티브 & 연산자, 링크드 리... (0)2006/07/10
- UNION 사용하기, 매크로란? 매크로 정의하기, 매크... (0)2006/07/10
- 구조체란? 구조체 선언, 구조체 변수 사용하기 (0)2006/07/10
- 버블소트 (0)2006/07/10

수안이의 컴퓨터 연구실



Leave your greetings.