#boot.bin [org 0] :origin 이라함. 이 프로그램이 메모리의 몇번지에서 실행 해야하는지를 알려줌 [bits 16] jmp 0x07C0:start :바로 밑의 줄의 start: 로 점프하라는 문장이다. start: mov ax, cs :cs에는 0x07c0이 들어있다. mov ds, ax :ds를 cs와 같게 해준다.
mov ax,0xB800 :0xb800 = 비디오 메모리의 세그먼트 mov es, ax :es 레지스터에 0xb800(비디오 메모리의 세그먼트)를 넣음. mov di, 0 :제일 윗줄의 처음에 쓸 것 mov ax, word [msgBack] :써야할 데이터의 주소값을 지정한다. mov cx, 0x7FF :화면 전체에 쓰기 위해선 0x7FF개의 word가 필요하다. paint: mov word [es:di], ax :비디오 메모리에 쓴다. (ax = word[msgBack]) add di, 2 :한 WORD를 썻으므로 2를 더한다. dec cx :한 word를 썻으므로 CX의 값을 하나 줄인다. jnz paint :cx가 0이 아니면 paint로 점프하여 나머지를 더 쓴다. mov edi, 0 :제일 윗줄의 처음에 쓸것. mov byte[es:edi], 'A' :비디오 메모리에 쓴다. inc edi :한개의 byte를 썻으므로 1을 더한다. mov byte[es:edi], 0x06 :배경색을 쓴다. inc edi :한개의 byte를 썻으므로 1을 더한다. mov byte[es:edi], 'B' :반복 inc edi mov byte[es:edi], 0x06 inc edi mov byte[es:edi], 'C' inc edi mov byte[es:edi], 0x06 inc edi mov byte[es:edi], '1' inc edi mov byte[es:edi], 0x06 inc edi mov byte[es:edi], '2' inc edi mov byte[es:edi], 0x06 inc edi mov byte[es:edi], '3' inc edi mov byte[es:edi], 0x06 jmp $ :여기서 무한루프를 돈다.
msgBack db'.', 0xE7 :배경색으로 사용할 데이터
times 510-($-$$) db 0x06:여기서부터 509번지까지 0으로 채운다. dw 0xAA55 :510번지에서 0xAA를, 511번지에서 0x55를 넣어둔다. |
코드 설명
[org 0] :origin 이라함. 이 프로그램이 메모리의 몇번지에서 실행 해야하는지를 알려줌. 정확하게 말하면 프로그램상에서 사용될 Offset의 기준을 마련하는 것
[bits 16] :이 프로그램이 16비트용으로 되어있다는 의미를 컴파일러에게 알려주기위함.
jmp 0x07C0:start :바로 밑의 start:로 점프하라는 명령이다.
start:
mov ax, cs :cs에는 0x07c0이 들어있다.
mov ds, ax :ds를 cs와 같게 해준다.
코드세그먼트와 데이터 세그먼트를 같은 값으로 사용하겠다는 의미. 이 두개를 같게 하는 이유는 나중에 mov ax, word[msgBack]과 msgBack db‘.’,0xE7과 같이 word[msgBack]이라는 식으로 세그먼트를 지정하지 않고 데이터를 사용하면 cpu는 묵시적으로 DSmsgBack과 같이 DS에 있는 값을 세그먼트로 사용하겠다는 뜻으로 받아들인다. 하지만 여기서 CS와 DS의 값이 다르다면 램상의 이상한 곳의 데이터를 읽거나 쓰게 된다.
이 부분은 배경을 그리는 루틴이며, C언어의 FOR문을 사용하여 메모리에 값을 넣는 동작과 같다.
mov ax,0xB800 :0xb800 = 비디오 메모리의 세그먼트
mov es, ax :es 레지스터에 0xb800(비디오 메모리의 세그먼트)를 넣음.
mov di, 0 :제일 윗줄의 처음에 쓸 것
mov ax, word [msgBack] :써야할 데이터의 주소값을 지정한다. AX에 MSGBACK에 있는 값을 2바이트(워드)로 읽어 드린다.
mov cx, 0x7FF :화면 전체에 쓰기 위해선 0x7FF개의 word가 필요하다.
이를 통해 CX에 데이터를 넣을 길이를 정한다. 뒤에서 이 CX를 계속 한 개씩 줄여가며 메모리상에 다 썻는지를 확인한다.
paint: //이 다음이 실제로 반복할 루틴이다.
mov word [es:di], ax :비디오 메모리에 쓴다. (ax = word[msgBack],) 지정된 주소에 값을 쓰는 부분으로 AX에는 msgBack에 있는 값이 들어있으며, 같은 값을 루프가 도는 동안에도 계속 유지한다.
add di, 2 :한 WORD를 썻으므로 2를 더한다.
주소값을 2바이트(워드)씩 더한다. 이로써 ax에 있는 값을 다음 번지에도 써넣을수 있다.
dec cx :한 word를 썻으므로 CX의 값을 하나 줄인다. 이로써 루프는 cx에 정해진 값만큼만 돌게 된다. 이후 cx 값이 0이 되면 cpu의 flag 레지스터에 있는 Zero Flag(ZF)가 ON이 된다.
jnz paint :cx가 0이 아니면 paint로 점프하여 나머지를 더 쓴다.
mov edi, 0 :제일 윗줄의 처음에 쓸것.
Edi에 0을 넣는다. es에는 0xB800이 들어 있으므로 화면의 제일 처음부분에서 시작한다는 의미.
mov byte[es:edi], 'A' :비디오 메모리에 쓴다.
화면의 첫부분에 ‘A’자를 나타낸다. 여기서 byte[]는 C언어의 char형과 같은 1바이트형의 포인터.
inc edi :한개의 byte를 썻으므로 1을 더한다. 주소를 한칸 뒤로 옮긴다.
mov byte[es:edi], 0x06 :배경색을 쓴다. ‘A’를 갈색바탕에 검은 글씨로 나타낸다.
inc edi :한개의 byte를 썻으므로 1을 더한다. 한글자는 2바이트로 구성된다.(앞은ASCII,뒤는 색)
mov byte[es:edi], 'B' :반복
inc edi
mov byte[es:edi], 0x06
inc edi
mov byte[es:edi], 'C'
inc edi
mov byte[es:edi], 0x06
inc edi
mov byte[es:edi], '1'
inc edi
mov byte[es:edi], 0x06
inc edi
mov byte[es:edi], '2'
inc edi
mov byte[es:edi], 0x06
inc edi
mov byte[es:edi], '3'
inc edi
mov byte[es:edi], 0x06
jmp $ :여기서 무한루프를 돈다.
$는 현재 이 명령이 있는 주소값을 나타내는 것이고, jmp $는 while(1)과 같다.
msgBack db'.', 0xE7 :배경색으로 사용할 데이터로 위에서 jmp$로 무한루프를 돌기 떄문에 이곳이 실행되지는 않는다. 실행된다면 cpu가 이상한 동작을 할것이다.
times 510-($-$$) db : 0x06에서부터 509번지까지 0으로 채운다.
dw 0xAA55 :510번지에서 0xAA를, 511번지에서 0x55를 넣어둔다.
바이오스가 디스크의 처음 mbr부분을 복사할떄 mbr의 제일 끝의 한 워드에 0xAA55 값이 있으면 이곳이 MBR이 맞다고 판단하게 되므로, 이값을 꼭 써줄 필요가 있다.
참고:
리얼 모드 에서는 메모리상에 저장된 데이터의 종류에 따라 CS, DS, SS, ES 로 나뉘는데, 코드 세그먼트 (CS)는 현재 사용중인 프로그램의 코드가 저장된 세그먼트의 주소를 가르키고, 데이터 세그먼트 (DS)는 현재 프로그램이 사용중인 데이터가 저장된 세그먼트의 주소를 가르키며, 스택 세그먼트 (SS)는 현재 프로그램에서 사용중인 스택이 저장된 세그먼트의 주소를 가르키고, 확장 세그먼트(EXTRA segment) (ES)는 프로그래머에 의해 결정된다.
참고:
Real Mode: 컴퓨터에 전원이 들어온 후 cpu가 처음 움직이기 시작하면서 활동하는 모드로 한번에 한가지의 일밖에 하지 못하는 문제가 있지만 호환성의 이점으로 인하여 아직도 사용되고 있으며 모든 커널은 컴퓨터에 전원이 들어온 후 리얼 모드에서 여러 가지 하드웨어적인 세팅을 마친후 프로텍티드 모드로 CPU를 전환한다.
Protected Mode: 모든 프로그램이 동시에 동작할수 있다. 이 모드에서는 유저모드와 커널모드의 두가지로 다시 나뉘어지는데, 인터럽트를 통하여 다중프로그래밍처럼 보여지게 할수 있다.
세그먼트와 오프셋: 앞에서 만든 프로그램의 맨 마지막에 디스크의 첫 512바이트를 램으로 읽어들인다는 이야기를 했다. 이 과정에서 바이오스 프로그램은 디스크에 있는 프로그램을 램의 0X07C00번저에 복사한다. 여기서 0X07C00번지를 물리주소라 부르고 0X07C0:0000 등을 논리 주소라한다.
물리주소는 CPU와 램의 연결선인 어드레스 버스에 실제로 나타나는 전기신호이다. 논리주소는 프로그래머가 소스를 작성할 때와 컴파일러가 소스를 기계어로 컴파일 했을 떄의 결과물인 기계어에 사용된다. 이 기계어가 실행될때 CPU의 하드웨어적인 펌웨어가 논리주소를 물리주소로 변환시켜 사용한다. 변환 시킬떄에는 세그먼트에 있는 값에 16을 곱하여 거기에 오프셋을 더한다.
따라서 0X07C0:005은 다음과 같이 계산할수 있다.
0X7C00+0X0005 = 0X7C05 (자릿수를 맞추기 위하여=>) 0X07C05
지금 설명한 것은 Real Mode에서의 주소 지정방식이다.
참고: Memory Map
참고:
#Disasm_boot.txt 00000000 EA0500C007 jmp word 0x7c0:0x5 :첫번째 칸의 숫자 00000000은 프로그램 기계어 코드의 실제 번지수이다. 두번째EA0500C007 은 프로그램의 실제 기계어이며 세번째 칸의 문장은 방금 전에 우리가 작성한 어셈블리어 프로그램이다. 00000005 8CC8 mov ax,cs 0x05에서 시작하는 이유는 위에서 4개의 오프셋을 차지하였기 때문이다. 00000007 8ED8 mov ds,ax 00000009 B800B8 mov ax,0xb800 0000000C 8EC0 mov es,ax 0000000E BF0000 mov di,0x0 00000011 A17A00 mov ax,[0x7a] 00000014 B9FF07 mov cx,0x7ff 00000017 268905 mov [es:di],ax 0000001A 83C702 add di,byte +0x2 0000001D 49 dec cx 0000001E 75F7 jnz 0x17 00000020 66BF00000000 mov edi,0x0 00000026 2667C60741 mov byte [es:edi],0x41 0000002B 6647 inc edi 0000002D 2667C60706 mov byte [es:edi],0x6 00000032 6647 inc edi 00000034 2667C60742 mov byte [es:edi],0x42 00000039 6647 inc edi 0000003B 2667C60706 mov byte [es:edi],0x6 00000040 6647 inc edi 00000042 2667C60743 mov byte [es:edi],0x43 00000047 6647 inc edi 00000049 2667C60706 mov byte [es:edi],0x6 0000004E 6647 inc edi 00000050 2667C60731 mov byte [es:edi],0x31 00000055 6647 inc edi 00000057 2667C60706 mov byte [es:edi],0x6 0000005C 6647 inc edi 0000005E 2667C60732 mov byte [es:edi],0x32 00000063 6647 inc edi 00000065 2667C60706 mov byte [es:edi],0x6 0000006A 6647 inc edi 0000006C 2667C60733 mov byte [es:edi],0x33 00000071 6647 inc edi 00000073 2667C60706 mov byte [es:edi],0x6 00000078 EBFE jmp short 0x78 0000007A 2EE700 cs out 0x0,ax 0000007D 0000 add [bx+si],al 0000007F 0000 add [bx+si],al 00000081 0000 add [bx+si],al 00000083 0000 add [bx+si],al 00000085 0000 add [bx+si],al 00000087 0000 add [bx+si],al 00000089 0000 add [bx+si],al 0000008B 0000 add [bx+si],al 0000008D 0000 add [bx+si],al 0000008F 0000 add [bx+si],al 00000091 0000 add [bx+si],al 00000093 0000 add [bx+si],al 00000095 0000 add [bx+si],al 00000097 0000 add [bx+si],al 00000099 0000 add [bx+si],al 0000009B 0000 add [bx+si],al 0000009D 0000 add [bx+si],al 0000009F 0000 add [bx+si],al 000000A1 0000 add [bx+si],al 000000A3 0000 add [bx+si],al 000000A5 0000 add [bx+si],al 000000A7 0000 add [bx+si],al 000000A9 0000 add [bx+si],al 000000AB 0000 add [bx+si],al 000000AD 0000 add [bx+si],al 000000AF 0000 add [bx+si],al 000000B1 0000 add [bx+si],al 000000B3 0000 add [bx+si],al 000000B5 0000 add [bx+si],al 000000B7 0000 add [bx+si],al 000000B9 0000 add [bx+si],al 000000BB 0000 add [bx+si],al 000000BD 0000 add [bx+si],al 000000BF 0000 add [bx+si],al 000000C1 0000 add [bx+si],al 000000C3 0000 add [bx+si],al 000000C5 0000 add [bx+si],al 000000C7 0000 add [bx+si],al 000000C9 0000 add [bx+si],al 000000CB 0000 add [bx+si],al 000000CD 0000 add [bx+si],al 000000CF 0000 add [bx+si],al 000000D1 0000 add [bx+si],al 000000D3 0000 add [bx+si],al 000000D5 0000 add [bx+si],al 000000D7 0000 add [bx+si],al 000000D9 0000 add [bx+si],al 000000DB 0000 add [bx+si],al 000000DD 0000 add [bx+si],al 000000DF 0000 add [bx+si],al 000000E1 0000 add [bx+si],al 000000E3 0000 add [bx+si],al 000000E5 0000 add [bx+si],al 000000E7 0000 add [bx+si],al 000000E9 0000 add [bx+si],al 000000EB 0000 add [bx+si],al 000000ED 0000 add [bx+si],al 000000EF 0000 add [bx+si],al 000000F1 0000 add [bx+si],al 000000F3 0000 add [bx+si],al 000000F5 0000 add [bx+si],al 000000F7 0000 add [bx+si],al 000000F9 0000 add [bx+si],al 000000FB 0000 add [bx+si],al 000000FD 0000 add [bx+si],al 000000FF 0000 add [bx+si],al 00000101 0000 add [bx+si],al 00000103 0000 add [bx+si],al 00000105 0000 add [bx+si],al 00000107 0000 add [bx+si],al 00000109 0000 add [bx+si],al 0000010B 0000 add [bx+si],al 0000010D 0000 add [bx+si],al 0000010F 0000 add [bx+si],al 00000111 0000 add [bx+si],al 00000113 0000 add [bx+si],al 00000115 0000 add [bx+si],al 00000117 0000 add [bx+si],al 00000119 0000 add [bx+si],al 0000011B 0000 add [bx+si],al 0000011D 0000 add [bx+si],al 0000011F 0000 add [bx+si],al 00000121 0000 add [bx+si],al 00000123 0000 add [bx+si],al 00000125 0000 add [bx+si],al 00000127 0000 add [bx+si],al 00000129 0000 add [bx+si],al 0000012B 0000 add [bx+si],al 0000012D 0000 add [bx+si],al 0000012F 0000 add [bx+si],al 00000131 0000 add [bx+si],al 00000133 0000 add [bx+si],al 00000135 0000 add [bx+si],al 00000137 0000 add [bx+si],al 00000139 0000 add [bx+si],al 0000013B 0000 add [bx+si],al 0000013D 0000 add [bx+si],al 0000013F 0000 add [bx+si],al 00000141 0000 add [bx+si],al 00000143 0000 add [bx+si],al 00000145 0000 add [bx+si],al 00000147 0000 add [bx+si],al 00000149 0000 add [bx+si],al 0000014B 0000 add [bx+si],al 0000014D 0000 add [bx+si],al 0000014F 0000 add [bx+si],al 00000151 0000 add [bx+si],al 00000153 0000 add [bx+si],al 00000155 0000 add [bx+si],al 00000157 0000 add [bx+si],al 00000159 0000 add [bx+si],al 0000015B 0000 add [bx+si],al 0000015D 0000 add [bx+si],al 0000015F 0000 add [bx+si],al 00000161 0000 add [bx+si],al 00000163 0000 add [bx+si],al 00000165 0000 add [bx+si],al 00000167 0000 add [bx+si],al 00000169 0000 add [bx+si],al 0000016B 0000 add [bx+si],al 0000016D 0000 add [bx+si],al 0000016F 0000 add [bx+si],al 00000171 0000 add [bx+si],al 00000173 0000 add [bx+si],al 00000175 0000 add [bx+si],al 00000177 0000 add [bx+si],al 00000179 0000 add [bx+si],al 0000017B 0000 add [bx+si],al 0000017D 0000 add [bx+si],al 0000017F 0000 add [bx+si],al 00000181 0000 add [bx+si],al 00000183 0000 add [bx+si],al 00000185 0000 add [bx+si],al 00000187 0000 add [bx+si],al 00000189 0000 add [bx+si],al 0000018B 0000 add [bx+si],al 0000018D 0000 add [bx+si],al 0000018F 0000 add [bx+si],al 00000191 0000 add [bx+si],al 00000193 0000 add [bx+si],al 00000195 0000 add [bx+si],al 00000197 0000 add [bx+si],al 00000199 0000 add [bx+si],al 0000019B 0000 add [bx+si],al 0000019D 0000 add [bx+si],al 0000019F 0000 add [bx+si],al 000001A1 0000 add [bx+si],al 000001A3 0000 add [bx+si],al 000001A5 0000 add [bx+si],al 000001A7 0000 add [bx+si],al 000001A9 0000 add [bx+si],al 000001AB 0000 add [bx+si],al 000001AD 0000 add [bx+si],al 000001AF 0000 add [bx+si],al 000001B1 0000 add [bx+si],al 000001B3 0000 add [bx+si],al 000001B5 0000 add [bx+si],al 000001B7 0000 add [bx+si],al 000001B9 0000 add [bx+si],al 000001BB 0000 add [bx+si],al 000001BD 0000 add [bx+si],al 000001BF 0000 add [bx+si],al 000001C1 0000 add [bx+si],al 000001C3 0000 add [bx+si],al 000001C5 0000 add [bx+si],al 000001C7 0000 add [bx+si],al 000001C9 0000 add [bx+si],al 000001CB 0000 add [bx+si],al 000001CD 0000 add [bx+si],al 000001CF 0000 add [bx+si],al 000001D1 0000 add [bx+si],al 000001D3 0000 add [bx+si],al 000001D5 0000 add [bx+si],al 000001D7 0000 add [bx+si],al 000001D9 0000 add [bx+si],al 000001DB 0000 add [bx+si],al 000001DD 0000 add [bx+si],al 000001DF 0000 add [bx+si],al 000001E1 0000 add [bx+si],al 000001E3 0000 add [bx+si],al 000001E5 0000 add [bx+si],al 000001E7 0000 add [bx+si],al 000001E9 0000 add [bx+si],al 000001EB 0000 add [bx+si],al 000001ED 0000 add [bx+si],al 000001EF 0000 add [bx+si],al 000001F1 0000 add [bx+si],al 000001F3 0000 add [bx+si],al 000001F5 0000 add [bx+si],al 000001F7 0000 add [bx+si],al 000001F9 0000 add [bx+si],al 000001FB 0000 add [bx+si],al 000001FD 0055AA add [di-0x56],dl |