分享
 
 
 

Visual C++ Inline Assembly 简介

王朝vc·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

如果你想编写出极高性能的游戏代码,那么使用汇编语言无疑将会是你的最佳选择。不过,眼看着编程技术已经发展到了今天这种格局,你再去直接用汇编语言来进行编程也未免太不合时宜了吧。作为一个高性能游戏程序的编写者,你应该用的是 Inline Assembly。

什么是 Inline Assembly

Inline Assembly 就是我们通常所说的在线汇编,即直接在你的 C/C++ 代码里加入汇编语言代码。

在线汇编的好处

那些习惯了在线汇编的人都觉得它用起来很方便。

同传统的汇编方式相比,我们可以完全避免那些烦琐的汇编和链接步骤,可以直接在汇编代码中使用 C 变量名和函数名。这样一来,我们的汇编代码就能够很容易地同我们的 C 语言程序紧密而自然地结合在一起了。另外,由于是把汇编语句和 C 或者 C++ 语句混合在一起进行编程,我们还将能实现许多原来光凭 C 或者 C++ 语句无法办到的事。

在线汇编的用处

通常,在线汇编被用来写某些特殊函数,例如优化代码中对速度有极高要求的部分,直接访问硬件和设备驱动程序和为一段调用代码编写进入和退出时用到的保护性代码等等。

在线汇编的限制

一方面,在线汇编是一种专用工具,它不支持宏汇编中的宏和其它一些功能。另一方面,当你想往不同的平台移植程序代码时,这些机器相关的代码会比较难于处理。

如何在 Visual C++ 环境中使用在线汇编

在 Visual C++ 环境下,使用在线汇编是一件非常容易的事情:你只要用一条“_asm { }”把你的汇编代码括起来就行了。

下面给大家看一个简单例子,这个例子是要实现一个叫 Mycode() 的 C 函数。这个函数的功能很简单,它把两个输入参数的值相加,结果存放到另外一个全局变量中。

long result;

void Mycode(long a, long *b)

{

_asm

{

MOV EAX, a // eax = a

MOV EBX, b // ebx = b

ADD EAX, [EBX] // eax = eax + [ebx] = eax + (*b)

MOV result, EAX // result = eax

}

}

这个例子虽然简单,但它在解释“_asm { }”的用法的同时,顺便演示了对一般变量和指针变量的不同处理方法。

Visual C++ Inline Assembly 的处理细节

根据微软的不完全资料和自己的长期实践,我总结出以下几条处理细节,供大家参考,也期待着大家来补充和修正。

在 32 位应用程序中,因为是处于保护模式,所有寻址的偏移地址都是 32 位的,此时应该尽量避免修改和使用段寄存器。

全局变量被翻译成立即地址。

函数内的局部变量被翻译成堆栈偏移地址,形如 [EBP + ????] 的形式,其中 EBP 在函数进入时被设定为 ESP 的值。故使用局部变量的函数中,注意不要破坏 EBP 的内容。

Visual C++ 编译器不会对位于“_asm { }”中的代码作任何优化和改动。

Visual C++ 编译器在优化时,会自动废弃穿越“_asm { }”代码段的寄存器,因此不需要在“_asm { }”代码段中添加寄存器保护和恢复代码。 补充说明

匆忙之中,就想到了这么几条,如果你有什么意见、问题和建议,请务必提出来,那样的话,大家可以一起作进一步的讨论,使本文得以完善和升级,从而让更多看到本文的人受益。

另外,如果你以前有一点汇编语言的基础,但没学过 INTEL X86 体系的 32 位汇编语言,请阅读我的另一篇文字:『INTEL X86 体系的 32 位汇编语言速成』。

VC 里如果你定义了结构, 比如:typedef struct {

int x;

int y;

} MYSTRUCT;

那么在 inline asm 里就多了两个常量:MYSTRUCT.x 是 0

MYSTURCT.y 是 4

它们表示了 x,y 在结构中的偏移量。所以你就可以用:MYSTURCT *a;

mov ebx,a;

mov eax,[ebx]MYSTRUCT.x;

(eax 里就是 a->x)

上面一行也可以写成 mov eax,[ebx+MYSTRUCT.x];

另外,VC 中你也可以创建一个函数不帮你做栈处理的,需要你自己来取输入参数、保护寄存器、甚至自己写 ret 等等。这可以看做一个“纯粹”的 asm 函数了。方法是在函数定义前加入: __declspec(naked)

就可以了。

VC inline asm 里可以用 ALIGN n 来对齐代码。如果需要填入数据,VC 将填入一些不改变任何寄存器和标志位的指令(不一定是 nop),不过小心 VC 在这方面有 bug,我的主页(cloudwu.yeah.net)上曾详细讲解。

另外,在 VC 的 inline asm 里不象我们在 BC 的 inline asm 里那样简洁的用 db 来插入一些非代码的数据,它要用 _emit n 插入一个字节。这有时很有用,比如 Pentium 的 cpuid 指令 VC 就不支持,我们可以用: #define cpuid __asm _emit 0x0F __asm _emit 0xA2

来代替就可以了。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有