2일차에 대한 것으로 개발 재개를 위해서 helloos.nas을 조금 개량되어 있다. (동작은 동일하다.)


 제대로된 어셈블리 명령어를 이용해서 제작하는 것을 목표로 하고 있는 것이다.


 그 전에 방식은 어셈블리어의 데이터만을 이용해서 만드는 것이라고 한다면, 이번 방식은 어셈블리어의 명령어를 제대로 처리하는 것이다.


 차이점은 이전 글은 기계어를 전부다 알고 있어야 된다면, 이번은 어셈블리어를 알고 있으면 제작이 가능하다는 점이다.


 중간 중간 오류가 나는 소스이다. 일단, 올려 놓고 어떤 문제점이 있는지 기록하면, 조금 더 차이점을 이해 할 수 있을 거라고 생각한다. 그래서 소스를 일단, 올린다.


 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
/*
    Hello-os
    TAB=4
*/
 
//.org    0x7c00;
 
/*
    표준적인 FAT12 포맷 플로피 디스크를 위한 서술
*/
/*
jmp    entry;
.byte    0x90;
*/
.byte    0xeb0x4e0x90;
.ascii    "HELLOIPL";
.word    512;
.byte    1;
.word    1;
.byte    2;
.word    224;
.word    2880;
.byte    0xf0;
.word    9;
.word    18;
.word    2;
.int    0;
.int    2880;
.byte    000x29;
.int    0xffffffff;
.ascii    "HELLO-OS   ";
.ascii    "FAT12   ";
.fill    18;
 
/*
    프로그램 본체
*/
 
entry:
    movw    $0, %ax;
    movw    %ax, %ss;
    movw    $0x7c00, %sp;
    movw    %ax, %ds;
    movw    %ax, %es;
    
    movw    msg, %si;
 
putloop:
    movb    (%si), %al;
    add        $1, %si;
    cmp        $0, %al;
    je        fin;
    movb    $0x0e, %ah;
    movw    $15, %bx;
    int        $0x10;
    jmp        putloop;
    
fin:
    hlt;
    jmp        fin;
    
msg:
    .byte    0x0a0x0a;
    .ascii    "Hello, World!";
    .byte    0x0a;
    .byte    0x00;
 
.org    510-(.-..);
 
.byte    0x550xaa;
 
/*
    부트로더 이외의 부분에 기술
*/
.byte    0xf00xff0xff0x000x000x000x000x00;
.fill    4600;
.byte    0xf00xff0xff0x000x000x000x000x00;
.fill    1469432;
 
cs


 이걸 알아 보는 방향으로 이글을 마친다.

Posted by JunkMam
,

 '꽤 그럴듯한 소스 프로그램' 파트를 작성하면서 꽤 고생했다.


 먼저, 어셈블리어에 익숙 하지 않은 부분을 들수 있다. 그 외도 정보가 부족하다.

 영어 메뉴얼을 전부 다 번역하고 작업을 해야 될 것 같다.


 일단, '꽤 그럴듯한 소스 프로그램' 에서 제대로 작동이 안되는 부분이 있다.


 고쳐야 되는 것으로 구글링을 해보니.


 'RESB    0x01fe-$'라는 부분의 줄을 'times    510-($-$$) db 0x00' 이렇게 되어야된다. 라고 되어있다.


 그래서 이 부분을 times을 검색해야되는지 고민하다가 AT&T에서 .org을 테스트해보았다.


 소스

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
/*
    Hello-os
    TAB=4
*/
 
/*
    표준적인 FAT12 포맷 플로피 ㄷ스크를 위한 서술
*/
 
.byte    0xeb0x4e0x90;
.ascii    "HELLOIPL";
.word    512;
.byte    1;
.word    1;
.byte    2;
.word    224;
.word    2880;
.byte    0xf0;
.word    9;
.word    18;
.word    2;
.int    0;
.int    2880;
.byte    000x29;
.int    0xffffffff;
.ascii    "HELLO-OS   ";
.ascii    "FAT12   ";
.fill    18;
 
/*
    프로그램 본체
*/
.byte    0xb80x000x000x8e0xd00xbc0x000x7c;
.byte    0x8e0xd80x8e0xc00xbe0x740x7c0x8a;
.byte    0x040x830xc60x010x3c0x000x740x09;
.byte    0xb40x0e0xbb0x0f0x000xcd0x100xeb;
.byte    0xee0xf40xeb0xfd;
 
/*
    메세지 부분
*/
.byte    0x0a0x0a;
.ascii    "hello, world";
.byte    0x0a;
.byte    0;
 
.org    510-(.-..);
 
.byte    0x550xaa;
 
/*
    부트로더 이외의 부분에 기술
*/
.byte    0xf00xff0xff0x000x000x000x000x00;
.fill    4600;
.byte    0xf00xff0xff0x000x000x000x000x00;
.fill    1469432;
cs


 이렇게 되어있는데, data double-word라는 것을 처리하는지 찾아보니.

 data double-word라는 것은 32bit을 뜻한다.

 32bit인 int을 사용하면, 된다는 것이다.


 이것 이용해서 메세지 부분을 출력하도록 만들어 봤다.


 여기서 중요한것은 .org이다.


 0x00을 채우는 명령어이기 때문이다.


 .이란, Intel Syntax에서 본다면, $와 동일한 것이고, ..은 Intel Syntax에 본다면, $$와 같다.


  ..($$)과 .($)는 각각 처음 프로그램 위치. 와 현재 프로그램 위치를 뜻한다.


 그래서 현재 위치 - 초기 위치는 음수가 되지 않는 한. 그 둘의 거리가 되는 것이다.


 그래서 0x00을 채워 나가는 소스가 되는 것이다.


 이걸 알기 위해서 근 10시간 이상을 검색했다.


 GNU AS을 사용할려면, 적어도 메뉴얼을 사용해 봐야 될 것 같다.

Posted by JunkMam
,

 "[OS 구조와 원리] - 저. 카와이 히데미" 라는 책이 있다. 이 책에서는 OS 구조와 원리라는 책에서는 NASM이라는 어셈블러를 사용하여 제작하고 있다.


 하지만, NASM을 무조건 사용해야된다는 점이 있다.


 NASM와 GAS가 서로 약간씩 다른 것이 있다.

 먼저, Syntax 차이가 있다. 가장 큰 차이라서 조사를 많이 해야 되는 경우도 있다.


 참조 : https://chromium.googlesource.com/chromium/deps/yasm/patched-yasm/+/master/modules/parsers/gas


 여기서 설명할 수 있는게 있다.


 원본에 존재하는 NASM은 책을 구매해서 비교하면, 될것 같다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
.byte 0xeb0x4e0x900x480x450x4c0x4c0x4f;
.byte 0x490x500x4c0x000x020x010x010x00;
.byte 0x020xe00x000x400x0b0xf00x090x00;
.byte 0x120x000x020x000x000x000x000x00;
.byte 0x400x0b0x000x000x000x000x290xff;
.byte 0xff0xff0xff0x480x450x4c0x4c0x4f;
.byte 0x2d0x4f0x530x200x200x200x460x41;
.byte 0x540x310x320x200x200x200x000x00;
.fill 16;
.byte 0xb80x000x000x8e0xd00xbc0x000x7c;
.byte 0x8e0xd80x8e0xc00xbe0x740x7c0x8a;
.byte 0x040x830xc60x010x3c0x000x740x09;
.byte 0xb40x0e0xbb0x0f0x000xcd0x100xeb;
.byte 0xee0xf40xeb0xfd0x0a0x0a0x680x65;
.byte 0x6c0x6c0x6f0x2c0x200x770x6f0x72;
.byte 0x6c0x640x0a0x000x000x000x000x00;
.fill 368;
.byte 0x000x000x000x000x000x000x550xaa;
.byte 0xf00xff0xff0x000x000x000x000x00;
.fill 4600;
.byte 0xf00xff0xff0x000x000x000x000x00;
.fill 1469432;
cs


 이렇게 하고 난 후에 GAS을 사용하면, 얻어 진다.


 여기서 .fill이랑 책에 있는 내용이랑 다르다.


 .byte라는 것은 Data Byte를 뜻한다.


 NASM은 DB라는 걸로 Data Byte을 처리한다면, AT&T 문법은 .byte라는 걸로 Data Byte을 표현한다.


 NASM은 RESB로 Byte을 채울 수 있다면, GAS는 .fill을 이용해서 채우는 작업을 한다.(이렇게한다면, 책에 어떤 내용을 가지는지 알 수 있을 것이다.)


 GAS에서 컴파일을 하기 위해서는 다음과 같은 명령어들을 입력해줘야 한다.


 as -o boot.o boot.s

 objcopy -O binary boot.o boot.bin


 GCC에서는 -O는 최적화 소스라고 -O는 Output 종류를 뜻한다.


 이렇게 해서 NASM을 설치 하지 않고, boot을 만들어 낼 수 있다.


 GAS을 사용하는 이유는 MinGW나 CygWin만 설치하고 제작을 할 수 있기 때문이다.


 그리고 여러개를 사용할 수 있을 경우. 다양한 환경에서 조절이 가능하니, 미리 해두는 것도 나쁘지는 않는 것 같다.


 완성품

boot.img

boot.o

boot.s


 여기서 Virtual Box에서 테스트 할려면, 플로피 디스크를 생성해서 불러오는 것을 만들어야한다.

Posted by JunkMam
,