====== MIC1 Errata divers ======
===== TD3-linux1=====
* Dans l'exemple comparatif, les constantes devraient s'écrire en majuscule, soit DEUX --Pbt
* À la page 3, on vous informe qu'il est possible de compiler //via// gcc. Dans notre cas, on compile en utilisant **nasm**. On peut par contre faire **l'édition des liens** avec gcc ou ld. --Pbt
* À la page 3, on vous parle d'un fichier //SurfTri.exe//, c'est une erreur, c'est bien //SurfTri//. Conceptuellement, on peut ajouter une extension .exe aux binaires sous linux mais ce n'est pas l'habitude. Par convention, les fichiers binaires n'ont pas d'extensions et s'écrivent tout en minuscules. --Pbt
* À la page 5, pour l'exercice utilisant l'intruction //chmod//, on vous parle de la syntaxe "octale" du l'instruction, pas de sa syntaxe "+/-". Remarquez qu'avec //nasm// vous pouvez utiliser le préfixe //0// pour les nombres octaux ou le suffixe //q//. À votre meilleure convenance. --Pbt
chmod file 555
chmod go-r file
* À la page 7 dans l'exercice portant sur //monCat//, on vous propose d'utiliser **fflush** pour imposer l'écriture du buffer. Ça ne fonctionnera pas ! C'est l'OS qui bufferise et la librairie C (stdio) ne peut rien y faire --même //sync// ne sera pas utile dans ce cas car je ne traite pas de disque mais stdout et stdin. --Pbt
* Toujours dans le même ordre d'idée, je signale qu'il faut éviter de mélanger les appels systèmes //read/write// avec les fonctions de la librairie //stdio// genre ... //fflush//, //putchar//, //getchar// ... en petit cadeau, deux codes pour **moncat**; un code "bas niveau" et un code de plus "haut niveau".
; nasm moncat-2-int80.asm -f elf
; ld moncat-2-int80.o -o moncat-2-int80
;
; Pas de possibilité d'écrire fflush dans ce code
; (il vaut mieux éviter de mélanger syscall (read/write) et
; stdio
SECTION .data
buf DB 0
SECTION .code
GLOBAL _start
_start:
.while
; read 3 (fd,buf, count)
mov EAX,3
mov EBX,0
mov ECX,buf
mov EDX,1
int 0x80
cmp EAX,0
jle .endwhile
; write 4 (fd, buf, count)
mov EAX,4
mov EBX,1
mov ECX,buf
mov EDX,1
int 0x80
jmp .while
.endwhile
mov EAX,1
mov EBX,0
int 0x80
; nasm moncat-3-stdio.asm -f elf
; gcc moncat-3-stdio.o -o moncat-3-stdio
EXTERN getchar
EXTERN putchar
EXTERN fflush
EOF EQU -1
SECTION .data
c DD 0
SECTION .code
GLOBAL main
main
.while
call getchar
mov [c],EAX
cmp EAX,EOF
je .endwhile
push dword [c]
call putchar
add esp,4*1
; Un fflush ne change rien, l'OS n'autorise pas un flush après chaque
; char
;push dword 0
;call fflush
;add esp,4*1
jmp .while
.endwhile
ret
===== TD2-dos2=====
* Page 1, remplacer le //label// **SI** par un autre, puisque **SI** représente un label.
* Page 1, code d'exemple, remplacer jne alors par **je sinon**. Adapter le commentaire en conséquence.
* Exercice 5, remplacer le '6' par un '8' dans l'exercice sur les masques et les divisibilités par 2^i
* Exercice 5, **shl**, devient **shr**.
====Remarques générales====
Les conventions d'écriture ((Ce sont bien des **conventions**, ce n'est pas imposé par le compilateur)) ne sont pas les mêmes que dans les //slides//. Pour rappel, on utilise les majuscules pour les directives et les registres et des minuscules sinon. --Pbt
Au sujet des différents modes d'adressage que l'on vous conseille de //relire//. Vous pouvez consulter le document d'intel [[http://localhost/esi/brol/mic/doc/IA-32IntelArchitectureSoftwareDevelopersManual_1BasicArchitecture.pdf|(PDF)]] au point 3.7, page 3.26, page 86 du pdf. Le point 3.7.5 à la page 88 du document vous intéressera plus particulièrement. --Pbt
=====Questions=====
=====Archives=====
==== (2006-2007) TD3-linux, Le jeu de l'oie ====
Comme promis, j'explique ici le point algorithmiquement "difficile" du TD.
===Aspect logique===
Il s'agit de parcourir un tableau (**plateau**) de la forme
|1 |2 |3 |
|8 |9 |4 |
|7 |6 |5 |
La manière la plus simple (à mon sens) est de me créer un tableau (**parcours**) faisant le lien entre le plateau et mon avancée sur ledit plateau. Mon avancée est renseignée dans une variable //position// simplement incrémentée de la valeur du dé. Ma //position// commence à 0 lorsque je me trouve sur la **case 1**
Comme en assembleur tous les tableaux sont des tableaux à une dimension (les autres sont une "vue de l'esprit"), je vais associer à chaque valeur son index (je le note entre parenthèses afin de bien montrer sa valeur). J'ai donc
|**1**(0) |**2**(1) |**3**(2) |
|**8**(3) |**9**(4) |**4**(5) |
|**7**(6) |**6**(7) |**5**(8) |
Mon tableau //parcours// permettant le lien entre ma position (avancée) et ma position sur le plateau sera
parcours = 0 1 2 5 8 7 6 3 4
Ainsi, si je suis sur la case 2 (position 1) et que j'avance de 3 -ma position devient 4- je me déplace dans mon plateau à la position, parcours[4], soit 8 ... et je suis bien sur la case 5 du plateau de jeu (//cette dernière phrase doit se lire lentement//).
**Notez bien** : Ne passez à la section suivante qu'après avoir bien compris cette section ;-)
===Techniquement en assembleur===
En assembleur, je dois tenir compte de quelques aspects techniques. En effet, je veux afficher le plateau, il doit donc être composé de **caractères** et pas de "valeurs". Je dois aussi marquer le retour à la ligne. La numérotation de parcours **change** puisque je dois tenir compte de la //case retour à la ligne//
|**1**(0) |**2**(1) |**3**(2) | LF(3) |
|**8**(4) |**9**(5) |**4**(6) | LF(7) |
|**7**(8) |**6**(9) |**5**(10)| LF(11)|
Et voilà ce que ça donne en assembleur.
plateau DB " 1 "," 2 "," 3 "," ",10
DB " 8 "," 9 "," 4 "," ",10
DB " 7 "," 6 "," 5 "," ",10
parcours DB 0,1,2,6,10,9,8,4,5
position DB ? ; mon avancée dans le jeu
J'ai choisi de prendre 3 caractères pour représenter une case, ma "correspondance" se fera donc avec quelque chose de la forme (que vous traduirez en assembleur)
plateau[parcours[position]*3]