这是我的代码:
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
}
}
直接使用有什么问题?有可能吗?
答案 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;
}