C语言中嵌入汇编,究竟有何意义?
我实在想不透,这种行为的意义,难道仅仅是为了快吗?
另外,汇编语言依赖于特定的机器,在C语言中嵌入的汇编语言,会不会出现移植性的问题?
分享到:
------解决方案--------------------
比如可以直接可以操作寄存器的值
会出现移植性的问题
------解决方案--------------------
这样加快操作速度。。看你移植的对象了!!
------解决方案--------------------
在C语言中嵌入的汇编语言,会不会出现移植性的问题?肯定会呀。
使用嵌入汇编,主要两个目的:一是为了控制方便(比如生成位置无关的代码、使用特权指令、使用特定架构的指令实现算法等等),其次才是提高性能。
------解决方案--------------------
引用:引用:
比如可以直接可以操作寄存器的值
会出现移植性的问题
请教agoago_2009
通常的c代码。在翻译成汇编的时候,是不是基本上都用到了那些寄存器?——比如int a=b+c这种——如果我们在嵌入的汇编代码中直接操作寄存器的值,会不会篡改了原本程序中保存在寄存器中的数据?我的意思是,就像非法访问内存那种情况差不多……当然内存和寄存器是无关的……
这个你有个理解误区,你的c语言其实也可以翻译成了汇编语言,
C和汇编都是面向过程的语言,
比如你上面的代码是用C写的,它已经执行完了,然后你后面的代码是汇编语言,它继续执行,
部存在篡改问题。
------解决方案--------------------
引用:引用:
在C语言中嵌入的汇编语言,会不会出现移植性的问题?肯定会呀。
使用嵌入汇编,主要两个目的:一是为了控制方便(比如生成位置无关的代码、使用特权指令、使用特定架构的指令实现算法等等),其次才是提高性能。
唔……控制方便……
可我感觉汇编代码太繁冗
高级语言一行能表达的东西,汇编需要好多行好多行……
还是有好多特殊用途,这个就一言难尽了。
------解决方案--------------------
有些东西只有用汇编才可以,比如溢出标志,另外在对效率很在乎的地方(如内核等),也会用到很多用来提高效率
------解决方案--------------------
引用:引用:
比如可以直接可以操作寄存器的值
会出现移植性的问题
请教agoago_2009
通常的c代码。在翻译成汇编的时候,是不是基本上都用到了那些寄存器?——比如int a=b+c这种——如果我们在嵌入的汇编代码中直接操作寄存器的值,会不会篡改了原本程序中保存在寄存器中的数据?我的意思是,就像非法访问内存那种情况差不多……当然内存和寄存器是无关的……
通常的C表达式是无法直接取到寄存器的数值的(使用寄存器变量和伪变量除外)。对于不使用寄存器变量和伪变量的表达式而言,寄存器中保存的仅是计算的中间结果而已。由于内嵌汇编不可能出现在表达式计算过程中,所以在内嵌汇编中修改寄存的值不会影响到表达式的计算。
当然也存在特殊的寄存器,例如80X86中的EIP,它保存的是下一条指令的相对地址(也就是PC),因此除了特殊应用外不要改变EIP的值。
------解决方案--------------------
如果函数工具一类的钢筋混凝土不够你来建造一座坚实的大楼 你可以用汇编纳米原子来填充
------解决方案--------------------
CSDN之前(http://topic.csdn.net/u/20100413/20/87aa7378-cd9f-44ad-90ae-4201a3680b71.html)已经有讨论过嵌入汇编的问题,可以好好参考一下。
基本上吵嚷者汇编效率高出C许多的都是没用过汇编的(典型语录——要效率你用汇编啊)……原因很简单,一般水平的家伙写汇编就别说逻辑上跑赢C/C++的代码优化了,就在指令集这块——教材上的386级别的指令也完全比不上最新的intel指令集,现在有些牛逼的SSE指令抵得上一个小型的C函数了。
VS2008可以直接认得SSE4指令集.
类似的,VS2005支持到SSE3.
我觉得,要内嵌汇编,不用SSE3~SSE4就没有价值,而能跑赢C/C++编译器优化的专业汇编选手也太少了,因此我见到喜欢内嵌汇编的,总感觉在装B……
又见到一篇欠扁的文章,该“大牛”竟然在32位C语言程序里内嵌8086汇编以“加强效率”——mov ax,bx
------解决方案--------------------
引用:引用:
在C语言中嵌入的汇编语言,会不会出现移植性的问题?肯定会呀。
使用嵌入汇编,主要两个目的:一是为了控制方便(比如生成位置无关的代码、使用特权指令、使用特定架构的指令实现算法等等),其次才是提高性能。
唔……控制方便……
可我感觉汇编代码太繁冗
高级语言一行能表达的东西,汇编需要好多行好多行……
两点:
1.方便。有些东西用汇编写会更加方便,代码反而更少
2.功能。有些功能靠C不能实现或者实现比较困难。例如你要写感染病毒等
------解决方案--------------------
有些地方需要控制寄存器。
------解决方案--------------------
看看汇编的作用吧:
//=====================================================================================
/* CPUID指令是intel IA32架构下获得CPU信息的汇编指令,
可以得到CPU类型,型号,制造商信息,商标信息,序列号,
缓存等一系列CPU相关的东西。
*/
#include
#include
#include
using namespace std;
//用来存储eax,ebx,ecx,edx四个寄存器的信息
DWORD deax;
DWORD debx;
DWORD decx;
DWORD dedx;
void ExeCPUID(DWORD veax) //初始化CPU
{
__asm
{
mov eax,veax
cpuid
mov deax,eax
mov debx,ebx
mov decx,ecx
mov dedx,edx
}
}
/*在Intel Pentium以上级别的CPU中,有一个称为“时间戳(Time Stamp)”的部件,
它以64位无符号整型数的格式,记录了自CPU上电以来所经过的时钟周期数。
由于目前的CPU主频都非常高,因此这个部件可以达到纳秒级的计时精度。
这个精确性是上述两种方法所无法比拟的。
在Pentium以上的CPU中,提供了一条机器指令RDTSC(Read Time Stamp Counter)
来读取这个时间戳的数字,并将其保存在EDX:EAX寄存器对中
*/
long GetCPUFreq() //获取CPU频率,单位: MHZ
{
int start,over;
_asm
{
RDTSC
mov start,eax
}
Sleep(50);
_asm
{
RDTSC
mov over,eax
}
return (over-start)/50000;
}
/* 把eax = 0作为输入参数,可以得到CPU的制造商信息。
cpuid指令执行以后,会返回一个12字符的制造商信息,
前四个字符的ASC码按低位到高位放在ebx,中间四个放在edx,最后四个字符放在ecx。
*/
string GetManID() //获取制造商信息
{
char ID[25];
memset(ID,0,sizeof(ID));
ExeCPUID(0); //初始化
memcpy(ID+0,&debx,4); //制造商信息复制到数组
memcpy(ID+4,&dedx,4);
memcpy(ID+8,&decx,4);