Aracılığıyla paylaş


MASM Sayıları ve İşleçleri

Bu konuda, Windows Hata Ayıklama araçlarıyla Microsoft Makro Derleyicisi (MASM) ifade söz diziminin kullanımı açıklanmaktadır.

Hata ayıklayıcısı iki farklı türde sayısal ifade kabul eder: C++ ifadeleri ve MASM ifadeleri. Bu ifadelerin her biri, giriş ve çıkış için kendi söz dizimi kurallarına uyar.

Her söz dizimi türünün ne zaman kullanıldığı hakkında daha fazla bilgi için bkz . İfadeleri Değerlendirme ve ? (İfadeyi Değerlendir).

Bu örnekte... komutu, MASM ifade değerlendiricisini kullanarak komut işaretçisi yazmacının değerini görüntüler.

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

İfade Değerlendiricisini MASM olarak ayarlama

Varsayılan ifade değerlendiricisinin ne olduğunu görmek ve MASM olarak değiştirmek için .expr (İfade Değerlendiriciyi Seç) kullanın.

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

Artık varsayılan ifade değerlendiricisi değiştirildiğine göre , ? (İfadeyi Değerlendir) komutu MASM ifadelerini görüntülemek için kullanılabilir. Bu örnek, 8'in onaltılık değerini rip yazmacına ekler.

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

@rip yazmacının başvurusu Yazmaç Söz Dizimi bölümünde daha ayrıntılı olarak açıklanmıştır.

Hata Ayıklayıcı MASM İfadelerindeki Sayılar

16, 10, 8 veya 2 tabanındaki MASM ifadelerine sayı koyabilirsiniz.

Varsayılan radyanı 16, 10 veya 8 olarak ayarlamak için n (Sayı Tabanını Ayarla) komutunu kullanın. Tüm ön eki olmayan sayılar daha sonra bu tabanda yorumlanır. Varsayılan tabanı geçersiz kılmak için 0x ön ekini (onaltılık), 0n ön ekini (ondalık), 0t ön ekini (sekizlik) veya 0y ön ekini (ikili) belirtebilirsiniz.

Ayrıca, sayının arkasına bir h ekleyerek onaltılık sayılar da belirtebilirsiniz. Sayılar içinde büyük veya küçük harfler kullanabilirsiniz. Örneğin, "0x4AB3", "0X4aB3", "4AB3h", "4ab3h" ve "4aB3H" aynı anlama sahiptir.

Bir ifadedeki ön ekin arkasına sayı eklemezseniz, sayı 0 olarak okunur. Bu nedenle, 0'ı 0, 0 ön ekini ve ardından yalnızca ön eki yazabilirsiniz. Örneğin, onaltılık sistemde "0", "0x0" ve "0x" aynı anlama gelir.

xxxx'xxxx biçiminde onaltılık 64 bit değerler girebilirsiniz. Ayrıca, aksan (') işaretinden de atlayabilirsiniz. Mezar aksanını eklerseniz , otomatik işareti genişletme devre dışı bırakılır.

Bu örnekte, ondalık, sekizlik ve ikili değerin kayıt 10'a nasıl ekleneceği gösterilmektedir.

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

Hata Ayıklayıcı MASM İfadelerindeki Simgeler

MASM ifadelerinde, herhangi bir simgenin sayısal değeri bellek adresidir. Simgenin başvurduğu şeye bağlı olarak, bu adres bir genel değişkenin, yerel değişkenin, işlevin, segmentin, modülün veya başka bir tanınan etiketin adresidir.

Adresin hangi modülle ilişkilendirileceğini belirtmek için, simge adının önüne modül adını ve ünlem işaretini (!) ekleyin. Simge onaltılık sayı olarak yorumlanabilirse, simge adından önce modül adını ve ünlem işaretini veya yalnızca ünlem işaretini ekleyin. Sembol tanıma hakkında daha fazla bilgi için bkz. Sembol Sözdizimi ve Simge Eşleştirme.

Bir sınıfın üyelerini belirtmek için iki nokta üst üste (::) veya iki alt çizgi (__) kullanın.

Sembol adında yalnızca simgeden önce bir modül adı ve ünlem işareti eklerseniz, nokta işareti (') veya kesme işareti (') kullanın.

MASM İfadelerinde Sayısal İşleçler

Bir birli işleci kullanarak ifadenin herhangi bir bileşenini değiştirebilirsiniz. İkili işleç kullanarak herhangi bir iki bileşeni birleştirebilirsiniz. Birli işleçler ikili işleçlere göre önceliklidir. Birden çok ikili işleç kullandığınızda, işleçler aşağıdaki tablolarda açıklanan sabit öncelik kurallarını izler.

Öncelik kurallarını geçersiz kılmak için her zaman parantez kullanabilirsiniz.

MASM ifadesinin bir bölümü parantez içine alınmışsa ve ifadeden önce iki at işareti (@@) görünüyorsa, ifade C++ ifade kurallarına göre yorumlanır. İşaretlerdeki ikisi ile açma parantezi arasına boşluk ekleyemezsiniz. İfade değerlendiricisini@@c++( ... ) veya @@masm( ... ) kullanarak da belirtebilirsiniz.

Aritmetik hesaplamalar gerçekleştirdiğinizde, MASM ifade değerlendiricisi tüm sayıları ve simgeleri ULONG64 türleri olarak değerlendirir.

Birli adres işleçleri, adresler için varsayılan kesim olarak DS'yi varsayar. İfadeler işleç önceliği sırasına göre değerlendirilir. Bitişik işleçler eşit önceliğe sahipse, ifade soldan sağa değerlendirilir.

Aşağıdaki tekli işleçleri kullanabilirsiniz.

Operatör Anlamı

+

Üniter artı

-

Tekli eksi

değil

Bağımsız değişken sıfırsa 1 döndürür. Sıfır olmayan herhangi bir bağımsız değişken için sıfır döndürür.

merhaba

Yüksek 16 bit

alçak

Düşük 16 bitler

tarafından

Belirtilen adresten düşük sıralı bayt.

$pby

Fiziksel bir adres alması dışında ile aynıdır. Yalnızca varsayılan önbelleğe alma davranışını kullanan fiziksel bellek okunabilir.

Wo

Belirtilen adresten düşük sıralı sözcük.

$pwo

Fiziksel bir adres alması dışında wo ile aynıdır. Yalnızca varsayılan önbelleğe alma davranışını kullanan fiziksel bellek okunabilir.

dwo

Belirtilen adresten çift sözcük.

$pdwo

Fiziksel bir adres alması dışında dwo ile aynıdır. Yalnızca varsayılan önbelleğe alma davranışını kullanan fiziksel bellek okunabilir.

qwo

Belirtilen adresten dört kelime.

$pqwo

Fiziksel bir adres alması dışında qwo ile aynıdır. Yalnızca varsayılan önbelleğe alma davranışını kullanan fiziksel bellek okunabilir.

poi

Belirtilen adresten gelen işaretçi boyutundaki veriler. İşaretçi boyutu 32 bit veya 64 bittir. Çekirdek hata ayıklamada, bu boyut hedef bilgisayarın işlemcisini temel alır. Bu nedenle, işaretçi boyutundaki verileri istiyorsanız poi kullanılacak en iyi işleçtir.

$ppoi

Fiziksel bir adres alması dışında poi ile aynıdır. Yalnızca varsayılan önbelleğe alma davranışını kullanan fiziksel bellek okunabilir.

Örnekler

Aşağıdaki örnek, bir işaretçinin bellek konumundaki depolanan değeri görmek için poi'nin nasıl kullanılacağını göstermektedir.

önce ilgilendiğin bellek adresini belirleyin. Örneğin iş parçacığı yapısına bakabilir ve CurrentLocale değerini görmek istediğimize karar verebiliriz.

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, TEB'in başlangıcının ötesinde 0x108 konumunda bulunmaktadır.

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

Bu adrese başvuruyu geri almak için poi kullanın.

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

Döndürülen 409 değeri, TEB yapısındaki CurrentLocale değeriyle eşleşir.

Veya hesaplanmış adresteki referansı kaldırmak için poi ve parantezleri kullanın.

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

Hedef adresten bayt veya sözcük döndürmek için by veya wo tekli işleçlerini kullanın.

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

İkili İşleçler

Aşağıdaki ikili işleçleri kullanabilirsiniz. Her hücredeki işleçler, alt hücrelerdekilerden daha üstündür. Aynı hücredeki işleçler aynı önceliğe sahiptir ve soldan sağa ayrıştırılır.

Operatör Anlamı

*

/

mod (veya %)

Çarpma

Tamsayı bölme

Modulus (kalan)

+

-

İlave

Çıkarma

<<

>>

>>>

Sola kaydırma

Mantıksal sağ kaydırma

Aritmetik sağ kaydırma

= (veya ==)

<

>

<=

>=

!=

Eşittir

Daha az

Daha büyük

Küçüktür ya da eşittir

Büyüktür veya eşittir

Eşit değil

ve (veya &)

Bit Düzeyinde VE

xor (veya ^)

Bit Düzeyinde XOR (özel OR)

veya (veya |)

Bit Düzeyinde OR

<, , >=, ==ve != karşılaştırma işleçleri, ifade doğruysa 1, ifade false ise sıfır olarak değerlendirilir. Tek bir eşittir işareti (=), çift eşittir işareti (==) ile aynıdır. MASM ifadesinde yan efektleri veya atamaları kullanamazsınız.

Hata Ayıklayıcı Komut penceresine, geçersiz bir işlem (sıfıra bölme gibi) yapıldığında bir "Operand hatası" döndürülür.

Döndürülen değerin 0x409 eşleştiğinde == karşılaştırma işlecini kullanarak denetleyebiliriz.

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

MASM İfadelerinde Sayısal Olmayan İşleçler

MASM ifadelerinde aşağıdaki ek işleçleri de kullanabilirsiniz.

Operatör Anlamı

$fnsucc(FnAddress, RetVal, Flag)

RetVal değerini FnAddress adresinde bulunan işlev için dönüş değeri olarak yorumlar. Bu dönüş değeri başarı kodu olarak nitelerse $fnsuccTRUE döndürür. Aksi takdirde , $fnsuccFALSE döndürür.

Dönüş türü BOOL, bool, HANDLE, HRESULT veya NTSTATUS ise , $fnsucc belirtilen dönüş değerinin başarı kodu olarak nitelenip nitelenmediğini doğru bir şekilde anlar. Dönüş türü bir işaretçiyse, NULL dışındaki tüm değerler başarı kodları olarak niteler. Diğer herhangi bir tür için başarı , Flag değeriyle tanımlanır. Flag 0 ise, RetVal'un sıfır olmayan bir değer olması durumunda başarı sağlanır. Bayrak 1 ise, RetVal değerinin sıfır değeri başarılı olur.

$iment (Adres)

Yüklenen modül listesindeki görüntü giriş noktasının adresini döndürür. Adres , Taşınabilir Yürütülebilir (PE) görüntü temel adresini belirtir. Giriş, Address öğesinin belirttiği görüntünün PE görüntü başlığındaki görüntü giriş noktası aranarak bulunur.

Bu işlevi, modül listesinde bulunan her iki modülde de kullanabilir ve bu komutunu kullanarak çözümlenmemiş kesme noktaları ayarlayabilirsiniz.

$scmp("String1", "String2")

strcmp C işlevini kullanarak strcmp gibi -1, 0 veya 1 olarak değerlendirilir.

$sicmp("String1", "String2")

Stricmp Microsoft Win32 işlevi gibi -1, 0 veya 1 olarak değerlendirilir.

$spat("String", "Pattern")

DizeninDesen ile eşleşip eşleşmediğine bağlı olarak TRUE veya FALSE olarak değerlendirilir. Eşleşme büyük/küçük harfe duyarlı değildir. Desen , çeşitli joker karakterler ve tanımlayıcılar içerebilir. Söz dizimi hakkında daha fazla bilgi için bkz. String Joker Karakter Sözdizimi.

$vvalid(Adres,Uzunluk)

Address konumunda başlayan ve Uzunluk baytları için genişleten bellek aralığının geçerli olup olmadığını belirler. Bellek geçerliyse , $vvalid 1 olarak değerlendirilir. Bellek geçersizse , $vvalid 0 olarak değerlendirilir.

Örnekler

Aşağıda, yüklenen modülün çevresindeki geçerli bellek aralığını araştırma özelliğinin nasıl kullanılacağı gösterilmektedir

İlk olarak, örneğin lm (Yüklenen Modülleri Listele komutu) kullanarak ilgili alanın adresini belirleyin.


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

Bellek aralığını denetlemek için $vvalid kullanın.

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

Bu büyük aralığın geçersiz bir bellek aralığı olduğunu onaylamak için $vvalid kullanın.

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

Bu aynı zamanda geçersiz bir aralıktır.

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

Bellek aralığı geçerli olduğunda sıfır döndürmek için not kullanın.

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

adresi belirlemek için daha önce lm komutunu kullandığımız COMCTL32 giriş noktasına bakmak için $imnet kullanın. 00007ff9'591d0000 ile başlar.

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

Giriş noktası kodunu incelemek için döndürülen adresi sökün.

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, bu modülün giriş noktası olduğunu onaylayan çıktıda görüntülenir.

MASM İfadelerinde Registerler ve Pseudo-Registers

MASM ifadeleri içinde yazmaçları ve sahte yazmaçları kullanabilirsiniz. Tüm yazmaçlardan ve sahte yazmaçlardan önce (@) işareti ekleyebilirsiniz. at işareti hata ayıklayıcının değere daha hızlı erişmesine neden olur. Bu @ işareti, en yaygın x86 tabanlı yazmaçlar için gereksizdir. Diğer yazmaçlar ve sahte yazmaçlar için at işaretini eklemenizi öneririz, ancak aslında zorunlu değildir. Daha az yaygın olan yazmaçlar için "at" işaretini atlarsanız, hata ayıklayıcı metni önce onaltılık bir sayı, sonra bir sembol ve son olarak bir yazmaç olarak ayrıştırmaya çalışır.

Geçerli yönerge işaretçisini belirtmek için nokta (.) de kullanabilirsiniz. Bu dönemden önce @ işareti eklememelisiniz ve r komutunun ilk parametresi olarak nokta kullanamazsınız. Bu dönem, $ip sahte yazmaç ile aynı anlama sahiptir.

Yazmaçlar ve sahte yazmaçlar hakkında daha fazla bilgi için bkz. Yazma Söz Dizimi ve Pseudo-Register Söz Dizimi.

Yazmaç değerinin @rip 00007ffb'7ed00770 olduğunu görmek için r register komutunu kullanın.

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

Aynı değer kullanılarak görüntülenebilir. nokta kısayolu.

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

Bu MASM ifadesini kullanarak bu değerlerin tümünün eşdeğer olduğunu ve varsa sıfır döndürdüğünü onaylayabiliriz.

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

MASM İfadelerinde Kaynak Satır Numaraları

MASM ifadeleri içinde kaynak dosya ve satır numarası ifadelerini kullanabilirsiniz. Bu ifadeleri vurgu (') kullanarak kapatmalısınız. Söz dizimi hakkında daha fazla bilgi için bkz. Kaynak Satırı Söz Dizimi.

Ayrıca bakınız

MASM İfadeleri ile C++ İfadeleri Karşılaştırması

Karma İfade Örnekleri

C++ Numaraları ve İşleçleri

Uzantıyı İmzala

? (İfadeyi Değerlendir)