开启辅助访问 切换到宽版

精易论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

用微信号发送消息登录论坛

新人指南 邀请好友注册 - 我关注人的新帖 教你赚取精币 - 每日签到


求职/招聘- 论坛接单- 开发者大厅

论坛版规 总版规 - 建议/投诉 - 应聘版主 - 精华帖总集 积分说明 - 禁言标准 - 有奖举报

查看: 1920|回复: 0
收起左侧

[图文教程] 内联会变基础知识(三)

[复制链接]
结帖率:50% (2/4)
发表于 2012-7-4 00:11:21 | 显示全部楼层 |阅读模式   湖南省长沙市
下面将举几个关于使用C\C++符号的例子。
如果先前C已经定义了一个变量var,那么则内联汇编可以访问这个变量如下:
__asm mov eax, var   ;将变量var中的值赋给eax寄存器中。
如果有一个结构体first_type和一个实例hal:
struct first_type
{
  char *weasel;
  int same_name;
} hal;
在访问hal对象时,则必须如下:
__asm
{
  mov ebx, OFFSET hal       ;取得hal对象的首地址
  mov ecx, [ebx]hal.same_name ;加上same_name偏移值,则可以访问到成员same_name
  mov esi, [ebx]hal.weasel  ;加上weasel偏移值。
}
下面是一个内联汇编如何实现一个函数的例子:
#include <stdio.h>
int power2( int num, int power );
void main( void )
{
  printf( "3 times 2 to the power of 5 is %d\n", \
      power2( 3, 5) );
}
int power2( int num, int power )
{
  __asm
  {
   mov eax, num  ; 取得第一个参数
   mov ecx, power ; 取得第二个参数
   shl eax, cl   ; EAX = EAX * CL
  }
  //在函数中,返回值是由eax负责往回传递的。(顺便问一句ax与eax有什么不同啊?是不是一样的?)
}
因为内联函数中没有return,所以在上面的例子中,编译器会报出警告。还好,不像Java一样,少一个多一个return都会编译不通过。你可以使用宏#pragma warning来关掉警告器。在pascall式函数中堆栈的复位是由函数负责的,而不是调用者。在上面的例子中,由是在C函数中内部嵌入汇编来完成汇编函数的。在C函数出口处,C编译器会自动添加复栈指令,而不必自己添写。那反而会使系统混乱. 在内联汇编中跳转指令(包括条件跳转),可以跳转到C语言goto能到的所有地方。Goto也可以跳到内联汇编中定义的标签,示例如下:
void func( void )
{
  goto C_Dest; /* Legal: correct case  */
  goto c_dest; /* Error: incorrect case在C中大小写区分。*/
  goto A_Dest; /* Legal: correct case  */
  goto a_dest; /* Legal: incorrect case */
  __asm
  {
   jmp C_Dest ; Legal: correct case
   jmp c_dest ; Legal: incorrect case
   jmp A_Dest ; Legal: correct case
   jmp a_dest ; Legal: incorrect case
   a_dest:  ; __asm label
  }
  C_Dest:    /* C label */
  return;
}
另外,在给标签起名时尽量避免与C内部的或已经使用了的标签名重名,如果那样的将会出现灾难性的程序错误。因此,在起名时最好追查一下是否这个名字已经被使用了。在引用函数时,应注意参数的从右向左方向地压栈。比如有一个函数是 int CAdd (int a,int b) 则应该如此调用:
__asm
{
    mov eax,2;
    push; 参数b等于2
    mov eax,3;
    push; 参数a等于3
    call CAdd;调用CAdd函数
    mov Result,eax;所有函数的返回值都被存放在eax。于是,Result等于5
}
注意内联汇编无法调用重载函数,因为被重载函数名与原函数名不一样。所以如果你需求调用的话, (我记得vckbase中有关于重载函数的文章),就不要定义重载函数,且C++函数必须使用extern "C"关键字来定义。因为C中的预处理指令#define是字符代换,所以你可以使用#define来定义一个汇编宏,例如:
#define PORTIO __asm      \
/* Port output */         \
{                         \
   __asm mov al, 2        \
   __asm mov dx, 0xD007   \
   __asm out al, dx       \
}
您需要登录后才可以回帖 登录 | 注册

本版积分规则 致发广告者

发布主题 收藏帖子 返回列表

sitemap| 易语言源码| 易语言教程| 易语言论坛| 易语言模块| 手机版| 广告投放| 精易论坛
拒绝任何人以任何形式在本论坛发表与中华人民共和国法律相抵触的言论,本站内容均为会员发表,并不代表精易立场!
论坛帖子内容仅用于技术交流学习和研究的目的,严禁用于非法目的,否则造成一切后果自负!如帖子内容侵害到你的权益,请联系我们!
防范网络诈骗,远离网络犯罪 违法和不良信息举报电话0663-3422125,QQ: 793400750,邮箱:wp@125.la
Powered by Discuz! X3.4 揭阳市揭东区精易科技有限公司 ( 粤ICP备12094385号-1) 粤公网安备 44522102000125 增值电信业务经营许可证 粤B2-20192173

快速回复 返回顶部 返回列表