基于转换的索引模式到间接寻址模式(x86 汇编)

Posted

技术标签:

【中文标题】基于转换的索引模式到间接寻址模式(x86 汇编)【英文标题】:Transform based indexed mode to indirect addressing mode (x86 assembly) 【发布时间】:2015-04-07 17:33:48 【问题描述】:

我在 Ubuntu 上使用 x86 AT&T 程序集。

我需要将任何复杂的间接寻址模式(例如基于索引的模式)重写为简单的间接寻址模式。

以这个sn-p为例:

.L4:
    movl    i, %eax
    movzbl  ch, %edx
    movb    %dl, dict(%eax)

我认为movb %dl, dict(%eax) 行是基于索引寻址的。它的作用是接受 dict+%eax 并取消引用它,然后将 %dl 放入其中,对吗?

现在我这样写是为了使它成为简单的间接寻址:

.L4:
    movl    i, %eax
    movzbl  ch, %edx
    addl    dict, %eax
    movb    %dl, (%eax)

如您所见,我首先添加了dict%eax,并将结果也放入%eax。然后在下一行我只是取消引用结果。

这应该和上面一样,对吧?

它也可以编译,但是在运行它时,我的新 movb 行出现分段错误。

为什么这不起作用?

【问题讨论】:

【参考方案1】:

除了 at&t 语法的特殊性之外,您做的一切都是正确的:您需要 $ 符号来表示立即数,并且您将地址用作那里的立即数。所以你真正想要的是addl $dict, %eax。您从地址dict 的内存中加载了一个值,然后将其用作地址,导致错误。

【讨论】:

谢谢,现在可以了!我忘记了 $ 符号,它的工作方式与 C 中的 & 相同。虽然现在我稍后在代码中遇到了分段错误...... 我知道为什么我现在得到一个错误。因为我使用%eax 来存储dict+%eax 的地址,所以%eax 现在是一个很长的数字,一个地址,而不是我的数组索引。因此,当我稍后再次使用它时,我会遇到分段错误,因为它会尝试执行类似dict[40203402] 的操作。也许我可以使用另一个我从未使用过的寄存器,例如 %ebx ……或者我只是在间接寻址之后将 i 移回 %eax。成功了!

以上是关于基于转换的索引模式到间接寻址模式(x86 汇编)的主要内容,如果未能解决你的问题,请参考以下文章

x86汇编如何查看一个地址的值

x86汇编语言

汇编语言ARM扩展资料数据寻址

操作系统学习80x86保护模式内存管理

x86 分页机制——虚拟地址到物理地址寻址

汇编语言中的寻址模式 (IA-32 NASM)