当然可以,在
创新互联建站服务项目包括子洲网站建设、子洲网站制作、子洲网页制作以及子洲网络营销策划等。多年来,我们专注于互联网行业,利用自身积累的技术优势、行业经验、深度合作伙伴关系等,向广大中小型企业、政府机构等提供互联网行业的解决方案,子洲网站推广取得了明显的社会效益与经济效益。目前,我们服务的客户以成都为中心已经辐射到子洲省份的部分城市,未来相信会继续扩大服务区域并继续获得客户的支持与信任!
嵌入式linux
中有一部分引导程序只能用汇编写,如果不能运行,那么linux岂不是垃圾么,当然,你得有相应的
编译器
才行。
答案是B.
确切地说是,R1的数据+R2的数据合成一个地址值,该地址中存放的数据赋值给R0
LDR指令是从某存储空间取数据,赋值给某寄存器.
这是ARM汇编,和Linux有什么关系?
建议看看ARM汇编的解释
linux 编译汇编程序常用的有两种,一种是AT方式的,你gcc 就可以编译了。还有一种是80X86方式,一般是用NASM,NASM你要在安装LINUX时就要添加软件包,或者你进入图型界面,增加NASM软件包,就可以编译了。
作者 Bharata B Rao 将各个部分组合起来 如果您是 Linux 内核的开发人员 您会发现自己经常要对与体系结构高度相关的功能进行编码或优化代码路径 您很可能是通过将汇编语言指令插入到 C 语句的中间(又称为内联汇编的一种方法)来执行这些任务的 让我们看一下 Linux 中内联汇编的特定用法 (我们将讨论限制在 IA 汇编 )GNU 汇编程序简述让我们首先看一下 Linux 中使用的基本汇编程序语法 GCC(用于 Linux 的 GNU C 编译器)使用 ATT 汇编语法 下面列出了这种语法的一些基本规则 (该列表肯定不完整 只包括了与内联汇编相关的那些规则 )寄存器命名寄存器名称有 % 前缀 即 如果必须使用 eax 它应该用作 %eax 源操作数和目的操作数的顺序在所有指令中 先是源操作数 然后才是目的操作数 这与将源操作数放在目的操作数之后的 Intel 语法不同 mov %eax %ebx transfers the contents of eax to ebx 操作数大小根据操作数是字节 (byte) 字 (word) 还是长型 (long) 指令的后缀可以是 b w 或 l 这并不是强制性的 GCC 会尝试通过读取操作数来提供相应的后缀 但手工指定后缀可以改善代码的可读性 并可以消除编译器猜测不正确的可能性 movb %al %bl Byte move movw %ax %bx Word move movl %eax %ebx Longword move立即操作数通过使用 $ 指定直接操作数 movl $ xffff %eax will move the value of xffff into eax register 间接内存引用任何对内存的间接引用都是通过使用 ( ) 来完成的 movb (%esi) %al will transfer the byte in the memory pointed by esi into alregister内联汇编GCC 为内联汇编提供特殊结构 它具有以下格式 GCG 的 a *** 结构 a *** ( assembler template : output operands (optional) : input operands (optional) : list of clobbered registers (optional) ); 本例中 汇编程序模板由汇编指令组成 输入操作数是充当指令输入操作数使用的 C 表达式 输出操作数是将对其执行汇编指令输出的 C 表达式 内联汇编的重要性体现在它能够灵活操作 而且可以使其输出通过 C 变量显示出来 因为它具有这种能力 所以 a *** 可以用作汇编指令和包含它的 C 程序之间的接口 一个非常基本但很重要的区别在于简单内联汇编只包括指令 而扩展内联汇编包括操作数 要说明这一点 考虑以下示例 内联汇编的基本要素{ int a= b; a *** ( movl % %%eax; movl %%eax % ; : =r (b) /* output */ : r (a) /* input */ : %eax ); /* clobbered register */}在上例中 我们使用汇编指令使 b 的值等于 a 请注意以下几点 b 是输出操作数 由 % 引用 a 是输入操作数 由 % 引用 r 是操作数的约束 它指定将变量 a 和 b 存储在寄存器中 请注意 输出操作数约束应该带有一个约束修饰符 = 指定它是输出操作数 要在 a *** 内使用寄存器 %eax %eax 的前面应该再加一个 % 换句话说就是 %%eax 因为 a *** 使用 % % 等来标识变量 任何带有一个 % 的数都看作是输入/输出操作数 而不认为是寄存器 第三个冒号后的修饰寄存器 %eax 告诉将在 a *** 中修改 GCC %eax 的值 这样 GCC 就不使用该寄存器存储任何其它的值 movl % %%eax 将 a 的值移到 %eax 中 movl %%eax % 将 %eax 的内容移到 b 中 因为 b 被指定成输出操作数 因此当 a *** 的执行完成后 它将反映出更新的值 换句话说 对 a *** 内 b 所做的更改将在 a *** 外反映出来 现在让我们更详细的了解每一项的含义 汇编程序模板汇编程序模板是一组插入到 C 程序中的汇编指令(可以是单个指令 也可以是一组指令) 每条指令都应该由双引号括起 或者整组指令应该由双引号括起 每条指令还应该用一个定界符结尾 有效的定界符为新行 (\n) 和分号 (;) \n 后可以跟一个 tab(\t) 作为格式化符号 增加 GCC 在汇编文件中生成的指令的可读性 指令通过数 % % 等来引用 C 表达式(指定为操作数) 如果希望确保编译器不会在 a *** 内部优化指令 可以在 a *** 后使用关键字 volatile 如果程序必须与 ANSI C 兼容 则应该使用 __a *** __ 和 __volatile__ 而不是 a *** 和 volatile 操作数C 表达式用作 a *** 内的汇编指令操作数 在汇编指令通过对 C 程序的 C 表达式进行操作来执行有意义的作业的情况下 操作数是内联汇编的主要特性 每个操作数都由操作数约束字符串指定 后面跟用括弧括起的 C 表达式 例如 constraint (C expression) 操作数约束的主要功能是确定操作数的寻址方式 可以在输入和输出部分中同时使用多个操作数 每个操作数由逗号分隔开 在汇编程序模板内部 操作数由数字引用 如果总共有 n 个操作数(包括输入和输出) 那么第一个输出操作数的编号为 逐项递增 最后那个输入操作数的编号为 n 总操作数的数目限制在 如果机器描述中任何指令模式中的最大操作数数目大于 则使用后者作为限制 修饰寄存器列表如果 a *** 中的指令指的是硬件寄存器 可以告诉 GCC 我们将自己使用和修改它们 这样 GCC 就不会假设它装入到这些寄存器中的值是有效值 通常不需要将输入和输出寄存器列为 clobbered 因为 GCC 知道 a *** 使用它们(因为它们被明确指定为约束) 不过 如果指令使用任何其它的寄存器 无论是明确的还是隐含的(寄存器不在输入约束列表中出现 也不在输出约束列表中出现) 寄存器都必须被指定为修饰列表 修饰寄存器列在第三个冒号之后 其名称被指定为字符串 至于关键字 如果指令以某些不可预知且不明确的方式修改了内存 则可能将 memory 关键字添加到修饰寄存器列表中 这样就告诉 GCC 不要在不同指令之间将内存值高速缓存在寄存器中 操作数约束前面提到过 a *** 中的每个操作数都应该由操作数约束字符串描述 后面跟用括弧括起的 C 表达式 操作数约束主要是确定指令中操作数的寻址方式 约束也可以指定 是否允许操作数位于寄存器中 以及它可以包括在哪些种类的寄存器中 操作数是否可以是内存引用 以及在这种情况下使用哪些种类的地址 操作数是否可以是立即数 约束还要求两个操作数匹配 常用约束在可用的操作数约束中 只有一小部分是常用的 下面列出了这些约束以及简要描述 有关操作数约束的完整列表 请参考 GCC 和 GAS 手册 寄存器操作数约束 (r)使用这种约束指定操作数时 它们存储在通用寄存器中 请看下例 a *** ( movl %%cr % \n : =r (cr val));这里 变量 cr val 保存在寄存器中 %cr 的值复制到寄存器上 cr val 的值从该寄存器更新到内存中 指定 r 约束时 GCC 可以将变量 cr val 保存在任何可用的 GPR 中 要指定寄存器 必须通过使用特定的寄存器约束直接指定寄存器名 a %eaxb %ebxc %ecxd %edxS %esiD %edi内存操作数约束 (m)当操作数位于内存中时 任何对它们执行的操作都将在内存位置中直接发生 这与寄存器约束正好相反 后者先将值存储在要修改的寄存器中 然后将它写回内存位置中 但寄存器约束通常只在对于指令来说它们是绝对必需的 或者它们可以大大提高进程速度时使用 当需要在 a *** 内部更新 C 变量 而您又确实不希望使用寄存器来保存其值时 使用内存约束最为有效 例如 idtr 的值存储在内存位置 loc 中 ( sidt % \n : : m (loc));匹配(数字)约束在某些情况下 一个变量既要充当输入操作数 也要充当输出操作数 可以通过使用匹配约束在 a *** 中指定这种情况 a *** ( incl % : =a (var): (var));在匹配约束的示例中 寄存器 %eax 既用作输入变量 也用作输出变量 将 var 输入读取到 %eax 增加后将更新的 %eax 再次存储在 var 中 这里的 指定第 个输出变量相同的约束 即 它指定 var 的输出实例只应该存储在 %eax 中 该约束可以用于以下情况 输入从变量中读取 或者变量被修改后 修改写回到同一变量中 不需要将输入操作数和输出操作数的实例分开 使用匹配约束最重要的意义在于它们可以导致有效地使用可用寄存器 一般内联汇编用法示例以下示例通过各种不同的操作数约束说明了用法 有如此多的约束以至于无法将它们一一列出 这里只列出了最经常使用的那些约束类型 a *** 和寄存器约束 r 让我们先看一下使用寄存器约束 r 的 a *** 我们的示例显示了 GCC 如何分配寄存器 以及它如何更 lishixinzhi/Article/program/Oracle/201311/17556