외로운 Nova의 작업실

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

Programming/Assembly

Assembly 언어 공부 - 5(hello world+)

Nova_ 2022. 5. 19. 21:44

여러분들 ㅎㅇ~~

안녕하세요~~

 

오늘은 저번시간에 이어서 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

 

저번시간에 .data까지 공부했던것같습니다.

이번시간에는 마지막으로 남은 .code를 공부해보도록 하겠습니다.

.code 이후 start라벨의 내용이 시작됩니다.

 

-invoke

먼저 invoke 명령어는 그 다음에오는 함수를 매개변수를 스택에 담고 실행 시킵니다.

invoke말고 call이라는 명령어도 사용할 수 있습니다.

단, invoke는 컴파일러 검사때 매개변수의 type을 검사하여 type이 일치하지않으면 에러를 냅니다.

하지만 call 명령어는 type검사를 실시하지않습니다.

 

-MessageBox

먼저 MessageBox 함수에대해 알아보겠습니다.

MessageBox(윈도우 메시지 생성함수)의 프로토타입(함수의 정의)는 user32.inc에서 찾을 수 있습니다.

위사진에서 아래와 같은 명령줄을 찾을 수 있습니다.

MessageBoxA PROTO STDCALL :DWORD,:DWORD,:DWORD,:DWORD
IFNDEF __UNICODE__
  MessageBox equ <MessageBoxA>
ENDIF

먼저 2~4번째줄에따라서 만약 MessageBox가 정의되어있지않으면 MessageBox를 MEssageBoxA함수의 기능으로 정의합니다.라는 줄이 MessageBox이름으로 함수를 사용할 수 있게해줍니다.

첫번쨰줄 MessageBoxA PROTO STDCALL : DWORD,:DWORD,:DWORD,:DWORD 구문은 MessageBoxA 함수의 PROTO는 함수호출 규약은 STDCALL을 사용하며 매개변수로는 DWORD크기가 4개 있다고 해석 할 수 있습니다.

각 매개변수의 의미는 ms에서 찾을 수 있습니다.

아래는 링크입니다.

https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-messageboxa

 

MessageBoxA function (winuser.h) - Win32 apps

Displays a modal dialog box that contains a system icon, a set of buttons, and a brief application-specific message, such as status or error information. The message box returns an integer value that indicates which button the user clicked.

docs.microsoft.com

위 사진과 링크에따라서 첫번째 매개변수는 메시지 상자 소유자에대한 핸들입니다.

두번째 매개변수는 표시할 메시지(문자열)의 첫번째 주소 입니다.

세번째 매개변수는 대화상자 제목(문자열)의 첫번째 주소 입니다.

네번째 매개변수는 대화 상자의 내용과 동작입니다.

 

따라서 invoke MessageBox, NULL, addr MsgBoxText, addr MsgBoxCaption, MB_OK 이 명령줄은

메시지박스의 소유자는 NULL이고, 표시할 메시지는 MsgBoxText 변수에 담겨있습니다.

하지만 사실 MsgBoxText에는 상대주소(라벨 테이블에 있는 주소)가 들어갑니다.

해당 코드는 응용프로그램이더라도 사용하기전에는 하드디스크에 있게됩니다.

이때 이 코드가 하드디스크에 있을때 MsgBoxText(문자열의 첫번째 주소가 담김) 변수에는 상대주소가 들어가게됩니다.

즉 하드디스크에서 MsgBoxText에는 0x10001000이지만 메모리로 올라오게되면 0x001055ff 일수도 있다는 말입니다.

따라서 addr 지시어로 MsgBoxText 변수의 절대주소를 넣어줘야합니다.

메세지 박스의 제목은 MsgBoxCaption 변수(문자열의 첫번째 주소가 담김)에 담겨있습니다.

MB_OK는 windows.inc에 담겨있는 상수입니다.

쓰고도 뭔말한건지 모르겟네요...

 

 

-ExitProcess

invoke ExitProcess는 kernel32.inc 파일에 들어있습니다.

ExitProcess의 함수의 호출규약은 STDCALL이며 매개변수는 DWORD 하나입니다.

이 함수의 쓰임은 ms에서 찾을 수 있습니다.

https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-exitprocess

 

ExitProcess function (processthreadsapi.h) - Win32 apps

Ends the calling process and all its threads.

docs.microsoft.com

uExitCode는 운영체제에 반환되는 종료코드입니다.

 

따라서 invoke ExitProcess, Null은 프로그램을 종료하고 운영체제에게 NULL 종료코드를 주는 명령줄입니다.

 

-end start

end start는 start 라벨이 끝낫다는 것을 알려줍니다.

 

-컴파일, 링크, 실행

이제 코드를 다 살펴보았으니 컴파일하고 실행 시켜보겠습니다.

아래는 컴파일화면입니다.

아래는 링크하는 화면입니다.

아래는 실행 화면입니다.

 

자, 어셈블리어는 이제 시작입니다!!

고생길이 보이는군요...

 

다음시간에는 뭘 배울지는 모르겠습니다.

아마 window 창말고 콘솔로 출력하고 싶기때문에, 콘솔로 출력하는 방법을 삽질해보고, 어셈블리어 책산것을 실습 및 정리하면서 포스팅 할 것 같습니다.

 

그럼 여러

여러분들 ㅂㅇ~~~

넓고 넓은 컴퓨터의 길...

Comments