1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    février 2014
    Messages
    28
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : février 2014
    Messages : 28
    Points : 18
    Points
    18

    Par défaut Problème d'adresse pour accéder à des données.

    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) :
    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 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
    [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 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
    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
    Le problème se situe à la ligne 18 de mon noyau.
    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) :
    (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 donc 0x20 octets d'écarts, et je ne parvient pas a comprendre pourquoi.

    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,

  2. #2
    Membre averti Avatar de bifur
    passe le balais et l'aspirateur
    Inscrit en
    mars 2008
    Messages
    256
    Détails du profil
    Informations personnelles :
    Âge : 32

    Informations professionnelles :
    Activité : passe le balais et l'aspirateur

    Informations forums :
    Inscription : mars 2008
    Messages : 256
    Points : 420
    Points
    420

    Par défaut

    je pense que c'est parce qu'il manque le [ORG 0x0] au début du code de ton noyau. ce qui m'étonne c'est que le compilateur ait choisis de décaler les données de 32 octets, peut être a cause du bit32?

  3. #3
    Rédacteur/Modérateur


    Homme Profil pro
    Technicien maintenance
    Inscrit en
    août 2011
    Messages
    6 743
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Technicien maintenance
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : août 2011
    Messages : 6 743
    Points : 14 137
    Points
    14 137

    Par défaut

    Le compilateur peut décaler les adresses en réorganisant les variables, en faisant du padding pour que celles-ci tombent sur des multiples afin d'optimiser les accès mémoire.
    Extrait du tuto :
    La directive __attribute__ ((packed)) indique à gcc que la structure en question doit occuper le moins de place possible en mémoire. Sans cette directive, le compilateur insère des octets entre les champs de la structure afin de les aligner pour optimiser la vitesse d'accès. Or dans notre cas, nous voulons que la structure décrive exactement l'occupation en mémoire des données.
    autre extrait du tuto :
    L'option -Ttext indique l'adresse linéaire à partir de laquelle le code commence. Par défaut, ld suppose que le code commence à l'adresse 0x0. Ici, ce paramètre est indispensable, car le code du noyau est recopié par le secteur de boot en 0x1000. La même fonctionnalité était implémentée par la directive [ORG 0x1000] dans les noyaux précédents en assembleur.
    Ma page sur developpez.com : http://chrtophe.developpez.com/ (avec mes articles)
    Mon article sur la création d'un système : http://chrtophe.developpez.com/tutoriels/minisysteme/
    Mon article sur le P2V : http://chrtophe.developpez.com/tutoriels/p2v/
    Consultez nos FAQ : Windows, Linux, Virtualisation

  4. #4
    Membre à l'essai
    Profil pro
    Inscrit en
    février 2014
    Messages
    28
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : février 2014
    Messages : 28
    Points : 18
    Points
    18

    Par défaut

    Citation Envoyé par chrtophe Voir le message
    Le compilateur peut décaler les adresses en réorganisant les variables, en faisant du padding pour que celles-ci tombent sur des multiples afin d'optimiser les accès mémoire.
    Extrait du tuto :
    La directive __attribute__ ((packed)) indique à gcc que la structure en question doit occuper le moins de place possible en mémoire. Sans cette directive, le compilateur insère des octets entre les champs de la structure afin de les aligner pour optimiser la vitesse d'accès. Or dans notre cas, nous voulons que la structure décrive exactement l'occupation en mémoire des données.
    Oui, mais cela concerne les structures de données, dans mon cas, il s'agit d'une simple données.

    Finalement, j'ai réussis a résoudre le problème (il faut encore que je creuse pour bien comprendre pourquoi cette erreur est survenue).

    J'utilisais l'option -m i386linux pour lancer ma commande ld. Avec l'option -m elf_i386, ça fonctionne, je n'ai pas ce décalage.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [WD21] Problème d'ergonomie pour afficher des données
    Par Nhaps dans le forum WinDev
    Réponses: 7
    Dernier message: 28/07/2016, 14h06
  2. Réponses: 5
    Dernier message: 16/04/2015, 22h18
  3. [WD15] Conseils pour accéder à des données
    Par thierrybatlle dans le forum WinDev
    Réponses: 5
    Dernier message: 24/02/2010, 14h38
  4. Réponses: 6
    Dernier message: 20/10/2009, 10h05
  5. Les modules pour accéder à des données ORACLE ?
    Par RemiBousquet dans le forum SAS Base
    Réponses: 2
    Dernier message: 29/06/2009, 15h40

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo