i386架构GAS语法下:如何不加载寄存器直接访问内存中的指针变量?
i386汇编:指针指向内存的直接访问问题
环境说明:arch i386; 汇编语法 GAS
问题背景
有一个指针变量active,需要将寄存器值复制到它指向的内存位置。尝试movl %esp, (active)时,发现该指令直接修改了active变量本身,而非它指向的内存;改用两步指令movl active, %eax; movl %esp, (%eax)可以实现目标,但当前场景不允许修改任何寄存器或栈,因此需要寻找无需加载寄存器的直接访问方法。
为什么必须先加载指针到寄存器?
这是i386架构的指令集设计限制:
- GAS语法中,
(active)表示直接访问active变量所在的内存地址(即修改变量自身); - 要访问指针指向的目标内存,需要先获取
active变量存储的目标地址,但i386的mov指令不支持直接将“内存中指针指向的内存”作为目标操作数——其寻址模式要求,内存操作数的地址必须通过基址/变址寄存器间接指定,不存在直接的双重间接寻址写法,因此必须先把指针值加载到寄存器,再通过寄存器访问目标内存。
替代方案
如果严格要求不修改任何通用寄存器或栈,不存在完全符合要求的方案。i386指令集的设计决定了访问双重间接内存地址必须依赖寄存器中转。
若场景允许临时保存并恢复寄存器值(仅临时修改,不破坏原有状态),可以用以下方法(但会修改栈):
pushl %eax # 保存原有寄存器值到栈 movl active, %eax # 加载指针到寄存器 movl %esp, (%eax) # 写入目标内存 popl %eax # 恢复寄存器原有值
若允许使用字符串操作指令,也可以通过movsb实现,但需要设置%esi、%edi、%ecx等寄存器,同样会修改寄存器,无法满足你的场景限制。
内容的提问来源于stack exchange,提问作者Eylon
相关产品推荐
相关产品推荐

