2017-04-11 117 views
1

我剛剛注意到一些有趣的事情,並且我試圖獲得更好的理解。 我試圖使用Irvine WriteString調用。程序集x86 Irvine WriteString字節與Dword

Writestring

寫一個空結尾的字符串。
輸入:DX指向字符串偏移

INCLUDE Irvine32.inc 

.data 
    fizz  BYTE "Fizz", 0 

...

MOV EDX, OFFSET fizz 
CALL WriteString 
CALL CrLf 

而且完美地工作,我可以在我的窗口中看到 「菲斯」,就像在documentation

但是,如果我嘗試使用DWORD,而不是BYTE

fizz  DWORD "Fizz", 0 

我要去看看 「zziF」 的提示窗口。 據我所知,唯一的區別是BYTE和DWORD,以位爲單位的大小(8位和32位)。 我真的不明白相反的順序。發生了什麼?

我很感謝每一個答案!

回答

1

你的問題與「Irvine」或「WriteString」完全無關。

簡短的回答是,你看到的是一個事實,即你是在Intel x86架構,這是小尾數編程的直接結果,並且使用的是寫由一些彙編老黑客。

長的答案如下。

如果您正在使用匯編語言打交道,那麼你應該瞭解一切有了解字節序,看它在維基百科或別的地方,但它定義字節是如何存儲在連續的內存位置簡而言之形成大於字節的數量。有兩種類型的字節序:

  • 大端,並
  • 小尾數

Little endian表示在大於字節的數量上,首先存儲最低有效(「低」)字節,然後是較高有效字節。因此,在DWORD中,最低有效(「低」)字首先被存儲,並且最高有效(「高」)字接下來。這與big endian相反,其中高字節首先被存儲。你可能認爲大字節更直觀,因爲它更接近於我們人類代表數字的方式,最重要的數字是最左邊的數字,而後面的數字也不太有效,但這只是我們人類,而且完全是任意的;關於數字的性質沒有任何規定,數字的意義應該從左到右或從右到左排列。相反,小端存在某些硬件優勢,這就是英特爾爲x86架構所選擇的。

但我離題了。

所以,這裏是正在發生的事情:

您使用正試圖是聰明的,並允許您指定字符串文字的一個DWORD價值的彙編。這是無稽之談,因爲DWORD應該包含一個32位號碼,而不是一個字符串,但他們試圖容納骯髒的黑客。這也完全是任意的,因爲有很多方法可以設想這樣的怪癖可以實現,他們只是選擇了一種方式,我想他們最喜歡的一種。

顯然,他們做的是他們把你的字符串文字,他們認爲它是一組四個字符組成一個DWORD。當然,當他們將DWORD存儲在內存中時,它們將其存儲在小端,適合英特爾架構,這意味着您獲得「zziF」而不是「Fizz」。理解這個「zziF」是由彙編程序烘焙到你的程序中的,並且「WriteString」函數在它看到它時打印它是很重要的。如果您使用任何其他打印字符串的函數,將會打印相同的內容。這不是函數的錯誤。

+0

謝謝你的解釋! 嗯,你得到我我已經試圖存儲「FizzBu​​zz」作爲一個DWORD,但有一個建立錯誤,由於「太大常量」的大小,我想。 我真的不知道尺寸的限制。 但是,我正在瞭解endianness,但我從來沒有它可以導致這樣的事情。 所以基本上,使用字節而不是DWORD意味着我將有四個字符塊作爲BYTE,並且它的小字節序將按預期工作,如果我理解正確的話。 –

+1

是的,單個字節的排序問題不起作用。至於「太大的常量」,顯然彙編器期望一個符合DWORD的字符串,所以4個字符是極限。逗號後面的零編碼爲另一個DWORD,佔用另外四個字節。爲了好玩,你可以嘗試看看彙編程序支持QWORD;那麼,你應該得到'zzuBzziF'。 –

+0

謝謝,你幫了我很多!在我們的研究範例中,我甚至沒有看到QWORD,而且我今天剛剛學到了一些新東西。謝謝!現在我可以玩zzuBzziF!:) - –