在C++中使用内联汇编更改数字值

5

我想通过在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吗? - Cameron
5
你可能需要拆解编译后的代码,并检查它是否符合你的预期。由于间接引用太少或太多,我曾见过这种情况出错。你可能是在增加x而不是*x - Mats Petersson
@MatsPetersson,我该如何反汇编呢?我知道只有exe文件可以反汇编,如果我使用括号,您怎么知道我是在递增x而不是*x呢? - Imri Persiado
@Cameron 它不起作用 =\ - Imri Persiado
2
@ImriPersiado cl /Fa filename.cpp 将生成包含汇编语言列表的 filename.asm 文件。 - Nik Bougalis
显示剩余2条评论
3个回答

7
您实际上是在增加变量 x 的值。在汇编语言中,X 是一个常量,包含函数 foo 中变量 x 的地址。而这个变量又包含了 main 函数中的 x 变量地址。因此,inc [x] 导致指针增加。您需要增加存储在地址 [x] 中的值,例如 inc [[x]]。当然,在汇编语言中,您不能使用一条指令完成它,因为您需要进行两次内存访问:一次是为了知道值存储在哪里,另一次则是为了实际地增加该值。因此,我建议您使用以下代码:
push eax
mov eax, [x]
inc dword ptr [eax]
pop eax

谢谢!出于好奇,我尝试了一种基于您的话的不同方法:mov eax,x; mov ebx,[eax]; inc [ebx],但我失败了,值保持不变。 - Imri Persiado
1
这是MSVC对您的帮助。它会自动将mov eax,x翻译为变量值的移动。因此,从技术上讲,您可以用mov eax,x替换我的代码的第二行。实际上,对于MSVC来说,这个x只是堆栈帧中的索引。在纯汇编语言中,您需要写mov eax,[ebp + 8],因为x是第一个堆栈变量。如果您使用fastcall调用约定,您将写入inc [eax],就像那样。 - Aneri

0

也许了解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
};

5
什么?胡说八道。 INC 可以操作寄存器或内存操作数。 - Nik Bougalis
那个“有效”是因为它增加了一个额外的间接性。但是inc [eax]也可以工作。 - Mats Petersson
3
代码“奏效”与否无关紧要。我从未说过它不行;实际上,我认为他展示的代码可以达到他所声称的效果。我的意思是,“INC”不能用于内存操作数(也称为指针)纯属无稽之谈。http://www.negatory.com/ref/viewpage.php?key=inc - Nik Bougalis
嘿,这种事情发生在每个人身上。毕竟它不是徒有CISC架构 ;) - Nik Bougalis

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