Assembly

[DOS] 간단한 Assembly 문법 정리

houdinist 2010. 1. 5. 00:37
1. 세그먼트 정의
    세그먼트이름 segment 옵션
    세그먼트이름 ends

    옵션 :
    1) alignment type
       BYTE, WORD, DWORD, PARA, PAGE으로 1,2,4,16,256의 배수에 시작
       지정하지 않으면 디폴트로 PARA
  
    2) combine type
       다른 세그먼트와 결합시키는 방식으로, PUBLIC, COMMON, STACK,
       PRIVATE, AT

    3) class type
       ''사이에 넣으며 세그먼트를 하나로 합치는게 아니라 독립적으로 존재
       하며, 단지 기억장소가 인접해 있음.

2. 프로시져 정의
    프로시져이름 proc 옵션
    프로시져이름 endp

    옵션 :
    1) NEAR : 옵션주소만 저장한다.
    2) FAR  : 세그먼트와 옵셋주소를 저장한다.

3. 지역변수와 매개변수의 사용

.model huge, stdcall
option casemap:none
.286

dseg segment
     char db "1234567890",'$'
dseg ends

sseg segment stack
     byte 100h dup('stack')
sseg ends

cseg segment
main proc near
     assume cs:cseg, ds:dseg, ss:sseg
     mov ax, dseg
     mov ds, ax

     mov ax, offset char
     push ax ; 매개변수로 주소를 넘김 (2바이트)
     call TTT

     mov ah, 4Ch
     int 21h
     main endp

TTT proc near

     push bp     ; bp를 저장
     mov bp, sp  ; 스택포인터를 저장
     sub sp, 2   ; 지역변수를 위해 2바이트 확보

     mov ah, 9
     mov dx, [bp+4] ; near 방식이므로 주소값과 bp크기만큼 더해 4
                          ; far 방식일때는 세그먼트까지 [bp+6]이 된다.
     int 21h

     mov byte ptr [bp], 'A' ; 확보한 첫바이트에 'A' 저장
     mov ah,2
     mov dl, [bp]
     int 21h

     mov byte ptr [bp+1], 'B' ; 확보한 두번째 바이트에 'B' 저장
     mov ah,2
     mov dl, [bp+1]
     int 21h

     add sp, 2 ; 지역변수를 해제, 즉 할당한 만큼스택크기를 줄인다
     pop bp     ; bp 복구
     ret
TTT endp
cseg ends

     end main

invoke 사용시는 local 변수이름:크기 를 사용해서 지역변수를 사용할 수 있
습니다. 하지만 결국은 위과 같은 방식으로 바뀌므로 기본적인 방법에 익숙해 지는 것이 좋겠지요.

4. 매크로의 정의
   매크로이름 macro 인자
   endm

   1) 매크로를 지정하면 매크로이름을 쓴곳에 정의한 부분으로 치환하여
      컴파일해 줍니다.

   2) 인자 역시 매크로 안에서 해당값으로 치환되어 들어갑니다.

   3) 인자:req 로 지정하면 항상 인자값을 넣어주어야 합니다. 반드시
      필요한 인자인데 넣지 않는 버그를 없애기 위해 컴파일 에러를 내줍
      니다.

   4) 소스에 내용이 치환되는 관계로 라벨이름이 중복되어 사용될 수 있습
      니다. 그래서 LOCAL 라벨이름을 이용하여 컴파일러가 중복되지 않는
      라벨을 자동으로 생성하게 합니다.
      여기서 중요한게 프로시져 내부에서도 local 을 사용하는데, 프로시져에
      서 local은 지역변수 선언을 의미하며, 스택에 지정한만큼 메모리를 잡아
      줍니다. 매크로의 local과 프로시져의 local을 구별해 두세요.


5. EXTERN, PUBLIC의 사용
   1) PUBLIC : 다른 파일에서 변수나 프로시져를 사용할 수 있게 이름을 외부
                로 노출시킵니다. 프로시져에서 PROTO를 사용할 경우 따로
                PUBLIC을 선언할 필요는 없습니다.

   2) EXTERN : 다른 파일에서 변수나 프로시져를 참조할때 사용합니다.


6. proto, invoke의 사용
    invoke문을 사용하기 위해서는 프로그램 선두에 사용할 프로시져의 인자
    를 미리 선언해야 합니다.

    프로시져이름 proto :byte, :byte  <- 바이트 2개를 받는 프로시져 선언

    invoke 프로시져이름 인자이름:byte, 인자이름:byte
    인자이름을 바로 사용해서 인자를 참조할 수 있습니다. invoke문은
    push 인자
    call 프로시져
    를 단순화한 명령이라고 할 수 있습니다. 결국은 위에서 설명한 방식으로
    매개변수와 지역변수를 사용합니다. 이 방식이 좋은 이유는 간단하면서
    인자를 크기에 맞게 자동캐스팅해줍니다. 그밖에 여러가지 잇점이 있습니
    다.