어셈블리 프로그래밍
어셈블리어(영어: Assembly language)는 기계어와 일대일 대응이 되는 컴퓨터 프로그래밍의 저급 언어이다.
컴퓨터 구조에 따라 사용하는 기계어가 달라지며, 따라서 기계어에 대응되어 만들어지는 어셈블리어도 각각 다르게 된다. 컴퓨터 CPU마다 지원하는 오퍼레이션의 타입과 개수는 제각각이며, 레지스터의 크기과 개수, 저장된 데이터 형의 표현도 각기 다르다. 모든 범용 컴퓨터는 기본적으로 동일한 기능을 수행하지만, 기능을 어떤 과정을 거쳐 수행할지는 다를 수 있으며, 이런 차이는 어셈블리어에 반영되게 된다.
게다가 단일 명령 집합에 대해 여러 니모닉과 통사론이 대응될 수 있다. 그런 경우에는 제조사가 만든 문서에서 쓰이는 것이 가장 자주 쓰이게 된다.
출처 : 위키 백과
프로그램이 만들어질떄에는 코드를 짜고난뒤 컴파일러를 통해 기계어로 변역을 한다음 오브젝트 파일을 만들고 링커를 통해 실행가능한 파일로 만들어 짐니다.
어셈블리어는 컴파일 뒤 과정이기 떄문에 오브젝트 파일을 만들고 링커로 실행가능한 파일을 만듬니다.
이떄 오브젝트 파일로 만들어 주는것이 NASM, TASM, GCC 등 이 있습니다. 주로 NASM이 유명합니다.
어셈블리 프로그래밍을 할떄에는 syscall이라는 것을 사용하여 프로그래밍 합니다. syscall은 32비트와 64비트 마다 다릅니다.
32비트 : http://crasy.tistory.com/73
64비트 : http://crasy.tistory.com/75
또한 리눅스 기준으로 /usr/include/asm/unistd.h 에 정의 되어 있습니다.
어셈블리어에는 두가지의 문법이 있습니다. 하나는 Intel문법과 at&t문법이 있습니다.
이 두 문법의 차이는 어셈블리 프로그래밍을 하면서 비교하도록 하겟습니다.
NASM과 GCC를 이용하여 어셈블리 프로그래밍을 해보도록 하겠습니다.
리눅스 기준으로
데비안 계열 sudo apt-get install gcc nasm
레드헷 계열 sudo yum install gcc nasm
우선 NASM을 이용하여 프로그래밍을 하겟습니다.
확장자가 asm인 파일을 만들어 주세요
어셈블리 프로그래밍를 할때 가장 중요한것이 자신의 컴퓨터의 버전에 따라 코드가 달라지는것입니다.
컴퓨터에는 레지스터라는 시피유의 기억장소가 있습니다. 이 기억 장소에 값을 저장하고 그것을 연산합니다.
컴퓨터 버전에 따라서 레지스터가 달라지기 떄문에 주의 하셔야 합니다.
32비트에는 eax, ebx, ecx, edx, edi, esi등이 있습니다. 허나 64비트에는 rax, rbx, rcx, rdx, rdi, rsi 등이 있습니다.
또한 하위호환이 가능해서 64비트에서는 32비트 레지스터와 16비트 레지스터를 사용 가능합니다.
또한 32비트에서는 16비트 레지스터를 사용 가능합니다.
레지스터에 알맞은 값을 넣어 줘야만 정상적으로 코드가 작동합니다.
또한 pe 구조를 보면 프로그램에는 섹션으로 분리가 되어 있습니다.
보통 data섹션에는 데이터가 들어가고 text섹션에는 코드가 들어감니다.
어셈블리에서는 변수명 - 자료형 - 데이터 순으로 변수를 만들어 사용할수 있습니다.
데이터 섹션에 들어가며 자료형은 db, dw, dd 등 이 있습니다.
위 코드에서 0x0A는 개행 입니다.
어셈블리에서는 syscall을 사용하는 코드가 시작 하기전 global _start라는 일종의 main함수를 선언해줍니다.
함수가 시작할때에는 : 를 뒤에 붙여서 구분을 해줌니다.
어셈블리에는 코드가 명령어로 구성이 되어 있습니다. 명령어 - 레지스터 및 데이터 값 (OpCode, operand)
또한 명령어는 컴퓨터 버전마다 다르게 나타날 수 도 있습니다.
하나의 syscall에 맞는 레지스터에 값을 넣어 주셧다면 32비트에서는 int 0x80으로 실행을 해주셔야 됨니다. 64비트에서는 syscall로 실행을 합니다.
또한 다 작성하신뒤에는 꼭 종료함수(예 exit)를 사용하여 종료를 해주셔야 합니다.
자 이제 코드에 대한 설명을 했으니 이제 오브젝트 파일을 만들고 실행 가능한 파일을 생성해 봅시다.
그전에 자신의 컴퓨터의 버전을 알아야 합니다. 모르신다면 uname -p로 x86이 나오면 32비트 x86_64면 64비트 입니다.
32비트
nasm -f elf 파일명.asm
64비트
nasm -f elf64 파일명.asm
으로 알맞게 오브젝트 파일을 만들어 줍니다.
오브젝트 파일은 파일명에 확장자가 .o로 생성 됨니다.
ld 파일명.o -o 아웃풋 파일명
-o 옵션을 통해 자신이 원하는 파일명의 실행가능한 파일을 만들수 있습니다 이 옵션이 없으면 기본적으로 a.out이란 파일이 생성됨니다.
실행 가능한 파일을 만드셧다면 실행을 해보시면 hello_world라는 문자열을 보실 수 있습니다.
이제 gcc를 이용한 어셈블리어 프로그래밍을 해보겠습니다.
확장자가 .s인 파일을 만들어 주세요
nasm과 비슷한 부분은 설명을 하지 않겟습니다.
데이터 값, 변수 에는 $이 레지스터에는 %가 앞에 붙어야 합니다.
또 section 이 생략됨니다.
AT&T 문법을 사용합니다.
'Development > Assembly' 카테고리의 다른 글
리눅스 syscall table for x86_64 (0) | 2014.09.18 |
---|---|
리눅스 system table for x86 (0) | 2014.09.14 |
어셈블리어 프로그래밍 helloword (0) | 2014.04.30 |