Assembly어로 Hello World 출력해보기

c0wb3ll ㅣ 2019. 11. 9. 17:46

Hello World 어셈블리어로 출력하기 (동빈나 님 영상)

image
  1. nano helloworld.s 입력

    nano -> nano 명령어는 리눅스 시스템에서 기본적으로 제공하는 편집기 nano를 사용하는 명령어다.
                nano helloworld.s 를입력함으로 helloworld.s 라는 어셈블리어 파일(.s)을 만들고 편집하겠다는 것                을 의미한다.

image

(nano 편집기 화면)

image

일단 hello world를 출력하는 어셈블리어 코드이다.
이제부터 내용을 살펴보자.

내용을 살펴보려면 우선 레지스터에 대해 알아보아야 하는데
우리가 현재 사용하는 레지스터는 64bit 레지스터이기 때문에 간단한 설명을 해보겠다.

1-1 data register

명령어(영어) 레지스터 명(한글) 역할
rax 누산기 레지스터 시스템 콜(system call)의 실질적인 번호를 부르는 레지스터 이며
함수가 실행된 다음에 그 결과값이 저장되는 레지스터
rbx 베이스 레지스터 메모리 주소를 지정하는데 사용
rcx 카운터 레지스터 반복문에 사용
rdx 데이터 레지스터 연산을 수행할때 rax와 함께 사용되는 레지스터

 

1-2pointer register

명령어(영어) 레지스터 명(한글) 역할
rsi 근원지(source) 인덱스 레지스터 메모리를 이동하거나 비교할 때 출발지 주소
rdi 목적지(destination) 인덱스 레지스터 메모리를 이동하거나 비교할때 목적지 주소를 가르킴
rbp 베이스 포인터 레지스터 함수의 파라미터나 변수의 주소를 가르킬 때 사용
rsp 스택 포인터 레지스터 스택에서 삽입 및 삭제가 일어날 때
변경되는 스택에서 최상위에 있는 주소를 가르키는 레지스터

1-3그 외 레지스터

명령어 역할
r8 ~ r15 함수의 매개 변수로서 사용

 

2-1 system call 이해하기

image

다음 블로그( https://blog.rchapman.org/posts/Linux_System_Call_Table_for_x86_64/ )에서 가져온 사진으로 대충 설명해보자면
rax값이 0이라면 sys_read 함수를 사용하게 된다.
위에 만들 helloworld.s 파일로 설명해 보겠다. 우선
mov rax, 1      로 rax에 1에 값을 담아 sys_write 함수를 실행시키고
mov rdi, 1      로 file discriptor( 파일 디스크립터에 대한 설명 : https://en.wikipedia.org/wiki/File_descriptor )에                        1에 값을 담는다. 일반적으로 file discriptor 1 은 write를 의미한다. 그 다음
mov rsi, msg   로 위에서 입력한 msg 즉 "Hello World" 를 입력받고
mov rdx, 12     로 hello world를 표현할 수 있는 사이즈를 만들어준다. 그 후
syscall            로 함수를 실행시키고
mov rax, 60     여기서 rax 60 은 sys_exit()이다. 즉, 함수를 종료하는 것 mov rdi, 0 으로 에러코드를 입력해준뒤                         종료시킨다.

자 그럼 이제 파일을 만들어 실행시켜보자

image-20191109173531666

위 명령어를 입력해 목적코드를 만들어 준다. (목적코드에 대한 설명 : https://ko.wikipedia.org/wiki/%EB%AA%A9%EC%A0%81_%ED%8C%8C%EC%9D%BC )

image-20191109174205634

다음 명령어로 만든 목적 코드로 실행 프로그램을 만들어준다.

image

그런 다음 실행해주면 Hello World 라는 문자가 출력된다!