외로운 Nova의 작업실

Assembly 언어 공부 - 8(demo4) 본문

Programming/Assembly

Assembly 언어 공부 - 8(demo4)

Nova_ 2022. 5. 26. 03:48

안녕하세요. 오늘은 어제에 이어서 demo4와 demo5의 코드를 리뷰해보도록 하겠습니다.

 

<demo4>

오늘도 어제와 이어서 demo4 파일을 열어보겠습니다.

locals.asm라는 어셈블리파일이 있군요.

MASM32 Editor로 열어줍시다.

코드를 한번 긁어와 보겠습니다.

; カカカカカカカカカカカカカカカカカカカカカカカカカカカカカカカカカカカカ?

;                 Build this with the "Project" menu using
;                        "Console Assemble & Link"

comment * カカカカカカカカカカカカカカカカカカカカカカカカカカカカカカカカ?

There is another method of allocating space for uninitialised data in
MASM that can only be done within a procedure. The use of LOCAL variables
is possible in a procedure because the memory from the "stack" can be
used in this way.

In MASM, allocating a LOCAL uninitialised variable is done at the beginning
of a procedure BEFORE you write any code in the procedure. With memory
allocated on the stack, it can only be used within that procedure and is
deallocated at the end of the procedure on exit.

    LOCAL MyVar:DWORD       ; allocate a 32 bit space on the stack
    LOCAL Buffer[128]:BYTE  ; allocate 128 BYTEs of space for TEXT data.

Variables created on the stack in this manner are sometimes called
automatic variables and their main advantage is being fast, flexible
and easy to use.

This demo also shows how to get user input from the console using "input".
It also introduces a simple procedure that has a value passed to it and
the procedure uses a PROTOTYPE to enable size and parameter count checking
to make the code more reliable.

カカカカカカカカカカカカカカカカカカカカカカカカカカカカカカカカカカカカ?*

    .486                                    ; create 32 bit code
    .model flat, stdcall                    ; 32 bit memory model
    option casemap :none                    ; case sensitive
 
    include \masm32\include\windows.inc     ; always first
    include \masm32\macros\macros.asm       ; MASM support macros

  ; -----------------------------------------------------------------
  ; include files that have MASM format prototypes for function calls
  ; -----------------------------------------------------------------
    include \masm32\include\masm32.inc
    include \masm32\include\gdi32.inc
    include \masm32\include\user32.inc
    include \masm32\include\kernel32.inc

  ; ------------------------------------------------
  ; Library files that have definitions for function
  ; exports and tested reliable prebuilt code.
  ; ------------------------------------------------
    includelib \masm32\lib\masm32.lib
    includelib \masm32\lib\gdi32.lib
    includelib \masm32\lib\user32.lib
    includelib \masm32\lib\kernel32.lib

  ; --------------------------------------------------------------
  ; This is a prototype for a procedure used in the demo. It tells
  ; MASM how many parameters are passed to the procedure and how
  ; big they are. This makes procedure calls far more reliable as
  ; MASM will not allow different sizes or different numbers of
  ; parameters to be passed. Note that a C calling convention
  ; procedure CAN have a variable number of arguments but these
  ; examples use the normal Windows STDCALL convention which is
  ; different.
  ; --------------------------------------------------------------
    show_text PROTO :DWORD

    .code                       ; Tell MASM where the code starts

; カカカカカカカカカカカカカカカカカカカカカカカカカカカカカカカカカカカカ?

start:                          ; The CODE entry point to the program

    call main                   ; branch to the "main" procedure

    exit

; カカカカカカカカカカカカカカカカカカカカカカカカカカカカカカカカカカカカ?

main proc

    LOCAL txtinput:DWORD        ; a "handle" for the text returned by "input"

    mov txtinput, input("Type some text at the cursor : ")
    invoke show_text, txtinput

    ret

main endp

; カカカカカカカカカカカカカカカカカカカカカカカカカカカカカカカカカカカカ?

show_text proc string:DWORD

    print chr$("This is what you typed at the cursor",13,10,"     *** ")
    print string                ; show the string at the console
    print chr$(" ***",13,10)

    ret

show_text endp

; カカカカカカカカカカカカカカカカカカカカカカカカカカカカカカカカカカカカ?

end start                       ; Tell MASM where the program ends

어제와 마찬가지로 주석부분을 한글로 번역해보겠습니다.

; カカカカカカカカカカカカカカカカカカカカカカカカカカカカカカカカカカカカ?

;                 프로젝트 메뉴의 콘솔 어셈블리와 링크를
;                        사용해서 빌드하세요.

comment * カカカカカカカカカカカカカカカカカカカカカカカカカカカカカカカカ?

MASM에서 초기화되지 않은 데이터를 위한 공간을 할당하는
또 다른 방법은 프로시저 내에서만 사용이 가능한 방법이 있습니다.
로컬 변수의 사용은 "스택"의 메모리 방식으로 사용될 수 있기 때문에
프로시져에서 가능합니다.

MASM에서 로컬 초기화되지 않은 변수 할당은
프로시저 시작 시 프로시저에서 코드를 작성하기 전에 수행됩니다.
스택에 할당된 메모리는 해당 프로시저 내에서만 사용할 수 있으며
종료 시 절차가 끝날 때 할당이 해제됩니다.

    LOCAL MyVar:DWORD       ; 32비트 공간을 스택에 할당합니다.
    LOCAL Buffer[128]:BYTE  ; 텍스트를 위한 128바이트 공간을 스택에 할당합니다.

이러한 방식으로 스택에 생성되는 변수를 자동 변수라고 부르기도 하며,
빠르고 유연하며 사용하기 쉬운 것이 주된 것이 장점입니다.

이 데모에서는 또한 "input" 함수를 사용하여 콘솔에서 사용자 입력을 가져오는 방법을 보여 줍니다.
또한 값이 전달된 간단한 프로시저를 소개하고 프로시저는 프로토타입을 사용하여
매개변수의 크기와 매개 변수 카운트 확인을 가능하게 하여 코드를 더욱 신뢰할 수 있게 만듭니다.

カカカカカカカカカカカカカカカカカカカカカカカカカカカカカカカカカカカカ?*

    .486                                    ; 32비트 코드를 만듭니다.
    .model flat, stdcall                    ; 32 bit 메모리 모델을 사용합니다.
    option casemap :none                    ; 대소문자를 구분합니다.
 
    include \masm32\include\windows.inc     ; 항상 처음에 써줍니다.
    include \masm32\macros\macros.asm       ; MASM 메크로 입니다.

  ; -----------------------------------------------------------------
  ; 함수 호출을 위한 MASM 형식 프로토타입을 포함하는 파일
  ; -----------------------------------------------------------------
    include \masm32\include\masm32.inc
    include \masm32\include\gdi32.inc
    include \masm32\include\user32.inc
    include \masm32\include\kernel32.inc

  ; ------------------------------------------------
  ; 함수에 대한 정의가 있고 신뢰할 수 있는 
  ; 사전 빌드 코드를 테스트한 라이브러리 파일입니다.
  ; ------------------------------------------------
    includelib \masm32\lib\masm32.lib
    includelib \masm32\lib\gdi32.lib
    includelib \masm32\lib\user32.lib
    includelib \masm32\lib\kernel32.lib

  ; --------------------------------------------------------------
  ; 아래 show_text는 데모에 사용된 프로시저의 프로토타입입니다.
  ; MASM에 프로시저로 전달되는 매개 변수의 수와 크기를 알려줍니다.
  ; 이것은 MASM이 다른 크기나 다른 수의 매개 변수를 전달할 수 없기 때문에
  ; 프로시저 호출을 훨씬 더 신뢰할 수 있게 만든다.
  ; C 호출 규약 프로시저는 변수 개수의 인수를 가질 수 있지만
  ; 이러한 예에서는 일반적인 Windows STDCALL 규약을 사용합니다.
  ; --------------------------------------------------------------
    show_text PROTO :DWORD

    .code                       ; MASMd에게 코드 실행부분을 알려줍니다.

; カカカカカカカカカカカカカカカカカカカカカカカカカカカカカカカカカカカカ?

start:                          ; 프로그램의 엔트리 포인트 코드입니다.

    call main                   ; main 프로시저로 분기합니다.

    exit

; カカカカカカカカカカカカカカカカカカカカカカカカカカカカカカカカカカカカ?

main proc

    LOCAL txtinput:DWORD        ; input함수에 의해 반환되는 값을 핸들링하는 변수입니다.
    							; 이번에 배울 LOCAL 변수입니다.

    mov txtinput, input("Type some text at the cursor : ")
    invoke show_text, txtinput

    ret

main endp

; カカカカカカカカカカカカカカカカカカカカカカカカカカカカカカカカカカカカ?

show_text proc string:DWORD

    print chr$("This is what you typed at the cursor",13,10,"     *** ")
    print string                ; show the string at the console
    print chr$(" ***",13,10)

    ret

show_text endp

; カカカカカカカカカカカカカカカカカカカカカカカカカカカカカカカカカカカカ?

end start                       ; MASM에게 코드가 끝낫다는것을 알려줌

주석과 함께 코드를 읽게되면 오늘은 .DATA?에서 변수를 선언하지않고, 프로시저내에서 정의되지않은 변수를 LOCAL 명령어를 통해 생성하고 다른 프로시저에게 값을 전달하는 것을 배우게 됩니다.

특히나 C호출규약과 STDALL 호출규약에대해서 짤막하게 소개하고있는데, 이에대해 자세히 알아봅시다.

호출규약이란 프로시저(함수)를 호출할때, 매개변수를 어떤방식으로 스택에 올리고, 쓰고난 스택을 누가 정리하는지에대해서 정합니다.

 

C호출 규약은 매개변수를 오른쪽에서 왼쪽순으로 스택에 올리고, 호출자가 스택을 정리합니다. 또한 장점으로는 함수가 정해놓은 매개 변수의 갯수를 따르지않고 가변적으로 매개변수를 줄 수 있습니다.

예를들어, show_text 프로시저가 string:DWORD int:DWORD로 정의 되어있고, main 프로시저가 호출 했다면, int먼저 stack에 올라가고 그다음 string이 stack에 올라갑니다. 이후 show_text프로시저가 끝이 나서 리턴했다면 main프로시저가 넣었던 int와 string을 스택에서 빼서 정리하게됩니다.

 

STDALL 호출규약은 매개변수를 오른쪽에서 왼쪽순으로 스택에 올리고, 피호출자가 스택을 정리합니다.

예를 들어, show_text 프로시저가 string:DWORD int:DWORD로 정의 되어있고, main 프로시저가 호출 했다면, int 먼저 stack에 올라가고 string이 stack에 올라갑니다. 이후 show_text 프로시저가 끝이 나기 직전에 int와 string을 스택에서 빼서 정리하고 리턴하게됩니다.

 

input 함수의 경우 macros.asm 파일에 정의되어있습니다.

prompt:VARARG는 아마 가변 배열 인자를 뜻하는 것같습니다. 또한, 밑에 보시게되면 StdOut 함수와 StdIn함수가 순서대로 사용되며 콘솔에 값을 출력하고 가져오는 함수로 이루어져있는 것을 알 수 있습니다.

즉, input("Type some text at the cursor") 를 사용하게되면 콘솔에 Type some text at the cursor 이뜨게되고 이후에 값을 입력하면 그 값을 리턴하는 함수인 것을 알 수 있습니다.

 

이제 파일을 실행시켜보도록 하겠습니다.

잘 실행이 되는 것을 확인할 수 있습니다.

Comments