我刚刚发现了一些有趣的东西,我正在努力寻求更好的理解。 我试图使用Irvine WriteString调用。
Writestring
写一个以空字符结尾的字符串。
输入:DX指向字符串偏移量
INCLUDE Irvine32.inc
.data
fizz BYTE "Fizz", 0
...
MOV EDX, OFFSET fizz
CALL WriteString
CALL CrLf
完美无缺,我可以看到" Fizz "在我的窗口中,就像在documentation中一样。
但是,如果我尝试使用 DWORD 而不是 BYTE
fizz DWORD "Fizz", 0
我要去看" zziF "在提示窗口中。 据我所知,唯一的区别是BYTE和DWORD之间的比特大小(8位对32位)。 我真的不明白相反的顺序。发生了什么?
我感谢每一个答案!
答案 0 :(得分:1)
你的问题与" Irvine"完全无关。或" WriteString"。
简短的回答是,您所看到的是您在英特尔x86架构上编程的直接结果,即 little endian ,而您正在使用由一些老黑客编写的汇编程序。
接下来的答案很长。
如果您正在处理汇编语言,那么您应该通过在维基百科或其他地方查找,了解有关 endianness 的所有内容,但简而言之,它定义了字节的存储方式连续的存储器位置,以形成大于字节的数量。有两种类型的字节顺序:
小端表示在大于字节的数量上,首先存储最低有效("低")字节,然后是连续更高有效位的字节。因此,在DWORD
中,首先存储最不重要("低")字,然后是最重要("高")字。这与 big endian 相反,其中首先存储高字节。您可能认为大端更直观,因为它更接近地匹配我们人类如何表示数字,最重要的数字是最左边的数字,而不是有效数字跟随,但这只是我们人类,它是完全随意;数字的性质没有任何关系要求数字的重要性应该从左到右或从右到左排序。相反,小端有一些硬件优势,这是英特尔为x86架构所选择的。
但我离题了。
所以,这是正在发生的事情:
您正在使用的汇编程序正在尝试变得智能,并允许您使用字符串文字指定DWORD
的值。这是荒谬的,因为DWORD
应该包含32位数字,而不是字符串,但他们正在尝试容纳肮脏的黑客攻击。它也完全是随意的,因为人们可以想象有很多方法可以实现这样的怪癖,他们只选择了一种方式,我想他们最喜欢的方式。
所以,显然,他们所做的是他们采用你的字符串文字,他们认为它是一组四个字符形成DWORD
。当然,当他们将DWORD
存储在内存中时,它们会以适合英特尔架构的小端存储它,这意味着您可以获得" zziF"而不是" Fizz"。重要的是要理解这个" zziF"由汇编程序烘焙到您的程序中,并且" WriteString"函数在看到它时打印它。如果您使用任何其他打印字符串的函数,则会打印相同的内容。这不是功能的错误。