Essential Linu Device Driver附录A Linu汇编.doc

Essential Linu Device Driver附录A Linu汇编.doc

  1. 1、本文档共7页,可阅读全部内容。
  2. 2、有哪些信誉好的足球投注网站(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
  3. 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  4. 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
Essential Linu Device Driver附录A Linu汇编

Essential Linux Device Driver附录A . Linux汇编 设备驱动程序有时需要用汇编实现一些代码片断,因此让我们看看Linux上汇编编程的不同特性。 图A.1显示了Linux在PC兼容系统上的引导顺序,是第2章“内核一瞥”中图2.1的缩减版。图中的固件组件是用不同的汇编语法实现的: · BIOS通常全部用汇编编写。一些流行的PC BIOS使用像Microsoft Macro Assembler (MASM)这样的汇编来编码。 · Linux 引导程序,像LILO和GRUB用C与汇编混合编写。SYSLINUX引导程序整个用Netwide Assembler(NASM)汇编编写。 · 实模式的Linux启动代码使用GNU汇编器(GAS)编码。 · 保护模式的BIOS调用用内联汇编编写。内联汇编是GCC支持的结构,在C语句之间插入汇编。 图 A.1. 固件组件与汇编语法 在图A.1中,上面的两个组件通常遵守基于Intel的汇编语法,而下面的两个用ART(或GAS)语法来编码。也有一些例外,GRUB的汇编部分就使用GAS。 为了演示这两种语法之间的差异,考虑如下输出一个字节到并口的代码。在BIOS或引导程序所使用的Intel格式中,你将会编写代码: mov dx, 03BCh ;0x3BC is the I/O address of the parallel port mov al, 0ABh ;0xAB is the data to be output out dx, al ;Send data to the parallel port 然而,如果你想从Linux实模式启动代码中完成同样的工作,你将需要编写如下代码: movw $0x3BC, %dx movb $0xAB, %al outb %al, %dx 你会发现,不像Intel格式,在ATT语法中,首先出现的是源操作数,目的操作数在其后。ATT格式中的寄存器名字由%开始,立即数用$开始。ATT的操作码为了指定内存操作数的宽度,都带有后缀如b(针对字节)和w(针对字);而Intel语法中通过查看操作数而不是操作码来实现此目的。在Intel语法中,为了移动指针引用,你需要为操作数指定前缀,如byte ptr。 学习ATT语法的益处是它被GAS和内联GCC所支持,而GAS和GCC不仅运行于基于Intel的系统上,也运行于各种处理器架构。 下面,让我们使用GCC内联汇编重写前面的代码片断,它是你在保护模式的内核将要用到的: unsigned short port = 0x3BC; unsigned char data = 0xAB; asm(outb %%al, %%dx\n\t : : a (data), d (port) ); GCC支持的汇编格式通常如下: asm(assembly : output operand constraints : input operand constraints : clobbered operand specifier ); 在操作数项,a,b,c,d,S和D分别代表EAX,EBX,ECX,EDX,ESI和EDI寄存器。输入操作数constraint用于在执行汇编指令之前,将数据从提供的变量里拷贝至寄存器。关于GCC内联汇编语法的细节请查看GCC 内联汇编指南(/gferg/ldp/GCC-Inline-Assembly-HOWTO.html)。 在我们的例子中,唯一用到的constraint是针对输入操作数的。此约束有效地拷贝data的值至AL寄存器,以及port的值至DX寄存器。在内联汇编中,寄存器名由%%开始,因为%被用于指定提供的操作数。%i代表第i个操作数,因此,在前面的例子内联汇编代码片断中,如果你想指定data和port,可以分别使用%0和%1。 为了对内联汇编转换有更清晰的了解,让我们看看对应于前面的内联汇编片断、通过提供-s命令行参数给GCC,由编译器产生的汇编代码。为了理解,请阅读针对产生的每行代码的注释: movw $956, -2(%ebp) # Value of data in stack set to 0x3BC movb $-85, -3(%ebp) # Value of port in stack set to 0xAB movb -3(%ebp), %al # movb 0xAB, %al movw -2(%ebp), %dx # movw 0x3BC, %dx #APP # Marker to note start of inline assembly outb %al, %dx # Write to parallel port #NO_APP # Marker to note e

文档评论(0)

almm118 + 关注
实名认证
内容提供者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档