/usr/share/doc/HOWTO/fr-html/Assembly-HOWTO.html is in doc-linux-fr-html 2013.01-2.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 | <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<html>
<head>
<meta name="generator" content=
"HTML Tidy for Linux/x86 (vers 25 March 2009), see www.w3.org">
<meta name="GENERATOR" content="LinuxDoc-Tools 0.9.69">
<title>Assembly HOWTO</title>
</head>
<body>
<h1>Assembly HOWTO</h1>
<h2>François-René Rideau
<code>rideau@ens.fr</code></h2>
v0.4l, 16 Novembre 1997
<hr>
<em>(Version française réalisée par Eric Dumas
<code>dumas@freenix.fr</code> <code>dumas@Linux.EU.Org</code>, et
Faré Rideau <code>rideau@ens.fr</code>, 11 Novembre 1997).
Ce document décrit comment programmer en assembleur x86 en
n'utilisant que des outils de développement <em>libres</em>,
et tout particulièrement avec le système
d'exploitation Linux sur la plate-forme i386. Les informations
contenues dans ce document peuvent être applicables ou non
applicables à d'autres plates-formes matérielles ou
logicielles. Les contributions à ce documents seront
acceptées avec gratitude. <em>mots-clefs</em>: assembleur,
libre, macroprocesseur, préprocesseur, asm, inline asm, 32
bits, x86, i386, gas, as86, nasm</em>
<hr>
<h2><a name="s1">1. Introduction</a></h2>
<h2><a name="ss1.1">1.1 Copyright</a></h2>
<p>Copyright © 1996,1997 François-René Rideau.
Ce document peut être redistribué sous les termes de
la license LDP, disponibles à <a href=
"http://sunsite.unc.edu/LDP/COPYRIGHT.html">http://sunsite.unc.edu/LDP/COPYRIGHT.html</a>.</p>
<h2><a name="ss1.2">1.2 Note importante</a></h2>
<p>Ceci est censé être la dernière version que
j'écrirai de ce document. Il y a un candidat pour reprendre
en charge le document, mais jusqu'à ce qu'il le reprenne
complètement en main, je serai heureux de m'occuper de tout
courrier concernant ce document.</p>
<p>Vous êtes tout spécialement invités à
poser des questions, à y répondre, à corriger
les données, à ajouter de nouvelles informations,
à compléter les références sur d'autres
logiciels, à mettre en évidence les erreurs et
lacunes du document. Si vous êtes motivés, vous pouvez
même <b>prendre en charge ce document</b>. En un mot,
apporter votre contribution!</p>
<p>Pour contribuer à ce document, contactez la personne qui
apparaît actuellement en charge. Au moment où
j'écris ces lignes, il s'agit de <a href=
"mailto:rideau@clipper.ens.fr">François-René
Rideau</a>) ainsi que de <a href=
"mailto:paul@geeky1.ebtech.net">Paul Anderson</a>.</p>
<h2><a name="ss1.3">1.3 Avant-Propos</a></h2>
<p>Ce document est destiné à répondre aux
questions les plus fréquemment posées par les gens
qui développent ou qui souhaitent développer des
programmes en assembleurs x86 32 bits en utilisant des logiciels
<em>libres</em>, et tout particulièrement sous Linux. Vous y
trouverez également des liens sur d'autres documents
traitant d'assembleur, fondés sur des outils logiciels qui
ne sont pas libres, pas 32-bit, ou pas dédiés
à l'architecture x86, bien que cela ne soit pas le but
principal de ce document.</p>
<p>Etant donné que l'intéret principal de la
programmation en assembleur est d'établir les fondations de
systèmes d'exploitation, d'interpréteurs, de
compilateurs, et de jeux, là où un compilateur C
n'arrive plus à fournir le pouvoir d'expression
nécessaire (les performances étant de plus en plus
rarement un problème), nous insisteront sur le
développement de tels logiciels.</p>
<h3>Comment utiliser ce document</h3>
<p>Ce document contient des réponses à un certain
nombre de questions fréquemment posées. Des URL y
sont donnés, qui pointent sur des sites contenant documents
ou logiciels. Prenez conscience que les plus utiles de ces sites
sont dupliqués sur des serveurs miroirs, et qu'en utilisant
le site miroir le plus proche de chez vous, vous évitez
à un gâchis inutile aussi bien de précieuses
ressources réseau communes à l'Internet que de votre
propre temps. Ainsi, il existe un certain nombre de gros serveurs
disséminés sur la planète, qui effectuent la
duplication d'autres sites importants. Cherchez où se
trouvent ces sites et identifiez les plus proches de chez vous (du
point de vue du réseau). Parfois, la liste des miroirs est
données dans un fichier ou dans le message de connexion.
Suivez ces conseils. Si ces informations ne sont pas
présentes, utilisez le programme archie.</p>
<p>La version la plus récente de ce document peut être
trouvée sur</p>
<p><a href=
"http://www.eleves.ens.fr:8080/home/rideau/Assembly-HOWTO">http://www.eleves.ens.fr:8080/home/rideau/Assembly-HOWTO</a>
ou <a href=
"http://www.eleves.ens.fr:8080/home/rideau/Assembly-HOWTO.sgml">http://www.eleves.ens.fr:8080/home/rideau/Assembly-HOWTO.sgml</a></p>
<p>mais les répertoires de HowTo Linux <em>devraient</em>
normalement être à peu près à jour (je
ne peux pas le garentir):</p>
<p><a href=
"ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO/">ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO/</a>
(?)</p>
<p>La version française de ce document peut être
trouvée sur le site</p>
<p><a href=
"ftp://ftp.ibp.fr/pub/linux/french/HOWTO/">ftp://ftp.ibp.fr/pub/linux/french/HOWTO/</a></p>
<h3>Autres documents de référence</h3>
<ul>
<li>si vous ne savez ce qu'est le <em>libre</em> logiciel, lisez
avec attention la GPL (GNU General Public License), qui est
utilisée dans un grand nombre de logiciels libres, et est
une source d'inspiration pour la plupart des autres licences
d'utilisations de logiciels libres. Elle se trouve
généralement dans un fichier nommé
<code>COPYING</code>, avec une version pour les
bibliothèques de routines dans un fichier nommé
<code>COPYING.LIB</code>. Les écrits publiés par la
FSF (free software foundation) peuvent également vous aider
à comprendre le phénomène.</li>
<li>plus précisément, les logiciels libres
intéressants sont ceux desquels les sources sont
disponibles, que l'on peut consulter, corriger, et desquels on peut
emprunter une partie. Lisez les licences d'utilisation avec
attention et conformez-vous y.</li>
<li>il existe une FAQ dans le forum de discussion comp.lang.asm.x86
qui répond aux questions générales concernant
la programmation en assembleur pour x86, et aux questions
concernant certains assembleurs commerciaux dans un environnement
DOS 16 bits. Certaines de ces réponses peuvent s'appliquer
à la programmation 32 bits, aussi serez-vous sans-doute
intéressés de lire cette FAQ... <a href=
"http://www2.dgsys.com/~raymoon/faq/asmfaq.zip">http://www2.dgsys.com/~raymoon/faq/asmfaq.zip</a></li>
<li>Sont disponibles des FAQs, de la documentation, et des sources,
concernant la programmation sur votre plate-forme
préférée, quelqu'elle soit, et vous devriez
les consulter pour les problèmes liés à votre
plate-forme qui ne seraient pas spécifique à la
programmation en assembleur.</li>
</ul>
<h2><a name="ss1.4">1.4 Historique de document</a></h2>
<p>Chaque version inclue quelques modifications et corrections
mineures, qui ne sont pas indiquées à chaque
fois.</p>
<dl>
<dt><b>Version 0.1 23 Avril 1996</b></dt>
<dd>
<p>Francois-Rene "Faré" Rideau <rideau@ens.fr>
crée et diffuse initialement le document sous forme d'un
mini-HOWTO car ``Je suis un peu fatigué d'avoir à
répondre encore et toujours aux mêmes questions dans
le forum comp.lang.asm.x86''</p>
</dd>
<dt><b>Version 0.2 4 Mai 1996</b></dt>
<dd>
<p>*</p>
</dd>
<dt><b>Version 0.3c 15 Juin 1996</b></dt>
<dd>
<p>*</p>
</dd>
<dt><b>Version 0.3f 17 Octobre 1996</b></dt>
<dd>
<p>Tim Potter indique l'option -fasm pour activer l'assembleur
en-ligne de GCC sans le reste des optimisations de -O.</p>
</dd>
<dt><b>Version 0.3g 2 Novembre 1996</b></dt>
<dd>
<p>Création de l'historique. Ajout de pointeurs dans la
section sur la compilation croisée. Ajout d'une section
concernant la programmation des entrées/sorties sous Linux
(en particulier pour l'accès vidéo).</p>
</dd>
<dt><b>Version 0.3h 6 Novembre 1996</b></dt>
<dd>
<p>plus sur la compilation croisée - voir sur sunsite:
devel/msdos/</p>
</dd>
<dt><b>Version 0.3i 16 Novembre 1996</b></dt>
<dd>
<p>NASM commence à être particulièrement
intéressant</p>
</dd>
<dt><b>Version 0.3j 24 Novembre 1996</b></dt>
<dd>
<p>Référence sur la version française</p>
</dd>
<dt><b>Version 0.3k 19 Décembre 1996</b></dt>
<dd>
<p>Quoi? J'avais oublié de parler de Terse?</p>
</dd>
<dt><b>Version 0.3l 11 Janvier 1997</b></dt>
<dd>
<p>*</p>
</dd>
<dt><b>Version 0.4pre1 13 Janvier 1997</b></dt>
<dd>
<p>Le mini-HOWTO au format texte est transformé en un
authentique HOWTO au format linuxdoc-sgml, pour explorer les
possibilités dudit format.</p>
</dd>
<dt><b>Version 0.4 20 Janvier 1997</b></dt>
<dd>
<p>Première diffusion de ce HOWTO.</p>
</dd>
<dt><b>Version 0.4a 20 Janvier 1997</b></dt>
<dd>
<p>Ajout de la section CREDITS</p>
</dd>
<dt><b>Version 0.4b 3 Février 1997</b></dt>
<dd>
<p>NASM mis avant AS86</p>
</dd>
<dt><b>Version 0.4c 9 Février 1997</b></dt>
<dd>
<p>Ajout de la partie "Avez-vous besoin d'utilisateur
l'assembleur?"</p>
</dd>
<dt><b>Version 0.4d 28 Février 1997</b></dt>
<dd>
<p>Annonce fantôme d'un nouveau responsable de ce HowTo.</p>
</dd>
<dt><b>Version 0.4e 13 Mar 1997</b></dt>
<dd>
<p>Version diffusée pour DrLinux</p>
</dd>
<dt><b>Version 0.4f 20 Mars 1997</b></dt>
<dd>
<p>*</p>
</dd>
<dt><b>Version 0.4g 30 Mars 1997</b></dt>
<dd>
<p>*</p>
</dd>
<dt><b>Version 0.4h 19 Juin 1997</b></dt>
<dd>
<p>Ajouts à propos de "Comment ne pas utiliser
l'assembleur"; mises à jour concernant NASM et GAS.</p>
</dd>
<dt><b>Version 0.4i 17 Juillet 1997</b></dt>
<dd>
<p>Informations sur l'accès au mode 16 bits à partir
de Linux.</p>
</dd>
<dt><b>Version 0.4j 7 September 1997</b></dt>
<dd>
<p>*</p>
</dd>
<dt><b>Version 0.4k 19 Octobre 1997</b></dt>
<dd>
<p>je (Faré) reprends en main la traduction française
du HowTo</p>
</dd>
<dt><b>Version 0.4l 16 Novembre 1997</b></dt>
<dd>
<p>version pour LSL 6ème édition.</p>
<p>Il s'agit encore d'une nouvelle ``toute dernière version
réalisée par Faré avant qu'un nouveau
responsable ne prenne la main''.</p>
</dd>
</dl>
<h2><a name="ss1.5">1.5 Crédits</a></h2>
<p>Je souhaiterais remercier les personnes suivantes:</p>
<ul>
<li><a href="mailto:buried.alive@in.mail">Linus Torvalds</a> pour
Linux</li>
<li><a href="mailto:bde@zeta.org.au">Bruce Evans</a> pour bcc
d'où as86 est extrait</li>
<li><a href="mailto:anakin@poboxes.com">Simon Tatham</a> et
<a href="mailto:jules@earthcorp.com">Julian Hall</a> pour
NASM.</li>
<li><a href="mailto:jim-neil@digital.net">Jim Neil</a> pour
Terse</li>
<li><a href="mailto:gregh@sunsite.unc.edu">Greg Hankins</a> pour la
coordination des HOWTOs</li>
<li><a href="mailto:raymoon@moonware.dgsys.com">Raymond Moon</a>
pour sa FAQ</li>
<li><a href="mailto:dumas@Linux.EU.Org">Eric Dumas</a> pour la
traduction initiale en français... (l'auteur,
français, est le premier attristé de devoir
écrire l'original en anglais)</li>
<li><a href="mailto:paul@geeky1.ebtech.net">Paul Anderson</a> et
<a href="mailto:rahim@megsinet.net">Rahim Azizarab</a> pour m'avoir
aidé, à défaut de reprendre le HowTo en
main.</li>
<li>toutes les personnes qui ont contribué à
l'écriture de ce document, par leurs idées, remarques
ou leur soutient moral.</li>
</ul>
<h2><a name="doyouneedasm"></a> <a name="s2">2. Avez-vous besoin de
l'assembleur?</a></h2>
<p>Je ne veux en aucun cas jouer les
empêcheurs-de-tourner-en-rond, mais voici quelques conseils
issus d'une expérience gagnée à la dure.</p>
<h2><a name="ss2.1">2.1 Le Pour et le Contre</a></h2>
<h3>Les avantages de l'assembleur</h3>
<p>L'assembleur peut vous permettre de réaliser des
opérations très bas niveau:</p>
<ul>
<li>vous pouvez accéder aux registres et aux ports
d'entrées/sorties spécifiques à votre
machine;</li>
<li>vous pouvez parfaitement contrôler le comportemant du
code dans des sections critiques où pourraient sinon advenir
un blocage du processeur ou des périphériques;</li>
<li>vous pouvez sortir des conventions de production de code de
votre compilateur habituel; ce qui peut vous permettre d'effectuer
certaines optimisations (par exemple contourner les règles
d'allocation mémoire, gérer manuellement le cours de
l'éxécution, etc.);</li>
<li>accéder à des modes de programmation non courants
de votre processeur (par exemple du code 16 bits pour
l'amorçage ou l'interfaçage avec le BIOS, sur les
pécés Intel);</li>
<li>vous pouvez construire des interfaces entre des fragments de
codes utilisant des conventions incompatibles (c'est-à-dire
produit par des compilateurs différents ou
séparés par une interface bas-niveau);</li>
<li>vous pouvez générer un code assez rapide pour les
boucles importantes pour pallier aux défauts d'un
compilateur qui ne sait les optimiser (mais bon, il existe des
compilateurs optimisateurs librement disponibles!);</li>
<li>vous pouvez générer du code optimisé
"à la main" qui est plus parfaitement règlé
pour votre configuration matérielle précise,
même s'il ne l'est pour aucune autre configuration;</li>
<li>vous pouvez écrire du code pour le compilateur
optimisateur de votre nouveau langage. (c'est là une
activité à laquelle peu se livrent, et encore,
rarement.)</li>
</ul>
<h3>Les inconvénients de l'assembleur</h3>
<p>L'assembleur est un langage très bas niveau (le langage
du plus bas niveau qui soit au dessus du codage à la main de
motifs d'instructions en binaire). En conséquence:</p>
<ul>
<li>l'écriture de code en est longue et ennuyeuse;</li>
<li>les bogues apparaissent aisément;</li>
<li>les bogues sont difficiles à repérer et
supprimer;</li>
<li>il est difficile de comprendre et de modifier du code (la
maintenance est très compliquée);</li>
<li>le résultat est extrêmement peu portable vers une
autre architecture, existante ou future;</li>
<li>votre code ne sera optimisé que une certaine
implémentation d'une même architecture: ainsi, parmi
les plates-formes compatibles Intel, chaque réalisation d'un
processeur et de ses variantes (largeur du bus, vitesse et taille
relatives des CPU/caches/RAM/Bus/disques, présence ou non
d'un coprocesseur arithmétique, et d'extensions MMX ou
autres) implique des techniques d'optimisations parfois
radicalement différentes. Ainsi diffèrent grandement
les processeurs déjà existant et leurs variations:
Intel 386, 486, Pentium, PPro, Pentium II; Cyrix 5x86, 6x86; AMD
K5, K6. Et ce n'est sûrement pas terminé: de nouveaux
modèles apparaissent continuellement, et cette liste
même sera rapidement dépassée, sans parler du
code ``optimisé'' qui aura été écrit
pour l'un quelconque des processeurs ci-dessus.</li>
<li>le code peut également ne pas être portable entre
différents systèmes d'exploitation sur la même
architecture, par manque d'outils adaptés (GAS semble
fonctionner sur toutes les plates-formes; NASM semble fonctionner
ou être facilement adaptable sur toutes les plates-formes
compatibles Intel);</li>
<li>un temps incroyable de programmation sera perdu sur de menus
détails, plutôt que d'être efficacement
utilisé pour la conception et le choix des algorithmes
utilisés, alors que ces derniers sont connus pour être
la source de la majeure partie des gains en vitesse d'un programme.
Par exemple, un grand temps peut être passé à
grapiller quelques cycles en écrivant des routines rapides
de manipulation de chaînes ou de listes, alors qu'un
remplacement de la structure de données à un haut
niveau, par des arbres équilibrés et/ou des tables de
hachage permettraient immédiatement un grand gain en
vitesse, et une parallélisation aisée, de
façon portable permettant un entretien facile.</li>
<li>une petite modification dans la conception algorithmique d'un
programme anéantit la validité du code assembleur si
patiemment élaboré, réduisant les
développeurs au dilemne de sacrifier le fruit de leur
labeur, ou de s'enchaîner à une conception
algorithmique obsolète.</li>
<li>pour des programmes qui fait des choses non point trop
éloignées de ce que font les benchmarks standards,
les compilateurs/optimiseurs commerciaux produisent du code plus
rapide que le code assembleur écrit à la main (c'est
moins vrai sur les architectures x86 que sur les architectures
RISC, et sans doute moins vrai encore pour les compilateurs
librement disponible. Toujours est-il que pour du code C typique,
GCC est plus qu'honorable).</li>
<li>Quoi qu'il en soit, ains le dit le saige John Levine,
modérateur de comp.compilers, "les compilateurs rendent
aisée l'utilisation de structures de données
complexes; ils ne s'arrêtent pas, morts d'ennui, à
mi-chemin du travail, et produisent du code de qualité tout
à fait satisfaisante". Ils permettent également de
propager <em>correctement</em> les transformations du code à
travers l'ensemble du programme, aussi hénaurme soit-il, et
peuvent optimiser le code par-delà les frontières
entre procédures ou entre modules.</li>
</ul>
<h3>Affirmation</h3>
<p>En pesant le pour et le contre, on peut conclure que si
l'assembleur est parfois nécessaire, et peut même
être utile dans certains cas où il ne l'est pas, il
vaut mieux:</p>
<ul>
<li>minimiser l'utilisation de code écrit en
assembleur;</li>
<li>encapsuler ce code dans des interfaces bien
définies;</li>
<li>engendrer automatiquement le code assembleur à partir de
motifs écrits dans un langage plus de haut niveau que
l'assembleur (par exemple, des macros contenant de l'assembleur
en-ligne, avec GCC);</li>
<li>utiliser des outils automatiques pour transformer ces
programmes en code assembleur;</li>
<li>faire en sorte que le code soit optimisé, si
possible;</li>
<li>utiliser toutes les techniques précédentes
à la fois, c'est-à-dire écrire ou
étendre la passe d'optimisation d'un compilateur.</li>
</ul>
<p>Même dans les cas où l'assembleur est
nécessaire (par exemple lors de développement d'un
système d'exploitation), ce n'est qu'à petite dose,
et sans infirmer les principes ci-dessus.</p>
<p>Consultez à ce sujet les sources du noyau de Linux: vous
verrez qu'il s'y trouve juste le peu qu'il faut d'assembleur, ce
qui permet d'avoir un système d'exploitation rapide, fiable,
portable et d'entretien facile. Même un jeu très
célèbre comme DOOM a été en sa plus
grande partie écrit en C, avec une toute petite routine
d'affichage en assembleur pour accélérer un peu.</p>
<h2><a name="ss2.2">2.2 Comment ne pas utiliser
l'assembleur</a></h2>
<h3>Méthode générale pour obtenir du code
efficace</h3>
<p>Comme le dit Charles Fiterman dans comp.compilers à
propos de la différence entre code écrit par l'homme
ou la machine,</p>
<p>``L'homme devrait toujours gagner, et voici pourquoi:</p>
<ul>
<li>Premièrement, l'homme écrit tout dans un langage
de haut nivrau.</li>
<li>Deuxièmement, il mesure les temps
d'éxécution (profiling) pour déterminer les
endroits où le programme passe la majeure partie du
temps.</li>
<li>Troisièmement, il demande au compilateur d'engendrer le
code assembleur produit pour ces petites sections de code.</li>
<li>Enfin, il effectue à la main modifications et
réglages, à la recherche des petites
améliorations possibles par rapport au code engendré
par la machine.</li>
</ul>
L'homme gagne parce qu'il peut utiliser la machine.''
<h3>Langages avec des compilateurs optimisateurs</h3>
<p>Des langages comme ObjectiveCAML, SML, CommonLISP, Scheme, ADA,
Pascal, C, C++, parmi tant d'autres, ont tous des compilateurs
optimiseurs librement disponibles, qui optimiseront le gros de vos
programmes, et produiront souvent du code meilleur que de
l'assembleur fait-main, même pour des boucles serrées,
tout en vous permettant de vous concentrer sur des détails
haut niveau, et sans vous interdire de gagner par la méthode
précédente quelques pourcents de performance
supplémentaire, une fois la phase de conception
générale terminée. Bien sûr, il existe
également des compilateurs optimiseurs commerciaux pour la
plupart de ces langages.</p>
<p>Certains langages ont des compilateurs qui produisent du code C
qui peut ensuite être optimisé par un compilateur C.
C'est le cas des langages LISP, Scheme, Perl, ainsi que de nombreux
autres. La vitesse des programmes obtenus est toute à fait
satisfaisante.</p>
<h3>Procédure générale à suivre pour
accélerer votre code</h3>
<p>Pour accélérer votre code, vous ne devriez traiter
que les portions d'un programme qu'un outil de mesure de temps
d'éxécution (profiler) aura identifié comme
étant un goulot d'étranglement pour la performance de
votre programme.</p>
<p>Ainsi, si vous identifiez une partie du code comme étant
trop lente, vous devriez</p>
<ul>
<li>d'abord essayer d'utiliser un meilleur algorithme;</li>
<li>essayer de la compiler au lieu de l'interpréter;</li>
<li>essayer d'activer les bonnes options d'optimisation de votre
compilateur;</li>
<li>donner au compilateur des indices d'optimisation
(déclarations de typage en LISP; utilisation des extensions
GNU avec GCC; la plupart des compilos fourmillent d'options);</li>
<li>enfin de compte seulement, se mettre à l'assembleur si
nécessaire.</li>
</ul>
<p>Enfin, avant d'en venir à cette dernière option,
vous devriez inspecter le code généré pour
vérifier que le problème vient effectivement d'une
mauvaise génération de code, car il se peut fort bien
que ce ne soit pas le cas: le code produit par le compilateur
pourrait être meilleur que celui que vous auriez
écrit, en particulier sur les architectures modernes
à pipelines multiples! Il se peut que les portions les plus
lentes de votre programme le soit pour des raisons
intrinsèques. Les plus gros problèmes sur les
architectures modernes à processeur rapide sont dues aux
délais introduits par les accès mémoires,
manqués des caches et TLB, fautes de page; l'optimisation
des registres devient vaine, et il vaut mieux repenser les
structures de données et l'enchaînement des routines
pour obtenir une meilleur localité des accès
mémoire. Il est possible qu'une approche complètement
différente du problème soit alors utile.</p>
<h3>Inspection du code produit par le compilateur</h3>
<p>Il existe de nombreuses raisons pour vouloir regarder le code
assembleur produit par le compilateur. Voici ce que vous pourrez
faire avec ce code:</p>
<ul>
<li>vérifier si le code produit peut ou non être
améliorer avec du code assembleur écrit à la
main (ou par un réglage différent des options du
compilateur);</li>
<li>quand c'est le cas, commencer à partir de code
automatiquement engendré et le modifier plutôt que de
repartir de zéro;</li>
<li>plus généralement, utilisez le code produit comme
des scions à greffer, ce qui à tout le moins vous
laisse permet d'avoir gratuitement tout le code
d'interfaçage avec le monde extérieur.</li>
<li>repérer des bogues éventuels dus au compilateur
lui-même (espérons-le très rare, quitte
à se restreindre à des versions ``stables'' du
compilo).</li>
</ul>
<p>La manière standard d'obtenir le code assembleur
généré est d'appeller le compilateur avec
l'option <code>-S</code>. Cela fonctionne avec la plupart des
compilateur Unix y compris le compilateur GNU C (GCC); mais
à vous de voir dans votre cas. Pour ce qui est de GCC, il
produira un code un peu plus compréhensible avec l'option
<code>-fverbose-asm</code>. Bien sur, si vous souhaitez obtenir du
code assembleur optimisé, n'oubliez pas d'ajouter les
options et indices d'optimisation appropriées!</p>
<h2><a name="s3">3. Assembleurs</a></h2>
<h2><a name="ss3.1">3.1 Assembleur en-ligne de GCC</a></h2>
<p>Le célèbre GNU C/C++ Compiler (GCC), est un
compilateur 32 bits optimisant situé au coeur du projet GNU.
Il gère assez bien les architectures x86 et permet
d'insérer du code assembleur à l'intérieur de
programmes C de telle manière que les registres puissent
être soit spécifiés soit laissé aux bons
soins de GCC. GCC fonctionne sur la plupart des plates-formes dont
Linux, *BSD, VSTa, OS/2, *DOS, Win*, etc.</p>
<h3>Où trouver GCC</h3>
<p>Le site principal de GCC est le site FTP du projet GNU: <a href=
"ftp://prep.ai.mit.edu/pub/gnu/">ftp://prep.ai.mit.edu/pub/gnu/</a>
On y trouve également toutes les applications provenant du
projet GNU. Des versions configurées ou
précompilées pour Linux sont disponibles sur <a href=
"ftp://sunsite.unc.edu/pub/Linux/GCC/">ftp://sunsite.unc.edu/pub/Linux/GCC/</a>.
Il existe un grand nombre de miroirs FTP des deux sites partout de
par le monde, aussi bien que des copies sur CD-ROM.</p>
<p>Le groupe de développement de GCC s'est récemment
scindé en deux; pour plus d'informations sur la version
expérimentale, egcs, voir <a href=
"http://www.cygnus.com/egcs/">http://www.cygnus.com/egcs/</a></p>
<p>Les sources adaptés à votre système
d'exploitation préféré ainsi que les binaires
précompilés peuvent être trouvés sur les
sites FTP courants.</p>
<p>Le portage le plus célèbre de GCC pour DOS est
DJGPP et il peut être trouvé dans le répertoire
du même nom sur les sites ftp. Voir:</p>
<p><a href=
"http://www.delorie.com/djgpp/">http://www.delorie.com/djgpp/</a></p>
<p>Il existe également un portage de GCC pour OS/2
appelé EMX qui fonctionne également sous DOS et
inclut un grand nombre de routines d'émulation Unix. Voir
les sites</p>
<p><a href=
"http://www.leo.org/pub/comp/os/os2/gnu/emx+gcc/">http://www.leo.org/pub/comp/os/os2/gnu/emx+gcc/</a></p>
<p><a href=
"http://warp.eecs.berkeley.edu/os2/software/shareware/emx.html">http://warp.eecs.berkeley.edu/os2/software/shareware/emx.html</a></p>
<p><a href=
"ftp://ftp-os2.cdrom.com/pub/os2/emx09c/">ftp://ftp-os2.cdrom.com/pub/os2/emx09c/</a></p>
<h3>Où trouver de la documentation sur l'assembleur en ligne
avec GCC?</h3>
<p>La document de GCC inclus les fichiers de documentation au
format texinfo. Vous pouvez les compiler avec TeX et les imprimer,
ou les convertir au format .info et les parcourir interactivement
avec emacs, ou encore les convertir au format HTML, ou en à
peu près n'importe quel format (avec les outils
adéquats). Les fichiers .info sont
généralement installés en même temps que
GCC.</p>
<p>La section à consulter est <code>C Extensions::Extended
Asm::</code></p>
<p>La section <code>Invoking GCC::Submodel Options::i386
Options::</code> peut également vous aider. En particulier,
elle donne les noms de contraintes pour les registres du i386:
abcdSDB correspondent respectivement à <code>%eax</code>,
<code>%ebx</code>, <code>%ecx</code>, <code>%edx</code>,
<code>%esi</code>, <code>%edi</code>, <code>%ebp</code> (aucune
lettre pour <code>%esp</code>).</p>
<p>Le site "DJGPP Games resource" (qui n'est pas
réservé aux seuls développeurs de jeux)
possède une page particulière sur l'assembleur:</p>
<p><a href=
"http://www.rt66.com/~brennan/djgpp/djgpp_asm.html">http://www.rt66.com/~brennan/djgpp/djgpp_asm.html</a></p>
<p>Enfin, il existe une page de la Toile appelée "DJGPP
Quick ASM Programming Guide", contenant des URL sur des FAQ, la
syntaxe assembleur AT&T x86, des informations sur l'assembleur
en ligne, et la conversion des fichiers .obj/.lib:</p>
<p><a href=
"http://remus.rutgers.edu/~avly/djasm.html">http://remus.rutgers.edu/~avly/djasm.html</a></p>
<p>GCC soutraite l'assemblage proprement dit à GAS et suit
donc sa syntaxe (voir plus bas), cela implique que l'assembleur en
ligne doit utiliser des caractères pourcents entre
apostrophes pour qu'ils soient passés à GAS. Voir la
section dédiée à GAS.</p>
<p>Vous trouverez un <em>grand</em> nombre d'exemples instructifs
dans le répertoire <code>linux/include/asm-i386/</code> des
sources de Linux.</p>
<h3>Appeller GCC pour obtenir du code assembleur en ligne
correcte?</h3>
<p>Assurez-vous d'appeller gcc avec l'option <code>-O</code> (ou
<code>-O2</code>, <code>-O3</code>, etc) pour activer les
optimisations et l'assembleur en ligne. Si vous ne le faîtes
pas, votre code pourra compiler mais ne pas s'exécuter
correctement!! En fait (merci à Tim Potter,
timbo@moshpit.air.net.au), il suffit d'utiliser l'option
<code>-fasm</code>, faisant partie de toutes les
fonctionnalités activées par l'option
<code>-O</code>. Donc si vous avez des problèmes en raison
d'optimisations boguées dans votre implémentation de
gcc, vous pouvez toujours utiliser l'assembleur en ligne. De
même, utilisez l'option <code>-fno-asm</code> pour
désactiver l'assembleur en ligne (on peut se demander
pourquoi?).</p>
<p>Plus généralement, les bonnes options de
compilation à utiliser avec gcc sur les plates-formes x86
sont</p>
<hr>
<pre>
gcc -O2 -fomit-frame-pointer -m386 -Wall
</pre>
<hr>
<p><code>-O2</code> est le bon niveau d'optimisation. Les
optimisations supérieures génèrent un code un
peu plus important, mais très légèrement plus
rapide. De telles sur-optimisations peuvent être utiles que
dans le cas d'optimisations de boucles que vous pouvez toujours
réaliser en assembleur. Si vous avez besoin de faire ce
genre de choses, ne le faîtes que pour les routines qui en
ont besoin.</p>
<p><code>-fomit-frame-pointer</code> permet au code
généré de se passer de la gestion inutile des
pointeurs de fenêtre, ce qui rend le code plus petit plus
rapide et libère un registre pour de plus amples
optimisations. Cette option exclue l'utilisation des outils de
déboggage (<code>gdb</code>), mais lorsque vous les
utilisez, la taille et la vitesse importent peu.</p>
<p><code>-m386</code> génère un code plus compacte
sans ralentissement notable, (moins de code signifie
également mois d'entrées/sorties sur disque et donc
une exécution plus rapide). Vous pouvez également
utiliser l'option -mpentium sur la version GCC gérant
l'optimisation pour ce processeur.</p>
<p><code>-Wall</code> active toutes les mises-en-garde (warning) et
vous évite de nombreuses erreurs stupides et
évidentes.</p>
<p>Pour optimiser encore plus, vous pouvez utiliser l'option
<code>-mregparm=2</code> et/ou les attributs de fonctions qui
peuvent être utilisés mais ils peuvent dans certains
cas poser de nombreux problèmes lors de l'édition de
liens avec du code externe (notamment les bibliothèques
partagées)...</p>
<p>Notez que vous pouvez ajoutez ces options aux options
utilisées par défaut sur votre système en
éditant le fichier
<code>/usr/lib/gcc-lib/i486-linux/2.7.2.3/specs</code> (cependant,
ne rajoutez pas <code>-Wall</code> à ces options).</p>
<h2><a name="ss3.2">3.2 GAS</a></h2>
<p>GAS est l'assembleur GNU, utilisé par gcc.</p>
<h3>Où le trouver?</h3>
<p>Au même endroit où vous avez trouvé gcc,
dans le paquetage binutils.</p>
<h3>Qu'est-ce que la syntaxe AT&T</h3>
<p>Comme GAS a été inventé pour supporter un
compilateur 32 bits sous unix, il utilise la syntaxe standard
"AT&T", qui ressemblent assez à l'assembleur m68k. La
syntaxe n'est ni pire, ni meilleur que la syntaxe "Intel". Elle est
juste différente. Lorsque vous aurez l'habitude de vous en
servir, vous la trouverez plus régulière que la
syntaxe Intel, quoique que légèrement plus ennuyeuse
aussi.</p>
<p>Voici les points les plus importants à propos de la
syntaxe de GAS:</p>
<ul>
<li>Les noms de registres sont préfixés avec
<code>%</code>, de façon que les registres sont
<code>%eax</code>, <code>%dl</code> et consorts au lieu de juste
<code>eax</code>, <code>dl</code>, etc. Ceci rend possible
l'inclusion directe de noms de symboles externes C sans risque de
confusion, ou de nécessité de préfixes _.</li>
<li>L'ordre des opérandes est source(s) d'abord, destination
en dernier, à l'opposé de la convention d'intel
consistant à mettre la destination en premier, les source(s)
ensuite. Ainsi, ce qui en syntaxe intel s'écrit <code>mov
ax,dx</code> (affecter au registre <code>ax</code> le contentu du
registre <code>dx</code>) s'écrira en syntaxe att <code>mov
%dx, %ax</code>.</li>
<li>La longueur des opérandes est spécifiée
comme suffixe du nom d'instruction. Le suffixe est <code>b</code>
pour un octet (8 bit), <code>w</code> pour un mot (16 bit), et
<code>l</code> pour un mot long (32 bit). Par exemple, la syntaxe
correcte pour l'instruction ci-dessus aurait dû être
<code>movw %dx,%ax</code>. Toutefois, gas n'est pas trop aussi
strict que la syntaxe att l'exige, et le suffixe est optionel quand
la longueur peut être devinée grâce aux
opérandes qui sont des registres, la taille par
défaut étant 32 bit (avec une mise en garde quand on
y fait appel).</li>
<li>Les opérandes immediates sont marqués d'un
préfixe <code>$</code>, comme dans <code>addl $5,%eax</code>
(ajouter la valeur longue immédiate 5 au registre
<code>%eax</code>).</li>
<li>L'absence de préfixe à une opérande
indique une adresse mémoire; ainsi <code>movl
$foo,%eax</code> met l'<em>adresse</em> de la variable
<code>foo</code> dans le registre <code>%eax</code>, tandis que
<code>movl foo,%eax</code> met le <code>contenu</code> de la
variable <code>foo</code> dans le registre <code>%eax</code>.</li>
<li>L'indexation ou l'indirection se fait en mettant entre
parenthèses le registre d'index ou la case mémoire
contenant l'indirection, comme dans <code>testb
$0x80,17(%ebp)</code> (tester le bit de poids fort de l'octet au
déplacement 17 après la case pointée par
<code>%ebp</code>).</li>
</ul>
<p>Un programme existe pour vous aider à convertir des
programmes écrits avec la syntaxe TASM en syntaxe AT&T.
Voir</p>
<p><a href=
"ftp://x2ftp.oulu.fi/pub/msdos/programming/convert/ta2asv08.zip">ftp://x2ftp.oulu.fi/pub/msdos/programming/convert/ta2asv08.zip</a></p>
<p>GAS possède une documentation complète au format
TeXinfo, qui est distribuée entre autre avec les sources.
Vous pouvez parcourir les pages .info qui en sont extraites avec
Emacs. Il y avait aussi un fichier nommé gas.doc ou as.doc
disponible autour des sources de GAS, mais il a été
fusionné avec la documentation TeXinfo. Bien sûr, en
cas de doute, l'ultime documentation est constituée par les
sources eux-mêmes! Une section qui vous intéressera
particulièrement est <code>Machine
Dependencies::i386-Dependent::</code></p>
<p>Les sources de Linux dont un bon exemple: regardez dans le
répertoire linux/arch/i386 les fichiers suivants:
<code>kernel/*.S, boot/compressed/*.S, mathemu/*.S</code></p>
<p>Si vous codez ce genre de chose, un paquetage de thread, etc
vous devriez regarder d'autres langages (OCaml, gforth, etc), ou
des paquetages sur les thread (QuickThreads, pthreads MIT,
LinuxThreads, etc).</p>
<p>Enfin générer à partir d'un programme C du
code assembleur peut vous montrer le genre d'instructions que vous
voulez. Consultez la section <a href="#doyouneedasm">Avez-vous
besoin de l'assembleur?</a> au début de ce document.</p>
<h3>mode 16 bits limité</h3>
<p>GAS est un assembleur 32 bits, conçu pour assembler le
code produit par un compilateur 32 bits. Il ne reconnaît que
d'une manière limité le mode 16 bits du i386, en
ajoutant des préfixes 32 bits aux instructions; vous
écrivez donc en réalité du code 32 bits, qui
s'exécute en mode 16 bits sur un processeur 32 bits. Dans
les deux modes, il gère les registres 16 bits, mais pas
l'adressage 16 bits. Utilisez les instructions <code>.code16</code>
et <code>.code32</code> pour basculer d'un mode à l'autre.
Notez que l'instruction assembleur en ligne
<code>asm(".code16\n")</code> autorisera gcc à
générer du code 32 bits qui fonctionnera en mode
réél!</p>
<p>Le code nécessaire pour que GAS gère le mode 16
bits aurait été ajouté par Bryan Ford
(à confirmer?). Toutefois, ce code n'est présent dans
aucune distribution de GAS que j'ai essayée (jusqu'à
binutils-2.8.1.x) ... plus d'informations à ce sujet
seraient les bienvenues dans ce HowTo.</p>
<p>Une solution bon marché pour insérer quelques
instructions 16-bit non reconnues pas GAS consiste à
définir des macros (voir plus bas) qui produisent
directement du code binaire (avec <code>.byte</code>), et ce
uniquement pour les rares instructions 16 bits dont vous avez
besoin (quasiment aucunes, si vous utilisez le <code>.code16</code>
précédement décrit, et pouvez vous permettre
de supposer que le code fonctionnera sur un processeur 32 bits).
Pour obtenir le système de codage correct, vous pouvez vous
inspirer des assembleurs 16 bits.</p>
<h2><a name="ss3.3">3.3 GASP</a></h2>
<p>GASP est un préprocesseur pour GAS. Il ajoute des macros
et une syntaxe plus souple à GAS.</p>
<h3>Où trouver gasp?</h3>
<p>gasp est livré avec gas dans le paquetage binutils
GNU.</p>
<h3>Comment il fonctionne?</h3>
<p>Cela fonctionne comme un filtre, tout comme cpp et ses
variantes. Je ne connais pas les détails, mais il est
livré avec sa propre documentation texinfo, donc
consultez-la, imprimez-la, assimilez-la. La combinaison GAS/GASP me
semble être un macro-assembleur standard.</p>
<h2><a name="ss3.4">3.4 NASM</a></h2>
<p>Du projet Netwide Assembler est issu encore un autre assembleur,
écrit en C, qui devrait être assez modulaire pour
supporter toutes les syntaxes connues et tous les formats objets
existants.</p>
<h3>Où trouver NASM?</h3>
<p><a href=
"http://www.cryogen.com/Nasm">http://www.cryogen.com/Nasm</a></p>
<p>Les versions binaires se trouvent sur votre miroir sunsite
habituel dans le répertoire <code>devel/lang/asm/</code>. Il
devrait également être disponible sous forme d'archive
.rpm ou .deb parmi les contributions à votre distribution
préférée RedHat ou Debian.</p>
<h3>Son rôle</h3>
<p>Au moment de l'écriture de ce HOWTO, NASM en est à
la version 0.96.</p>
<p>La syntaxe est à la Intel. Une gestion de macros est
intégrée.</p>
<p>Les formats objets reconnus sont <code>bin</code>,
<code>aout</code>, <code>coff</code>, <code>elf</code>,
<code>as86</code>, (DOS) <code>obj</code>, <code>win32</code>, et
<code>rdf</code> (leur propre format).</p>
<p>NASM peut être utilisée comme assembleur pour le
compilateur libre LCC.</p>
<p>Comme NASM évolue rapidement, ce HowTo peut ne pas
être à jour à son sujet. A moins que vous
n'utilisiez BCC comme compilateur 16 bit (ce qui dépasse le
cadre de ce document), vous devriez utiliser NASM plutôt que
AS86 ou MASM, car c'est un logiciel libre avec un excellent service
après-don, qui tourne sur toutes plateformes logicielles et
matérielles.</p>
<p>Note: NASM est également livré avec un
désassembleur, NDISASM.</p>
<p>Son analyseur "grammatical", écrit à la main, le
rend beaucoup plus rapide que GAS; en contrepartie, il ne
reconnaît qu'une architecture, en comparaison de la
pléthore d'architectures reconnues par GAS. Pour les
plates-formes x86, NASM semble être un choix judicieux.</p>
<h2><a name="ss3.5">3.5 AS86</a></h2>
<p>AS86 est un assembleur 80x86, à la fois 16 et 32 bits,
faisant partie du compilateur C de Bruce Evans (BCC). Il
possède une syntaxe à la Intel.</p>
<h3>Where to get AS86</h3>
<p>Une version complètement dépassée de AS86
est diffusée par HJLu juste pour compiler le noyau Linux,
dans un paquetage du nom de bin86 (actuellement version 0.4)
disponible dans le répertoire GCC des sites FTP Linux. Je
déconseille son utilisation pour toute autre chose que
compiler Linux. Cette version ne reconnaît qu'un format de
fichiers minix modifié, que ne reconnaissent ni les binutils
GNU ni aucun autre produit. Il possède de plus certains
bogues en mode 32 bits. Ne vous en servez donc vraiment que pour
compiler Linux.</p>
<p>Les versions les plus récentes de Bruce Evans
(bde@zeta.org.au) est diffusée avec la distribution FreeBSD.
Enfin, elles l'étaient! Je n'ai pas pu trouver les sources
dans la distribution 2.1. Toutefois, vous pouvez trouver les
sources dans</p>
<p><a href=
"http:///www.eleves.ens.fr:8080/home/rideau/files/bcc-95.3.12.src.tgz">
http:///www.eleves.ens.fr:8080/home/rideau/files/bcc-95.3.12.src.tgz</a></p>
<p>Le projet Linux/8086 (également appelé ELKS) s'est
d'une certaine manière chargée de maintenir bcc (mais
je ne crois pas qu'ils aient inclus les patches 32 bits). Voir les
sites <a href=
"http://www.linux.org.uk/Linux8086.html">http://www.linux.org.uk/Linux8086.html</a>
et <a href="ftp://linux.mit.edu/">ftp://linux.mit.edu/</a>.</p>
<p>Entre autres choses, ces versions plus récentes, à
la différence de celle de HJLu, gèrent le format
a.out de Linux; vous pouvez donc effectuer des éditions de
liens avec des programmes Linux, et/ou utiliser les outils
habituels provenant du paquetage binutils pour manipuler vos
données. Cette version peut co-exister sans problème
avec les versions précédentes (voir la question
à ce sujet un peu plus loin).</p>
<p>La version du 12 mars 1995 de BCC ainsi que les
précédentes a un problème qui provoque la
génération de toutes les opérations
d'empilement/dépilement de segments en 16 bits, ce qui est
particulièrement ennuyant lorsque vous développez en
mode 32 bits. Un patch est diffusé par le projet Tunes</p>
<p><a href=
"http://www.eleves.ens.fr:8080/home/rideau/Tunes/">http://www.eleves.ens.fr:8080/home/rideau/Tunes/</a></p>
<p>à partir du lien suivant:
<code>files/tgz/tunes.0.0.0.25.src.tgz</code> ou dans le
répertoire <code>LLL/i386/</code>.</p>
<p>Le patch peut également être directement
récupéré sur</p>
<p><a href=
"http://www.eleves.ens.fr:8080/home/rideau/files/as86.bcc.patch.gz">
http://www.eleves.ens.fr:8080/home/rideau/files/as86.bcc.patch.gz</a></p>
<p>Bruce Evans a accepté ce patch, donc si une version plus
récente de BCC existe, le patch devrait avoir
été intégré...</p>
<h3>Comme appeller l'assembleur?</h3>
<p>Voici l'entrée d'un Makefile GNU pour utiliser bcc pour
transformer un fichier assembleur <code>.s</code> à la fois
en un objet a.out GNU <code>.o</code> et un listing
<code>.l</code>:</p>
<hr>
<pre>
%.o %.l: %.s
bcc -3 -G -c -A-d -A-l -A$*.l -o $*.o $<
</pre>
<hr>
<p>Supprimez <code>%.l</code>, <code>-A-l</code>, et
<code>-A$*.l</code>, si vous ne voulez pas avoir de listing. Si
vous souhaitez obtenir autre chose que du a.out GNU, consultez la
documentation de bcc concernant les autres formats reconnus et/ou
utilisez le programme objcopy du paquetage binutils.</p>
<h3>Où trouver de la documentation</h3>
<p>Les documentations se trouvent dans le paquetage bcc. Des pages
de manuel sont également disponibles quelque part sur le
site de FreeBSD. Dans le doute, les sources sont assez souvent une
bonne documentation: ce n'est pas très commenté mais
le style de programmation est très simple. Vous pouvez
essayer de voir comment as86 est utilisé dans Tunes
0.0.0.25...</p>
<h3>Que faire si je ne peux plus compiler Linux avec cette nouvelle
version</h3>
<p>Linus est submergé par le courrier électronique et
mon patch pour compiler Linux avec un as86 a.out n'a pas dû
lui parvenir (!). Peu importe: conservez le as86 provenant du
paquetage bin86 dans le répertoire /usr/bin, et laissez bcc
installer le bon as86 en tant que /usr/local/libexec/i386/bcc/as
comme que de droit. Vous n'aurez jamais besoin d'appeler
explicitement ce dernier, car bcc se charge très bien de
tout, y compris la conversion en a.out Linux, lorsqu'il est
appelé avec les bonnes options. Assemblez les fichiers
uniquement en passant par bcc, et non pas en appelant as86
directement.</p>
<h2><a name="ss3.6">3.6 Autres assembleurs</a></h2>
<p>Il s'agit d'autres possibilités, qui sortent de la voie
ordinaire, pour le cas où les solutions
précédentes ne vous conviennent pas (mais je voudrais
bien savoir pourquoi?), que je ne recommande pas dans les cas
habituels, mais qui peuvent se montrer fort utiles si l'assembleur
doit faire partie intégrante du logiciel que vous concevez
(par exemple un système d'exploitation ou un environnement
de développement).</p>
<h3>L'assembleur de Win32Forth</h3>
<p>Win32Forth est un système ANS FORTH 32 bit <em>libre</em>
qui fonctionne sous Win32s, Win95, Win/NT. Il comprend un
assembleur 32 bit libre (sous forme préfixe ou postfixe)
intégrée au langage FORTH. Le traitement des macro
est effectué en utilisant toute la puissance du langage
réflexif FORTH. Toutefois, le seul contexte d'entrée
et sortie reconnu actuellement est Win32For lui-même (aucune
possibilité d'obtenir un fichier objet, mais vous pouvez
toujours l'ajouter par vous-même, bien sûr). Vous
pouvez trouver Win32For à l'adresse suivante: <a href=
"ftp://ftp.forth.org/pub/Forth/win32for/">ftp://ftp.forth.org/pub/Forth/win32for/</a></p>
<h3>Terse</h3>
<p>Terse est un outil de programmation qui fournit <em>LA</em>
syntaxe assembleur la plus compacte pour la famille des processeur
x86! Voir le site <a href=
"http://www.terse.com">http://www.terse.com</a>. Ce n'est cependant
pas un logiciel libre. Il y aurait eu un clone libre quelque part,
abandonné à la suite de mensongères
allégations de droits sur la syntaxe, que je vous invite
à ressusciter si la syntaxe vous intéresse.</p>
<h3>Assembleurs non libres et/ou non 32 bits</h3>
<p>Vous trouverez un peu plus d'informations sur eux, ainsi que sur
les bases de la programmation assembleur sur x86, dans la FAQ de
Raymond Moon pour le forum comp.lang.asm.x86. Voir <a href=
"http://www2.dgsys.com/~raymoon/faq/asmfaq.zip">http://www2.dgsys.com/~raymoon/faq/asmfaq.zip</a></p>
<p>Remarquez que tous les assembleurs DOS devraient fonctionner
avec l'émulateur DOS de Linux ainsi qu'avec d'autres
émulateurs du même genre. Aussi, si vous en
possédez un, vous pouvez toujours l'utiliser à
l'intérieur d'un vrai système d'exploitation. Les
assembleurs sous DOS assez récents gèrent
également les formats de fichiers objets COFF et/ou des
formats gérés par la bibliothèque GNU BFD de
telle manière que vous pouvez les utiliser en conjonction
avec les outils 32 bits libres, en utilisant le programme GNU
objcopy (du paquetage binutils) comme un filtre de conversion.</p>
<h2><a name="s4">4.
Méta-programmation/macro-traitement</a></h2>
<p>La programmation en assembleur est particulièrement
pénible si ce n'est pour certaines parties critiques des
programmes.</p>
<p>Pour travail donné, il faut l'outil approprié; ne
choisissez donc pas l'assembleur lorsqu'il ne correspond pas au
problème à résoudre: C, OCAML, perl, Scheme
peuvent être un meilleur choix dans la plupart des cas.</p>
<p>Toutefois, il y a certains cas où ces outils n'ont pas un
contrôle suffisamment fin sur la machine, et où
l'assembleur est utile ou nécessaire. Dans ces cas, vous
apprécierez un système de programmation par macros,
ou un système de méta-programmation, qui permet aux
motifs répétitifs d'être factorisés
chacun en une seule définition indéfiniment
réutilisable. Cela permet une programmation plus sûre,
une propagation automatique des modifications desdits motifs, etc.
Un assembleur de base souvent ne suffit pas, même pour
n'écrire que de petites routines à lier à du
code C.</p>
<h2><a name="ss4.1">4.1 Description</a></h2>
<p>Oui, je sais que cette partie peut manquer d'informations utiles
à jour. Vous êtes libres de me faire part des
découvertes que vous auriez dû faire à la
dure...</p>
<h3>GCC</h3>
<p>GCC vous permet (et vous oblige) de spécifier les
contraintes entre registres assembleurs et objets C, pour que le
compilateur puisse interfacer le code assembleur avec le code
produit par l'optimiseur. Le code assembleur en ligne est donc
constitué de motifs, et pas forcément de code
exact.</p>
<p>Et puis, vous pouvez mettre du code assembleur dans des
macro-définitions de CPP ou des fonctions "en-ligne"
(inline), de telle manière que tout le monde puisse les
utiliser comme n'importe quelle fonction ou macro C. Les fonctions
en ligne ressemblent énormément aux macros mais sont
parfois plus propres à utiliser. Méfiez-vous car dans
tous ces cas, le code sera dupliqué, et donc seules les
étiquettes locales (comme <code>1:</code>) devraient
être définies dans ce code assembleur. Toutefois, une
macro devrait permettre de passer en paramètre le nom
éventuellement nécessaire d'une étiquette
définie non localement (ou sinon, utilisez des
méthodes supplémentaires de
méta-programmation). Notez également que propager du
code assembleur en-ligne répandra les bogues potentiels
qu'il contiendrait, aussi, faites doublement attention à
donner à GCC des contraintes correctes.</p>
<p>Enfin, le langage C lui-même peut être
considéré comme étant une bonne abstraction de
la programmation assembleur, qui devrait vous éviter la
plupart des difficultés de la programmation assembleur.</p>
<p>Méfiez-vous des optimisations consistant à passer
les arguments en utilisant les registres: cela interdit aux
fonctions concernées d'être appelées par des
routines exterieurs (en particulier celles écrites à
la main en assembleur) d'une manière standard; l'attribut
asmlinkage devrait empêcher des routines données
d'être concernées par de telles options
d'optimisation. Voir les sources du noyau Linux pour avoir des
exemples.</p>
<h3>GAS</h3>
<p>GAS a quelques menues fonctionnalité pour les macro,
détaillées dans la documentation TeXinfo. De plus</p>
<p>J'ai entendu dire que les versions récentes en seront
dotées... voir les fichiers TeXinfo). De plus, tandis que
GCC reconnaît les fichiers en .s comme de l'assembleur
à envoyer dans GAS, il reconnaît aussi les fichiers en
.S comme devant être filtrer à travers CPP avant
d'être envoyer à GAS. Au risque de me
répéter, je vous convie à consulter les
sources du noyau Linux.</p>
<h3>GASP</h3>
<p>Il ajoute toutes les fonctionnalités habituelles de macro
à GAS. Voir sa documentation sous forme texinfo.</p>
<h3>NASM</h3>
<p>NASM possède aussi son système de macros.
Consultez sa documentation. Si vous avez quelqu'idée
lumineuse, contactez les auteurs, étant donné qu'ils
sont en train de développer NASM activement. Pendant ce
même temps, lisez la partie sur les filtres externes un peu
plus loin.</p>
<h3>AS86</h3>
<p>Il possède un système simple de macros, mais je
n'ai pas pu trouver de documentation. Cependant, les sources sont
d'une approche particulièrement aisée, donc si vous
êtes intéressé pour en savoir plus, vous
devriez pouvoir les comprendre sans problème. Si vous avez
besoin d'un peu plus que des bases, vous devriez utiliser un filtre
externe (voir un peu plus loin).</p>
<h3>Autres assembleurs</h3>
<ul>
<li>Win32FORTH: CODE et END-CODE sont des macros qui ne basculent
pas du mode interprétation au mode compilation; vous aurez
donc accès à toute la puissance du FORTH lors de
l'assemblage.</li>
<li>Tunes: cela ne fonctionne pas encore, mais le langage Scheme
est un langage de très haut niveau qui permet une
méta-programmation arbitraire.</li>
</ul>
<h2><a name="ss4.2">4.2 Filtres externes</a></h2>
<p>Quelque soit la gestion des macros de votre assembleur, ou
quelque soit le langage que vous utilisez (même le C), si le
langage n'est pas assez expressif pour vous, vous pouvez faire
passer vos fichier à travers un filtre externe grâce
à une règle comme suit dans votre Makefile:</p>
<hr>
<pre>
%.s: %.S autres_dépendances
$(FILTER) $(FILTER_OPTIONS) < $< > $@
</pre>
<hr>
<h3>CPP</h3>
<p>CPP n'est vraiment pas très expressif, mais il suffit
pour les choses faciles, et il est appelé d'une
manière transparente par GCC.</p>
<p>Comme exemple de limitation, vous ne pouvez pas déclarer
d'objet de façon à ce qu'un destructeur soit
automatiquement appelé à la fin du bloc ayant
déclaré l'objet. Vous n'avez pas de diversions ou de
gestion de portée des variables, etc.</p>
<p>CPP est livré avec tout compilateur C. Si vous pouvez
faire sans, n'allez pas chercher CPP (bien que je me demande
comment vous pouvez faire).</p>
<h3>M4</h3>
<p>M4 vous donne la pleine puissance du macro-traitement, avec un
langage Turing-équivalent, récursivité,
expressions régulières, etc. Vous pouvez faire avec
tout ce que cpp ne peut faire.</p>
<p>Voir macro4th/This4th que l'on trouve sur <a href=
"ftp://ftp.forth.org/pub/Forth/">ftp://ftp.forth.org/pub/Forth/</a>
dans Reviewed/ ANS/ (?), ou les sources de Tunes 0.0.0.25 comme
exemple de programmation avancée en utilisant m4.</p>
<p>Toutefois, le système de citation est très
pénible à utiliser et vous oblige à utiliser
un style de programmation par fonctions récursives avec
passage explicite de continuation (CPS) pour toute programmation
<em>avancée</em> (ce qui n'est pas sans rappeler à
TeX -- au fait quelqu'un a-t-il déjà essayé
d'utiliser TeX comme macro-processeur pour autre chose que de la
mise-en-page?). Toutefois, ce n'est pas pire que cpp qui ne permet
ni citation ni récursivité.</p>
<p>La bonne version de m4 à récupérer est GNU
m4 1.4 (ou ultérieure si elle existe). C'est celle qui
contient le plus de fonctionnalité et le moins de bogues ou
de limitations. m4 est conçu pour être
intrinsèquement lent pour toute utilisation sauf la plus
simple; cela suffit sans aucun doute pour la plupart des programmes
en assembleur (vous n'allez quand même pas écrire des
millions de lignes en assembleur, si?).</p>
<h3>Macro-traitement avec votre propre filtre</h3>
<p>Vous pouvez écrire votre propre programme d'expansion de
macro avec les outils courants comme perl, awk, sed, etc. C'est
assez rapide à faire et vous pouvez tout contrôler.
Mais bien toute puissance dans le macro-traitement doit se gagner
à la dure.</p>
<h3>Méta-programmation</h3>
<p>Plutôt que d'utiliser un filtre externe qui effectue
l'expansion des macros, une manière de réaliser cela
est d'écrire des programmes qui écrivent d'autres
programmes, en partie ou en totalité.</p>
<p>Par exemple, vous pourriez utiliser un programme
générant du code source</p>
<ul>
<li>pour créer des tables de sinus/cosinus (ou autre),</li>
<li>pour décompiler un fichier binaire en source
annoté annoté,</li>
<li>pour compiler vos bitmaps en des routines d'affichage
rapides,</li>
<li>pour extraire de la documentation, du code d'initilisation ou
finalisation, des tables de descriptions, aussi bien que du code
normal depuis les mêmes fichiers sources;</li>
<li>pour utiliser une technique spécifique de production de
code, produite avec un script perl/shell/scheme</li>
<li>pour propager des données définies en une seule
fois dans de nombreux morceaux de code ou tables avec
références croisées.</li>
<li>etc.</li>
</ul>
<p>Pensez-y!</p>
<h3>Backends provenant de compilateur existants</h3>
<p>Des compilateurs comme SML/NJ, Objective CAML, MIT-Scheme, etc,
ont leur propre générateur de code assembleur, que
vous pouvez ou non utiliser, si vous souhaitez
générer du code semi-automatiquement depuis les
langages correspondants.</p>
<h3>Le New-Jersey Machine-Code Toolkit</h3>
<p>Il s'agit projet utilisant le langage de programmation Icon pour
bâtir une base de code de manipulation d'assembleur. Voir
<a href=
"http://www.cs.virginia.edu/~nr/toolkit/">http://www.cs.virginia.edu/~nr/toolkit/</a></p>
<h3>Tunes</h3>
<p>Le projet de système d'exploitation OS développe
son propre assembleur comme étant une extension du langage
Scheme. Il ne fonctionne pas encore totalement, de l'aide est
bienvenue.</p>
<p>L'assembleur manipule des arbres de syntaxes symboliques, de
telle manière qu'il puisse servir comme base d'un traducteur
de syntaxe assembleur, un désassembleur, l'assembleur d'un
compilateur, etc. Le fait qu'il utile un vrai langage de
programmation puissant comme Scheme le rend imbatable pour le
macro-traitement et pour la méta-programmation.</p>
<p><a href=
"http://www.eleves.ens.fr:8080/home/rideau/Tunes/">http://www.eleves.ens.fr:8080/home/rideau/Tunes/</a></p>
<h2><a name="s5">5. Conventions d'appel</a></h2>
<h2><a name="ss5.1">5.1 Linux</a></h2>
<h3>Edition de liens avec GCC</h3>
<p>C'est la solution la plus pratique. Consultez la documentation
de gcc et prenez exemple sur les sources du noyau Linux (fichiers
<code>.S</code> qui sont utilisés avec gas, non pas
as86).</p>
<p>Les arguments 32 bits sont empilés dans la pile vers le
bas dans l'ordre inverse de l'ordre syntaxique (c'est-à-dire
qu'on accède aux arguments ou les dépile dans l'ordre
syntaxique), au-dessus de l'adresse de retour 32 bits.
<code>%ebp</code>, <code>%esi</code>, <code>%edi</code>,
<code>%ebx</code> doivent être conservés par
l'appelé, les autres registres peuvent être
détruits; <code>%eax</code> doit contenir le
résultat, ou <code>%edx:%eax</code> pour des
résultats sur 64 bits.</p>
<p>Pile virgule flottante: je ne suis pas sûr, mais je pense
que le résultat se trouve dans <code>st(0)</code>, la pile
étant à la discrétion de l'appelé.</p>
<p>Notez que GCC possède certaines options pour modifier les
conventions d'appel en réservant certains registres, en
mettant les arguments dans des registres, en supposant que l'on ne
possède pas de FPU, etc. Consultez les pages .info
concernant le i386.</p>
<p>Il faut prendre garde à déclarer l'attribut
<code>cdecl</code> pour une fonction qui suit la convention
standard GCC (je ne sais pas exactement ce que cela produit avec
des conventions modifiées). Consultez la documentation GCC
dans la section: <code>C Extensions::Extended Asm::</code></p>
<h3>Problèmes ELF et a.out</h3>
<p>Certains compilateurs C ajoutent un underscore avant tout
symbole, alors que d'autres ne le font pas.</p>
<p>En particulier, la version GCC a.out effectue ce genre d'ajouts,
alors que la version ELF ne le fait pas.</p>
<p>Si vous êtes confronté à ce problème,
regardez comment des paquetages existants traitent le
problèmes. Par exemple, récupérer une ancienne
arborescence des sources de Linux, Elk, les qthreads ou
OCAML...</p>
<p>Vous pouvez également redéfinir le renommage
implicite de C en assembleur en ajoutant les instructions
suivantes:</p>
<hr>
<pre>
void truc asm("machin") (void);
</pre>
<hr>
pour s'assurer que la fonction C truc sera réellement
appelée machin en assembleur.
<p>Remarquez que l'outil <code>objcopy</code>, du paquetage
<code>binutils</code>, devrait vous permettre de transformer vos
fichiers objets a.out en objets ELF et peut-être inversement
dans certains cas. D'une manière plus
générale, il vous permet d'effectuer de nombreuses
conversions de formats de fichiers.</p>
<h3>Appels systèmes directs</h3>
<p>Il n'est absolument pas recommandé d'effectuer de tels
appels par ce que leurs conventions peuvent changer de temps en
temps, ou d'un type de noyau à un autre (cf L4Linux), de
plus, ce n'est pas portable, difficile à écrire,
redondant avec l'effort entrepris par libc, et enfin, cela
empêche les corrections et les extensions effectuées
à travers la libc, comme par exemple avec le programme
<code>zlibc</code> qui réalise une décompression
à la volée de fichiers compressés avec gzip.
La manière standard et recommendée d'effectuer des
appels systèmes est et restera de passer par la libc.</p>
<p>Les objets partagés devraient réduire l'occupation
mémoire des programmes, et si vous souhaitez absolument
avoir de petits exécutables, utilisez <code>#!</code> avec
un interpréteur qui contiendra tout ce que vous ne voulez
pas mettre dans vos binaires.</p>
<p>Maintenant, si pour certaines raisons, vous ne souhaitez pas
effectuer une édition des liens avec la libc,
récupérez-la et essayez de comprendre comment elle
fonctionne! Après tout, vous prétendez bien la
remplacer non?</p>
<p>Vous pouvez aussi regarder comment <a href=
"ftp://ftp.forth.org/pub/Forth/Linux/linux-eforth-1.0c.tgz">eforth
1.0c</a> le fait.</p>
<p>Les sources de Linux sont fort utiles, en particulier le fichier
d'en-tête asm/unistd.h qui décrit comment sont
effectués les appels système...</p>
<p>Le principe général est d'utiliser l'instruction
<code>int $0x80</code> avec le numéro de l'appel
système <code>__NR_</code>machin (regarder dans
<code>asm/unistd.h</code>) dans <code>%eax</code>, et les
paramètres (jusqu'à cinq) dans <code>%ebx</code>,
<code>%ecx</code>, <code>%edx</code>, <code>%esi</code>,
<code>%edi</code>. Le résultat est renvoyé dans
<code>%eax</code> avec un résultat négatif
étant l'erreur dont l'opposé est
tranféré par la libc dans errno. La pile utilisateur
n'est pas modificée donc n'avez pas besoin d'en avoir une
correcte lors de l'appel.</p>
<h3>Entrées/sorties sous Linux</h3>
<p>Si vous souhaitez effectuer des entrées/sorties
directement sous Linux, soit il s'agit de quelque chose de
très simple qui n'a pas besoin de spécificités
du système et dans ce cas là, consultez le mini-HOWTO
<code>IO-Port-Programming</code>, ou alors vous devez créer
un nouveau gestionnaire de périphérique et vous
devriez alors lire quelques documents sur les méandres du
noyau, le développement de gestionnaires de
périphériques, les modules du noyau, etc. Vous
trouverez d'excellents HOWTO ou autres documents du projet LDP.</p>
<p>Plus particulièrement, si vous souhaitez réaliser
des programmes graphiques, rejoignez le projet GGI: <a href=
"http://synergy.caltech.edu/~ggi/">http://synergy.caltech.edu/~ggi/</a>
<a href=
"http://sunserver1.rz.uni-duesseldorf.de/~becka/doc/scrdrv.html">http://sunserver1.rz.uni-duesseldorf.de/~becka/doc/scrdrv.html</a></p>
<p>Dans tous les cas, vous devriez plutôt utiliser
l'assembleur en ligne de GCC avec les macros provenant des fichiers
linux/asm/*.h que d'écrire des sources en assembleur
pur.</p>
<h3>Accéder aux gestionnaires 16 bits avec Linux/i386</h3>
<p>De telles choses sont théoriquement possibles (preuve:
voir comment DOSEMU permet à des programmes d'accéder
au port série), et j'ai entendu des rumeurs que certaines
personnes le font (avec le gestionnaire PCI? Accès aux
cartes VESA? PnP ISA? Je ne sais pas). Si vous avez de plus amples
précisions à ce sujet, soyez les bienvenus. Le bon
endroit à regarder est les sources du noyau, les sources de
DOSEMU (et des autres programmes se trouvant dans <a href=
"ftp://tsx-11.mit.edu/pub/linux/ALPHA/dosemu/">le répertoire
DOSEMU</a>), ainsi que les sources d'autres programmes bas niveaux
(peut-être GGI s'il gère les cartes VESA).</p>
<p>En fait, vous devez utiliser soit le mode protégé
16 bits, soit le mode vm86.</p>
<p>Le premier est plus simple à configurer mais il ne
fonctionne qu'avec du code ayant un comportement propre qui
n'effectue pas d'arithmétique de segments ou d'adressage
absolu de segment (en particulier pour l'adressage du segment 0),
à moins que par chance tous les segments utilisés
peuvent être configuré à l'avance dans le
LDT.</p>
<p>La seconde possiblité permet d'être plus
"compatibles" avec les environnements 16 bits mais il
nécessite une gestion bien plus compliquée.</p>
<p>Dans les deux cas, avant de sauter sur le code 16 bits, vous
devez:</p>
<ul>
<li>mmapper toute adresse absolue utilisée dans le code 16
bits (comme la ROM, les tampons vidéo, les adresses DMA et
les entrées/sorties passant des zones de mémoires
mappées) à partir de /dev/mem dans votre espace
d'adressage de votre processus.</li>
<li>configurer le LDT et/ou le moniteur en mode vm86.</li>
<li>demander au noyau les droits d'accès nécessaires
pour les entrées/sorties (voir plus haut).</li>
</ul>
<p>Encore une fois, lisez attentivement les codes sources
situés dans le répertoire de DOSEMU et consorts, en
particulier ces mini-émulateurs permettant de faire tourner
des programmes ELKS et/ou des .COM assez simples sous
Linux/i386.</p>
<h2><a name="ss5.2">5.2 DOS</a></h2>
<p>La plupart des émulateurs DOS sont livrés avec
certaines interfaces d'accès aux services DOS. Lisez leur
documentation à ce sujet, mais bien souvent, ils ne font que
simuler <code>int $0x21</code> et ainsi de suite, donc c'est comme
si vous étiez en mode réel (je doute qu'ils aient de
possibilités de fonctionner avec des opérandes 32
bits: ils ne font que réfléchir l'interruption dans
le mode réel ou dans le gestionnaire vm86).</p>
<p>Certaines documentations concernant DPMI (ou ses variantes
peuvent) être trouvées sur <a href=
"ftp://x2ftp.oulu.fi/pub/msdos/programming/">ftp://x2ftp.oulu.fi/pub/msdos/programming/</a></p>
<p>DJGPP est livré avec son propre sous-ensemble,
dérivé, ou remplacement (limité) de la
glibc.</p>
<p>Il est possible d'effectuer une compilation croisée de
Linux vers DOS. Consultez le répertoire devel/msdos/ de
votre miroir FTP de sunsite.unc.edu. Voir également le
dos-extender MOSS du projet Flux d'utah.</p>
<p>D'autres documentations et FAQ sont plus consacrés
à DOS. Nous déconseillons le développement
sous DOS.</p>
<h2><a name="ss5.3">5.3 Windauberies...</a></h2>
<p>Heu, ce document ne traite que de libre logiciel.
Téléphonez-moi lorsque Windaube le deviendra ou du
moins ses outils de développement!</p>
<p>En fait, après tout, cela existe: <a href=
"http://www.cygnus.com">Cygnus Solutions</a> a
développé la bibliothèque cygwin32.dll pour
que les programmes GNU puissent fonctionner sur les machines
MicroMerdiques. Donc, vous pouvez utiliser GCC, GAS et tous les
outils GNU ainsi que bon nombre d'applications Unix. Consultez leur
site Web. Je (Faré) ne souhaite pas m'étendre sur la
programmation sous Windaube, mais je suis sûr que vous
trouverez tout un tas d'informations partout...</p>
<h2><a name="ss5.4">5.4 Votre propre système
d'exploitation</a></h2>
<p>Le contrôle sur le système étant ce qui
attire de nombreux programmeurs vers l'assembleur, une
prémisse ou un corollaire naturel de son utilisation est la
volonté de développer son propre système
d'exploitation. Remarquons tout d'abord que tout système
permettant son auto-développement pourrait être
qualifié de système d'exploitation, combien
même tournerait-il au-dessus d'un autre système sur
lequel il se déchargerait de la gestion du multitâche
(Linux sur Mach) ou des entrées/sorties (OpenGenera sur
Digital Unix), etc. Donc, pour simplifier le débogage, vous
pouvez souhaiter développer votre système
d'exploitation comme étant un processus fonctionnant sous
Linux (au prix d'un certain ralentissement), puis, utiliser le
<a href="http://ww.cs.utah.edu/projects/flux/">Flux OS kit</a> (qui
permet l'utilisation des drivers Linux et BSD dans votre propre
système d'exploitation) pour le rendre indépendant.
Lorsque votre système est stable, il est toujours temps
d'écrire vos propres gestionnaires de matériels si
c'est vraiment votre passion.</p>
<p>Ce HowTo ne couvrira pas des sujets comme le code de chargement
du système, le passage en mode 32 bits, la gestion des
interruptions, les bases concernant les horreurs des processeurs
Intel (mode protégé, V86/R86), la définition
de votre format d'objets ou de vos conventions d'appel. L'endroit
où vous pourrez trouver le plus d'informations concernant
tous ces sujets est le code source de système
déjà existants.</p>
<p>Un grand nombre de pointeurs se trouvent dans la page: <a href=
"http://www.eleves.ens.fr:8080/home/rideau/Tunes/Review/OSes.html">http://www.eleves.ens.fr:8080/home/rideau/Tunes/Review/OSes.html</a></p>
<h2><a name="s6">6. A faire et pointeurs</a></h2>
<ul>
<li>compléter les sections incomplètes;</li>
<li>ajouter des pointeurs sur des programmes et des
documentations;</li>
<li>ajouter des exemples de tous les jours pour illustrer la
syntaxe, la puissance et les limitation de chacune des solutions
proposées;</li>
<li>demander aux gens de me donner un coup de main;</li>
<li>trouver quelqu'un qui a assez de temps pour prendre en charge
la maintenance de ce HOWTO;</li>
<li>peut-être dire quelques mots sur l'assembleur d'autres
plates-formes?</li>
<li>Quelques pointeurs (en plus de ceux qui se trouvent dans ce
document)
<ul>
<li><a href="http://www.intel.com/design/pentium/manuals/">pages de
manuel pour pentium</a></li>
<li><a href="http://www.eng.ufl.edu/ftp">hornet.eng.ufl.edu pour
les codages assembleurs</a></li>
<li><a href=
"ftp://ftp.luth.se/pub/msdos/demos/code/">ftp.luth.se</a></li>
<li><a href="ftp://zfja-gate.fuw.edu.pl/cpu/protect.mod">PM
FAQ</a></li>
<li><a href="http://www.fys.ruu.nl/~faber/Amain.html">Page
Assembleur 80x86</a></li>
<li><a href=
"http://www.cit.ac.nz/smac/csware.htm">Courseware</a></li>
<li><a href=
"http://www.ee.ucl.ac.uk/~phart/gameprog.html">programmation de
jeux</a></li>
<li><a href="http://bewoner.dma.be/JanW">experiences de
programmation sous Linux exclusivement en assembleur</a></li>
</ul>
</li>
<li>Et bien sur, utilisez vos outils habituels de recherche sur
Internet pour trouver les informations. Merci de m'envoyer tout ce
que vous trouvez d'interessant.</li>
</ul>
<p>Signature de l'auteur:</p>
<pre>
-- , , _ v ~ ^ --
--
-- Fare -- rideau@clipper.ens.fr -- Francois-Rene Rideau -- +)ang-Vu Ban --
-- ' / . --
Join the TUNES project for a computing system based on computing freedom!
TUNES is a Useful, Not Expedient System
WWW page at URL: http://www.eleves.ens.fr:8080/home/rideau/Tunes/
</pre>
</body>
</html>
|