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?
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).
C'est la syntaxe de l'assemblage AT&T:
q
pour quad, etc.)%
et les valeurs immédiates avec $
DISP(BASE, INDEX, SCALE)
(DISP + BASE + INDEX * SCALE)*
(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.
Mettre les choses dans la syntaxe Intel rend toujours les choses plus claires:
FF24C5 80264000 JMP QWORD PTR [RAX*8+402680]
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.
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).
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:
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)]
où 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)]