web-dev-qa-db-fra.com

Comprendre le registre% rip dans l'assemblage Intel

Concernant le petit code suivant, qui a été illustré dans un autre article sur la taille de la structure et toutes les possibilités d'aligner correctement les données:

struct
{
 char Data1;
 short Data2;
 int Data3;
 char Data4;
} x;

unsigned fun ( void )
{
    x.Data1=1;
    x.Data2=2;
    x.Data3=3;
    x.Data4=4;
    return(sizeof(x));
}

J'obtiens le démontage correspondant (avec 64 bits)

0000000000000000 <fun>:
   0:   55                      Push   %rbp
   1:   48 89 e5                mov    %rsp,%rbp
   4:   c6 05 00 00 00 00 01    movb   $0x1,0x0(%rip)        # b <fun+0xb>
   b:   66 c7 05 00 00 00 00    movw   $0x2,0x0(%rip)        # 14 <fun+0x14>
  12:   02 00 
  14:   c7 05 00 00 00 00 03    movl   $0x3,0x0(%rip)        # 1e <fun+0x1e>
  1b:   00 00 00 
  1e:   c6 05 00 00 00 00 04    movb   $0x4,0x0(%rip)        # 25 <fun+0x25>
  25:   b8 0c 00 00 00          mov    $0xc,%eax
  2a:   5d                      pop    %rbp
  2b:   c3                      retq   

Je ne sais pas comment calculer les termes situés à droite qui semblent être les address of local variables utilisé. De plus, je ne sais pas le calculer avec %rip register

Pourriez-vous donner un exemple qui montre le lien entre %rip et %rsp ou %rbp, c'est-à-dire notamment dans le calcul d'adresse lorsque j'utilise des instructions move.

8
youpilat13

L'adressage RIP est toujours relatif au registre RIP (64bit Instruction Pointer). Il ne peut donc être utilisé que pour les variables globales. Le décalage 0 est égal à l'adresse de l'instruction suivante après l'instruction adressée RIP. Par exemple:

   mov  al,[rip+2]                     al=53
   jmp  short next   (length=2 bytes)   
db 53
next:
   mov  bl,[rip-7]   (length=6 bytes)  bl=53

Normalement, vous ne mélangeriez pas directement les données avec votre code, sauf dans l'immédiat, mais cela montre ce qui se passerait si vous exécutiez réellement du code avec de très petits décalages.

Dans votre code, vous ne pouvez pas voir et vérifier les décalages (vous voyez quatre zéros) car vous avez désassemblé un .o. Utilisation objdump -drwC pour afficher les noms/délocalisations des symboles lors du démontage. Ils seront remplis par l'éditeur de liens lorsque vous liez cet objet dans un exécutable.


Exemple d'accès aux sections locales par rapport à `rbp:

Push rbp      ;save rbp
mov rbp,rsp   ;rbp = pointer to return address (8 bytes)
sub rsp,64    ;reserve 64 bytes for local variables
mov rax,[rbp+8];  rax = the last stack-passed qword parameter (if any)
mov rdx,[rbp];    rdx = return address
mov rcx,[rbp-8];  rcx = first qword local variable (this is undefined now)
mov r8, [rbp-16];  r8  = second qword local variable (this is undefined now)
.
.
mov rsp,rbp
pop rbp
ret
5
toncsi