구조체란? 구조체 선언, 구조체 변수 사용하기
어느덧 본 강좌도 끝을 향해 가고 있다. 이제 우리는 최소한 어셈블리어 코드를 보고 어떤 일을 하는지 정도는 파악할 수 있지만, 아직 뭔가 허전함을 느낄지 모르겠다. 본 회에 배울 구조체와 매크로에 관련된 내용은 그러한 허전함을 채워주리라 믿어 의심치 않는다.
다른 언어도 마찬가지이지만, 나중에 버전업이 되어 새로운 것이 나오더라도 예전에 사용하던 형식과 개념 등은 그대로 묻어있게 마련이다. 어셈블리어도 마찬가지인데, 특히나 다른 프로그래밍언어에서 흔히 쓰이는 것이 어셈블리어에 약간 원초적(?)인 모습으로 존재하는 것을 볼 수 있다. 여기서 원초적이라는 말은 좀더 사용하기 불편하고 원시적으로 생겼다는 이야기이다. 필자는 어셈블리어의 프로시져나 배열, 구조체, 매크로 등을 처음 접할 때도 이러한 사실을 느끼고는 매우 흥미로워 했던 기억이 난다. 여러분도 기존에 사용하던 언어에 존재하던 클래스나 구조체, 매크로 등이 어셈블리어에 좀더 원초적(?)으로 존재하는 것을 배우며 희열을 느껴보길 바란다.
다른 프로그래밍 언어를 접해보신 분이라면 구조체가 무엇인지는 잘 알고 계실 것이다. 그래도 형식상 간단히 설명하자면 구조체는 개념적으로 연관있는 변수들의 그룹이자 틀이며 데이터형이다. 물론 이렇게 설명한다고 해서 이해하시는 분은 아무도 없을 것이다. 구조체를 하나 간단히 정의해 보겠다.
| COORD STRUCT X WORD ? Y WORD ? COORD ENDS |
위 구조체의 이름은 COORD이며 이것이 곧 데이터형이 된다. 뒤에 STRUCT라고 적힌 것을 보면 구조체를 말하는 것이라 추리할 수 있다. 또 마지막에 ENDS가 보이는데, 추측해 보건데, END Struct의 약자일 것이다. 보다시피 구조체의 정의는 너무나 간단하다. 구조체에 포함된 하나하나의 변수는 필드(field)라 불리우며, 멤버변수라고도 부른다. 그리고 ?표시를 한 곳은 초기화를 하지 않겠다는 뜻이다.
구조체에 관련되어 배울 항목은 정의, 선언, 구조체변수 참조 이다. 하나하나씩 항목별로 배워보자.
구조체의 정의는 다음과 같이 한다.
| 구조체이름 STRUCT 필드선언들... 구조체이름 ENDS |
구조체를 정의할 때는 초기값을 같이 넣어줄 수 있다. 초기값을 적는 형식은 우리가 일반 변수를 선언할 때와 같다. 다음의 예를 보자.
| Employee STRUCT IdNum BYTE "000000000" LastName BYTE 30 DUP(0) Years WORD 0 SalaryHistory DWORD 0, 0, 0, 0 Employee ENDS |

첫번째 필드 IdNum을 보자. 스트링을 초기값으로 정해 놓았다. 숫자'0' 9개와 널문자 0, 총 10바이트가 들어간다. 잘 이해가 가지 않으면 3회를 다시 참고하기 바란다. 두번째 필드 LastName은 바이트원소가 30개 들어가는 배열에 초기값으로 모두 0을 넣어 두었다.(비어있는 스트링과 같기 때문에 그림1에서는 (null)이라고 적어 놓았다) 세번째 필드 Years는 WORD형으로 0을 하나 갖는다. 마지막 필드는 SalaryHistory로써 DWORD형 원소 4개에 각각 초기값을 0으로 넣어두었다. 두말할 필요도 없이 초기화를 하고 싶지 않으면 ?를 사용하면 된다.
한가지 유의할 것은 위에 적어놓은 것은 구조체의 정의라는 것이다. 따라서 일종의 데이터 타입이 하나 생긴 것이고, 이를 사용하려면 구조체 변수를 선언해서 사용해야 한다.
좀 더 엄밀히 말하면 구조체에 대한 인스턴스의 선언 또는 구조체 변수의 선언이다. 두말할 필요도 없이 다음의 예제를 보면 쉽게 이해갈 것이라 믿는다. COORD는 본 회의 "구조체란?"단락에서 정의해 놓았던 그 구조체이다.
| .data point1 COORD <5, 10> point2 COORD <> point3 COORD {} |
이렇게<와 >를 사용하여 초기화를 해준다. 만약 < 와 >안에 아무것도 적어주지 않는다면 각 필드에 구조체의 정의에서 적어놓았던 초기값이 적용된다. <와 > 대신 { 와 }을 사용해도 무방하다. 이제 다음 구문을 보고 무슨 뜻일지 한번 생각해 보자.
| person3 Employee <, "Jones"> |
눈치가 빠른 분은 이미 눈치챘을 것이다. 두번째 필드만 프로그래머가 지정한 초기값으로 초기화 하고 나머지는 디폴트 초기값으로 적용시키게 된다. 마지막으로 , 구조체의 배열은 어떻게 사용하는지 고민해 보자.
| AllPoints COORD 3 DUP (<0,0>) |
이제 COORD형 구조체 변수가 세 개 생겼고 구조체의 배열로 사용할 수 있게 되었다.
지금까지는 구조체 변수를 선언하는 방법이었고, 다음 단락에서는 직접 구조체 변수를 사용하는 법을 배워보자.
구조체 변수를 사용하는 것은 놀랍게도 C언어와 다를 바가 없다. '.'을 이용하여 멤버에 접근하기 때문이다.
| .data worker Employee <> .code mov worker.SalaryHistory, 20000 ; 첫번째 봉급 mov worker.SalaryHistory + 4, 30000 ; 두번째 봉금 |
C와 비슷하게 쓴다고 해서 마지막 줄의 코드까지 헷갈리지 않길 바란다. + 4를 했는데도 두번째 봉급이 된 이유는 DWORD타입(4바이트를 차지)이기 때문이다. 또 배열이라고 해서 다른 언어처럼 특별한 접근방식이 존재하는 것이 아니라 단지 주소에 덧셈을 하여 다음 원소로 접근한다는 것도 잊지 않기 바란다. 이제 인다이렉트 오퍼랜드로 어떻게 접근하는지 알아보자. 인다이렉트 오퍼랜드는 4회에서 언급한 바 있다. 쉽게말하면 포인터로 접근하는 방법이다.
| mov esi, OFFSET worker mov ax, (Employee PTR [esi]).Years |
[esi].Years로 사용하는 실수를 범하지 않길 바란다. 구조체는 어셈블리에서 매우 잘 정의되어 있으며 사용하는데 있어 크게 어려울 것이 없다는 것을 느꼈을 것이다.
- 반복 출력, REPEAT 디렉티브 & 연산자, 링크드 리... (0)2006/07/10
- UNION 사용하기, 매크로란? 매크로 정의하기, 매크... (0)2006/07/10
- 구조체란? 구조체 선언, 구조체 변수 사용하기 (0)2006/07/10
- 버블소트 (0)2006/07/10
- 스트링 비교 예제, 이차원 배열, 베이스-인덱스 디... (0)2006/07/10

수안이의 컴퓨터 연구실



Leave your greetings.