从Visual C ++中的内联汇编访问类成员

时间:2011-11-19 07:36:27

标签: c++ assembly inline-assembly

这是我的代码:

void Graph::PutPixel(DWORD x, DWORD y, DWORD c)
{
    __asm 
    {
        Mov Eax, y
        Mov Ebx, _width
        Mul Ebx
        Add Eax, x
        Shl Eax, 2 // Multiply by four
        Add Eax, _buffer
        Mov Edi, Eax
        Mov Eax, c
        StosD
    }
}

其中_buffer和_width是Graph类成员:

private:
    DWORD _width;
    DWORD* _buffer;

它不起作用;我从两个变量得到0值,但实际上它们还有一些其他值。

我可以通过将类变量复制到局部变量并使用它来修复它:

void Graph::PutPixel(DWORD x, DWORD y, DWORD c)
{
    DWORD bufAddr = (DWORD)_buffer;
    DWORD w = _width;
    __asm 
    {
        Mov Eax, y
        Mov Ebx, w
        Mul Ebx
        Add Eax, x
        Shl Eax, 2 // Multiply by four
        Add Eax, bufAddr
        Mov Edi, Eax
        Mov Eax, c
        StosD
    }
}

直接使用有什么问题?有可能吗?

3 个答案:

答案 0 :(得分:6)

如果你有一些确实需要汇编的东西(参见Bo的答案),那么有一篇关于在内联汇编块中访问C或C ++数据的文章here

在你的情况下,我们得到:

void Graph::PutPixel(DWORD x, DWORD y, DWORD c)
{
    __asm 
    {
        mov ecx,this
        mov Eax, y
        mov Ebx, [ecx]Graph._width //alias ecx to type 'Graph' and access member
        mul Ebx
        add Eax, x
        shl Eax, 2
        add Eax, [ecx]._buffer //access member with bound alias
        mov Edi, Eax
        mov Eax, c
        stosd
    }
}

答案 1 :(得分:4)

为什么首先使用装配?!

不是这个

void Graph::PutPixel(DWORD x, DWORD y, DWORD c)
{
    __asm 
    {
        Mov Eax, y
        Mov Ebx, _width
        Mul Ebx
        Add Eax, x
        Shl Eax, 2 // Multiply by four
        Add Eax, _buffer
        Mov Edi, Eax
        Mov Eax, c
        StosD
    }
}

相同
DWORD* ptr = ((y * _width) + x) + _buffer;
*ptr = c;

只需将c存储在计算的内存地址中。


或者,甚至更简单

_buffer[y * _width + x] = c;

现在我们正在谈论!

答案 2 :(得分:0)

如上所述,从其他答案中可以看出,使用Visual Studio以内联汇编的方式访问类或结构的成员可以做到这一点。 有关更多信息的来源,请访问Microsoft网站上的https://docs.microsoft.com/en-us/cpp/assembler/inline/accessing-c-or-cpp-data-in-asm-blocks?view=vs-2019

// InlineAssembler_Accessing_C_asm_Blocks.cpp
// processor: x86
#include <stdio.h>
struct first_type
{
   char *weasel;
   int same_name;
};

struct second_type
{
   int wonton;
   long same_name;
};

int main()
{
   struct first_type hal;
   struct second_type oat;

   __asm
   {
      lea ebx, hal
      mov ecx, [ebx]hal.same_name ; Must use 'hal'
      mov esi, [ebx].weasel       ; Can omit 'hal'
   }
   return 0;
}