c++内嵌汇编代码编译不过,求答案

时刻准备中 2009-10-17 11:22:18
bool has_eflag(const DWORD mask)
{
DWORD f0, f1;
asm("pushfl ; "
"pushfl ; "
"popl %0 ; "
"movl %0,%1 ; "
"xorl %2,%1 ; "
"pushl %1 ; "
"popfl ; "
"pushfl ; "
"popl %1 ; "
"popfl"
: "=&r" (f0), "=&r" (f1)
: "ri" (mask));
return ((f0^f1) & mask);
}

bool is_support = has_eflag((DWORD)0x00040000);

哪位大侠能解释一下上面C++语言(gcc环境)中嵌入的汇编语言的意思:has_eflag是函数,下面是调用。在vs2005中这段代码编译不过去,好像这段汇编只是gcc编译器特有的格式?
谢谢!
...全文
279 23 打赏 收藏 转发到动态 举报
写回复
用AI写文章
23 条回复
切换为时间正序
请发表友善的回复…
发表回复
时刻准备中 2009-10-17
  • 打赏
  • 举报
回复
编译没问题,只是运行时错误:
Unhandled exception at 0x7c90e55f in placement_new_test.exe: 0xC00000FD: Stack overflow.
时刻准备中 2009-10-17
  • 打赏
  • 举报
回复
多谢11楼,我试一下先
时刻准备中 2009-10-17
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 arong1234 的回复:]
这种代码用在项目中是危险的,还是应该找替换算法了
引用 10 楼 tsinghua605 的回复:
呵呵,用这段代码的同事也是很早之前在网上找到的代码,他也不清楚什么意思,直接拿来用了,是关于license控制的,取cpu相关信息之类的代码。现在也不知道他到底是在哪儿找到的了。。。

[/Quote]

呵呵,同意。但是还是想弄明白,如果有碰到过这样代码的,就更好了。
arong1234 2009-10-17
  • 打赏
  • 举报
回复
这种代码用在项目中是危险的,还是应该找替换算法了
[Quote=引用 10 楼 tsinghua605 的回复:]
呵呵,用这段代码的同事也是很早之前在网上找到的代码,他也不清楚什么意思,直接拿来用了,是关于license控制的,取cpu相关信息之类的代码。现在也不知道他到底是在哪儿找到的了。。。
[/Quote]
时刻准备中 2009-10-17
  • 打赏
  • 举报
回复
函数最后两句:
: "=&r" (f0), "=&r" (f1)
: "ri" (mask)
是干嘛的?赋值吗?
zming 2009-10-17
  • 打赏
  • 举报
回复


#define DWORD unsigned int

bool has_eflag(const DWORD mask)
{
DWORD f0, f1;
_asm
{
pushf; // GCC: pushfl 标志寄存器值进栈,对应 VC++: pushf
pushf;
pop f0 ; // GCC: popl %0 占位符,按下面 : 后的顺序指定,即 f0

//movl f0, f1; // GCC 使用 AT&T 汇编语法,源在左
// VC++使用 Intel 汇编语法,源在右
mov eax, f0; // VC++内嵌汇编中,mov指令的参数不内全为内存变量
mov f1, eax;

//xorl %2,%1
mov eax, f1;
xor eax, mask;
mov f1, eax;

push f1;
popf; // GCC: popfl 标志寄存器值出栈,对应 VC++: popf
pushf;
pop f1;
popf;
}

return ((f0^f1) & mask);
}


void main(int argc, char** argv)
{
bool is_support = has_eflag((DWORD)0x00040000);
}


VC++下面编译通过,至于你的 push/pop 是否正确,需要你自己去检查。
时刻准备中 2009-10-17
  • 打赏
  • 举报
回复
呵呵,用这段代码的同事也是很早之前在网上找到的代码,他也不清楚什么意思,直接拿来用了,是关于license控制的,取cpu相关信息之类的代码。现在也不知道他到底是在哪儿找到的了。。。
arong1234 2009-10-17
  • 打赏
  • 举报
回复
问一下写这个的人么,mLee79的代码是个很好的尝试,但是老实说是不是能work就要看这个代码是不是和平台有关了
[Quote=引用 6 楼 tsinghua605 的回复:]
是在.h文件中的代码,我只贴了这段提示编译不过去的函数代码,费解啊!!那这样吧,不管格式的问题了,求解一下这段代码的意思,或者换成标准的语法。目前知道的这个函数的功能是和cpu相关的,别的实在是不清楚了,对汇编很抓瞎啊。。。。
[/Quote]
mLee79 2009-10-17
  • 打赏
  • 举报
回复
大概就这样,没检查过,不知道干嘛的。。
pushfd
pushfd
pop f0
mov f1 , f0
xor f1 , mask
push f1
popfd
pushfd
pop f1
popfd
mLee79 2009-10-17
  • 打赏
  • 举报
回复
标准C就没定义汇编的语法,显然的是AT&T的汇编语法。。。

时刻准备中 2009-10-17
  • 打赏
  • 举报
回复
是在.h文件中的代码,我只贴了这段提示编译不过去的函数代码,费解啊!!那这样吧,不管格式的问题了,求解一下这段代码的意思,或者换成标准的语法。目前知道的这个函数的功能是和cpu相关的,别的实在是不清楚了,对汇编很抓瞎啊。。。。
arong1234 2009-10-17
  • 打赏
  • 举报
回复
很显然那不是标准的C语法,从来没听说asm里的东西需要引号的。很怀疑那不是被编译直接编译的,而是需要预处理后编译的,这在make中很容易做到,用一个shell cmd把引号中的东西换成合法的asm
[Quote=引用 4 楼 tsinghua605 的回复:]
是啊,我也很奇怪的,但是这是同事在gcc环境下用的代码,也是从网上找的代码,现在移植到win32下,用vs2005编译不过去,asm换成__asm{}也是不行。
[/Quote]
时刻准备中 2009-10-17
  • 打赏
  • 举报
回复
是啊,我也很奇怪的,但是这是同事在gcc环境下用的代码,也是从网上找的代码,现在移植到win32下,用vs2005编译不过去,asm换成__asm{}也是不行。
arong1234 2009-10-17
  • 打赏
  • 举报
回复
而且你的语法也很奇怪,在里面用的诸如%1之类的东西我只在shell编程中见过,从来没有在汇编中见过。asm中包含的必须是合法的汇编指令
clhposs 2009-10-17
  • 打赏
  • 举报
回复
__asm
{}
arong1234 2009-10-17
  • 打赏
  • 举报
回复
汇编是直接编译的,不需要你用引号把他们括起来
时刻准备中 2009-10-17
  • 打赏
  • 举报
回复
[Quote=引用 22 楼 arong1234 的回复:]
你只是找到报错的地方,没找到正式的导致错误的地方

问题在于,pushf只push 2个字节的内容进栈,而pop f0却pop出4字节,导致堆栈指针被错误的移位了

把DWORD改成unsigned short,然后把所有的eax全部换成ax就好了

[/Quote]
确实没错,不过这段代码的本来意思应该不是这样的,它还是要用4个字节的参数、4个字节的寄存器;在AT&T中pushl指令的后缀"l"代表的是long,而在win32下对应的语句应该是pushfd;同理,popfl对应popfd,这样就没错了,而且和之前的代码含义保持一致。
多谢arong1234,zming以及各位的帮助!
arong1234 2009-10-17
  • 打赏
  • 举报
回复
你只是找到报错的地方,没找到正式的导致错误的地方

问题在于,pushf只push 2个字节的内容进栈,而pop f0却pop出4字节,导致堆栈指针被错误的移位了

把DWORD改成unsigned short,然后把所有的eax全部换成ax就好了
时刻准备中 2009-10-17
  • 打赏
  • 举报
回复
我知道问题出在哪里了。在debug下,总是自动在return ((f0^f1) & mask);处中断,然后再运行就会出现上述运行时错误;而换到release下却没问题。
arong1234 2009-10-17
  • 打赏
  • 举报
回复
11F的代码看起来没问题,建议你什么自己代码都不要加,直接用他的代码测试
加载更多回复(3)

64,654

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

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