• [^] # Re: Questions pas très claire

    Posté par . En réponse au message adressage relatif en assembleur amd64, je suis perdu. Évalué à 1. Dernière modification le 02 avril 2012 à 00:05.

    Lors de la première instruction, rip contient 0, lors de la seconde instruction rip contient 10.
    Et pourtant, le résultat de ces deux instructions est de mettre ce qu'il y a dans la mémoire à l'adresse data dans %eax. Non ?
    Je ne comprend pas comment il fait pour calculer.
    rip c'est bien le compteur ordinal ? Raw Instruction Pointer. Autrement dit, le contenu de ce registre change à chaque nouvelle instructions.

    Un peu de vrai code :

    int a = 0;
    void f(void){
     a = a + a;
    }
    
    

    l'assembleur généré :

     .file "a.c"
     .globl a
     .bss
     .align 4
     .type a, @object
     .size a, 4
    a:
     .zero 4
     .text
     .globl f
     .type f, @function
    f:
    .LFB0:
     .cfi_startproc
     pushq %rbp
     .cfi_def_cfa_offset 16
     .cfi_offset 6, -16
     movq %rsp, %rbp
     .cfi_def_cfa_register 6
     movl a(%rip), %edx
     movl a(%rip), %eax
     addl %edx, %eax
     movl %eax, a(%rip)
     popq %rbp
     .cfi_def_cfa 7, 8
     ret
     .cfi_endproc
    .LFE0:
     .size f, .-f
     .ident "GCC: (GNU) 4.6.3 20120306 (Red Hat 4.6.3-2)"
     .section .note.GNU-stack,"",@progbits
    
    

    et le binaire généré a.o :

    a.o: file format elf64-x86-64
    Disassembly of section .text:
    0000000000000000 <f>:
     0: 55 push %rbp
     1: 48 89 e5 mov %rsp,%rbp
     4: 8b 15 00 00 00 00 mov 0x0(%rip),%edx # a <f+0xa>
     a: 8b 05 00 00 00 00 mov 0x0(%rip),%eax # 10 <f+0x10>
     10: 01 d0 add %edx,%eax
     12: 89 05 00 00 00 00 mov %eax,0x0(%rip) # 18 <f+0x18>
     18: 5d pop %rbp
     19: c3 retq 
    
    

    Dans le AMD64 Architechture Programmer's Manual v1 on lit :

    The 64-bit RIP instruction-pointer register contains the address of the next instruction to be executed.

    Autrement dit la valeur contenue dans ce registre change après chaque instruction traitée par le processeur.

    Et pourtant dans mon code C, il n'y a qu'un seul 'a', qui a une position fixe dans la mémoire. Et dans le code assembleur généré, et dans le binaire il est question du registre rip pour y accéder, avec la même syntaxe que pour le l'adressage indexé. mov offset(registre),registre. Bref, on accède à une position fixe grâce à un registre dont la valeur qu'il contient change après chaque instruction traitée.
    La question : Comment ça marche ?

    Please do not feed the trolls