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

x86 32-bits / 64-bits Assembleur Discussion :

Semble ne pas passer en 32 bits, il s'exécute comme du 16 bits


Sujet :

x86 32-bits / 64-bits Assembleur

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre actif
    Avatar de daniel06600
    Homme Profil pro
    Ingénieur Temps Réel, Android, Windows et Linux
    Inscrit en
    Décembre 2007
    Messages
    41
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 68
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur Temps Réel, Android, Windows et Linux
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2007
    Messages : 41
    Billets dans le blog
    1
    Par défaut Semble ne pas passer en 32 bits, il s'exécute comme du 16 bits
    Bonjour à tous. En assembleur 16 bits j'ai un prog qui après avoir préparé et passé en protected mode, fait un call vers du code 32 bits mais il l'exécute comme du 16 bits. Exemple au lieu de faire mov eax,A145Fh il fait autre chose. Après plusieurs jours de recherche je ne trouve aucune explication. Quelqu'un aurai déjà rencontré ce problème ou des explications qui me permetterai d'orienter ma recherche. D'avance merci
    Matériel utilisé: PC avec pentium.

  2. #2
    Membre actif
    Avatar de daniel06600
    Homme Profil pro
    Ingénieur Temps Réel, Android, Windows et Linux
    Inscrit en
    Décembre 2007
    Messages
    41
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 68
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur Temps Réel, Android, Windows et Linux
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2007
    Messages : 41
    Billets dans le blog
    1
    Par défaut Le texte de la fonction qui devrai écrire en video ram
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    00003000 <__main>:
        3000:	55                   	push   %ebp
        3001:	89 e5                	mov    %esp,%ebp
        3003:	a1 ff ff ff ff       	mov    0xffffffff,%eax
        3008:	a3 5f 14 0a 00       	mov    %eax,0xa145f
        300d:	b8 fe ca 00 00       	mov    $0xcafe,%eax
        3012:	5d                   	pop    %ebp
        3013:	c3                   	ret

  3. #3
    Membre très actif
    Avatar de edfed
    Profil pro
    être humain
    Inscrit en
    Décembre 2007
    Messages
    476
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : être humain

    Informations forums :
    Inscription : Décembre 2007
    Messages : 476
    Billets dans le blog
    1
    Par défaut
    ton code semble bon, sauf que c'est pas du code, c'est un listing de desassemblege, il faut d'abord faire l'effort de le rendre compilable et lisible avant de poster, pliz!

    use32
    c'est une directive à mettre devant le code fait pour le mode protégé en cas de mix de 16 et 32 bits.
    en effet, il manque un peu le prefixe 66h ou 67h devant tes instructions en cas d'instructions 32bits sous 16bits.
    les prefixes 66h 67h et les autres sont utilisés pour mixer du code 32 et 16
    si le µP est en mode 16bits, ces prefixes servent à dire que c'est du 32bits.
    et si le µP est en mode 32bits, ces prefixes servent à dire que c'est du 16bits.

    le µP est automatiquement mis dans le bon mode, il faut pas oublier les directives use16 use32 et use64 si on mixe differents modes.

    sinon, es tu sur que ton programme ne bug pas, car si c'est le cas, il se peu tres bien que le 32bits fonctionne, mais que comme un truc ne vat pas, ça bug.

  4. #4
    Membre actif
    Avatar de daniel06600
    Homme Profil pro
    Ingénieur Temps Réel, Android, Windows et Linux
    Inscrit en
    Décembre 2007
    Messages
    41
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 68
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur Temps Réel, Android, Windows et Linux
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2007
    Messages : 41
    Billets dans le blog
    1
    Par défaut
    Bonsoir edfed. Bien sur que c'est du listing, si non on ne vois pas le problème.
    USE32 n'est pas dispo sur le compilo, ce bout de code est produit par GCC et il est en 32 bit natif. Quand au code 16 bits il est produit par TASM, les deux codes sont compilés et produits de façon séparé. L'un est en ASM pour le Kernel et l'autre est en C compiler par GCC.
    Dans le Kernel j'ai ajouté les instructions pour initialiser la GDT et passer en la main par un CALL BX au code 32 bits. En résumé cela donne :
    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
    lgdt    fword ptr cs:GdtDescriptor
    call    set_a20
    mov   eax,cr0     ; The lsb of cr0 is the protected mode bit
    or     al,01h	        ; Set protected mode bit
    mov  cr0,eax     ; Mov modified word to the control register
    FJMP32	08h,protected_mode    ; Jump to Start32 (below)
     
    protected_mode:
    ; Initialize all segment registers to 10h (entry #2 in the GDT)
    mov	ax,10h	; entry #1 in GDT
    mov	ds,ax	; ds = 10h
    mov	es,ax	; es = 10h
    mov	fs,ax	; fs = 10h
    mov	gs,ax	; gs = 10h
    mov	ss,ax	; ss = 10h
     
    mov       eax,1234h ;this push is for test only
    push      eax
    mov       ebx,entry_c_code ; 03000h
    call        ebx
    pop        ebx; this pop is for push balance
     
    mov      ebx,cr0	  ; The lsb of cr0 is the protected mode bit
    and       bl,0FEh	  ; Clear protected mode bit
    mov      cr0,ebx	  ; Mov modified word to the control register
    Farjmp real_mode,0h  ; jump to next int real mode with CS=0h
     
    real_mode:
    ; Initialize all segment registers to CS segment register
    mov		bx,cs
    mov		ds,bx
    mov		es,bx
    mov		fs,bx
    mov		gs,bx
    mov		ss,bx
    etc........
     
    la GDT:
    GdtDescriptor:							; GDT descriptor
     dw	GDT_SIZE2 - 1	; GDT limit
     dd	Gdt2		; GDT base address (below)
     ; Global Descriptor Table (GDT) (faster accessed if aligned on 4).
     Gdt2:
     
     ; GDT[0]: Null entry, never used.
     dd	0
     dd	0
     
    ; GDT[1]:	Executable, read-only code, base address of 0, limit of FFFFFh, 
    ;	granularity bit (G) set (making the limit 4GB)
     
     dw	0FFFFh		; Limit[15..0]
     dw	0h		; Base[15..0]
     db	00h		; Base[23..16]
     db	09ah;10011010b	; Present(1) DPL(00) Sys(1) Type[Code(1) C(0) R(1) Acces(0)]
     db	0CFh;11001111b	; Gra(1) Dsize(1) ZERO(0) AVL(0) Limit[19..16]
     db	0h		; Base[31..24]
     
    ; GDT[2]: Writable data segment, covering the save address space than GDT[1].
     
     dw	0FFFFh		; Limit[15..0]
     dw	0h		; Base[15..0]
     db	0h		; Base[23..16]
     db	092h;10010010b	; Present(1) DPL(00) Sys(1) Type[Code(0) E(0) W(1) Acces(0)]
     db	0CFh;11001111b	; Gra(1) Bsize(1) ZERO(0) AVL(0) Limit[19..16]
     db	0h		; Base[31..24]
     
    GDT_SIZE2  EQU	$ - offset Gdt2	; Size, in bytes
    Je ne comprends vraiment pas pourquoi dans la partie code C il ne comprend pas le code 32 bits et il l'execute comme du 16 bits alors que j'ai spécifié un segment 32bits dans les descripteur

  5. #5
    Membre chevronné Avatar de dapounet
    Profil pro
    Étudiant
    Inscrit en
    Juillet 2007
    Messages
    469
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2007
    Messages : 469
    Par défaut
    Citation Envoyé par daniel06600 Voir le message
    BExemple au lieu de faire mov eax,A145Fh il fait autre chose.
    Citation Envoyé par daniel06600 Voir le message
    3008: a3 5f 14 0a 00 mov %eax,0xa145f
    Je ne connais pas bien la syntaxe AT&T mais je crois que la deuxième instruction correspond plutôt à "mov eax, [0xa145f]".

  6. #6
    Membre très actif
    Avatar de edfed
    Profil pro
    être humain
    Inscrit en
    Décembre 2007
    Messages
    476
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : être humain

    Informations forums :
    Inscription : Décembre 2007
    Messages : 476
    Billets dans le blog
    1
    Par défaut
    [TVHA]
    sinon, j'ai commencé un tutoriel sur fasm, il y est expliqué le minimum, je n'ai rien ajouté la dessus depuis que je l'ai commencé, (la flème) et des le debut, je dis:
    "fasm a d'abord été codé en tasm", puis le developpeur de fasm a decidé de faire une syntaxe differente. pourquoi?
    pour que ce soit plus simple.
    et c'est le cas, avant de passer à fasm, je les ai tous essayés, et je n'arrivait à rien, puis avec fasm, tout est devenu plus simple à commprendre et j'ai pu me mettre aux choses serieuses.
    [/TVHA]
    par exemple, lgdt n'a pas besoin d'operateur de format ni de la directive ptr, un simple [balisage] du pointeur quffit à differencier une addresse d'une valeur immediate, et si une des deux operandes à deja son format de defini, nul besoin de rajouter les bytes word et dwords usuels dans d'autres compilos.
    en gros, je fait de la pub non pas pour fasm, mais pour la simplicité de sa syntaxe. tasm, à la poubelle
    masm idem
    etc etc...
    donc il ne reste plus que fasm et ses clones.
    octasm en est un avec le support du single line code, cad qu'on peu ecrire tout le code sur une seule ligne, ça sert pas à grand chose, mais c'est cool.

    tasm = époque revolue
    masm = aussi
    nasm = pareil

    petit rappel sur l'asm intel et autre:
    chaque constructeur de µP à decidé de creer sa propre syntaxe, ce qui ne simplifie la vie de personne. puis, en plus, ils ont pas choisi les syntaxes les plus simples.
    avec des #$ff (asm 6809) au lieu de 0ffh on se retrouve à voyager sur le clavier comme pas possible, ça rend fou
    avec le coup des fs:[0x0453434] c'est pire.

    bon, j'arrete le coup de pub et je te converti vite fait ton code en fasm.

    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
     
            lgdt  [cs:GDT]
            call set_a20
            mov eax,cr0 ; The lsb of cr0 is the protected mode bit
            or al,01h ; Set protected mode bit
            mov cr0,eax ; Mov modified word to the control register
            jmp 08h:protected_mode ; Jump to Start32 (below)
    protected_mode:
    ; Initialize all segment registers to 10h (entry #2 in the GDT)
            mov ax,10h ; entry #1 in GDT
            mov ds,ax ; ds = 10h
            mov es,ax ; es = 10h
            mov fs,ax ; fs = 10h
            mov gs,ax ; gs = 10h
            mov ss,ax ; ss = 10h
            mov eax,1234h ;this push is for test only
            push eax
            mov ebx,entry_c_code ; 03000h
            call ebx
            pop ebx; this pop is for push balance
            mov ebx,cr0 ; The lsb of cr0 is the protected mode bit
            and bl,0FEh ; Clear protected mode bit
            mov cr0,ebx ; Mov modified word to the control register
            jmp 0:real_mode ; jump to next int real mode with CS=0h
    real_mode:
    ; Initialize all segment registers to CS segment register
            mov bx,cs
            mov ds,bx
            mov es,bx
            mov fs,bx
            mov gs,bx
            mov ss,bx
    ;etc........
    align 4
    align 2 ; pour aligner la gdt et gdtr sur les bonnes addresses
    GDT:
    dw GDT_SIZE2 - 1
    dd Gdt2
    Gdt2:
    dd 0,0
    ; GDT[1]: Executable, read-only code, base address of 0, limit of FFFFFh,
    dw 0FFFFh,0,0,9ah,0CFh,0
    ; GDT[2]: Writable data segment, covering the save address space than GDT[1].
    dw 0FFFFh,0,0,92h,0CFh,0
    GDT_SIZE2 = $ - Gdt2
    ; à propos des commentaires, desfois, ils ne sont pas du tout indispensables,
    ;les etiquettes et les instructions parlent d'elles même
    voilà, done...
    ici on voit très clairement que le code est incomplet, il manque encore quelques instructions et un contexte. je ne voit pas vraiment d'où vien ce code, mais il est pas fameux.

  7. #7
    Membre très actif
    Avatar de edfed
    Profil pro
    être humain
    Inscrit en
    Décembre 2007
    Messages
    476
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : être humain

    Informations forums :
    Inscription : Décembre 2007
    Messages : 476
    Billets dans le blog
    1
    Par défaut
    on manque d'elements, le probleme est ailleur.
    sinon, le
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    mov ebx, entry_c_code
    call ebx
    peut etre remplacé par
    s'il te plait,pourrais tu poster le reste?
    parce que dans ce code, hormis la presence de etc..... il n'y a pas d'erreurs.
    sauf peut etre
    qui ne devrai pas se fairte par rapport à cs, mais par rapport à ds, question de securité

  8. #8
    Membre actif
    Avatar de daniel06600
    Homme Profil pro
    Ingénieur Temps Réel, Android, Windows et Linux
    Inscrit en
    Décembre 2007
    Messages
    41
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 68
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur Temps Réel, Android, Windows et Linux
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2007
    Messages : 41
    Billets dans le blog
    1
    Par défaut
    Oui, c'est bien là le problème, il n'y a pas d'erreur visible dans l'extrait de code qui permet de passer du real-mode au protected-mode et la déclaration des 2 segments 32 bits de 4 Go. Pour info le code ASM 16 bits fait 750 Ko et le code C auquel je souhaite me connecter fait 700 Mo, je ne peux pas poster cela. La seulle solution que j'ai trouvée à ce jour est de compiler le code C avec GCC en mode 16 bits en ajoutant une pseudo directive __asm__(".code16"); au début de chaque fichier. Mais dans ce cas, GCC préfixe beaucoup de code, je perds énormément en vitesse (un bon rapport de 3). A ce jour je ne comprends toujours pas pourquoi le pentium n'exécute pas le code en 32 bits pure d'où peut bien venir ce blocage.
    Merci de votre précieuse aide car ce problème me prend la tête. Le Pentium aurai t'il un bug? ou bien c'est moi qui à un bug dans la tête....

  9. #9
    Membre actif
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    82
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Décembre 2007
    Messages : 82
    Par défaut
    Quel est exactement le problème ?

    Le code C ("entry_code" je suppose) est-il exécuté ?
    ou bien est-ce que ça plante avant ?

    Qu'est-ce qui prouve que le compilateur C code en 32 bits ?
    Est-on sur que la GDT n'est pas effacée par le C ?
    Est-on sur que le compilateur C ne s'ajoute pas une entrée ? (genre microsoft)

    Sinon la commutation de modes semble correcte, c'est lorsque l'on fait des segments autres que base=0 et limite=0xFFFFF que cela se complique (particulièrement pour DS)

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

Discussions similaires

  1. requetes qui ne veut pas passer
    Par suya95 dans le forum Requêtes
    Réponses: 14
    Dernier message: 04/07/2006, 14h17
  2. Caractères spéciaux à ne pas passer dans une form
    Par LE NEINDRE dans le forum Général JavaScript
    Réponses: 4
    Dernier message: 02/03/2006, 12h39
  3. [firePropertyChange] semble ne pas fonctionner ?
    Par jcodeunpeu dans le forum AWT/Swing
    Réponses: 11
    Dernier message: 19/12/2005, 14h37
  4. Configuration pour ne pas passer par le proxy
    Par Worldofdada dans le forum JWS
    Réponses: 5
    Dernier message: 10/11/2005, 19h54
  5. Réponses: 12
    Dernier message: 02/09/2005, 17h44

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