在函数中更改数组值 - 内联汇编

7

我之前学习了x86汇编语言,最近在尝试使用C++内联汇编。

我的想法是,在函数的参数中传递一个数组、一个索引(无符号整数)和一个数字。通过汇编语言,它将改变数组中该内存位置的值为传入的值。代码看起来像这样:

inline void Set( int pArray[], unsigned int pIndex, int pNum ) {
    __asm {
        mov ebx, pIndex
        mov eax, 4
        mul ebx
        mov ebx, pNum

        lea edi, pArray
        mov [ edi + eax ], ebx
    }
}

int main() {
    int myArray[ 5 ] = { 1, 2, 3, 4, 5 };
    Set( myArray, 2, 7 );
    std::cout << myArray[ 2 ] << std::endl;
}

因此,代码应该加载数组地址的开头,获取索引并将其乘以4,以便内存位置向右移动那么多个字节,并将其更改为传递的值。然而,当我这样做时,值保持不变。为什么会这样?出了什么问题?


2
你可能想要使用 mov edi, pArray,否则你可能会加载参数变量的地址,而不是它指向的位置。你可能还想通过使用调试器来自学 :) - Jester
1
是的,那就是问题所在。我最初是在函数外部编写的,因此可以在其范围内访问数组,所以当时它能够正常工作,但是当封装在函数中时,它停止工作了,所以使用“mov”而不是“lea”是有道理的。谢谢 :-) - CMilby
1个回答

1

lea代表“加载有效地址”,你的lea放置参数的地址。你的意思是lea edi, [pArray]

然而,还有两件事情: 1)你不必乘以四。你可以这样做:lea edi, [pArray + 4*ebx],因为“比例索引字节”寻址模式允许你乘以4并添加一个立即地址。

2)你假设是32位。在2015年中期仍在使用32位模式的电脑是什么?

我对intel语法汇编有点生疏。我可以推荐你学习GCC中汇编和C++代码的集成吗? https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html


对于第一点,lea edi,[pArray + 4 * ebx]不会改变值。至于第二点,这是一个很好的问题。我使用的是Visual Studio Professional 2010,它不允许我使用64位寄存器。我最初使用了64位寄存器,但一直收到错误C2415。 - CMilby
不需要加载有效地址,也不需要使用乘法指令。 检查gcc编译器的资源管理器显示: http://goo.gl/njHPU3 只需使用“比例索引字节”寻址方式,如下所示: mov [rdi + rsi * 4],edx 其中rdi是Linux调用约定中的数组基地址,rsi是索引参数,edx是值。 - TheCppZoo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接