我试图绕过一些内联ASM,但由于某种原因,这不符合我的预期。为什么不设置x的值等于62?
#include <stdio.h>
int main()
{
int x = 525;
int* y = &x;
_asm
{
mov eax, 62
mov [y], eax
}
printf("%i", x);
getchar();
return 0;
}
代码导致输出525。我预计它会是62岁。
答案 0 :(得分:2)
这里有一个完全可以理解的误解:
肯定[y]意味着[0xCCCCCCCC](假设x的地址是0xCCCCCCCC)
在高级理论中,是的。问题是,在实际汇编[0xCCCCCCCC]
没有意义 - CPU不能直接取消引用内存地址 - 它只能从该地址加载一个值到一个寄存器中,然后取消引用< EM>那
同样,由于y
是变量,而不是寄存器,因此它被隐含地视为地址 1 ,即{{在y
块内部,1}}相当于 2 之外的C代码中的asm
。正如您在调试器中逐步看到的那样,发生了什么事情,汇编器只是忽略了没有意义的括号(而不是抛出一个有用的错误)并组装了等效的&y
。
获得你期望的方式将是这样的:
mov y, eax
[1]这显然不是GCC。 GCC扩展asm是一个整个不同的球赛......
[2]有点简化 - 从C的角度来看它是一个“地址”,但在汇编语境中它是一个内存操作数,它更像是地址的 use 。当我编译它时,asm {
mov eax, 62
mov edx, y
mov [edx], eax
}
出现为y
,从高级视图看来是“堆栈中的地址”。
答案 1 :(得分:0)
您将x
的地址加载到y
。然后,您将62
存储在变量 y
的地址(再次!)中 - 这就是[..]
语法的含义。所以你不是修改变量x
而是修改存储在*(* y)的值。 (并且这不会让你的程序崩溃,这是一个小小的奇迹。)
你可能想要
mov [&y], eax
(如果您的编译器接受该语法)。