Bonjour,
J'ai de nouveau un problème suite à la lecture du tutoriel sur la programmation d'OS. (http://michelizza.developpez.com/rea...ysteme/#LV-B-1)
Actuellement j'ai réussis a passer mon processeur en mode protégé, je parviens a afficher du texte en écrivant directement à l'adresse de la mémoire vidéo.
J'ai tenté de faire une fonction en C qui me permet d'afficher une chaîne de caractère qui se termine par 0x00.
Mais j'ai un problème quand je tente d'appeler cette fonction depuis un noyau écris en assembleur.
En effet, je ne parviens pas a faire un push de mon adresse correctement juste avant mon call.
Voici mon code :
La fonction C (qui n'est pas terminée) :
Le code de mon noyau :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10 void print(char *string) { unsigned char *ptr = (unsigned char *) (0xB8A00); while (*string != 0) { *ptr = *string; *(ptr + 1) = 0x57; ++string; ptr += 2; } }
Le code de mon bootloader :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 [BITS 32] EXTERN print GLOBAL _start _start: jmp start msg1 db "init kernel", 0 start: mov byte [0xB8A00], 'H' mov byte [0xB8A01], 0x56 mov eax, msg1 push eax call print pop eax end: jmp end
Le problème se situe à la ligne 18 de mon noyau.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
80
81
82
83
84
85
86
87
88
89 [BITS 16] ; indique a nasm que l'on travaille en 16 bits [ORG 0x0] jmp start %include "display.asm" msgDebut: db "Chargement du kernel", 13, 10, 0 gdt: db 0, 0, 0, 0, 0, 0, 0, 0 gdt_cs: db 0xFF, 0xFF, 0x0, 0x0, 0x0, 10011011b, 11011111b, 0x0 gdt_ds: db 0xFF, 0xFF, 0x0, 0x0, 0x0, 10010011b, 11011111b, 0x0 gdtptr: dw 0 ; limite dd 0 ; base start: ; initialisation des segments en 0x07C00 mov ax, 0x07C0 mov ds, ax mov es, ax mov ax, 0x8000 mov ss, ax mov sp, 0xf000 ; stack de 0x8F000 -> 0x80000 ; affiche un msg mov si, msgDebut call afficher xor ah, ah xor dl, dl int 0x13 push es mov ax, 0x100 mov es, ax mov bx, 0 mov ah, 2 mov al, 50 mov ch, 0 mov cl, 2 mov dh, 0 mov dl, 0 int 0x13 pop es mov ax, gdtptr mov bx, gdt sub ax, bx mov word [gdtptr], ax xor eax, eax xor ebx, ebx mov ax, ds mov ecx, eax shl ecx, 4 mov bx, gdt add ecx, ebx mov dword [gdtptr+2], ecx cli lgdt [gdtptr] mov si, msgDebut mov eax, cr0 or ax, 1 mov cr0, eax mov si, msgDebut jmp next next: mov ax, 0x10 mov ds, ax mov fs, ax mov gs, ax mov es, ax mov ss, ax mov esp, 0x9F000 jmp dword 0x8:0x1000 times 510-($-$$) db 144 dw 0xAA55
Quand j’exécute l'instruction : mov eax, msg1
msg1 vaut 0x1022.
Alors que ma chaîne se situe en 0x1002.
Voici un extrait de mes traces de debug (j'ai mis en bleu l'endroit où se situe ma chaine, et en rouge, l'instruction exécutée qui pose problème) :
J'ai donc 0x20 octets d'écarts, et je ne parvient pas a comprendre pourquoi.(0) [0x000000000000100e] 0008:000000000000100e (unk. ctxt): mov byte ptr ds:0xb8a00, 0x48 ; c605008a0b0048
<bochs:54>
Next at t=271759839
(0) [0x0000000000001015] 0008:0000000000001015 (unk. ctxt): mov byte ptr ds:0xb8a01, 0x56 ; c605018a0b0056
<bochs:55>
Next at t=271759840
(0) [0x000000000000101c] 0008:000000000000101c (unk. ctxt): mov eax, 0x00001022 ; b822100000
<bochs:56> x/100 0x10:0x1002
[bochs]:
0x0000000000001002 <bogus+ 0>: 0x74696e69 0x72656b20 0x006c656e 0x8a0005c6
0x0000000000001012 <bogus+ 16>: 0xc648000b 0x0b8a0105 0x22b85600 0x50000010
0x0000000000001022 <bogus+ 32>: 0x000003e8 0xfeeb5800 0x83e58955 0x45c710ec
0x0000000000001032 <bogus+ 48>: 0x0b8a00fc 0x8b1eeb00 0xb60f0845 0x8bc28900
0x0000000000001042 <bogus+ 64>: 0x1088fc45 0x83fc458b 0x00c601c0 0x08458357
0x0000000000001052 <bogus+ 80>: 0xfc458301 0x08458b02 0x8400b60f 0x90d875c0
0x0000000000001062 <bogus+ 96>: 0x0000c3c9 0x00000000 0x00000000 0x00000000
J'ai testé avec le code exacte du tutoriel, j'ai toujours ce décalage.
Cela pourrait il provenir de mon environnement ? Bochs ?
Quand je remplace ma ligne mov eax, msg1 par mov eax, 0x1002
Mon message s'affiche correctement.
Merci d'avance pour votre aide,
Partager