C++中嵌入汇编时如何调用类成员变量?

Mal 2002-08-20 02:23:47
有以下一例程:
//==============================
class AClass
{
public:
int anInt;
void edit();
};

void AClass::edit()
{
__asm {
MOV AX, WORD PTR anInt
}
}

void main()
{
AClass anObj;
}

//=======================================
有编译错误:
TC++3 : Expression Syntax
VC++6 : error C2420: 'anInt' : illegal symbol in second operand

我试图以rhis指针指向anInt,即:
MOV AX, WORD PTR anInt 改为 MOV AX, WORD PTR this->anInt
则相信由于->为C++操作符造成错误,有编译错误:
TC++3 : Expression Syntax
VC++6 : error C2400: inline assembler syntax error in 'third operand'; found 'bad token'
error C2400: inline assembler syntax error in 'opcode'; found 'bad token'

寻旧帖,有一例“VC的嵌入汇编中如何调用外部的函数,如类的成员函数updatedata()之类”(由goby()于2002-2-7 11:29:28发表于VC板)。其中有一方法为使用局部变量令标号合法(gboy(hello) 2002-2-7 12:26:07):
//=================================
MYFUN pFun=CWnd::UpdateData;
_asm
{
push 1
mov ecx,dword ptr [ebp-4]
call pFun
}
//==================================
故以此为据试之:
//==================================
void AClass::edit()
{
int b = this->anInt;
__asm {
MOV AX, WORD PTR b
INC AX
MOV WORD PTR b, AX
}
this->anInt = b;
}
//===================================
可行,但效率不佳。欲改换以指针或引用以提高效率。
试以缺省参数传递:
//===================================
void AClass::edit(int& b=anInt)
//===================================
则引发error C2648: 'anInt' : use of member as default parameter requires static member错误

换以另一函数对其进行封装:
//===================================
void edit(){editF(&this->anInt)};
void editF(int* b)
{
__asm {
MOV AX, WORD PTR b
INC AX
MOV WORD PTR b, AX
}
}
//====================================
则编译通过,但结果不正确,因为当前操作的是指针b而非b所指向的anInt,忘记了汇编的寻址语法,无计可施……


求正确的寻址语法,或更简单的调用成员变量的方法,薄酬。
...全文
506 24 打赏 收藏 转发到动态 举报
写回复
用AI写文章
24 条回复
切换为时间正序
请发表友善的回复…
发表回复
Mal 2002-09-01
  • 打赏
  • 举报
回复
在下参考各位的意见,在TC++3平台下这样写:

void AClass::edit()
{
int far *b = &this->anInt;

asm {
PUSH DS
LDS BX, b
INC WORD PTR [BX]
POP DS
}
}

则DS:BX能直接指向需要操作的成员变量,可对其直接操作。

而在VC6中,则:
void AClass::edit()
{
int *b = &this->anInt;

__asm {
MOV EBX, b
INC [EBX]
}
}

即可。

至于对不同数据类型的支持,则又另作讨论了。

谢谢各位的帮助。
alexxing 2002-08-28
  • 打赏
  • 举报
回复
或者,直接用指针得了

class AClass
{
public:
int anInt;
void edit();
};

void AClass::edit()
{
int * p = &anInt;
__asm {
mov eax, p //取得地址
mov eax, dword ptr [eax] //取得内容
}
}
alexxing 2002-08-28
  • 打赏
  • 举报
回复
C++ 的引用其实是一个指针(指向被引用变量的指针),所以在汇编中应该把它当作地址

class AClass
{
public:
int anInt;
void edit();
};

void AClass::edit()
{
int& intMask = anInt; //编译器生成的代码其实是把计算出的anInt的地址赋给了 intMask
__asm {
mov eax, intMask //取得地址
mov eax, dword ptr [eax] //取得内容
}
}

xghost 2002-08-28
  • 打赏
  • 举报
回复
还是用C + 汇编吧,
在C++ 的类中很难使用汇编的
程序猿1234567 2002-08-28
  • 打赏
  • 举报
回复
还可以这样:
void edit()
{
__asm {
PUSH ebx
MOV ebx, this.anInt
INC word ptr [ebx]
POP ebx
}
}
Mal 2002-08-28
  • 打赏
  • 举报
回复
请容许我逐一验证再作判断……
程序猿1234567 2002-08-22
  • 打赏
  • 举报
回复
Mal(懒懒的坏狐狸):
在vc下跟踪了一下,intMask和this->anInt的地址是一样的啊。
Tommy 2002-08-22
  • 打赏
  • 举报
回复
没必要用临时变量,也不必加上一层调用了,直接就可以进行操作了。如果确认修改ebx的值对程序没有影响的话,push/pop都可以省去了。
Tommy 2002-08-22
  • 打赏
  • 举报
回复
上面写错了。汇编中可以直接得到this指针,也可以直接访问结构中的内容的:

void edit()
{
__asm {
PUSH ebx
MOV ebx, this
INC word ptr [ebx]this.anInt
POP ebx
}
}
程序猿1234567 2002-08-22
  • 打赏
  • 举报
回复
哦,
原来是引用来着……
程序猿1234567 2002-08-22
  • 打赏
  • 举报
回复
研究了半天反汇编代码,发觉VC中好像是:
变量名是一个压栈的偏移地址,这个地址所指的地方保存变量内容的地址,通过该地址才能访问变量的内容。

为什么会这样呢?
程序猿1234567 2002-08-22
  • 打赏
  • 举报
回复
知道哪儿错了!!

取变量intMask的值应该这么写:
mov edx, dword ptr [intMask]
mov ax, word ptr [edx]
Mal 2002-08-22
  • 打赏
  • 举报
回复
sclzmbie(梦里红尘) 的方法好有启发性!详细尝试与研究中……
Tommy 2002-08-22
  • 打赏
  • 举报
回复
我不建议在汇编中用this指针加上成员变量的偏移来访问,这样就必须了解this指针在什么地方,变量的偏移也必须写死,万一以后对类进行了修改,比如加一个成员变量的话,所有用到的地方都要改,不好。

还是用指针、引用间接寻址比较好,不用关心类的内存布局,对类作的修改不影响访问变量的代码
Tommy 2002-08-22
  • 打赏
  • 举报
回复
汇编的间接寻址应该是用[]吧?

//===================================
void edit(){editF(&this->anInt)};
void editF(int* b)
{
__asm {
MOV AX, WORD PTR b ; MOV AX, WORD PTR [b]如何?
INC AX
MOV WORD PTR b, AX
}
}

程序猿1234567 2002-08-22
  • 打赏
  • 举报
回复
可是结果确实是错误的……
Mal 2002-08-21
  • 打赏
  • 举报
回复
virginsoldier(北欧野马——哈根) 的方法,
编译错误:error C2094: label '_anInt' was undefined

yanyongyuan(程序猿,低智商灵长类动物) 的方法,
编译通过,然而跟我之前的尝试传递指针/引用的方法同出一辙,AX指向的是间接变量的值,而非原变量

zhc(zhc) 的方法正尝试中……
sclzmbie 2002-08-21
  • 打赏
  • 举报
回复
另,汇编的 call 调用不能写什么CDialog::DoModal ,需要写后面括号中的地址,如

call 41A858h

呵呵,希望你是用微软的编译器。其它编译器的编译模型有少许差别,不能照搬。
sclzmbie 2002-08-21
  • 打赏
  • 举报
回复
这种情况我也遇过,解决办法是先写C++的代码,然后在VC中按CTRL+F11打开汇编模式看,再照抄下来。因为编译时成员变量的偏远量是固定的,所以可以直接指定值,如下面的18h等等。关于VC编译模型,可以参看MSDN中的《C++:UNDER THE HOOD》一文。

例子如下:

dlg.m_sDllPath=info.m_strFileName;
004014F7 lea edx,[esp+18h]
004014FB push edx
004014FC lea ecx,[esp+0F0h]
00401503 call ATL::CSimpleStringT<wchar_t>::operator= (401410h)

INT_PTR nResponse = dlg.DoModal();
00401508 lea ecx,[esp+28h]
0040150C call CDialog::DoModal (41A858h)

讨论请致EMAIL sclzmbie@sina.com
Mal 2002-08-21
  • 打赏
  • 举报
回复
zhc(zhc) 的方法在下无法实现,望给出实例。
加载更多回复(4)

70,037

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧