【问题标题】:Defining variables in c++ inline assembly在 C++ 内联汇编中定义变量
【发布时间】: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 或类似的。另请注意,由于您移动了espebp,如果您引用output,编译器可能会生成错误代码。简而言之,不要尝试这样做。
  • 好的,谢谢 :) 但是数据库呢?为什么它不起作用?
  • 你是在一个更大的 c++ 函数中写这个还是你试图用内联汇编创建一个完整的函数?
  • 相关:Defining a variable inside c++ inline assembly - 不可能在内联 asm 中声明 C++ 变量,但您可以在堆栈上保留匿名空间以在您的 asm 中使用。

标签: c++ assembly x86


【解决方案1】:

它不起作用,它没有定义 C++ 变量。

它只是弄乱了堆栈,以便在编译器创建的堆栈帧下方保留一些新的存储空间。 您修改了 EBP,因此编译器生成的使用 EBP 的寻址模式将被破坏。1

如果您想定义声明一个 C++ 变量,请使用 C++ 语法,如 int tmp

asm 并没有真正的变量。它有寄存器和内存。跟踪值在何处使用 cmets。如果你想从 MSVC 内联汇编中使用一些额外的堆栈空间,我认为这是安全的,但如果你还想引用 C++ 局部变量,请不要修改 EBP。


脚注 1:

如果您的代码完全组装,情况就会如此,因为mov output,[ebp-4] 有2 个显式内存操作数。 MSVC 内联汇编无法在寄存器中分配 C++ 变量。

mov [ebp - 4], 2 也有不明确的操作数大小:两个操作数都没有与之关联的大小,因为它们都不是寄存器。也许你想要mov dword ptr [ebp - 4], 2

【讨论】:

  • 如果搞乱 ESP 是个坏主意,那么尝试 [eax+4] 之类的东西可能会更好吗?然后堆栈不会被破坏并且变量将在内存中。或者它不会工作? :D(虽然我是组装新手...)
  • @Raicha:你必须将 EAX 指向某个东西,如果那是 ESP 下方的空间,那么它是不安全的。无论如何,修改 ESP(堆栈指针)安全的,只要你事后恢复它。就像你在回答中所做的那样,推送和相同数量的弹出。修改 EBP(MSVC 将其用作帧指针)通常是安全的。查看使用内联 asm 的函数的编译器生成代码(反汇编或 godbolt.org),了解它如何使用 EBP。
猜你喜欢
  • 2010-11-26
  • 1970-01-01
  • 2014-10-07
  • 1970-01-01
  • 2018-09-15
  • 2019-12-31
  • 2017-01-30
  • 2013-07-23
  • 1970-01-01
相关资源
最近更新 更多