Plan de la rencontre Retour sur la semaine précédente


Download 445 b.
Sana19.01.2018
Hajmi445 b.
#24871



Plan de la rencontre

  • Retour sur la semaine précédente

  • Types de données

  • Rangement des données

  • Modes d’adressage

  • Gestion de la pile

  • Variables locales

  • Passage des arguments

  • Interface avec les langages de haut niveau

  • Récursivité, réentrance et translatabilité



La semaine précédente

  • Compilateur

  • Assembleur

  • L’éditeur de liens

  • « Listing files »

  • Assembleur « inline »

  • Déverminage

  • Masm32

  • Programme complètement en assembleur

  • Programme mixte



Types de données entières

  • Octet (byte)

  • Mot (word)

  • Mot double (doubleword)

  • BCD

  • BCD compacté (packed BCD)

  • Near Pointer

  • Far Pointer (Logical Address)

  • Champ de bits (bit field)



Types de données virgule flottante

  • Simple précision

  • Double précision

  • Précision étendue

  • Décimal compacté



float

  • Simple précision

  • Nombres normalisés

    • e = 1 à 254
  • e = 0 réservé pour 0 et les nombres dénormalisés

  • e = 255 réservé pour les infinis et les NaNs



Normalisé vs dénormalisé

  • Nombres normalisés (e = 1 à 254)

  • Nombre maximum normalisé:

  • 1,11111111111111111111111  2127 = 3,402823  1038

  • Nombre minimum normalisé:

  • 1,00000000000000000000000  2-126 = 1,175494  10-38

  • Nombres dénormalisés (e = 0 et f ≠ 0)

  • e = 0 et f ≠ 0. Alors: N = (-1)s  0,f  2-126

  • Nombre dénormalisé minimum:

  • 0.00000000000000000000001  2-126 = 1,401298  10-45



Zéro, infini et NaN

  • Zéro (e = 0 et f = 0)

  • Zéro est représenté par

  • 1,0000000000000000000000 x 2-127

  • = 00000000000000000000000000000000

  • Infini (e = 255 et f = 0)

  • L’infini est représenté par

  • 1,0000000000000000000000 x 2128

  • = 01111111100000000000000000000000

  • = 7F800000

  • Nan (e = 255 et f ≠ 0)



double

  • Double précision

  • Nombres normalisés:

  • e = 1 à 2046

  • e = 0 réservé pour 0 et les nombres dénormalisés

  • e = 2047 réservé pour les infinis et les NaNs



Limites des doubles

  • Nombres normalisés (e entre 1 et 2026)

  • Nombre maximum normalisé:

  • 1,111111111111111…  21023 = 1,79769313486  10308

  • Nombre minimum normalisé:

  • 1,000000000000000…  2-1022 = 2,22507385851  10-308

  • Nombres dénormalisés (e = 0 et f ≠ 0)

  • e = 0 et f ≠ 0. Alors: N = (-1)s  0,f  2-1022

  • Nombre dénormalisé minimum:

  • 0,00000000…000001  2-1022 = 4,94065645842  10-324



Zéro, Infini et NaN

  • Zéro (e = 0 et f = 0)

  • Zéro est représenté par

  • 1,00000… x 2-1023

  • = 0000000000000000

  • Infini (e = 2047 et f = 0)

  • L’infini est représenté par

  • 1,00000000 x 21024

  • = 011111111111000000000….

  • = 7FF0 0000 0000 0000

  • Nan (e = 2047 et f ≠ 0)



Précision étendue

  • Précision étendue

  • Nombres normalisés:

  • e = 1 à 32766

  • e = 0 réservé pour 0 et les nombres dénormalisés

  • e = 32767 réservé pour les infinis et les NaNs



Limites

  • Nombres normalisés (e entre 1 et 16383)

  • Nombre maximum normalisé :

  • 1,11111111111111111…  216383 = 6  104931

  • Nombre minimum normalisé :

  • 1,000000……0000000... 2-16383 = 8  10-4933

  • Nombres dénormalisés

  • e = 0 et f ≠ 0. Alors: N = (-1)s  0,f  2-16383

  • Nombre dénormalisé minimum:

  • 0,00000000…000001  2-16383 = 9  2-4952



Format Packed Decimal

  • Format Packed Decimal

  • Représentation : -1018 + 1 à 1018 - 1



Les NaN

  • Les NaN ne représentent pas des nombres, on ne peut donc pas les comparer avec des nombres. Ce sont des quantités considérées comme non ordonnées.

  • • Pour la même raison, le signe des NaN est ignoré, donc un NaN n’est ni positif ni négatif.

  • • La fraction d’un QNaN (Quiet NaN)est toujours de la forme :

  • 0,1xxxxx…xxxxxxx

  • tandis que celle d’un SNaN (Signaling NaN) est de la forme :

  • 0,0xxxxx…xxxxxxx



Les NaN (la suite)

  • Les Nan

  • • Les SNaN signalent des exceptions lorsqu’ils sont fournis comme opérandes arithmétiques. Ils ne sont jamais générés par une opération. On peut toutefois les créer manuellement en mémoire.

  • • Les QNaN représentent le résultat de certaines opérations invalides telles que des opérations arithmétiques invalides sur des infinis ou sur des NaN.

  • • Un QNaN est généré dans les conditions suivantes:

    • Une opération invalide se produit alors que le masque d’opération invalide de FPSCR est 1.
    • Par exemple ∞ - ∞, ∞ ÷ ∞, 0 ÷ 0, ∞  0, opération sur un SNaN, comparaison ordonnée avec un NaN.
    • La conversion en entier d’un infini ou d’un NaN.


Les NaN (la suite)

  • Les Nan

  • • Les QNaN se propagent à travers toutes les opérations, sauf les comparaisons ordonnées et la conversion en entier, sans signaler d’exception.

  • • Le code d’un QNaN donné peut servir d’information de diagnostic pour permettre d’identifier les résultats d’opérations invalides.

  • • Si l’un ou l’autre des opérandes d’une opération est un NaN, le résultat de l’opération est ce NaN.

  • • Chacune des conditions pouvant provoquer un NaN peut générer une exception, c’est-à-dire une interruption logicielle, si une telle exception est autorisée dans le registre FPCR.



Type de données MMX

  • Octets compactés

  • Mots compactés

  • Double mots compactés

  • Quadruples mots



Types de données SIMD

  • Doubles compactés

  • Quadruples mots

  • Simples compactés

  • Doubles mots compactés

  • Mots compactés

  • Octets compactés



Rangement des données

  • Little Endian vs Big Endian

  • Chez Intel, l’octet de poids faible est stocké à l’adresse la plus basse (Little Endian).



Modes d’adressage



Adressage de registre

    • mov ebx, eax ; (ebx) = (eax)
  • Le plus utilisé

  • Très rapide

  • Utilisé pour tout les calcule interne au processeur

  • La largeur de la données dépends de la largeur du registre

    • AL 8 bits
    • AX 16 bits
    • EAX 32 bits


Adressage immédiat

    • mov eax, 0122Bh ; ou mov eax, 0x0122B
  • mov eax, -1 ; eax = 0xFFFFFFFF

    • mov bx, 3 ; bx = 0x0003
  • Utilisé lors de calcule impliquant des constantes

  • La données et encodé à même l’instruction



Adressage direct

    • mov eax, variable
  • variable est traduite par l’assembleur en offset par rapport au début du segment (habituellement le data segment). Cet offset est l’adresse à laquelle la variable a été implantée.

  • Utilisé pour lire ou écrire des variables de type simple



Adressage implicite

  • Certaines instructions n’ont pas d’opérande explicite et la description de l’adresse est contenue dans l’instruction elle-même ou dans des registres prédéfinis

    • ret ; dépile l’adresse de retour
    • xlat ; utilise EBX et AL
    • mul ; utilise edx et eax
    • div ; utilise edx et eax


Exemple 01

  • ; Constantes

  • ; ////////////////////////////////////////////////////////

  • .const

  • X dw 2

  • ; Variables

  • ; ////////////////////////////////////////////////////////

  • .data

  • sZ dw ?

  • ; Debut du segment de code

  • ; ////////////////////////////////////////////////////////



Exemple 01 (suite)

  • .code

  • ; ===== Start =======================================

  • ; Le point d'entree du programme

  • start:

  • mov ax, X

  • add ax, 2

  • mov sZ, ax

  • push 0

  • call ExitProcess

  • end start



Indirection registre

    • mov edx, [ebx] ; adresse dans ebx
  • Le registre entre crochets est appelé registre de base. Les registres suivants peuvent servir de registre de base :

    • eax edi
    • ebx esi
    • ecx ebp
    • edx esp
  • Indirection registre avec offset

    • mov eax, [ebx + 8] ; adresse = ebx + 8


Exemple 02

  • Disponible sur le site du cours



Instruction lea

  • lea Load Effective Address

  • Calcule l’adresse efficace de l’opérande source et place le résultat dans le registre destination.

    • oszapc = oszapc
    • lea reg, mem 0,5
    • Équivalent :
    • mov reg, offset mem 0,5
  • Quand doit-on utiliser lea au lieu de mov ?

    • Pour les paramètres d'une fonction, on utilise toujours mov.
    • Pour les variables, on utilise lea lorsqu'il s'agit d'une variable de type tableau, mais on utilise mov lorsqu'il s'agit d'un pointeur ou d'un type simple.


Indirection registre avec offset registre

  • L’offset registre est aussi appelé index

    • mov [ebx + edi * k],eax ; adresse = ebx + edi * k
  • ; k = 1, 2, 4 ou 8 seulement

  • Indirection registre avec index + offset

    • mov ax,[ebx + esi * k + 16] ; adresse= ebx + esi * k + 16
  • Les registres suivants peuvent servir d’index :

    • eax edi
    • ebx esi
    • ecx ebp
    • edx


Utilisation des index

  • Dans les modes d’adressage précédents, la constante k permet d’ajuster l’instruction à la taille de l’opérande, de façon à accéder directement au ième élément d’un tableau.

  • Pour des octets (char, byte, boolean), k = 1,

  • pour des mots (short), k = 2,

  • pour des mots doubles (int, long, float), k = 4,

  • pour des mots quadruples (long long, double), k = 8.

  • .data

  • tableau dw 50, 75, 342, -9, …

  • .code

  • lea ebx, tableau

  • mov esi, i

  • mov ax, [ebx + esi * 2] ; ax = tableau[ i ]

  • ...



Exemple 03

  • Disponible sur le site du cours



Entrées-sorties en mode console

  • Dans les exemples précédents, nous aurions pu afficher les résultats en utilisant la méthode démontré dans l’exemple 04

  • A ne surtout pas oublier !

  • Il faut compiler au moyen de Console Assemble & Link.



Programmation Windows

  • On n’utilise plus la console dans les applications contemporaines, mais plutôt une fenêtre avec menus, boutons, bandes de défile-ment, case de fermeture, etc. Par exemple :

  • Pour réaliser de telles applications, il faut faire appel aux libraires de Windows (API). La programmation Windows dépasse le cadre de ce cours, mais vous trouverez des exemples dans les travaux pratiques et sur le site du cours.



Instruction mov

  • mov Move Data

  • Copie l’opérande source dans l’opérande destination

    • oszapc = oszapc
    • mov reg, reg mov dx, bx 0,5
    • mem, reg mov table[edi], ebx
    • reg, mem mov ebx, a
    • reg, immed mov cx, 256
    • mem, immed mov word ptr [ebx], 15


Instructions movzx et movsx

  • Variantes de mov : movzx et movsx

  • Supposons que bl contient 0x94

  • movzx ax, bl -> ax = 0094 = + 148 sur 16 bits

  • movzx eax, bl -> eax = 00000094 = + 148 sur 32 bits

  • movsx ax, bl -> ax = FF94 = –108 sur 16 bits

  • movsx eax, bl -> eax = FFFFFF94 = – 108 sur 32 bits

  • Ces instructions permettent de changer le type d’une variable

  • sx = Signe extend

  • zx = Zero extend



Instructions xchg, xlat et xlatb

  • xchg Exchange

  • Échange les deux opérandes

  • oszapc = oszapc

  • xchg reg, reg xchg cx, dx

  • mem, reg xchg [ebx], ax

  • reg, mem xchg ebx, pointer

  • xlat, xlatb Translate

  • Remplace un indice contenu dans al par le contenu correspondant d’une table dont l’adresse est dans ebx.

  • oszapc = oszapc

  • xlat mem

  • xlatb



Pile d’exécution

  • À quoi sert-elle ?

  • Placer l’adresse de retour lors d’un appel de fonction

  • Sauvegarder le contexte d’exécution lorsqu’une interruption doit être traité

  • Placer les variables locales

  • Passer les arguments à une fonction



Comment le Pentium IV manipule la pile ?

  • Le Pentium IV a trois registres spécialement conçu pour la gestion de la pile

  • SS Stack Segment

  • ESP Stack Pointer

  • EBP Base Pointer

  • ESP pointe sur la dernière donnée empiler et la première à être dépilé.



Instruction call

  • Exemples:

  • call Fonction

  • call sVariable

  • Déroulement:

  • Ajouter la grandeur de l’adresse de retour à ESP

  • Placer l’adresse de retour dans l’espace mémoire pointé par ESP

  • Placer l’opérande dans IP ou EIP



Instruction ret

  • Exemples:

  • ret

  • ret 12

  • Déroulement:

  • Lire l’adresse de retour de l’espace mémoire pointé par ESP et la placer dans IP ou EIP

  • Ajouter la grandeur de l’adresse de retour à ESP

  • Ajoute l’opérande à ESP

  • Spécialement conçu pour qu’une fonction puisse enlever elle même ses arguments de la pile



Exemple 05

  • Disponible sur le site du cours



La pile et les interruptions

  • Lors d’un interruption certaines informations supplémentaires sont placé sur la pile comparativement à un appel de fonction normal

  • cs Code Segment

  • eflags Registre de flags

  • Dans certains cas, d’autres informations sont aussi sauvegardé

  • Le retour d’un interruption se fait à l’aide de l’instruction iret et non ret



Instruction push

  • Exemples:

  • push eax

  • push sVariable

  • push 64

  • Déroulement:

  • Soustrait la grandeur de l’opérande à ESP

  • Place l’opérande dans l’espace mémoire pointé par ESP

  • Dans le mode 32 bit, tout les items poussés sur la pile occupent 4 octets.



Instruction pop

  • Exemples:

  • pop eax

  • pop sVariable

  • Déroulement:

  • Lit la valeur pointée par ESP et la place dans l’opérande

  • Ajoute la grandeur de l’opérande à ESP



pusha – pushad – popa – popad

  • Ces quatre instructions manipule l’ensemble des registre généraux d’un seul coup

  • Sans le D final, les registres suivants sont affectés

  • AX, CX, DX, BX, SP, BP, SI, DI

  • Avec le D final, les registres suivants sont affectés

  • EAX, ECX, EDX, EBX, ESP, EBP, ESI, EDI

  • Très utile pour sauvegarder le contexte d’exécution lors du traitement d’un interruption



pushf – pushfd – popf – popfd

  • Cas particulier pour le traitement du registre de flag

  • Si le processeur est dans un mode d’exécution qui ne permet pas le changement de certains bits du registre, ces bits ne change pas et aucune erreur ne se produit

  • Vous pouvez utiliser ces deux instructions pour conserver, sur la pile, le résultat d’une comparaison



Variables locales

  • Création

  • sub esp, 12

  • Utilisation

  • mov eax, [esp] ; Variable 3

  • inc [esp + 4] ; Variable 2

  • add eax, [esp + 8] ; Variable 1

  • Destruction

  • add esp, 12



« Stack Frame »

  • Espace de rangement pour les variables locales

  • Empiler EBP

  • Copier ESP dans EBP

  • Ajouter la grandeur des variables locales à ESP



Adressage des variables locales

  • Habituellement les variables locales sont adressées en utilisant un adressage indirect basé sur le registre EBP

  • Supposons que la première variable locale soit un mot double, nous pourrions lui ajouter un de la manière suivante

  • inc [ebp+4]



Instruction enter

  • Exemple:

  • enter 12,0

  • Description:

  • Création d’un « Stack Frame » avec N bytes de variables locales



Instruction leave

  • Exemple:

  • leave

  • Description:

  • Retirer un « Stack Frame » de la pile



Passage des arguments

  • Par variables globales

  • Par registres

  • cdecl

  • stdcall

  • fastcall



Passage par variables globales

  • Le moyen le plus simple de tous !

  • L’appelant place les arguments dans des variables globales connues de tous

  • L’appelé lit les arguments de ces même variables globales

  • La valeur de retour peut suivre le même chemin

  • Voir l’exemple 06

  • Que faire pour les fonctions récursives ?

  • Que faire pour les fonctions utilisés par

  • plusieurs threads ?



Passage par registres

  • La méthode plus rapide de tous

  • Très simple

  • Permet les fonctions réentrantes

  • Il faut cependant oublier plusieurs des registres: cs, ds, es, ss, esp,…

  • Il reste donc un nombre limité de registres

  • La valeur de retour peut prendre le même chemin

  • Oblige à sauvegarder les arguments en mémoire pour retrouver l’usage des registres nécessaires aux opérations



cdecl

  • Les arguments sont empilés dans l’ordre inverse de leur déclaration

  • L’appelant a la responsabilité de dépiler les arguments

  • Les arguments plus petit qu’un mot double sont tout de même empilés sous la forme de mots doubles pour préserver l’alignement de la pile



La valeur de retour

  • Si la valeur de retour est un mot double ou qu’elle est plus petite qu’un mot double, elle est placé dans eax

  • Si c’est un mot quadruple, elle est placé dans la paire de registres edx:eax

  • Si c’est une valeur virgule flottante, elle est placé dans st(0)



stdcall

  • Les arguments sont empilés dans l’ordre inverse de leur déclaration

  • La fonction appelée à la responsabilité de dépiler les arguments

  • Si la fonction a un nombre variable d’argumente, c’est l’appelant qui a la responsabilité de dépiler les arguments

  • Les arguments plus petit qu’un mot double sont tout de même empilés sous la forme de mots doubles pour préserver l’alignement de la pile



Fastcall

  • Le premier argument est passé dans le registre ecx

  • Le second argument est passé dans le registre edx

  • Les autres sont empilés sur la pile dans l’ordre inverse de leur déclaration

  • Les arguments plus petit qu’un mot double sont tout de même empilés sous la forme de mots doubles pour préserver l’alignement de la pile



Le “Stack Frame” et les arguments

  • [ebp + 16]

  • [ebp + 12]

  • [ebp + 8]

  • [ebp + 4]

  • [ebp]

  • [ebp – 4]

  • [ebp – 8]



Récursivité

  • Un programme récursif est un programme qui s’appelle lui-même.

  • Un exemple bien connu est celui de la fonction factorielle, même si ce n’est pas une façon très efficace d’évaluer cette fonction:

  • unsigned long factorial(unsigned long n)

  • {

  • if (n == 1)

  • return 1;

  • else

  • return n * factorial(n - 1);

  • }



Récursivité (la suite)

  • En assembleur du Pentium, on aura:

  • factorial:

  • mov eax, [esp+4]

  • cmp eax, 1 // if (n == 1)

  • jne suite

  • mov eax, 1 // return 1

  • jmp fin

  • suite: dec eax

  • push eax // factorial (n - 1)

  • call factorial

  • add esp, 4 // factorial (n-1) dans eax

  • mov ebx, n

  • mul ebx // n * factorial (n - 1) dans eax

  • fin: ret



Réentrance

  • Définition

  • Un programme dit est réentrant s’il peut être interrompu et que le programme interrupteur peut l’appeler et obtenir un résultat correct, et qu’après l’interruption, le programme interrompu donne lui aussi un résultat correct;

  • Conditions

    • Avoir du code pur, c.-à-d. qui ne se modifie pas lui-même: aucune information interne au code ne peut être modifiée par le code;
    • Ne jamais utiliser de stockage temporaire interne au code;
    • Le programme doit être interruptible.
  • Un programme récursif doit être rentrant (s’il n’interdit pas les interruptions), mais un programme réentrant n’est pas nécessairement récursif.



Translatabilité

  • Un sous-programme est dit translatable ou indépendant de la position s'il fonctionne correctement où qu'il soit placé en mémoire.

  • Un programme indépendant de la position ne nécessite pas un chargeur relocalisant car toutes les adresses sont exprimées par rapport à la valeur courante du compteur ordinal (EIP). Il peut ainsi être utilisé avec n'importe quelle combinaison d'autres programmes.

  • Un programme indépendant de la position est donc presque toujours préférable à une programme qui ne l'est pas, même s'il est de 5 à 10% moins rapide.



Comment faire

  • Pour écrire du code indépendant de la position, il faut:

    • a. Éviter les branchements absolus (Ex. jmp 0x1000)
    • b. Référer aux variables au moyen des modes d'adressage indexés qui utilisent un offset par rapport à un registre comme ebp ou esp.
    • c. Utiliser la pile système pour du stockage temporaire (allocation dynamique). On peut par exemple réserver 32 octets dans la pile en soustrayant 32 du pointeur de pile avec l'instruction
  • sub esp, 32

    • On réfère ensuite à cet espace mémoire avec des offsets indexés par rapport à esp ou ebp.


Déterminer l’adresse d’exécution

  • Si nécessaire, on peut toujours déterminer la valeur courante du compteur ordinal au moyen d'une instruction comme :

  • ici: lea eax, ici

  • Le programme peut donc calculer son adresse réelle en mémoire.



Translatabilité et adresses absolues

  • Il existe habituellement des adresses absolues dans une machine, par exemple, celles des vecteurs d ’interruption. On peut accéder à de telles adresses de façon absolue sans nuire à la translatabilité du programme, si elles ne se trouvent pas dans la zone d'implantation du programme.



Download 445 b.

Do'stlaringiz bilan baham:




Ma'lumotlar bazasi mualliflik huquqi bilan himoyalangan ©fayllar.org 2024
ma'muriyatiga murojaat qiling