Differences

This shows you the differences between two versions of the page.

Link to this comparison view

codaz:asm:l_assembleur_pour_lutins_presses_3 [2010/01/12 13:29] (current)
Line 1: Line 1:
 +====== L'ASM efficace pour lutins pressés ======
  
 +===== PART III =====
 +
 +
 +Dans cet ultime volet nous nous attaquerons à la conception d'un serveur socket. Oulaaaa.. chôôôoo.. OUI ! MAIS ! C'est l'​assurance d'un poil brillant pour toute l'​année! Alors, partant?.. Coquin(e) va :)
 +
 +
 +==== I - Le code mystérieux et magique ====
 +
 +Le code si dessous s'​acquitte d'une tache simple: accepter une connexion, lire les données qu'on lui envoie et renvoyer un anagramme dès que l'​utilisateur appuie sur la touche entrée. Si l'​utilisateur ne saisis rien et appuie sur la touche entrée, l'​application se termine.
 +
 +<​code>​
 +     ​1 section .bss
 +     ​2 buffer:​ resb 256
 +     3
 +     ​4 section .text
 +     ​5 global main
 +     ​6 extern strfry
 +     ​7 extern strlen
 +     ​8 extern fprintf
 +     ​9 extern puts
 +    10 extern socket
 +    11 extern bind
 +    12 extern dup2
 +    13 extern accept
 +    14 extern listen
 +    15 extern read
 +    16 extern write
 +    17 extern close
 +    18 extern perror
 +    19
 +    20 section .rodata
 +    21 KERN:​ equ 0x80
 +    22 STDIN:​ equ 0
 +    23 STDOUT:​ equ 1
 +    24 STDERR:​ equ 2
 +    25 AF_INET:​ equ 2
 +    26 SOCK_STREAM:​ equ 1
 +    27 IPPROTO_TCP:​ equ 6
 +    28 INADDR_ANY:​ equ 0
 +    29 SOCKADDRIN_SIZE:​ equ 16
 +    30 PORT:​ equ 47269
 +    31
 +    32 section .data
 +    33 str_perror:​ db "​Perror "
 +    34
 +    35 align 4
 +    36 sockaddr_in:​
 +    37 sin_family:​ dw 0
 +    38 sin_port:​ dw 0
 +    39 sin_addr:​ dd 0
 +    40 sin_zero:​ db 0,​0,​0,​0,​0,​0,​0,​0
 +    41
 +    42 sock_listen:​ dd 0
 +    43 sock_accept:​ dd 0
 +    44 socklen:​ dd 0
 +    45 length: dd 0
 +    46
 +    47
 +    48 main:
 +    49 push dword 0
 +    50 push dword SOCK_STREAM
 +    51 push dword AF_INET
 +    52 call socket
 +    53 add esp, 12
 +    54
 +    55 cmp dword eax, 0
 +    56 jnz asm_perror
 +    57
 +    58 mov [sock_listen],​ eax
 +    59
 +    60 mov word [sin_family],​ AF_INET
 +    61 mov dword [sin_addr], INADDR_ANY
 +    62 mov word [sin_port], PORT
 +    63
 +    64 push dword SOCKADDRIN_SIZE
 +    65 push sockaddr_in
 +    66 push dword [sock_listen]
 +    67 call bind
 +    68 add esp, 12
 +    69
 +    70 cmp dword eax, 0
 +    71 jnz asm_perror
 +    72
 +    73 push dword 1
 +    74 push dword [sock_listen]
 +    75 call listen
 +    76 add esp, 8
 +    77
 +    78 cmp dword eax, 0
 +    79 jnz asm_perror
 +    80
 +    81 mov dword [socklen], SOCKADDRIN_SIZE
 +    82 push socklen
 +    83 push sockaddr_in
 +    84 push dword [sock_listen]
 +    85 call accept
 +    86 add esp, 12
 +    87
 +    88 cmp dword eax, 0
 +    89 jnz asm_perror
 +    90
 +    91 mov [sock_accept],​ eax
 +    92
 +    93 read_lbl:​
 +    94 push dword 256
 +    95 push buffer ​
 +    96 push dword [sock_accept]
 +    97 call read
 +    98 add esp, 12
 +    99
 +   ​100 cmp dword eax, 3
 +   ​101 jnz asm_perror
 +   102
 +   ​103 mov [length], eax
 +   104
 +   ​105 ;​ removing \r\n
 +   ​106 mov dword ebx, [length]
 +   ​107 mov byte [buffer+ebx-2],​0x00
 +   ​108 mov byte [buffer+ebx-1],​0x00
 +   109
 +   ​110 push buffer
 +   ​111 call strfry
 +   ​112 add esp, 4
 +   113
 +   ​114 ;​ adding \n
 +   ​115 mov byte [buffer+ebx-1],​0x0a
 +   116
 +   ​117 push dword [length]
 +   ​118 push buffer
 +   ​119 push dword [sock_accept]
 +   ​120 call write
 +   ​121 add esp, 12
 +   122
 +   ​123 cmp dword eax, 0
 +   ​124 jnz asm_perror
 +   125
 +   ​126 jmp read_lbl
 +   127
 +   ​128 close_sock_accept:​
 +   ​129 push dword [sock_accept]
 +   ​130 call close
 +   ​131 add esp,4
 +   132
 +   ​133 close_sock_listen:​
 +   ​134 push dword [sock_listen]
 +   ​135 call close
 +   ​136 add esp, 4
 +   137
 +   ​138 exit:​
 +   ​139 xor eax, eax
 +   ​140 inc eax
 +   ​141 xor ebx, ebx
 +   ​142 int 80h
 +   143
 +   ​144 asm_perror:​
 +   ​145 push str_perror
 +   ​146 call perror
 +   ​147 add esp, 4
 +   ​148 cmp dword [sock_accept],​0
 +   ​149 jnz close_sock_accept
 +   ​150 cmp dword [sock_listen],​0
 +   ​151 jnz close_sock_listen
 +   ​152 jmp exit
 +</​code>​
 +
 +152 lignes, ça reste correct, sachant qu'il y a une gestion minimale des erreurs avec perror. Oui, car on aurait pu se la jouer crado hein..
 +
 +
 +==== II - Explications ====
 +
 +Si vous lisez ces lignes, je suppose que vous avez lu les deux premières parties, et vais donc me contenter d'​expliquer les parties pas ou peu étudiées dans les parties précédentes.
 +
 +Vous êtes aussi censés savoir comment fonctionne un serveur socket.
 +
 +__Ligne 1__: Section .bss, là où on alloue de la mémoire.
 +
 +__Ligne 2__: Ici on réservere 256 octets (bytes), et comme nous savons tous, un char = 1 octet sur nos architextures x86, et comme vous vous en doutez cette lignes équivaut à un "​buffer[256];"​ en C.
 +
 +__Ligne 4__: La section .text où on déclare la fonction principale et les fonctions externes. Genre ici on déclare toutes les fonctions de la libC que l'on va utiliser dans notre programme. On pourrait très bien utiliser des fonctions d'​autres librairies, mais pour ce faire il faudra l'​indiquer à gcc avec un truc genre -lqqc..
 +
 +__Ligne 20__: La section .rodata où l'on déclare toutes nos constantes, l'​équivalent d'un "#​define BLAH 654"..
 +
 +__Ligne 32__: La section data où l'on déclare nos variables. Vous remarquerez ici la déclaration de la fameuse "​struct sockaddr_in"​. En fait ici on ne fait que déclarer une variable nommée sockaddr_in,​ qui va pointer sur sin_family. Ouais c'est la même zone mémoire, c'est ce qu'il faut voir. Pour connaitre le nombre d'​octets à réserver pour chaque membre de la structure, référez vous aux headers de la libc.
 +
 +__Ligne 49 à 53__: Ce qu'il faut retenir ici c'est que pour passer des argument à une fonction suffit de les empiler sur la stack dans l'​ordre inverse de la déclaration. Genre ici pour socket(..) on va push en premier le dernier argument, puis le second, puis le premier.\\
 +Ensuite on call socket qu'on a déclaré dans la section .text, puis on enlève les arguments de la stack (comme 4*3=12 on enlève 12 octets).
 +
 +__Ligne 55-56__: Ici on ne fait que vérifier le retour de socket. Si le résultat n'est pas supérieur à 0 alors on appelle perror.
 +
 +Dans les lignes qui suivent on remplit notre pseudo structure, puis on appelle bind.
 +
 +Je pense que la suite du code se passe de commentaires,​ si vous avez compris les principes de base, ce n'est qu'une répétition de push/​call/​add/​cmp hein...
 +
 +__Ligne 93__: Boucle principale du programme où on attend que l'​utilisateur envoie du texte sur la socket.
 +
 +On vérifie que la chaine fasse plus de 3 caractères,​ sinon ça voudrait dire que l'​utilisateur veut quitter le programme. CF explications du début.
 +
 +Comme on suppose que l'​utilisateur utilise telnet, on enlève \r\n de la fin de la chaine pour pas qu'​strfry les prenne en compte.
 +
 +Ensuite la fin de programme est on ne peut plus claire, enfin je l'​espère.
 +
 +Pour compiler tout ça :
 +     nasm -felf sockstrfry.asm
 +     gcc sockstrfry.o -o sockstrfry
 +
 +Il y a quelques oublis volontaires,​ qui ne vous empêcherons pas de faire tourner le programme. J'​espère que vous saurez les apercevoir.
 +
 +
 +==== III - Conclusionnage ====
 +
 +A présent vous êtes censés pouvoir voler de vos propres ailes et faire des programmes utiles en assembleur.
 +
 +Pour terminer voici tous les liens utiles que j'ai sur l'ASM. Si ces turotiels vous ont plus, un petit mail me ferait plaisir, et dans le cas contraire un mail expliquant ce qui vous a déplu m'​aidera pour mes prochaines rédactions.
 +
 +Certains sont mieux que d'​autres,​ mais tous m'ont été utiles à un moment donné ou à un autre. J'​espère qu'ils vous permettront d'​approfondir vos connaissance.
 +
 +J'​espère enfin vous avoir donné envie d'​aller plus loin.
 +
 +     ​http://​www.monkey.org/​openbsd/​archive/​misc/​0105/​msg01202.html
 +     ​http://​inferno.cs.univ-paris8.fr/​~am/​tutorial/​os/​nasmC.html
 +     ​http://​asm.sourceforge.net/​resources.html#​tutorials
 +     ​http://​docs.cs.up.ac.za/​programming/​asm/​derick_tut/​
 +     ​http://​www.alrj.org/​docs/​asm/​linux-asm.html
 +     ​http://​docs.cs.up.ac.za/​programming/​asm/​derick_tut/​syscalls.html
 +     ​http://​www.iprezo.org/​index.php?​page=asm
 +     ​http://​rs1.szif.hu/​~tomcat/​win32/​apj3.txt
 +     ​http://​jeanfrancoisdelnero.free.fr/​hard.htm
 +     ​http://​www.leto.net/​writing/​nasm.txt
 +     ​http://​milw0rm.org/​papers/​46
 +     ​http://​download.savannah.gnu.org/​releases/​pgubook/​
 +     ​http://​sourceware.org/​binutils/​docs-2.17/​as/​index.html
 +     ​http://​database.sarang.net/​study/​linux/​asm/​linux-asm.txt
 +     ​http://​www.coder-studio.com/​index.php?​page=tutoriaux_aff&​code=asm_4
 +     ​http://​mdbui2.ift.ulaval.ca/​17583_E2007/​Labs/​Instructions_Chaines_caracteres.htm
 +     ​http://​www.developpez.net/​forums/​showthread.php?​t=378804
 +     ​http://​cui.unige.ch/​DI/​cours/​1840/​cours/​
 +     ​http://​www.dil.univ-mrs.fr/​~jfp/​tp_lex_yacc2005/​yacc/​docAs/​Assembleur/​index.html
 +     ​http://​www.ai.univ-paris8.fr/​~n/​gpi/​GPIas32bits/​GPIas32bits.html
 +     ​http://​pluton.up.univ-mrs.fr/​eremy/​Ens/​Info1.Archi/​asm.html
 +     ​http://​www.games-creators.org/​wiki/​Tutorial_7_:​_Les_instructions_asm_les_plus_courantes_et_le_corps_d'​un_programme_FASM_pour_les_librairies
 +     ​http://​www.technocage.com/​~ray/​notespage.jsp?​pageName=nasmexamples
 +     ​http://​www.kernelthread.com/​programming/​miscellaneous/​asm/​
 +     ​http://​www.csee.umbc.edu/​~plusquel/​310/​nasm/​
 +     ​http://​pdos.csail.mit.edu/​6.828/​2004/​readings/​i386/​toc.htm
 +     ​http://​asm.sourceforge.net/​articles/​
 +     ​http://​www.alrj.org/​docs/​asm/​linux-asm.html
 +     ​http://​www.pouet.free.fr/​docs/​boso/​tutorial07.html
 +     ​http://​flyers.next-touch.com/​data/​homework/​article/​Nasm_fr.htm
 +
 +
 + --- //​[[jf.guchens@gmail.com|jfg]] 2007/09/21 00:37//
codaz/asm/l_assembleur_pour_lutins_presses_3.txt · Last modified: 2010/01/12 13:29 (external edit)