【发布时间】:2019-09-16 18:02:36
【问题描述】:
我正在寻找一种在 c++ 内联汇编中定义变量的方法。我找到了一种有趣的方法。但这让我很困惑,这是如何工作的。
__asm
{
push ebp
mov ebp, esp
add esp, 4
mov [ebp - 4], 2
mov esp, ebp
pop ebp
}
我将此代码视为 - 将基指针地址推入堆栈,将堆栈指针地址移入基指针(堆栈逻辑上应该在这里折叠,因为这是清理堆栈的常见结尾功能)。然后我们将 4 移动到 esp 地址(甚至不是值),然后从 esp 中删除那个 4。所以我们回到同一个 esp 地址。对我来说奇怪的事实是,它甚至可以编译,并且可以工作。但是当我尝试通过输出值来测试它时
uint32_t output;
__asm
{
push ebp
mov ebp, esp
add esp, 4
mov [ebp - 4], 2
mov output,[ebp-4]
mov esp, ebp
pop ebp
}
std::cout << output;
它没有编译,显示“操作数大小冲突”,这对我来说似乎很奇怪,因为我使用 32 位整数并且寄存器也是 32 位的。当使用不带 [] 的 [ebp-4] 时,它会按预期给出垃圾值。 所以,也许有人可以解释这是如何工作的而不给出错误:) 还有一个问题,为什么 db 不能在内联汇编中工作?
【问题讨论】:
-
代码错误:
add esp, 4应该是sub esp, 4。至于另一个问题,你不能做mov output,[ebp-4],因为两者都是内存操作数,mov只接受一个。你可以做mov eax, [ebp-4]; mov [output], eax或类似的。另请注意,由于您移动了esp和ebp,如果您引用output,编译器可能会生成错误代码。简而言之,不要尝试这样做。 -
好的,谢谢 :) 但是数据库呢?为什么它不起作用?
-
你是在一个更大的 c++ 函数中写这个还是你试图用内联汇编创建一个完整的函数?
-
相关:Defining a variable inside c++ inline assembly - 不可能在内联 asm 中声明 C++ 变量,但您可以在堆栈上保留匿名空间以在您的 asm 中使用。