본문 바로가기

Programming Language/Assembly

Visual Studio 2013에서 어셈블리어 코딩 후 실행하기

336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.

 Visual Studio 2013은 MASM 어셈블러가 내장되어 있습니다. 별도의 어셈블러 등 추가 설치 없이 설정만으로 어셈블리어 프로그램을 작성할 수 있습니다.

 1단계. [파일(F)]-[새로 만들기(N)]-[프로젝트(P)]를 클릭합니다. [새 프로젝트] 창에서 [Visual C++]-[Win32 프로젝트]를 선택합니다. 프로젝트 이름을 지정하고 [확인] 버튼 누릅니다.


 2단계. 응용 프로그램 마법사 화면에서 응용 프로그램 종류를 [콘솔 응용 프로그램]에 두고 추가 옵션에서 [빈 프로젝트]를 선택한 후 [마침] 버튼을 누릅니다.


 3단계. 이 프로젝트에서 MASM을 사용하기 위해서는 솔루션 탐색기에서 프로젝트를 선택 후 마우스 오른쪽 버튼을 누르고 [빌드 종속성(B)]-[사용자 지정 빌드(B)]를 클릭합니다.

 4단계. [사용 가능한 빌드 사용자 지정 파일(A):]에서 masm(.targets, .props)를 클릭 후 [확인]을 누릅니다. 이와 같이 간단한 클릭만으로 프로젝트에서 MASM으로 어셈블리어로 작성된 소스코드를 어셈블 할 수 있습니다.

 5단계. 이제 어셈블리어 코드를 작성해 보겠습니다. 솔루션 탐색기에서 프로젝트 선택 후 마우스 오른쪽 버튼을 누르고 [추가(D)]-[새 항목(W)]을 누릅니다.

 6단계. 새 항목 추가 화면에서 [Visual C++]-[코드]-[C++파일 (.cpp)]을 선택 후 파일 이름을 main.asm으로 지정합니다. 확장명이 가급적 asm 또는 s여야 합니다.

  7단계. 이 파일을 MASM으로 어셈블 하겠다고 지정해야 합니다. 솔루션 탐색기에서 main.asm을 선택 후 마우스 오른쪽 버튼 누르고 [속성(R)]을 누릅니다.

8단계. 속성 페이지에서 [빌드에서 제외]는 "아니요"를 선택합니다. 항목 형식은 Microsoft Macro Assembler로 선택합니다.

 9단계. printf, scanf, gets, puts 등의 C함수를 사용하기 위해서는 "libc" 라이브러리를 프로젝트에 추가해야 합니다. 만일 printf 함수를 호출하는 부분에서 "printf 기호를 찾을 수 없습니다." 종류의 오류가 뜬다면 프로젝트를 선택 후 마우스 오른쪽 버튼을 눌러 [속성(R)]을 클릭합니다.

10단계. 속성 페이지에서 화면 상단의 구성이 활성(Debug)로 되어 있을텐데요. 이를 모든 구성으로 바꾸어줍니다. 그런 다음 화면 왼쪽의 [구성 속성]-[링커]-[입력] 메뉴로 들어가 추가 종속성을 클릭합니다. <편집...>버튼을 누릅니다.

 11단계. kernel32, user32, gdi32 등 Windows API를 위한 라이브러리들이 기본으로 설정되어 있는데, 여기에 libcmt.lib를 적고 [확인]을 누릅니다. 구형 Visual C++은 libc.lib였다고 하는데, 최신 버전은 기능이 약간 바뀐 libcmt.lib로 이름이 변경되었습니다.

 12단계. [추가 종속성] 항목이 아래 그림과 같이 굵은색으로 바뀌었는데, [확인]을 누릅니다.

13단계. 이제 어셈블리어 코드를 작성해 보겠습니다. libcmt.lib에 있는 C함수들을 사용하기 위해서는 먼저 _heap_init(1), _mtinit(1), _ioinit(1)의 순으로 내부 함수 호출이 필요합니다. exit와 printf는 C 라이브러리에 있는 그 함수 맞습니다. 아래와 같이 코드를 적고 Ctrl+F5를 눌러봅니다.

.386
.model flat, c
.stack 4096
.data
	message db "Hello, World!", 0Dh, 0Ah, 00h

.code
	extern _heap_init: proc
	extern _mtinit: proc
	extern _ioinit: proc

	extern exit: proc	
	extern printf: proc

	main proc
		; _heap_init(1) 호출
		push 1
		call _heap_init
		add esp, 4

		; _mtinit(1) 호출
		push 1
		call _mtinit
		add esp, 4

		; _ioinit() 호출
		call _ioinit

		; main() 함수 본문 시작
		; C언어로 printf(message);의 한 줄은 아래와 같이 push, call, 스택정리(add esp, 4)의 3줄로 표현됩니다.
		push offset message
		call printf
		add esp, 4

		; exit(0) 호출
		push 0
		call exit
		add esp, 4

		; return 0
		xor eax, eax
		ret
	main endp

	end main

실행 결과는 다음과 같습니다.