You are on page 1of 109

Programmation du sol vers le haut

Jonathan Bartlett
Sous la direction de
Dominick Bruno, Jr.
Programmation du sol vers le haut
par Jonathan Bartlett
Edit par Dominick Bruno, Jr.
Copyright 2003 par Jonathan Bartlett
Permission est accorde de copier, distribuer et/ou modifier ce document selon les termes de la
GNU Free
Documentation License, Version 1.1 ou toute version ultrieure publie par la Free Software
Foundation ;
avec sans Sections invariantes, sans texte de premire page de couverture et sans texte de
couverture. Une copie de la
licence est incluse dans l'annexe H. En outre, vous est accorde de plein droit d'utiliser les exemples
de code pour
n'importe quel but sans mme avoir crditer les auteurs.
Toutes les marques sont la proprit de leurs propritaires respectifs.
Ce livre peut tre achet http://www.bartlettpublishing.com/
Ce livre n'est pas un ouvrage de rfrence, c'est un livre d'introduction. Il n'est donc pas adapt par
lui-mme
apprendre comment au programme professionnellement dans x 86 assembly language, comme
certains dtails ont t laisses aux
rendre l'apprentissage plus lisse. Le point du livre est d'aider l'lve comprendre comment
langage d'assemblage et la programmation des travaux, ne pas d'tre une rfrence l'objet
informatique. Rfrence
informations sur un processeur particulier peuvent tre obtenues en communiquant avec la socit
qui le rend.
Pour recevoir un exemplaire de cet ouvrage sous forme lectronique, veuillez visiter le site Web
http://Savannah.nongnu.org/projects/pgubook/ ce site contient les instructions pour tlcharger un
Copie transparente de ce livre, tel que dfini par la licence de Documentation libre GNU.
Table des matires
1. Introduction........................................................................................................1
Welcome to Programming ...............................................................................1
Your Tools........................................................................................................3
2. Computer Architecture .....................................................................................7
Structure de la mmoire de l'ordinateur...7
The CPU...........................................................................................................9
Some Terms ...................................................................................................11
Interpreting Memory......................................................................................13
Data Accessing Methods................................................................................14
Review ...........................................................................................................16
3. Your First Programs........................................................................................19
Entering in the Program.................................................................................19
Esquisse d'un programme de langage d'assemblage...22
Planning the Program.....................................................................................28
Finding a Maximum Value.............................................................................31
Addressing Modes .........................................................................................41
Review ...........................................................................................................45
4. All About Functions.........................................................................................49
Traitant de complexit...49
How Functions Work.....................................................................................50
Fonctions du langage assembleur en utilisant la Convention d'appel C...52
A Function Example......................................................................................59
Recursive Functions.......................................................................................64
Review ...........................................................................................................71
5. Dealing with Files.............................................................................................75
The UNIX File Concept.................................................................................75
Buffers and .bss ...........................................................................................76
Fichiers standards et spciaux...78
Using Files in a Program................................................................................79
III
Review ...........................................................................................................93
6. lecture et d'criture des registres simples...95
Writing Records...........................................................................................100
Reading Records..........................................................................................104
Modifying the Records ................................................................................111
Review .........................................................................................................114
7. dvelopper des programmes robustes...117
Where Does the Time Go?...........................................................................117
Quelques conseils pour l'laboration de programmes robustes...118
Grer efficacement les erreurs...121
Notre programme de fabrication plus robuste...123
Review .........................................................................................................126
8. partage de fonctions avec des bibliothques de Code...129
Using a Shared Library................................................................................130
Comment partage les bibliothques du travail...133
Trouver des informations sur les bibliothques...134
Useful Functions..........................................................................................140
Construction d'une bibliothque partage...141
Review .........................................................................................................143
9. intermdiaire mmoire sujets...147
Comment un ordinateur vue (s) mmoire...147
La disposition de la mmoire d'un programme de Linux...149
Chaque adresse mmoire est un mensonge...151
Getting More Memory.................................................................................155
Un Simple gestionnaire de mmoire...157
Using our Allocator......................................................................................174
More Information.........................................................................................177
Review .........................................................................................................178
IV
10. compter comme un ordinateur...181
Counting.......................................................................................................181
Vrit, mensonge et nombres binaires...186
Le registre d'tat de programme...195
Autres systmes de numrotation...196
Nombre octal et hexadcimal...199
Order of Bytes in a Word.............................................................................201
Conversion de nombres pour l'affichage...204
Review .........................................................................................................210
11. High-Level Languages.................................................................................213
Langages compils et interprts...213
Your First C Program...................................................................................215
Perl...............................................................................................................218
Python..........................................................................................................219
Review .........................................................................................................220
12. Optimization.................................................................................................223
When to Optimize........................................................................................223
Where to Optimize.......................................................................................224
Local Optimizations.....................................................................................225
Global Optimization.....................................................................................229
Review .........................................................................................................230
13. Moving On from Here .................................................................................233
From the Bottom Up....................................................................................234
From the Top Down.....................................................................................234
From the Middle Out ...................................................................................235
Specialized Topics .......................................................................................236
Autres ressources sur le langage d'assemblage...237
v
A. GUI Programming........................................................................................239
B. Common x 86 Instructions...257
C. Important System Calls................................................................................271
D. Table of ASCII Codes ...................................................................................275
E. C idiomes en assembleur...277
F. Using the GDB Debugger..............................................................................289
G. Document History.........................................................................................299
H. licence de Documentation libre GNU...301
I. Personal Dedication........................................................................................311
Index....................................................................................................................313
VI
Chapitre 1. Introduction
Bienvenue la programmation
J'aime la programmation. J'aime le dfi de faire non seulement un programme de travail,
mais de le faire avec style. La programmation est comme la posie. Elle vhicule un message, non
seulement
l'ordinateur, mais ceux qui modifier et utiliser votre programme. Avec un programme,
vous construisez votre propre monde avec vos propres rgles. Vous crez votre monde selon
votre conception de la solution et le problme. Programmeurs magistrales
crer des mondes avec des programmes qui sont trs clairs et concis, comme un pome ou
dans cet essai.
Un des plus grands programmeurs, Donald Knuth, dcrit la programmation pas comme
indiquant un ordinateur Comment faire quelque chose, mais dire une personne comment ils le
feraient
Commandez un ordinateur pour faire quelque chose. Le point est que les programmes sont destins
tre
lu par des gens, pas seulement les ordinateurs. Vos programmes vont tre modifis et mis jour
en d'autres temps aprs que vous passez d'autres projets. Programmation n'est donc pas comme
beaucoup sur la communication et un ordinateur qu'il communique ceux qui
viennent aprs vous. Un programmeur est un rsolveur, un pote et un instructeur tout
une fois. Votre but est de rsoudre le problme la main, faisant avec l'quilibre et le got,
et enseigner votre solution pour les futurs programmeurs. J'espre que ce livre peut enseigner
moins une partie de la posie et la magie qui fait le calcul passionnant.
La plupart des livres Introduction la programmation me frustrent sans fin. la fin de
eux vous pouvez toujours demander comment l'ordinateur vraiment fonctionne? et n'ont pas
une bonne
rponse. Ils ont tendance passer sur les sujets qui sont difficiles, mme s'ils sont
important. Je vous emmnera travers les questions difficiles parce que c'est le seul moyen
pour passer la programmation magistrale. Mon but est de vous emmener de savoir
rien sur la programmation pour comprendre comment penser, crire et apprendre comme un
programmeur. Vous ne saurez pas tout, mais vous aurez un fond pour savoir comment
tout se tient ensemble. la fin de ce livre, vous devriez tre en mesure de faire la
suivant :
1
Chapitre 1. Introduction
Comprendre comment un programme fonctionne et interagit avec d'autres programmes
Lire les programmes d'autrui et apprendre comment ils fonctionnent
Apprendre de nouveaux langages de programmation rapidement
Apprendre les concepts avancs en informatique rapidement
Je ne vais pas vous apprendre tout. L'informatique est un champ massif, surtout
Lorsque vous combinez la thorie avec la pratique de la programmation informatique.
Cependant, je vais essayer de vous aider dmarrer sur les fondations, ainsi vous pouvez facilement
aller
partout o vous voulez par la suite.
Il y a un peu d'un problme de poulets et des ufs dans l'enseignement de la programmation,
en particulier le langage assembleur. Il y a beaucoup apprendre - c'est presque trop de choses
apprendre
presque aussitt, mais chaque pice dpend de tous les autres. Par consquent, vous devez tre
patient avec vous-mme et l'ordinateur tout en apprenant programmer. Si vous n'avez pas
comprendre quelque chose la premire fois, le relire. Si vous ne comprenez toujours pas elle, c'est
parfois mieux de le prendre par la foi et y revenir plus tard. Souvent aprs plusieurs
exposition aux ides de programmation fera plus de sens. Ne vous dcouragez pas.
C'est une longue monte, mais trs utile.
la fin de chaque chapitre sont trois sries d'exercices de rvision. La premire srie est plus
ou moins rgurgitation - ils vrifient pour voir si pouvez vous donner en retour ce que vous avez
appris dans
le chapitre. Le deuxime ensemble contient les questions d'application - ils vrifient pour voir si
vous pouvez appliquer ce que vous avez appris rsoudre des problmes. L'ensemble final est de
voir si vous tes
capable d'largir vos horizons. Certaines de ces questions ne peuvent pas tre
responsable jusqu'au plus tard dans le livre, mais ils vous donnent quelques choses penser.
Autres questions ncessitent des recherches dans des sources externes pour dcouvrir la rponse.
D'autres ncessitent simplement analyser vos options et expliquer une meilleure solution.
Beaucoup de questions n'ont pas les rponses bonnes ou mauvaises, mais cela ne signifie pas
ils sont sans importance. Les questions lies la programmation, apprendre comment
l'apprentissage
la recherche de rponses, et apprendre regarder vers l'avant sont tous une grande partie d'un
travail du programmeur.
Si vous avez des problmes que vous juste ne pouvez pas aller au-del, il y a une liste de diffusion
pour cela
2
Chapitre 1. Introduction
livre o les lecteurs peuvent discuter et obtenir de l'aide avec ce qu'ils lisent. Le
l'adresse est pgubook-readers@nongnu.org. Cette liste de diffusion est ouverte pour tout
type de question ou de discussion dans le sens de ce livre. Vous pouvez vous abonner
Cette liste en vous rendant http://mail.nongnu.org/mailman/listinfo/pgubook-readers.
Vos outils
Ce livre enseigne le langage assembleur pour x 86 processeurs et le GNU/Linux
Systme d'exploitation. C'est pourquoi nous donnerons tous les exemples l'aide de la
Ensemble standard d'outils GCC GNU/Linux. Si vous n'tes pas familier avec GNU/Linux et
le jeu d'outils GCC, elles seront dcrites sous peu. Si vous tes nouveau sur Linux, vous
devrait consulter le guide disponible http://rute.sourceforge.net/ 1 ce que j'ai l'intention
pour vous montrer est plus sur la programmation en gnral que l'utilisation d'un ensemble d'outils
spcifiques
sur une plateforme spcifique, mais la standardisation sur un seul rend la tche beaucoup plus facile.
Ceux nouveaux au Linux devraient aussi essayer de s'impliquer dans leur local de GNU/Linux
Groupe d'utilisateurs. Membres du groupe de l'utilisateur sont gnralement trs utiles pour les
nouvelles personnes, et
vous permettra de tout, de l'installation de Linux apprendre l'utiliser plus
efficacement. Une liste de groupes de l'utilisateur de GNU/Linux est disponible
http://www.Linux.org/groups/
Tous ces programmes ont t tests l'aide de Red Hat Linux 8.0 et devraient fonctionner
avec toutes les autres distributions de GNU/Linux, trop. 2 ils ne fonctionneront pas avec non-Linux
systmes d'exploitation tels que BSD ou d'autres systmes. Cependant, toutes les comptences
apprises
dans ce livre devrait tre facilement transfrable tout autre systme.
Si vous n'avez pas accs une machine GNU/Linux, vous pouvez chercher un hbergement
fournisseur qui propose un compte shell Linux, qui est une seule interface de ligne de commande
1. il s'agit d'un document de grande taille. Vous n'avez pas besoin de savoir tout faire
a commenc avec ce livre. Il faut simplement savoir comment naviguer en ligne de commande
et comment utiliser un diteur comme pico, emacs ou vi (ou autres).
2. par Distribution GNU/Linux , j'entends une distribution de GNU/Linux 86 x. GNU/Linux dis-
contributions pour le Power Macintosh, le processeur Alpha ou autres processeurs ne fonctionnera
pas
avec ce livre.
3
Chapitre 1. Introduction
une machine Linux. Il existe de nombreux fournisseurs de compte de coquille de faible cot, mais
vous
doivent s'assurer qu'ils correspondent aux exigences ci-dessus (c'est--dire - Linux sur x 86).
Quelqu'un groupe votre utilisateur de GNU/Linux local du peut tre en mesure de vous donner un
titre
Eh bien. Comptes Shell exigent seulement que vous avez dj une connexion Internet et
un programme telnet. Si vous utilisez Windows , vous avez dj un client telnet - juste
Cliquez sur Dmarrer, puis excuter, puis tapez telnet. Toutefois, il est gnralement prfrable de
Tlcharger PuTTY de http://www.chiart.greenend.co.uk/~sgtatham/putty/
parce que telnet Windows a des problmes bizarres. Il y a beaucoup d'options pour
Macintosh, trop. NiftyTelnet est mon prfr.
Si vous n'avez pas GNU/Linux et impossible de trouver un service de compte shell, vous pouvez
Tlcharger Knoppix de http://www.knoppix.org/ Knoppix est un systme GNU/Linux
distribution qui dmarre sur CD afin que vous n'avez pas l'installer en fait. Fois
vous tes fait en l'utilisant, vous venez de redmarrez et retirez le CD et vous tes de retour votre
systme d'exploitation ordinaire.
Alors qu'est GNU/Linux ? GNU/Linux est un systme d'exploitation inspir de
UNIX . La partie de GNU vient du projet GNU (http://www.gnu.org/) 3,
qui comprend la plupart des programmes vous allez excuter, y compris l'outil de la GCC qui dfini
Nous utiliserons au programme avec. Le jeu d'outils GCC contient tous les programmes
ncessaire de crer des programmes dans diffrents langages informatiques.
Linux est le nom du noyau. Le noyau est la partie essentielle du systme d'exploitation
qui garde trace de tout. Le noyau est une clture et une porte. Comme une barrire, il
permet aux programmes d'accder aux matriels de manire uniforme. Sans le noyau, vous
faudrait crire des programmes pour faire face chaque modle d'appareil jamais faite. Le
noyau gre toutes les interactions spcifiques au priphrique, donc vous n'avez pas . Il gre
galement
accs aux fichiers et l'interaction entre les processus. Par exemple, lorsque vous tapez, votre
Si vous tapez passe par plusieurs programmes avant il frappe votre diteur. Tout d'abord, le noyau
est
ce qui gre votre matriel, donc c'est le premier recevoir un avis concernant la pression de la
touche.
Le clavier envoie en scancodes l'amande, puis les convertit la
relles lettres, chiffres et symboles qu'ils reprsentent. Si vous utilisez un fentrage
3. le projet GNU est un projet de la Free Software Foundation pour produire un complet,
systme d'exploitation libre.
4
Chapitre 1. Introduction
systme (tels que Microsoft Windows ou le systme X Window), puis le fentrage
systme lit les keypress dans le noyau et le livre quelque programme est
actuellement, en mettant l'accent sur l'cran de l'utilisateur.
Exemple 1-1. Comment les processus de l'ordinateur clavier sigals
Clavier -> noyau -> Windowing system -> Programme d'Application
Le noyau contrle galement la circulation des informations entre divers programmes. Le noyau est
portail du programme sur le monde autour d'elle. Chaque fois que les donnes se dplace entre
processus, le noyau gre la messagerie. Dans notre exemple de clavier ci-dessus, la
noyau devra tre impliqu pour le systme de fentrage communiquer les
KeyPress pour le programme d'application.
Comme une clture, le noyau empche les programmes d'craser accidentellement l'uns
donnes de l'autre et d'accder des fichiers et priphriques qu'ils n'ont pas l'autorisation
. Elle limite le montant des dommages, qu'un programme mal crit peut faire aux autres
programmes en cours.
Dans notre cas, le noyau est Linux. Maintenant, le noyau par elle-mme ne fera rien.
Mme, vous ne pouvez pas dmarrer un ordinateur avec seulement un noyau. Pensez au noyau
comme le
conduites d'eau pour une maison. Sans les tuyaux, les robinets ne fonctionnent pas, mais les tuyaux
sont assez inutile s'il n'y a pas de robinets. Ensemble, les demandes de l'utilisateur (de la
Projet GNU et autres lieux) et le noyau (Linux) composent l'ensemble de la
systme d'exploitation GNU/Linux.
Pour l'essentiel, cet ouvrage utiliseront l'Assemble bas niveau de l'ordinateur
langue. Il existe essentiellement trois types de langues :
Langage machine
Il s'agit de ce que l'ordinateur en fait voit et traite. Chaque commande la
ordinateur voit est administr par un nombre ou une squence de nombres.
5
Chapitre 1. Introduction
Langage d'assemblage
C'est le mme que le langage machine, sauf les numros de commande ont
t remplacs par des squences de lettres qui sont plus faciles mmoriser. Autres petits
choses pour le rendre plus facile ainsi.
Langage de haut niveau
Langages de haut niveau sont l pour faciliter la programmation. Assemble
langue ncessite de travailler avec la machine elle-mme. Langages de haut niveau
vous permettent de dcrire le programme dans un langage plus de naturel. Un seul
commande dans un langage de haut niveau est gnralement quivalente plusieurs commandes
dans un langage d'assemblage.
Dans cet ouvrage, nous allons apprendre langage d'assemblage, bien que nous couvrirons un peu de
langages de haut niveau. J'espre que par l'apprentissage de langage d'assemblage, votre
comprendre comment les travaux de programmation et d'ordinateurs vous mettra une tape
venir.
6
Chapitre 2. Architecture des ordinateurs
Avant d'apprendre programmer, vous devez d'abord comprendre comment un ordinateur
programmes de l'interprte. Vous n'avez pas besoin d'un diplme en gnie lectrique, mais vous
besoin de comprendre certaines bases.
Architecture de l'ordinateur moderne est bas sur une architecture appele le Von
Architecture de Neumann, nomm d'aprs son crateur. L'architecture de Von Neumann
divise l'ordinateur vers le haut en deux parties principales : le CPU (pour centrale de traitement
Unit) et la mmoire. Cette architecture est utilise dans tous les ordinateurs modernes,
y compris les ordinateurs personnels, superordinateurs, mainframes et mme les tlphones
cellulaires.
Structure de la mmoire de l'ordinateur
Pour comprendre comment l'ordinateur considre mmoire, Imaginez votre bureau de poste local.
Ils ont gnralement une pice remplie de botes postales. Ces botes sont semblables aux
mmoire de l'ordinateur que chacune sont des squences numrotes de stockage de taille fixe
emplacements. Par exemple, si vous avez 256 mgaoctets de mmoire de l'ordinateur, qui
signifie que votre ordinateur contienne environ 256 millions stockage de taille fixe
emplacements. Ou, pour reprendre notre analogie, 256 millions de botes postales. Chaque
emplacement a un
nombre et chaque emplacement a la mme taille longueur fixe. La diffrence entre
un mmoire de PO Box et l'ordinateur, c'est que vous pouvez stocker tous les types d'lments
diffrents
dans une bote postale, mais vous pouvez stocker seulement un numro unique dans une mmoire
d'ordinateur
emplacement de stockage.
7
Chapitre 2. Architecture des ordinateurs
Emplacements de mmoire sont comme des botes postales
Vous pouvez vous demander pourquoi un ordinateur est organis de cette faon. C'est parce que
c'est simple
pour mettre en uvre. Si l'ordinateur tait compos de beaucoup de diffrente taille
lieux, ou si vous pouvez stocker diffrents types de donnes en eux, il serait difficile
et coteux mettre en uvre.
Mmoire de l'ordinateur est utilise pour un certain nombre de choses diffrentes. Tous les rsultats
de tous les calculs sont stocks en mmoire. En fait, tout ce qui est stocke est
stockes en mmoire. Pensez votre ordinateur la maison et imaginez ce que tout est stock
la mmoire de votre ordinateur.
L'emplacement de votre curseur sur l'cran
La taille de chaque fentre sur l'cran
La forme de chaque lettre de chaque police utilise
La mise en page de tous les contrles sur chaque fentre
Les graphiques pour toutes les icnes de la barre d'outils
8
Chapitre 2. Architecture des ordinateurs
Le texte pour chaque bote de message et de la bote de dialogue d'erreur
La liste s'allonge encore et...
En plus de tout cela, l'architecture de Von Neumann indique que non seulement
donnes informatiques doivent vivre dans la mmoire, mais les programmes qui contrlent
l'ordinateur
opration devrait vivre l, trop. En effet, dans un ordinateur, il n'y a pas de diffrence
entre un programme et donnes d'un programme sauf sur la manire, il est utilis par l'ordinateur.
Ils sont stocks et accessibles de la mme manire.
Le CPU
Alors, comment fonctionne l'ordinateur ? videmment, le simple stockage de donnes ne fait
beaucoup d'aide - vous devez tre en mesure d'accder, de manipuler et de le dplacer. C'est l
le CPU est disponible en.
Le CPU se lit dans les instructions de la mmoire, l'un la fois et les excute. Ceci
est connu comme le cycle de fetch-execute. Le processeur contient les lments suivants
accomplir ceci :
Compteur de programme
Instruction dcodeur
Bus de donnes
Registres usage gnral
L'unit arithmtique et logique
Le compteur de programme est utilis pour indiquer l'ordinateur o aller chercher le prochain
instruction de. Nous l'avons mentionn plus tt qu'il n'y a pas de diffrence entre la faon dont
programmes et les donnes sont stockes, elles sont juste interprtes diffremment par le CPU. Le
compteur de programme contient l'adresse de mmoire de la prochaine instruction excuter.
Le CPU commence en regardant le compteur de programme et aller chercher quel que soit le
nombre
est stock en mmoire dans l'emplacement spcifi. Il est ensuite transmis l'instruction
9
Chapitre 2. Architecture des ordinateurs
dcodeur qui figure sur ce que l'instruction signifie. Cela comprend quel processus
doit avoir lieu (addition, soustraction, multiplication, dplacement de donnes, etc.) et
Quels emplacements de mmoire vont tre impliqus dans ce processus. Ordinateur
instructions se composent gnralement de l'instruction actuelle et la liste de mmoire
emplacements qui sont utiliss pour s'en acquitter.
Maintenant, l'ordinateur utilise le bus de donnes pour rcuprer les emplacements de mmoire
utiliser dans
le calcul. Le bus de donnes est la connexion entre le CPU et la mmoire. C'est
le rel fil qui les relie. Si vous regardez la carte mre de la
ordinateur, les fils qui sortent de la mmoire sont votre bus de donnes.
En plus de la mmoire l'extrieur du processeur, le processeur lui-mme a
certains emplacements de mmoire spcial, grande vitesse appels registres. Il existe deux types
des registres - registres gnraux et des registres spciaux. Usage gnral
registres sont o se passe l'action principale. Addition, soustraction, multiplication,
comparaisons et autres oprations utilisent gnralement des registres usage gnral pour
traitement. Toutefois, les ordinateurs ont trs peu registres usage gnral. Plupart
sont stockes dans la mmoire principale, prsente les registres pour traitement,
et puis remettre en mmoire lorsque le traitement est termin. spciales
les rpertoires sont des registres qui ont des buts bien prcis. Nous allons discuter de ces derniers
comme
nous arrivons eux.
Maintenant que la CPU a rcupr toutes les donnes ncessaires, il transmet les donnes et
l'instruction dcode l'unit arithmtique et logique pour un traitement ultrieur.
Ici elle s'excute en fait. Aprs que les rsultats du calcul ont
t calculs, les rsultats sont ensuite placs sur le bus de donnes et envoys la
endroit appropri en mmoire ou dans un registre, tel que spcifi par l'instruction.
Il s'agit d'une explication trs simplifie. Processeurs avancent tout fait un peu en
ces dernires annes et sont maintenant beaucoup plus complexe. Bien que le fonctionnement de
base est
toujours la mme, elle est complique par l'utilisation des hirarchies de cache, superscalaire
processeurs, traitement en pipeline, direction de la prvision, l'excution out-of-order, microcode
traduction, coprocesseurs et autres optimisations. Ne vous inquitez pas si vous ne savez pas
ce que ces mots signifient, vous pouvez les utiliser juste comme termes de recherche d'Internet si
vous voulez
10
Chapitre 2. Architecture des ordinateurs
pour en savoir plus sur le CPU.
Certains termes
Mmoire de l'ordinateur est un numro de squence des emplacements de stockage de taille
fixe. Le
nombre attach chaque emplacement de stockage est appel son adresse. La taille d'un seul
emplacement de stockage est appel un octet. Sur x 86 processeurs, un octet est un nombre
compris entre 0
et 255.
Vous mai se demander comment les ordinateurs peuvent afficher et utiliser les textes, graphiques,
et
mme les grands nombres quand tout ce qu'ils peuvent faire est magasin nombres entre 0 et 255.
Tout d'abord, un matriel spcialis comme les cartes graphiques ont des interprtations
particulires des
chaque numro. Lors de l'affichage l'cran, l'ordinateur utilise les tables de codes ASCII
les numros que vous sont envoyer dans des lettres afficher sur l'cran, de la traduction
avec chaque numro de traduire exactement une lettre ou un chiffre. 1 par exemple, la
Lettre majuscule A est reprsent par le numro 65. Le chiffre 1 est reprsent par
le numro 49. Ainsi, pour imprimer HELLO , vous donneriez en fait l'ordinateur
la squence de nombres 72, 69, 76, 76, 79. Pour imprimer le nombre 100, vous
donnerait l'ordinateur la squence des numros 49, 48, 48. Une liste des codes ASCII
personnages et leurs codes numriques se trouve en annexe D.
En plus d'utiliser les nombres pour reprsenter des caractres ASCII, vous comme la
programmeur obtenir faire les numros veux dire ce que vous voulez faire, aussi bien.
Par exemple, si je fais tourner un magasin, je voudrais utiliser un nombre pour reprsenter chaque
lment
Je vendais. Chaque numro serait li une srie d'autres nombres qui
serait les codes ASCII pour ce que je voulais afficher lorsque les articles ont t
balayes dedans. J'aurais plus de numros pour le prix, combien j'ai
l'inventaire et ainsi de suite.
1. avec l'avnement des jeux de caractres internationaux et Unicode, ce n'est pas tout fait vrai
plus. Toutefois, aux fins de garder cela simples pour les dbutants, nous allons utiliser le
prise en charge qu'un seul numro traduit directement un caractre. Pour plus d'informations,
consultez
Annexe D.
11
Chapitre 2. Architecture des ordinateurs
Alors qu'en est-il si nous avons besoin de numros suprieur 255 ? Nous pouvons simplement
utiliser un
combinaison d'octets pour reprsenter un plus grand nombre. Deux octets peut tre utiliss pour
reprsente n'importe quel nombre compris entre 0 et 65536. Quatre octets peut tre utiliss pour
reprsenter
n'importe quel nombre compris entre 0 et 4294967295. Maintenant, il est assez difficile crire
programmes de coller octets ensemble pour augmenter la taille de vos numros et ncessite
un peu de maths. Heureusement, l'ordinateur le fera pour nous pour les nombres jusqu' 4 octets
long. En fait, les numros de quatre octets sont ce que nous allons travailler avec par dfaut.
Nous l'avons mentionn plus tt qu'en plus de la mmoire ordinaire que l'ordinateur a,
Il a galement des emplacements de stockage spciaux appels registres. Registres sont ce qui
l'ordinateur utilise pour le calcul. Pensez un registre comme un endroit sur votre bureau - il
dtient des choses que vous travaillez actuellement. Vous pouvez avoir beaucoup d'informations
Nich dans les tiroirs et les dossiers, mais les trucs que vous travaillez sur ce moment est
sur le bureau. Registres que le contenu des numros qui vous sont actuellement
la manipulation.
Sur les ordinateurs que nous utilisons, les registres sont chacun quatre octets de long. La taille d'un
Registre typique est appel taille de mot de l'ordinateur. x 86 Processeur a quatre octets
Mots. Cela signifie qu'il est plus naturel sur ces ordinateurs pour faire des calculs
quatre octets la fois. Cela nous donne des valeurs peu prs 4 milliards.
Les adresses sont galement quatre octets (1 mot) longs et donc aussi s'adaptent dans un registre.
x 86 processeurs peuvent accder jusqu' 4294967296 octets si assez de mmoire est install.
Notez que cela signifie que nous pouvons stocker des adresses de la mme manire que nous
stockons tout
autre numro. En fait, l'ordinateur ne peut pas faire la diffrence entre une valeur qui est
une adresse, une valeur est un nombre, une valeur qui correspond un code ASCII ou une valeur qui
vous avez dcid d'utiliser d'autres fins. Un certain nombre devient un code ASCII
Lorsque vous essayez d'afficher. Un certain nombre devient une adresse lorsque vous essayez de
Recherchez l'octet qu'il pointe vers. Prenez un moment pour rflchir cela, parce que c'est
essentielle pour comprendre comment les programmes de travail informatique.
Les adresses sont stockes en mmoire sont aussi appels pointeurs, parce qu'au lieu de
ayant une valeur rgulire en eux, ils vous pointent vers un autre emplacement en mmoire.
Comme nous l'avons mentionn, les instructions de l'ordinateur sont galement stockes dans la
mmoire. En fait
12
Chapitre 2. Architecture des ordinateurs
ils sont stocks exactement de la mme manire que les autres donnes sont stockes. La seule
faon le
ordinateur sait qu'un emplacement de mmoire est une instruction qui est une spciale
Registre appel le cours de la flche pointe vers eux un moment ou un autre. Si le
pointeur d'instruction se pointe vers un mot mmoire, il est charg comme une instruction. Autres
que cela, l'ordinateur n'a aucun moyen de connatre la diffrence entre les programmes
et d'autres types de donnes. 2
Interprter de mmoire
Les ordinateurs sont trs prcises. Parce qu'ils sont exacts, les programmeurs doivent tre
tout aussi exacte. Un ordinateur n'a aucune ide ce que votre programme est cens pour faire.
Par consquent, il fera seulement exactement ce que vous dites qu'il fasse. Si vous imprimez
accidentellement
une srie rgulire au lieu des codes ASCII qui composent chiffres du nombre,
l'ordinateur permettra de vous - et vous vous retrouvez avec jibberish sur votre cran (il
va essayer de chercher ce que reprsente votre numro au format ASCII et qu'imprimer). Si vous
dire l'ordinateur pour dmarrer l'excution des instructions un emplacement qui contient les
donnes
au lieu d'instructions de programme, qui sait comment l'ordinateur interprtera qui -
mais il va certainement essayer. L'ordinateur excutera vos instructions dans l'exact
afin de que vous prciser, mme si elle n'est pas sens.
Le point est, l'ordinateur va faire exactement ce que vous dites, peu importe combien peu
sens que rend. C'est pourquoi, en tant que programmeur, vous devez savoir exactement comment
vous
avoir votre mmoire de donnes. N'oubliez pas, les ordinateurs ne peuvent pas stocker
numros, tant lettres, photos, musique, pages web, documents et tout autre sont
juste de longues Suites de nombres dans l'ordinateur, savent quels programmes particuliers
Comment interprter.
Supposons que vous vouliez stocker des informations client en mmoire. Un
faon de le faire serait de dfinir une taille maximale pour le nom et l'adresse du client
-dire 50 caractres ASCII pour chacun, qui serait de 50 octets pour chacune. Puis, aprs
2. Notez qu'ici nous parlons de la thorie gnrale en informatique. Certains processeurs et utili-
systmes de rmu en fait marquent les rgions de mmoire qui peut tre excut avec un spcial
marqueur qui indique ceci.
13
Chapitre 2. Architecture des ordinateurs
qui, avoir un numro pour l'ge du client et leur id de client. Dans ce cas, vous
aurait un bloc de mmoire qui se prsente comme suit :
Dbut de l'enregistrement :
Nom du client (50 octets) - dbut du dossier
Adresse du client (50 octets) - dbut d'enregistrement + 50 octets
Dpart de (1 mot - 4 octets) - ge du client du dossier + 100 octets
Numro d'identification du client (1 mot - 4 octets) - dbut de record + 104 byt
De cette faon, tant donne l'adresse d'un enregistrement de client, vous savez o le reste de la
donnes se trouve. Toutefois, elle ne limite le nom du client et l'adresse seulement 50
ASCII caractres chacun.
Que se passe-t-il si nous ne voulions pas de spcifier une limite ? Une autre faon de procder serait
d'avoir
dans notre Records pointeurs vers ces informations. Par exemple, au lieu du client
nom, nous aurions un pointeur leur nom. Dans ce cas, la mmoire se prsenterait
Comme a:
Dbut de l'enregistrement :
Pointeur de nom du client (1 mot) - dbut du dossier
Pointeur d'adresse du client (1 mot) - dbut d'enregistrement + 4
ge du client (1 mot) - enregistrement de + 8
Numro d'identification du client (1 mot) - dbut d'enregistrement + 12
Le nom et l'adresse seraient stocks ailleurs en mmoire. De cette faon, il est
facile dire o chaque partie des donnes est ds le dbut de l'enregistrement, sans
limitation explicitement la taille du nom et adresse. Si la longueur des champs
au sein de nos dossiers pourrait changer, nous n'aurions aucune ide o le champ suivant
a commenc. Parce que les documents seraient diffrentes tailles, il serait galement difficile
trouver
o a commenc l'enregistrement suivant. Par consquent, presque tous les enregistrements sont de
longueurs fixes.
Donnes de longueur variable est gnralement conserver sparment du reste du dossier.
14
Chapitre 2. Architecture des ordinateurs
Donnes pour accder aux mthodes
Processeurs ont un certain nombre de diffrents modes d'accs aux donnes, connu sous le nom
modes d'adressage. Le mode plus simple est le mode immdiat, dans lequel les donnes
accs est intgr dans l'instruction elle-mme. Par exemple, si nous voulons initialiser une
s'inscrire 0, au lieu de donner l'ordinateur une adresse pour lire la valeur 0, nous
serait spcifier le mode immdiat et lui donner le numro 0.
Dans le mode d'adressage Registre, l'instruction contient un registre d'accs, plutt
qu'un emplacement de mmoire. Le reste des modes traitera des adresses.
Dans le mode d'adressage direct, l'instruction contient l'adresse mmoire
accs. Par exemple, je pourrais dire, veuillez charger ce registre avec les donnes l'adresse
2002. l'ordinateur serait aller directement au nombre d'octets 2002 et copier le contenu
dans notre Registre.
Dans le mode d'adressage index, l'instruction contient une adresse de mmoire
accder et spcifie galement un registre d'index pour compenser cette adresse. Par exemple, nous
pourrait spcifier adresse 2002 ainsi qu'un index Registre. Si le registre d'index contient la
Numro 4, l'adresse relle, les donnes sont charges partir serait 2006. De cette faon, si
vous avez un ensemble de nombres commenant l'emplacement 2002, vous pouvez naviguer entre
les diffrents
l'aide d'un index s'inscrire. Sur x 86 processeurs, vous pouvez galement spcifier un multiplicateur
pour l'index. Cela vous permet d'accder une mmoire un octet un moment ou un mot un
temps (4 octets). Si vous accdez un mot entier, votre index devront tre
multipli par 4 pour obtenir l'emplacement exact du quatrime lment de votre adresse.
Par exemple, si vous voulez accder au quatrime octet d'emplacement 2002, vous
serait charger votre registre d'index avec 3 (n'oubliez pas, nous avons commencer compter 0) et
la valeur
le multiplicateur 1 puisque vous allez un octet la fois. Cela devrait vous aider
emplacement 2005. Toutefois, si vous vouliez accder le quatrime mot d'emplacement
2002, vous chargez votre registre d'index avec 3 et 4 la valeur du multiplicateur. Ceci
chargerait d'emplacement 2014 - le quatrime mot. Prenez le temps de calculer ces
vous-mme pour s'assurer que vous comprenez comment il fonctionne.
Dans le mode d'adressage indirect, l'instruction contient un registre qui contient un
pointeur vers o les donnes doivent tre accdes. Par exemple, si nous utilisions indirecte
15
Chapitre 2. Architecture des ordinateurs
mode d'adressage et spcifi le registre eax et le %EAX Registre confine
la valeur 4, quelle que soit la valeur tait l'emplacement de mmoire 4 serait utilis. En direct
s'adressant, nous aurait il suffit de charger la valeur 4, mais en adressage indirect, nous utilisons 4
comme
l'adresse utiliser pour rechercher les donnes que nous voulons.
Enfin, il y a le mode d'adressage pointeur de base. Ceci est similaire l'indirect
adresse, mais vous galement inclure un nombre appel l'offset ajouter au registre
valeur avant de l'utiliser pour la recherche. Nous utiliserons ce mode un peu dans ce livre.
Nous avons discut de la Section intitule interprtation mmoire ayant une structure
Mmorisation d'informations client. Supposons que nous voulions pour accder la
l'ge du client, qui tait le huitime octet des donnes, et nous avons eu l'adresse de
le dbut de la structure dans un registre. Nous pourrions utiliser l'adressage de pointeur de base et
spcifier le Registre tant que le pointeur de base et 8 comme notre dcalage. C'est un peu comme
indexe s'adressant, avec la diffrence que l'offset est constant et que le pointeur est
qui s'est tenue dans un registre et en abordant indexe, l'offset est dans un registre et la
pointeur est constante.
Il existe d'autres formes d'adressage, mais ceux-ci sont les plus importants.
Examen
Connatre les Concepts
Dcrire le cycle de fetch-execute.
Ce qui est un registre ? Comment calcul serait plus difficile sans registres ?
Comment reprsentez-vous les nombres suprieurs 255 ?
Quelle taille sont les registres sur les machines que nous allons utiliser ?
Comment un ordinateur sait comment interprter un octet donn ou un ensemble d'octets de
mmoire ?
16
Chapitre 2. Architecture des ordinateurs
Quels sont les modes d'adressage et quels sont ils utiliss pour ?
Que fait-il le pointeur d'instruction ?
Utiliser les Concepts
Quelles donnes vous utiliseriez dans un enregistrement d'employ ? Comment vous poserait dans
mmoire ?
Si j'avais le pointeur au dbut de l'employ record au-dessus et je voulais
pour accder un lment particulier de donnes l'intrieur, quel mode d'adressage serait j'ai
utiliser ?
En pointeur de base traitant de mode, si vous avez un registre contenant la valeur 3122,
et un dcalage de 20, quelle adresse serait vous tentez d'accder ?
En mode d'adressage index, si l'adresse de base est 6512, le registre d'index a un
5 et le coefficient multiplicateur est de 4, quelle adresse serait vous tentez d'accder ?
En mode d'adressage index, si l'adresse de base est 123472, le registre d'index
a un 0 et le coefficient multiplicateur est de 4, quelle adresse serait vous tentez d'accder ?
En mode d'adressage index, si l'adresse de base est 9123478, le registre d'index
a 20 et le coefficient multiplicateur est de 1, quelle adresse serait vous tentez d'accder ?
Aller plus loin
Quels sont le nombre minimal de modes d'adressage ncessaires pour le calcul ?
Pourquoi inclure traitant des modes qui ne sont pas strictement ncessaires ?
Recherche et ensuite dcrire comment pipeline (ou l'un de l'autre compliquer
facteurs) affecte le cycle de fetch-execute.
17
Chapitre 2. Architecture des ordinateurs
Recherche et ensuite dcrire les compromis entre les instructions de longueur fixe et
instructions de longueur variable.
18
Chapitre 3. Vos premiers programmes
Dans ce chapitre, vous apprendrez le processus d'criture et de construction de Linux
programmes de langage assembleur. En outre, vous apprendrez la structure de
programmes de langage d'assemblage et quelques commandes de langage assembleur. Comme
vous allez
Grce ce chapitre, vous pouvez voir aussi annexe B et l'annexe F.
Ces programmes peuvent vous submerger dans un premier temps. Cependant, passer par eux avec
diligence, lire, eux et leurs explications autant de fois que ncessaire et vous
auront des connaissances construire des bases solides. S'il vous plat bricoler autour avec
les programmes autant que vous le pouvez. Mme si votre bricolage ne fonctionne pas, chaque
chec vous aidera apprendre.
Entrant dans le programme
Bon, ce premier programme est simple. En fait, il ne va pas faire autre chose que de sortir !
Il est court, mais il montre quelques bases sur le langage assembleur et Linux
de programmation. Vous devez entrer le programme dans un diteur exactement comme crit, avec
le nom de fichier exit.s. Le programme suit. Ne vous inquitez ne pas comprendre
il. Cette section ne traite qu'il en tapant et en l'excutant. Dans la Section intitule
Esquisse d'un programme de langage d'assemblage, nous allons dcrire comment cela fonctionne.
#PURPOSE : Programme simple qui quitte et retourne un
code d'tat # retour au noyau Linux
#
#INPUT : aucun
#
#OUTPUT : retourne un code d'tat. Ceci peut tre vu
# en tapant
#
# echo $?
#
19
Chapitre 3. Vos premiers programmes
# Aprs avoir excut le programme
#
#VARIABLES :
# %EAX conserve le numro d'appel systme
# % ebx dtient le statut de retour
#
.data .section
.section .text
.Globl _start
_start :
movl $1, %EAX # il s'agit de la commande du noyau linux
nombre de # (appel systme) pour quitter le
# un programme
movl $0, ebx % # c'est le numro d'tat nous allons
# retour au systme d'exploitation.
# Changer ce autour et il sera
# renvoyer des choses diffrentes
# echo $?
int 0 x 80 $ # cela rveille le noyau pour excuter
# la commande exit
On appelle ce que vous avez tap dans le code source. Le code source est le
forme lisible d'un programme. Afin de le transformer en un programme qui a
ordinateur peut excuter, nous avons besoin d'assembler et de lier.
La premire tape consiste assembler. Montage est le processus qui transforme ce que vous
tap dans les instructions pour la machine. La machine elle-mme ne lit que des ensembles de
les nombres, mais les humains prfrent les mots. Un langage d'assemblage est un plus
forme lisible des instructions que comprend un ordinateur. Assemblage
20
Chapitre 3. Vos premiers programmes
transforme le fichier lisible en un lisible par une machine. l'Assemble le
type de programme la commande
comme exit.s -o exit.o
comme c'est la commande qui excute l'assembleur, exit.s est le fichier source et o-
Exit.o raconte l'assemble de mettre sa sortie dans le fichier exit.o. Exit.o est un
fichier de l'objet. Un fichier objet est le code qui est dans la langue de la machine, mais n'a pas
t compltement mis en place. Dans la plupart des grands programmes, vous disposez de plusieurs
fichiers source et vous permet de convertir chacun dans un fichier objet. L'diteur de liens est la
programme qui est charg de rassembler les fichiers objets et en ajoutant
informations pour elle afin que le noyau sait comment charger et excutez-le. Dans notre cas, nous
avoir un fichier objet, donc l'diteur de liens ajoute uniquement les informations pour lui permettre
de
pour excuter. Pour lier le fichier, entrez la commande
LD exit.o -o sortie
LD est la commande excuter l'diteur de liens, exit.o est le fichier objet, nous voulons crer un
lien, et
o - sortie indique l'diteur de liens pour le nouveau programme de sortie dans un fichier appel
sortie. 1 si
une de ces commandes a signal des erreurs, vous avez fait non plus de votre programme ou
la commande. Aprs avoir corrig le programme, vous devez r-excuter toutes les commandes.
Vous devez toujours r-assembler et rajouter un lien vers des programmes aprs avoir modifi le
fichier source
pour que les modifications se produisent dans le programme. Vous pouvez excuter sortie en tapant
dans le
commande
. / sortie
Le. / sert indiquer l'ordinateur que le programme n'est pas dans l'un de la normale
programmer des rpertoires, mais correspond au rpertoire actif la place de 2. Vous remarquerez
que lorsque vous
tapez cette commande, la seule chose qui se passe, c'est que vous irez la ligne suivante.
1. Si vous tes nouveau sur Linux et UNIX , vous ne peut-tre pas au courant que les fichiers ne
doivent
ont des extensions. En effet, alors que Windows utilise l'extension .exe pour signifier un excutable
programme, fichiers excutables UNIX n'ont habituellement aucune extension.
2.. dsigne le rpertoire courant dans les systmes Linux et UNIX.
21
Chapitre 3. Vos premiers programmes
C'est parce que ce programme ne fait que la sortie. Cependant, immdiatement aprs
vous excutez le programme, si vous tapez dans
echo $?
Il va dire 0. Ce qui se passe, c'est que chaque programme lorsqu'il se termine donne Linux un
sortie code d'tat, qui lui demande si tout s'est bien pass. Si tout allait bien,
elle retourne 0. Les logiciels UNIX retournent des nombres autres que zro pour indiquer l'chec ou
autres erreurs, avertissements ou statuts. Le programmeur dtermine quel numro de chaque
moyens. Vous pouvez afficher ce code en tapant dans echo $?. Par la suite de l'article nous
se penchera sur ce que fait chaque partie du code.
Esquisse d'un programme de langage d'assemblage
Jetez un oeil au programme que nous vient d'entrer. Au dbut, il y a beaucoup de lignes
qui commencent avec des hachages (#). Voici les commentaires. Commentaires ne sont pas traduits
par
l'assembleur. Ils sont utiliss uniquement pour le programmeur de parler quelqu'un qui a l'air
le code l'avenir. La plupart des programmes que vous crivez seront modifies par
d'autres. Tlcharger
l'habitude d'crire des commentaires dans votre code qui les aideront comprendre
Pourquoi le programme existe tant son fonctionnement. Toujours inclure ce qui suit en
vos commentaires :
Le but du code
Un aperu du traitement impliqu
Quelque chose trange votre programme fait et pourquoi il le fait 3
Aprs les commentaires, la ligne suivante dit
3. vous trouverez que les nombreux programmes finissent par faire des choses tranges
faons. Habituellement il y a une rea-
fils pour a, mais, malheureusement, programmeurs jamais document ces choses dans leurs
commentaires.
Donc, les futurs programmeurs doivent soit en savoir la raison pour laquelle la dure en modifiant le
code
et le regarder pause, ou juste laisser seul s'il est toujours ncessaire ou non. Vous devriez
toujours documenter toute votre programme effectue un comportement
trange. Malheureusement, savoir
ce qui est trange, et ce qui est simple vient surtout avec l'exprience.
22
Chapitre 3. Vos premiers programmes
.data .section
Quoi que ce soit en commenant par une priode n'est pas traduit directement dans une instruction
machine.
Au lieu de cela, c'est une instruction l'assembleur lui-mme. Ce qu'on appelle assembleur
directives ou pseudo-oprations parce qu'elles sont manipules par l'assembleur et sont
pas en fait dirig par l'ordinateur. La commande .section brise votre programme
vers le haut en sections. Cette commande lance la section donnes, lorsque vous numrez toute
mmoire
stockage, vous aurez besoin pour les donnes. Notre programme n'utilise pas tout, donc il ne faut
pas la
section. C'est juste ici par souci d'exhaustivit. Presque chaque programme que vous crivez dans le
avenir aura donnes.
Juste aprs ce que vous avez
.section .text
qui commence la section de texte. La section de texte d'un programme est l'endroit o le
programme
instructions en direct.
L'instruction suivante est
.Globl _start
Cela indique l'assembleur que _start est important de se rappeler. _start est un
symbole, qui signifie qu'il va tre remplac par autre chose non plus
au cours de l'Assemble ou de liaison. Symboles sont gnralement utiliss pour marquer les
emplacements des
programmes ou donnes, donc vous pouvez faire rfrence leur nom au lieu de par leur situation
numro. Imaginez si vous deviez faire rfrence chaque emplacement de mmoire par son
adresse. Premire
d'abord, il serait trs droutant parce que vous devez mmoriser ou chercher
l'adresse de mmoire numrique de chaque morceau de code ou de donnes. En outre, chaque
temps vous deviez insrer un morceau de donnes ou de code, vous devez changer toutes les
adresses dans votre programme ! Les symboles sont utiliss afin que l'assembleur et l'diteur de
liens peut
prendre soin de garder la trace des adresses, et vous pouvez vous concentrer sur l'criture de votre
programme.
23
Chapitre 3. Vos premiers programmes
.Globl signifie que l'assembleur ne devrait pas jeter ce symbole aprs assemblage,
parce que l'diteur de liens en aurez besoin. _start est un symbole spcial qui doit toujours tre
marqu avec .globl car elle marque l'emplacement de dbut du programme.
Sans marquer cet endroit de cette manire, lorsque l'ordinateur charge votre programme
il ne saura pas o commencer votre programme en cours d'excution.
La ligne suivante
_start :
dfinit la valeur de l'tiquette _start. Une tiquette est un symbole suivi d'un deux-points.
tiquettes dfinissent valeur d'un symbole. Lorsque l'assembleur est assembler le programme, il
a assigner chaque valeur de donnes et l'instruction d'adresse. tiquettes dire l'assembleur
pour faire valeur du symbole tre partout o l'lment de donnes ou d'instructions suivant sera
tre. De cette faon, si l'emplacement physique rel des donnes ou d'instructions change, vous
n'ai pas de rcrire toutes les rfrences lui - le symbole obtient automatiquement le nouveau
valeur.
Maintenant, nous entrons dans les instructions de l'ordinateur. Le premier, cet enseignement est la
suivante :
movl $1, % eax
Lorsque le programme s'excute, cette instruction transfre le numro 1 dans le _eax
s'inscrire. En langage assembleur, beaucoup d'instructions ont des oprandes. movl a deux
oprandes - la source et la destination. Dans ce cas, la source est le littral
Numro 1 et la destination est le registre eax. Les oprandes peuvent tre des nombres,
rfrences d'emplacement de mmoire ou registres. Diffrentes instructions permettent diffrentes
types d'oprandes. Voir l'annexe B pour plus d'informations sur quelles instructions
prendre quels types d'oprandes.
Sur la plupart des instructions qui ont deux oprandes, le premier est l'oprande source
et le second est la destination. Notez que dans ces cas, l'oprande source
n'est pas modifi du tout. Autres instructions de ce type sont, par exemple, plus deux autres, subl,
et imull. Ces ajouter/soustraire/multiplier la source oprande de//par la
oprande de destination et puis enregistrez le rsultat dans l'oprande de destination. Autres
24
Chapitre 3. Vos premiers programmes
instructions peut avoir un oprande cod en dur po idivl%%, par exemple, exige que
le dividende tre dans %EAX, % edx tre gal zro et le quotient est alors transfr
% eax et le reste % edx. Toutefois, le diviseur peut tre n'importe quel Registre ou
emplacement de la mmoire.
Sur x 86 processeurs, il existe plusieurs registres usage gnral 4 (tous qui peut
servir avec movl) :
% eax
% ebx
% ecx
% edx
% edi
% esi
Outre ces registres usage gnral, il existe aussi plusieurs
registres spciaux, y compris :
% ebp
% esp
% eip
% eflags
Nous allons discuter plus tard, sachez qu'ils existent. 5. certains de ces registres,
4. note que sur processeurs x 86, mme les registres usage gnral ont certains pur spcial-
pose, ou utilis pour avant que a s'est pass de 32 bits. Cependant, ce sont des registres usage
gnral pour
la plupart des instructions. Chacun d'eux possde au moins une instruction o il est utilis d'une
manire spciale.
Toutefois, pour la plupart, ces instructions ne sont pas couverts dans ce livre.
5. vous demandez peut-tre, pourquoi est-ce tous ces registres commencent par la lettre e ? La
raison
est que les premires gnrations de processeurs x 86 taient 16 bits au lieu de 32 bits. Par
consquent, la
registres taient seulement la moiti de la longueur qu'ils sont maintenant. Dans les gnrations
suivantes de processeurs x 86, le
les registres doubl. Ils ont gard les anciens noms pour dsigner la premire moiti du Registre,
25
Chapitre 3. Vos premiers programmes
comme % eflags eip et % sont accessibles uniquement par le biais des instructions spciales. Le
d'autres sont accessibles en utilisant les mmes instructions que les registres usage gnral,
mais ils ont des significations particulires, certains usages particuliers ou sont tout simplement plus
vite lorsqu'il est utilis dans un
manire spcifique.
Ainsi, l'instruction movl entame le nombre 1 % eax. Le signe dollar en face
de celui indique que nous voulons utiliser l'adressage mode immdiat (renvoyer au
la Section intitule mthodes pour accder aux donnes dans le chapitre 2). Sans le signe dollar
il ferait direct s'adressant, quel que soit le nombre est l'adresse 1 de chargement. Nous voulons
le nombre rel 1 charge en, donc il faut utiliser le mode immdiat.
La raison pour laquelle que nous nous dirigeons le numro 1 dans %eax est parce que nous nous
apprtons
appelez le noyau Linux. Le numro 1 est le numro de l'appel systme de sortie. Nous
discutera des appels systme plus en dtail bientt, mais ils sont fondamentalement des demandes
de
aide du systme d'exploitation. Programmes normaux ne peuvent pas tout faire. Nombreux
spcifiquede l'appel des autres programmes, traitant des fichiers et quitter la dois
tre traites par le systme d'exploitation travers des appels systme. Lorsque vous effectuez une
l'appel systme, ce que nous ferons peu de temps, le numro d'appel systme doit tre charg dans
% eax (pour une liste complte des appels systme et de leurs numros, voir l'annexe C).
Selon l'appel systme, les autres registres devrez ont des valeurs en eux comme
Eh bien. Notez que les appels systme n'est pas la seule utilisation ou mme l'utilisation principale
des registres. Il
est le seul dont nous traitons dans ce premier programme. Programmes plus tard utilisera
registres de calcul ordinaire.
Le systme d'exploitation, cependant, a gnralement besoin d'informations plus que juste qui
appel faire. Par exemple, lorsqu'il s'agit des fichiers, le systme d'exploitation doit
savoir quel fichier vous traitez, quelles donnes vous souhaitez crire et d'autres
Dtails. Les dtails supplmentaires, appeles paramtres sont stocks dans les autres
registres. Dans le
cas de l'appel systme de sortie, le systme d'exploitation ncessite un code d'tat charg
et ajout un e pour dsigner les versions tendues du Registre. Gnralement, vous allez utiliser
uniquement le
versions tendues. Les modles plus rcents offrent galement un mode 64-bit, ce qui double la
taille de ces
enregistre encore une fois et utilise un prfixe r pour indiquer les plus grands registres (c'est--dire
% rax est le 64 bits
version de %EAX). Toutefois, ces processeurs ne sont pas largement utiliss et ne sont pas couverts
dans ce
livre.
26
Chapitre 3. Vos premiers programmes
dans ebx %. Cette valeur est ensuite retourne au systme. C'est la valeur que vous avez rcupr
Lorsque vous avez tap echo $?. Ainsi, nous chargeons ebx % avec 0 en tapant ce qui suit :
movl $0, % ebx
Maintenant, registres de chargement avec ces numros ne fait rien lui-mme. Registres sont
utilis pour toutes sortes de choses en plus des appels systme. Ils sont o tous les programme
logique
telles que l'addition, soustraction et les comparaisons ont lieu. Linux ncessite simplement
que certains registres charge avec certaines valeurs de paramtre avant de programmer un
appel systme. %EAX est toujours requise doit tre charg avec le numro d'appel systme. Pour
les autres registres, cependant, chaque appel systme a des besoins diffrents. Dans le
sortie appel systme, ebx % est ncessaire pour tre charg avec l'tat de sortie. Nous allons
discuter des appels systme diffrent car ils sont ncessaires. Pour une liste du rgime commun
appels et ce qui est ncessaire pour tre dans chaque registre, voir l'annexe C
L'instruction suivante est celle magique . Il ressemble ceci :
int 0 x 80 $
L'int est synonyme de l'interruption. Le 0 x 80 est le numro d'interruption utiliser. 6 une
interruption interrompt le flux du programme normal, et transfre le contrle de nos
programme pour Linux donc qu'il va faire un appel systme. 7. Vous pouvez considrer comme
signalisation Batman (ou bolzec 8, si vous prfrez). Vous avez besoin de quelque chose, vous
Envoyer le signal, et puis il vient la rescousse. Vous ne souciez pas comment il fait son
travail - c'est plus ou moins magique - et quand il est fait, vous tes en contrle. Dans le prsent
cas, tout ce que nous faisons est demandant Linux pour terminer le programme, auquel cas nous
6. vous demandez peut-tre pourquoi c'est 0 x 80 au lieu de seulement 80. La raison est que le
nombre
est crit en hexadcimal. En hexadcimal, un chiffre unique peut contenir 16 valeurs au lieu de la
10 normal. Ceci est fait en utilisant les lettres a f, outre les chiffres rguliers.
a reprsente 10, b reprsente 11 et ainsi de suite. 0 x 10 reprsente le nombre 16 et ainsi de
suite. Ceci
nous le verrons plus en dtail plus tard, mais sachez que les numros commenant par 0 x sont en
hexadcimal. Clouant sur un H la fin est galement parfois utilis au lieu de cela, mais nous ne
que, dans cet ouvrage. Pour plus d'informations ce sujet, consultez le chapitre 10
7. en fait, l'interruption transfre le contrle celui mis en place un gestionnaire d'interruption pour
la
Numro d'interruption. Dans le cas de Linux, chacun d'eux sont dfinies pour tre gres par le
noyau Linux.
8. Si vous n'observez pas Veggie Tales, vous devriez. Dmarrer avec Dave et le cornichon gant.
27
Chapitre 3. Vos premiers programmes
ne sera pas en contrle. Si nous ne signale pas l'interruption, puis n'appelez aucun systme
serait ont t effectues.
Examen d'appel rapide systme : Pour rsumer - la sont des fonctionnalits du systme
d'exploitation
accessible via les appels systme. Ceux-ci sont appels en mettant en place le
registres d'une manire spciale et mettre l'instruction int $ 0 x 80. Linux
sait quel systme appel nous voulons accder par ce que nous avons stock dans le
Registre de _eax. Chaque appel systme a d'autres exigences quant ce qu'il faut
tre stocks dans les autres registres. Numro d'appel systme 1 est le systme de sortie
appelez, qui ncessite le code d'tat pour tre plac dans % ebx.
Maintenant que vous avez assembl, lie, excuter et examin le programme, vous devriez
faire quelques modifications de base. Des choses comme changer le nombre qui est charg dans %
ebx,
et regardez-le de sortir la fin avec echo $?. N'oubliez pas d'assembler et de lier
Il a encore une fois avant de l'excuter. Ajouter quelques commentaires. Ne vous inquitez pas, la
pire chose qui
arriverait est que le programme ne sera pas assembler un lien ou glera votre
cran. C'est juste une partie de l'apprentissage !
Le programme de planification
Dans notre prochain programme, nous allons essayer de trouver le maximum d'une liste de
nombres.
Les ordinateurs sont trs minutieux, donc pour crire le programme que nous aurons
aurait planifi un certain nombre de dtails. Ces dtails incluent :
O seront la liste originale des nombres stocks ?
Quelle est la dmarche va nous devons suivre pour trouver le nombre maximal ?
Quel espace de stockage avons-nous besoin d'effectuer cette procdure ?
Seront tous le stockage dans les registres, ou avons-nous besoin d'utiliser une mmoire comme
Eh bien ?
28
Chapitre 3. Vos premiers programmes
Si vous ne pensez pas que quelque chose aussi simple que de trouver le nombre maximum
dans la liste prendrait beaucoup de planification. Vous pouvez dire habituellement les gens trouver
la
nombre maximal et ils peuvent faire avec peu d'ennui. Cependant, nos esprits sont
utilis pour assembler automatiquement des tches complexes. Ordinateurs doivent tre
charg par le processus. En outre, nous pouvons habituellement tenir n'importe quel nombre de
choses dans notre esprit sans beaucoup de peine. Nous avons habituellement ne ralisent mme pas
que nous sommes
le faire. Par exemple, si vous numrisez une liste de nombres pour le maximum, vous ne
probablement garder l'esprit les deux le plus grand nombre que vous avez vu jusqu'ici et o vous
figurent dans la liste. Alors que votre esprit fait automatiquement, avec les ordinateurs, vous avez
pour dfinir explicitement une capacit de stockage pour la tenue de la position actuelle sur la liste
et la
nombre maximal actuel. Vous avez aussi d'autres problmes tels que comment savoir
quand s'arrter. Lorsque vous lisez un morceau de papier, vous pouvez arrter lors de l'excution de
numros. Toutefois, l'ordinateur contient uniquement les chiffres, donc il n'a aucune ide quand il
a atteint le dernier de vos numros.
Dans les ordinateurs, vous devez planifier chaque tape de la voie. Donc, nous allons faire un peu de
planification.
Tout d'abord, juste pour la rfrence, nommons l'adresse o la liste des numros
commence comme data_items. Disons que le dernier numro de la liste sera donc un zro,
Nous savons o s'arrter. Nous avons galement besoin d'une valeur de tenir la position actuelle
dans le
liste, une valeur de tenir l'lment actuel de la liste en cours d'examen et le courant
valeur la plus leve sur la liste. Nous allons affecter chacun d'entre eux un registre :
% edi occupera le poste actuel dans la liste.
% ebx maintient la valeur la plus leve actuellement dans la liste.
%EAX tiendra l'lment actuel en cours d'examen.
Quand nous commenons le programme et regardez le premier lment dans la liste, puisque nous
n'avons pas
vu tout autre lment que le point sera automatiquement tre l'lment le plus important courant
en
la liste. Aussi, nous allons dfinir la position actuelle dans la liste zro - la premire
lment. A partir de l, nous allons suivre les tapes suivantes :
29
Chapitre 3. Vos premiers programmes
1. vrifier si l'lment de liste actuel (%EAX) pour voir si c'est zro (la rsiliation
lment).
2. si elle est nulle, la sortie.
3. augmenter la position actuelle (% edi).
4. charger la valeur suivante dans la liste dans le registre de valeur actuelle (%EAX). Ce qui
mode d'adressage pourrions-nous utiliser ici ? Pourquoi ?
5. Comparez la valeur actuelle (%EAX) avec la valeur la plus leve courante (ebx %).
6. Si la valeur actuelle est suprieure la valeur la plus leve actuellement, remplacer le
valeur actuelle la plus leve avec la valeur actuelle.
7. rpter les tapes.
C'est la procdure. Plusieurs fois dans ce procdure, j'ai fait usage de la mention si .
Ces lieux sont o les dcisions doivent tre effectus. Vous voyez, l'ordinateur ne
suivre la squence exacte mme des instructions chaque fois. Selon laquelle
Si s sont corrects, l'ordinateur peut suivre un ensemble diffrent d'instructions. Le
deuxime fois, il n'aurait pas la valeur la plus leve. Dans ce cas, il va sauter
tape 6, mais revenir l'tape 7. Dans tous les cas sauf le dernier, il n'effectue pas
2. dans des programmes plus complexes, les sauter augmente considrablement.
Ces si s sont une classe d'instructions appel flux des instructions de contrle, parce qu'ils
dire le calcul quelles tapes suivre et les chemins prendre. Lors de la prcdente
programme, nous n'avions pas des instructions de contrle de flux, comme il n'y n'avait qu'un seul
chemin possible prendre - sortie. Ce programme est beaucoup plus dynamique qu'elle est
ralis par les donnes. Selon les donnes qu'il reoit, il suivra diffrents
chemins de l'instruction.
Dans ce programme, cet objectif sera ralis par deux instructions diffrentes, la
saut conditionnel et le saut inconditionnel. Le saut conditionnel change de chemins
selon les rsultats d'une comparaison prcdente ou le calcul. L'inconditionnel
saut va juste directement un chemin diffrent n'importe quoi. Le saut inconditionnel
peut sembler inutile, mais il est trs ncessaire, tant donn que toutes les instructions seront
poses
30
Chapitre 3. Vos premiers programmes
sur une ligne. Si un chemin d'accs doit converger vers le chemin principal, il devra faire
Ceci par un saut inconditionnel. Nous verrons plus de deux de ces sauts dans le prochain
section.
Une autre utilisation du contrle de flux est mise en uvre des boucles. Une boucle est un morceau
de programme
code qui est cens tre rpt. Dans notre exemple, la premire partie du programme
(affectant 0 la position actuelle et le chargement de la plus haute valeur actuelle avec la
valeur actuelle) a t fait seulement une fois, donc il n'tait pas une boucle. Toutefois, la partie
suivante est
rpt maintes et maintes fois pour chaque numro dans la liste. Il reste seulement quand nous
sont venus jusqu'au dernier lment, indiqu par un zro. Cela s'appelle une boucle car il
se produit encore et encore. Il est mis en uvre en faisant des sauts inconditionnels la
dbut de la boucle l'extrmit de la boucle, ce qui oblige recommencer. Toutefois,
Il faut toujours se rappeler d'avoir un saut conditionnel pour quitter la boucle
quelque part, ou la boucle continuera pour toujours ! Cette condition est appele un infini
boucle. Si nous avons quitt accidentellement l'tape 1, 2 ou 3, la boucle (et notre programme)
serait
jamais de fin.
Dans la section suivante, nous mettrons en oeuvre ce programme que nous avons prvu.
Sons de planification de programme compliqu - et c'est, dans une certaine mesure. Lorsque vous
premier
commencer la programmation, il est souvent difficile de convertir notre normal pens le processus
en une
procdure que l'ordinateur peut comprendre. On oublie souvent le nombre de
emplacement de stockage temporaire que nos esprits sont utilise pour traiter les
problmes. Comme
vous lire et d'crivez des programmes, cependant, cela finira par devenir trs naturel de
vous. Juste avoir de la patience.
Trouver une valeur maximale
Entrez le programme suivant comme maximum.s :
#PURPOSE : Ce programme trouve le nombre maximal d'un
# set d'lments de donnes.
#
31
Chapitre 3. Vos premiers programmes
#VARIABLES : Les registres ont des utilisations suivantes :
#
# % edi - contient l'index de l'lment de donnes en cours d'examen
# % ebx - donnes plus grands lment trouvs
# % eax - lment de donnes actuel
#
# Les emplacements de mmoire suivants sont utiliss :
#
# data_items - contient les donnes d'lment. Un 0 est utilis
# pour mettre fin des donnes
#
.data .section
data_items : #These sont les lments de donnes
.long 3,67,34,222,45,75,54,34,44,33,22,11,66,0
.section .text
.Globl _start
_start :
movl $0, % edi # dplacer 0 dans le registre d'index
movl data_items(,%edi,4), charge de # % eax le premier octet de donnes
movl % eax, ebx % # puisque c'est le premier lment, %eax est
# le plus grand
start_loop: # dmarrer la boucle
CMPL $0, % eax # vrifier pour voir si nous avons touch la fin
Je loop_exit
valeur suivante % charge edi incl #
movl data_items(,%edi,4), eax %
CMPL % ebx, eax de % # compare values
jle start_loop # saut au dbut de la boucle si le nouveau
# one n'est pas plus grand
movl % eax, dmnagement de # ebx % la valeur comme le plus grand
32
Chapitre 3. Vos premiers programmes
JMP start_loop # saut au dbut de la boucle
loop_exit :
# % ebx est le code d'tat pour l'appel systme de sortie
# et possde dj le nombre maximal
movl $1, %EAX #1 est le syscall exit()
int 0 x 80 $
Maintenant, assemblez et liez-le avec ces commandes :
comme maximum.s -o maximum.o
LD maximum.o -o maximum
Maintenant excuter et vrifier son statut.
. / maximum
echo $?
Vous remarquerez, qu'elle retourne la valeur de 222. Nous allons jeter un coup d'oeil au programme
et ce qu'il
le fait. Si vous regardez dans les commentaires, vous verrez que le programme trouve le maximum
d'un ensemble de nombres (ne sont pas commentaires merveilleux!). Vous pouvez galement
remarquer que dans ce
programme nous avons rellement quelque chose dans la section donnes. Ces lignes sont les
donnes
section :
data_items : #These sont les lments de donnes
.long 3,67,34,222,45,75,54,34,44,33,22,11,66,0
Permet de regarder cela. data_items est un label qui correspond l'emplacement qui le suit.
Puis, il y a une directive qui commence par .long. Qui provoque l'assembleur
rserver de la mmoire pour la liste des numros qui suivent. data_items se rfre la
emplacement de la premire. Parce que data_items est un label, un moment de notre programme
l o il faut se rfrer cette adresse, nous pouvons utiliser le symbole de la data_items, et
l'assembleur il substituera avec l'adresse o les numros commencent au cours de
Assemble. Par exemple, l'instruction movl data_items, %EAX dplacerait
33
Chapitre 3. Vos premiers programmes
la valeur 3 dans %EAX. Il y a plusieurs types de mmoires autres
que .long qui peuvent tre rservs. Les principales sont les suivantes :
.Byte
Octets occupent un emplacement de stockage pour chaque numro. Ils se limitent
nombres entre 0 et 255.
.int
Ints (qui diffrent de l'instruction int) occupent deux emplacements de stockage pour
chaque numro. Voici les capacits de nombres compris entre 0 et 65535. 9
.long
Longs reprennent les quatre emplacements de stockage. Il s'agit de la mme quantit d'espace la
enregistre l'utilisation, c'est pourquoi ils sont utiliss dans ce programme. Ils peuvent tenir
nombres entre 0 et 4294967295.
.ASCII
La directive .ascii est entrer dans les caractres dans la mmoire. Caractres chacune
occuper un emplacement de stockage (ils sont convertis en octets en interne). Donc, si
vous avez donn la directive .ascii Bonjour there\0 , serait de l'assembleur
rserver 12 emplacements de stockage (en octets). Le premier octet contient le code numrique
pour H, le deuxime octet contient le code numrique pour e et ainsi de suite. Le dernier
caractre est reprsent par \0, et c'est le caractre de fin (il sera
jamais affichage, il indique juste ailleurs dans le programme qu'il s'agit de la fin de la
caractres). Lettres et chiffres qui commencent par une barre oblique inverse reprsentent
les caractres qui ne sont pas typables sur le clavier ou facilement visible sur la
cran. Par exemple, \n fait rfrence au caractre nouvelle ligne qui provoque la
9. Notez qu'aucun numro en langage assembleur (ou tout autre langage informatique que j'ai vu)
des virgules ont intgr en eux. Donc, toujours crire des nombres comme 65535 et jamais comme
65 535.
34
Chapitre 3. Vos premiers programmes
ordinateur la sortie de dmarrage sur la nouvelle ligne et \t fait rfrence au caractre onglet .
Toutes les lettres dans une directive .ascii doivent tre entre guillemets.
Dans notre exemple, l'assembleur rserve 14 .long s, un droit aprs l'autre. Depuis
Chaque long occupe 4 octets, ce qui signifie que toute la liste reprend 56 octets. Ces
sont les nombres que nous vont chercher travers pour trouver le maximum. data_items
est utilis par l'assembleur de renvoyer l'adresse de la premire de ces valeurs.
Prendre note que le dernier lment de donnes dans la liste est un zro. J'ai dcid d'utiliser un
zro pour dire
mon programme qu'il a atteint la fin de la liste. J'aurais pu faire cette autrement. J'ai
aurait pu avoir la taille de la liste code en dur dans le programme. Aussi, j'aurais pu
mettre la longueur de la liste comme premier lment, ou dans un autre endroit. J'ai galement pu
ont fait un symbole qui a marqu le dernier emplacement de la liste des articles. Peu importe
Comment je le fais, je dois avoir une mthode de dtermination de la fin de la liste. Le
ordinateur ne sait rien - il ne peut le faire ce que dit sa. Il ne va pas s'arrter
traitement moins que je lui donne une sorte de signal. Dans le cas contraire cela pourrait continuer
traitement au-del de la fin de la liste dans les donnes qui lui succdera et mme
endroits o nous n'avons pas mis toutes les donnes.
Notez que nous n'avons pas une dclaration de .globl pour data_items. C'est parce que
Nous nous rfrons uniquement ces emplacements au sein du programme. Aucun autre fichier ou
programme
Il faut savoir o ils se trouvent. Cela fait contraste avec le symbole _start,
dont Linux a besoin de savoir o c'est alors qu'il sait o commencer le
excution du programme. Il n'est pas une erreur d'crire .globl data_items, que c'est juste pas
ncessaire. En tout cas, jouer avec cette ligne et ajouter vos propres numros. Mme
Bien qu'ils soient .long, le programme produira des rsultats tranges si n'importe quel nombre est
suprieure 255, parce que c'est l'tat de sortie autorise plus grand. Notez galement que si
vous dplacez le 0 au plus haut dans la liste, le reste s'ignor. N'oubliez pas que n'importe quel
moment
vous modifiez le fichier source, vous devez r-assembler et re-lier votre programme. Do
cela maintenant et voir les rsultats.
Bon, nous avons jou avec les donnes quelque peu. Maintenant regardons le code. Dans le
vous remarquerez que nous avons marqu quelques variables que nous prvoyons d'utiliser les
commentaires.
Une variable est un emplacement de stockage ddi utilis dans un but prcis, gnralement
35
Chapitre 3. Vos premiers programmes
tant donn un nom diffrent par le programmeur. Nous avons parl dans le prcdent
l'article, mais n'a pas leur donner un nom. Dans ce programme, nous avons plusieurs variables :
une variable pour le nombre maximal actuel trouv
une variable pour laquelle nombre de la liste que nous examinons actuellement, appel le
index
une variable contenant le numro en cours en cours d'examen
Dans ce cas, nous avons assez peu de variables que nous pouvons les tenir tous dans les
registres. Dans
des programmes plus vastes, vous devez mettre en mmoire et puis les dplacer aux registres
Lorsque vous tes prt les utiliser. Nous discuterons comment faire cela plus tard. Quand les gens
programmation au dpart, ils sous-estiment souvent le nombre de variables qu'ils
aurez besoin. Les gens ne servent pas avoir penser travers chaque dtail d'un processus,
et donc laisser de ct les variables ncessaires dans leurs premires tentatives de programmation.
Dans ce programme, nous utilisons ebx % comme l'emplacement de l'lment plus important, que
nous avons trouv.
edi % est utilis comme index pour l'lment de donnes actuel, que nous cherchons. Maintenant,
nous allons parler
a propos de ce qu'un index est. Quand nous lisons les informations de data_items, nous allons
Dmarrer avec le premier un (numro d'article 0 de donnes), puis passez la seconde un (lment
de donnes
Numro 1), puis le troisime (numro d'article de donnes 2) et ainsi de suite. Le nombre de point
de donnes
est l'indice de data_items. Vous remarquerez que la premire instruction que nous donnons la
ordinateur est :
movl $0, % edi
Puisque nous utilisons % edi comme notre index, et nous voulons commencer examiner lors de la
premire
ordre du jour, nous chargeons % edi avec 0. Maintenant, la prochaine instruction est rus, mais
crucial pour ce qui
nous le faisons. Il est dit :
movl data_items(,%edi,4), eax %
Maintenant pour comprendre cette ligne, vous devez garder plusieurs choses l'esprit :
36
Chapitre 3. Vos premiers programmes
data_items est le numro d'emplacement du dbut de notre numro de la liste.
Chaque numro est stock dans 4 emplacements de stockage (parce que nous avons dclar
l'aide
.long)
% edi organise ce stade 0
Donc, en gros en quoi consiste cette ligne est dire "commencer au dbut de data_items, et
prendre le premier lment numro (car % edi est 0) et n'oubliez pas que chaque nombre
reprend quatre emplacements de stockage. Ensuite, il stocke ce nombre dans %EAX. C'est
comment
vous rdiger des instructions de mode adressage index en langage assembleur. Le
instruction sous une forme gnrale est la suivante :
movl BEGINNINGADDRESS(,%INDEXREGISTER,WORDSIZE)
Dans notre cas data_items tait notre adresse de dbut, % edi tait notre Registre d'index,
et 4 a t la taille de notre mot. Ce sujet est discut plus en dtail dans la Section appele
Modes d'adressage.
Si vous regardez les chiffres en data_items, vous verrez que le nombre 3 est maintenant
dans % eax. Si % edi a t dfinie sur 1, le nombre 67 serait dans %EAX, et si elle a t dfinie
2, le nombre 34 serait dans %EAX et ainsi de suite. Des choses trs tranges se
arriver si nous avons utilis un nombre diffrent de 4 comme la taille de nos emplacements de
stockage. 10 la
faon dont vous crivez ceci est trs gnant, mais si vous savez ce que fait chaque pice, il n'est pas
trop difficile. Pour plus d'informations ce sujet, voir la Section calledAddressing
Modes
Regardons la ligne suivante :
movl % eax, ebx %
10. Theinstructiondoesn'treallyuse4forthesizeofthestoragelocations, althoughlooking
elle de cette faon fonctionne maintenant pour nos besoins. C'est en fait ce qu'on appelle un
multiplicateur. Fondamentalement,
la faon dont cela fonctionne est que vous commencez l'emplacement spcifi par data_items,
puis vous ajoutez
edi % * 4 emplacements de stockage, puis rcuprez le numro. Gnralement, vous utilisez la taille
de la
nombres comme votre multiplicateur, mais dans certaines circonstances, que vous aurez envie de
faire d'autres choses.
37
Chapitre 3. Vos premiers programmes
Nous avons le premier point examiner stocke dans %EAX. Puisque c'est le premier point, nous
savons
Il est le plus grand que nous avons regard. Nous ranger dans ebx %, puisque c'est l o nous
sommes
garder le plus grand nombre trouv. Aussi, mme si movl est synonyme de se dplacer, il
en fait copie la valeur, donc % eax et ebx % contiennent la valeur de dpart. 11
Maintenant, nous entrons dans une boucle. Une boucle est un segment de votre programme qui
peut s'excuter
plus d'une fois. Nous avons marqu l'emplacement de dpart de la boucle dans le symbole
start_loop. Nous faisons une boucle c'est parce que nous ne savons pas comment
plusieurs lments de donnes, que nous avons au processus, mais la procdure sera la mme
n'importe
combien ils sont. Nous ne voulons pas avoir rcrire notre programme pour toutes les listes
longueur possible. En fait, nous ne voulons mme pas d'avoir crire le code pour une
comparaison pour chaque lment de liste. Par consquent, nous avons une seule section du code
(un
boucle) que nous excutons maintes et maintes fois pour chaque lment de data_items.
Dans la section prcdente, nous avons expos ce que devais faire cette boucle. Passons en revue :
Vrifiez si la valeur actuelle l'tude est gale zro. Dans l'affirmative, cela signifie que nous
la fin de nos donnes et devrait quitter la boucle.
Il faut charger la valeur suivante de notre liste.
Il faut voir si la valeur suivante est plus grande que notre valeur actuelle plus grande.
Si c'est le cas, il faut copier dans l'emplacement que nous tenons la plus grande valeur.
Maintenant, nous devons revenir au dbut de la boucle.
Bon, alors maintenant laisse aller au code. Nous avons le dbut de la boucle marque avec
start_loop. C'est donc nous savons o aller retour pour la fin de notre boucle.
Ensuite, nous avons ces instructions :
CMPL $0, % eax
Je end_loop
11. en outre, le l en movl est synonyme de dmnagement depuis longtemps, nous nous dirigeons
une valeur qui reprend quatre
emplacements de stockage.
38
Chapitre 3. Vos premiers programmes
L'instruction de cmpl compare les deux valeurs. Ici, on compare la
numro 0 au numro stock dans %EAX cette instruction compare galement affecte un
s'inscrire ne pas mentionns ici, les eflags % vous inscrire. C'est aussi connu sous le nom de l'tat
s'inscrire, et a de nombreuses utilisations dont nous discuterons plus tard. Juste tre conscient que
la
rsultat de la comparaison est stock dans le registre d'tat. La ligne suivante est un flux
contrler l'instruction qui dit pour accder l'emplacement d'end_loop si les valeurs qui
On a compar les juste sont gales (c'est ce que signifie le e de l'EI). Il utilise l'tat de
Registre pour stocker la valeur de la dernire comparaison. Nous avons utilis je, mais il existe de
nombreux
instructions de saut que vous pouvez utiliser :
Je
Saut si les valeurs sont gales
JG
Saut si la deuxime valeur est suprieure la valeur premire 12
jge
Saut si la deuxime valeur est suprieure ou gale la valeur du premier
Jl
Saut si la deuxime valeur tait infrieure la premire
jle
Saut si la deuxime valeur est infrieure ou gale la valeur du premier
JMP
Sauter n'importe quoi. Cela n'a pas besoin d'tre prcd d'une comparaison.
12. constate que la comparaison est de voir si la deuxime valeur est suprieure la premire. Je le
ferais
il pens l'inverse. Vous y trouverez beaucoup de choses comme a lors de l'apprentissage
de programmation. Il se produit parce que la logique des choses diffrentes pour diffrentes
personnes. De toute faon,
vous aurez juste mmoriser des choses et aller.
39
Chapitre 3. Vos premiers programmes
La liste complte est dcrite dans l'annexe B. Dans ce cas, nous sautons si
%EAX conserve la valeur de zro. Dans l'affirmative, nous avons fait et nous allons loop_exit. 13
Si le dernier lment charg n'tait pas nul, nous continuons aux instructions suivantes :
edi % incl
movl data_items(,%edi,4), eax %
Si vous vous souvenez de notre discussion prcdente, l'edi % contient l'index notre liste
des valeurs data_items. incl incrmente la valeur de % edi de. Ensuite, la
movl est semblable celle que nous avons fait au pralable. Cependant, depuis que nous avons dj
incrmente % edi, %EAX reoit la valeur suivante de la liste. Maintenant %EAX a la
prochaine valeur tester. Donc, nous allons le tester !
CMPL % ebx, eax %
jle start_loop
Ici, nous comparons notre valeur actuelle, stocke dans %EAX notre plus grande valeur ce jour,
stock dans % ebx. Si la valeur actuelle est infrieure ou gale notre plus grande valeur ce jour,
nous
ne m'inquite ce sujet, donc on saute juste au dbut de la boucle. Dans le cas contraire,
Nous avons besoin d'enregistrer cette valeur comme la plus grande salle :
movl % eax, ebx %
JMP start_loop
qui dplace la valeur actuelle dans ebx %, que nous utilisons pour stocker le courant
plus grande valeur, et lance la boucle tout recommencer.
Bon, alors la boucle s'excute jusqu' ce qu'il atteint 0, quand il saute loop_exit. Ceci
partie du programme appelle le noyau Linux pour quitter. Si vous vous souvenez de la dernire
13. les noms de ces symboles peuvent tre ce que vous voulez qu'ils soient, aussi longtemps qu'ils
seulement
contenir des lettres et le caractre de soulignement (_). Le seul qui est forc est _start, et
peut-tre d'autres que vous dclarez l'aide de .globl. Toutefois, si c'est un symbole que vous
dfinissez et seulement
vous utilisez, n'hsitez pas appeler tout ce que vous voulez qui est suffisamment descriptive
(n'oubliez pas que
d'autres devront modifier votre code plus tard et devront figurer dehors ce que vos symboles
moyenne).
40
Chapitre 3. Vos premiers programmes
programme, lorsque vous appelez le systme d'exploitation (n'oubliez pas c'est comme la
signalisation
Batman), vous rangez le numro d'appel systme dans %EAX (1 pour l'appel de sortie) et stocker
les autres valeurs dans les autres registres. L'appel de sortie requiert que nous avons mis notre
sortie
statut dans ebx % nous avons dj l'tat de sortie l puisqu'on utilise ebx % comme
notre plus grand nombre, donc tout ce que nous devons faire est de charger %EAX avec le numro
un et appel
le noyau pour quitter. Comme a:
movl $1, % eax
int 0 x 80
Bon, c'tait beaucoup de travail et d'explication, surtout pour un tel petit programme.
Mais h, vous souhaitez apprendre beaucoup ! Maintenant, relisez travers l'ensemble du
programme, payant
une attention particulire aux observations. Assurez-vous que vous comprenez ce qui se passe
chaque ligne. Si vous ne comprenez pas une ligne, revenir en arrire dans cette section et la figure
ce que signifie la ligne.
Vous pourriez galement saisir un morceau de papier et passer par le programme tape par tape,
enregistrer tous les changements chaque registre, donc vous pouvez voir plus clairement ce qui est
en cours.
Modes d'adressage
Dans la Section intitule mthodes pour accder aux donnes dans le chapitre 2, nous avons appris
la
diffrents types de modes d'adressage disponibles pour utilisent en langage assembleur. Ceci
section portera sur comment ces modes d'adressage sont reprsents l'Assemble
instructions en langage clair.
La forme gnrale des rfrences de mmoire adresse est la suivante :
ADDRESS_OR_OFFSET(%BASE_OR_OFFSET,%INDEX,MULTIPLIER)
Tous les champs sont facultatifs. Pour calculer l'adresse, il suffit d'effectuer la
calcul suivant :
41
Chapitre 3. Vos premiers programmes
ADRESSE FINALE = ADDRESS_OR_OFFSET + % BASE_OR_OFFSET + MULTIPLICATEUR * % INDE
ADDRESS_OR_OFFSET et multiplicateur doivent tous deux tre constantes, tandis que l'autre
deux doivent tre des registres. Si aucun des morceaux est laiss de ct, il est juste remplac par
zro
dans l'quation.
Tous les modes d'adressage mentionns dans la Section appele l'accs aux donnes
Mthodes en chapitre 2 exceptimmediate-mode peuvent tre reprsents de cette faon.
mode d'adressage direct
Ceci est fait en utilisant uniquement la partie ADDRESS_OR_OFFSET. Exemple :
movl adresse, %EAX
Ceci charge eax % avec la valeur l'adresse adresse de la mmoire.
mode d'adressage index
Ceci est fait en utilisant la ADDRESS_OR_OFFSET et la partie INDEX.
Vous pouvez utiliser n'importe quel Registre gnraliste comme le registre d'index. Vous pouvez
galement
avoir un multiplicateur constant de 1, 2 ou 4 pour le registre d'index, afin de faciliter
indexer en octets, double-octets et mots. Par exemple, disons que nous
avait une chane d'octets comme string_start et je voulais accder le tiers
(index 2 puisque nous avons commencer compter de l'indice zro) et _ecx qui s'est tenue le
valeur 2. Si vous voulez charger dans %EAX vous pourriez faire ce qui suit :
movl string_start(,%ecx,1), eax %
Cela commence string_start et ajoute 1 * % ecx cette adresse et les charges
la valeur en % eax.
mode d'adressage indirect
Mode d'adressage indirect charge une valeur partir de l'adresse indique par un
s'inscrire. Par exemple, si %EAX tenue une adresse, nous pourrions passer la valeur
42
Chapitre 3. Vos premiers programmes
que cette adresse % ebx en procdant comme suit :
movl (%EAX), ebx %
mode d'adressage pointeur base
Adressage de pointeur de base est similaire l'adressage indirect, sauf qu'il ajoute une
valeur de constante l'adresse dans le registre. Par exemple, si vous avez un enregistrement
o la valeur d'ge est de 4 octets dans le dossier, et vous avez l'adresse de la
record dans %EAX, vous pouvez rcuprer l'ge en % ebx en publiant le texte suivant
instruction :
movl 4(%eax), ebx %
mode immdiat
Mode immdiat est trs simple. Il ne s'ensuit pas la forme gnrale, que nous avons
sers. Mode immdiat est utilis pour charger des valeurs directes dans les registres ou
emplacements de mmoire. Par exemple, si vous vouliez charger le nombre 12 dans
% eax, vous feriez tout simplement ce qui suit :
movl $12, % eax
Notez que pour indiquer le mode immdiat, nous avons utilis un signe de dollar en face de la
numro. Si nous ne le faisions pas, il serait direct addressing mode, auquel cas la
valeur situ l'emplacement de mmoire 12 serait charge dans %EAX plutt que
le nombre 12 lui-mme.
s'inscrire mode d'adressage
S'inscrire mode dplace simplement les donnes en ou hors d'un registre. Dans l'ensemble de nos
exemples, Registre mode d'adressage a t utilis pour l'autre oprande.
Ces modes d'adressage sont trs importants, comme tout souvenir access utilise un
de ceux-ci. Tous les modes sauf le mode immdiat peut tre utilis comme tant la source ou
oprande de destination. Mode immdiat ne peut tre un oprande source.
43
Chapitre 3. Vos premiers programmes
En plus de ces modes, il y a aussi des instructions diffrentes pour diffrentes tailles
des valeurs dplacer. Par exemple, nous utilisons movl pour dplacer les donnes un mot
une fois. dans de nombreux cas, vous voudrez seulement dplacer donnes un octet la fois. Il s'agit
accompli par l'instruction movb. Cependant, puisque les registres que nous avons
discuts sont de taille mot et pas taille octets, vous ne pouvez pas utiliser le registre complet.
Au lieu de cela, vous devez utiliser une partie du Registre.
Prenez par exemple % eax. Si vous voulez seulement utiliser deux octets la fois, vous
pouvez simplement utiliser % ax. % ax est la moiti moins significatif (c'est--dire - la dernire partie
de la
numro) du registre eax % et est utile lorsqu'il s'agit des quantits de deux octets.
% ax est encore divise en % et % al ah. % al est l'octet le moins significatif de
ax % et % ah est l'octet le plus significatif. 14 chargement d'une valeur dans %EAX essuiera
hors tout tait en % et % al ah (et aussi % ax, puisque % ax est compose d'entre eux).
De mme, la charger une valeur en % ou % al ah corrompra toute valeur qui a t
anciennement en % eax. Fondamentalement, il est conseill d'utiliser uniquement un registre pour
soit un octet ou un
mot, mais jamais les deux en mme temps.
14. lorsque nous parlons de l'octet plus ou moins importante, il peut tre un peu droutant. Nous
allons
prendre le n 5432. Dans ce nombre, 54 est la plus importante moiti de ce nombre et 32
est la moiti moins importante. Vous ne peut pas tout fait diviser comme a pour les registres, car
ils fonctionnent
sur la base 2, plutt que de base de 10 numros, mais c'est l'ide de base. Pour plus d'informations
sur
Cette rubrique, reportez-vous au chapitre 10.
44
Chapitre 3. Vos premiers programmes
Mise en page du registre eax %
Pour une liste plus complte des instructions, consultez l'annexe B.
Examen
Connatre les Concepts
Que si dire si une ligne dans le programme commence par le caractre # ?
Quelle est la diffrence entre un fichier de langage d'assemblage et un code d'objet
fichier ?
Qu'est-ce que le faire de l'diteur de liens ?
Comment vrifiez-vous le code d'tat de rsultat du dernier programme que vous avez excut ?
Quelle est la diffrence entre movl $1, % eax et movl 1, %EAX ?
45
Chapitre 3. Vos premiers programmes
Quel registre contient le numro d'appel systme ?
Quels sont les indices utiliss pour ?
Pourquoi index commencent gnralement 0 ?
Si j'ai mis la commande movl data_items(,%edi,4), % eax et
data_items a t adresse 3634 et % edi qui s'est tenue la valeur 13, quelle adresse serait
vous utiliser pour se dplacer dans %EAX ?
La liste des registres usage gnral.
Quelle est la diffrence entre movl et movb ?
Ce qui est contrle de flux ?
Que doit faire un saut conditionnel ?
Qu'est-ce que vous devez planifier pour lorsque vous crivez un programme ?
Passer par chaque instruction et liste quel mode d'adressage est utilis pour
chaque oprande.
Utiliser les Concepts
Modifier le premier programme pour retourner la valeur 3.
Modifier le programme maximum pour trouver le minimum au lieu de cela.
Modifier le programme maximum d'utiliser le numro 255 pour terminer la liste plutt que
le numro 0
Modifier le programme maximal utiliser une adresse de fin, plutt que le nombre
0 savoir quand s'arrter.
Modifier le programme maximal utiliser un nombre de longueur plutt que le nombre de 0
savoir quand s'arrter.
46
Chapitre 3. Vos premiers programmes
Quel serait l'instruction movl _start, % eax do ? Soyez prcis, bas sur
vos connaissances sur les modes d'adressage et la signification de _start. Comment
Ceci diffre de l'instruction movl $_start, %EAX ?
Aller plus loin
Modifier le premier programme abandonner la ligne d'instruction int. Assembler, relier,
et excuter le nouveau programme. Quel message d'erreur que vous obtenez. Pourquoi avez-vous
pense que cela pourrait tre ?
Jusqu' prsent, nous avons discut trois approches pour trouver la fin de la liste - utilisation
un numro spcial, l'aide de l'adresse de fin et en utilisant le compte de la longueur. Qui
approche que vous pensez est le meilleur ? Pourquoi ? Quelle approche utiliseriez-vous si vous
sachant que la liste a t trie ? Pourquoi ?
47
Chapitre 3. Vos premiers programmes
48
Chapitre 4. Tout sur les fonctions
Traitant de la complexit
Dans le chapitre 3, les programmes que nous avons crit seulement se composait d'une section de
code.
Cependant, si nous avons crit des programmes rels comme a, il serait impossible de maintenir
eux. Il serait vraiment difficile d'obtenir plusieurs personnes travaillant sur le projet, comme
tout changement dans une partie susceptible d'affecter une autre partie qu'un autre dveloppeur
travaille sur.
Pour aider les programmeurs travailler ensemble dans les groupes, il est ncessaire de rompre
apart dans des pices spares, qui communiquent entre eux par le biais de programmes
interfaces bien dfinies. De cette faon, chaque pice peut tre dvelopp et test
indpendamment des autres, ce qui rend plus facile pour plusieurs programmeurs de travailler sur
le projet.
Programmeurs utilisent des fonctions de briser leurs programmes en morceaux qui peut tre
indpendamment dvelopps et tests. Fonctions sont des units de code que faire un dfini
travail sur les types de donnes spcifis. Par exemple, dans un traitement de texte
programme, j'ai peut-tre une fonction appele handle_typed_character qui est
activ chaque fois qu'un utilisateur tape dans une cl. Les donnes qui qu'utilise la fonction serait
sans doute le keypress elle-mme et le document de l'utilisateur est actuellement ouverte. Le
fonction modifierait alors le document selon le keypress disait
tout.
Une fonction est donne pour traiter les lments de donnes sont appels ses paramtres. Dans le
exemple de traitement de texte, la cl qui est presse et le document serait
considr comme paramtres la fonction handle_typed_characters. Le
Liste des paramtres et les attentes de traitement d'une fonction (ce qu'elle est cense
voir avec les paramtres) sont appels l'interface de la fonction. Beaucoup de soin va dans
conception des interfaces de fonction, parce que si elles sont appeles de nombreux endroits dans
un
projet, il est difficile de les changer si ncessaire.
Un programme typique se compose de centaines ou milliers de fonctions, chacun avec un
49
Chapitre 4. Tout sur les fonctions
petite et bien dfinie, tche effectuer. Toutefois, en fin de compte il y a des choses que vous
Impossible d'crire des fonctions qui doivent tre fournies par le systme. Ceux qui sont appels
fonctions primitives (ou justes primitives) - ils sont les lments fondamentaux dont tout le reste
est construit hors de. Par exemple, imaginez un programme qui dessine un graphique
interface. Il doit y avoir une fonction pour crer des menus. Qui fonctionne sans doute
appelle d'autres fonctions pour crire du texte, pour crire des icnes, pour peindre l'arrire-plan,
calculer o le pointeur de la souris est, etc.. Toutefois, en fin de compte, ils rejoindront un
ensemble de primitives fournies par le systme d'exploitation la ligne de base d'ou point
dessin. Programmation peut non plus considrer que briser un vaste programme
en petits morceaux jusqu' ce que vous obtenez aux fonctions primitives, ou incrmentielle
renforcement des fonctions primitives jusqu' ce que vous obtenez l'image grande mise au point sur
le dessus. Dans
langage d'assemblage, les primitives sont habituellement la mme chose que les appels systme,
mme si les appels systme ne sont pas vrai les fonctions que nous allons parler dans ce chapitre.
Fonctionnement de travail
Fonctions sont composes de plusieurs pices diffrentes :
nom de la fonction
Nom de la fonction est un symbole qui reprsente l'adresse o le
code de la fonction commence. En langage assembleur, le symbole est dfini en tapant
le nom de la fonction comme une tiquette avant le code de la fonction. C'est comme
tiquettes que vous avez utilis pour le saut.
paramtres de fonction
Paramtres de la fonction sont les lments de donnes qui sont explicitement donns la
fonction pour traitement. Par exemple, en mathmatiques, il y a un sinus
fonction. Si vous deviez demander un ordinateur pour trouver le sinus de 2, sinus serait
nom de la fonction et 2 est le paramtre. Certaines fonctions ont
50
Chapitre 4. Tout sur les fonctions
beaucoup de paramtres, d'autres n'en ont pas. 1
variables locales
Les variables locales sont le stockage de donnes qui a une fonction utilise lors du traitement qui est
jets lors de son retour. C'est un peu comme un bloc-notes papier.
Fonctions extraire un nouveau morceau de papier chaque fois qu'ils sont activs et ils
faut il jeter quand ils ont fini de traitement. Les variables locales d'une
fonction ne sont pas accessibles d'autres fonctions au sein d'un programme.
variables statiques
Les variables statiques sont le stockage de donnes qui a une fonction utilise lors du traitement qui
est
ne pas jet par la suite, mais il est rutilis chaque fois le code fonction
est activ. Ces donnes ne sont pas accessibles une autre partie du programme.
Variables statiques ne sont gnralement pas utiliss, sauf si absolument ncessaire, car ils
peut causer des problmes plus tard.
variables globales
Variables globales sont le stockage de donnes utilis par une fonction de traitement qui
sont grs par la fonction. Par exemple, un diteur de texte simple peut mettre
tout le contenu du fichier qu'il travaille sur dans une variable globale, donc ce n'est pas
doivent tre passs chaque fonction qui opre ce sujet. 2 valeurs de configuration
sont galement souvent stockes dans des variables globales.
adresse de l'expditeur
L'adresse de retour est un paramtre invisible qu'il n'est pas utilis directement
au cours de la fonction. L'adresse de retour est un paramtre qui indique la fonction
1. paramtres permet galement d'organiser les donnes que la fonction veut pointeurs
Envoyer au programme.
2. il est gnralement considr comme de mauvaise pratique. Imaginez si un programme est crit
de cette faon, et
dans la prochaine version, d' qu'ils ont dcid de permettre une seule instance du programme
diter plusieurs fichiers.
Chaque fonction devra alors tre modifi de sorte que le fichier qui a t manipul
s'tre pass comme paramtre. Si vous avait simplement pass comme un paramtre dans un
premier temps,
la plupart de vos fonctions aurait pu survivre votre mise niveau inchang.
51
Chapitre 4. Tout sur les fonctions
o reprendre l'excution une fois la fonction termine. Cela est ncessaire
parce que les fonctions peuvent tre appeles pour effectuer un traitement de beaucoup de
diffrentes parties du
votre programme et la fonction doit tre capable de revenir partout o il
a t appel. Dans la plupart des langages de programmation, ce paramtre est pass
Lorsque la fonction est appele automatiquement. En langage d'assemblage, l'appel
instruction handles en passant le retour adresse pour vous et ret des handles l'aide
cette adresse pour retourner vers o vous avez appel la fonction de.
valeur de retour
La valeur de retour est la principale mthode de transfert des donnes vers les principaux
programme. La plupart des langages de programmation permettent uniquement une seule valeur de
retour pour une
fonction.
Ces pices sont prsents dans la plupart des langages de programmation. Comment vous spcifiez
chacune
pice est diffrent dans chacun d'eux, cependant.
La manire dont les variables sont stockes et les paramtres et valeurs de retour sont
transfr de l'ordinateur varie de la langue la langue aussi bien. Ceci
la variance est connue comme la convention d'appel de la langue, car il dcrit comment
fonctions attendent d'obtenir et de recevoir des donnes lorsqu'elles sont appeles. 3
Langage d'assemblage peut utiliser toute convention d'appel qu'il veut. Vous pouvez mme faire
un vous-mme. Toutefois, si vous souhaitez interagir avec les fonctions crites dans
autres langues, vous devez obir leurs conventions d'appel. Nous utiliserons la
appeler convention de langage de programmation C pour nos exemples, parce que c'est
la plus rpandue, et parce que c'est la norme pour les plates-formes Linux.
3. une convention est une faon de faire qui est standardise, mais pas par la force. Pour ex-
ample, il s'agit d'une convention pour les gens de serrer la main quand ils se rencontrent. Si je refuse
de serrer la
mains avec vous, vous pouvez penser que je n'aime pas vous. Suivant les conventions est important
tre-
cause, pour qu'il le rend plus facile pour les autres comprendre ce que vous faites et rend plus
facile
programmes crits par plusieurs auteurs indpendants travailler ensemble.
52
Chapitre 4. Tout sur les fonctions
Fonctions de langage assembleur l'aide de l'appel de la C
Convention
Vous ne pouvez pas crire fonctions de langage assembleur sans comprendre comment la
pile de l'ordinateur fonctionne. Chaque programme de l'ordinateur qui excute utilise une rgion de
mmoire appele la pile pour activer les fonctions travailler correctement. Pensez une pile en tant
que
un tas de papiers sur votre bureau qui peut tre ajout indfiniment. Vous gnralement
garder les choses que vous travaillez vers le haut, et vous enlevez choses comme
vous avez fini de travailler avec eux.
Votre ordinateur a une pile, trop. Vie de pile de l'ordinateur tout en haut
adresses de mmoire. Vous pouvez pousser les valeurs sur le dessus de la pile par un
instruction appele pushl, qui pousse soit une valeur de registre ou de la mmoire vers le
haut de la pile. Eh bien, nous disons, c'est le top, mais le top de la pile est en fait la
bas de la mmoire de la pile. Bien que cela prte confusion, la raison pour cela est que
Lorsque nous pensons une pile de quoi que ce soit - vaisselle, papiers, etc. - nous envisager l'ajout
et en enlevant la partie suprieure de celui-ci. Toutefois, la mmoire la pile commence au
sommet de
mmoire et pousse vers le bas en raison de considrations architecturales. Par consquent,
Lorsque nous parlons de haut de la pile n'oubliez pas que c'est au bas de la pile
mmoire. Vous pouvez galement extraire des valeurs sur le dessus l'aide d'une instruction
appele popl.
Cela supprime la valeur de la pile et la place dans un registre ou de la mmoire
emplacement de votre choix...
Quand on pousse une valeur dans la pile, le haut de la pile se dplace accueillir le
valeur supplmentaire. Nous pouvons pousser en fait continuellement des valeurs dans la pile et il
sera
continuer crotre plus loin et plus loin dans la mmoire jusqu' ce que nous avons atteint notre
code ou des donnes.
Alors, comment savons-nous o le courant haut de la pile est ? Le registre de pile,
% esp, contient toujours un pointeur vers l'actuel Haut de la pile, partout o il est.
Chaque fois que nous enfoncer quelque chose dans la pile avec pushl, % esp obtient soustrait
par 4 afin qu'il pointe vers le nouveau haut de la pile (n'oubliez pas, chaque mot est quatre
octets de long et la pile pousse vers le bas). Si nous voulons retirer quelque chose de
la pile, nous utilisons simplement l'instruction de la population, qui ajoute 4 % esp et met le
prcdente valeur dans tout ce que vous avez spcifi s'inscrire. pushl et popl chaque prendre
53
Chapitre 4. Tout sur les fonctions
un oprande - le registre pour pousser dans la pile pour pushl, ou recevoir les donnes qui
est sorti de la pile pour la population.
Si nous voulons simplement accder la valeur en haut de la pile sans le supprimer,
Nous pouvons simplement utiliser le registre esp en mode d'adressage indirect. Par exemple, la
code suivant dplace tout ce qui est en haut de la pile dans %EAX :
movl (% esp), % eax
Si nous devions juste faire ceci :
movl % esp, %EAX
puis %EAX tiendrait simplement le pointeur vers le haut de la pile, et non la valeur
dans la partie suprieure. Mettre % esp parenthses provoque l'ordinateur aller indirecte
mode d'adressage et par consquent nous obtenir la valeur pointe par % esp. Si nous voulons
accder la valeur juste en dessous du haut de la pile, nous pouvons mettre simplement cela
instruction :
movl 4(%esp), eax %
Cette instruction utilise le mode d'adressage pointeur de base (voir la Section intitule
Mthodes accder des donnes dans le chapitre 2) qui ajoute simplement 4 % esp avant
en levant la valeur tant pointe.
Dans la convention d'appel C language, la pile est l'lment cl pour
mettre en uvre d'une fonction variables locales, paramtres et adresse de l'expditeur.
Avant d'excuter une fonction, un programme pousse tous les paramtres pour la
fonction sur la pile dans l'ordre inverse qu'elles sont documentes. Ensuite, la
programme met une instruction d'appel indiquant qui fonctionnent, il souhaite dmarrer. Le
instruction d'appel fait deux choses. Tout d'abord il excute un push de l'adresse de la prochaine
instruction, qui est l'adresse de retour, dans la pile. Ensuite il modifie le
pointeur d'instruction (eip %) pour pointer vers le dbut de la fonction. Oui, au moment o la
fonction permet de dmarrer, la pile ressemble ceci (le top de la pile est en bas sur
54
Chapitre 4. Tout sur les fonctions
Cet exemple) :
Paramtre #N
...
Paramtre 2
Paramtre 1
Adresse de l'expditeur <---(% esp)
Chacun des paramtres de la fonction ont t pousss dans la pile, et
Enfin, l'adresse de retour est l. Maintenant la fonction elle-mme a du travail faire.
La premire chose qu'il fait est de sauvegarder le registre de pointeur de base actuel, % ebp, en
faisant
pushl % ebp. Le pointeur de base est un registre spcial utilis pour accder la fonction
paramtres et variables locales. Ensuite, il copie le pointeur de pile pour %EBP par la pratique
movl % esp, ebp %. Cela vous permet d'tre en mesure d'accder aux paramtres de la fonction
en tant qu'index fixes depuis le pointeur de base. Vous pouvez penser que vous pouvez utiliser la
pile
pointeur pour cela. Cependant, au cours de votre programme vous pouvez faire autre chose avec le
empiler tels que pousser les arguments d'autres fonctions.
Copiant le pointeur de pile dans le pointeur au dbut d'une fonction de base
vous permet de toujours savoir o sont vos paramtres (et comme nous verrons, local
variables trop), alors mme que vous pouvez tre pousser les choses sous et hors tension de la pile.
% ebp sera toujours lorsque le pointeur de pile a t au dbut de la fonction,
Il est donc plus ou moins une rfrence constante pour le frame de pile (le frame de pile
se compose de toutes les variables de la pile utilises dans une fonction, y compris les paramtres,
les variables locales et l'adresse de retour).
ce stade, la pile ressemble ceci :
Paramtre #N <---N*4+4(%ebp)
...
Paramtre 2 <---12(%ebp)
Paramtre 1 <---8(%ebp)
Adresse de l'expditeur <---4(%ebp)
Vieux % ebp <---(% esp) et (%EBP)
55
Chapitre 4. Tout sur les fonctions
Comme vous pouvez le constater, chaque paramtre est accessible en utilisant l'adressage de base
pointeur
mode utilisant le % ebp s'inscrire.
Ensuite, la fonction rserve un espace dans la pile d'ventuelles variables locales, qu'il a besoin. Ceci
se fait en dplaant simplement le pointeur de pile de la route. Disons que nous sommes
avoir besoin de deux mots de mmoire pour excuter une fonction. Nous pouvons simplement
dplacer le
pointeur de pile vers le bas de deux mots pour rserver de l'espace. Ceci est fait comme ceci :
Subl $8, % esp
Il soustrait 8 %la esp (n'oubliez pas, un mot est long de quatre octets). 4 cette faon, nous
peut utiliser la pile de stockage variable sans inquitante sur eux avec rcriture
excute un push de que nous pouvons faire pour les appels de fonction. Aussi, depuis lors, il est
allou sur la pile
cadre pour cet appel de fonction, la variable ne sera vivante qu'au cours de cette fonction.
Lorsque nous revenons, le frame de pile va disparatre et sera donc ces variables. C'est
pourquoi ils sont appels locales - ils n'existent que si cette fonction est appele.
Maintenant, nous avons deux mots pour le stockage local. Notre pile ressemble maintenant ceci :
Paramtre #N <---N*4+4(%ebp)
...
Paramtre 2 <---12(%ebp)
Paramtre 1 <---8(%ebp)
Adresse de l'expditeur <---4(%ebp)
Vieux % ebp <---(%EBP)
La Variable locale 1 <----4(%ebp)
La Variable locale 2 <----8(%ebp) (% esp) et
Ainsi, nous pouvons accder maintenant toutes les donnes que nous avons besoin de cette
fonction l'aide de base
pointeur s'adressant l'aide de diffrents dcalages de % ebp. %EBP a t faite spcifiquement
pour cela, c'est pourquoi on l'appelle le pointeur de base. Vous pouvez utiliser d'autres
enregistre en pointeur de base traitant de mode, mais le x 86 architecture fait l'aide
l'ebp % registre beaucoup plus rapidement.
4. juste un rappel - le signe de dollar devant les huit indique adresse mode immdiat-
ING, ce qui signifie que nous chargeons le numro 8 dans % esp plutt que la valeur l'adresse 8.
56
Chapitre 4. Tout sur les fonctions
Variables globales et les variables statiques sont accessibles tout comme nous avons t pour
accder aux
mmoire dans les chapitres prcdents. La seule diffrence entre le global et le statique
variables, c'est que les variables statiques ne sont utilises que par une seule fonction, alors que
global
variables sont utilises par nombreuses fonctions. Langage d'assemblage les traite exactement la
mme, bien que la plupart des autres langues distinguent.
Quand une fonction est faite excuter, il fait trois choses :
1. it magasins c'est la valeur de retour dans %EAX.
2. il rinitialise la pile qu'elle avait lorsqu'elle a t appele (il se dbarrasse du courant
frame de pile et le frame de pile de code appelant remet en vigueur).
3. elle retourne le contrle partout o il a t appel partir. Cela se fait l'aide de la
RET d'instruction qui apparat n'importe quelle valeur est en haut de la pile et dfinit
le pointeur d'instruction, %EIP, cette valeur.
Donc, avant une fonction retourne le contrle au code qui l'a appel, il doit restaurer la
prcdent frame de pile. Notez galement que, sans cela, ret ne fonctionnerait pas,
parce que dans notre frame de pile actuel, l'adresse de retour n'est pas en haut de la pile.
Donc, avant de nous le renvoyer, il faut rinitialiser le % de pointeur de pile esp et base
pointeur % ebp qu'elles avaient au dbut de la fonction.
Donc, pour revenir de la fonction que vous devez faire ce qui suit :
movl % ebp, % esp
POPL % ebp
RET
ce stade, vous devriez considrer toutes les variables locales immerger. La raison
est qu'aprs avoir dplac le pointeur de pile back, pousse pile futures est probablement
craser tout ce que vous mettez l. Par consquent, vous ne devez jamais enregistrer l'adresse
d'un local variable la vie de la fonction passe, il a t cr dans, ou bien il sera
crase aprs la vie de la pile c' est encadrer les extrmits.
57
Chapitre 4. Tout sur les fonctions
Contrle a maintenant beenhanded retour au code appelant, qui peut maintenant examiner
eax % pour la valeur de retour. Le code appelant doit galement retirer tous les
paramtres il push dans la pile, afin d'obtenir le pointeur de pile de retour o il
tait (vous pouvez aussi tout simplement ajouter 4 * nombre de paramtres % esp l'aide de
l'addl
instruction, si vous n'avez pas besoin des valeurs des paramtres plus). 5
Destruction des registres
Lorsque vous appelez une fonction, vous devriez supposer que tout actuellement
dans vos registres seront effacs. Le seul registre qui est garanti
pour se retrouver avec la valeur avec que cela a commenc est % ebp. %EAX est assur d'tre
crase, et les autres sont probablement. S'il existe des registres que vous voulez
enregistrer avant d'appeler une fonction, vous devez les sauver en les poussant
sur la pile avant de pousser les paramtres de la fonction. Vous pouvez ensuite pop
leur marche arrire en sens inverse aprs sautant hors les paramtres. Mme si
vous connaissez qu'une fonction ne remplace pas un registre, que vous devez l'enregistrer,
parce que les versions futures de cette fonction peuvent.
Conventions d'appel des autres langues peuvent tre diffrentes. Par exemple,
autres conventions d'appel peuvent mettre le fardeau sur la fonction Enregistrer
les registres qu'il utilise. N'oubliez pas de vrifier que l'appel
conventions de vos langues sont compatibles avant d'essayer de mlanger
Traduction. Ou dans le cas de langage d'assemblage, assurez-vous de que connatre
Comment appeler des fonctions de l'autre langue. eux.
Spcifications tendues : Dtails du langage C, convention d'appel (galement
appele ABI, ou Application Binary Interface) est disponible en ligne. Nous
ai trop simplifi et l'extrieur gauche plusieurs pices importantes pour rendre cela plus simple
pour les nouveaux programmeurs. Pour plus de dtails, vous devriez vrifier les documents
disponible http://www.linuxbase.org/spec/refspecs/ plus prcisment, vous devriez
5. ce n'est pas toujours strictement ncessaire sauf si vous enregistrez les registres sur la pile avant
un appel de fonction. Le pointeur de base conserve le frame de pile dans un tat raisonnablement
cohrent.
Toutefois, il est toujours une bonne ide et il est absolument ncessaire si vous enregistrez
temporairement
registres sur la pile...
58
Chapitre 4. Tout sur les fonctions
Recherchez le systme V Application Binary Interface - Intel386 Architecture
Supplment de processeur.
Un exemple de fonction
Nous allons jeter un coup d'oeil au fonctionne d'un appel de fonction dans un programme rel. La
fonction nous
sont aller crire est la fonction de puissance. Nous allons donner la fonction de puissance deux
paramtres - le nombre et la puissance que nous voulons porter . Par exemple, si nous
Il a donn les paramtres 2 et 3, elle allait augmenter de 2 la puissance de 3, ou 2 * 2 * 2, ce qui
donne
8. afin de simplifier ce programme, nous n'autoriserons les numros 1 et plus.
Voici le code pour le programme complet. Comme d'habitude, une explication
s'ensuit. Nommez le fichier power.s.
#PURPOSE : Programme pour illustrer le fonctionnement des fonctions
# Ce programme calculera la valeur de
# 2 ^ 3 + 5 ^ 2
#
#Everything dans le programme principal est stock dans des registres,
#so la section de donnes n'a rien.
.data .section
.section .text
.Globl _start
_start :
pushl $3 #push deuxime argument
pushl $2 #push premier argument
appel de puissance #call la fonction
ADDL $8, % esp #move le pointeur de pile de retour
59
Chapitre 4. Tout sur les fonctions
pushl % eax #save la premire rponse avant
#calling la fonction suivante
pushl $2 #push deuxime argument
pushl $5 #push premier argument
appel de puissance #call la fonction
ADDL $8, % esp #move le pointeur de pile de retour
POPL % ebx #The seconde rponse est dj
#in % eax. Nous avons conomis le
rponse de #first dans la pile,
#so maintenant nous pouvons juste pop
#out dans ebx %
ADDL % eax, ebx %#add ensemble
#the rsulte dans ebx %
movl $1, % eax #exit (% ebx est retourn)
int 0 x 80 $
#PURPOSE : Cette fonction est utilise pour calculer
# la valeur d'un nombre lev de
# un pouvoir.
#
#INPUT : Premier argument - le nombre de base
# Deuxime argument - le pouvoir de
# l'lever
#
#OUTPUT : Donne le rsultat comme valeur de retour
#
#NOTES : Le pouvoir doit tre 1 ou suprieur
#
#VARIABLES :
# % ebx - dtient le nombre de base
# % ecx - dtient le pouvoir
60
Chapitre 4. Tout sur les fonctions
#
#-4(%ebp) - contient le rsultat actuel
#
# %EAX est utilis pour le stockage temporaire
#
puissance .type, @function
puissance :
pushl % ebp #save vieux pointeur de base
movl % esp, pointeur de pile % ebp #make le pointeur de base
Subl $4, salle esp #get % pour notre stockage local
movl 8(%ebp), % ebx #put premier argument dans %EAX
movl 12(%ebp), % ecx #put deuxime argument dans le registre ecx %
movl % ebx,-4(%ebp) #store rsultat courant
power_loop_start :
CMPL $1, % ecx #if la puissance est de 1, nous avons termin
Je end_power
movl-4(%ebp), % eax #move le rsultat actuel dans %EAX
imull % ebx, % eax #multiply le rsultat actuel de
#the nombre de base
movl % eax,-4(%ebp) #store le rsultat actuel
decl _ecx #decrease la puissance
JMP power_loop_start #run pour la puissance suivante
end_power :
movl-4(%ebp), valeur d'eax #return % va dans %EAX
movl % ebp, % esp #restore le pointeur de pile
POPL % ebp #restore le pointeur de base
RET
61
Chapitre 4. Tout sur les fonctions
Entrez dans le programme, assembler et excutez-le. Essayer d'appeler la puissance pour des valeurs
diffrentes,
mais n'oubliez pas que le rsultat doit tre infrieur 256 quand il est repass la
Systme d'exploitation. Aussi tente de soustraire les rsultats des deux calculs. Essayez
Ajout d'un troisime appel la fonction de la puissance et ajouter il a rsultat de retour en.
Le code principal du programme est assez simple. Vous poussez les arguments sur la pile,
appelez la fonction et puis replacez le pointeur de pile. Le rsultat est stock dans
% eax. Notez qu'entre les deux appels au pouvoir, nous Sauvons la premire valeur sur le
pile. C'est parce que le seul registre qui est garanti pour tre sauv est % ebp.
C'est pourquoi nous pousser la valeur dans la pile et faire ressortir la valeur faire marche arrire
aprs la
deuxime appel de fonction est termine.
Nous allons tudier comment la fonction elle-mme est crit. Notez qu'avant la fonction,
Il n'y a documentation quant ce que la fonction fait, ce qu'il a les arguments sont, et
ce qu'il donne comme valeur de retour. Ceci est utile pour les programmeurs qui utilisent ce
fonction. Il s'agit d'interface de la fonction. Cela permet au programmeur sait quoi
les valeurs sont ncessaires sur la pile, et ce qui sera dans %EAX la fin.
Nous avons ensuite la ligne suivante :
.type power,@function
Cela indique l'diteur de liens que la puissance du symbole doit tre traite comme une
fonction. Depuis
ce programme n'est que dans un seul fichier, il fonctionne tout de mme avec ce laiss de ct.
Toutefois, il est conseill.
Aprs cela, nous dfinissons la valeur de l'tiquette nergie :
puissance :
Tel que mentionn prcdemment, cela dfinit la puissance du symbole est l'adresse o
les instructions qui suit l'tiquette commencent. C'est comment appeler les uvres de puissance. Il
transfre le contrle cet endroit du programme. La diffrence entre l'appel et
JMP est qu'appel pousse galement l'adresse de retour dans la pile afin que la fonction
peut retourner, n'est pas le cas de la jmp.
62
Chapitre 4. Tout sur les fonctions
Ensuite, nous avons nos instructions de mettre en place notre fonction :
pushl % ebp
movl % esp, ebp %
Subl $4, % esp
ce stade, notre pile ressemble ceci :
Numro de base <---12(%ebp)
Puissance <---8(%ebp)
Adresse de l'expditeur <---4(%ebp)
Vieux % ebp <---(%EBP)
Rsultat courant <----4(%ebp) et (% esp)
Bien que nous pourrions utiliser un registre pour le stockage temporaire, ce programme utilise un
autochtone !
variable afin de montrer comment mettre en place. Souvent il ne suffisent pas
registres pour stocker tout, il faut les dcharger dans des variables locales.
Tantt, votre fonction devra appeler une autre fonction et envoyez-le un pointeur
certaines de vos donnes. Vous ne pouvez avoir un pointeur vers un registre, donc vous devez
stocker
dans une variable locale afin d'envoyer un pointeur vers elle.
Fondamentalement, ce que fait le programme est de commencer avec le nombre de base et stockez-
le deux comme
le multiplicateur (stock dans ebx %) et la valeur actuelle (stock dans - 4(%ebp)). Il galement
a la puissance stocke dans le registre ecx %, on multiplie ensuite continuellement la valeur actuelle
de
le multiplicateur, diminue la puissance et quitte la boucle si la puissance (dans % ecx) devient
jusqu' 1.
Maintenant, vous devriez tre capable de passer par le programme sans aide. Le seul
choses que vous devez savoir est qu'imull fait multiplication entier et
stocke le rsultat dans le deuxime oprande et decl diminue le registre donn par 1.
Pour plus d'informations sur ces questions et autres instructions, voir l'annexe B
Un bon projet d'essayer maintenant est d'tendre le programme, il retournera la valeur d'un
numro si la puissance est de 0 (hint, quoi que ce soit lev la puissance zro est 1). Garder
essayer. Si cela ne fonctionne pas dans un premier temps, essayez d'aller travers de votre
programme la main avec une
63
Chapitre 4. Tout sur les fonctions
chiffon de papier, suivi des o pointent % ebp et % esp, ce qui est sur le
pile, et quelles sont les valeurs dans chaque registre.
Fonctions rcursives
Le prochain programme s'tirera vos cerveaux encore plus. Le programme calculera
la factorielle d'un nombre. Une factorielle est le produit d'un nombre et tous les
nombres entre elle et l'autre. Par exemple, la factorielle de 7 est 7 * 6 * 5 * 4 * 3 * 2 * 1,
et la factorielle de 4 est 4 * 3 * 2 * 1. Maintenant, une chose, vous pouvez remarquer est que la
factorielle d'un nombre est le mme que le produit d'un nombre et de la factorielle juste
au-dessous de lui. Par exemple, la factorielle de 4 est 4 fois la factorielle de 3. La factorielle
de 3 est 3 fois la factorielle de 2. 2 est 2 fois la factorielle de 1. Est la factorielle de 1
1. ce type de dfinition est appel une dfinition rcursive. Cela signifie que la dfinition
de la fonction factorielle comprend la factoriels funtion lui-mme. Toutefois, tant donn que tous
fonctions doivent se terminer, une dfinition rcursive doit inclure un scnario de rfrence. La base
de
affaire est le point o la rcursivit s'arrte. Sans un scnario de rfrence, la fonction
pourrait durer ternellement, se faisant appeler jusqu' ce que finalement, il a couru hors de
l'espace de pile. Dans le
cas de la factorielle, le scnario de rfrence est le numro 1. Lorsque nous avons atteint le nombre
1, nous
n'excutez de nouveau la factorielle, nous disons juste que la factorielle de 1 est 1. Donc, nous allons
excuter
par le biais de ce que nous voulons le code pour ressembler notre fonction factorielle :
1. examiner le nombre
2. est le numro 1 ?
3. dans l'affirmative, la rponse est une
4. dans le cas contraire, la rponse est aux fois numros la factorielle du nombre moins
un
Cela poserait problme si nous n'avions pas les variables locales. Dans d'autres programmes,
stocker des valeurs dans les variables globales a bien fonctionn. Cependant, seulement des
variables globales
fournir une copie de chaque variable. Dans ce programme, nous aurons plusieurs copies
64
Chapitre 4. Tout sur les fonctions
de la fonction en cours d'excution en mme temps, chacun d'eux qui ont besoin de leurs propres
copies de
les donnes ! 6 tant donn que les variables locales existent sur le frame de pile et chaque appel de
fonction
obtient sa propre trame de pile, nous sont d'accord.
Regardons le code pour voir comment cela fonctionne :
#PURPOSE - reoit un numro, ce programme calcule le
factorielle #. Par exemple, la factorielle de
# 3 est 3 * 2 * 1 ou 6. La factorielle de
# 4 est 4 * 3 * 2 * 1, ou 24 et ainsi de suite.
#
#This programme montre comment appeler un fonction rcursive.
.data .section
Programme de #This n'a aucuns donnes globales
.section .text
.Globl _start
.Globl factorielle #this n'est pas ncessaire moins que nous voulons partager
#this fonction parmi d'autres programmes
_start :
pushl $4 #The factorielle prend un argument - la
#number, nous voulons une factorielle de l'argument. Alors, il
#gets pouss
#run factorielle du appeler la fonction factorielle
ADDL $4, % esp #Scrubs le paramtre qui a t pouss sur
#the pile
movl % eax, ebx %#factorial renvoie la rponse dans le _eax, mais
#we veux en % ebx envoyer sous forme de notre sortie
#status
6. par excution en mme temps , je veux parler du fait qu'on n'aura pas fini
avant une nouvelle activation. Je ne sous-entends pas que leurs instructions sont en cours
d'excution la
en mme temps.
65
Chapitre 4. Tout sur les fonctions
movl $1, % eax de #call le noyau sortie fonction
int 0 x 80 $
#This est la dfinition de la fonction relle
.type factorial,@function
factorielle :
pushl % ebp #standard trucs de fonction - il faut
#restore % ebp son tat antrieur avant
#returning, alors il faut pousser
movl % esp, ebp %#This est parce que nous ne voulons pas modifier
#the pointeur de pile, donc nous utilisons ebp %.
movl 8(%ebp), % eax #This dplace le premier argument %eax
#4(%ebp) contient l'adresse de retour, et
#8(%ebp) dtient le premier paramtre
CMPL $1, %EAX #If le nombre est 1, c'est notre base
#case et nous retourner simplement (1 est
#already dans %EAX comme valeur de retour)
Je end_factorial
decl % eax #otherwise, diminuer la valeur
pushl % eax #push il pour notre appel la factorielle
Appelez factorielle Factorielle #call
movl 8(%ebp), %EAX ebx #% a la valeur de retour, donc nous
#reload notre paramtre dans ebx %
imull % ebx, eax %#multiply que par le rsultat de la
#last appel factorielle (dans %EAX)
rponse de #the est stock dans % eax, qui
#is bon puisque c'est l retour
#values aller.
end_factorial :
movl % ebp, fonction esp #standard % retour trucs - nous
POPL % ebp #have restaurer % ebp et % esp l'endroit o
#they ont t avant la fonction dmarrage
RET #return la fonction (cela apparat le
66
Chapitre 4. Tout sur les fonctions
#return valeur, trop)
Assembler, relier et excutez-le avec ces commandes :
comme factorial.s -o factorial.o
factorielle de -o factorial.o LD
. / factorielle
echo $?
Cela devrait vous donner la valeur 24. 24 est la factorielle de 4, vous pouvez tester
vous-mme avec une calculatrice: 4 * 3 * 2 * 1 = 24.
Je devine que vous ne comprenais pas l'inscription de la totalit du code. Nous allons passer par l
un
ligne la fois de voir ce qui se passe.
_start :
pushl $4
Call factorielle
Bon, ce programme est destin calculer la factorielle du nombre 4. Quand
fonctions de programmation, vous tes cens pour mettre les paramtres de la fonction
le haut de la pile juste avant de vous appeler. N'oubliez pas, sont des paramtres de la fonction
les donnes que vous voulez que la fonction de travailler avec. Dans ce cas, la fonction factorielle
prend 1 paramtre - le numro que vous souhaitez la factorielle de.
L'instruction pushl met la valeur donne en haut de la pile. L'appel
instruction puis rend la fonction appeler.
Ensuite, nous avons ces lignes :
ADDL $4, % esp
movl % eax, ebx %
movl $1, % eax
67
Chapitre 4. Tout sur les fonctions
int 0 x 80 $
Ceci a lieu aprs que factorielle a termin et calculer la factorielle de 4 pour
nous. Maintenant, il faut nettoyer la pile. L'instruction addl dplace la pile
pointeur vers o il tait avant nous avons pouss le 4 $ dans la pile. Vous devriez
toujours nettoyer vos paramtres de pile aprs un appel de fonction.
L'instruction suivante dplace %EAX % ebx. Ce qui est dans %EAX ? C'est de la factorielle
valeur de retour. Dans notre cas, c'est la valeur de la fonction factorielle. Avec 4, comme notre
paramtre, 24 devrait tre notre valeur de retour. N'oubliez pas, retourner les valeurs sont toujours
stock dans % eax. Nous voulons revenir cette valeur comme le code d'tat l'exploitation
systme. Cependant, Linux ncessite que l'tat final du programme soient stocks dans ebx %,
pas % eax, alors il faut le dplacer. Ensuite, nous faisons l'appel systme de sortie standard.
La chose gentille au sujet des appels de fonction est celui :
Autres programmeurs ne doivent pas savoir quoi que ce soit leur sujet, sauf il a
arguments de les utiliser.
Ils fournissent des blocs de construction standardises d'o vous pouvez former un programme.
Ils peuvent tre appels plusieurs fois et plusieurs endroits et ils toujours
savoir comment revenir o ils taient depuis appel pousse l'adresse de retour
dans la pile.
Voici les principaux avantages des fonctions. Plus gros programmes utilisent galement des
fonctions
faire tomber les pices complexes du code en plus petits, les plus simples. En fait, presque tous
de programmation est crit et appeler des fonctions.
Prenons maintenant un regard sur comment la fonction factorielle lui-mme est mis en uvre.
Avant le dbut de la fonction, on obtient cette directive :
.type factorial,@function
factorielle :
68
Chapitre 4. Tout sur les fonctions
La directive .type raconte l'diteur de liens que factorielle est une fonction. Ce n'est pas vraiment
ncessaire moins que nous utilisions factorielle dans d'autres programmes. Nous l'avons inclus
par souci d'exhaustivit. La ligne qui indique la factorielle : donne la factorielle symbole
l'emplacement de stockage de l'instruction suivante. Voil comment appel savait o aller
Quand nous l'avons dit appel factorielle.
Les premires instructions relles de la fonction sont :
pushl % ebp
movl % esp, ebp %
Comme indiqu dans le programme prcdent, cela cre le frame de pile pour cette fonction.
Ces deux lignes sera la faon dont vous devriez commencer toutes les fonctions.
L'instruction suivante est la suivante :
movl 8(%ebp), eax %
Cet exemple utilise base pointeur s'adressant pour dplacer le premier paramtre de la fonction en
% eax. N'oubliez pas, (%EBP) a la vieille % ebp, 4(%ebp) a l'adresse de retour, et
8(%EBP) est l'emplacement du premier paramtre la fonction. Si vous pensez revenir,
ce sera la valeur 4 lors du premier appel, puisque c'tait l ce qui nous a pouss sur la pile
avant d'appeler la fonction (avec pushl $4). paramtre dans %EAX. Comme cela
fonction s'appelle elle-mme, elle aura des autres valeurs, trop.
Ensuite, nous vrifions pour voir si nous avons touch notre scnario de rfrence (un paramtre de
1). Dans l'affirmative, on saute
dans l'instruction l'end_factorial de l'tiquette, o il sera retourn. De et
dans % eax dont nous avons parls est dj o vous mettez les valeurs de retour. Que
s'effectue par ces lignes :
CMPL 1 $ % eax
Je end_factorial
Si elle n'est pas notre scnario de rfrence, que nous avons dit que nous ferions ? Nous appelons la
fonction factorielle avec notre paramtre moins un. Alors, tout d'abord, nous rduisons
%EAX par un :
69
Chapitre 4. Tout sur les fonctions
decl %EAX
decl est synonyme de dcrmentation. Il soustrait 1 la mmoire ou un registre donn
emplacement (%EAX dans notre cas). incl est l'inverse : il ajoute 1. Aprs la dcrmentation
% eax nous pousser dans la pile car il va tre le paramtre de la prochaine
appel de fonction. Et puis nous appelons factorielle nouveau !
pushl % eax
Call factorielle
Bon, maintenant nous avons appel factoriel. Une chose retenir est que, aprs un
fonction appel, nous ne pouvons jamais savoir ce que les registres sont (sauf % ebp esp et %).
Mme si nous avions la valeur que nous avons t appels avec dans %EAX, n'est pas l tout
plus. Par consquent, nous devons retirer la pile d'au mme endroit que nous l'avons eu le
premire fois ( 8(%ebp)). Nous avons donc, procdez comme suit :
movl 8(%ebp), ebx %
Maintenant, nous voulons multiplier ce nombre par le rsultat de la fonction factorielle. If
vous vous souvenez de notre discussion prcdente, le rsultat des fonctions demeurent %
eax. Alors,
Nous devons multiplier ebx % avec % eax. Cela se fait avec cette instruction :
imull % ebx, eax %
Cela aussi stocke le rsultat dans %EAX, qui est exactement l o nous voulons le retour
valeur de la fonction d'tre ! tant donn que la valeur de retour est en place, que nous avons juste
besoin de quitter
la fonction. Si vous vous souvenez, au dbut de la fonction, nous avons pouss % ebp, et
dplac % esp en % ebp pour crer le frame de pile actuel. Maintenant, nous avons invers le
opration pour dtruire le frame de pile actuel et ractiver un dernier :
end_factorial :
movl % ebp, % esp
POPL % ebp
Maintenant nous sommes dj de retour, alors nous crivez la commande ci-dessous
70
Chapitre 4. Tout sur les fonctions
RET
Cette pop de la valeur de la pile et puis saute elle. Si vous n'oubliez pas notre
discussion sur appel, nous a dit que l'appel pouss tout d'abord l'adresse de la prochaine
instruction dans la pile avant il a saut au dbut de la fonction. Alors,
ici nous pop il marche arrire afin que nous puissions y retourner. La fonction s'effectue, et nous
avons
notre rponse !
Comme notre programme prcdent, vous devriez regarder par-dessus le programme nouveau et
faire
bien sr, vous savez ce que tout fait. Regarder en arrire par l'intermdiaire de cette section et la
les sections prcdentes pour l'explication de tout ce que vous ne comprenez pas. Ensuite, prendre
un morceau de papier et passez en revue le programme tape par tape, ce que le suivi des
les valeurs des registres sont chaque tape, et quelles sont les valeurs dans la pile. Faisant
Cela devrait approfondir votre comprhension de ce qui se passe.
Examen
Connatre les Concepts
Quels sont les primitives ?
Ce que demandent les conventions ?
Quelle est la pile ?
Comment pushl et popl affectent-ils la pile ? Quel Registre spciales
elles touchent ?
Quelles sont les variables locales et quoi servent ils ?
Pourquoi les variables locales si ncessaire dans les fonctions rcursives ?
Quels sont les % et % ebp esp destin ?
Ce qui est un frame de pile ?
71
Chapitre 4. Tout sur les fonctions
Utiliser les Concepts
crire une fonction appele carr qui reoit un argument et retourne le
la place de l'argument.
crire un programme pour tester votre fonction carre.
Convertir le programme maximal indique dans la Section intitule trouver un Maximum
Valeur au chapitre 3, alors que c'est une fonction qui prend un pointeur plusieurs valeurs
et retourne leur maximum. crire un programme qui appelle maximal avec 3
diffrentes listes et retourne le rsultat de cette dernire comme tat de sortie du programme
code.
Expliquer les problmes qui se poseraient en absence d'une norme de convention d'appel.
Aller plus loin
Pensez-vous que c'est mieux pour un systme d'avoir un grand nombre de primitives ou un petit
un, en supposant que le plus grand ensemble peut tre crites en termes de celui plus petit ?
La fonction factorielle peut tre crit de manire non rcursive. Le faire.
Trouver une application sur l'ordinateur que vous utilisez rgulirement. Essayez de localiser un
spcifique
fonctionnalit et pratique briser cette fonctionnalit dehors en fonctions. Dfinir la
fonction des interfaces entre cette fonction et dans le reste du programme.
Proposer votre propre convention d'appel. Rcrire les programmes dans ce
chapitre de l'utiliser. Un exemple d'une convention d'appel diffrente serait passer
paramtre dans les registres plutt que sur la pile, de les transfrer dans un ordre diffrent,
valeurs de retour dans d'autres registres ou les emplacements de mmoire. Tout ce que vous
chercher, tre
cohrente et l'appliquer tout au long de l'ensemble du programme.
Pouvez-vous construire une convention d'appel sans utiliser la pile ? Quelles limites
il aurait ?
72
Chapitre 4. Tout sur les fonctions
Quels scnarios de test faut-il utiliser dans notre exemple de programme pour vrifier si elle est
fonctionne correctement ?
73
Chapitre 4. Tout sur les fonctions
74
Chapitre 5. Traitant des fichiers
Beaucoup de programmation informatique traite les fichiers. Aprs tout, quand nous redmarrer
notre
ordinateurs, la seule chose qui reste lors de sessions antrieures sont les choses qui
ont t mis sur le disque. Les donnes qui sont stockes dans les fichiers sont appeles donnes
persistantes,
parce qu'il persiste dans les fichiers qui restent sur le disque, mme si le programme n'est pas
en cours d'excution...
La notion de fichier UNIX
Chaque systme d'exploitation a sa propre faon de traiter les fichiers. Toutefois, l'UNIX
mthode qui est utilise sur Linux, est le plus simple et le plus universel. Fichiers UNIX,
n'importe quel programme les a crs, tous sont accessibles sous forme de flux squentiel
d'octets. Lorsque vous accdez un fichier, vous dmarrez en l'ouvrant par nom. Le fonctionnement
systme vous donne alors un numro, appel un descripteur de fichier, ce qui vous permet de
consulter
le fichier jusqu' ce que vous avez fini avec elle. Vous pouvez ensuite lire et crire dans le fichier
l'aide
son descripteur de fichier. Lorsque vous avez termin la lecture et l'criture, vous fermez le fichier,
alors ce qui rend le descripteur de fichier inutilisables.
Dans nos programmes, nous traiterons des fichiers de la manire suivante :
1. dire Linux le nom du fichier ouvrir, et dans ce mode, vous voulez qu'il a ouvert
(lecture, criture, aussi bien lire et crire, crer s'il n'existe pas, etc..). Il s'agit
gr avec l'appel systme ouvert, qui prend un nom de fichier, un certain nombre
qui reprsente le mode et un jeu comme paramtres d'autorisations. %EAX tiendra
le numro d'appel systme, qui est 5. L'adresse du premier caractre de la
nom de fichier doit tre stock dans % ebx. Les intentions de lecture/criture, reprsent comme un
numro, doit tre conserv dans le registre ecx %. Pour l'instant, utilisez 0 pour les fichiers que vous
souhaitez lire
depuis et 03101 pour vous souhaitez crire dans des fichiers (vous devez inclure les principales
zro). 1 Enfin, le jeu d'autorisations doit tre stock sous forme de numro dans % edx. If
1. cela sera expliqu plus en dtail dans la Section intitule la vrit, le mensonge et binaire
Nombres chapitre 10.
75
Chapitre 5. Traitant des fichiers
vous n'tes pas familier avec les permissions UNIX, il suffit d'utiliser pour les permissions 0666
(encore une fois, vous devez inclure le zro non significatif).
2. Linux renverra ensuite vous un descripteur de fichier en % eax. N'oubliez pas, il s'agit d'un
numro que vous utilisez pour faire rfrence ce fichier tout au long de votre programme.
3. ensuite vous allez oprer sur le fichier, faire des lectures ou critures, chaque fois donnent
Linux le descripteur de fichier que vous souhaitez utiliser. lire est un appel systme 3 et l'appeler
vous devez avoir le descripteur de fichier en % ebx, l'adresse d'une mmoire tampon pour le
stockage
les donnes lues dans ecx % et la taille de la mmoire tampon dans % edx. Tampons sera
expliqu dans la Section intitule les mmoires tampons et .bss. lecture retournera avec soit
le nombre de caractres lus depuis le fichier, ou un code d'erreur. Codes d'erreur peuvent
tre distingues car elles sont toujours des nombres ngatifs (plus d'informations
sur des nombres ngatifs se trouvent dans le chapitre 10). crire est un appel systme 4, et
elle ncessite les mmes paramtres que le systme de lecture appel, sauf que la mmoire tampon
doit dj tre rempli avec les donnes crire. L'appel systme d'criture sera
rendez le nombre d'octets crits dans %EAX ou un code d'erreur.
4. Lorsque vous avez termin avec vos fichiers, vous pouvez alors dire Linux pour les fermer.
Par la suite, votre descripteur de fichier n'est plus valide. Cela se fait l'aide de proches,
appel systme 6. Le seul paramtre de fermeture est le descripteur de fichier, qui est
plac dans ebx %
Tampons et .bss
Dans la section prcdente, nous avons mentionn tampons sans expliquer ce qu'ils taient.
Un tampon est un bloc continu d'octets utiliss pour transfrer des donnes en bloc. Lorsque vous
demander lire un fichier, le systme d'exploitation doit avoir un endroit pour stocker les donnes il
lectures. Cet endroit s'appelle une mmoire tampon. Habituellement les tampons servent
uniquement stocker des donnes
temporairement, et il est ensuite lire les mmoires tampons et converti en une forme qui est
plus facile pour les programmes grer. Nos programmes ne sera pas assez compliqus
besoin aprs cela. Pour obtenir un exemple, disons que vous voulez lire en une seule ligne de
texte partir d'un fichier, mais vous ne sais pas combien de temps est de cette ligne. Vous serait
alors tout simplement
76
Chapitre 5. Traitant des fichiers
lire un grand nombre d'octets/caractres du fichier dans un tampon, recherchez le
fin de la ligne de caractres, puis copiez tous les personnages sur ce caractre de fin de ligne
un autre emplacement. Si vous n'a pas trouv et le caractre de fin de ligne, vous attribuerait
un autre tampon et continuer la lecture. Vous se retrouveraient probablement avec certains
personnages en survolant dans votre tampon dans ce cas, que vous utiliserez comme dpart
moment o vous devez ensuite les donnes du fichier. 2
Une autre chose noter est que les tampons sont de taille fixe, dfinie par le programmeur. Donc, si
vous voulez lire dans 500 octets de donnes un moment, vous envoyez l'appel systme lire la
adresse d'un emplacement de 500 octets inutilis et envoyez-le au nombre de 500, afin qu'il sache
comment
elle est grande. Vous pouvez le faire plus petit ou plus grand, selon les besoins de votre application.
Pour crer un tampon, vous devez rserver soit stockage statique ou dynamique. Statique
stockage est ce que nous avons parl jusqu'ici, les emplacements de stockage dclars l'aide
directives .long ou .byte. Nous le verrons dans la Section stockage dynamique
appel obtenant plus mmoire au chapitre 9. Il y a des problmes, cependant, avec
dclarant tampons l'aide de .byte. Tout d'abord, il est fastidieux taper. Vous devez taper
500 numros aprs que la dclaration de .byte et ils ne serait pas servir autre chose
mais pour occuper l'espace. Deuximement, il utilise l'espace dans le fichier excutable. Dans les
exemples
Nous avons utilis jusqu' prsent, il n'utilise pas trop vers le haut, mais cela peut changer en plus
grand
programmes. Si vous voulez 500 octets il faut taper dans les 500 numros et il gaspille
500 octets dans le fichier excutable. Il y a une solution ces deux. Jusqu'ici, nous avons
discut des deux sections du programme, le .text et les sections .data. Il y a
une autre section appele la .bss. Cette section est comme la section de donnes, sauf qu'il
ne prend pas de place dans l'excutable. Cette section peut rserver de stockage, mais il
Impossible d'initialiser il. Dans la section .data, vous pourriez rserver stockage et affectez-lui une
valeur initiale. Dans la section .bss, vous ne pouvez pas dfinir une valeur initiale. Ceci est utile pour
tampons parce que nous n'avez pas besoin pour les initialiser en tout cas, nous avons juste besoin de
rserver
stockage. Pour ce faire, nous faisons les commandes suivantes :
.section .bss
2. tout cela parat compliqu, la plupart du temps en programmation, vous n'aurez pas besoin de
traiter directement avec les tampons et les descripteurs de fichiers. Dans le chapitre 8, vous
apprendrez comment utiliser existant
code prsent sous Linux pour grer la plupart des complications du fichier d'entre/sortie pour vous.
77
Chapitre 5. Traitant des fichiers
.LComm my_buffer, 500
Cette directive, .lcomm, va crer un symbole, my_buffer, qui fait rfrence un
emplacement de stockage de 500 octets, nous pouvons utiliser comme un tampon. Nous pouvons
alors faire la
suivant, en supposant que nous avez ouvert un fichier pour la lecture et ont plac le fichier
descripteur dans ebx % :
movl $my_buffer, ecx %
movl 500, % edx
movl 3, % eax
int 0 x 80 $
Il indiquera jusqu' 500 octets dans le tampon. Dans cet exemple, j'ai plac un dollar
signe en face de my_buffer. N'oubliez pas que la raison en est que, sans le
signe de dollar, my_buffer est considr comme un emplacement de mmoire et est accessible en
direct
mode d'adressage. Le signe dollar il passe au mode immdiat s'adressant,
qui charge effectivement le nombre reprsent par my_buffer (c.--d. - l'adresse de
le dbut de notre tampon). (qui est l'adresse de my_buffer) dans le registre ecx %.
Fichiers standards et spciaux
Vous pourriez penser que les programmes dmarrer sans les fichiers ouverts par dfaut. Ce n'est pas
valeur true. Linux programmes ont gnralement au moins trois descripteurs de fichiers ouverts
quand ils
commencer. Ils sont :
STDIN
Il s'agit de l'entre standard. C'est un fichier en lecture seule et reprsente habituellement votre
clavier. 3 c'est toujours le descripteur de fichier 0.
3. comme nous l'avons mentionn plus tt, sous Linux, presque tout est un dossier . L'entre de
votre clavier est
considr comme un fichier, et est donc de votre cran.
78
Chapitre 5. Traitant des fichiers
STDOUT
Il s'agit de la sortie standard. C'est un fichier en criture seule et reprsente habituellement votre
affichage l'cran. C'est toujours le descripteur de fichier 1.
STDERR
Il s'agit de votre erreur standard. C'est un fichier en criture seule et reprsente habituellement
votre
affichage l'cran. Sortie de traitement plus rgulire va STDOUT, mais toute erreur
les messages qui surgissent dans le processus aller vers STDERR.De cette faon, si vous le souhaitez,
vous pouvez fractionner leur dans des endroits spars. C'est toujours le descripteur de fichier 2.
Un de ces fichiers peuvent tre Redirig depuis ou vers un fichier rel, plutt que sur un cran ou
un clavier. C'est en dehors de la porte de cet ouvrage, mais un bon livre sur UNIX
ligne de commande il dcrira en dtail. Le programme lui-mme n'a mme pas besoin de
Soyez au courant de cette indirection - il peut juste utiliser les descripteurs de fichier standard
comme d'habitude.
Notez que nombreux fichiers que vous crire ne sont pas les fichiers du tout. Bas sur UNIX
fonctionnant
systmes de traitent tous les systmes d'entre/sortie sous forme de fichiers. Connexions rseau
sont traites comme des
fichiers, votre port srie est trait comme un fichier, mme vos appareils audio sont traits comme
des
fichiers. Communication entre processus se faite gnralement par le biais de fichiers spciaux
appel pipes. Certains de ces fichiers ont des mthodes diffrentes de l'ouverture et la cration
eux que des fichiers normaux (c'est--dire - ils n'utilisent l'appel systme ouvert), mais ils peuvent
tous
lire et tre crit l'aide de la lecture standard et les appels de systme d'criture.
l'aide de fichiers dans un programme
Nous allons crire un programme simple pour illustrer ces concepts. Le programme
mnera deux fichiers et lire un, toutes ses lettres minuscules convertir
majuscules et crire dans l'autre fichier. Avant que nous le faisons, nous allons rflchir ce que
nous
il fallait faire pour faire le travail :
Ont une fonction qui prend un bloc de mmoire et le convertit en majuscules.
Cette fonction aurait besoin d'une adresse d'un bloc de mmoire et de sa taille comme
79
Chapitre 5. Traitant des fichiers
paramtres.
Avoir une section de code que les lectures dans vers une mmoire tampon, appelle plusieurs
reprises notre conversion
fonction sur le tampon, puis crit le tampon rcrirait l'autre fichier.
Commencez le programme en ouvrant les fichiers ncessaires.
Notez que j'ai spcifi des choses dans l'ordre inverse qu'elles seront fera. C'est un
truc utile dans l'criture des programmes complexes - tout d'abord dcider de la viande de ce que
l'on
fait. Dans ce cas, il se convertit en blocs de caractres en majuscules. Puis, vous
Pensez ce que tous les besoins d'tre installer et traitement pour obtenir que cela se
produise. Dans le prsent
cas, vous devez ouvrir les fichiers et sans cesse de lire et d'crire des blocs sur le disque. L'un des
les touches de programmation est continuellement faire tomber les problmes en plus petits et
petits morceaux jusqu' ce qu'il est assez petit pour que vous pouvez facilement rsoudre le
problme. Puis
vous pouvez crer ces morceaux de retour jusqu' ce que vous avez un programme de travail. 4
Vous avez t pensez que vous vous en souviendrez jamais tous ces nombres
leve vous - les numros d'appel systme, le numro d'interruption, etc.. Dans le prsent
Nous allons aussi introduire une nouvelle .equ de la directive, qui devrait aider le programme.
.EQU vous permet d'assigner des noms aux nombres. Par exemple, si vous avez fait .equ
LINUX_SYSCALL, 0 x 80, tout moment aprs que vous avez crit LINUX_SYSCALL, le
assembleur serait remplacer 0 x 80 pour cela. Alors maintenant, vous pouvez crire
int $LINUX_SYSCALL
qui est beaucoup plus facile lire et beaucoup plus facile retenir. Le codage est complexe,
mais il y a beaucoup de choses que nous pouvons faire comme a pour le rendre plus facile.
Voici le programme. Notez que nous n'avons plus d'tiquettes que nous utilisons rellement pour
sauts, parce que certains d'entre eux sont juste l pour plus de clart. Essayez de la trace travers la
programme et voir ce qui se passe dans diffrents cas. Une explication approfondie de la
programme suivra.
#PURPOSE : Ce programme convertit un fichier d'entre
De 4. Maureen Sprankle rsolution de problmes et les Concepts de programmation est un excellent
livre
sur le processus de rsolution de problmes appliqu la programmation informatique.
80
Chapitre 5. Traitant des fichiers
# pour un fichier de sortie avec toutes les lettres
# convertis en majuscules.
#
#PROCESSING: 1) ouvrir le fichier d'entre
# 2) Ouvrir le fichier de sortie
# 4) alors que nous ne sommes pas la fin du fichier d'entre
# un) lire la partie du fichier dans notre mmoire tampon
# b) traverser chaque octet de mmoire
# Si l'octet est une lettre minuscule,
# il convertir en majuscules
# c) crire la mmoire tampon dans le fichier de sortie
.data .section
### #CONSTANTS ###
numros d'appel #system
.EQU SYS_OPEN, 5
.EQU SYS_WRITE, 4
.EQU SYS_READ, 3
.EQU SYS_CLOSE, 6
.EQU SYS_EXIT, 1
#options pour ouvrir (Regardez
#/usr/include/asm/fcntl.h pour
#various valeurs. Vous pouvez les combiner
#by ajout d'eux ou ORing eux)
#This est discute plus longuement
#in comptage comme un ordinateur
.EQU O_RDONLY, 0
.EQU O_CREAT_WRONLY_TRUNC, 03101
descripteurs de fichiers #standard
.eQu STDIN, 0
.EQU STDOUT, 1
81
Chapitre 5. Traitant des fichiers
.EQU STDERR, 2
#system appel interruption
.EQU LINUX_SYSCALL, 0 x 80
.EQU END_OF_FILE, #This 0 est la valeur de retour
#of lire ce qui signifie que nous avons
#hit la fin du fichier
.EQU NUMBER_ARGUMENTS, 2
.section .bss
#Buffer - c'est o les donnes sont charges dans
# le fichier de donnes et crit partir de
# dans le fichier de sortie. Cela devrait
# jamais excder 16 000 pour diverses
raisons de #.
.EQU BUFFER_SIZE, 500
.LComm BUFFER_DATA, BUFFER_SIZE
.section .text
POSTES #STACK
.EQU ST_SIZE_RESERVE, 8
.EQU ST_FD_IN, -4
.EQU ST_FD_OUT, -8
.EQU ST_ARGC, 0 #Number d'arguments
.EQU ST_ARGV_0, 4 #Name de programme
.EQU ST_ARGV_1, 8 #Input nom de fichier
.EQU ST_ARGV_2, nom de fichier #Output 12
.Globl _start
_start :
## #INITIALIZE PROGRAMME ###
#save le pointeur de pile
82
Chapitre 5. Traitant des fichiers
movl % esp, ebp %
#Allocate espace pour nos descripteurs de fichier
#on la pile
Subl $ST_SIZE_RESERVE, % esp
open_files :
open_fd_in :
FICHIER D'ENTRE #OPEN ## ###
#open syscall
movl $SYS_OPEN, eax %
nom de fichier #input dans % ebx
movl ST_ARGV_1(%ebp), ebx %
#read-pavillon seulement
movl $O_RDONLY, ecx %
#this n'a aucune importance pour la lecture
movl $0666, % edx
#call Linux
int $LINUX_SYSCALL
store_fd_in :
#save le descripteur de fichier
movl % eax, ST_FD_IN(%ebp)
open_fd_out :
FICHIER DE SORTIE #OPEN ## ###
#open le fichier
movl $SYS_OPEN, eax %
nom de fichier #output dans % ebx
movl ST_ARGV_2(%ebp), ebx %
#flags pour l'criture dans le fichier
movl $O_CREAT_WRONLY_TRUNC, ecx %
#mode pour le nouveau fichier (si elle est cre)
movl $0666, % edx
#call Linux
83
Chapitre 5. Traitant des fichiers
int $LINUX_SYSCALL
store_fd_out :
#store le descripteur de fichier ici
movl % eax, ST_FD_OUT(%ebp)
BOUCLE DE MAIN #BEGIN ## ###
read_loop_begin :
## #READ DANS UNE PT DE MAISONS DE LA FILE D'ENTRE ###
movl $SYS_READ, eax %
#get le descripteur de fichier d'entre
movl ST_FD_IN(%ebp), ebx %
#the emplacement pour lire dans
movl $BUFFER_DATA, ecx %
#the taille du tampon
movl $BUFFER_SIZE, % edx
#Size de mmoire tampon de lecture est retourn dans %EAX
int $LINUX_SYSCALL
## #EXIT SI NOUS AVONS ATTEINT LA FIN ###
#check pour le marqueur de fin de fichier
CMPL $END_OF_FILE, eax %
#if trouv ou en cas d'erreur, aller jusqu'au bout
jle end_loop
continue_read_loop :
## #CONVERT LE BLOC MAJUSCULES ###
pushl $BUFFER_DATA #location de tampon
pushl % eax #size du tampon
appel convert_to_upper
POPL %EAX #get au dos de la taille
ADDL $4, esp #restore % esp
## #WRITE LE BLOC DEHORS LA SORTIE FICHIER ###
84
Chapitre 5. Traitant des fichiers
#size de la mmoire tampon
movl % eax, edx %
movl $SYS_WRITE, eax %
#file utiliser
movl ST_FD_OUT(%ebp), ebx %
#location du tampon
movl $BUFFER_DATA, ecx %
int $LINUX_SYSCALL
## #CONTINUE LA BOUCLE ###
JMP read_loop_begin
end_loop :
## #CLOSE LES FICHIERS ###
#NOTE - nous n'avez pas besoin de faire la vrification des erreurs
# sur ceux-ci, car conditions d'erreur
# ne pas signifier quelque chose de spcial ici
movl $SYS_CLOSE, eax %
movl ST_FD_OUT(%ebp), ebx %
int $LINUX_SYSCALL
movl $SYS_CLOSE, eax %
movl ST_FD_IN(%ebp), ebx %
int $LINUX_SYSCALL
### #EXIT ###
movl $SYS_EXIT, eax %
movl $0, % ebx
int $LINUX_SYSCALL
#PURPOSE : Cette fonction ne fait la
conversion # en majuscules pour un bloc
#
#INPUT : Le premier paramtre est l'emplacement
85
Chapitre 5. Traitant des fichiers
# du bloc de mmoire pour convertir
# Le second paramtre est la longueur de
# que la mmoire tampon
#
#OUTPUT : Cette fonction remplace l'actuel
# mmoire tampon avec la version haute-casified.
#
#VARIABLES :
# % eax - dbut du tampon
# % ebx - longueur du tampon
# % edi - offset de mmoire tampon courant
# % cl - byte actuel en cours d'examen
# (premire partie d'ecx %)
#
## #CONSTANTS ##
#The la limite infrieure de notre recherche
.EQU LOWERCASE_A, a
#The limite suprieure de notre recherche
.EQU LOWERCASE_Z, z
#Conversion entre majuscules et minuscules
.EQU UPPER_CONVERSION, A - a
## #STACK STUFF ###
.EQU ST_BUFFER_LEN, 8 #Length de mmoire tampon
.EQU ST_BUFFER, 12 #actual tampon
convert_to_upper :
pushl % ebp
movl % esp, ebp %
## #SET UP VARIABLES ###
movl ST_BUFFER(%ebp), eax %
movl ST_BUFFER_LEN(%ebp), ebx %
movl $0, % edi
86
Chapitre 5. Traitant des fichiers
#if un tampon avec une longueur nulle a t donn
#to nous, il suffit de laisser
CMPL $0, % ebx
Je end_convert_loop
convert_loop :
#get l'octet courant
movb (%EAX, % edi, 1), % cl
#go l'octet suivant moins qu'il n'entre
# a et z
CMPB $LOWERCASE_A, % cl
Jl next_byte
CMPB $LOWERCASE_Z, % cl
JG next_byte
#otherwise convertit l'octet en majuscules
addb $UPPER_CONVERSION, % cl
#and stockez-le retour
movb % cl, (%EAX, % edi, 1)
next_byte :
incl % edi #next octets
CMPL % edi, ebx %#continue moins que
#we avons atteint les
#end
JNE convert_loop
end_convert_loop :
valeur de retour #no, il suffit de laisser
movl % ebp, % esp
POPL % ebp
RET
Tapez dans ce programme comme toupper.s et puis entrez les commandes suivantes :
87
Chapitre 5. Traitant des fichiers
comme toupper.s -o toupper.o
LD toupper.o -o toupper
Cela gnre un programme appel toupper, qui convertit toutes les minuscules
caractres dans un fichier en majuscule. Par exemple, pour convertir le fichier toupper.s
majuscules, tapez la commande suivante :
. / toupper toupper.s toupper.uppercase
Vous trouverez dans le fichier toupper.uppercase une version en majuscules de votre
fichier d'origine.
Examinons comment fonctionne le programme.
La premire partie du programme est marque constantes. En programmation, un
constante est une valeur qui est assigne lorsqu'un programme assemble ou compile et est
n'a jamais chang. J'ai pour habitude de toutes mes constantes mise la
dbut du programme. Il suffit de les dclarer avant d'utiliser
eux, mais mettre leur tout au dbut les rend faciles trouver. Ce qui les rend
toutes les majuscules rend vident dans votre programme, quelles valeurs sont constantes et
o les trouver. 5 en langage assembleur, nous dclarons constantes avec le
.EQU directive comme mentionn prcdemment. Ici, nous donnons simplement des noms tous
les
numros standards, nous avons utilis jusqu' prsent, comme les numros d'appel systme, le
syscall interrompre
nombre et les options d'ouverture de fichier.
La section suivante est marque de tampons. Nous utilisons seulement une mmoire tampon dans
ce programme,
que nous appelons BUFFER_DATA. Nous dfinissons galement une constante, BUFFER_SIZE, qui
contient la taille de la mmoire tampon. Si nous nous rfrons toujours cette constante plutt que
de taper
le nombre de 500, chaque fois que nous avons besoin d'utiliser la taille de la mmoire tampon, si elle
a plus tard
changements, nous avons seulement besoin de modifier cette valeur, plutt que de devoir passer
par la
programme complet et toutes les valeurs changer individuellement.
Au lieu d'aller la la section _start du programme, aller jusqu'au bout o
Nous dfinissons la fonction convert_to_upper. C'est la partie qui fait rellement la
5. il s'agit d'une pratique assez classique chez les programmeurs dans toutes les langues.
88
Chapitre 5. Traitant des fichiers
conversion.
Cette section commence par une liste de constantes que nous allons utiliser la raison pour laquelle
que ce sont
Mettez ici plutt que d'en haut est qu'ils traitent uniquement de cette une fonction. Nous
sont dfinis comme suit :
.EQU LOWERCASE_A, a
.EQU LOWERCASE_Z, z
.EQU UPPER_CONVERSION, A - a
Les deux premiers dfinissent simplement les lettres qui sont les limites de ce que nous sommes
vous cherchez. N'oubliez pas que dans l'ordinateur, les lettres sont reprsentes sous forme de
nombres.
Par consquent, nous pouvons utiliser LOWERCASE_A dans les comparaisons, des additions, des
soustractions, ou
autre chose, nous pouvons utiliser les numros en. Notez galement, Qu'on dfinit la constante
UPPER_CONVERSION. tant donn que les lettres sont reprsentes sous forme de nombres, nous
pouvons soustraire
eux. En soustrayant une lettre majuscule de la lettre minuscule mme nous donne
combien nous avons besoin d'ajouter une lettre minuscule pour le rendre haut de casse. Si cette
n'est pas sens, regardez les tableaux de codes ASCII eux-mmes (voir l'annexe D).
Vous remarquerez que le nombre pour le caractre A est 65 et le caractre une est 97.
Le facteur de conversion est alors -32. Pour n'importe quelle lettre minuscule si vous ajoutez -32,
vous aurez
obtenir son capital quivalent.
Aprs cela, nous avons quelques constantes tiquets pile POSITIONS. N'oubliez pas que
paramtres de fonction sont push dans la pile avant les appels de fonction. Ces
constantes (prcdes ST pour plus de clart) dfinissent o nous devrions attendre dans la pile
pour trouver chaque lment de donnes. L'adresse de retour est la position 4 + % esp, la longueur
de
le tampon est la position 8 + % esp, ainsi que l'adresse de la mmoire tampon est la position 12 +
% esp. L'utilisation de symboles pour ces numros au lieu des chiffres eux-mmes
Il est plus facile de voir quelles donnes sont utiliss et dplac.
Vient ensuite l'tiquette convert_to_upper. C'est le point d'entre de la fonction.
Les deux premires lignes sont nos lignes de fonction standard pour enregistrer le pointeur de
pile. Le
ensuite deux lignes
movl ST_BUFFER(%ebp), eax %
89
Chapitre 5. Traitant des fichiers
movl ST_BUFFER_LEN(%ebp), ebx %
dplacer les paramtres de la fonction dans les registres appropris utiliser. Ensuite, nous
chargeons
zro en % edi. Ce que nous allons faire est de parcourir chaque octet de la mmoire tampon
par chargement partir de l'emplacement % eax + % edi, incrmentation % edi et rpter
jusqu' ce que l'edi % est gale la longueur du tampon stocke dans % ebx. Les lignes
CMPL $0, % ebx
Je end_convert_loop
sont juste une vrification de la sant mentale pour s'assurer que personne ne nous a donn une
mmoire tampon de taille nulle. If
ils l'ont fait, nous venons d'assainir et de quitter. Se prmunir contre l'utilisateur potentiel et
Erreurs de programmation est une tche importante d'un programmeur. Vous pouvez toujours
spcifier
que votre fonction ne devrait pas prendre un tampon de taille nulle, mais c'est encore mieux d'avoir
la fonction vrifier et avoir un plan de sortie fiable si a arrive.
Maintenant, nous commenons notre boucle. Tout d'abord, il dplace un octet dans % cl. Le code
c'est
movb (%EAX, % edi, 1), % cl
Il utilise un mode d'adressage indirect index. Il est dit de commencer % eax et aller
% edi emplacements avant, avec chaque emplacement tant gros 1 octet. Il prend la valeur
qui s'y trouvent et le mettre dans % cl. Aprs cela, il vrifie pour voir si cette valeur est dans le
gamme de minuscules un z en minuscules. Pour vrifier la gamme, il vrifie tout simplement pour
voir
Si la lettre est infrieure un. Si c'est le cas, il ne peut pas tre une lettre minuscule. De mme, si
c'est
il ne peut pas tre plus grand que z, une lettre minuscule. Ainsi, dans chacun de ces cas, il tout
simplement
se dplace. Si c'est dans la plage correcte, il ajoute ensuite la conversion en majuscules, et
il stocke dans la mmoire tampon.
Quoi qu'il en soit, il va ensuite la valeur suivante en incrmentant % cl;. Ensuite, il vrifie
voir si nous sommes la fin de la mmoire tampon. Si nous ne sommes pas la fin, on saute vers le
dbut de la boucle (label convert_loop). Si nous sommes la fin, il tout simplement
continue jusqu' la fin de la fonction. Parce que nous sommes modifiant la mmoire tampon
directement, nous n'avez pas besoin de quoi que ce soit retourner au programme appelant - les
modifications sont
90
Chapitre 5. Traitant des fichiers
dj dans la mmoire tampon. L'end_convert_loop de l'tiquette n'est pas ncessaire, mais il est l
Il est donc facile de voir o sont les parties du programme.
Maintenant, nous savons comment fonctionne le processus de conversion. Maintenant nous avons
besoin de comprendre comment
pour obtenir les donnes et les fichiers.
Avant de lire et crire les fichiers, nous devons ouvrir eux. Le systme ouvert UNIX
appel, c'est ce qui gre cela. Il prend les paramtres suivants :
%EAX contienne l'appel systme numro comme d'habitude - 5 dans ce cas.
% ebx contient un pointeur vers une chane qui reprsente le nom du fichier ouvrir. Le
chane doit se terminer par le caractre null.
% ecx contient les options utilises pour ouvrir le fichier. Ces dire Linux comment
ouvrir le fichier. Ils peuvent indiquer des choses tels qu'ouvert pour la lecture, ouvert la
criture, ouvrir pour lire et crire, crer, s'il n'existe pas, supprimez le fichier si
dj, il existe, etc.. Nous n'entrerons pas dans la cration les numros pour la
options jusqu' la Section appele vrit, le mensonge et les nombres binaires dans
Chapitre 10. Pour l'instant, juste faire confiance les nombres que nous nous heurtons.
% edx contienne les autorisations qui sont utilises pour ouvrir le fichier. Elle est utilise dans
cas le fichier doit tre cr tout d'abord, pour Linux sache quelles sont les autorisations pour crer
le fichier avec. Ils sont exprims en octal, tout comme les permissions UNIX ordinaires. 6
Aprs avoir fait l'appel systme, le descripteur de fichier du fichier rcemment ouvert est stock
dans % eax.
Alors, quels sont les fichiers nous ouvrons ? Dans cet exemple, nous allons ouvrir les fichiers
spcifie sur la ligne de commande. Heureusement, les paramtres de ligne de commande existe
dj
stockes par Linux dans un emplacement facile d'accs et est dj termine par null.
Quand un programme Linux, tous les pointeurs vers les arguments de ligne de commande sont
stocks
sur la pile. Le nombre d'arguments est stock 8(%esp), le nom de la
programme est stock 12(%esp), et 16(%esp), les arguments sont entreposs sur.
6. Si vous n'tes pas familier avec les permissions UNIX, il suffit de mettre $0666 ici. N'oubliez pas le
zro non significatif, car cela signifie que le nombre est un nombre octal.
91
Chapitre 5. Traitant des fichiers
En langage de programmation C, ceci est dnomm le tableau argv, donc nous allons
parlent de cette faon dans notre programme.
La premire chose que fait notre programme est de sauvegarder la position actuelle de la pile en %
ebp et
puis rserver de l'espace sur la pile pour stocker les descripteurs de fichier. Aprs cela, il
commence ouvrir des fichiers.
Le premier fichier que le programme s'ouvre est le fichier d'entre, qui est la premire ligne de
commande
argument. Nous faisons cela en mettant en place l'appel systme. Nous avons mis le nom du fichier
en
ebx %, le nombre de mode lecture seule en % ecx, le mode par dfaut de $0666 en
% edx et le numro d'appel systme dans %EAX aprs le systme, le fichier est ouvert
et le descripteur de fichier est stock dans % eax. 7 le descripteur de fichier est ensuite transfr au
C'est l'endroit appropri sur la pile.
Est puis faire de mme pour le fichier de sortie, sauf qu'elle est cre avec un
mode criture seule, crer-if--inexistant, tronquer-if-does-existent. Son descripteur de fichier
est stock ainsi.
Maintenant, nous arrivons la partie principale - la boucle de lecture/criture. Fondamentalement,
nous lirons
des blocs de taille fixe de donnes depuis le fichier d'entre, appelez notre fonction de conversion
ce sujet,
et il rcrit dans le fichier de sortie. Bien que nous lisons des morceaux de taille fixe, les
taille des blocs n'importe pour ce programme - nous fonctionnons juste tout droit
squences de caractres. On pourrait lire en avec aussi peu ou aussi grands que des morceaux
comme
Nous voulons, et il fonctionne toujours correctement.
La premire partie de la boucle est pour lire les donnes. Cet exemple utilise l'appel systme de
lecture. Ceci
appel juste prend un descripteur de fichier pour lire partir et crire dans une mmoire tampon
de la taille de
la mmoire tampon (i.e. - le nombre maximal d'octets pouvant tre crits). Le systme
appel renvoie le nombre d'octets rellement lu, ou fin de fichier (le chiffre 0).
7. Notez que nous ne faisons aucune vrification d'erreur sur cela. C'est fait juste pour garder le
programme
simple. Dans les programmes normaux, chaque appel systme normalement il faudrait vrifier
succs ou
chec. En cas d'chec, %EAX tiendra un code d'erreur au lieu d'une valeur de retour. Codes d'erreur
sont ngatifs, donc elles peuvent tre dtectes en comparant %EAX zro et en sautant si elle est
infrieure
zro.
92
Chapitre 5. Traitant des fichiers
Aprs avoir lu un bloc, nous vrifions % eax pour un marqueur de fin de fichier. Si trouv, il quitte
la boucle. Dans le cas contraire, nous continuons avancer.
Aprs la lecture des donnes, la fonction convert_to_upper est appele avec le tampon
nous viens de lire dans et le nombre de caractres lus dans l'appel systme prcdent.
Aprs l'excution de cette fonction, le tampon doit tre capitalises et prt crire
dehors. Les registres sont ensuite restaurs avec ce qu'ils avaient avant.
Enfin, nous publions un appel systme d'criture, qui est exactement comme l'appel systme de
lecture,
sauf qu'il dplace les donnes de la mmoire tampon de sortie vers le fichier. Maintenant, nous
allons juste retour
au dbut de la boucle.
Aprs la boucle s'arrte (n'oubliez pas, il se termine si, aprs une lecture, il dtecte la fin de la
fichier), il se ferme simplement les descripteurs de fichiers et les sorties. L'appel systme troite
prend juste
le descripteur de fichier pour fermer en % ebx.
Le programme est alors termin !
Examen
Connatre les Concepts
Dcrire le cycle de vie d'un descripteur de fichier.
Quels sont la norme de fichiers descripteurs et quoi servent ils ?
Ce qui est un tampon ?
Quelle est la diffrence entre la section .data et la section .bss ?
Quels sont les appels systme lies la lecture et l'criture de fichiers ?
93
Chapitre 5. Traitant des fichiers
Utiliser les Concepts
Modifier le programme de toupper afin qu'il lit depuis STDIN et crit
STDOUT au lieu d'utiliser les fichiers sur la ligne de commande.
Modifier la taille de la mmoire tampon.
Rcrire le programme afin qu'il utilise le stockage dans la section .bss plutt que le
pile pour stocker les descripteurs de fichier.
crire un programme qui va crer un fichier nomm heynow.txt et crire les mots
"Hey diddle diddle! dedans.
Aller plus loin
Quelle diffrence est la taille de la marque de tampon ?
Quelle est l'erreur des rsultats peuvent tre retournes par chacun de ces appels systme ?
Rendre le programme peut fonctionner sur des arguments de ligne de commande ou d'utiliser
STDIN ou STDOUT base sur le nombre d'arguments de ligne de commande spcifie
par l'ARGC.
Modifier le programme afin qu'il vrifie les rsultats de chaque appel systme et imprime
un message d'erreur dans STDOUT lorsqu'il se produit.
94
Chapitre 6. Lecture et l'criture Simple
Comptes rendus
Comme mentionn dans le chapitre 5, de nombreuses applications traitent les donnes persistantes-
ce qui signifie que la vie de donnes plus longtemps que le programme en tant stockes sur disque
inf
fichiers. Vous pouvez fermer le programme et l'ouvrir vers le haut, et vous tes de retour o
vous avez commenc. Maintenant, il y a deux types fondamentaux de donnes persistantes -
structures et
non structures. Des donnes non structures sont comme ce que nous avons trait dans le toupper
programme. Elle traitait seulement des fichiers texte qui ont t conclues par une personne. Le
contenu de
les fichiers ne sont pas utilisables par un programme, car un programme ne peut pas interprter ce
que le
utilisateur essaie de dire en texte alatoire.
Des donnes structures, quant elle, sont ce qu'ordinateurs excellent dans la
manipulation. Structur
les donnes sont les donnes qui se compose de champs et d'enregistrements. Pour l'essentiel, les
champs
et enregistrements de longueur fixe. Parce que les donnes sont divises en enregistrements de
longueur fixe
et les champs de format fixe, l'ordinateur peuvent interprter les donnes. Donnes structures
peuvent
contiennent des champs de longueur variable, mais ce stade, vous tes gnralement mieux avec
un
base de donnes.
1
Ce chapitre traite de la lecture et l'criture des enregistrements de longueur fixe simples. Disons que
Nous voulions stocker certaines informations de base sur les personnes nous savons. Nous pourrions
Imaginez l'enregistrement de longueur fixe exemple suivant sur les gens :
Prnom - 40 octets
Lastname - 40 octets
Adresse - 240 octets
ge - 4 octets
1. une base de donnes est un programme qui gre les donnes structures persistantes pour
vous. Vous n'avez pas
dois crire des programmes pour lire et crire les donnes sur le disque, faire des recherches, ou
mme pour faire
traitement de base. C'est une interface de trs haut niveau aux donnes structures qui, bien qu'il
ajoute
certains frais gnraux et la complexit supplmentaire, est trs utile pour les tches de traitement
de donnes complexes.
Rfrences pour apprendre comment fonctionnent les bases de donnes sont rpertoris dans le
chapitre 13.
95
Chapitre 6. Lire et crire des documents simples
Dans ce domaine, tout est des donnes de caractres l'exception de l'ge, qui est simplement un
numrique
sur le terrain, l'aide d'un mot standard de 4 octets (nous pourrions il suffit d'utiliser un seul octet
pour cela, mais
le garder un mot le rend plus facile traiter).
En programmation, vous avez souvent certaines dfinitions que vous utiliserez encore et encore
encore une fois dans le programme, ou peut-tre dans plusieurs programmes. Il est bon de
sparer ces dans des fichiers sont simplement incluses dans le langage assembleur
fichiers si ncessaire. Par exemple, dans nos programmes prochaines, nous aurons besoin d'accder
la
diffrentes parties de l'enregistrement ci-dessus. Cela signifie que nous devons savoir les dcalages
de
chaque terrain depuis le dbut de l'enregistrement afin d'y accder l'aide de base
adressage de pointeur. Les constantes suivantes dcrivent les offsets ce qui prcde
structure. Placez-les dans un fichier nomm dossier-def.s :
.EQU RECORD_FIRSTNAME, 0
.EQU RECORD_LASTNAME, 40
.EQU RECORD_ADDRESS, 80
.EQU RECORD_AGE, 320
.EQU RECORD_SIZE, 324
En outre, il y a plusieurs constantes que nous avons t dfinition reprises dans
nos programmes et il est utile de les mettre dans un fichier, afin que nous ne devrons pas garder
les entrant. Mettre les constantes suivantes dans un fichier nomm linux.s :
Dfinitions de Linux #Common
Numros d'appel #System
.EQU SYS_EXIT, 1
.EQU SYS_READ, 3
.EQU SYS_WRITE, 4
.EQU SYS_OPEN, 5
.EQU SYS_CLOSE, 6
.EQU SYS_BRK, 45
96
Chapitre 6. Lire et crire des documents simples
#System appel numro d'interruption
.EQU LINUX_SYSCALL, 0 x 80
Descripteurs de fichiers #Standard
.eQu STDIN, 0
.EQU STDOUT, 1
.EQU STDERR, 2
Codes d'tat #Common
.EQU END_OF_FILE, 0
Nous allons crire trois programmes dans ce chapitre, l'aide de la structure dfinie dans
Notice-def.s. Le premier programme va construire un fichier contenant plusieurs enregistrements
comme
dfini ci-dessus. Le deuxime programme affiche les enregistrements dans le fichier. Le troisime
programme ajoutera 1 an l'ge de tous les records.
Outre les constantes standards nous utiliserons tout au long des programmes,
Il y a aussi deux fonctions que nous utiliserons dans plusieurs programmes - un
qui lit un enregistrement et qui crit un enregistrement.
Quels sont les paramtres ces fonctions faut-il pour exploiter ? Fondamentalement, nous devons :
L'emplacement d'un tampon que nous pouvons lire un enregistrement en
Le descripteur de fichier que nous voulons lire ou crire
Regardons tout d'abord notre fonction de lecture :
comprennent "dossier-def.s"
comprennent linux.s
#PURPOSE : Cette fonction lit un enregistrement dans le fichier
97
Chapitre 6. Lire et crire des documents simples
descripteur de #
#
#INPUT : Le descripteur de fichier et un tampon
#
#OUTPUT : Cette fonction crit les donnes dans la mmoire tampon
# et renvoie un code d'tat.
#
#STACK VARIABLES LOCALES
.EQU ST_READ_BUFFER, 8
.EQU ST_FILEDES, 12
.section .text
.Globl read_record
.type read_record, @function
read_record :
pushl % ebp
movl % esp, ebp %
pushl % ebx
movl ST_FILEDES(%ebp), ebx %
movl ST_READ_BUFFER(%ebp), ecx %
movl $RECORD_SIZE, % edx
movl $SYS_READ, eax %
int $LINUX_SYSCALL
#NOTE - %EAX a la valeur de retour, qui nous sera
# redonner notre programme appelant
POPL % ebx
movl % ebp, % esp
POPL % ebp
RET
C'est une fonction assez simplement. Il lit juste les donnes la taille de notre structure dans un
tampon partir du descripteur de fichier donne de taille approprie. L'criture un est similaire :
98
Chapitre 6. Lire et crire des documents simples
comprennent linux.s
comprennent "dossier-def.s"
#PURPOSE : Cette fonction crit un enregistrement de
# le descripteur de fichier
#
#INPUT : Le descripteur de fichier et un tampon
#
#OUTPUT : Cette fonction gnre un code d'tat
#
#STACK VARIABLES LOCALES
.EQU ST_WRITE_BUFFER, 8
.EQU ST_FILEDES, 12
.section .text
.Globl write_record
.type write_record, @function
write_record :
pushl % ebp
movl % esp, ebp %
pushl % ebx
movl $SYS_WRITE, eax %
movl ST_FILEDES(%ebp), ebx %
movl ST_WRITE_BUFFER(%ebp), ecx %
movl $RECORD_SIZE, % edx
int $LINUX_SYSCALL
#NOTE - %EAX a la valeur de retour, qui nous sera
# redonner notre programme appelant
POPL % ebx
movl % ebp, % esp
POPL % ebp
RET
99
Chapitre 6. Lire et crire des documents simples
Maintenant que nous avons nos dfinitions de la base vers le bas, nous sommes prts crire nos
programmes.
Dossiers de la rdaction
Ce programme sera simplement crire certains enregistrements cods en dur sur le disque. Il sera :
Ouvrir le fichier
crire trois records
Fermez le fichier
Tapez le code suivant dans un fichier appel criture-records.s :
comprennent linux.s
comprennent "dossier-def.s"
.data .section
Donnes de #constant des dossiers que nous voulons crire
lment de donnes pour le texte #Each est rembourr l'adquat
#length avec la valeur null (c'est--dire 0) octets.
# .rept est utilis pour remplir chaque lment. .REPT dit
#the assembleur de rpter la section entre
# .rept et .endr le nombre de fois spcifi.
#This est utilis dans ce programme pour ajouter extra null
#characters la fin de chaque champ remplir
#it vers le haut
Record1 :
.ASCII Fredrick\0
.REPT #Padding 31 40 octets
.Byte 0
.endr
.ASCII Bartlett\0
100
Chapitre 6. Lire et crire des documents simples
.REPT #Padding 31 40 octets
.Byte 0
.endr
.ASCII S 4242 Prairie\nTulsa, 55555\0 OK
.REPT #Padding 209 240 octets
.Byte 0
.endr
.long 45
Record2 :
.ASCII Marilyn\0
.REPT #Padding 32 40 octets
.Byte 0
.endr
.ASCII Taylor\0
.REPT #Padding 33 40 octets
.Byte 0
.endr
.ASCII 2224 Johannan S St\nChicago, IL 12345\0
.REPT #Padding 203 240 octets
.Byte 0
.endr
.long 29
enregistrement Record3 :
.ASCII Derrick\0
.REPT #Padding 32 40 octets
.Byte 0
.endr
101
Chapitre 6. Lire et crire des documents simples
.ASCII McIntire\0
.REPT #Padding 31 40 octets
.Byte 0
.endr
.ASCII 500 W Oakland\nSan Diego, CA 54321\0
.REPT 206 #Padding 240 octets
.Byte 0
.endr
.long 36
#This est le nom du fichier que nous allons crire
file_name :
.ASCII test.dat\0
.EQU ST_FILE_DESCRIPTOR, -4
.Globl _start
_start :
#Copy le pointeur de pile pour % ebp
movl % esp, ebp %
Espace de #Allocate pour contenir le descripteur de fichier
Subl $4, % esp
#Open le fichier
movl $SYS_OPEN, eax %
movl $file_name, ebx %
movl $0101, ecx %#This dit crer s'il
# n'existe et ouvert pour
#writing
movl $0666, % edx
int $LINUX_SYSCALL
#Store le descripteur de fichier.
movl % eax, ST_FILE_DESCRIPTOR(%ebp)
102
Chapitre 6. Lire et crire des documents simples
#Write le premier enregistrement
pushl ST_FILE_DESCRIPTOR(%ebp)
pushl $record1
appel write_record
ADDL $8, % esp
#Write le second enregistrement
pushl ST_FILE_DESCRIPTOR(%ebp)
pushl $record2
appel write_record
ADDL $8, % esp
#Write le troisime enregistrement
pushl ST_FILE_DESCRIPTOR(%ebp)
pushl $record3
appel write_record
ADDL $8, % esp
#Close le descripteur de fichier
movl $SYS_CLOSE, eax %
movl ST_FILE_DESCRIPTOR(%ebp), ebx %
int $LINUX_SYSCALL
#Exit le programme
movl $SYS_EXIT, eax %
movl $0, % ebx
int $LINUX_SYSCALL
Il s'agit d'un programme assez simple. Il consiste simplement dfinir les donnes que nous voulons
crire dans la section .data et en appelant ensuite les appels systme droite et fonction
appels de l'accomplir. D'un recyclage de tous les appels de systme utiliss, voir l'annexe
C.
103
Chapitre 6. Lire et crire des documents simples
Vous avez peut-tre remarqu les lignes :
comprennent linux.s
comprennent "dossier-def.s"
Ces instructions provoquent les fichiers donns fondamentalement tre coll l dans le
code. Vous n'avez pas besoin de le faire avec les fonctions, parce que l'diteur de liens peut
s'occuper de
combinant des fonctions exportes avec .globl. Toutefois, les constantes dfinies dans
un autre fichier dois tre imports de cette faon.
En outre, vous avez peut-tre remarqu l'utilisation d'une nouvelle directive de l'assembleur,
.rept. Ceci
directive reprend le contenu du fichier entre le .rept et le
directives .endr le nombre de fois spcifi aprs .rept. Ceci est gnralement utilis
la faon dont nous l'avons utilis - pour remplir les valeurs dans la section .data. Dans notre cas,
nous ajoutons
caractres null la fin de chaque champ jusqu' ce qu'ils soient leurs longueurs dfinies.
Pour gnrer l'application, excutez les commandes :
comme l'criture-records.s o - criture-record.o
comme l'criture-record.s o - criture-record.o
LD criture-record.o criture-records.o o - criture-dossiers
Ici nous sommes assembler deux fichiers sparment et puis en les combinant ensemble
l'aide de l'diteur de liens. Pour excuter le programme, il suffit de taper ce qui suit :
. / criture-dossiers
Cela entranera un fichier appel test.dat pour cr contenant les enregistrements.
Cependant, depuis lors, ils contiennent des caractres non imprimables (le caractre nul,
en particulier), ils ne peuvent tre visibles par un diteur de texte. C'est pourquoi nous devons le
le prochain programme de les lire pour nous.
104
Chapitre 6. Lire et crire des documents simples
Lecture des enregistrements
Maintenant, nous examinerons le processus de lecture des enregistrements. Dans ce programme,
nous lirons
chaque enregistrement et afficher le prnom rpertori avec chaque enregistrement.
Nom de chaque personne tant une longueur diffrente, nous aurons besoin d'une fonction pour
compter
le nombre de caractres que nous voulons crire. Depuis lors nous touche chaque champ avec la
valeur null
caractres, nous pouvons compter simplement caractres jusqu' ce que nous atteignons un
caractre null. 2 note
que cela signifie que nos dossiers contiennent chacun au moins un caractre null.
Voici le code. Mettre dans un fichier appel comte-chars.s :
#PURPOSE : Compter les caractres jusqu' ce qu'un octet nul est atteint.
#
#INPUT : L'adresse de la chane de caractres
#
#OUTPUT : Retourne le nombre dans %EAX
#
#PROCESS :
# Registres utiliss :
# % ecx - nombre de caractres
# % al - caractre courant
# % edx - adresse actuelle de caractre
.type count_chars, @function
.Globl count_chars
#This, c'est o notre un seul paramtre est sur la pile
.EQU ST_STRING_START_ADDRESS, 8
count_chars :
pushl % ebp
movl % esp, ebp %
#Counter commence zro
movl $0, _ecx
2. Si vous avez utilis le C, c'est ce que la fonction strlen().
105
Chapitre 6. Lire et crire des documents simples
Adresse de #Starting des donnes
movl ST_STRING_START_ADDRESS(%ebp), % edx
count_loop_begin :
#Grab le caractre courant
movb (% edx), % al
#Is il est null ?
CMPB $0, % al
#If Oui, nous avons termin
Je count_loop_end
#Otherwise, incrmente le compteur et le pointeur
ecx % incl
incl % edx
#Go retour au dbut de la boucle
JMP count_loop_begin
count_loop_end :
#We avons termin. Le dcompte dans %EAX
#and retour.
movl % ecx, %EAX
POPL % ebp
RET
Comme vous pouvez le voir, c'est une fonction assez simple. Il parcourt simplement la
octets, comptant comme il va, jusqu' ce qu'il frappe d'un caractre null. Puis, il retourne le compte.
Notre programme de lecture d'enregistrement sera assez simple, aussi. Il fera la
suivant :
Ouvrir le fichier
Tentative de lecture d'un enregistrement
106
Chapitre 6. Lire et crire des documents simples
Si nous sommes la fin du fichier, quitter
Dans le cas contraire, compter les caractres du prnom
crire le prnom STDOUT
crire une nouvelle ligne vers STDOUT
Revenir lire un autre enregistrement
Pour crire cela, nous avons besoin d'une fonction simple plus - une fonction pour crire une
nouvelle ligne
vers STDOUT. Insrez le code suivant dans l'criture-newline.s :
comprennent linux.s
.Globl write_newline
.type write_newline, @function
.data .section
saut de ligne :
.ASCII \n
.section .text
.EQU ST_FILEDES, 8
write_newline :
pushl % ebp
movl % esp, ebp %
movl $SYS_WRITE, eax %
movl ST_FILEDES(%ebp), ebx %
movl $newline, ecx %
movl $1, % edx
int $LINUX_SYSCALL
movl % ebp, % esp
POPL % ebp
RET
107
Chapitre 6. Lire et crire des documents simples
Maintenant, nous sommes prts crire le programme principal. Voici le code
lecture-records.s :
comprennent linux.s
comprennent "dossier-def.s"
.data .section
file_name :
.ASCII test.dat\0
.section .bss
.LComm record_buffer, RECORD_SIZE
.section .text
#Main programme
.Globl _start
_start :
#These sont les emplacements sur la pile o
#we stockera les descripteurs d'entre et de sortie
#(FYI - nous aurions pu utiliser des adresses de mmoire dans
#a .data section la place)
.EQU ST_INPUT_DESCRIPTOR, -4
.EQU ST_OUTPUT_DESCRIPTOR, -8
#Copy le pointeur de pile pour % ebp
movl % esp, ebp %
Espace de #Allocate pour contenir les descripteurs de fichier
Subl $8, % esp
#Open le fichier
movl $SYS_OPEN, eax %
movl $file_name, ebx %
movl $0, _ecx #This dit ouverte en lecture seule
108
Chapitre 6. Lire et crire des documents simples
movl $0666, % edx
int $LINUX_SYSCALL
Descripteur de fichier #Save
movl % eax, ST_INPUT_DESCRIPTOR(%ebp)
#Even si c'est une constante, nous sommes
#saving la sortie du fichier descripteur dans
#a variable locale afin que si nous avons ensuite
#decide qu'il ne va pas toujours
#be STDOUT, nous pouvons le changer facilement.
movl $STDOUT, ST_OUTPUT_DESCRIPTOR(%ebp)
record_read_loop :
pushl ST_INPUT_DESCRIPTOR(%ebp)
pushl $record_buffer
appel read_record
ADDL $8, % esp
#Returns le nombre d'octets lu.
#If ce n'est pas le mme numro nous
#requested, puis il est soit un
#end-of-file, ou une erreur, donc nous sommes
#quitting
CMPL $RECORD_SIZE, eax %
JNE finished_reading
#Otherwise, imprimer le prnom
#but tout d'abord, nous devons connatre sa taille
pushl $RECORD_FIRSTNAME + record_buffer
appel count_chars
ADDL $4, % esp
109
Chapitre 6. Lire et crire des documents simples
movl % eax, edx %
movl ST_OUTPUT_DESCRIPTOR(%ebp), ebx %
movl $SYS_WRITE, eax %
movl $RECORD_FIRSTNAME + record_buffer, ecx %
int $LINUX_SYSCALL
pushl ST_OUTPUT_DESCRIPTOR(%ebp)
appel write_newline
ADDL $4, % esp
JMP record_read_loop
finished_reading :
movl $SYS_EXIT, eax %
movl $0, % ebx
int $LINUX_SYSCALL
Pour construire ce programme, il faut assembler toutes les pices et liez-les ensemble :
comme lecture de lecture-record.s - o-record.o
comme comte de comte-chars.s - o-chars.o
comme l'criture-newline.s o - criture-newline.o
comme lecture de lecture-records.s - o-records.o
criture de LD comte de lecture-record.o-chars.o-newline.o \
lecture lecture-records.o - o-comptes rendus
La barre oblique inverse la premire ligne signifie simplement que la commande continue sur la
ligne suivante. Vous pouvez excuter votre programme en faisant. / lecture-records.
Comme vous pouvez le voir, ce programme ouvre le fichier et excute ensuite une boucle de lecture,
vrification de la fin du fichier et l'criture le prnom. La construction qui
peut tre nouveau est la ligne qui indique :
pushl $RECORD_FIRSTNAME + record_buffer
110
Chapitre 6. Lire et crire des documents simples
Il semble que nous unissent et ajouter une instruction avec une instruction push, mais nous
ne sont pas. Vous voyez, les RECORD_FIRSTNAME et record_buffer sont constantes.
Le premier est une constante directe, cr grce l'utilisation de la directive .equ, tandis que la
cette dernire est dfinie automatiquement par l'assembleur son utilisation comme une tiquette
(c'est de valeur
tant l'adresse laquelle les donnes qui suit il vont commencer ). Puisqu'ils sont tous deux
constantes qui sait de l'assembleur, il est capable de les ajouter ensemble alors que c'est
assembler votre programme, l'instruction entire est donc un seul mode immdiat
Pousse d'une constante unique.
La constante RECORD_FIRSTNAME est le nombre d'octets aprs le dbut d'une
enregistrement avant que nous frapper le prnom. record_buffer est le nom de notre tampon pour
dossiers de tenue. Nous les additionner obtient l'adresse du prnom
membre de l'enregistrement stock dans record_buffer.
Modifier les enregistrements
Dans cette section, nous allons crire un programme qui :
Ouvre un fichier d'entre et de sortie
Les dossiers de lectures de l'entre
Augmente l'ge
Enregistre le nouvel enregistrement dans le fichier de sortie
Comme la plupart des programmes que nous avons croiss rcemment, ce programme est joli
simple. 3
comprennent linux.s
comprennent "dossier-def.s"
3. vous constaterez qu'aprs avoir appris la mcanique de la programmation, la plupart des
programmes sont
assez simple une fois que vous savez exactement ce que c'est vous voulez faire. La plupart d'entre
eux ini -
tialize donnes, effectuer un traitement en boucle et puis tout nettoyer.
111
Chapitre 6. Lire et crire des documents simples
.data .section
INPUT_FILE_NAME :
.ASCII test.dat\0
nom_fichier_sortie :
.ASCII testout.dat\0
.section .bss
.LComm record_buffer, RECORD_SIZE
#Stack dcalages des variables locales
.EQU ST_INPUT_DESCRIPTOR, -4
.EQU ST_OUTPUT_DESCRIPTOR, -8
.section .text
.Globl _start
_start :
#Copy pointeur de pile et faire de la place pour les variables locales
movl % esp, ebp %
Subl $8, % esp
#Open fichier pour lecture
movl $SYS_OPEN, eax %
movl $input_file_name, ebx %
movl $0, _ecx
movl $0666, % edx
int $LINUX_SYSCALL
movl % eax, ST_INPUT_DESCRIPTOR(%ebp)
#Open fichier pour l'criture
movl $SYS_OPEN, eax %
movl $output_file_name, ebx %
movl $0101, _ecx
112
Chapitre 6. Lire et crire des documents simples
movl $0666, % edx
int $LINUX_SYSCALL
movl % eax, ST_OUTPUT_DESCRIPTOR(%ebp)
Boucle_dbut :
pushl ST_INPUT_DESCRIPTOR(%ebp)
pushl $record_buffer
appel read_record
ADDL $8, % esp
#Returns le nombre d'octets lu.
#If ce n'est pas le mme numro nous
#requested, puis il est soit un
#end-of-file, ou une erreur, donc nous sommes
#quitting
CMPL $RECORD_SIZE, eax %
JNE loop_end
#Increment l'ge
incl record_buffer + RECORD_AGE
#Write le record out
pushl ST_OUTPUT_DESCRIPTOR(%ebp)
pushl $record_buffer
appel write_record
ADDL $8, % esp
JMP Boucle_dbut
loop_end :
movl $SYS_EXIT, eax %
movl $0, % ebx
int $LINUX_SYSCALL
113
Chapitre 6. Lire et crire des documents simples
Vous pouvez taper dedans comme ajouter-anne. Pour le construire, tapez les 4 suivants :
comme l'anne Ajouter Ajouter - o-year.o
Ajouter-year.o LD record.o lecture criture-record.o o - ajouter-anne
Pour excuter le programme, il suffit de taper les 5 suivants :
. / Ajouter-anne
Cela va ajouter une anne chaque dossier rpertori dans test.dat et crire les nouveaux
enregistrements
pour le fichier testout.dat.
Comme vous pouvez le voir, l'criture des enregistrements de longueur fixe est assez simple. Il vous
suffit de
lu dans des blocs de donnes dans une mmoire tampon, traiter eux et crire que les rgulariser.
Malheureusement, ce programme n'crivez les nouveaux ges dehors l'cran si vous
peut vrifier l'efficacit de votre programme. C'est parce que nous n'obtiendrez pas
affichage des numros jusqu'au chapitre 8 et au chapitre 10. Aprs la lecture de ceux que vous
pouvez
envie de revenir et de rcrire ce programme pour afficher les donnes numriques que nous
modifiez.
Examen
Connatre les Concepts
Ce qui est un record ?
Quel est l'avantage d'enregistrements de longueur fixe sur les enregistrements de longueur
variable ?
Comment intgrez les constantes dans plusieurs fichiers de source de l'Assemble ?
4. ce qui suppose que vous avez dj construit l'objet fichiers lecture-record.o et l'criture-
record.o dans les exemples prcdents. Si ce n'est pas le cas, vous devrez le faire.
5. c'est en supposant que vous avez cr le fichier dans une excution prcdente de l'criture-
records. Sinon, vous
besoin de lancer l'criture-enregistrements premire avant d'excuter ce programme.
114
Chapitre 6. Lire et crire des documents simples
Pourquoi vous pouvez diviser un projet en plusieurs fichiers source ?
En quoi consiste l'instruction incl record_buffer + RECORD_AGE ? Ce qui
mode d'adressage est l'aide ? Le nombre d'oprandes que les instructions incl
dans ce cas-ci ? Quelles parties sont traites par l'assembleur, qui
pices sont traits lorsque le programme est excut ?
Utiliser les Concepts
Ajouter un autre membre de donnes la structure de la personne dfinie dans le prsent
chapitre, et
rcrire la lecture et criture des fonctions et des programmes pour les emmener dans
compte. N'oubliez pas de remonter et de recrer un lien vers vos fichiers avant d'excuter votre
programmes.
Crer un programme qui utilise une boucle pour crire 30 enregistrements identiques dans un
fichier.
Crer un programme pour trouver le plus grand ge dans le fichier et revenir cet ge comme le
code d'tat du programme.
Crer un programme pour trouver le plus petit ge dans le fichier et revenir cet ge comme le
code d'tat du programme.
Aller plus loin
Rcrire les programmes dans ce chapitre permet de spcifier des arguments de ligne de
commande
la question.
Recherche le systme lseek appeler. Rcrire le programme ajouter ans pour ouvrir la
fichier source pour lecture et criture (utilisation de 2 $ pour le mode lecture/criture), et
rcrire les enregistrements modifis dans le mme fichier, qu'elles ont t lues partir.
tudier les diffrents codes d'erreur qui peuvent tre retournes par les appels systme effectus
dans ces programmes. Choisissez-en une de rcrire et ajoutez le code qui vrifie % eax pour erreur
115
Chapitre 6. Lire et crire des documents simples
conditions et, s'il en existe, a crit un message ce sujet STDERR et sortez.
crire un programme qui va ajouter un seul enregistrement dans le fichier en lisant les donnes de
le clavier. N'oubliez pas, vous devrez vous assurer que les donnes ont au moins
un caractre nul la fin et vous avez besoin d'avoir un moyen pour l'utilisateur d'indiquer
ils sont font taper. Parce que nous n'avons pas obtenu en caractres numros
conversion, vous ne serez pas en mesure de lire l'ge partir du clavier, donc vous aurez
doivent avoir un ge par dfaut.
crire une fonction appele comparer-chanes qui comparent deux chanes jusqu'
5 caractres. Alors crire un programme qui permet l'utilisateur d'entrer les 5 caractres,
et que le programme de renvoyer tous les enregistrements dont le prnom commence par ces 5
caractres.
116

You might also like