다음 이전 차례

2. 어셈블러들

2.1 GCC 인라인 어셈블리

잘 알려진 바와 같이, GNU 프로젝트에서 중요한 위치를 차지하고 있는 최적화된 32비트 컴파일러인 GNU C/C++ 컴파일러 (GCC)는 x86 아키텍쳐를강력하게 지원 한다. 그리고 C 프로그램안에 어셈블리 코드를 삽입할 수 있는 능력을 제공한다. GCC 는 대부분의 가능한 플랫폼에서 동작한다. 그중에서도 Linux, *BSD, VSTa, OS/2, *DOS, Win*, 등등..

GCC가 있는 곳

GCC 원본사이트는 prep.ai.mit.edu/pub/gnu/ 에 다른 GNU 계획에 의한 어플리케이션 소프트웨어들과 같이 발표된다. 그리고, 또한 많은 미러 사이트들이 존재하고 있다. 여러분들의 개방적인 OS에 맞도록 개정된 소스들과 미리 컴파일된 바이너리들이 통상적인 FTP 사이트에있다. inux 의 GCC를 사용한다면 아래에 가본다. www.linux.org.uk/ 가장 인기 있는 도스기반의 GCC는 DJGPP이다. 다음 사이트의 디렉토리에서 발견할 수 있다: www.delorie.com/djgpp/ OS/2 기반의 도스에서 작동하는 GCC는 또한 EMX라 불린다; www.leo.org/pub/comp/os/os2/gnu/emx+gcc/ warp.eecs.berkeley.edu/os2/software/shareware/emx.html

GCC 인라인 어셈블리 DOC들을 구하는 곳

GCC 문서는 texinfo 포멧으로 문서파일들을 포함한다. 당신은 그것을 텍스로 변 환할 수 있고, 텍스로 컴파일 할수도 있으며, 프린트를 하던지, 이막스 .info파일 이나 브라우저, 기타 여러분들이 좋아하는 포멧으로 변환할 수 있다. .info 파일은 GCC의 괜찮은 설치본에는 들어 있는 것 같다. 그 부분은 다음과 같다: C 확장::확장된 Asm:: 부분 GCC 불러오기::서브모델 옵션::i386 옵션:: 이러한 것들이 도움이 될 것이다. 세세하게 보면, 그것은 i386의 레지스터를 위 해 특별히 규정된 이름을 제공한다: abcdSDB 는 %eax, %ebx, %ecx, %edx,%esi, %edi, %ebp 와 하나씩 일치한다. (%esp에는 글자가 배당되어 있지 않다.) HTML 포멧으로 변환된 이러한 문서들과 부분들의 URL은 다음과 같다. www.cygnus.com/doc/usegcc_89.html#SEC92 DJGPP 게임리소스 (게임 해커들에게 뿐만이 아니라)는 특별하게 어셈블리에 관한 이러한 페이지를 가지고 있다: www.rt66.com/~brennan/djgpp/djgpp_asm.html 마지막으로, 이러한 웹페이지들은 "DJGPP Quick ASM Programming Guide" 로 불리워지고 FAQ들과 AT&T x86 어셈블리 문법, 몇몇의 인라인 어셈블리 정보, .obj/.lib 파일들을 변환하는 것들에 대한 것들로 가득차 있다. remus.rutgers.edu/~avly/djasm.html

GCC 는 어셈블링에서는 GAS에 의존하고 아래의 문법을 따른다; 인라인 어셈블리는 인용된 퍼센트 문자를 필요로 한다. 그래서 그것들은 GAS 에게로 건네진다. 아래의 GAS에 대한 부분을 보자. 많은 유용한 예제들을 리눅스의 linux/include/asm-i386/ 소스 서브디렉토리 에서 찾아보자.

어떻게 GCC 안에서 정확히 어셈블리 코드를 불러내는가?

최적화와 인라인 어셈블리를 가능하게 하기 위해서 GCC 를 "-O" 플래그와 같이 불러내자. 그렇게 하지 않는 다면, 코드는 컴파일되기는 하나, 정확히 동작하지 않을 것 이다. 좀 더 일반적으로, x86 플랫폼에서 좋은 컴파일 플래그는

         gcc -O2 -fomit-frame-pointer -m386
정도가 될 것이다. -O2 는 좋은 최적화 레벨이다. 최적화에 더하여 컴파일러는 코드를 크게 만든다. 그러나 그것은 단지 bit faster일 뿐이다; 그러한 과다한 최적화는 루프를 타이트하게 만드는 데 정도에만 유용할 수 있다. 여러분들이 어떻게든 어셈블리에서 사용한다면 말이다. 그것이 필요하다면 필요한 만큼만의 루틴들에 사용하라. -fomit-frame-pointer 는 stupid frame pointer maintenance를 건너뛰게 코드를 생성시키고, 코드를 좀더 작고 빠르게 만들며, 그 이상의 최적화를 위해서 레지스터를 자유롭게 한다. 이것은 디버깅 툴(gdb)들을 사용하기 어렵게 만들긴 하나, 더이상 사이즈와 속도 를 향상 시킬 수 없을 것이다. -m386 은 어떠한 속도의 저하없이 좀 더 콤팩트한 코드를 생성해 낸다. ( 작은 코드는 또한 디스크 입출력을 적게 수행하고 빠른 실행을 한다는 것을 기억하자.) 그러나 아마도 위에 언급한 타이트한 루프상에서 일 것이다. 좀더 최적화 하려면, -mregparm=2 옵션이나 이에 대응하는 함수가 도움이 될 것이다. 그러나 외부 코드와 링킹을 할때에는 많은 문제점들이 여러분들을 괴롭히게 될 것이다. 여러분들은 이러한 플래그들을 기본설정파일인
         /usr/lib/gcc-lib/i486-linux/2.7.2/specs
에 추가할 수 있다. (이 파일은 시스템에 따라 조금 틀릴 수 있다.)

2.2 GAS

GAS는 GCC와 한쌍으로 움직이는 GNU 어셈블러이다.

어디서 찾을 수 있는가

binutils라 이름붙여진 패키지 속에 GCC가 있는 같은 곳에서 찾을 수 있다.

AT&T 문법은 무엇을 말하는가

GAS는 32비트 유닉스 컴파일러를 제공하기 위해 창안되었기 때문에 표준 AT&T 문법을 이용한다. AT&T 문법은 많은 것들이 표준 680x0 어셈블러와 닮았다. 이 문법은 "Intel" 문법에 비해서 좋지도 않고, 나쁘지도 않다. 단지 다를 뿐이다. 여러분들이 그것을 사용해보게 되면, 인텔 문법에 비해 좀더 많은 규칙이 있음 을 알게 될 것이다. 여러분들이 프로그램을 변환하는 것을 돕기 위한 프로그램이 존재한다. 이것은 TASM 문법을 AT&T 문법으로 변환하는 것이다. ftp.oulu.fi/pub/msdos/programming/convert/ta2asv08.zipgas.doc 이나 as.doc파일(GAS를 찾은 같은 곳 주위에 있을 것이다)은 그 문법을 기술한다. 다음의 FTP 디렉토리에 있다 sunsite.unc.edu/pub/linux/GCC/ sunsite.doc.ic.ac.uk/packages/linux/sunsite.unc-mirror/GCC/ (?) 다시한번 이야기하지만, 리눅스에는 괜찮은 예들이 들어있다; 아래의 linux/arch/i386의 다음 파일들을 보라: kernel/entry.S, kernel/head.S, boot/compressed/head.S, mathemu/*.S

2.2.3 제한된 16비트 모드

GAS 는 32비트 어셈블러이며 32비트 컴파일러를 제공한다는 것을 의미한다. GAS 는 현재 제한된 16 비트모드를 제공하는데, 그 16비트모드는 미리 예비된, 명령어들의 32비트 접두어로 이루어져 있으며, 따라서 32비트 CPU상의 16비트 모드에서 돌아가는 32비트 모드를 쓸 수 있다. 양모드에서 공히, 그것은 16비트 레지스터 사용이 가능하나, 16비트 어드레싱 은 제공하지 않는다. 모드사이를 전환하려면 "code16"과 "code32"의 지시자를 사용하라. 인라인 어셈블리에서의 asm("code16\n") 상태는 32비트 GCC로 하여금 리얼모드! 에서 돌아가는 코드를 만들것을 허용한다. 여러분들이 필요하다고 느낀다면 풀 16비트를 사용함으로써 마음껏 누려보자.

2.3 2.3 GASP

GASP 는 GAS의 전처리기이다. 이것은 GAS에 매크로와 몇몇 괜찮은 문법을 추가시킨다.

2.3.1 GASP를 어디서 찾을 것인가

나는 정확하게 모른다. GNU 사이트 (prep.ai.mit.edu & mirrors)를 보기바란다. 아마도 GAS와 같이 binutils 패키지에 같이 있을 것이다.

2.3.2 GASP는 어떠한 일을 하는가

난 아무 생각이 없다, 그러나 그것은 자체의 texinfo 문서가 따라올 것이다. 그래서 그것을 프린트 해서 보라, 아니면 .info 파일들을 브라우즈하기 바란다. 매크로 어셈블러의 규칙을 나에게 보내주면 좋겠다.

2.4 2.4 AS86

AS86은 Bruce Evans' C 컴파일러 부분중의 16비트, 32비트를 다 같이 제공하는 80x86 어셈블러이다. 그것은 최근의 인텔 문법을 가지고 있으며 as와 조금 어드레싱 모드를 달리한다.

2.4.1 AS86을 어디서 얻을 수 있는가

완전히 시대에 뒤떨어진 AS86은 HJLu에 의해 배포되며 바로 리눅스 커널을 컴 파일 할 수 있다. 이 패키지는 bin86(현재버젼 0.3)로 되어 있으며 Linux GCC 사이트에서 발견할 수 있다. 그러나 내가 보기에는 리눅스 컴파일링을 제외하고는 아무곳에도 사용되지 않고 있다. 이 버젼은 오로지 해킹된 미닉스 오브젝트 파일 포멧을 제공하며 32비트모드에서 는 조금의 버그가 있는데, 단지 리눅스를 컴파일만 하기 위해서라면 괜찮으리라. 가장 최근의 버젼은 FreeBSD 배포판과 같이 출시되었다. 나는 그것을 다음에서 구했다. ftp.ibp.fr/pub/FreeBSD/packages-2.1/development/bcc-95.3.12.tgz 그러나 그 버젼이 이제 많이 발전했을 것이다. 여러개들 중에서 AS86도 이제 리눅스 GNU a.out 포맷을 지원한다. 그래서 여러분 들도 코드를 리눅스 프로그램에 링크를 시킬 수 있고, 데이타를 다루기 위해 GNU binutil 패키지의 보통의 툴을 사용할 수 있을 것이다. 이 버젼은 이전의 것들과 함께 아무런 손상없이 공동으로 존재할 수 있다. (아래의 질문 2.4.4를 보라). BCC 의 1995.3.12 이전의 버젼들이 실수한 이유는 32비트 모드 프로그래밍 시에 모든 세그먼트 팝과 푸쉬를 16비트로 처리함으로써 매우 번거롭게 된 데 있었다. 그 패치가 Tunes 프로젝트에 의해 다음에 발표되었다. www.eleves.ens.fr:8080/home/rideau/Tunes/ 보조페이지는 files/tunes.0.0.0.25.src.tgz 이다. 풀린 서브디렉토리의 LLL/i386/ 그 패치는 또한 바로 다음에서 찾을 수 있다. www.eleves.ens.fr:8080/home/rideau/files/as86.bcc.patch.gz Bruce Evans 는 이 패치를 받아들였는데, 가장 최근의 bcc 버젼은 이 패치 를 포함하고 있다. 도스 사용자를 위한 주의사항:

doc들을 어디서 찾을 수 있는가

doc들은 bcc 패키지에 포함이 되어 있다. 맨페이지도 또한 FreeBSD 사이트의 어 느 곳이던지 구할 수 있을 것이다. 의심이 간다면, 그들 소스에 가끔 괜찮은 doc들이 있다: 그리 잘 설명이 된 것은 아니지만, 프로그래밍 스타일은 깨끗하게 되어 있다. 관심이 있다면 Tunes 0.0.0.25 에서 어떻게 as86이 사용되었는 지를 살펴보라.

어떻게 어셈블러를 불러오는가 ?

bcc를 사용해서 .s 어셈블리 소스 파일을 GNU a.out .o 오브젝트 파일, .l 리스팅 파일로 변환하는 GNU 메이크 파일의 예를 하나 들어보자.

%.o %.l:       %.s
         bcc -3 -G -c -A-d -A-l -A$*.l -o $*.o $<
어떠한 리스팅 파일도 뭔하지 않는다면 "%.l", "-A-l", "-A$*.l"을 없애라. GNU a.out 이외의 것을 얻고자 한다면 bcc doc중에서 다른 제공하는 포맷에 대한 글을 보거나 GNU binutils 패키지의 objcopy 유틸리티를 사용할 수 있다.

이 새로운 버젼으로 리눅스를 컴파일 할수 없다면 어떻게 해야 하는가?

리누스는 메일로 왕성하게 활동하고 있다. 리눅스 a.out as86으로 리눅스를 컴 파일하는 나의 패치도 그것을 만들지 못한다. 이제, 이것들이 성공하지 못한다면: bin86 페키지안의 /usr/bin에 있는 여러분들의 as86 을 가지고 있고, 더 좋은 as86을 /usr/local/libexec/i386/bcc/as에 가져다 놓아라. 아마도 이 "좋은" as86을 부를 필요가 더이상 없을 것이다.

2.5 다른 어셈블러들

Win32Forth 어셈블러

Win32Forth 는 Win32s, Win95, Win/NT에서 훌륭하게 돌아가는 프리 32비트 FORTH 시스템이다. 그것은 어셈블러에 통합된 프리 32비트 어셈블러(접두사 또는 접미사 문법)를 포 함하고 있다. 매크로 처리는 사려깊은 FORTH 언어의 full power에 의해 처리된다. 그러나 단지 입출력은 Win32For 그것 자체를 이용할 뿐이다. 다음에서 찾을 수 있다. ftp.forth.org/pub/Forth/win32for/

NASM

네트워크 상에서 벌어지고 있는 어셈블러 프로젝트는 아직 다른 어셈블러를 만들기 위해 노력하고 있는 중이다. 이것은 C에서 쓰여졌는데, 모든 알려진 문법들과 오브젝트 포맷들을 제공하는 데 충분한 모듈러가 될것이다. 현재 버젼은 조금의 매우 간단한 문법들과 평이한 바이너리 출력에 있어서는 잘돌아간다; 매크로 프로세싱에는 흥미가 없어보인다. 확실히 NASM은 이 하우투가 업데이트 되는 것 보다 빠르게 발전하고 있다; 그렇다고 NASM이 현재 요구되는 모든 특징들을 가지고 있을 것이라고 기대하 지는 말라. 적어도 여러분들이 그것의 계획이행을 도울 준비없이는... www.dcs.warwick.ac.uk/~jules/nasm1.html

Tunes

Tunes OS 프로젝트는 그들 자신의 어셈블러를 Scheme 언어를 사용함으로써 전체 개발 수행의 일부분으로 개발하고 있다. 그것은 아직 잘 돌아가지 않고 있으며 도움을 필요로 하고 있다. 이 어셈블러는 심볼릭 문법 트리를 처리하는 데, 이것은 어셈블리 문법의 기초로 동등하게 서비스 될 수 있으며, 디스어셈블러, 공통 어셈블러/컴파일러 back-end 등등의, 그리고 전정한 언어인 Scheme의 풀파워는 매크로처리/메트로처리에 있어서 타의 추종을 불허한다. www.eleves.ens.fr:8080/home/rideau/Tunes/

프리가 아니거나 32비트가 아닌 x86 어셈블러들

여러분들은 x86 어셈블리 프로그래밍의 기본으로서 그것들에 대해 좀더 찾아 볼 수 있다. Raymond Moon의 comp.lang.asm.x86을 위한 FAQ 를 찾아보기 바란 다. www2.dgsys.com/~raymoon/faq/asmfaq.zip


다음 이전 차례