외로운 Nova의 작업실

Assembly 언어 공부 - 35(메크로) 본문

Programming/Assembly

Assembly 언어 공부 - 35(메크로)

Nova_ 2022. 10. 29. 18:07

안녕하세요, 이번 시간에는 메크로에대해서 정리 및 공부해볼까합니다.

 

- 메크로

메크로는 전처리 단계 동안 어셈블러에 의해서 등록된 코드로 확장됩니다.

 

- 메크로 정의 및 호출하기

메크로 정의는 아래와 같이 진행합니다.

name MACRO parameter1, parameter2 ...
	source code
ENDM

아래는 예시입니다.

PrintX MACRO
    mov al, 'X'
    call WriteChar
ENDM

메크로 호출의 경우 아래와 같이 진행합니다.

macroname argument1, argument2...

위 PrintX의 호출은 아래와 같이 call 명령어 없이 사용합니다.

.code
printX

이렇게 선언을 하면 어셈블러는 전처리 단계동안 아래와 같은 코드로 확장시켜줍니다.

.code
    mov al, 'X'
    call WriteChar

 

- 필수 매개변수 정의방법

매개변수를 필수로 정의하려면 REQ라는 수식어를 사용하여 정의할 수 있습니다. 아래는 예시입니다.

mPutchar MACOR char:REQ
	push eax
    mov al, char
    call WriteChar
    pop eax
ENDM

 

- LOCAL 디렉티브

메크로를 정의할때는 보통 코드와 데이트를 포함하여 사용됩니다. 아래는 예시입니다.

mWrite MACRO text
    .data
    string BYTE text, 0
    .code
    push edx
    mov edx, OFFSET string
    call WriteString
    pop edx
ENDM

하지만 실제 위 메크로를 알애 첫번째 코드처럼 호출을 하면 컴파일러가 두번째 코드처럼 확장되면서 에러를 일으킵니다.

.code
    mWrite "hello"
    mWirte "goodbye"
.code
    .data
    string BYTE "hello", 0
    .code
    push edx
    mov edx, OFFSET string
    call WriteString
    pop edx
    .data
    string BYTE "goodbye", 0
    .code
    push edx
    mov edx, OFFSET string
    call WriteString
    pop edx

왜냐하면 string 레이블이 재정의되는 것을 허용치 않기 때문입니다. 이러한 문제를 피하기위해 LOCAL 디렉티브를 사용합니다. LOCAL 디렉티브는 전처리 단계에서 레이블의 이름을 고유한 식별자로 변환시켜줍니다. 아래는 사용예시입니다.

mWrite MACRO text
    LOCAL string
    .data
    string BYTE text, 0
    .code
    push edx
    mov edx, OFFSET string
    call WriteString
    pop edx
ENDM

위 처럼 코드를 작성하고 아까처럼 2번 호출을 하게되면 아래와 같은 코드로 확장됩니다.

.code
    .data
    ??0000 BYTE "hello", 0
    .code
    push edx
    mov edx, OFFSET ??0000
    call WriteString
    pop edx
    .data
    ??0001 BYTE "goodbye", 0
    .code
    push edx
    mov edx, OFFSET ??0001
    call WriteString
    pop edx
Comments