在 visual c++ 中使用内联汇编
【程序编程相关:.NET框架类命名空间】 【推荐阅读:用VC++6.0 Sockets API】一. 优点 【扩展信息:关于数据库名(db_name)、实例名(】
使用内联汇编可以在 c/c++ 代码中嵌入汇编语言指令,而且不需要额外的汇编与连接步骤.在 visual c++ 中,内联汇编是内置的编译器,因此不需要配置诸如 masm 一类的独立汇编工具.这里,我们就以 visual studio .net 2003 为背景,介绍在 visual c++ 中使用内联汇的相关知识(如果是早期的版本,可能会有些许出入).
内联汇编代码可以使用 c/c++ 变量与函数,因此它能非常容易地整合到 c/c++ 代码中.它能做一些对于单独使用 c/c++ 来说非常笨重或不可能完成的任务.
内联汇编的用途包括:
l 使用汇编语言编写特定的函数;
l 编写对速度要求非常较高的代码;
l 在设备驱动程序中直接访问硬件;
l 编写 naked 函数的初始化与结束代码.
二. 关键字
使用内联汇编要用到 __asm 关键字,它可以出现在任何允许 c/c++ 语句出现的地方.我们来看一些例子:
l 简单的 __asm 块:
__asm
{
mov al, 2
mov dx, 0xd007
out al, dx
}
l 在每条汇编指令之前加 __asm 关键字:
__asm mov al, 2
__asm mov dx, 0xd007
__asm out al, dx
l 因为 __asm 关键字是语句分隔符,所以可以把多条汇编指令放在同一行:
__asm mov al, 2 __asm mov dx, 0xd007 __asm out al, dx
显然,第一种方法与 c/c++ 的风格很一致,并且把汇编代码与 c/c++ 代码清楚地分开,还避免了重复输入 __asm 关键字,因此推荐使用第一种方法.
不像在 c/c++ 中的“{}”,__asm 块的“{}”不会影响 c/c++ 变量的作用范围.同时,__asm 块可以嵌套,而且嵌套也不会影响变量的作用范围.
为了与低版本的 visual c++ 兼容,_asm 与 __asm 具有相同的意义.另外,visual c++ 支持标准 c++ 的 asm 关键字,但是它不会生成任何指令,它的作用仅限于使编译器不会出现编译错误.要使用内联汇编,必须使用 __asm 而不是 asm 关键字.
三. 汇编语言
1. 指令集
内联汇编支持 intel pentium 4 与 amd athlon 的所有指令.更多其它处理器的指令可以通过 _emit 伪指令来创建(_emit 伪指令说明见下文).
2. masm 表达式
在内联汇编代码中,可以使用所有的 masm 表达式(masm 表达式是指用来计算一个数值或一个地址的操作符与操作数的组合).
3. 数据指示符与操作符
虽然 __asm 块中允许使用 c/c++ 的数据类型与对象,但它不能使用 masm 指示符与操作符来定义数据对象.这里特别指出,__asm 块中不允许 masm 中的定义指示符(db.dw.dd.dq.dt 与 df),也不允许使用 dup 与 this 操作符.masm 中的结构与记录也不再有效,内联汇编不接受 struc.record.width 或者 mask.
4. even 与 align 指示符
尽管内联汇编不支持大多数 masm 指示符,但它支持 even 与 align.当需要的时候,这些指示符在汇编代码里面加入 nop 指令(空操作)使标号对齐到特定边界.这样可以使某些处理器取指令时具有更高的效率.
5. masm 宏指示符
内联汇编不是宏汇编,不能使用 masm 宏指示符(macro.rept.irc.irp 与 endm)与宏操作符(<>.!.&.% 与 .type).
6. 段
必须使用寄存器而不是名称来指明段(段名称“_text”是无效的).并且,段跨越必须显式地说明,如 es:[ebx].
7. 类型与变量大小
在内联汇编中,可以用 length.size 与 type 来获取 c/c++ 变量与类型的大小.
... 下一页