代码之家  ›  专栏  ›  技术社区  ›  Zaratustra

难以理解机器指令的执行

  •  0
  • Zaratustra  · 技术社区  · 11 年前

    我正在读兰德尔·海德(Randall Hyde)的《编写伟大的代码:理解机器》(Write great code:understanding the machine)一书,这是一本很棒、清晰的书,但在这里我完全坚持他的解释,例如mov指令。

    他剖析了 mov(srcReg,destMem) 说明如下:

    1. Fetch the instruction's opcode from memory.
    2. Update the EIP register with the address of the byte following the opcode.
    3. Decode the instruction's opcode to see what instruction it specifies.
    4. Fetch the displacement associated with the memory operand from the memory location immediately
    following the opcode.
    5. Update EIP to point at the first byte beyond the operand that follows the opcode.
    6. If the mov instruction uses a complex addressing mode (for example, the indexed addressing mode),compute the effective address of the destination memory location.
    7. Fetch the data from srcReg.
    8. Store the fetched value into the destination memory location.
    

    我迷失在第4-6步。我的确切问题是:

    第四步:我为什么需要这个位移,我以后要怎么用,为什么?

    步骤5:我理解在步骤2中,EIP必须“指向”存储下一条要执行的指令的下一个字节。但我不明白为什么EIP需要超出操作数地址一个字节。我认为EIP只关注指令/操作码,而不是数据。

    第六步:什么是准确有效的地址?还有其他类型的地址吗?

    1 回复  |  直到 11 年前
        1
  •  2
  •   Mirinth    11 年前

    步骤4:

    一些操作码引用与操作码位置相关的内存。例如,函数可能有一个常量或静态数据段。如果是这样,代码可能会选择在函数开始之前(或在函数结束之后)放置它,并通过说“提前46字节获取内存”来引用它。这就是位移——它是寄存器(在本例中是EIP)内容的偏移量,用于引用相对于寄存器内容的数据。

    步骤5

    操作码的操作数通常存储在操作码之后。所以你可能有这样安排的一些记忆: a b c . a is和操作码, b 是的操作数 c 是下一个操作码。

    如果只将EIP移动到 (所以它引用了 b ),则在下一个指令周期中,计算机将假设 b 是要执行的下一个操作码。 b 不应该是操作码;它是一个操作数。不过,计算机无法分辨操作码和操作数之间的区别。它只是假设EIP指向的是一条指令并执行它。这就是为什么EIP也需要移过操作数。

    步骤6

    一个“有效”地址只是一个绝对地址(相对于内存的开始),而书中所指的“复杂”地址是相对于其他地址(通常是寄存器的内容)。

    步骤4显示操作码可能不引用绝对内存地址。它可以很容易地指代一个相对的。事实上,程序经常引用与某些寄存器相关的地址。例如,如果您 some_struct.data 在C中,并为x86处理器编译它,它将加载 some_struct 进入寄存器(比如EAX),然后硬代码 data 的偏移量 某些结构 输入操作数。因此,如果结构的开头和结构的开头之间有5个字节的数据 数据 元素,那么指令可能看起来像 load [EAX + 5] -> EBX 这意味着“获取EAX中的内容,添加5,从该地址获取数据并将其放入EBX”。

    问题是,内存并不能真正理解这样的相对地址。它只理解绝对的。因此,为了访问相对地址,处理器必须首先将该5添加到EAX中的任何值,以计算绝对地址。然后,它可以将该地址发送到内存控制器并使其被理解。

    我使用过两种基本类型的相对地址(还有更多我没有)。

    • 相对寄存器:处理器获取寄存器的内容,并将其用作内存中的地址。根据操作码和处理器支持,它还可以向寄存器中添加操作数。第4步是处理这种寻址,将EIP作为地址所对应的寄存器。
    • 相对记忆:有时称为“间接”。处理器从一个寄存器相对地址开始,然后自动获取该地址的数据,并将其视为实际地址。
    • 维基百科在其网站上描述了许多其他寻址模式 addressing modes

    记忆亲戚花了我一段时间才明白。假设您在寄存器包含 10 偏移量为 5 。处理器会将它们相加( 10 + 5 = 15 ). 然后,它会转到那个地址( 15 在这种情况下)并抓住那里的任何东西。If地址 15 恰好包含该值 60 然后 60 将被视为实际地址,处理器将加载地址的内容 60 如果你熟悉一种带有指针的语言(例如C),相对内存就像指针对指针。