외로운 Nova의 작업실

Assembly 언어 공부 - 4(hello world) 본문

Programming/Assembly

Assembly 언어 공부 - 4(hello world)

Nova_ 2022. 5. 18. 23:27

여러분들 ㅎㅇ~~

안녕 여러분들~~~

오늘은 저번 시간에 이어서 어셈블리 MASM의 기본 뼈대와 기본 Hello World를 출력하는 프로그램을 만들어보겠습니다.

 

<MASM의 기본 뼈대>

.386
.MODEL Flat, STDCALL
.DATA
    <Your initialized data>
    ......
.DATA?
   <Your uninitialized data>
   ......
.CONST
   <Your constants>
   ......
.CODE
	label:
		<Your code>
		.....
	end label

위코드는 MASM코드의 기본 뼈대의 구조입니다.

맨위의 코드부터 설명해보도록 하겠습니다.

 

<.386>

.386은 intel의 80386 CPU의 명령어 체계를 사용하겠다는 뜻입니다.

intel 80386 cpu

cpu마다 명령어 체계가 다르기때문에 알려주는 것과 같습니다.

80386 CPU 말고도 80186, 80286 80486 CPU등이 있습니다.

80386, 80486 CPU는 IA-32(Intel Architcture) 명령어 체계를 따르지만, 80186, 80286 CPU의 경우 IA-32 명령어 체계를 따르지않습니다.(하위버전과 186,286의 경우 16비트 명령어 체계이기때문)

따라서 우리는 386부터 상위버전의 CPU 명령어 체계를 많이 사용합니다.

 

<.model flat, stdcall>

.model은 메모리 모델을 명시하는 어셈블리 지시자입니다.

Win32에서는 flat 메모리만 있기때문에 flat을 써줍니다.

stdcall은 MASM에게 파라미터 전달 방식을 알려줍니다.

파라미터는 오른쪽에서 왼쪽순서로 전달합니다. 또한 호출 후에는 호출받은 쪽에서 스택을 되돌려 놓아야합니다.

 

<.data, .data?, .const, .code>

.data, .data?, .const, .code 이 네가지 지시자는 섹션이라고 부릅니다.

메모리공간을 논리적인 섹션으로 나누게됩니다.

다른 섹션을 선언하면 그전의 섹션은 끝나게됩니다.

 

.data섹션의 경우 프로그램에서 초기화된 데이터를 넣습니다.

.data?섹션의 경우 프로그램에서 메모리를 확보할 데이터를 넣습니다.

.const 섹션의 경우 프로그램에서 사용할 상수를 선언합니다.

.code 섹션의 경우 실제 프로그램이 작동하는 코드를 넣습니다.

 

<label>

label의 경우 코드확장을 위한 표시입니다.

모든 코드는 label과 end label 사이에 위치해야합니다.

 

자 이해가 쉽게 되시죠??

이해가 안된다면.. 구글링으....ㄹㄹ..

자 이해하셧다면 이제 뼈대에 살을 붙여서 hello world를 출력하는 프로그램을 만들어보도록 하겠습니다.

 

<Hello world 출력 프로그램>

백문일 불여일견 먼저 출력하는 프로그램의 코드를 먼저 보시겠습니다.

.386
.model flat, stdcall
option casemap:none
include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
includelib \masm32\lib\kernel32.lib
include \masm32\include\user32.inc
includelib \masm32\lib\user32.lib

.data
MsgBoxCaption db "Hello world program", 0
MsgBoxText db "Hello world!", 0

.code
start:
    invoke MessageBox, NULL, addr MsgBoxText, addr MsgBoxCaption, MB_OK
    invoke ExitProcess, NULL
end start

위에서부터 살들을 설명해보도록 하겠습니다.

 

먼저 option casemap:none은 대소문자를 구별해달라는 지시어입니다.

MASM은 대소문자를 기본적으로 구별하지않거든요..

 

include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
includelib \masm32\lib\kernel32.lib
include \masm32\include\user32.inc
includelib \masm32\lib\user32.lib

include 지시어를 설명하기전에 .inc파일과 .lib파일에대해서 이해해야합니다.

inc파일은 컴파일때 필요하고 lib파일은 실제 응용프로그램을 만들때 필요합니다.

우리가 어셈블리를 작성할때 WORD나 DWORD의 자료형을 씁니다.

하지만 이러한 자료형도 어딘가에 선언이 되어야 컴파일러가 오류를 내지않고 컴파일을 해줍니다.

이 어딘가가 inc파일입니다.

include 지시어를 쓰게되면 컴파일러는 inc파일을 내가 만든 프로그램에 복붙하여 코드를 검사합니다.

따라서 우리가 직접 DWORD를 선언하지 않았더라도 windows.inc파일에 들어있는 DOWRD의 선언문을 보고 패스하게됩니다.

컴파일러는 이제 오브젝트 파일을 만들게됩니다.

하지만 오브젝트 파일에는 DOWRD는 '선언'만 확인됫을뿐(inc파일을통해) ''정의'문은 어디에도 없습니다.

이때 정의문은 windows.lib파일에 있습니다.

windows.lib파일은 오브젝트 파일임으로 링크할때 링크가 lib파일들을 내가 만든 코드에 연결시킵니다.

그다음 응용프로그램을 만드는 것입니다.

하지만 사실 windows.lib파일은 없습니다.

windows.lib은 운영체제 자체에 기록되어있기때문에 필요 없는 것입니다.

또한 lib을 include하실때는 includelib을 사용하셔야합니다.

 

.data
MsgBoxCaption db "Hello world program", 0
MsgBoxText db "Hello world!", 0

위 두가지 문장은 프로그램에서 쓰는 데이터를 정의한것입니다.

MsgBoxCaption 변수에 db(1byte)를 할당하고 "Hello World Program",0 (NULL)의 시작주소를 넣어라 라는 문장입니다.

아래 MSgBoxText 변수도 같은 의미입니다.

 

.code부분은 다음시간에 이어서 하겠습니다.. 너무 힘드네요..

저도 처음 배우는 것들을 정리해서 올리는 겁니다ㅠㅜ

그러니 제 발자취를 따라오시는분들도 할 수 있습니다!!

 

내일 충전해서 내용 이어가도록 하겠습니다..(이해부탁,,,)

여러분들 ㅂㅇ~

인생,,,,,쓰다

 

Comments