【发布时间】:2018-02-06 14:30:18
【问题描述】:
我是汇编语言的新手。我正在尝试下面的代码,你可以看到下面的代码。
bits 64
global _start
section .text
_start:
mov rcx, 1234567890
xor rcx, rcx
mov rcx, 'wxyz'
mov rax, 60
mov rdi, 0
syscall
我想知道为什么数字在寄存器中存储为大端,而字符在寄存器中存储为小端
我以为只有在内存中,数据以小端序存储。但我不明白为什么这些字符在寄存器中存储为小端。请告诉我。
谢谢。
【问题讨论】:
-
这取决于你的汇编器(你没有指定但看起来像
nasm)。这个想法是,如果写入内存,您将按预期顺序获取字符串。 -
x86 会将其读取为小端序。但是 NASM 将以这样的方式组装它,“abcd”将作为字节“a”、“b”、“c”、“d”进入内存......关于字符串字节序和这个特殊的原因没有太多意义NASM 关于字符串常量的特性就是这样设计的,它“额外的方便”,稍微偏离了严格的机器逻辑。因此,如果您使用
mov eax,'0123'与mov eax,0x30313233,这两个是不同的值(bswap方式不同)。您只需记住这一点(就像任何其他语法“怪癖”一样)。或者在组装你得到的东西后检查列表文件中的机器代码。 -
这更像是 NASM 将字符串常量视为字节流(在生成的机器代码中保持它们的“字符串”顺序),即使在上下文中用作单词或更大的类型时,数字常量也很少-endian 处理并在内存中“反转”。 CPU 不知道您的来源,因此它不知道(来自字符串和表示字符的值),如果您执行类似
mov eax,'0123'=>eax = 0x33323130. -
@vanquish 我不太明白你在这里的最后一条评论,它是温和的“是”,在内存中小端,在寄存器中你可以认为它是大端,但它更像是在注册值只是 value (无字节序)。除了左移/右移之外,它几乎没有“空间方向”,它在 CPU 中的某个地方有位,很难说在哪里以及以什么顺序,你可以把它当作常识使用,作为二进制整数值/等等......当存储到内存中时被撕成LE字节。并且调试器自然地显示 reg 值(“BE”-like),但这是格式化代码。
标签: assembly x86-64 endianness