【问题标题】:Changing a number value using an inline assembly in C++在 C++ 中使用内联程序集更改数值
【发布时间】:2013-02-26 00:35:11
【问题描述】:

我正在尝试通过在 C++ 中使用内联程序集来增加数值。我这样做的原因是为了练习我的“内联汇编”技能。

这就是我到目前为止所做的:

void main()
{
    int x;
    cout << "Please enter a number ";
    cin >> x;
    cout << "The number you entered is: " << x << "\n";
    foo(&x);
    cout << "The new number is: " << x;
    cin >> x;
}

void foo(int *x) 
{
    __asm
    {
        inc [x]
    };
}

而且价值从未改变。

【问题讨论】:

  • 你用的是什么编译器? MSVC?
  • Microsoft Visual Studio 2012
  • 您可能想反汇编编译后的代码,看看它是否符合您的预期。由于间接性太少或太多,我已经看到这种事情出错了。您可能会增加 x 而不是 *x
  • 在黑暗中拍摄,但inc DWORD PTR [x] 有效吗?
  • @ImriPersiado cl /Fa filename.cpp 将生成包含汇编语言列表的filename.asm

标签: c++ inline-assembly


【解决方案1】:

实际上,您正在增加x 的值。就汇编语言而言,X 是一个常量,包含x 变量(函数foo)的地址。其中又包含mainx 的地址。因此,inc [x] 导致指针递增。您需要增加存储在地址[x] 中的值,例如inc [[x]]。当然,你不能在汇编语言的一条指令中做到这一点,因为你需要 两次 内存访问:知道 哪里 存储值并实际 递增 em> 值。所以我建议这样的代码:

push eax
mov eax, [x]
inc dword ptr [eax]
pop eax

【讨论】:

  • 谢谢!出于好奇,我根据您的话尝试了另一种方法: mov eax,x;移动 ebx,[eax]; inc [ebx] 我失败了,值保持不变。
  • 这是 MSVC 对您的帮助。它会自动将mov eax, x 转换为变量值的移动。因此,从技术上讲,您可以将我的代码的第二行替换为 mov eax, x。事实上,这个 MSVC 的 x 只是堆栈帧中的一个索引。在纯汇编语言中,您必须编写mov eax, [ebp + 8],因为 x 是第一个堆栈变量。如果你使用fastcall 调用约定,你会写inc [eax],就像那样。
【解决方案2】:

也许了解 Visual C++ 如何递增 int 指针的值很有用:

void foo(*x)
{
  (*x)++;
}

在调试模式下,它被翻译成

(*x)++;
mov         eax,dword ptr [x] 
mov         ecx,dword ptr [eax] 
add         ecx,1 
mov         edx,dword ptr [x] 
mov         dword ptr [edx],ecx 

在发布模式下与 Aneri 的回答相同。

【讨论】:

    【解决方案3】:

    x86 只能增加一个寄存器,不能增加一个内存,所以你需要移动一个指向寄存器的指针。我以这个结尾:

    __asm
    {
        mov eax, x
        mov ebx, [eax]
        inc ebx
        mov [eax], ebx
    };
    

    【讨论】:

    • 嗯?废话。 INC 可以对寄存器或内存操作数进行操作。
    • 这“有效”,因为它增加了额外的间接性。但是inc [eax] 也可以。
    • 代码“有效”是无关紧要的。我从来没有说过没有;事实上,我同意他展示的代码将按照他的要求进行。我的意思是INC 不适用于内存操作数(又名指针),这是无稽之谈。 negatory.com/ref/viewpage.php?key=inc
    • 嘿。它发生在每个人身上。这不是一个免费的 CISC 架构 ;)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-01
    • 2012-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-08
    • 2011-07-02
    相关资源
    最近更新 更多