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

Assembly 基于转换的索引模式到间接寻址模式(x86汇编),assembly,x86,att,addressing,Assembly,X86,Att,Addressing,我在Ubuntu上使用x86 AT&T汇编 我需要将任何复杂的间接寻址模式(如基于索引的模式)重写为简单的间接寻址模式 例如,以以下代码段为例: .L4: movl i, %eax movzbl ch, %edx movb %dl, dict(%eax) 我认为行movb%dl,dict(%eax)是基于索引寻址的。它所做的是取dict+%eax并取消引用它,然后将%dl放入其中,对吗 现在我这样写是为了简化间接寻址: .L4: movl i

我在Ubuntu上使用x86 AT&T汇编

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

例如,以以下代码段为例:

.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
行中遇到了一个分段错误


为什么这不起作用呢?

除了at&t语法的一个特点之外,你什么都做对了:你需要对立即数进行
$
签名,然后把地址用作立即数。所以您真正想要的是
addl$dict,%eax
。您从内存中的地址
dict
加载了一个值,然后将其用作地址,从而导致了故障。

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