[어셈블리어] 리눅스 64비트 환경에서 32비트 프로그램 컴파일하기

2020. 1. 29. 17:29컴퓨터/어셈블리어

컴퓨터가 점점 발전해감에 따라 레지스터도 발전하게 되었습니다.

또한 프로그래밍을 할 때 사용하는 레지스터의 구성도 다르답니다. 아래의 표와 같이 말이죠.

64-bit register Lower 32 bits Lower 16 bits Lower 8 bits

rax

eax

ax

al

rbx

ebx

bx

bl

rcx

ecx

cx

cl

rdx

edx

dx

dl

rsi

esi

si

sil

rdi

edi

di

dil

rbp

ebp

bp

bpl

rsp

esp

sp

spl

r8

r8d

r8w

r8b

r9

r9d

r9w

r9b

r10

r10d

r10w

r10b

r11

r11d

r11w

r11b

r12

r12d

r12w

r12b

r13

r13d

r13w

r13b

r14

r14d

r14w

r14b

r15

r15d

r15w

r15b


(출처 : https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/x64-architecture)

 

x64 Architecture - Windows drivers

x64 Architecture

docs.microsoft.com

 

실제로, 64비트를 지원하지 않는 운영체제나 CPU에서 64비트 전용 프로그램을 실행하면 동작을 하지 않게 됩니다.

또한 램을 4GB까지 밖에 인식을 못한답니다. 그러니까 32비트와 64비트를 모두 실행할 수 있는 64비트를 사용합시다!

 

사실 그게 문제가 아니구요..

"64비트도 32비트에서 발전돼서 만들어진 것이잖아요. 32비트부터 공부해보고 싶어요."

지금 64비트에서 32비트 프로그램을 컴파일해보고 싶어요. 어떻게 할까요?

 


맞아요. 64비트에서 아무 옵션 없이 컴파일을 하면 64비트 프로그램이 컴파일 됩니다. (Machine Dependent)

32비트 프로그램으로 컴파일하고 싶으시다구요?

 

아래의 명령문들을 터미널에 입력해보세요!

$ sudo apt-get install gcc-multilib

무슨 명령어냐구요? 64비트 리눅스에서 gcc를 사용하고 계시다면 64비트 컴파일 라이브러리는 자동으로 설치가 되어 있을 것입니다.

그러나 32비트 컴파일 라이브러리는 설치가 되어 있지 않기 때문에, 설치를 해주셔야 합니다. 설치하지 않고 컴파일을 시도하면 오류가 뜬답니다. 위에는 그 명령어에요.

 

$ nasm -f elf32 -o object.o source.s
$ gcc -m32 -S -o a.out object.o

source.s 어셈블리 소스코드를 a.out 32비트 실행 파일로 컴파일하는 과정이에요.

 


컴파일은 완료했습니다.

한번 실행을 해볼까요?

$ ./a.out

 

오류가 생기나요?

실행이 잘 된다면 당장 이 페이지를 나가셔도 좋습니다. :D

 

하지만 리눅스 순정 상태라면 오류가 날 수 밖에 없을텐데요..

32비트 실행 라이브러리가 없기 때문입니다.

참 복잡하죠? 그래도 명령어 한 줄이면 끝납니다.

$ sudo apt-get install libc6:i386 libncurses5:i386 libstdc++6:i386

끝났습니다. 다시 실행을 해보시면 오류 없이 잘 실행이 될 것 입니다.

 


여기까지 읽어주신 분들에게 감사하다고 말씀드리고 싶네요.

만약 32비트로 컴파일 한 뒤에 레지스터들의 동작 모습이 궁금하시다면 디버거를 통해 한 줄 씩 실행해보시길 바랍니다. 생각보다 흥미로워요. 

디버거는 gdb를 사용하시면 됩니다. pwndbg(필자 사용중)도 추천드려요.

읽어주셔서 감사합니다. xD

 

P.S.) C언어가 32비트 어셈블리어 코드로 어떤 모양으로 변환되는지 궁금하신 분들은 아래 명령어를 사용해보세요.

$ gcc -m32 -S -o source.s source.c

32비트로 컴파일하는 옵션은 nasm의 elf32와 gcc의 -m32입니다.

elf64로 바꾸고 -m32 옵션을 지우면 64비트 파일이 컴파일 될 것입니다.

똑같은 작동을 하지만 모습이 다른 32비트와 64비트의 소스를 비교하면 좋은 경험이 될 것 같네요.