【问题标题】:Why is data stored in memory reversed?为什么存储在内存中的数据会颠倒?
【发布时间】:2015-01-08 21:26:36
【问题描述】:

这是我的源代码:

section .data           
msg:    db "pppaaa"     
len:    equ $
section .text           
    global  main    
main:                    
    mov     edx,len 
    mov     ecx,msg 
    mov     ebx,1   
    mov     eax,4   
    int     0x80

当我调试这段代码时,我会看到:

(gdb) info register ecx
ecx            0x804a010        134520848
(gdb) x 0x804a010
0x804a010 <msg>:        0x61707070
(gdb) x 0x804a014
0x804a014:      0x00006161

这里的“70”代表字符'p',而“61”显然代表字符'a'。

我感到困惑的是,为什么位置 0x804a010 中的数据是 0x61707070 (appp) 而在 0x804a014 处向前移动 4 个字节,数据是 --aa ?

我希望看到第一个位置的 (pppa) 和第二个位置的 (aa--)。为什么会这样?

【问题讨论】:

  • 您很可能在 little-endian 环境中工作。字节只是以“另一种方式”存储。 See here
  • @lared 如何切换到高字节序?
  • @KorayTugay:你没有(大多数架构不能,而那些可以的,会导致你所有的程序崩溃)。您所做的是停止在 32 位视图中查看字节数组。使用面向字节的视图来匹配您的数据。当你说“位置 0x804a010 中的数据是 0x61707070”时你错了 实际上位置 0x804a010 中的数据是 0x70
  • 你(很可能!)不能。当我说环境时,我还指的是您正在使用的硬件。你能告诉我你的电脑有什么处理器吗?
  • 我一直认为您使用的是 x86 兼容处理器 - 英特尔历来在其处理器中使用小端约定,并且不允许切换它(与某些 ARM 处理器不同)。一般来说,您的程序应该与字节序无关,但是当使用 x86 程序集时,您可以假设它是小字节序。你真的无能为力。

标签: linux assembly x86 endianness


【解决方案1】:

GDB 不知道您有一堆字符。您只是要求它查看内存位置并显示那里的内容,默认为 4 字节整数。它假定整数首先存储最低有效字节,因为这是在 Intel 上完成的,因此您可以反转字节。

要解决此问题,请在您的 x 命令中使用格式说明符,如下所示:

 x/10c 0x804a010 

(将从 0x804a010 开始打印 10 个字符)。

GDB 中的help x 将提供更多信息。

【讨论】:

  • 所以我们可以这么说,实际上字节不是以相反的顺序存储的,但是 gdb 向我显示是因为它假设我正在查看一个整数?
  • @KorayTugay,是的,这是我的理解。
  • @lared Lared,这是否意味着字节实际上不是“以其他方式”存储的,而只是 gdb 的一种表示?
  • @KorayTugay 它们以另一种方式存储在寄存器中。字节序仅影响解释为不同变量(或数组元素)的超过 1 个字节的块。托尼说的是真的,每个字符都是 1 个字节长,所以字节序不会起作用。但是,如果您将它们解释为整数,它们将被解释为好像它们在写入内存时已被翻转,这意味着它们在读取时会自动翻转。在内存中它们没有被翻转,而是在处理器的注册表中 - 是的。
猜你喜欢
  • 2019-09-22
  • 2017-03-20
  • 1970-01-01
  • 2011-07-11
  • 1970-01-01
  • 2012-01-10
  • 2013-02-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多