IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C Discussion :

Une fonction qui fonctionne, mais qui ne veut pas fonctionner


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2014
    Messages
    18
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 29
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2014
    Messages : 18
    Par défaut Une fonction qui fonctionne, mais qui ne veut pas fonctionner
    Bonjour à tous, je développe mon propre système d'exploitation en assembleur (syntaxe NASM) et en C avec gcc. Je suis aux prémices de mon système et j'ai un bug dans l'exécution de mon petit noyau que je ne parviens pas à résoudre :
    j'ai une fonction print qui écrit dans la mémoire vidéo une chaîne de caractère qu'on lui passe en argument, je l'ai écrite en deux versions :

    version 1 :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    void print (const uint8_t* string)
    {
        for (const uint8_t* i = string; *i != 0; ++i)
        {
            put_char(*i, char_color | char_mode);
            ++cursor_x;
        }
    }
    et version 2 :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    void print (const uint8_t* string)
    {
        for (; *string != 0; ++string)
        {
            put_char(*string, char_color | char_mode);
            ++cursor_x;
        }
    }
    (que personnellement je n'aime pas)

    j'ai ensuite deux versions de mon noyau (si on peut vraiment lui donner ce nom) qui appelle cette fonction, une en assembleur et une en C :

    version assembleur:
    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
    BITS 32
     
    extern init_video
    extern print
     
    global _start
     
    _start:
    call init_video
    mov eax, msg
    push eax
    call print
    pop eax
     
    cli
    hlt
    msg: db " OK : Beetle kernel loaded successfully !", 0
    et version C :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    #include "Beetle/screen.h"
     
    void _start (void)
    {
        init_video();
        print(" OK : Beetle kernel loaded successfully !");
        while(1);
    }
    Quand je compile pour utiliser mon "noyau" assembleur l'appel à ma fonction print marche parfaitement et le texte voulu s'affiche à l'écran, peut importe la version de print que j'utilise, cependant pour la version C du noyau l'appelle marche mais le texte ne s'affiche que pour la deuxième version de print, si j'utilise la première, un bandeau blanc de la taille d'un caractère et faisant toute la longueur de la chaîne s'affiche, et je n'ai pas trouvé pourquoi, avez vous une idée? Au cas où ça serait utile voici les arguments que je passe à
    gcc : -c -ffreestanding -nostdlib -lgcc -I /Users/adrien/Documents/Informatique/OS/Beetle/include. A noter que je suis sur Mac et que j'ai dû compiler une version de gcc avec clang ce qui apparemment n'est pas tout à fait supporter, peut être le problème vient-il de là? Je mettrais sous ce poste tout les fichiers avec le code source pour éviter de sur-charger ce message

  2. #2
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2014
    Messages
    18
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 29
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2014
    Messages : 18
    Par défaut Fichiers
    Comme dit je poste ici tout les fichiers dans leurs intégralité

    bootloader.s
    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
    %define BOOT_POS 0x07C0
    %define BOOT_STACK_START 0x50
    %define BOOT_STACK_SIZE 0x76FF
     
    %define KERNEL_POS_SECTOR_START 0x2
    %define KERNEL_SECTOR_SIZE  0x2
    %define KERNEL_POS_COPY 0x7E0 ;Le kernel sera copié à l'adresse 0x7E00
     
    mov ax, BOOT_POS
    mov ds, ax
    mov es, ax
     
    mov ax, BOOT_STACK_START
    mov ss, ax
    mov sp, BOOT_STACK_SIZE
     
    c_error:
    xor ax, ax
    xor dl, dl
    int 0x13
    jc c_error
     
    ;Le contrôleur de disquette est initialisé
    ;On copie 2 secteurs après le premier secteur de la disquette dans lequel le bootloader est chargé
    mov ax, KERNEL_POS_COPY
    mov es, ax
    xor bx, bx
    mov ah, 0x02
    mov al, KERNEL_SECTOR_SIZE
    xor ch, ch
    mov cl, KERNEL_POS_SECTOR_START
    xor dx, dx
    int 0x13
     
    ;passage en mode 32bits
    cli
     
    mov ax, gdt_end
    mov bx, gdt_start
    sub ax, bx
    mov word [gdtr_limit], ax
     
    xor eax, eax
    xor ebx, ebx
    mov ax, ds
    shl eax, 4
    mov ebx, gdt_start
    add eax, ebx
    mov dword [gdtr_base], eax
     
    lgdt [gdtr_limit]
     
    mov eax, cr0
    or eax, 1
    mov cr0, eax
     
    jmp nxt
    nxt:
    mov ax, 0x10
    mov ds, ax
    mov es, ax
    mov fs, ax
    mov gs, ax
    mov ss, ax
    mov esp, BOOT_STACK_START
     
    jmp 0x8:0x7E00
     
    gdt_start:
        null_segment: dd 0, 0
        code_segment: db 0xFF, 0xFF, 0x0, 0x0, 0x0, 10011011b, 11011111b, 0x0
        data_segment: db 0xFF, 0xFF, 0x0, 0x0, 0x0, 10010011b, 11011111b, 0x0
    gdt_end:
     
    gdtr_limit: dw 0x00
    gdtr_base:  dd 0x0
     
    times 510 - ($ - $$) db 0x00
    dw 0xAA55
    screen.h
    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
    #ifndef SCREEN_H
    #define SCREEN_H
     
    #include <stdint.h>
     
    #define VIDEO_RAM_START 0xB8000
    #define VIDEO_RAM_END   0xBFFFF
     
    static uint8_t cursor_x;
    static uint8_t cursor_y;
    static enum COLOR char_color;
    static enum MODE  char_mode;
     
    enum COLOR
    {
        BLACK,
        BLUE,
        GREEN,
        CYAN,
        RED,
        MAGENTA,
        YELLOW,
        WHITE
    };
     
    enum MODE
    {
        FLASH = 1 << 7,
        NO_FLASH = 0 << 7,
        OVER = 1 << 3,
        NO_OVER = 0 << 3,
        DEFAULT = NO_FLASH | NO_OVER
    };
     
    void init_video (void);
    void print      (const uint8_t*);
     
    #endif
    screen.c
    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
    #include "Beetle/screen.h"
     
    void put_char (const uint8_t pchar, const uint8_t char_attr)
    {
        uint8_t* memory_ptr = (uint8_t*)(cursor_y * 160 + cursor_x * 2 + VIDEO_RAM_START);
        *memory_ptr = pchar;
        *(memory_ptr + 1) = char_attr;
    }
     
    void init_video (void)
    {
        for (uint8_t* i = (uint8_t*)VIDEO_RAM_START; i != (uint8_t*) (VIDEO_RAM_END + 1); ++i)
        {
            *i = 0x00;
        }
     
        cursor_x = 0;
        cursor_y = 0;
        char_color = WHITE;
        char_mode  = DEFAULT;
    }
     
    void print (const uint8_t* string)
    {
        for (; *string != 0; ++string)
        {
            put_char(*string, char_color | char_mode);
            ++cursor_x;
        }
    }
    je vais assez doucement dans le développement c'est pour ça qu'il n'y a pas de fonction pour scroller l'écran etc, je teste tout ce que je fais sur machine réelle car j'ai déjà eu la surprise de voir que quelque chose qui fonctionne sur VirtualBox ne fonctionne pas forcément sur mon petit i5

  3. #3
    Expert éminent

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 202
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 202
    Par défaut
    Et si tu ajoutais des warnings de compilations: -Wall et -Wextra (dans un second temps)?
    Et si tu compilais en optimisant (-O2 ou -O3)?

    parce qu'a part une copie d'un pointeur, tes deux versions de la fonction semblent identiques.

  4. #4
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2014
    Messages
    18
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 29
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2014
    Messages : 18
    Par défaut
    Citation Envoyé par ternel Voir le message
    Et si tu ajoutais des warnings de compilations: -Wall et -Wextra (dans un second temps)?
    Et si tu compilais en optimisant (-O2 ou -O3)?

    parce qu'a part une copie d'un pointeur, tes deux versions de la fonction semblent identiques.
    Alors c'est assez étrange :
    J'ai compilé avec -Wall et -Wextra et apparement c'était le fait d'utiliser uint8_t* à la place de char* qui posait problème j'ai donc re compilé en remplaçant uint8_t par char, ça à marché, et maintenant quand je remet la version avec des uint8_t ça marche parfaitement. Je n'ai toujours pas compris le problème mais merci

  5. #5
    Expert confirmé

    Avatar de fearyourself
    Homme Profil pro
    Ingénieur Informaticien Senior
    Inscrit en
    Décembre 2005
    Messages
    5 121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Ingénieur Informaticien Senior
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2005
    Messages : 5 121
    Par défaut
    Je pense que tu avais une partie de ton programme qui était compilé avec une autre compréhension des méthodes. Je dis cela parce que je pense que tes méthodes sont identiques.

    En compilant avec O1, j'obtiens le même code assembleur.

    Note: pas de variables statiques dans ton .h...

  6. #6
    Expert éminent

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 202
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 202
    Par défaut
    C'est probablement parce que sur ton système, les char sont signés, ce qui n'est pas le cas des uint8_t.

  7. #7
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2014
    Messages
    18
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 29
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2014
    Messages : 18
    Par défaut
    Citation Envoyé par ternel Voir le message
    C'est probablement parce que sur ton système, les char sont signés, ce qui n'est pas le cas des uint8_t.
    pourtant du point de vue du processeur signé ou pas ça ne veut plus rien dire, c'est juste une interprétation du compilateur ça après, ça pourrait jouer un rôle de signer ou pas ses variables ? Ça me semble assez étrange

    Citation Envoyé par fearyourself Voir le message
    Je pense que tu avais une partie de ton programme qui était compilé avec une autre compréhension des méthodes. Je dis cela parce que je pense que tes méthodes sont identiques.

    En compilant avec O1, j'obtiens le même code assembleur.

    Note: pas de variables statiques dans ton .h...
    Bat elles me semblent totalement identique c'est bien pour ça que je ne comprenais pourquoi ça ne marchait pas, et pourquoi je le comprends encore moins maintenant que ça marche.

    De toute façon, je pense que vu ce dans quoi je m'embarque je n'ai pas finis d'en rencontrer des choses étranges qui devraient marcher et qui ne marchent pas ^^ En parlant de ça je bloque sur quelque chose donc je vais probablement réapparaître dans un nouveau post mais pas avant d'avoir moi même retourner le problème dans tout les sens. En tout cas merci pour vos réponses rapides, bonne soirée à vous

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

Discussions similaires

  1. Réponses: 1
    Dernier message: 20/04/2011, 17h03
  2. Réponses: 3
    Dernier message: 20/04/2008, 21h06
  3. Une formule qui ne veut pas fonctionner
    Par Maxence45 dans le forum Excel
    Réponses: 4
    Dernier message: 09/11/2007, 01h17
  4. [C#] Fonction comme MessageBox mais qui renvoie un string
    Par kinou dans le forum Windows Forms
    Réponses: 5
    Dernier message: 19/05/2006, 11h40
  5. Une table qui existe mais qui est inconnu! ?
    Par Nino dans le forum InterBase
    Réponses: 6
    Dernier message: 13/06/2003, 11h47

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