본문 바로가기

List/Windows

OS 구조와 원리 - 어셈블러 및 용어 정리 (1~10장)



OS 구조와 원리 - OS 개발 30일 프로젝트

저자
카와이 히데미 지음
출판사
한빛미디어 | 2007-04-14 출간
카테고리
컴퓨터/IT
책소개
이 책의 특징과 장점-. 초간단 예제부터 계속 추가해나가기 때문...
가격비교 글쓴이 평점  



1주차 : CPU 설정, 마우스 움직임, 인터럽트 루틴 작성, C언어 기초, 어셈블러 기초

2주차 : 알고리즘

3주차 : 멀티태스크, 콘솔, 어플리케이션 제작

4주차 : 어플리케이션 제작


nask : 필자가 직접 만든 어셈블러 (기존의 NASM에 최적화 능력을 높임)

DB : DB명령은 'data byte'의 약자로 1바이트만 직접 쓰는 명령

RESB : 'reserve byte'의 약어로, RESB 10 과 같은 방식으로 사용 함. 10바이트를 0x00으로 채워넣음

DW : 'data word'의 약어로, 2바이트를 직접 쓰는 명령

DD : 'data double-word'의 약어로, 4바이트를 직접 쓰는 명령

부트 섹터 : 부팅 프로그램을 담을 수 있는 하드디스크, 플로피 디스크 등의 기억장치에 있는 섹터. 부트 블록이라고도 함.

IPL : 'initial program loader'의 약어로, 초기 프로그램 읽기 장치를 뜻함. 부트 섹터의 공간이 적어서 대부분 OS는 부트섹터에 OS 본체를 읽어들이는 프로그램을 써 둠. 그래서 부트섹터를 IPL이라고 부르기도 함.

ORG : 기계어가 실행 시에 PC의 메모리 내 어디에 로딩되는지를 nask에 가르쳐주기 위한 명령


레지스터 (16비트, 2바이트 레지스터 8개)

AX : accumulator (누적 연산기)

CX : counter

DX : data

BX : base

SP : stack pointer (스택용 포인터)

BP : base pointer (베이스용 포인터)

SI : source index (읽기 인덱스)

DI : destination index (쓰기 인덱스)

각종 연산에 알맞은 레지스터를 사용하면 프로그램이 좀 더 간결화 됨.

즉, CX는 수를 세는데 최적화 되어있고, BX는 메모리의 번지 계산의 기준 주소 사용에 최적화 되어 있음.


레지스터 (8비트, 1바이트 레지스터 8개)

AL : 어큐뮬레이터 로우

CL : 카운터 로우

DL : 데이터 로우

BL : 베이스 로우

AH : 어큐뮬레이터 하이

CH : 카운터 하이

DH : 데이터 하이

BH : 베이스 하이

이는 AX 레지스터의 16비트 중 하위 8비트를 AL이라고 하고 상위 8비트를 AH로 나눈 것이다. (BP, SP, SI, DI는 제외. 나눌 수 없음)


레지스터 (32비트, 4바이트 레지스터 8개)

EAX, ECX, EDX, EBX, ESP, EBP, ESI, EDI

Exntend, 즉 확장 레지스터로 기존 16비트에서 32비트 레지스터로 확장 함.

중요한건 EAX의 하위 16비트가 AX 그 자체이고, 상위 16비트는 이름이 없고 레지스터 번호도 없어서 상위 16비트를 사용하고 싶다면 쉬프트연산으로 밀어내서 사용해야 함. 또, cpu의 최대 기억 용량은 최대 44바이트라는 것도 알 수 있음 

( (4바이트짜리가 8개 =) 32바이트 + 세그먼트 레지스터 12바이트 = 44바이트 )


세그먼트 레지스터 (16비트, 2바이트 세그먼트 레지스터 6개)

ES : extra segment

CS : code segment

SS : stack segment

DS : data segment

FS : 명칭 없음

GS  : 명칭 없음


4장

CLI : 'clear interrupt flag' 인터럽트 플래그를 0으로 만듦

SLI : 'set interrupt flag' 인터럽트 플래그를 1로 만듦

EFLAGS : FAGS라는 16비트 레지스터가 확장된 32비트 레지스터로 캐리 플래그나 인터럽트 플래그 등으로 구성된 레지스터 

PUSHFD : 'push flags double-word' 플래그를 더블워드로 스택에 넣음

POPFD : 'pop flags double-word' 플래그를 더블워드로 스택에서 나오게 함


5장

binfo : bootinfo (ipl에 필요한 정보)

scrn : screen

GDT : 'global segment descriptor table' 

GDTR : 'global segment descriptor table register'

IDT : 'interrupt descriptor table'

IDTR : 'interrupt descriptor table register'

세그먼테이션 : 합계 4GB의 메모리를 분할한 뒤, 각 블록의 처음 번지를 0으로 하여 다루는 기능

페이징 : 4GB를 태스크의 수만큼 만들고, 메모리 순서를 바꿈


6장

#include "" : 소스파일과 같은 폴더에 있는 경우

#include <> : 컴파일러에 딸려오는 폴더 안에 있는 경우

LGDT : 

PIC : 'programmable interrupt controller' 설정 가능한 인터럽트 컨트롤러로 PIC 마스터와 PIC 슬레이브로 구성되어 있다. PIC는 8개의 인터럽트 신호를 1개의 인터럽트 신호로 정리하는 장치로, 입력 핀의 신호를 계속 감시하다가 어느 것이든 한개라도 인터럽트 신호가 오면 PIC의 단 한 개의 핀이 ON이 되어 인터럽트가 발생했음을 CPU에 알림

IRQ : Interrupt Request, 인터럽트 요청, 인터럽트 신호

IMR : 'interrupt mask register' 인터럽트를 막아놓은 레지스터 

ICW : 'initail control word' 초기화 제어 데이터라는 의미


7장

wait_KBC_sendready : CPU와의 속도 차이로인해 CPU에서 보내는 명령을 키보드 제어회로가 받아들일 수 있을 때까지 기다림


8장 

어셈블러 out : 

INSTRSET : LGDT 명령이나 EAX, CR0와 같은 386 이후의 명령어들을 사용하고 싶을 때 사용

CR0 : 'control register 0' 으로 OS 이외에 다른 주체가 건드리면 안되는 중요한 레지스터

protect 모드 : 애플리케이션이 맘대로 세그먼트의 설정 바꾸기 금지, OS용 세그먼트 사용 금지. 즉, OS는 CPU에 의해 보호 됨

본래는 '프로텍트 버추얼 어드레스 모드'로 GDT를 사용하여 실제 번지가 아닌 세그먼트 번호로 가상 지정함 또한 기계어의 해석이 바뀜.

그 반대로 '리얼 어드레스 모드'로 메모리 번지의 계산에서 세그먼트 레지스터의 값으로 직접 번지의 일부를 지정

IMUL : 'integer multiple' 정수곱셈

SUB : substract 뺄셈

SHR : shift right, >>, 나누기 2

JZ : jump if zero

JNZ : jump if not zero

ALIGNB : 잘 나뉘어 떨어질 때 가지 DB 0을 넣음, 예를들어 ALIGNB 16인 경우 주소가 16으로 나눠 떨어지는 것을 말함


10장

struct SHEET {  //레이어 구조체

unsigned char *buf; //레이어의 내용이 위치한 주소

int bxsize, bysize;   //레이어 전체 크기

int vx0, vy0;            //vram에서의 위치

int col_inv;             //투명 색

int height;              //높이

int flags;                //설정

};


#define MAX_SHEETS 256  //레이어 최대 개수

struct SHTCTL { // 레이어 관리 구조체

unsigned char *vram; // vram

int xsize, ysize;  // binfo의 화면 전체 크기와 동일한 값

int top; //가장 위에 있는 레이어의 높이

struct SHEET *sheets[MAX_SHEETS]; // 높이순으로 정렬된 레이어 주소값

struct SHEET sheets0[MAX_SHEETS]; // 레이어 공간 할당(정렬x)

};


struct SHTCTL *sthctl_init (struct MEMMAN *memman, unsigned char *vram, int xsize, int ysize) : SHTCTL구조체에 메모리 공간 할당 및 변수 초기화

struct SHEET *sheet_alloc (struct SHTCTL *ctl) : sheet0[]중에서 사용하지 않은 레이어가 발견되면 사용 중으로 변경 후 번지를 되돌려 줌

void sheet_free (struct SHTCTL *ctl, struct SHEET *sht) : 이미 사용하여 필요없게 된 레이어를 해제 함

void sheet_setbuf (struct SHEET *sht, unsigned char *buf, int xsize, int ysize, int col_inv) : 레이어에 버퍼와 레이어 크기, 투명색을 설정 함

void sheet_updown (struct SHTCTL *ctl, struct SHEET *sht, int height) : 레이어의 높이를 설정 함

sheet_updown 같은 경우에는 현재 높이와 변경하고자 하는 높이 정보를 이용하여 SHTCTL구조체의 sheets 변수에서의 레이어 순서를 바꾸고 sheet_refresh()함수로 전체 레이어를 다시 그린다. 


void sheet_refresh (struct SHTCTL *ctl) : 레이어들의 설정된 높이대로 아래쪽부터 vram에 복사 함

void sheet_slide (struct SHTCTL *ctl, struct SHEET *sht, int vx0, int vy0) : 레이어의 상하좌우 움직임을 담당 함


위 함수들을 이용하여 메인함수에서 응용하고자 한다면 아래와 같은 순서로 이용될 수 있다.

  

 


  

Main.c 


  

  struct SHTCTL *shtctl;  

  struct SHEET *sht_back, *sht_mouse;

  unsigned char *buf_back, buf_mouse[256];


  init_palette();

shtctl = shtctl_init(memman, binfo->vram, binfo->scrnx, binfo->scrny);    //1

sht_back  = sheet_alloc(shtctl);   //2

      sht_mouse = sheet_alloc(shtctl);  //2

buf_back  = (unsigned char *) memman_alloc_4k(memman, binfo->scrnx * binfo->scrny);

sheet_setbuf(sht_back, buf_back, binfo->scrnx, binfo->scrny, -1); /* 투명색없음 */  //3

      sheet_setbuf(sht_mouse, buf_mouse, 16, 16, 99);   //3

init_screen8(buf_back, binfo->scrnx, binfo->scrny);

init_mouse_cursor8(buf_mouse, 99);

sheet_slide(shtctl, sht_back, 0, 0);  //4

mx = (binfo->scrnx - 16) / 2; /* 화면 중앙이 되도록 좌표 계산 */

my = (binfo->scrny - 28 - 16) / 2;

sheet_slide(shtctl, sht_mouse, mx, my);  //4

      sheet_updown(shtctl, sht_back,  0);  //5

      sheet_updown(shtctl, sht_mouse, 1);  //5

sprintf(s, "(%3d, %3d)", mx, my);

putfonts8_asc(buf_back, binfo->scrnx, 0, 0, COL8_FFFFFF, s);

sprintf(s, "memory %dMB   free : %dKB",

memtotal / (1024 * 1024), memman_total(memman) / 1024);

putfonts8_asc(buf_back, binfo->scrnx, 0, 32, COL8_FFFFFF, s);

sheet_refresh(shtctl);  //6

  for (;;) {

(중략)

sprintf(s, "(%3d, %3d)", mx, my);

      boxfill8(buf_back, binfo->scrnx, COL8_008484, 0, 0, 79, 15); /* 좌표 지운다 */

        putfonts8_asc(buf_back, binfo->scrnx, 0, 0, COL8_FFFFFF, s); /* 좌표 쓴다 */

        sheet_slide(shtctl, sht_mouse, mx, my); /* sheet_refresh를 포함한다 */ //7

        } 


     1. shtctl_init() 함수로 binfo에서 얻은 vram의 주소와 스크린의 크기를 매개변수로 넘겨주어 SHTCTL 구조체에 공간을 할당한다.

     2. sheet_alloc() 함수로 미사용되고 있는 레이어를 가져와서 sht_back과 sht_mouse에 각각 넘겨준다. (배경화면과 마우스)

     3. sheet_setbuf() 함수로 sht_back과 sht_mouse 레이어에 레이어의 크기, 내용, 투명색을 설정해준다.

     4. sheet_slide() 함수로 sht_back 레이어와 sht_mouse 레이어에 위치를 지정해 줌

     5. sheet_updown() 함수로 sht_back 레이어의 높이는 0, sht_mouse 레이어의 높이는 1로 설정 함  (마우스가 위)

     6. sheet_refresh() 함수로 sht_back레이어와 sht_mouse레이어를 그림

     7. 움직임이 있을 때마다 sheet_slide함수로 위치 변경 후 내부 루틴에서 sheet_refresh 함수를 호출시켜 다시 그림



void sheet_refresh (struct SHTCTL *ctl) : 레이어들의 설정된 높이대로 아래쪽부터 vram에 복사 함

void sheet_refreshsub (struct SHTCTL *ctl, int vx0, int vy0, int vx1, int vy1) : refresh() 함수의 개량

 (refresh함수는 vram전체를 다시 그리므로 효율이 떨어진다. refreshsub() 함수는 vx0~vy1로 refresh 범위를 정해줄 수 있음)

























'List > Windows' 카테고리의 다른 글

VMware에 MS-DOS 6.22 설치  (0) 2014.12.12
OS 구조와 원리 - 어셈블러 및 용어 정리 (11~20장)  (0) 2014.08.12
Intel CPU 가계도  (0) 2014.08.08
nmap 사용법  (0) 2014.05.13
xp 포트 열기  (0) 2014.05.12