首页 reference article

reference article

举报
开通vip

reference article 您还未登录!| 登录 | 注册 | 帮助首页 业界 移动 云计算 研发 论坛 博客 下载 刺猬小屋 目录视图 摘要视图 订阅 公告:CSDN 搜索第二版正式上线! Hadoop与大数据精彩议题发布 2000元大奖征异构开发博文 CSDN博客频道搬家功能改版正式上线! 【免费】解读海外市场营销奥秘 CSDN博客频道推出TAG功能 GCC内嵌汇编 2008-04-08 09:45 4508人阅读 评论(1) 收藏 举报 GCC内嵌汇编 刺猬@http://blog.csdn.net/littleh...

reference article
您还未登录!| 登录 | 注册 | 帮助首页 业界 移动 云计算 研发 论坛 博客 下载 刺猬小屋 目录视图 摘要视图 订阅 公告:CSDN 搜索第二版正式上线! Hadoop与大数据精彩议题发布 2000元大奖征异构开发博文 CSDN博客频道搬家功能改版正式上线! 【免费】解读海外市场营销奥秘 CSDN博客频道推出TAG功能 GCC内嵌汇编 2008-04-08 09:45 4508人阅读 评论(1) 收藏 举报 GCC内嵌汇编 刺猬@http://blog.csdn.net/littlehedgehog AT&T手册里面的,我整理了下,方便阅读 内核代码绝大部分使用C 语言编写,只有一小部分使用汇编语言编写,例如与特定体系结构相关的代码和对性 能影响很大的代码。GCC提供了内嵌汇编的功能,可以在C代码中直接内嵌汇编语言语句,大大方便了程序设 计。 简单的内嵌汇编很容易理解 例如: “__asm__” 关于同志近三年现实表现材料材料类招标技术评分表图表与交易pdf视力表打印pdf用图表说话 pdf 示后面的代码为内嵌汇编,“asm”是“__asm__”的别名。 “__volatile__”表示编译器不要优化代码,后面的指令保留原样, “volatile”是它的别名。括号里面是汇编指令。 使用内嵌汇编,要先编写汇编指令模板,然后将C语言表达式与指令的操作数相关联,并告诉GCC对这些操作有哪 些限制条件。例如在下面的汇编语句:[下段解释一定要耐着性子看懂读懂!] “movl %1,%0”是指令模板;“%0”和“%1”代表指令的操作数,称为占位符,内嵌汇编靠它们将C语言表达式与 指令操作数相对应。指令模板后面用小括号括起来的是C语言表达式,本例中只有两个:“result”和“input”,他 们按照出现的顺序分别与指令操作数“%0”,“%1,”对应;注意对应顺序:第一个C表达式对应“%0”;第二 个表达式对应“%1”,依次类推,操作数至多有10个,分别用“%0”,“%1”….“%9,”表示。在每个操作数前 面有一个用引号括起来的字符串,字符串的内容是对该操作数的限制或者说要求。“result”前面的限制字符串是 “=r”,其中“=”表示“result”是输出操作数,“r”表示需要将“result”与某个通用寄存器相关联,先将操作数的 值读入寄存器,然后在指令中使用相应寄存器,而不是“result”本身,当然指令执行完后需要将寄存器中的值存入 变量“result”,从表面上看好像是指令直接对“result”进行操作,实际上GCC做了隐式处理,这样我们可以少写 一些指令。“input”前面的“r”表示该表达式需要先放入某个寄存器,然后在指令中使用该寄存器参加运算。 下面来看看一个内嵌汇编的小例子: 分类: Operating System __asm____volatile__("hlt"); __asm__ __violate__ ("movl %1,%0" : "=r" (result) : "m" (input)); littlehedgehog C++ (1) DataStructure (8) Linux Kernel 0.11 (12) Linux Kernel 2.4/2.6 (7) Masm&Nasm (9) Operating System (36) Unix/Linux Programming (31) WindowsSDK (7) 随笔 (22) 个人资料 访问: 234690次 积分: 3868分 排名: 第1059名 原创: 118篇 转载: 5篇 译文: 2篇 评论: 419条 文章搜索 文章分类 文章存档 2011年06月 (1) 2010年10月 (1) 2010年04月 (1) 2009年04月 (3) 2009年02月 (2) 阅读排行 我看UNIX与Windows的本 (27351) Linux内核高端内存管理 (7962) 多重继承和虚继承的内存布局 (7813) 我对读计算机软件专业硕 (6801) 虚拟机ubuntu与XP的文件共享 (6207) Linux 网卡设备驱动 (5809) Clamav杀毒软件源码分析 (5620) Clamav杀毒软件源码分析 (5557) 异步信号安全和线程安全 (5534) Clamav杀毒软件源码分析 (5491) 更多 页码,1/7GCC内嵌汇编 - 刺猬小屋 - 博客频道 - CSDN.NET 2012/11/24http://blog.csdn.net/littlehedgehog/article/details/2259665 对应的汇编代码如下; 行号 代码 解释 1 7 8 movl $1, input 对应C语言语句input = 1; 9 movl input, %eax 10 #APP GCC插入的注释,表示内嵌汇编开始 11 movl %eax,%eax 我们的内嵌汇编语句 12 #NO_APP GCC 插入的注释,表示内嵌汇编结束 13 movl %eax, result 将结果存入result变量 从汇编代码可以看出,第9行和第13行是GCC,自动增加的代码,GCC 根据限定字符串决定如何处理C表达式, 本例两个表达式都被指定为“r”型,所以先使用指令 movl input, %eax 将input读入寄存器%eax; GCC,也指定一个寄存器与输出变量result 相关,本例也是%eax,等得到操作结果后再使用指令: movl %eax, result 将寄存器的值写回C变量result中。从上面的汇编代码我们可以看出与result 和input,相关连的寄存器都是%eax, GCC使用%eax,替换内嵌汇编指令模板中的 %0,%1 movl %eax,%eax 显然这一句可以不要。但是没有优化,所以这一句没有被去掉。 由此可见,C表达式或者变量与寄存器的关系由GCC自动处理,我们只需使用限制字符串指导GCC 如何处理即 可。限制字符必须与指令对操作数的要求相匹配,否则产生的汇编代码将会有错,读者可以将上例中的两个 “r”,都改为“m”(m,表示操作数放在内存,而不是寄存器中),编译后得到的结果是: movl input, result 很明显这是一条非法指令,因此限制字符串必须与指令对操作数的要求匹配。例如指令movl允许寄存器到寄存 器,立即数到寄存器等,但是不允许内存到内存的操作,因此两个操作数不能同时使用“m”作为限定字符。 由此我们可以总结出来内嵌汇编的格式: __asm__( 汇编语句模板: 输出部分: 输入部分: extern int input,result; void test(void) { input= 1; __asm__ __volatile__ ("movl %1,%0" : "=r" (result) : "r" (input)); return ; } zhuyi2654715: @erazy0:这里并 没有开启分页机制 所以个人觉得 写成物理地址也可以 zhuyi2654715: 太棒了 真的写的 太精彩了 受教了! 谢谢LZ itbj00: 不错。什么时候我也能自 创一种编程语言? aaasssmnb: 获益良多 chenshuye009: 看着有点压力 gaoyueh0ng: “input”前面的 “r”表示该表达式需要先放入某 个寄存器,然后在指令中使用该 寄存器参加运算。???... lishanchao: @hunterdragen:或 者加const修饰。 wj12345678910: 写得很好 qlz37238: 这个计算方法是不是 有点不对的我看王爽的 关于书的成语关于读书的排比句社区图书漂流公约怎么写关于读书的小报汉书pdf 上明明 写的是19扇区是0面1道2扇区。 guohegong: centos 6.0 编译失败 # makemake: *** 错误 1make: *** 错误 ... lingang的博客 caoxu的博客 飘的博客 walkingman Unix对话录 评论排行 我看UNIX与Windows的本 (192) 重言式判别 (数据结构课 (18) 富人和穷人的区别 (18) Intel手册申请攻略 (14) 自己动手写操作系统读书笔记 (14) 保护模式下寻址 (13) 我对读计算机软件专业硕 (11) 虚拟机ubuntu与XP的文件共享 (10) 未雨绸缪——临界区中断 (9) 如何成为一个优秀的程序 (9) 推荐文章 * 专访方兴:Web应用将成企业 未来开发趋势 * 阿里巴巴分布式服务框架 Dubbo 团队成员梁飞专访 * Linux性能监控(1) * Java输出数组的内容 * 从K近邻算法谈到KD树、 SIFT+BBF算法 * 浅学 设计 领导形象设计圆作业设计ao工艺污水处理厂设计附属工程施工组织设计清扫机器人结构设计 模式之建造者模式 及在android中的应用 最新评论 保护模式下寻址 保护模式下寻址 自己动手写basic解释器(七) 多重继承和虚继承的内存布局 多重继承和虚继承的内存布局 GCC内嵌汇编 Linux shellcode 编写入门 (转) 保护模式下寻址 软盘结构(磁头号和起始扇区的计 Linux 文件隐藏 V0.2 朋友博客 页码,2/7GCC内嵌汇编 - 刺猬小屋 - 博客频道 - CSDN.NET 2012/11/24http://blog.csdn.net/littlehedgehog/article/details/2259665 破坏描述部分) 共四个部分:汇编语句模板,输出部分,输入部分,破坏描述部分,各部分使用“:”格开,汇编语句模板必不可 少,其他三部分可选,如果使用了后面的部分,而前面部分为空,也需要用“:”格开,相应部分内容为空。例 如: __asm__ __volatile__( "cli": : :"memory") 我们来分别说明: 输出部分 输出部分描述输出操作数,不同的操作数描述符之间用逗号格开,每个操作数描述符由限定字符串和C语言变量 组成。每个输出操作数的限定字符串必须包含“=”表示他是一个输出操作数。 例: 描述符字符串表示对该变量的限制条件,这样GCC就可以根据这些条件决定如何分配寄存器,如何产生必要的代 码处理指令操作数与C表达式或C变量之间的联系. 输入部分 输入部分描述输入操作数,不同的操作数描述符之间使用逗号格开,每个操作数描述符由限定字符串和C语言表 达式或者C语言变量组成。 例如: 该例子功能是将(*addr)的第nr位设为1。第一个占位符%0与C,语言变量ADDR对应,第二个占位符%1与C,语 言变量nr对应。因此上面的汇编语句代码与下面的伪代码等价: btsl nr, ADDR,该指令的两个操作数不能全是内存变量,因此将nr的限定字符串指定"lr"(下文会有解释),与立即 数或者寄存器相关联,这样两个操作数中只有ADDR为内存变量。 限制字符 限制字符有很多种,有些是与特定体系结构相关,此处仅列出常用的限定字符和i386中可能用到的一些常用的限 定符。它们的作用是指示编译器如何处理其后的C语言变量与指令操作数之间的关系,例如是将变量放在寄存器 中还是放在内存中等,下表列出了常用的限定字母。 “b”将输入变量放入ebx __asm__ __volatile__("pushfl ; popl %0 ; cli":"=g" (x) ) Static __inline__ void __set_bit(int nr, volatile void * addr) { __asm__( "btsl %1,%0" : "=m"(addr) : "Ir"(nr) ); } 页码,3/7GCC内嵌汇编 - 刺猬小屋 - 博客频道 - CSDN.NET 2012/11/24http://blog.csdn.net/littlehedgehog/article/details/2259665 “c”将输入变量放入ecx “d”将输入变量放入edx “s”将输入变量放入esi “d”将输入变量放入edi “q”将输入变量放入eax,ebx ,ecx ,edx中的一个 “r”将输入变量放入通用寄存器,也就是eax ,ebx,ecx,edx,esi,edi中的一个 “A”把eax和edx,合成一个64位的寄存器(uselong longs) “m”内存变量 “o”操作数为内存变量,但是其寻址方式是偏移量类型,也即是基址寻址,或者是基址加变址寻址 “V”操作数为内存变量,但寻址方式不是偏移量类型 “,” 操作数为内存变量,但寻址方式为自动增量 “p”操作数是一个合法的内存地址(指针) 寄存器或内存 “g” 将输入变量放入eax,ebx,ecx ,edx中的一个或者作为内存变量 “X”操作数可以是任何类型 立即数 “I” 0-31 之间的立即数(用于32位移位指令) “J” 0-63 之间的立即数(用于64 位移位指令) “N” 0-255 ,之间的立即数(用于out 指令) “i” 立即数 “n” 立即数,有些系统不支持除字以外的立即数,这些系统应该使用“n”而不是“i” 匹配 "0"、"1" ....."9" 表示用它限制的操作数与某个指定的操作数匹配,也即该操作数就是指定的那个操作数,例如用“0 ”去描述 “%1”操作数,那么“%1”引用的其实就是“%0”操作数,注意作为限定符字母的0-9 ,与指令中的“%0”- “%9”的区别,前者描述操作数,后者代表操作数。 操作数类型 “=” 操作数在指令中是只写的(输出操作数) “+” 操作数在指令中是读写类型的(输入输出操作数) 浮点数 “f” 浮点寄存器 “t”第一个浮点寄存器 “u”第二个浮点寄存器 “G” 标准 excel标准偏差excel标准偏差函数exl标准差函数国标检验抽样标准表免费下载红头文件格式标准下载 的80387 现在继续看上面的例子: "=m" (ADDR)表示ADDR为内存变量(“m”),而且是输出变量(“=”);"Ir" (nr)表示nr,为 0-31之间的立 即数(“I”)或者一个寄存器操作数(“r”)。 匹配限制符是一位数字 "0"、"1" ....."9" , 分别表示它限制的C表达式分别与占位符%0,%1,……%9对应的C变 量匹配。例如使用“0”作为%1,的限制字符,那么 %0和%1表示同一个C变量。 还是来看个例子吧: 页码,4/7GCC内嵌汇编 - 刺猬小屋 - 博客频道 - CSDN.NET 2012/11/24http://blog.csdn.net/littlehedgehog/article/details/2259665 输入部分中的result用匹配限制符“0”限制,表示%1与%0,代表同一个变量,输入部分说明该变量的输入功能, 输出部分说明该变量的输出功能,两者结合表示result, 是读写型。因为%0和%1,表示同一个C变量,所以放在 相同的位置,无论是寄存器还是内存。 寄存器破坏描述符 通常编写程序只使用一种语言:高级语言或者汇编语言。高级语言编译的步骤大致如下: 预处理; l 编译 l 汇编 l 链接 我们这里只关心第二步编译(将C代码转换成汇编代码):因为所有的代码都是用高级语言编写,编译器可以识 别各种语句的作用,在转换的过程中所有的寄存器都由编译器决定如何分配使用,它有能力保证寄存器的使用不 会冲突;也可以利用寄存器作为变量的缓冲区,因为寄存器的访问速度比内存快很多倍。如果全部使用汇编语言 则由程序员去控制寄存器的使用,只能靠程序员去保证寄存器使用的正确性。但是如果两种语言混用情况就变复 杂了,因为内嵌的汇编代码可以直接使用寄存器,而编译器在转换的时候并不去检查内嵌的汇编代码使用了哪些 寄存器(因为很难检测汇编指令使用了哪些寄存器,例如有些指令隐式修改寄存器,有时内嵌的汇编代码会调用 其他子过程,而子过程也会修改寄存器),因此需要一种机制通知编译器我们使用了哪些寄存器(程序员自己知道 内嵌汇编代码中使用了哪些寄存器),否则对这些寄存器的使用就有可能导致错误,修改描述部分可以起到这种 作用。当然内嵌汇编的输入输出部分指明的寄存器或者指定为“r”,“g”型由编译器去分配的寄存器就不需要在破 坏描述部分去描述,因为编译器已经知道了。 下面看个例子就很清楚为什么需要通知GCC内嵌汇编代码中隐式(称它为隐式是因为GCC并不知道)使用的寄存 器。 在内嵌的汇编指令中可能会直接引用某些寄存器,我们已经知道AT&T格式的汇编语言中,寄存器名以“%”作为 前缀,为了在生成的汇编程序中保留这个“%”号,在asm语句中对寄存器的引用必须用“%%”作为寄存器名称 的前缀。原因是“%”在asm,内嵌汇编语句中的作用与“/”在C语言中的作用相同,因此“%%”转换后代表 “%”。 extern int input,result; void test_at_t() { result = 0; input = 1; __asm__ __volatile__ ("addl %2,%0":"=r"(result):"0"(result),"m"(input)); } int main(void) { int input, output,temp; input = 1; __asm__ __volatile__ ("movl $0, %%eax; 页码,5/7GCC内嵌汇编 - 刺猬小屋 - 博客频道 - CSDN.NET 2012/11/24http://blog.csdn.net/littlehedgehog/article/details/2259665 这段代码使用%eax作为临时寄存器,功能相当于C代码:“temp = 0;output=input”, 对应的汇编代码如下: movl $1,-4(%ebp) movl -4(%ebp),%eax /APP movl $0, %eax; movl %eax, -12(%ebp); movl %eax, %eax; movl %eax, -8(%ebp); /NO_APP 显然GCC给input分配的寄存器也是%eax,发生了冲突,output的值始终为0,而不是input。 使用破坏描述后的代码: 对应的汇编代码: movl $1,� � (%ebp) movl � � (%ebp),%edx � � A� � movl $0, %eax; movl %eax, � 12(%ebp); movl %edx, %eax; movl %eax, � � (%ebp); � � � _A� � 通过破坏描述部分,GCC得知%eax已被使用,因此给input分配了%edx。在使用内嵌汇编时请记住一点:尽量告 诉GCC尽可能多的信息,以防出错。 movl %%eax, %1; movl %2, %%eax; movl %%eax, %0; " :"=m"(output),"=m"(temp) � * output *� :"r"(input) � * input *� ); return 0; } int main(void) { int input, output,temp; input = 1; __asm__ __volatile__ ( "movl $0, %%eax; movl %%eax, %1; movl %2, %%eax; movl %%eax, %0; " :"=m"(output),"=m"(temp) � * output *� :"r"(input) � * input *� :"eax"); � * 描述符 *� return 0; } 页码,6/7GCC内嵌汇编 - 刺猬小屋 - 博客频道 - CSDN.NET 2012/11/24http://blog.csdn.net/littlehedgehog/article/details/2259665 1楼 gaoyueh0ng 2012-10-06 11:30发表 您还没有登录,请[登录]或[注册] * 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场 分享到:上一篇: Oracle CEO在耶鲁大学的演讲:退学吧!- - - 下一篇:Align 透明地提升效率 查看评论 “input”前面的“r”表示该表达式需要先放入某个寄存器,然后在指令中使用该寄存器参加运算。???这句话有误吧。。。 专区推荐内容 多线程知识点整理 最好的HTML 5编码教程和参考... “高德地图杯”位置应用大赛 再掀... 网易邮箱首页帮女大学生送出父亲节... 使用HTML+CSS制作三角形 使用HTML+CSS制作居中布局 << >> 更多招聘职位 我公司职位也要出现在这里 【广州东软科技有限公司】web工程师 【上海科锐福克斯人才顾问有限公司】IT行业猎头顾问- 上海/北京/深圳 【深圳市解惑管理咨询有限公司】全球500强美资企业 Network Engineer 【北京天诺德咨询有限公司】通信 Staff Software 公司简介 | 招贤纳士 | 广告服务 | 银行汇款帐号 | 联系方式 | 版权声明 | 法律顾问 | 问题 报告 软件系统测试报告下载sgs报告如何下载关于路面塌陷情况报告535n,sgs报告怎么下载竣工报告下载 京 ICP 证 070598 号 北京创新乐知信息技术有限公司 版权所有 联系邮箱:webmaster(at)csdn.net Copyright © 1999-2012, CSDN.NET, All Rights Reserved 页码,7/7GCC内嵌汇编 - 刺猬小屋 - 博客频道 - CSDN.NET 2012/11/24http://blog.csdn.net/littlehedgehog/article/details/2259665
本文档为【reference article】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
该文档来自用户分享,如有侵权行为请发邮件ishare@vip.sina.com联系网站客服,我们会及时删除。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。
本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。
网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
下载需要: 免费 已有0 人下载
最新资料
资料动态
专题动态
is_694721
暂无简介~
格式:pdf
大小:335KB
软件:PDF阅读器
页数:7
分类:工学
上传时间:2012-12-05
浏览量:249