web-dev-qa-db-fra.com

Que signifie un astérisque * avant une adresse dans un assemblage x86-64 AT&T?

Que signifie la ligne suivante:

...
401147: ff 24 c5 80 26 40 00    jmpq   *0x402680(,%rax,8)
...

Que signifie l'astérisque devant l'adresse mémoire? En outre, qu'est-ce que cela signifie lorsque la méthode d'accès à la mémoire est manquante, c'est sa première valeur de registre?

Habituellement, c'est quelque chose comme ("% register",% rax, 8), mais dans ce cas, il n'a pas le premier registre.

Des conseils?

31
de1337ed

En fait, c'est table calculée jmp, où 0x402680 est l'adresse de la table et rax est l'index du pointeur de 8 octets (qword).

18
GJ.

C'est la syntaxe de l'assemblage AT&T:

  • la source vient avant la destination
  • les suffixes mnémoniques indiquent la taille des opérandes (q pour quad, etc.)
  • les registres sont préfixés avec % et les valeurs immédiates avec $
  • les adresses effectives sont sous la forme DISP(BASE, INDEX, SCALE) (DISP + BASE + INDEX * SCALE)
  • opérandes de saut/appel absolus indiqués par * (par opposition à IP relatif)

Donc, vous avez un jmpq pour sauter à l'adresse absolue qui est stockée dans %rax * 8 + 0x402680, Et est un quadruple Word.

16
Michael Foukarakis

Mettre les choses dans la syntaxe Intel rend toujours les choses plus claires:

FF24C5 80264000  JMP QWORD PTR [RAX*8+402680]
12
Necrolis

jmpq n'est qu'un saut inconditionnel vers une adresse donnée. Le "q" signifie que nous avons affaire à des mots quadruples (64 bits de long).

*0x402680(,%rax,8): C'est une façon d'écrire une adresse dans l'assemblage x-86. Vous avez raison de dire qu'il y a généralement un registre avant la première virgule, mais vous suivez toujours les mêmes règles si aucun registre n'est spécifié.

Le format fonctionne de cette façon: D(reg1, reg2, scalingFactor) où D représente le déplacement. Le déplacement est fondamentalement juste un entier. reg1 est le premier ou le registre de base. reg2 est le deuxième registre et scalingFactor est l'un des 2, 4, 8 (peut-être même 1, mais je n'en suis pas sûr). Maintenant, vous pouvez obtenir votre adresse en ajoutant simplement les valeurs de cette façon: Déplacement + (valeur à reg1) + scalingFactor * (valeur à reg2).

Je ne sais pas exactement à quoi sert l'astérisque devant l'adresse, mais je suppose que cela signifie que la valeur de déplacement est stockée à cette adresse.

J'espère que cela t'aides.

5
vyb

C'est un saut vers une adresse contenue en mémoire. L'adresse est stockée en mémoire à l'adresse rax*8+0x402680, où rax est la valeur actuelle de rax (lorsque cette instruction s'exécute).

5
Alexey Frunze

Exemple minimal

Pour rendre les choses plus claires:

.data
    # Store he address of the label in the data section.
    symbol: .int label   
.text   
    # Jumps to label.
    jmp *symbol
    label:

GitHub en amont .

Sans le *, il passerait à l'adresse de symbol dans le .data section et segfault.

Je pense que cette syntaxe est un peu incohérente, car pour la plupart des instructions:

mov symbol, %eax
mov label, %eax

déplace déjà les données à l'adresse symbol et $symbol est utilisé pour l'adresse. La syntaxe Intel est plus cohérente sur ce point car elle utilise toujours [] pour le déréférencement.

Le * est bien sûr un mnémonique pour l'opérateur de déréférence C *ptr.

Comme l'écrivait Necrolis, la syntaxe Intel la rend un peu plus évidente, mais RTN est vraiment plus clair. La ligne

jmpq   *0x402680(,%rax,8)

serait décrit dans RTN par:

RIP <- M[0x402680 + (8 * RAX)]

M est la mémoire système.

En tant que tel, nous pouvons écrire la forme générale jmpq *c(r1, r2, k), où c est une constante immédiate, r1 Et r2 Sont des registres à usage général et k est soit 1 (par défaut), 2, 4 ou 8:

RIP <- M[c + r1 + (k * r2)]
4
eepp