操作数必须是可重定位的程序集 x86 问题

Posted

技术标签:

【中文标题】操作数必须是可重定位的程序集 x86 问题【英文标题】:operand must be relocatable Assembly x86 problem 【发布时间】:2018-12-24 11:20:46 【问题描述】:

在这段代码中,我试图访问数组[i-1][j+1],在汇编中,我们只能处理一维数组,所以我试图通过从我的宽度中减去当前索引来访问这个索引"W" 并乘以 4,因为类型是 DWORD 但是当我尝试这行“MOV EAX,[EDI - P]”时,它会导致错误提示吗?

        MOV EAX, W
        ADD EAX, 1
        MOV EBX, 4
        MUL EBX
        MOV P, EAX
        MOV EAX, [EDI- p];; up Right
        ADD ESI, EAX

【问题讨论】:

哪些寄存器包含i和j? 没有寄存器包含 i , j 我正在通过宽度访问 数组中字节偏移量的计算为:(W * (i - 1) + (j + 1)) * 4 没有i和j怎么访问array[i-1][j+1]? 假设你有一个宽度 = 5 的数组并且你在索引 7 上并且你想访问 arr[i-1][j] 然后当前索引 - 宽度 = arr[i-1][ j] 【参考方案1】:

您的尝试有两个问题:您不能在寻址模式下进行减法,并且您不能使用内存位置的内容。

但是,您可以添加一个常数,然后乘以 2、4 或 8,这两者都可以在这里发挥优势。

        MOV EAX, W
        NEG EAX
        MOV EAX, 4[EDI+EAX*4];; up Right
        ADD ESI, EAX

常数可以是负数,所以当你想访问array[i-1][j-1]时,可以使用

        MOV EAX, -4[EDI+EAX*4];; up left

【讨论】:

您可以在寻址模式中添加一个负数。问题是目标文件格式不支持否定绝对地址的重定位类型,因此无法让链接器为[esi - P] 填写正确的disp32。有一个合理的用例:LEA eax, [esi - P] 作为大小计算。但是,是的,看起来 OP 认为会有额外的间接级别。

以上是关于操作数必须是可重定位的程序集 x86 问题的主要内容,如果未能解决你的问题,请参考以下文章

AT&T 语法中的 3 或 4 参数 x86 程序集[重复]

x86指令集总结

80x86调用函数指令是啥

在“任何 CPU”.NET 程序集上强制 x86 CLR

x86 程序集分段错误

未能加载的文件或程序集.怎么解决