Доступ к членам класса из встроенной сборки в Visual C ++ - PullRequest
6 голосов
/ 19 ноября 2011

Вот мой код:

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
    }
}

В чем проблема с прямым использованием? Возможно ли это?

Ответы [ 2 ]

6 голосов
/ 11 января 2012

Если у вас есть что-то, что действительно нуждается в сборке (см. Ответ Бо), здесь есть статья здесь о доступе к данным C или C ++ во встроенных блоках сборки.

В вашем случае мы получаем:

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
    }
}
4 голосов
/ 11 января 2012

Зачем вообще использовать сборку?!

Разве это не

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;

Теперь мы говорим!

...