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

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

    Informations professionnelles :
    Activité : Ingénieur Temps Réel et Android
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Décembre 2007
    Messages : 41
    Points : 46
    Points
    46
    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.
    Président du Club Insitec.fr

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

    Informations professionnelles :
    Activité : Ingénieur Temps Réel et Android
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Décembre 2007
    Messages : 41
    Points : 46
    Points
    46
    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
    Président du Club Insitec.fr

  3. #3
    Membre éclairé
    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
    Points : 701
    Points
    701
    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 du Club
    Avatar de daniel06600
    Homme Profil pro
    Ingénieur Temps Réel et Android
    Inscrit en
    Décembre 2007
    Messages
    41
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 67
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur Temps Réel et Android
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Décembre 2007
    Messages : 41
    Points : 46
    Points
    46
    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
    Président du Club Insitec.fr

  5. #5
    Membre confirmé 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
    Points : 567
    Points
    567
    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]".
    :wq

  6. #6
    Membre éclairé
    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
    Points : 701
    Points
    701
    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 éclairé
    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
    Points : 701
    Points
    701
    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 du Club
    Avatar de daniel06600
    Homme Profil pro
    Ingénieur Temps Réel et Android
    Inscrit en
    Décembre 2007
    Messages
    41
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 67
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur Temps Réel et Android
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Décembre 2007
    Messages : 41
    Points : 46
    Points
    46
    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....
    Président du Club Insitec.fr

  9. #9
    Membre régulier
    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
    Points : 89
    Points
    89
    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)

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

    Informations professionnelles :
    Activité : Ingénieur Temps Réel et Android
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Décembre 2007
    Messages : 41
    Points : 46
    Points
    46
    Billets dans le blog
    1
    Par défaut
    Oui c'est la partie en C qui pose problème.
    Voici une longue explication d'un test relativement simple qui montre le problème.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    int _main(int valeur)// Valeur est le push eax
    {
       int val;
       val = valeur;
       val = val *2;
       return(val);// val reste dans eax
    }
    Compilé en 32 bits avec GCC cela donne.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    00003000 <__main>:
        3000: 55           push   %ebp
        3001: 89 e5        mov    %esp,%ebp
        3003: 83 ec 04     sub    $0x4,%esp
        3006: 8b 45 08     mov    0x8(%ebp),%eax
        3009: 89 45 fc     mov    %eax,0xfffffffc(%ebp)
        300c: 8b 45 fc     mov    0xfffffffc(%ebp),%eax
        300f: 01 c0        add    %eax,%eax
        3011: 89 45 fc     mov    %eax,0xfffffffc(%ebp)
        3014: 8b 45 fc     mov    0xfffffffc(%ebp),%eax
        3017: c9           leave  
        3018: c3           ret
    et cela ne marche pas, il passe mais au final dans eax il n'y a pas la value attendue.

    Maintenant si je compile le bout de code avec la pseudo directive comme suit
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    __asm__(".code16");
    int _main(int valeur)// Valeur est le push eax
    {
       int val;
       val = valeur;
       val = val *2;
       return(val);// val reste dans eax
    }
    Cela donne avec le desasembleur GCC
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    00003000 <__main>:
        3000: 66 55                 push   %bp
        3002: 66 89 e5             mov    %sp,%bp
        3005: 66 83 ec 04         sub    $0x4,%sp
        3009: 67 66 8b 45 08     addr16 mov 8(%di),%ax
        300e: 67 66 89 45 fc     addr16 mov %ax,-4(%di)
        3013: 67 66 8b 45 fc     addr16 mov -4(%di),%ax
        3018: 66 01 c0             add    %ax,%ax
        301b: 67 66 89 45 fc     addr16 mov %ax,-4(%di)
        3020: 67 66 8b 45 fc     addr16 mov -4(%di),%ax
        3025: c9                     leave  
        3026: c3                     ret
    Ou encore avec un autre desasembleur en lui disant c'est du 16 bits
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    ** 00000000 6655                 push	ebp
    ** 00000002 6689E5              mov	ebp,esp
    ** 00000005 6683EC04          sub	esp,byte 04h
    ** 00000009 67668B4508       mov	eax,[ebp+08h]
    ** 0000000E 67668945FC       mov	[ebp-04h],eax
    ** 00000013 67668B45FC       mov	eax,[ebp-04h]
    ** 00000018 6601C0             add	eax,eax
    ** 0000001B 67668945FC       mov	[ebp-04h],eax
    ** 00000020 67668B45FC       mov	eax,[ebp-04h]
    ** 00000025 C9                   leave	
    ** 00000026 C3                   ret
    ou en lui disant c'est du 32 bits
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    00000000 6655                   push	bp
    00000002 6689E5                mov	bp,sp
    00000005 6683EC04             sub	sp,byte 04h
    00000009 67668B4508          mov	ax,[di+08h]
    0000000E 67668945FC          mov	[di-04h],ax
    00000013 67668B45FC          mov	ax,[di-04h]
    00000018 6601C0                add	ax,ax
    0000001B 67668945FC          mov	[di-04h],ax
    00000020 67668B45FC          mov	ax,[di-04h]
    00000025 C9                       leave	
    00000026 C3                       ret
    Et là le bout de code fonctionne et retourne la bonne valeur dans eax.
    Donc le bon desasemblage est celui que j'ai précédé par deux étoiles ci dessus.

    Mais si maintenant je fais
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    __asm__(".code16");
    int _main(int valeur)// Valeur est le push eax
    {
    	int val;
    	val = valeur;
    	val = FonctionX2(val);
    	return(val);// val reste dans eax
    }
    int FonctionX2(int valeur)
    {
    	int val;
    	val = valeur *2;
    	return(val);
    }
    Cela donne avec le bon desasemblage
    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
    00000000 6655                 push	ebp
    00000002 6689E5              mov	ebp,esp
    00000005 6683EC08           sub	esp,byte 08h
    00000009 67668B4508        mov	eax,[ebp+08h]
    0000000E 67668945FC        mov	[ebp-04h],eax
    00000013 67668B45FC        mov	eax,[ebp-04h]
    00000018 6766890424        mov	[esp+esp],eax
    0000001D E80C00              call	00000002Ch
    00000020 67668945FC        mov	[ebp-04h],eax
    00000025 67668B45FC        mov	eax,[ebp-04h]
    0000002A C9                    leave	
    0000002B C3                    ret	
    0000002C 6655                 push	ebp
    0000002E 6689E5              mov	ebp,esp
    00000031 6683EC04           sub	esp,byte 04h
    00000035 67668B4508        mov	eax,[ebp+08h]
    0000003A 6601C0              add	eax,eax
    0000003D 67668945FC       mov	[ebp-04h],eax
    00000042 67668B45FC       mov	eax,[ebp-04h]
    00000047 C9                    leave	
    00000048 C3                    ret
    Mais au final dans EAX il n'y a pas la bonne valeur.
    Donc au final c'est inexploitable, et je suis perdu..........
    Président du Club Insitec.fr

  11. #11
    Membre éclairé
    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
    Points : 701
    Points
    701
    Billets dans le blog
    1
    Par défaut
    ouhaaa, et dire que tout le monde code en C au minimum, je vous plaint, l'optimisation, c'est pas du tout ça en C
    je vois plein d'instructions inutiles, genre:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    pour obtenir un litre d'eau:
    mettre un demi litre
    ajouter deux decilitres
    ajouter un quart de litre
    ajouter 5 centilitres
    effectuer l'algorithme dans l'autre sens pour verifier
    si c'est ça le C, on est pas pret de me voir en faire... ;-)

    les prefixes.
    66h, 67h
    ils servent à inverser provisoirement le mode du µP
    si un code à le prefixe 66h ou 67h le µP voit ça comme du code dans l'autre mode que le mode courant, et je l'ai déja marqué plus haut.
    ici, c'est de l'asm qu'on parle, pas de desassemblege de C.
    le C, c'est juste pour permettre aux gens de coder sans trop se fatiguer, en gros C = Qbasic.
    d'ailleur, ils ont la meme couche d'appel de fonctions, pleine de push est de pop

  12. #12
    Membre confirmé 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
    Points : 567
    Points
    567
    Par défaut
    Citation Envoyé par edfed Voir le message
    ouhaaa, et dire que tout le monde code en C au minimum, je vous plaint, l'optimisation, c'est pas du tout ça en C
    je vois plein d'instructions inutiles, genre:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    pour obtenir un litre d'eau:
    mettre un demi litre
    ajouter deux decilitres
    ajouter un quart de litre
    ajouter 5 centilitres
    effectuer l'algorithme dans l'autre sens pour verifier
    si c'est ça le C, on est pas pret de me voir en faire... ;-)
    Il serait quand même temps que tu apprennes pour de vrai à quoi ressemble un langage de haut niveau au lieu de colporter tes a priori. On n'active pas les optimisations des compilateurs pour le plaisir quand on fait des essais, mais forcément ça donne du code assembleur moche. Avec GCC il faut au moins être en -O2 pour que ce soit lisible.
    Daniel si j'ai bien compris GCC ne se rend même pas compte que le code doit être compilé en 16 bits, du coup ça donne des bizarreries et tu utilises à tout bout de cham préfixes 66h et 67h partout, et je ne comprends pas comment le code fonctionne correctement si il est censé être 32 bits. À la limite peut-être ta fonction d'exemple retourne la bonne valeur, mais seulement dans AX et pas EAX. Ou alors le code s'exécute en 16 bits et les instructions préfixées sont prises pour des instructions 32 bits. Tu devrais demander sur le forum de FASM, de MASM32 ou autre...
    :wq

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

    Informations professionnelles :
    Activité : Ingénieur Temps Réel et Android
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Décembre 2007
    Messages : 41
    Points : 46
    Points
    46
    Billets dans le blog
    1
    Par défaut
    Merci de tous vos conseils, je vais refaire un code très petit en asm 16 qui prépare le passage en protected mode et continu avec du code 32 bits afin d'isoler uniquement ce problème. Je reviendrai vers vous si mon pentium refuse toujours de passer en 32 bits. Ce sera beaucoup plus facile et on n'aura pas tendance à vouloir refaire le monde. Au revoir et encore merci...
    Daniel
    Président du Club Insitec.fr

  14. #14
    Membre régulier
    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
    Points : 89
    Points
    89
    Par défaut
    J'ai deux pistes :

    1/ une fonction '_main' peut-elle accepter un paramètre ?

    2/ peut-elle renvoyer une valeur autres que celles déterminées par le système d'exploitation ?

    Tout à l'heure (on m'appelle pour le repas) je compilerais l'exemple avec Visual et je vous dirais ce qu'il en est.

  15. #15
    Membre régulier
    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
    Points : 89
    Points
    89
    Par défaut
    Apparemment il n'y a aucun contrôle de la valeur retournée par "main"

    le C de microsoft produit le code ci-après pour une fonction ainsi faite :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    int f(int val)
    {
    	int val2;
    	val2 = val * 2;
    	return val2;
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
      00000	55		push	 ebp
      00001	8b ec		mov	 ebp, esp
     
      00003	8b 45 08	mov	 eax, DWORD PTR _val$[ebp]
      00006	d1 e0		 shl	 eax, 1
      00008	89 45 f8	mov	 DWORD PTR _val2$[ebp], eax
     
      0000a	8b 45 f8	mov	 eax, DWORD PTR _val2$[ebp]
     
      0000d	8b e5		mov	 esp, ebp
      0000f	5d		 pop	 ebp
      00010	c3		ret	 0

    La ligne 0x0a va faire hurler 'EdFed' mais au final c'est assez propre.

    J'ai essayé avec "main" c'est identique

    En conclusion on retrouve notre valeur dans eax.

    Mais je ne comprend pas pourquoi Daniel conclu que le processeur n'est pas en 32 bits (en mode protégé serait plus juste).
    est parfaitement valable en mode réel, la différence c'est la taille des éléments empilés et dépilés. C'est peut être par là qu'il faut chercher.

    Il y a aussi ceci dans le dernier exemple de Daniel

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    00000018 6766890424        mov	[esp+esp],eax
    0000001D E80C00              call	00000002Ch
    le "esp+esp" est vraiment bizarre !

  16. #16
    Membre éclairé
    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
    Points : 701
    Points
    701
    Billets dans le blog
    1
    Par défaut
    selon la valeur de esp:

    si esp = 4, alors on va copier eax à la valeur supposée [esp+4]
    si esp = -4, alors on va copier à [ss:0], l'entry de la fonction.
    et donc, l'optimisation reside dans le fait que c'est plus rapide et plus petit que
    si esp est grand ou autre, alors ça veu dire qu'on ecrit dans une autre partie de la memoire que celle de la fonction, ou alors que la fonction possede un nombre etandu de cases memoires allouées.

    ceci est une optimisation calculée par l'etre humain, et reproduite dans le compilateur ou par un humain.
    c'est ce qu'il faut faire dès qu'un code est fonctionel. optimiser au maximum. en fonction de tout les parametres.

    pour le probleme de code C qui fait planter, je peut pas aider, sauf si on me fournit le meme code en asm (du boot jusquà la fin le code entier, en tout cas ce qui est sur le passage de IP, des pointeurs et des index ) qui fait planter.

    il faudrait peut etre que je lise des bouquins sympas (un bon petit roman policier??) pour réapprendre à parler.

+ 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