┌───────────────────────────────────┐ │ ▶ 번 호 : 2/19 ▶ 등록자 : MABARY │ │ ▶ 등록일 : 98년 08월 20일 01:01 │ │ ▶ 제 목 : [강좌] 어셈블리어란? (1) │ └───────────────────────────────────┘ 어셈블리어는 어렵다고 생각하는 사람이 있을 것 같은데 이는 잘못된 생각일 수 있다. 어셈블리어는 특별히 어려운 문법이 필요가 없으므로 (자바를 공부해 보면 이해하기 힘든 개념이 너무 많다 싶을 정도로 많이 나온다.) 오히려 쉽다. 대신 프로그램이 매우 크게 되고 구조를 명확하게 하여 짜지 않으면 나중에는 알아볼 수 없는 프로그램이 되 고 마는 단점이 있다. 오히려 이러한 것들이 어렵다고 할 수 있다. 보통 어셈블리어는 단순반복의 노동이므로 다른 언어와 같이 쓰게 된다. 다른 고급 프로그밍 언어로 프로그랩을 짜다가 특히 시간이 많이 걸리 는 부분(그래픽이나 사운드 혹은 복잡한 계산)을 어셈블리어로 짜게 된다. 예를 들어 우리가 잘 아는 '둠'을 예로 들어 본다면, 이 게임은 C언어로 짜여져 있고 단 두 모듈만이 어셈블리어로 짜여 있습니다. 어셈블리어를 공부해야 할 필요는 CPU와 컴퓨터의 구조에 대해 좀더 자세하게 알고 고급프로그래밍에 도움이 되는데 있습니다. 어셉블리어 를 공부해 나가다 보면 C언어에서 추상적으로만 알던 것들을 좀더 잘 알 수 있을 것입니다. 1. 어셈블러란 무엇인가? 1-1. 어셈블러의 탄생 이 글을 읽는 사람은 대부분 한 번 쯤은 프로그램을 짜보았을 것 이다. 프로그램을 짠다는 것은 자바나 C언어, 포트란, 코볼, 베이직 등의 프로그래밍 언어로 각 언어의 문법에 맞도록 하면서 자신의 알 고리즘을 구현해 나가는 것이다. 그런데 이런 의문이 생길 것이다. '이 언어를 컴파일해주는 컴파일 러 또한 프로그램인데 그럼 이 프로그램은 어떤 언어로 짜는가?' 하 는 것이다. 보통 컴파일러는 다른 언어를 사용하게 된다. 자바 컴파 일러의 경우는 C언어로 만들어졌다. 그렇다면 그 최초 프로그램은 어떻게 짜겠는가? 최초 프로그램은 지 금 우리가 말하고자 하는 어셈블러이다. 이 어셈블러(그것도 최초의 어셈블러)는 기계로 일일이 1,0,1,0 등을 반복함으로써(이 뜻을 잘 모르는 사람은 계속 읽어보면 무슨 말인 지 알게 된다.) 만들어 지게 된다. 이제 최초의 어셈블러가 있으므로 그 후의 어셈블러는 이 어셈 블러로 만들 수가 있는 것이다. 1-2. 어셈블리어=기계어? 아마 '어셈블리어=기계어'라고 어디선가 들어본 사람이 있을 것이 다. 이 등식이 완전히 옳다고는 할 수 없다. 실제 기계어는 1과 0의 반복으로 이루어 진다. 반면 어셈블리 언어는 명령어를 영어로 표현 한 것이다. 그런데 어셈블리 언어와 기계어는 1:1로 매치가 될 수 있 으므로 보통 어셈블리 언어를 기계어라 표현하기도 하는 것이다. 어셈블리어를 기계어로 변환하는 작업을 '어셈블'한다라고 하고 어 셈블리어를 컴파일해주는 프로그램을 '어셈블러'라고 부른다. 어셈블리어가 곧 바로 기계어로 대응되어 변환되므로 우리는 컴퓨터 그중에서도 CPU에 대해 알 필요가 있다. 1-3. CPU의 작동과 구조 (1) 디지탈 회로 -- 이 부분은 아는 사람은 넘어가도 됨. CPU를 설명하기 전에 디지탈 회로를 알 필요가 있다. 디지탈 회로는 1과 0만을 다루는 회로이다. 보통 1은 5V, 0은 0V를 사용하게 된다. 디 지탈 회로의 대표적인 예는 게이트 회로이다. 다음은 NOT GATE, AND GATE, OR GATE 회로의 논리도이다.(회로 그림은 그리기 어려워서 그리지 않습니다. ^^;) ----- NOT GATE ----- | 입력 출력 | 입력단 하나. 출력단 하나 | 0 => 1 | 입력단의 값의 반대가 출력으로 나옴. | 1 => 0 | -------------------- ----- AND GATE ----- | 입력 출력 | 입력단 둘. 출력 하나. | 0, 0 => 0 | 입력이 둘 모두 참(즉, 1)일때만 출력이 | 0, 1 => 0 | 참(즉, 1). | 1, 0 => 0 | | 1, 1 => 1 | -------------------- ----- OR GATE ----- | 입력 출력 | 입력단 둘. 출력 하나. | 0, 0 => 0 | 입력이 하나라도 참(즉, 1)일때 출력이 | 0, 1 => 1 | 참(즉, 1) | 1, 0 => 1 | | 1, 1 => 1 | -------------------- 이외에도 출력이 반대인 NAND, NOR GATE등이 있다. 이 부분에 잘 아는 사람이 아니면 생소할 지 모른다. 더 알고 싶은 사람은 디지탈 회로 책 을 찾아 읽어 보도록 권한다. 어찌 되었던 여기서 말하고자 하는 바는 AND GATE 회로의 경우 회로의 입력이 0V, 5V이면 0V가 출력되고, 5V, 5V 가 입력으로 들어오면 5V가 출력된다는 것이다. 모든 디지탈 IC(시꺼멓고 지네발이 달린 것같은 칩)가 이러한 GATE회로로 이루어져 있다. CPU의 경 우는 이러한 게이트가 수 X개(하여간 많다는 것이다.)로 이루어져 있다. (2) CPU의 작동 CPU의 작동은 의외로 단순하다. CPU에도 입력단과 출력단이 있어서 입력에 따라 출력값이 나오는 것이다. 예를 들어 1010이 더하라는 입력이라고 할 때 0111+0101=1100이 어떻게 계산되는 지 알아보자. 먼저 더하라는 신호 인 1010을 주고 그 다음에 더할 숫자인 0111과 0101을 순서대로 입력단에 주면 그 결과 값인 1100이 출력되는 것이다. ---------- ---------- ---------- 5V --| |-- ? 0V --| |-- ? 0V --| |-- 5V 0V --| CPU |-- ? ==> 5V --| CPU |-- ? ==> 5V --| CPU |-- 5V 5V --| |-- ? 5V --| |-- ? 0V --| |-- 0V 0V --| |-- ? 5V --| |-- ? 5V --| |-- 0V ---------- ---------- ---------- 위의 작동은 아주 단순화 시킨 것이고 실제로는 훨씬 더 복잡한 과정을 거치게 된다. CPU의 작동에 관심이 있는 사람은 관련 서적을 읽어보기 바 란다. 지금 우리는 4비트 덧셈을 행했다. 더하라는 입력 신호인 1010(이를 instruction이라고 부른다.) 또한 4비트이다. 이처럼 instruction과 데이 터들이 4비트의 구조를 가지면 4비트 micro process, 8비트이면 8비트 micro process라 부른다. 예전의 애플 컴퓨터가 8비트 컴퓨터였고 XT,AT, 286컴퓨터가 16비트 컴퓨터 였으며, 386이후는 32비트 컴퓨터이다. 그러나 인텔사에서 CPU를 개발하면서 이전의 CPU와 호환성을 유지하기 위해 16비 트 명령체계를 유지시켰다. 이것이 386이후의 CPU를 묶는 한계로 작용하기 도 한다. 다시 한번 설명한다면 어셈블러는 어셈블리어를 CPU가 이해할 수 있는 언어인 기계어로 변환한다고 했는데 이 기계어는 바로 instruction인 것 이다. (3) CPU는 어떤 일을 하나? 컴퓨터 모니터를 통해 보여지는 화면을 보면 너무 화려해서 주 프로세 서인 CPU가 매우 많은 일을 할 것처럼 보인다. 그러나 CPU의 가장 주된 임 무가 사칙연산이라는 것을 안다면 의외라고 생각들 수도 있다. 물론 다른 일도 하지만 사칙연산이 차지하는 비중이 50% 이상이라 해도 틀리지 않을 것이다. 여러 명령들 중 가장 시간을 잡아먹는 부분도 사칙연산이다. 이외에 메모리에서 레지스터(바로 뒤에 설명)로 반대로 레지스터에서 메 모리로 데이터 이동, 특정 주소로 분기 등의 일을 한다. (4) CPU의 구조 CPU의 세부 구조는 알 필요가 없고 어큐물레이터와 레지스터만 알면 된 다. 이 둘 모두 데이터를 저장할 수 있다. ** 어큐물레이터(Accumulator, Acc) : 계산을 위해 사용되고 또한 계산 결과가 저장된다. ** 레지스터(Resister) : CPU에 어떠한 데이터를 일시 저장하기 위해 쓰 인다. 80X86에서는 어큐물레이터가 레지스터에 포함되어 있는 형태를 띠고 있 으며 레지스터의 기능들이 분리되어 있다. 그러나 8051(혹은 8031)에서는 어큐물레이터가 따로 존재하고 레지스터들은 특별한 기능으로 나뉘어 있지 않고 8개씩 4묶음(24개)으로 되어 있다. -------------------------------------------------------------------- 휴~~~ 힘들군요. 좀 장황해진 경향이 없지 않았는가 하는 생각이 드네요. 모르는 게 있으면 메일 주세요. (주)교학사, MS-DOS 매크로 어셈블러, 황희융 편저 한글과컴퓨터, 게임설계의 안쪽, LaMonthe Rateliff, Seminatore & Tyler저 위 두 권의 책을 참고 했습니다. ┌───────────────────────────────────┐ │ ▶ 번 호 : 2/19 ▶ 등록자 : MABARY │ │ ▶ 등록일 : 98년 08월 22일 18:14 │ │ ▶ 제 목 : [강좌] 어셈블리어란? (2) │ └───────────────────────────────────┘ 아마 잡다한 설명(하지만 중요해요.)을 공부하기 보다는 빨리 프로그 래밍을 하고 싶을 겁니다. 그렇다면 그런 설명은 뒤에 하기로 하고 프로 그래밍을 해보죠. 우선 명령들을 알아보아야 겠죠? 우리의 최종 목표로 하나의 프로그램을 정합시다. 팩토리얼 프로그 램이 좋겠군요. 이건 그냥 팩토리얼 프로그램이 아닙니다. 계산기로 100!을 계산해 보세요. 웬만한 계산기는 값이 정수로 나오지 않고 x.xxE+xx 형태로 나타날 겁니다. 그러나 우리가 최종적으로 만들 프로그 램은 10000!(무지하게 큰 수임)도 정수형태로 나타나는 프로그램입니다. 레지스터에 대한 설명을 뒤에서 하려 하니 우선 레지스터를 값을 저장 하기 위한 변수 정도로 생각해 두세요. ( AX,BX,CX,DX,SP,BP,SI,DI,IP,FL,CS,DS,SS,ES ==> 16비트, AX,BX,CX,DX는 상하위 8비트로 나뉨. AX = AH + AL ) 2. 80x866 어셈블리어 명령 개요 -- 전송명령 -- 사칙연산 명령 -- 비교 명령 -- 분기 명령 -- 인터립트 명령 -- 기타 명령 2-1. 전송명령(MOV) ex) MOV AX,3675 ; ';'은 어셈블리어에서 주석을 의미. ; C언어에서 AX=3675를 의미 ; AX레지스터에 3675를 전송 MOV DS,AX ; DS레지스터에 AX레지스터 내용을 전송 MOV AX,[1234H] ; AX레지스터에 1234H번지의 내용 전송 ; 1234H에서 H는 16진수라는 의미. H가 없으면 10진수. B는 2진수 2-2. 사칙연산 명령(ADD,SUB,MUL,DIV, ...) ADD AX,BX ; AX = AX + BX의 의미. SUB [1234H],CX ; (1234H번지의 값) = (1234H번지의 값) - CX MUL CX ; AX*CX, DX와 AX에 결과 저장 DIV CH ; AL*CH, AX에 결과 저장 2-3. 비교명령(CMP) CMP AX,1234H ; AX와 1234H를 비교 CMP BX,[1234H] ; BX와 (1234H번지의 값) 비교 2-4. 분기명령(JMP,JA,JB,JE, ...) -- 보통 비교 명령과 함께 사용 JMP END ; END가 가르키는 번지로 분기 JMP 1234H ; 1234H번지로 분기 2-5. 인터럽트 명령(INT) -- 보통 두 명령을 함께 사용 ex) MOV AH,1 INT 21H ; 키보드로부터 입력을 기다림. ; 입력이 있으면 입력된 키의 아스키 코드를 ; AL에 저장 MOV AH,2 INT 21H ; 모니터에 DL에 해당하는 한 문자 출력 MOV AH,4CH INT 21H ; 프로그램을 종료하고 도스 모드로 돌아옴. 2-6. 기타 명령(RET,IRET,PUSH,POP, ...) -- 나중에 설명 위 내용이 무슨 이야기 인지 모르더라도 아래 프로그램의 예를 읽어 보면 이해가 갈 겁니다. 그럼 HELLO 프로그램부터 시작해 봅시다. 3. 어셈블리어 프로그램의 간단한 예 3-1. HELLO 프로그램 -- 원래 프로그밍 언어 시작하면 하죠^^; MAIN SEGMENT ASSUME CS:MAIN,DS:MAIN ; MOV DL,'H' MOV AH,2 ;---(1) INT 21H ;H출력 ; MOV DL,'E' MOV AH,2 ;---(2) INT 21H ;E출력 ; MOV DL,'L' MOV AH,2 ;---(3) INT 21H ;L출력 ; MOV DL,'L' MOV AH,2 ;---(4) INT 21H ;L출력 ; MOV DL,'O' MOV AH,2 ;---(5) INT 21H ;O출력 ; MOV AH,4CH INT 21H ;프로그램 종료 ; MAIN ENDS END 3-2. 프로그램의 어셈블과 링크 1) 위 프로그램이 있는 텍스트 화일을 HELLO.ASM 으로 저장하세요. 2) 프로그램의 어셈블 MASM HELLO.ASM 하고 도스 모드에서 실행하면 다음의 메세지가 순서대로 나올 겁니다. Object filename [HELLO.OBJ]: Source listing [NUL.LST]: Cross-reference [NUL.CRF]: []안의 파일 이름은 디폴트 입니다. 우리가 현재 원하는 파일은 HELLO.OBJ이고 아래의 두 화일은 지금으로서는 필요하지 않으므 로(나중에 프로그램이 커졌을 때 버그를 잡기 위해 이용합니다.) 그냥 내리 엔터를 쌔리면(?) 됩니다. 3) 프로그램 링크 LINK HELLO.OBJ 라고 도스 모드에서 실행하면 마찬가지로 몇 가지 메세지가 나타나는데 그냥 모두 언터를 지면 HELLO.EXE 화일 이 생성이 될 겁니다. NO STACK SEGMENT라는 메세지가 뜨는데 이 건 무시해도 될 겁니다. 아직은 무엇인지 잘 모르겠음. 4) HELLO를 실행 시키면 우리가 원하는 결과를 얻습니다. 3-3. HELLO 프로그램 해석 1) 처음과 끝에 나오는 MAIN 어쩌구 저쩌구는 처음 C언어를 배울 때처럼 그냥 이렇게 하는 거구나 하고 알아두세요. C언어에서의 MAIN 함수 비슷한 겁니다. 2) 한 문자씩 출력한 것임은 그냥 보아도 알 수 있을 겁니다. 3) AH에 처음 (1)에서 2를 넣어 주었고 그 후로 값의 변화가 없으 므로 (2)-(5)는 생략해도 되겠죠. 한 번 해 보세요. 4) 반드시 종료시키는 문장이 들어가야 합니다. 이것때문에 자주 시 스템이 폭주(아무키도 안먹는 상태)합니다. 3-4. 1부터 10까지 더하는 프로그램(SIGMA.EXE라고 합시다.) MAIN SEGMENT ASSUME CS:MAIN, DS:MAIN ; MOV AL,0 ; AL 초기화 MOV DL,0 ; DL 초기화 ; LOOP1: ; <=번지를 나타내는 의사명령 ADD AL,DL ; AL= AL + DL CMP DL,10 ; DL과 10 비교 JE LOOP1_END ; DL==10이면 LOOP1_END로 분기 INC DL ; DL의 값 1증가 JMP LOOP1 ; LOOP1으로 분기 LOOP1_END: ; <=번지를 나타내는 의사명령 ; MOV DL,AL ; 결과를 DL에 저장 MOV AH,2 INT 21H ; 결과의 출력 ; MOV AH,4CH INT 21H ; 프로그램 종료 ; MAIN ENDS END 3-5. SIGMA 프로그램의 해석 1) 이 프로그램은 AL과 DL을 각각 0으로 둔다음 DL을 1씩 증가 시켜 AL에 더해 주는 프로그램입니다. 2) LOOP1: 과 LOOP1_END: 는 레이블이라고 불리는 의사명령으로서 번 지를 나타냅니다. 의사명령은 뒤에서 설명합니다. MAIN ~ 도 의사 령 중의 하나입니다. 3) JE는 분기 명령중의 하나로 위에서 비교한 두 수가 같으면 분기하 라는 명령어 입니다. 4) 결과를 봅시다. SIGMA.EXE를 실행 시키면 결과가 7이 됩니다. 어라! 이거 틀린 답 아닙니까? 아닙니다. 이 7은 숫자 7이 아니고 문자 7입니다. 즉 1부터 10까지 더한 답 즉 55에 해당하는 아스키 코드가 바로 7입니다. 그러면 55를 출력하려면 어떻게 해야 하나? 이는 좀 복잡한 프로그램을 짜야 합니다. 이는 나중에 설명하기로 하고 과연 아스키 코드 55가 '7'을 나타내는 지 다음 프로그램으로 확인할 수가 있겠죠... MAIN SEGMENT ASSUME CS:MAIN, DS:MAIN ; MOV DL,55 MOV AH,2 INT 21H ; 아스키코드 55를 문자로 출력 ; MOV AH,4CH INT 21H ; 프로그램 종료 ; MAIN ENDS END 역시 결과는 7이 화면에 나타납니다. -------------------------------------------------------------------- 다음에는 레지스터와 세그먼트에 대해 설명하겠습니다. 역시 < (주)교학사, MS-DOS 매크로 어셈블러, 황희융 편저 > 를 참 고 했습니다. ---- 좋은 주말 방안에서 MABARY -_-;