2022年嵌入式汇编 .pdf

上传人:Che****ry 文档编号:27193028 上传时间:2022-07-23 格式:PDF 页数:3 大小:35.76KB
返回 下载 相关 举报
2022年嵌入式汇编 .pdf_第1页
第1页 / 共3页
2022年嵌入式汇编 .pdf_第2页
第2页 / 共3页
点击查看更多>>
资源描述

《2022年嵌入式汇编 .pdf》由会员分享,可在线阅读,更多相关《2022年嵌入式汇编 .pdf(3页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。

1、本节是第一次在内核源程序中接触到C 语言中的嵌入式汇编代码。由于我们在通常的C 语言程序的编制过程中一般是不会使用嵌入式汇编程序的,因此这里有必要对其基本格式进行简单的描述, 详细的说明可参见GNU gcc手册中 5 第 4 章的内容 (Extensions to the C Language Family) ,或见参考文献20 (Using Inline Assembly with gcc) 。具有输入和输出参数的嵌入汇编的基本格式为:asm( “ 汇编语句 ” : 输出寄存器 : 输入寄存器 : 会被修改的寄存器); 其中, “ 汇编语句 ” 是你写汇编指令的地方;“ 输出寄存器 ” 表示

2、当这段嵌入汇编执行完之后,哪些寄存器用于存放输出数据。此地,这些寄存器会分别对应一C 语言表达式或一个内存地址; “ 输入寄存器 ” 表示在开始执行汇编代码时,这里指定的一些寄存器中应存放的输入值,它们也分别对应着一C 变量或常数值。下面我们用例子来说明嵌入汇编语句的使用方法。我们在下面列出了前面代码中第22 行开始的一段代码作为例子来详细解说,为了能看清楚我们将这段代码进行了重新编排和编号。01 #define get_seg_byte(seg,addr) 02 ( 03 register char _res; 04 _asm_(push %fs; 05 mov %ax,%fs; 06 mo

3、vb %fs:%2,%al; 07 pop %fs 08 :=a (_res) 09 : (seg),m (*(addr); 10 _res;) 这段 10 行代码定义了一个嵌入汇编语言宏函数。因为是宏语句,需要在一行上定义,因此这里使用反斜杠 将这些语句连成一行。这条宏定义将被替换到宏名称在程序中被引用的地方。第1 行定义了宏的名称,也即是宏函数名称get_seg_byte(seg,addr)。第 3 行定义了一个寄存器变量_res 。第 4 行上的 _asm_表示嵌入汇编语句的开始。从第4行到第 7 行的 4 条 AT&T 格式的汇编语句。第 8 行即是输出寄存器,这句的含义是在这段代码运

4、行结束后将eax 所代表的寄存器的值放入 _res变量中,作为本函数的输出值,=a中的 a 称为加载代码,= 表示这是输出寄存器。第9 行表示在这段代码开始运行时将seg 放到 eax 寄存器中, 表示使用与上面同个位置的输出相同的寄存器。而(* (addr)表示一个内存偏移地址值。为了在上面汇编语句中使用该地址值,嵌入汇编程序规定把输出和输入寄存器统一按顺序编号,顺序是从输出寄存器序列从左到右从上到下以%0开始,分别记为%0 、%1 、%9 。因此,输出寄存器的编号是%0 (这里只有一个输出寄存器),输入寄存器前一部分( (seg)的编号是 %1 ,而后部分的编号是%2 。上面第 6 行上的

5、 %2 即代表 (*(addr)这个内存偏移量。现在我们来研究4 7 行上的代码的作用。第一句将fs 段寄存器的内容入栈;第二句将 eax 中的段值赋给fs 段寄存器;第三句是把fs:(*(addr)所指定的字节放入al 寄存器中。当执行完汇编语句后,输出寄存器eax 的值将被放入 _res ,作为该宏函数的返回值。很简单,不是吗?通过上面分析, 我们知道, 宏名称中的seg 代表一指定的内存段值,而 addr表示一内名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 1 页,共 3 页

6、 - - - - - - - - - 存偏移地址量。 到现在为止, 我们应该很清楚这段程序的功能了吧!该宏函数的功能是从指定段和偏移值的内存地址处取一个字节。在看下一个例子。01 asm(cldnt 02 repnt 03 stol 04 : /* 没有输出寄存器*/ 05 : c(count-1), a(fill_value), D(dest) 06 : %ecx, %edi); 1-3行这三句是通常的汇编语句,用以清方向位,重复保存值。第4 行说明这段嵌入汇编程序没有用到输出寄存器。第 5 行的含义是: 将 count-1的值加载到ecx 寄存器中(加载代码是 c ) ,fill_valu

7、e加载到 eax 中, dest 放到 edi 中。为什么要让gcc 编译程序去做这样的寄存器值的加载,而不让我们自己做呢?因为gcc在它进行寄存器分配时可以进行某些优化工作。例如fill_value值可能已经在eax 中。如果是在一个循环语句中的话,gcc 就可能在整个循环操作中保留eax ,这样就可以在每次循环中少用一个movl语句。最后一行的作用是告诉gcc 这些寄存器中的值已经改变了。很古怪吧?不过在gcc 知道你拿这些寄存器做些什么后,这确实能够对gcc 的优化操作有所帮助。下面列表中,是一些你可能会用到的寄存器加载代码及其具体的含义。表 4.1 常用寄存器加载代码说明代码说明代码说

8、明- a 使用寄存器eax m 使用内存地址b 使用寄存器ebx o 使用内存地址并可以加偏移值c 使用寄存器ecx I 使用常数0-31 d 使用寄存器edx J 使用常数 0-63 S 使用 esi K 使用常数0-255 D 使用 edi L 使用常数0-65535 q 使用动态分配字节可寻址寄存器(eax 、 ebx 、ecx 或 edx ) M 使用常数 0-3 r 使用任意动态分配的寄存器N 使用 1 字节常数( 0-255 )g 使用通用有效的地址即可(eax 、 ebx 、ecx 、edx 或内存变量) O 使用常数0-31 A 使用 eax 与 edx 联合 (64位) 下面

9、的例子不是让你自己指定哪个变量使用哪个寄存器,而是让gcc 为你选择。01asm(leal (%1, %1, 4), %0 02: =r(y) 03: 0(x); 第一句汇编语句leal (r1, r2,4), r3语句表示r1+r2*4  r3。这个例子可以非常快地将x 乘 5。其中 %0,%1是指 gcc 自动分配的寄存器。这里%1 代表输入值 x 要放入的寄存器,%0 表示输出值寄存器。输出寄存器代码前一定要加等于号。如果输入寄存器的代码是0 或为空时,则说明使用与相应输出一样的寄存器。所以,如果gcc将 r 指定为 eax 的话,那么上面汇编语句的含义即为:leal (

10、eax,eax,4), eax 注意:在执行代码时,如果不希望汇编语句被gcc 优化而挪动地方,就需要在asm 符名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 2 页,共 3 页 - - - - - - - - - 号后面添加volatile关键词:as m volatile ();或者更详细的说明为:_asm_ _volatile_ ();下面在具一个较长的例子,如果能看得懂, 那就说明嵌入汇编代码对你来说基本没问题了。这段代码是从include/string.h文件中摘取的,

11、是 strncmp()字符串比较函数的一种实现。需要注意的是,其中每行中的nt是用于 gcc 预处理程序输出列表好看而设置的,含义与 C 语言中相同。/ 字符串 1 与字符串2 的前 count个字符进行比较。/ 参数: cs - 字符串 1, ct - 字符串 2,count - 比较的字符数。/ %0 - eax(_res)返回值, %1 - edi(cs)串 1 指针, %2 - esi(ct)串 2 指针, %3 - ecx(count)。/ 返回:如果串1 串 2,则返回1;串 1 = 串 2,则返回0;串 1 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 3 页,共 3 页 - - - - - - - - -

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 教育专区 > 高考资料

本站为文档C TO C交易模式,本站只提供存储空间、用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。本站仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知淘文阁网,我们立即给予删除!客服QQ:136780468 微信:18945177775 电话:18904686070

工信部备案号:黑ICP备15003705号© 2020-2023 www.taowenge.com 淘文阁