2014년 1월 4일 토요일

아키텍쳐의 특성과 어셈블리 - ARM 아케텍쳐 (완결)

2. ARM



1) 정의와 변천



초기엔 생소했지만 스마트폰이 많이 보급되면서 지금은 접하기 쉬운 아키텍쳐명이 ARM일 것이다.
ARM 아키텍쳐는 ARM이라는 회사가 직접 CPU를 만들어 파는 것이 아닌 IP(Intellecual property)를 파는 업체다.
즉 CPU의 소스코드를 파는 업체라는 뜻이다.
CPU의 소스코드라 하면 일부 분들은 당황 할 수 있을 것이다.
“CPU가 하드웨어인데 소프트웨어마냥 소스코드라니.. 회로도 말인가?”
초기 반도체를 설계할 때에는 로직도를 그려 제작하였다.
하지만 반도체 기술의 발전으로 로직 자체를 언어로서 표현하여 로직간의 관계를 프로그래밍 하여 테스트할 수 있는 프로그래밍 가능한 칩(CPLD,FPGA)에 넣어 시험해 볼 수 있게 되었다.
일부 제품은 반도체를 직접 ASIC으로 만들지 않고 CPLD나 FPGA 상태로 양산하기도 할 정도로 가격과 성능이 좋아 졌다.
이런 반도체 개발 방식의 변경은 각종 하드웨어 기능을 소스로서 거래를 가능하게 했고, 이렇게 CPU소스부분만 판매하는 업체 중 하나가 바로 ARM 인 것이다.
소프트웨어를 제작하는 사람이 사용할 라이브러리를 구매하여 사용하듯, ARM을 가지고 SOC(System on chip)을 만들고자 하는 사람은 구매하고자 하는 ARM의 버전을 결정하고 주변기기로 사용할 IP들도 같이 구매하여 서로 연결되고 관리하는 부분의 코드를 추가하여 완성하게 된다.
물론 코드만 완성하고 FPGA로 디버깅을 한다고 해서 끝나는 것은 아니다.
FPGA 와 ASIC간의 특성 차이도 있기 때문에 완성된 코드를 디자인 하우스에 맡겨 최적화 및 특성 조정을 한 후 반도체 제작 공정에 들어가게 된다.


ARM과 x86의 대표적인 차이라면 RISC와 CISC다.
RISC는 대부분의 연산을 레지스터 상에서 하기 때문에 한 클럭에 수행되는 명령이 적다.
대신 명령 하나하나가 단순해서 구현하는 시스템의 속도를 높이기가 수월하다.
하지만 intel이 x86의 성능 향상을 위하여 많은 투자를 하면서 이 경계가 모호해졌다.
펜티엄 이후부턴 내부적으로 CISC명령을 RISC수준의 명령으로 풀어 적절한 파이프라인에 할당하는 슈퍼스케일러스가 적용되었기 때문이다.
다른 연재에서도 다루겠지만 이런 구조는 x86을 보다 빠르게 만드는 장점이 되기도 했지만, x86와 같은 CISC특유의 강점인 쉬운 원자화구현을 더이상 하기 어렵게 만드는 원인이 되기도 하였다.
사실 요즘처럼 멀티코어가 기본으로 쓰이게 된 시절에는 기존 x86의 원자화는 의미가 없을태니 강점이 없어졌다고 할 수 없다.


ARM은 초기 저전력 고효율을 목표로 시작한 CPU다보니 MMU조차 없었다.
임베디드 환경에서는 가상메모리로 PC처럼 하드디스크로 메모리 스와핑을 할 일이 없을 것이라는 생각이었던 것 같다.
하지만 리눅스가 임베디드로서 본격적으로 사용되기 시작하고, 저가 CPU를 여러개 쓰는 것 보다 고성능 CPU하나에 멀티테스킹을 사용하는 것이 효율적으로 생각되면서 ARM은 MMU를 추가하게 된것 같다.
공정이 점점 낮아지면서 저 전력으로 보다 많은 로직을 내장 할 수 있게 되자 JAVA 가속기능과 MAC연산기능,SIMD명령등을 추가하게 된다.
여기서 잠깐 SIMD에 대해 언급하고자 한다.
간혹 SIMD 명령이 DSP와 비슷할 것이다라고 예상하는 분들도 계실 것이지만, 널리 쓰이는 DSP들은 SIMD 아키텍쳐가 아닌 병렬 명령실행이나 입력가 출력 메모리 영역의 분리를 통한 순차 연산등을 사용한다.
초기에는 DSP는 멀티미디어와 같은 배열 연산이나 부동소숫점 연산을 빠르게 할 수 있다는 장점을 가지고 있었지만, 범용 CPU들이 슈퍼스케일러스와 SIMD명령 내장으로 오히려 범용 CPU가 DSP보다 빠른 경우도 많다.


2) 개발 시 발생할 수 있는 문제


필자가 ARM으로 개발 할 때 제일 두려웠던건 오류(BUG)였다.
개발자가 자신이 만든 소프트웨어의 BUG를 두려워하는건 당연하지만, 여기서 말하는 것은 CPU의 BUG다.
ARM의 의도는 자신이 판매한 IP를 사용하는 CPU간에는 컴파일러가 서로 호환되도록 하는 것이었을탠데 실제로는 그러질 못했다.
CPU제작자들은 구입한 IP를 이식하는 과정에서 실수가 발생하는 경우가 많았기 떄문이다.
천하의 Intel도 Pentium 때처럼 눈에 띄는 연산 오류부터 눈에 잘 안보이는 작은 오류도 만드는데 이보다 작은 업체들의경우는 더욱 심각 할수 있을 것이다.
더우기 몇몇 업체들은 자신이 만들 제품의 목적에 맞춰 성능을 강화하려고 수정을 시도하는 경우도 있었다.
이러다 보니 ARM은 일반적으로 공개된 컴파일러를 사용하지 못하는 경우가 많았다.
임베디드 개발자들 사이에 널리 퍼진 이야기 중 하나가 “SOC를 개발할 때에는 컴파일러를 업체에서 준 것을 사용하라!” 라는 것이다.
리눅스는 PC에서 다른 아키텍쳐 용 결과물을 출력해 주는 컴파일러를 크로스컴파일러( Cross compiler) 또는 툴체인(Tool chain)이라 한다.
툴체인의 설정상태는 자신이 사용 할 수 있는 라이브러리등 여러 제약을 주기 때문에 잘 파악한 후 사용해야 한다.

데이터의 주소 정렬 위치에도 주의 해야 한다.
Cortex 시리즈로 넘어오고 난 이후 이 문제는 신경을 안 써도 되는 문제였으나, 지금도 여전히 많이 사용되는 ARM9시리즈의 경우 이 부분에 대하여 매우 민감하다.
ARM은 저전력을 목표로 했던 아키텍쳐 답게 초기에는 정렬이 되지 않은 주소 접근에 대한 배려기능이 없었다.
즉, 1byte를 읽을 때는 문제가 없으나 short(2byte)이나 int(4byte)크기로 읽거나 쓰기를 할 경우 주소는 제어하고자 하는 크기의 배수가 되어야 한다.
C언어를 통해 예를 들자면

i = 2;
라는 명령을 수행 한다면 i라는 변수가 char(1byte)타입의 변수일 때는 문제가 없으나 short 일 경우 주소는 2의 배수여야 하고 int일 경우 4의 배수여야 한다.
만약 이 규칙을 어긴다면 수행한 결과값이 잘 못 되거나 예상치 못한 오류가 발생하게 된다.
이런 제약이 일반적인 경우에는 struct align 설정만 잘 되어 있다면 컴파일러가 알아서 피해주지만 네트워크로 들어온 패킷을 분석하거나 하는 경우 곤란한 상황을 접하게 되는 경우가 많다.
네트워크로 들어오는 패킷은 변수크기에 맞춰 정렬되어 있지 않은 경우가 많기 떄문에 이런 값을 읽으려면 1byte 씩 읽어서 조립해서 써야 하는 경우가 발생한다.
Cortex 계열 CPU에서는 정렬되지 않은 주소에 대한 배려가 되어있어 정렬된 데이터를 제어할 때와 수행 성능에서 약간의 차이가 있을 뿐 실행되는 데에는 문제가 없다.
그래도 성능 향상을 조금이라도 더 시키고 싶다면 데이터 정렬은 반드시 하는게 좋다.

Endian 문제도 중요한 문제다.
초기 ARM 아키텍쳐를 사용하는 CPU나 SOC들은 네트워크데이터를 효율적으로 다루기 위하여 Big endian 계열이 많았다.
독립적으로 운영될 때에는 문제가 없었으나 PC와 같은 Little endian 계열 제품과 연동하거나 통신을 할 때에 많은 부하를 주게 되었다.
요즘은 PC와 연동을 중요하게 생각해서 그런지 Little endian으로 나오는 제품들이 많아졌다.



3. 마치면서…


제품을 개발하면서 CPU특성보다 더 힘들게 하는 문제가 많다.
PC계열 소프트웨어의 경우 호환성이라는 문제를, 임베디드 계열 제품을 개발 할 때에는 양산성과 안정성을 좋게 하는 문제가 개발자를 괴롭히게 된다.
오랜만에 글을 연재하게 된 탓인지 아직 할 말은 더 있을 것 같은데 막상 키보드를 잡으면 생각이 안나게 되는것 같다.
부족한 연재지만, 이 글을 시작으로 필자가 경험했던 일들을 올려 읽는 분들이 시행오차를 줄이는데 도움이 될 수 있도록 노력하려 한다.

2013년 12월 28일 토요일

아키텍쳐의 특성과 어셈블리 - x86아키텍쳐 - 32bit, 64bit

3) 32 bit

32비트 초/중기 시절에 와서도 어셈블리는 여전히 많이 쓰였다.
생각보다 DOS의 수명이 길었던 탓과 윈도우의 자원관리 성능 때문이었다.


32bit로 와서 DOS의 1MByte 메모리 영역제어의 한계를 넘어서고자 새로운 OS를 필요로 하였는데, 대표적인 것이 Windows 와 OS/2 였다.
하지만 초기에 나온 OS들이 그렇듯, 사용할만한 어플리케이션 부족이라는 문제와 가정에서의 컴퓨터 활용 용도에서 적지않은 비중을 차지하는 것이 게임이었는데, 새로 나온 GUI 기반 OS들은 그래픽카드 자원 사용을 어플리케이션과 타협하는 부분에 대한 배려가 매우 부족했다.
결국 게임 개발자들은 그래픽카드와 주변기기 성능을 최대한 끌어내기 위해 DOS를 계속 사용하였고 사용자들 역시 게임을 즐기기 위하여 DOS를 계속 사용했다.
게임 개발자들 역시 메모리 사용의 한계를 넘기 위하여 DOS에서 32비트 모드를 사용하고자 했는데 이때 사용한 것이 어셈블러와 Dos-extender 였다.
하지만 Dos-extender를 사용한 다 하더라도 메모리만 해결 될 뿐, 아직 문제는 많았다.


당시 PC 사용자들에게 제일 어려운 문제는 게임등을 실행할 때 자신의 비디오카드나 오디오카드등의 주변기기가 무었인지를 설정 해 주어야 한다는 것과 주변기기를 설치 할 때 장치간 서로 충돌하지 않도록 자원을 설정 해 주어야 한다는 것이었다.
즉, 개발자 뿐 아니라 PC사용자도 자신의 컴퓨터에 대해 잘 알아야 하는 시절이었던 것이다.
이를 해결하려면 32bit OS의 표준화와 게임등을 위하여 적절한 자원 몰아주기 기능의 지원, 주변 기기간 자원 자동 할당 기능이 필요했다.
이런 필요를 느끼던 시절이다 보니, OS독점이라는 빌게이츠의 자리를 차지하고자 32비트 OS를 개발해서 내놓으려는 사람들이 여럿 나타나기 시작했다.
필자도 그중 한 사람이었다.
당시 거의 모든 사람이 비슷한 시작선 상에 있었기 때문에 누가 먼저 OS와 사용자들이 사용하고싶어 하는 어플리케이션을 만드냐가 성공의 관건이었다.
다른 선례를 봐도 알겠지만, 사용자들은 OS의 안정성이나 완성도 보다 어플리케이션을 보고 OS를 택하게 되기 때문에 소수의 개발자가 OS를 만든다는 것은 자동차를 엔진만 완성한 다음 자기가 만들 차를 고객들이 사주길 바라는 것과 같았다.
그래도 그런 도전이 나쁘지 않았던 점은 그 시절 개발자들이 OS를 만들기 위해 노력하다 보니 CPU에 대한 이해도가 높은 편이었다는 것이다.


32bit OS의 초기에도 역시 난립하는 장치들에 대한 device driver가 부족하다는 것이 문제였는데, 특히 device driver를 읽어 실행(loading)하기 전인 booting 할 때 , OS를 저장장치에서 메모리로 읽어 들이는 bootloader라는 프로그램이나 OS 운용 초기 부분에는 여전히 16bit로 운영되는 BIOS에 의지해야 한다는 것이었다.
DOS가 존재하는 한 BIOS는 16bit로 유지되어야 할 필요가 있었다.
따라서 32bit 보호모드 상에서 16bit real mode 코드를 실행 할 수 있는 가상86모드 (virtual 86 mode)의 안정적인 운용이 중요 했다.


시스템 상에서 16bit 코드를 제거한다는 것은 DOS를 더 이상 사용하지 못하게 한다는 것이고, 그 뜻은 32bit OS상에서도 게임을 돌릴 수 있도록 자원운용을 할 수 있어야 한다는 뜻이었다.
Direct X가 7.0 이상으로 자리 잡아갈 때 까지 게임 제작자 들은 OS플렛폼으로 DOS를 선호하는 경향이 많았다.
16bit코드를 가상86모드로 사용한다는 것은 보안 밎 안정성에 적지 않은 추가 노력이 필요하다는 뜻이다.
가상86모드로 돌리는 코드는 OS의 커널이 아닌 검증되지 않은 외부 코드를 사용한 다는 뜻이기 때문이다.
또한 OS커널을 통하지 않은 I/O 에대한 접근을 허용해야 하기 때문에 이로 인한 안정성 저하를 막기 위하여 많은 노력이 필요했다.
Device driver 역시 하드웨어 제작사가 지원을 해주어야 가능하기 때문에 인지도 없는 OS의 안정성은 본의 아니게(?) 낮아질 수 밖에 없었다.
현재의 linux의 드라이버들은 많은 개발자들의 노력 덕에 이루어 진 것이라 할 수 있다.


32bit OS들이 자리를 잡아 가면서 어셈블리의 활용성은 점점 낮아지는 듯 했다.
하지만 인간의 눈높이는 지칠 줄 모르고 높아만 갔다.
8bit에 128Kbyte 메모리를 가지고 잘 사용하다가 16bit에 640kbyte 메모리를 사용하는 시대로 바뀌면서 10년 이상 유지 될 것만 같았지만 얼마 안되 더 높은 성능을 요구받았고 결국 32bit 시대에 와서도 사용자의 요구 사항은 시스템을 넘어 서고야 말았다.
특히 멀티미디어 시대가 오면서 연산량은 대폭 늘어 멀티미디어를 위한 MMX, SSE와 같은 SIMD계열 전용 명령을 추가하게 되었다.
결국 이마저 부족하여 Graphic card가 CPU와 같은 연산을 하게 되는 시대까지 맞이하게 된다.


이러한 멀티미디어 전용 명령이 나오면서 인라인 어셈블리 명령의 형식으로 어셈블리의 사용빈도가 높아지게 된다.
컴파일러의 성능도 많이 발전하여 어설프게 어셈블리로 만드는 것 보다 더 빨라지게 되었지만, 병렬연산을 수행하는 SIMD계열 명령을 순차/직선적인 연산을 위한 언어인 C/C++ 가 최적화하여 사용하기에는 한계가 있었다.
결국 제대로 된 성능을 내기 위해서는 인라인 어셈블리라는 형식으로 구현하는 경우가 많았다.


가속 관련된 부분은 나중에 따로 연재하기로 하겠다.


또한 32bit에서 와서 CPU의 속도 증가를 위한 여러가지 기술들이 들어가면서 , 이 기술들이 제 성능을 내기 위해서 개발자나 컴파일러 제작자가 해야 할 일이 생겼다.
최적화라고 부르는 것이 그것이다.


먼저 pipe line이 도입되면서 branch (점프 관련 명령들, 분기들..) 사용을 줄여야 했고,
Super scalers 가 도입되면서 명령들의 순서에 대해서도 신경을 써야 했다.
자세한 최적화 역시 나중에 따로 연재를 하면서 자세하게 다루기로 하겠다.


이렇듯, CPU를 개발하는 하드웨어 개발자 들도 시스템의 성능을 조금이라도 높이기 위하여 일부 제약이 생기더라도 새로운 기술을 도입하게 됨으로서 소프트웨어 개발자들은, 성능을 높이기 위해 최적화라는 과제가 생기게 되었다.


32bit에 와서 임베디드가 활성화 되기 시작하면서 여러가지 아키텍쳐들이 나왔다.
MIPS, ARM, DSP 등 여러 아키텍쳐가 나왔지만, 필자가 겪어본 것들 중에선 x86이 같은 클럭(Clock)대 비 성능이 x86계열이 좋았다.
Intel과 AMD에서 지속적이고 많은 투자를 해서 효율을 높여서가 아닐까 추측한다.
실제로 500Mhz 18$짜리 x86계열 CPU가 다른 10~20$하는 800Mhz 속도를 가진 ARM이나 MIPS보다 빠른 성능을 내는 경우를 보았다.
물론 ARM도 최근 들어 여러가지 기술들을 내장하면서 많이 빨라지긴 했지만, 추가하는 기술 중 적지 않은 수가 이미 x86에서 예전부터 도입해서 쓰는 기술이었다.
ARM이 성능보다 저전력을 목표로 만든 아키텍쳐이긴 하지만, 사용자가 임베디드, 특히 모바일쪽에서 요구하는 성능이 높아지다 보니, 점점 PC를 따라가게 되는 형태가 되어가는 것 같다.
실제로 요즘 임베디드 제품들이 저전력 구현이 코어 자체가 소모하는 전력 비율을 줄이는 것 보다 아무 일도  안하는 대기시에 CPU의 사용하지 않는 부분을 꺼서 소비를 낮추거나 아예 저전력 저성능 코어와 고성능 고전력 코어를 같이 내장해서 성능이 높게 필요하지 않을 때에는 저전력 코어로, 높은 성능을 필요할 때에는 높은 코어를 돌리는 방식도 사용하고 있다.
물론 이런 방식의 구현이 사용자가 특별한 일을 안 할 때 대기 시간에 대한 배터리 효율이 올라가긴 하지만,  열심히 무언가를 할 때에 대한 효율이 좋아지는 것이 아니라 가끔은 사용자를 기만하는 것이 아닌가 하는 생각이 들기도 한다.


32bit는 약 4GByte 의 주소영역을 지원하는 데, 주변기기등이 사용하는 공간을 제하고 나면 3Gbyte 남짓한 용량만큼 RAM을 장착 할 수 있다.
대형 어플리케이션이 많아지면서 3GByte 라는 메모리 공간으론 부족해 지게 된다.
특히 멀티미디어 분야가 심한데 HD 해상도 그림 한장의 크기가 약 8MByte 가량 차지하므로 3GByte 용량에 300장 가량밖에 못 들어가고 UHD 해상도에서는  그 수는 훨씬 줄어들게 된다.
부족한 주소공간을 확장하기 위하여 16bit에서 80286이 selector 를 사용하여 16MByte 영역을 16bit 주소공간에 연결하여 사용할 수 있도록  한 것과 같이 PAE라는 기능을 도입하여 page table director 에 64bit address 를 지정할 수 있도록 하여 64bit 영역의 어느 곳이라도 32bit 주소공간에 배치 할 수 있도록 하였다.
PAE를 사용해도 어플리케이션은 크게 신경 쓸 필요는 없으나 OS kernel과 device driver는 영향이 많았다.

PAE는 64bit로 가는 과도기적 과정에서 나온 기술이라 크게 신경을 쓸 필요는 없어보인다.


4) 64bit



다시 한번 과거 호환성이 발목을 잡는 때가 왔다.
Intel은 32bit에서 16bit가 발목을 잡혔으나, 64bit에서는 새롭게 시작을 하고 싶었다.
IA-64는 기존 x86계열과 호환을 배제하고 성능과 효율 만을 생각하며 새로 디자인 하였다.
기존 x86 32bit(IA-32) 호환을 위한 부분도 추가를 해 놓았지만 성능은 좋지 않았고, 오로지 새로운 64bit에만 집중 했다.
기존 32bit 어플리케이션들은 새로운 64bit CPU에서 형편없는 성능을 보여주었고, 아직 64bit 어플리케이션이 충분치 않은 상황은 사용자들을 혼란에 빠트렸다.
AMD는 이런 상황을 기회로 여기고 기존 IA-32를 확장한 AMD64를 내놓았다.
AMD64는 기존 IA-32를 호환하는 명령셑이기 때문에 별다른 성능 저하 없이 32bit와 64bit어플리케이션을 사용할 수 있게 되었다.
물론 기존 호환성을 구현하기 위해 더욱 복잡해지고 그만큼 64bit에 대한 성능적 배려가 줄어드는 단점은 있었으나 사용자들은 열광했다.
결국 Intel도 입장을 바꾸고 em64t 라는 AMD64 호환 아키텍쳐를 내놓게 되고 후에는 이름도 Intel64로 바꾸게 된다.


64 bit에선 SSE 기능이 기본으로 들어가 있기 때문에 XMM레지스터를 기본 레지스터로 대우하여 사용한다.
XMM레지스터는 함수 호출시 아규멘트를 넣는 용도로도 사용하게 된다.
64bit 모드에서 어셈블리를 사용하려는 사용자는 XMM레지스터 관리에도 신경을 써야 한다.


사실 필자는 64bit 계열에 대한 개발을 직접적으로 해본 경험이 없어 이 정도로 줄이고 ARM에 대해 설명하기로 하겠다.


출처 - 어셈러브 www.asmlove.co.kr

저자 - 됨지


2013년 12월 26일 목요일

아키텍쳐의 특성과 어셈블리 - x86아키텍쳐 - 정의와 변천, 16bit

1. x86 아키텍쳐

1) 정의와 변천

intel이라는 기업을 많이 들어보았을 것이다.
TV 광고를 통하여, 또는 잡지등을 통하여 많이 접 할수 있는 세계적인 반도체 메이커다.
이 intel 에서 만들어 세계적인 회사로 자리 잡을 수 있도록 해준 아키텍쳐가 x86이다.
x86 아키텍쳐는 intel이 PC용으로 만든 CPU칩의 OP-CODE 체계로 칩 이름에 붙인 제품 명의 끝 숫자가 86으로 끝나기 때문에 x86이라 부른다.






필자가 게을러 다 표시는 못했지만, 이후 Pentium II , Pentium III , core , i 시리즈등이 나왔다.


2) 16bit

요즘같이 64bit로 바뀌어 가는 시대에 16bit에 대해 논한다는 것을 단순히 옛날 이야기로 치부하는 사람도 있을 것이다.
하지만 잘 보면 우리주위에는 16비트, 또는 8비트 CPU들이 아직도 많이 사용되고 있다.
왜 이런 구형방식의 CPU가 사용되는 것일까?
첫번째는 가격이다.
8bit 계열인 8051이나 PIC 계열 CPU는 2$ 보다 싼 제품이 많다.
물론 32bit인 Coretex M 계열 제품 중에서도 10$ 밑의 제품들이 있지만 대부분 flash 메모리를 별도 장착해야 하거나 별도의 부가비용을 필요로 하는 경우가 많다.
또한 1$라는 가격차이도 제품 가격에서는 무시할 수 없다.
보통 제품을 양산할 때 최소 500개에서 1만개 가량 생산한다.
여기서 1$의 차이는 한번 양산 시 500$에서 1만$의 차이라는 뜻이 된다.
두번째는 크기이다.
단순한 아키텍쳐일 수록 크기를 작게 만들 수 있다.
실제 8bit CPU들의 경우 가로 세로 7mm 이하의 제품들도 존재한다.
여기에 CPU외에 플레시메모리와 기타 장치까지 내장되어 있어 빠른 속도를 필요로 하지 않는 다면 적은 공간과 비용을 소요하는데에 요긴하게 사용된다.
세번째는 신뢰성이다.
단순할 수록 신뢰성이 강하다.
따라서 일부 제품의 경우 별도의 8bit나 16bit CPU를 사용하여 메인 CPU의 동작 여부를 감시시키기도 한다.
일부 관심있는 사람들은 인공위성이나 우주선에 8bit나 16비트 CPU를 쓰고, 32bit CPU를 쓴 것도 얼마 안된다는 것을 알 것이다.
신형 CPU들은 성능이 높고 집적해야 하는 로직이 많아져 공정을 낮출 수 밖에 없게 된다.
공정을 낮춤과 함께 사용하는 전압도 낮아지게 되기 때문에 같은 전압차의 노이즈에도 높은 공정이 낮은 공정의 칩보다 강해지게 된다.


그렇다면 16bit x86은 어디에 사용할까?
현재 필자가 주로 본 곳은 모터제어였다.
8086의 확장판인 80186/80188 을 주로 사용하며 이마저도 사실 ARM의 Coretex-M3에 밀리는 중이다.
그래도 80186계열은 아래와 같은 장점으로 아직도 적지 않은 사용자가 존재한다.


첫번째로 DOS와 호환이 된다.
즉 윈도우의 Visual Studio 로 DOS옵션에 맞춰 작성한 소프트웨어가 수정없이 그대로 실행이 가능하다는 뜻이다.
물론 플레시와 연동을 위하여 DOS를 애뮬레이션 시켜줄 수 있는 부트로더가 필요하다.
이미 시중에 나온 80186/80188 칩에는 DOS를 에뮬레이션 해주는 부트로더에 대한 자료가 있으므로 활용하면 된다.


두번째로 빠른 편이다.
40Mhz 스피드의 모델까지 존재하며, 같은 스피드라도 8051같은 8bit CPU보다 빠른 효율을 보인다.


이런 장점을 가진 186/188 계열 칩을 자신의 마음대로 주무르기 위해서는 위에서 설명한 것 처럼 DOS를 애뮬레이션 해주는 부트로더가 필요하다.
어플리케이션을 실행하기 위해서 필요한 DOS의 기능은 화면표시 , 실행파일 로딩, 실행보조기능이다.


DOS의 주요기능은 interrupt 0x21, 0x20번을 통해 실행된다.


PC에서는 화면표시를 비디오카드를 통하여 모니터로 했으나 임베디드 분야에서는 시리얼포트를 통하여 한다.
따라서 시리얼 포트를 통해서 프로그래머가 표시하고자 하는 문자열을 출력해야 한다.
따라서 INT 21h 의 9번이나 몇몇 화면출력 기능들을 애뮬레이션 해줘야 한다.
시리얼 포트를 통하여 글자를 출력하기 때문에 비디오카드처럼 그래픽을 프레임버퍼를 통하여 출력하는 기능을 구현하기란 매우 어렵다.


DOS의 실행파일은 COM 파일과 EXE파일 두가지가 있다.
COM은 쉽게 실행 코드 바이너리 이미지다. 최대 64Kbyte 까지 크기를 가질 수 있고
통째로 메모리에 로딩만하면 된다.
반면 EXE는 64Kbyte보다 큰 실행 파일을 만들 수 있지만 재배치 테이블을 분석해서 코드와 데이터들을 재 배치하고 내용을 일부 수정해 주어야 한다.


또한 C library는 기본적으로 부동소숫점 연산을 아무렇지도 안게 시도를 한다.
이에 대한 예외처리를 해줘야 한다.


이런 부트로더를 구현 할 때에 자주 사용되는 기능이 스텍관리다.
8086/8088보다 80186/80188에서 편해진 기능이 스텍 관리 명령들이 추가된 것이다.


enter , leave , pusha, popa 와 같은 명령들이 스텍관리를 편하게 해주고 실행코드 크기를 줄여준다.
필자는 같이 일하는 후임 연구원들에게 8051이나 PIC와 같은 8bit 마이컴을 다룰땐 한번정도 전체를 어셈블리로 만들어 보고 16bit CPU를 다룰때에도 어느정도 어셈블리로 함수몇개정도는 만들어 봐야 한다고 말하고 있다.
8086 - 8088 - 80186 - 80286으로 변천 해 오면서 양산성이나 보호모드 지원과 같은 기능도 추가 되었지만, opcode 여러 개를 써야 할 것을 하나로 만들어 코드를 좀 더 빠르게 실행하고자 하는 부분도 추가되었다.
이런 기능이 추가된 다는 것은 어셈블리로 코딩이 점점 편해진 다는 뜻으로 많은 어셈블리 사용자들이 매우 환영할 만한 일이었다.


당시 어셈블리의 사용 빈도는 높았다.

DOS 특성 상 주변기기 제어를 DOS 드라이버를 만들어 사용하는 것 보다 어플리케이션에서 직접 제어하는 것이 편했었고,  8bit 시절에 그랫듯 16bit도 메모리와 속도가 한계에 달하기 시작하면서 이를 조금이라도 해결하고자 어플리케이션에서도 어셈블리가 사용되기 시작했 었다.

- 계속

출처 - 어셈러브 www.asmlove.co.kr
저자 - 됨지


2013년 12월 25일 수요일

아키텍쳐의 특성과 어셈블리 - 시작하며

[어셈러브 칼럼] 아키텍쳐의 특성과 어셈블리 - 시작하며

본 칼럼은 어셈블리 입문자를 위해 어셈러브에서 발행하는 칼럼으로
어셈블리 개발의 현역으로 일하시는 됨지님이 작성하고, 어셈러브 관리자가 발행합니다.
매주 1회의 칼럼이 업데이트 될 예정이며, 프로그래밍 기법이나 코드 보다는 경험에 기반한 의견을 스토리 형식으로 풀어갈 예정입니다. 많은 관심과 격려 부탁드립니다.

집필을 시작하며 
2000년대 초 중반만큼 많은 CPU아키텍쳐들이 각축을 벌였던 때가 없었던 것 같다.
그 당시 PC쪽은 Windows 진영의 x86 아키텍쳐와 MAC 진영의 Power PC 아키텍쳐로 평정이 되다시피 했지만, 임베디드 시스템이 활성화 되면서 그 시장에서의 주도권을 잡고자 Power PC, x86, ARM, MIPS, AVR, DSP 등, 여러 아키텍쳐에서 상당히 공격적으로 마케팅을 하고 제품을 양산하기도 했다.



근래 들어 다시 정리가 되고 PC쪽에서는 MAC 진영마저 돌아서면서 x86으로 평정되는 분위기가 되어가고 임베디드는 ARM으로 평정되어 가고 있다. 
간간히 모바일이나 게임기에서 x86진영이 자리를 잡으려고 노력하는 편이다.



글쓴이 역시 저 시기를 겪어와서 x86, ARM, Power PC , ARM, MIPS, DSP 를 겪어 보게 되었다. (AVR은 검토만 하다 끝났다. ) 
이런 게시글에서 나열한 모든 아키텍쳐를 다룬다는 것은 글쓰는 이로서도 힘든 일이고
요즘처럼 x86과 ARM이 대세로 자리 잡은 시절에는 불필요한 옛날 이야기를 주절되는것과도 같을 수 있다고 생각되어 주를 x86과 ARM으로 이야기하고 , 간간히 비교할 만한 부분에서 다른 아키텍쳐를 언급하려 한다.



- 계속

출처 - 어셈러브 www.asmlove.co.kr
저자 - 됨지

2013년 12월 21일 토요일

어셈러브 포럼(가칭) 구상중

안녕하세요. 어셈러브지기 코람데오 입니다.
한해가 저물어가는 요즈음 여러분들은 내년에 어떤 구상을 하고 계시는지요?


저는 몇일 전 어셈러브 창립멤버이자 어셈블리 현역 개발자인 됨지님과 뜻 깊은 자리를 갖게되었습니다.

도메인만 유지되고 있는 어셈러브에 대해서 여러가지 이야기를 하다가 어셈러브를 시작했던 첫 마음과 취지를 기억하게 되었습니다.

짧지 않은 여러가지 대화를 나누면서 내년부터 다른 형태의 어셈러브를 운영하기로 뜻을 같이하게 되었네요.

정확한 구상은 나오지 않았지만 단순히 기술적인 정보를 주고 받는 자리가 아니라 프로그래밍 언어의 철학을 세워가는 모임을 만들어보자는 취지로 정리되었던것 같습니다.

각자 바쁘기 때문에 빠듯한 일정을 잡지는 않겠고, 얼추 내년 3월 정도에 어셈러브 첫 포럼(가칭)을 계획하고 있습니다.

부담스럽고 거창한 자리는 아니고 토즈같은 자리를 빌어 됨지님이 발표를 하는 조촐한 자리를 생각하고 있습니다.


강의 주제는 내부적으로 구상 중이니 관심있는 분들의 좋은 의견 바랍니다.

감사합니다.



2013년 9월 30일 월요일

처음을 되돌아보다.

사업하느라고 바빠서 거의 어셈러브를 들어올 일이 없었는데 몇 일전에 들어와보니 스팸천지더군요.

게다가 호스팅 서비스에서는 트래픽 초과라고 되어있어서 접속해서 자료를 백업하는데도 애를 먹었습니다.

수천 건의 스팸글에 융단폭격을 맞은어셈러브를 보면서 반성되고 되고 왜 어셈러브를 만들고 운영했는지에 대한 질문도 다시 해보았습니다.

어셈러브의 시작에 대해서 구구절절하게 설명하기는 그렇지만 아직도 유효한 저 나름의 이유는 있다는 결론을 내렸습니다.

어차피 사회적 책임이 있는 곳도 아니였고, 크게 기여도 한 곳이 아닌 바에 개인적인 이유만으로도 운영할 이유는 있겠다는 판단이 들었습니다.

때문에 유지는 되겠으나 지극히 개인적인 관점에 따라 운영되는 곳이 될 것 같은 생각입니다.

그러나 비슷한 생각과 고민이 있는 사람들과 생각을 나누는 장이 될 수 있도록 몇가지 시도도 해볼까 합니다.

또 뵙지요.