x86 Assembly高级索引模式:如何在起始地址之前以可变的数量访问内存?

问题描述

我试图从存储在EAX寄存器中的内存地址开始,逐字节读取内存的一部分。我将当前字节推送到EBX寄存器。但是,当我执行以下代码行(高级索引模式)时:

movb byteCount(%eax),%ebx

我收到以下错误

程序收到信号SIGSEGV,分段错误

似乎Assembly不支持在高级索引中使用标签。在不使用标签或先注册(%eax)的情况下,我将如何模拟相同的操作?以下是数据部分:

.data
    str:
        .string "abcdefg"
        
    byteCount:
        .int 1

解决方法

在这种情况下,byteCount是标签地址,而不是恰好在内存中的dword 。您需要将所有运行时可变的东西加载到寄存器中,以在寻址模式下使用它们。 x86不执行内存间接寻址。

   mov    byteCount,%edx           # dword load
   movzbl (%eax,%edx),%ebx        # zero-extending byte load

或者当然可以使用add byteCount,%eax并取消引用(%eax)。或者更好的是,您可以首先将byteCount保存在寄存器中,以备不时之需。那就是寄存器的用途。 In x86 assembly,when should I use global variables instead of local variables?(通常不应该)。


movb进入EBX是一个错误(操作数大小不匹配),因此可以肯定这不是您实际运行的内容。但这将访问bytecount[ (uintptr_t)eax ]处的一个字节。如果仅使用mov,则将是双字加载。

但是,无论如何,两个地址的总和很少是有效地址,因此它会出现段错误。调试器应该已经告诉您错误的地址,因此您可以看到它与str距离很远。


相关: