【问题标题】:Relative addressing in assembly汇编中的相对寻址
【发布时间】:2012-02-20 22:00:58
【问题描述】:

我想知道我是否理解正确:

据我所知,x86 中相对寻址的语法是这样的:

base + index * scale + displacement

现在假设这些假设:

int i //valuee in ecx 
int arr[256] //adress in esi

我想将以下内容加载到 eax 中:

arr[i + 10]

我的第一个猜测是:

mov eax, dword ptr[esi + ecx*4 + 10*4]

但我不确定第二次乘法,因为它不符合上述语法。

另外:如果索引和数组的数据类型不同怎么办。例如:

short arr[i + 10]

乘法会发生什么?

【问题讨论】:

    标签: assembly intel


    【解决方案1】:

    按照您的代码,它总是更容易分解:

    • esi 是指向 arr 的指针
    • ecxi
    • 10 * sizeof(int) = 40

    所以现在我们把它放在一起:

    mov eax, dword ptr[esi + ecx* 4 + 40]

    因此您的陈述是正确的。第二个乘法应该由你的汇编器折叠到一个常数 40,如果不是,那么你需要手动计算它,但是你需要在你的汇编器上测试它(或者编译器,如果这是用于内联组装)。

    更新

    您需要将常量调整为新的元素大小,但不需要更改寄存器: mov eax, dword ptr[esi + ecx * 2 + 20]

    如果这是作为内联汇编程序完成的,那么您可以使用 sizeof 运算符,以简化操作,并将其折叠起来,某些汇编程序也可能允许 SIZEOF 宏。

    【讨论】:

    • 啊啊啊啊啊啊啊啊啊。完全忘记了这样的优化;-)
    • 嘿,我修改了原始问题以包含相关主题。你也可以评论一下吗?
    • 它应该是esi+ecx*4+40(32 位)或rsi+rcx*8+80(64 位),但不能混合使用两者。另外,我认为您现在找不到不进行常量表达式折叠的汇编程序。即使假设您确实得到了一个,它也肯定会在组装时抱怨“无效”指令。
    • @Igor:看来我的数学有点不对劲……不过,ints 的大小是恒定的,所以 32 位或 64 位为 40
    • 哎呀,不知道为什么我决定它在 x64 上更长:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-16
    • 1970-01-01
    相关资源
    最近更新 更多