Aller au contenu

Les programmes

Qu'est-ce qu'un programme ?

Programme

Un programme est une suite d'instructions que va exécuter un ordinateur. Ces instructions donnent des ordres sur les actions que doit faire l'ordinateur. Par exemple, il peut calculer une valeur, enregistrer une valeur dans sa mémoire, vérifier une valeur, etc.

Ces instructions sont écrites en langage machine. Il s'agit d'une suite de 0 et de 1 (32 ou 64 selon le modèle du processeur) dont la signification varie selon les constructeurs. Par exemple, l'instruction 00111001 pourrait signifier "Additionner (00) et mettre dans la case mémoire 11 les valeurs 10 et 01".

Mais comment programmer ?

Programmer consiste à créer un programme. Nul besoin de connaître le langage machine, puisqu'il existe des compilateurs. Un compilateur est un programme qui va traduire un autre programme rédigé avec des mots clefs (souvent en anglais et proche du langage naturel) en langage machine.

Ce type de langage avec des mots clefs est appelé langage de haut niveau. À l'inverse, un langage spécifique à un processeur, est appelé langage de bas niveau. Le langage de bas niveau utilise également des mots clefs, mais qui restent spécifiques à un processeur en particulier. L'assembleur est un langage bas niveau.

Observer le langage assembleur

Sous Linux, on peut afficher le langage assembleur d'un programme avec objdump -d lien/vers/programme dans un terminal. Voici un exemple avec un programme qui affiche "Hello World" dans un terminal :

Quote
hello:     file format elf64-x86-64


Disassembly of section .init:

0000000000001000 <_init>:
    1000:       f3 0f 1e fa             endbr64
    1004:       48 83 ec 08             sub    $0x8,%rsp
    1008:       48 8b 05 c1 2f 00 00    mov    0x2fc1(%rip),%rax        # 3fd0 <__gmon_start__@Base>
    100f:       48 85 c0                test   %rax,%rax
    1012:       74 02                   je     1016 <_init+0x16>
    1014:       ff d0                   call   *%rax
    1016:       48 83 c4 08             add    $0x8,%rsp
    101a:       c3                      ret

Disassembly of section .plt:

0000000000001020 <puts@plt-0x10>:
    1020:       ff 35 ca 2f 00 00       push   0x2fca(%rip)        # 3ff0 <_GLOBAL_OFFSET_TABLE_+0x8>
    1026:       ff 25 cc 2f 00 00       jmp    *0x2fcc(%rip)        # 3ff8 <_GLOBAL_OFFSET_TABLE_+0x10>
    102c:       0f 1f 40 00             nopl   0x0(%rax)

0000000000001030 <puts@plt>:
    1030:       ff 25 ca 2f 00 00       jmp    *0x2fca(%rip)        # 4000 <puts@GLIBC_2.2.5>
    1036:       68 00 00 00 00          push   $0x0
    103b:       e9 e0 ff ff ff          jmp    1020 <_init+0x20>

Disassembly of section .text:

0000000000001040 <_start>:
    1040:       f3 0f 1e fa             endbr64
    1044:       31 ed                   xor    %ebp,%ebp
    1046:       49 89 d1                mov    %rdx,%r9
    1049:       5e                      pop    %rsi
    104a:       48 89 e2                mov    %rsp,%rdx
    104d:       48 83 e4 f0             and    $0xfffffffffffffff0,%rsp
    1051:       50                      push   %rax
    1052:       54                      push   %rsp
    1053:       45 31 c0                xor    %r8d,%r8d
    1056:       31 c9                   xor    %ecx,%ecx
    1058:       48 8d 3d da 00 00 00    lea    0xda(%rip),%rdi        # 1139 <main>
    105f:       ff 15 5b 2f 00 00       call   *0x2f5b(%rip)        # 3fc0 <__libc_start_main@GLIBC_2.34>
    1065:       f4                      hlt
    1066:       66 2e 0f 1f 84 00 00    cs nopw 0x0(%rax,%rax,1)
    106d:       00 00 00 
    1070:       48 8d 3d a1 2f 00 00    lea    0x2fa1(%rip),%rdi        # 4018 <__TMC_END__>
    1077:       48 8d 05 9a 2f 00 00    lea    0x2f9a(%rip),%rax        # 4018 <__TMC_END__>
    107e:       48 39 f8                cmp    %rdi,%rax
    1081:       74 15                   je     1098 <_start+0x58>
    1083:       48 8b 05 3e 2f 00 00    mov    0x2f3e(%rip),%rax        # 3fc8 <_ITM_deregisterTMCloneTable@Base>
    108a:       48 85 c0                test   %rax,%rax
    108d:       74 09                   je     1098 <_start+0x58>
    108f:       ff e0                   jmp    *%rax
    1091:       0f 1f 80 00 00 00 00    nopl   0x0(%rax)
    1098:       c3                      ret
    1099:       0f 1f 80 00 00 00 00    nopl   0x0(%rax)
    10a0:       48 8d 3d 71 2f 00 00    lea    0x2f71(%rip),%rdi        # 4018 <__TMC_END__>
    10a7:       48 8d 35 6a 2f 00 00    lea    0x2f6a(%rip),%rsi        # 4018 <__TMC_END__>
    10ae:       48 29 fe                sub    %rdi,%rsi
    10b1:       48 89 f0                mov    %rsi,%rax
    10b4:       48 c1 ee 3f             shr    $0x3f,%rsi
    10b8:       48 c1 f8 03             sar    $0x3,%rax
    10bc:       48 01 c6                add    %rax,%rsi
    10bf:       48 d1 fe                sar    $1,%rsi
    10c2:       74 14                   je     10d8 <_start+0x98>
    10c4:       48 8b 05 0d 2f 00 00    mov    0x2f0d(%rip),%rax        # 3fd8 <_ITM_registerTMCloneTable@Base>
    10cb:       48 85 c0                test   %rax,%rax
    10ce:       74 08                   je     10d8 <_start+0x98>
    10d0:       ff e0                   jmp    *%rax
    10d2:       66 0f 1f 44 00 00       nopw   0x0(%rax,%rax,1)
    10d8:       c3                      ret
    10d9:       0f 1f 80 00 00 00 00    nopl   0x0(%rax)
    10e0:       f3 0f 1e fa             endbr64
    10e4:       80 3d 2d 2f 00 00 00    cmpb   $0x0,0x2f2d(%rip)        # 4018 <__TMC_END__>
    10eb:       75 33                   jne    1120 <_start+0xe0>
    10ed:       55                      push   %rbp
    10ee:       48 83 3d ea 2e 00 00    cmpq   $0x0,0x2eea(%rip)        # 3fe0 <__cxa_finalize@GLIBC_2.2.5>
    10f5:       00 
    10f6:       48 89 e5                mov    %rsp,%rbp
    10f9:       74 0d                   je     1108 <_start+0xc8>
    10fb:       48 8b 3d 0e 2f 00 00    mov    0x2f0e(%rip),%rdi        # 4010 <__dso_handle>
    1102:       ff 15 d8 2e 00 00       call   *0x2ed8(%rip)        # 3fe0 <__cxa_finalize@GLIBC_2.2.5>
    1108:       e8 63 ff ff ff          call   1070 <_start+0x30>
    110d:       c6 05 04 2f 00 00 01    movb   $0x1,0x2f04(%rip)        # 4018 <__TMC_END__>
    1114:       5d                      pop    %rbp
    1115:       c3                      ret
    1116:       66 2e 0f 1f 84 00 00    cs nopw 0x0(%rax,%rax,1)
    111d:       00 00 00 
    1120:       c3                      ret
    1121:       66 66 2e 0f 1f 84 00    data16 cs nopw 0x0(%rax,%rax,1)
    1128:       00 00 00 00 
    112c:       0f 1f 40 00             nopl   0x0(%rax)
    1130:       f3 0f 1e fa             endbr64
    1134:       e9 67 ff ff ff          jmp    10a0 <_start+0x60>

0000000000001139 <main>:
    1139:       55                      push   %rbp
    113a:       48 89 e5                mov    %rsp,%rbp
    113d:       48 8d 05 c0 0e 00 00    lea    0xec0(%rip),%rax        # 2004 <_IO_stdin_used+0x4>
    1144:       48 89 c7                mov    %rax,%rdi
    1147:       e8 e4 fe ff ff          call   1030 <puts@plt>
    114c:       b8 00 00 00 00          mov    $0x0,%eax
    1151:       5d                      pop    %rbp
    1152:       c3                      ret

Disassembly of section .fini:

0000000000001154 <_fini>:
    1154:       f3 0f 1e fa             endbr64
    1158:       48 83 ec 08             sub    $0x8,%rsp
    115c:       48 83 c4 08             add    $0x8,%rsp
    1160:       c3                      ret

Nous utiliserons Python, qui est un langage de haut niveau. Il dispose de divers mots clefs qui vont nous permettre d'interagir avec la machine sans effort (ou presque).