2010-12-21 24 views
5

我需要帮助理解x86处理器的CPU寄存器内部的字节顺序。我写这个小汇编程序:CPU寄存器内的字节序编号

section .data 
section .bss 

section .text 
    global _start 
_start: 
    nop 
    mov eax, 0x78FF5ABC 
    mov ebx,'WXYZ' 
    nop ; GDB breakpoint here. 
    mov eax, 1 
    mov ebx, 0 
    int 0x80 

我在GDB运行此程序与行号10(在上面的源注释)断点。在此断点处,info registers显示的值为eax=0x78ff5abcebx=0x5a595857。由于W,X,Y,Z的ASCII码分别为57,58,59,5A,因此,而intel是小端,0x5a595857似乎是正确的字节顺序(最低有效字节在前)。那么为什么不是eax寄存器0xbc5aff78(数字0x78ff5abc的最低有效字节)的输出而不是0x78ff5abc

回答

5

字节序才有用内存,每个字节有数字地址。当一个值的MSByte被放在比LSByte更高的内存地址中时,它被称为Littte endian,这是任何x86处理器的字节序。

虽然整数低字节和高字节之间的区别是显而易见的:

0x12345678 
MSB---^^ ^^---LSB 

它不是字符串常量定义!这不是很明显应该被认为是什么WXYZ的一部分低位或高位:

1)最明显的方法,

'WXYZ' -> 0x5758595A 

会导致内存顺序ZYXW

2)不是不那么明显的方式,当内存顺序应与文字的顺序:

'WXYZ' -> 0x5A595857 

汇编器必须选择其中的一个,显然它选择第二个。

14

寄存器内部的字节顺序是没有意义的,因为字节顺序是描述字节顺序是从低到高存储器地址还是从高到低存储器地址。寄存器不是字节可寻址的,因此寄存器内没有低位或高位地址。你所看到的是你的调试器如何打印出数据。

+0

谢谢你的回复。显然'WXYZ'确实是以相反的顺序存储在ebx寄存器中的。根据调试器,BL寄存器包含87(十进制值0x57);当然,这里有一个字节顺序的概念?为什么'W'不是存储在ebx的最高8位? – wrxyz 2010-12-22 00:01:43

+3

实际上,寄存器*是*部分字节寻址的。您可以使用AL和AH访问EAX的较低两个字节。 – 2010-12-22 00:46:57

9

汇编程序以不同的方式处理这两个常量。在内部,EAX寄存器中的值以big-endian格式存储。你可以看到,通过文字:

mov eax, 1 

如果你查阅登记册,你会发现它的价值是0x00000001

当你告诉汇编器你想要恒定值0x78ff5abc时,这正是存储在寄存器中的东西。 EAX的高8位将包含0x78,并且AL寄存器包含0xbc

现在如果您将存储为 EAX中的值存入内存,它将以相反的顺序排列在内存中。也就是说,如果你写:

mov [addr],eax 

然后在[地址],你会看到0xbc,0x5a检查内存,为0xFF,0x78。

在'WXYZ'的情况下,汇编程序假定您要加载的值如果要写入内存,它将被布置为0x57,0x58,0x59,0x5a。

看看汇编器生成的代码字节,你会看到不同之处。在mov eax,0x78ff5abc的情况下,你会看到:

<opcodes for mov eax>, 0xbc, 0x5a, 0xff, 0x78 

mov eax,WXYZ的情况下,你会看到:

<opcodes for mov eax>, 0x57, 0x58, 0x59, 0x5a 
相关问题