程序集x86 Irvine WriteString字节与Dword

问题描述:

我刚刚注意到一些有趣的事情,并且我试图获得更好的理解。 我试图使用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位)。 我真的不明白相反的顺序。发生了什么?

我很感谢每一个答案!

你的问题与“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!:) - –