Partager via


Numéros et opérateurs MASM

Cette rubrique décrit l’utilisation de la syntaxe d’expression MICROSOFT Macro Assembleur (MASM) avec les outils de débogage Windows.

Le débogueur accepte deux types d’expressions numériques différents : les expressions C++ et les expressions MASM. Chacune de ces expressions suit ses propres règles de syntaxe pour l’entrée et la sortie.

Pour plus d’informations sur l’utilisation de chaque type de syntaxe, consultez Évaluation des expressions et ? (Évaluer l’expression).

Dans cet exemple le ? la commande affiche la valeur du registre du pointeur d’instruction à l’aide de l’évaluateur d’expression MASM.

0:000> ? @rip
Evaluate expression: 140709230544752 = 00007ff9`6bb40770

Définir l’évaluateur d’expression sur MASM

Utilisez .expr (Choisir l’évaluateur d’expression) pour voir ce qu’est l’évaluateur d’expression par défaut et le remplacer par MASM.

0:000> .expr /s masm
Current expression evaluator: MASM - Microsoft Assembler expressions

Maintenant que l'évaluateur d'expressions par défaut a été modifié, la commande ? (Évaluer l’expression) peut être utilisée pour afficher des expressions MASM. Cet exemple additionne la valeur hexadécimale de 8 au registre rip.

0:000> ? @rip + 8
Evaluate expression: 140709230544760 = 00007ff9`6bb40778

La référence du registre @rip est décrite plus en détail dans la syntaxe de registre.

Nombres dans les expressions MASM du débogueur

Vous pouvez placer des nombres dans des expressions MASM en base 16, 10, 8 ou 2.

Utilisez la commande n (Définir la base de nombres) pour définir le radix par défaut sur 16, 10 ou 8. Tous les nombres non corrigés sont ensuite interprétés dans cette base. Vous pouvez remplacer le radix par défaut en spécifiant le préfixe 0x (hexadécimal), le préfixe 0n (décimal), le préfixe 0t (octal) ou le préfixe 0y (binaire).

Vous pouvez également spécifier des nombres hexadécimaux en ajoutant un h après le nombre. Vous pouvez utiliser des lettres majuscules ou minuscules dans des chiffres. Par exemple, « 0x4AB3 », « 0X4aB3 », « 4AB3h », « 4ab3h » et « 4aB3H » ont la même signification.

Si vous n’ajoutez pas de nombre après le préfixe d’une expression, le nombre est lu sous la forme 0. Par conséquent, vous pouvez écrire 0 en tant que 0, le préfixe suivi de 0 et uniquement le préfixe. Par exemple, en hexadécimal, « 0 », « 0x0 » et « 0x » ont la même signification.

Vous pouvez entrer des valeurs hexadécimales 64 bits au format xxxxxxxx’xxxxxxxx . Vous pouvez également omettre l’accent grave ('). Si vous incluez l’accent grave, l’extension de signe automatique est désactivée.

Cet exemple montre comment ajouter une valeur décimale, octale et binaire pour inscrire 10.

? @r10 + 0x10 + 0t10 + 0y10
Evaluate expression: 26 = 00000000`0000001a

Symboles dans les expressions MASM du débogueur

Dans les expressions MASM, la valeur numérique d’un symbole est son adresse mémoire. Selon ce que le symbole fait référence, cette adresse est l’adresse d’une variable globale, d’une variable locale, d’une fonction, d’un segment, d’un module ou d’une autre étiquette reconnue.

Pour spécifier le module auquel l’adresse est associée, incluez le nom du module et un point d’exclamation ( !) avant le nom du symbole. Si le symbole peut être interprété comme un nombre hexadécimal, incluez le nom du module et un point d’exclamation, ou simplement un point d’exclamation, avant le nom du symbole. Pour plus d’informations sur la reconnaissance des symboles, consultez Syntaxe des symboles et Correspondance des symboles.

Utilisez deux points-virgules ( ::) ou deux traits de soulignement (__) pour indiquer les membres d’une classe.

Utilisez un accent grave (') ou une apostrophe (') dans un nom de symbole uniquement si vous ajoutez un nom de module et un point d’exclamation avant le symbole.

Opérateurs numériques dans les expressions MASM

Vous pouvez modifier n’importe quel composant d’une expression à l’aide d’un opérateur unaire. Vous pouvez combiner deux composants à l’aide d’un opérateur binaire. Les opérateurs unaires sont prioritaires sur les opérateurs binaires. Lorsque vous utilisez plusieurs opérateurs binaires, les opérateurs suivent les règles de précédence fixe décrites dans les tableaux suivants.

Vous pouvez toujours utiliser des parenthèses pour remplacer les règles de précédence.

Si une partie d'une expression MASM est placée entre parenthèses et que deux arrobas (@@) se trouvent avant l'expression, l'expression est interprétée en fonction des règles d'expression C++. Vous ne pouvez pas ajouter d’espace entre les deux signes et la parenthèse ouvrante. Vous pouvez également spécifier l’évaluateur d’expression à l’aide de @@c++( ... ) ou de @@masm( ... ).

Lorsque vous effectuez des calculs arithmétiques, l’évaluateur d’expression MASM traite tous les nombres et symboles comme des types ULONG64.

Les opérateurs d’adresses unaires supposent que DS est le segment par défaut pour les adresses. Les expressions sont évaluées dans l’ordre de priorité de l’opérateur. Si les opérateurs adjacents ont une priorité égale, l’expression est évaluée de gauche à droite.

Vous pouvez utiliser les opérateurs unaires suivants.

Opérateur Sens

+

Plus unaire

-

Unaire moins

non

Retourne 1 si l’argument est égal à zéro. Retourne zéro pour n’importe quel argument différent de zéro.

Salut

16 bits élevés

faible

Faible 16 bits

par

Octet de faible ordre depuis l’adresse spécifiée.

$pby

Même chose que by sauf qu'il utilise une adresse physique. Seule la mémoire physique qui utilise le comportement de mise en cache par défaut peut être lue.

Wo

Mot de faible ordre à partir de l’adresse spécifiée.

$pwo

Identique à wo , sauf qu’il prend une adresse physique. Seule la mémoire physique qui utilise le comportement de mise en cache par défaut peut être lue.

dwo

Double mot de l’adresse spécifiée.

$pdwo

Identique à dwo , sauf qu’il prend une adresse physique. Seule la mémoire physique qui utilise le comportement de mise en cache par défaut peut être lue.

qwo

Mot quadruple de l'adresse spécifiée.

$pqwo

Identique à qwo , sauf qu’il prend une adresse physique. Seule la mémoire physique qui utilise le comportement de mise en cache par défaut peut être lue.

Poi

Données à la taille du pointeur depuis l’adresse spécifiée. La taille du pointeur est de 32 bits ou 64 bits. Dans le débogage du noyau, cette taille est basée sur le processeur de l’ordinateur cible . Par conséquent, poi est le meilleur opérateur à utiliser si vous souhaitez des données de taille pointeur.

$ppoi

Identique à poi , sauf qu’il prend une adresse physique. Seule la mémoire physique qui utilise le comportement de mise en cache par défaut peut être lue.

Exemples

L’exemple suivant montre comment utiliser poi pour déréférer un pointeur pour voir la valeur stockée à cet emplacement de mémoire.

Commencez par déterminer l’adresse de mémoire intéressante. Par exemple, nous pouvons examiner la structure de threads et décider de voir la valeur de CurrentLocale.

0:000> dx @$teb
@$teb                 : 0x8eed57b000 [Type: _TEB *]
    [+0x000] NtTib            [Type: _NT_TIB]
    [+0x038] EnvironmentPointer : 0x0 [Type: void *]
    [+0x040] ClientId         [Type: _CLIENT_ID]
    [+0x050] ActiveRpcHandle  : 0x0 [Type: void *]
    [+0x058] ThreadLocalStoragePointer : 0x1f8f9d634a0 [Type: void *]
    [+0x060] ProcessEnvironmentBlock : 0x8eed57a000 [Type: _PEB *]
    [+0x068] LastErrorValue   : 0x0 [Type: unsigned long]
    [+0x06c] CountOfOwnedCriticalSections : 0x0 [Type: unsigned long]
    [+0x070] CsrClientThread  : 0x0 [Type: void *]
    [+0x078] Win32ThreadInfo  : 0x0 [Type: void *]
    [+0x080] User32Reserved   [Type: unsigned long [26]]
    [+0x0e8] UserReserved     [Type: unsigned long [5]]
    [+0x100] WOW32Reserved    : 0x0 [Type: void *]
    [+0x108] CurrentLocale    : 0x409 [Type: unsigned long]

CurrentLocale se trouve 0x108 au-delà du début du TEB.

0:000> ? @$teb + 0x108
Evaluate expression: 613867303176 = 0000008e`ed57b108

Utilisez poi pour déréférencer cette adresse.

0:000> ? poi(0000008e`ed57b108)
Evaluate expression: 1033 = 00000000`00000409

La valeur retournée de 409 correspond à la valeur de CurrentLocale dans la structure TEB.

Vous pouvez également utiliser poi et des parenthèses pour déréférencer l’adresse calculée.

0:000> ? poi(@$teb + 0x108)
Evaluate expression: 1033 = 00000000`00000409

Utilisez les opérateurs unaires by ou wo pour renvoyer un octet ou un word à partir de l’adresse cible.

0:000> ? by(0000008e`ed57b108)
Evaluate expression: 9 = 00000000`00000009
0:000> ? wo(0000008e`ed57b108)
Evaluate expression: 1033 = 00000000`00000409

Opérateurs binaires

Vous pouvez utiliser les opérateurs binaires suivants. Les opérateurs de chaque cellule sont prioritaires sur ceux des cellules inférieures. Les opérateurs de la même cellule sont de la même priorité et sont analysés de gauche à droite.

Opérateur Sens

*

/

mod (ou %)

Multiplication

Division d'entier

Modulo (reste)

+

-

Ajout

Soustraction

<<

>>

>>>

Décalage à gauche

Décalage logique vers la droite

Décalage droit arithmétique

= (ou ==)

<

>

<=

>=

!=

Égal à

Inférieur à

Supérieur à

Inférieur ou égal à

Supérieur ou égal à

Non égal à

et (ou &)

AND au niveau du bit

xor (ou ^)

XOR au niveau du bit (OR exclusif)

ou (ou |)

OR au niveau du bit

Les <opérateurs de comparaison , = >, == et != sont évalués à 1 si l’expression a la valeur true ou zéro si l’expression a la valeur false. Un seul signe égal (=) est identique à un signe égal double (==). Vous ne pouvez pas utiliser d’effets secondaires ou d’affectations dans une expression MASM.

Une opération non valide (telle qu'une division par zéro) entraîne une « erreur d’opérande » qui est retournée à la fenêtre Commande du débogueur.

Nous pouvons vérifier que la valeur retournée correspond 0x409 à l’aide de l’opérateur de comparaison ==.

0:000> ? poi(@$teb + 0x108)==0x409
Evaluate expression: 1 = 00000000`00000001

Opérateurs non numériques dans les expressions MASM

Vous pouvez également utiliser les opérateurs supplémentaires suivants dans les expressions MASM.

Opérateur Sens

$fnsucc(FnAddress, RetVal, Flag)

Interprète la valeur RetVal comme valeur de retour pour la fonction située à l’adresse FnAddress . Si cette valeur de retour est qualifiée de code de réussite, $fnsucc retourne TRUE. Sinon, $fnsucc retourne FALSE.

Si le type de retour est BOOL, bool, HANDLE, HRESULT ou NTSTATUS, $fnsucc comprend correctement si la valeur de retour spécifiée est qualifiée de code de réussite. Si le type de retour est un pointeur, toutes les valeurs autres que NULL sont qualifiées de codes de réussite. Pour tout autre type, la réussite est définie par la valeur de Flag. Si l’indicateur est 0, une valeur différente de zéro de RetVal indique un succès. Si l’indicateur est égal à 1, une valeur de RetVal de zéro indique un succès.

$iment (Adresse)

Retourne l’adresse du point d’entrée d’image dans la liste des modules chargés. L’adresse spécifie l'adresse de base de l'image Portable Executable (PE). L'entrée est identifiée en recherchant le point d'entrée de l'image dans l'en-tête du fichier image PE spécifié par Adresse.

Vous pouvez utiliser cette fonction pour les deux modules qui se trouvent déjà dans la liste des modules et pour définir des points d’arrêt non résolus à l’aide de la commande bu .

$scmp(« String1 », « String2 »)

Prend la valeur -1, 0 ou 1, comme le strcmp en utilisant la fonction C strcmp.

$sicmp(« String1 », « String2 »)

Prend la valeur -1, 0 ou 1, comme la fonction stricmp Microsoft Win32 .

$spat(« String », « Pattern »)

Prend la valeur TRUE ou FALSE selon que la chaîne correspond au modèle. La correspondance est insensible à la casse. Le modèle peut contenir divers caractères génériques et spécificateurs. Pour plus d’informations sur la syntaxe, consultez Syntaxe générique de chaîne.

$vvalid(Adresse,Longueur)

Détermine si la plage de mémoire qui commence à l’adresse et s’étend pour les octets de longueur est valide. Si la mémoire est valide, $vvalid prend la valeur 1. Si la mémoire n’est pas valide, $vvalid prend la valeur 0.

Exemples

L’exemple suivant montre comment examiner la plage de mémoire valide autour d’un module chargé

Commencez par déterminer l’adresse de la zone d’intérêt, par exemple à l’aide de la commande lm (commande List Loaded Modules ).


0:000> lm
start             end                 module name
00007ff6`0f620000 00007ff6`0f658000   notepad    (deferred)
00007ff9`591d0000 00007ff9`5946a000   COMCTL32   (deferred)        
...

Utilisez $vvalid pour vérifier une plage de mémoire.

0:000> ? $vvalid(0x00007ff60f620000, 0xFFFF)
Evaluate expression: 1 = 00000000`00000001

Utilisez $vvalid pour confirmer que cette plage plus grande est une plage de mémoire non valide.

0:000> ? $vvalid(0x00007ff60f620000, 0xFFFFF)
Evaluate expression: 0 = 00000000`00000000

Il s’agit également d’une plage non valide.

0:000> ? $vvalid(0x0, 0xF)
Evaluate expression: 0 = 00000000`00000000

N’utilisez pas pour retourner zéro lorsque la plage de mémoire est valide.

0:000> ? not($vvalid(0x00007ff60f620000, 0xFFFF))
Evaluate expression: 0 = 00000000`00000000

Utilisez $imnet pour examiner le point d'entrée de COMCTL32, dont nous avions précédemment déterminé l'adresse en utilisant la commande lm. Il commence à 00007ff9'591d0000.

0:000> ? $iment(00007ff9`591d0000)
Evaluate expression: 140708919287424 = 00007ff9`59269e80

Désassemblez l’adresse retournée pour examiner le code de point d’entrée.

0:000> u 00007ff9`59269e80
COMCTL32!DllMainCRTStartup:
00007ff9`59269e80 48895c2408      mov     qword ptr [rsp+8],rbx
00007ff9`59269e85 4889742410      mov     qword ptr [rsp+10h],rsi
00007ff9`59269e8a 57              push    rdi

COMCTL32 s’affiche dans la sortie confirmant qu’il s’agit du point d’entrée de ce module.

Registres et Pseudo-Registers dans les expressions MASM

Vous pouvez utiliser des registres et des pseudo-registres dans des expressions MASM. Vous pouvez ajouter une arobase (@) avant tous les registres et pseudo-registres. Le signe at (@) permet au débogueur d'accéder plus rapidement à la valeur. Ce signe @ n’est pas nécessaire pour les registres x86 les plus courants. Pour les autres registres et pseudo-registres, nous vous recommandons d’ajouter l'arobase, mais cela n’est pas réellement nécessaire. Si vous omettez le signe arobase pour les registres moins courants, le débogueur essaie d'analyser le texte d'abord en tant que nombre hexadécimal, ensuite en tant que symbole, et finalement en tant que registre.

Vous pouvez également utiliser un point (.) pour indiquer le pointeur d’instruction actuel. Vous ne devez pas ajouter un signe @ avant cette période, et vous ne pouvez pas utiliser un point comme premier paramètre de la commande r. Cette période a la même signification que le pseudo-registre $ip .

Pour plus d’informations sur les registres et les pseudo-registres, consultez Syntaxe de registre et syntaxePseudo-Register.

Utilisez la commande r register pour voir que la valeur du @rip registre est 00007ffb'7ed00770.

0:000> r
rax=0000000000000000 rbx=0000000000000010 rcx=00007ffb7eccd2c4
rdx=0000000000000000 rsi=00007ffb7ed61a80 rdi=00000027eb6a7000
rip=00007ffb7ed00770 rsp=00000027eb87f320 rbp=0000000000000000
 r8=00000027eb87f318  r9=0000000000000000 r10=0000000000000000
r11=0000000000000246 r12=0000000000000040 r13=0000000000000000
r14=00007ffb7ed548f0 r15=00000210ea090000
iopl=0         nv up ei pl zr na po nc
cs=0033  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
ntdll!LdrpDoDebuggerBreak+0x30:
00007ffb`7ed00770 cc              int     3

Cette même valeur peut être affichée à l’aide du fichier . Raccourci de point.

0:000> ? .
Evaluate expression: 140718141081456 = 00007ffb`7ed00770

Nous pouvons confirmer que ces valeurs sont toutes équivalentes et retournent zéro s’ils le sont, à l’aide de cette expression MASM.

0:000>  ? NOT(($ip = .) AND ($ip = @rip) AND (@rip =. ))
Evaluate expression: 0 = 00000000`00000000

Numéros de ligne source dans les expressions MASM

Vous pouvez utiliser des expressions de fichier source et de numéro de ligne dans des expressions MASM. Vous devez placer ces expressions en utilisant des accents graves ('). Pour plus d’informations sur la syntaxe, consultez Syntaxe de ligne source.

Voir aussi

Expressions MASM et expressions C++

Exemples d’expressions mixtes

Nombres et opérateurs C++

Extension du Signe

? (Évaluer l’expression)