汇编语言的指令格式目前有两种不同的标准:Windows下的汇编语言基本上都遵循Intel风格的语法,比如:MASM、NASM,Unix/Linux下的汇编语言基本上都遵循AT&T风格的语法。 下面主要介绍Unix/Linux下的汇编,具体格式如下:

[名称[:]] 指令码 源操作数SRC,目的操作数DST ;注释

开发一个OS,尽管绝大部分代码只需要用C/C++等高级语言,但是和硬件相关部分的代码需要使用汇编语言;由于启动部分的代码有大小限制,使用精练的汇编可以缩小目标代码的Size;另外,对于某些需要被经常调用的代码,使用汇编可以提高性能。
如果我们选择的OS开发工具是GCC以及GAS的话,就必须了解AT&T汇编语言语法,因为GCC/GAS只支持这种汇编语法。下面介绍GCC的内嵌汇编语法。
GCC 支持在C/C++代码中嵌入汇编代码,这些汇编代码被称作GCC Inline ASM——GCC内联汇编。这是一个非常有用的功能,有利于我们将一些C/C++语法无法表达的指令直接潜入C/C++代码中,另外也允许我们直接写 C/C++代码中使用汇编编写简洁高效的代码。

1.基本内联汇编

基本格式如下:

__asm__ [__volatile__] ( assembler template
: [output operand list] /* optional */
: [input operand list] /* optional */
: [clobbered register list] /* optional */
);

(1)关键字“__asm__”,其实也可以写成“asm”。但是“asm”并不是所有版本的GCC编译器都支持的,而且有可能和程序中别的地方定义的变量或函数名冲突,所以用“__asm__”的话,兼容性会好一点。 

(2)“__volatile__”关键字,这个是可选的,其作用是禁止编译器对后面编写的汇编指令再进行优化。一般情况下,自己写的汇编代码肯定是自己进行设计优化过了的,如果编译器再进行优化的话,很有可能效果还不如不优化,而且也有可能会出现奇怪的错误,所以通常都会带上这个关键字。同样,“__volatile__”也可以写成“volatile”,但可能兼容性会没那么好。

(3)汇编代码由4部分组成,分别是汇编代码模板、输出操作数列表、输入操作数列表和修改寄存器列表,下面进行介绍。

1)汇编代码模板

汇编代码部分是必需的,所以即使一行汇编代码没有也需要传入空字符串(""),否则会报错。所有的汇编代码必须用双引号括起来。如果有多行汇编代码的话,每一条语句都要用双引号括起来,并且在代码后面要加上换行符(“\n”或者“\n\t”)。这样做是因为GCC会将汇编代码部分作为字符串形式直接传给汇编器,加上换行符后,汇编器就能准确知道哪些字符串表示的是一条汇编语句。同时,为了增加可读性,每条汇编语句都可以换行。

2)输入操作数列表与输出操作数列表

前面介绍了,第二部分和第三部分分别表示输出操作数列表和输入操作数列表。

输入操作数表示要作为汇编代码输入的C表达式,而输出操作数刚好相反,表示汇编代码处理完后要输出结果的C表达式。如果有多个输出或输入表达式,需要用逗号(“,”)将它们分隔开来。

可以再前面的汇编代码模板中直接应用定义的输出操作数和输入操作数,其用法是使用百分号(“%”)后面接一个数字,0表示定义的第一个操作数,1表示定义的第二个操作数,依次类推。下面举个例子:

__asm__("mov %0, %1, ror #1"
            : "=r" (result)
            : "r" (value)
        );

这里%0代表后面定义的第一个操作数,即输出操作数,代表C语言中的result变量。%1代表定义的第二个操作数,即输入操作数,代表C语言中的value变量。其作用是将value的值右移一位,然后保存到result中。

每一个操作数由三部分组成,分别是修改符(Modifier),限定符(Constraint)和C表达式,其中修改符是可选的。具体形式如下:  

"[modifier]constraint" (C expression)

修改符和限定符要用双引号括起来,而C表达式要用括号括起来。那么这些修改符和限定符又是什么呢?有什么作用呢?
我们接下来先来说说所谓的限定符。可以看出,操作数在这里的作用是将C语言定义的变量与汇编语言中要使用到的变量进行一一对应。但并不是所有的汇编指令都可以接受任何类型的变量作为输入或输出变量的,因此汇编器需要知道这些变量到底用在什么地方,从而帮助在传递之前做一些转换。常用的限定符主要有以下一些,而且汇编语句到底是ARM的还是Thumb的,对限定符的定义也会不同:

  

参考文章 :

(1)如何在C或C++代码中嵌入ARM汇编代码 https://blog.csdn.net/Roland_Sun/article/details/42921131

(2)汇编与C/C++内联嵌入汇编 https://blog.csdn.net/Levet/article/details/78516307

C/C++中书写汇编指令的更多相关文章

  1. C表达式中的汇编指令

    C 表达式中的汇编指令 asm 为 gcc 中的关键字,asm 表达式为在 C代码中嵌套汇编指令,该表达式只是单纯的替换出汇编代码,并不对汇编代码的含义进行解析. asm 表达式有两种形式,第二种 a ...

  2. C 表达式中的汇编指令

    asm 为 gcc 中的关键字,asm 表达式为在 C代码中嵌套汇编指令,该表达式只是单纯的替换出汇编代码,并不对汇编代码的含义进行解析. asm 表达式有两种形式,第二种 asm-qualifier ...

  3. ARM中的汇编指令

    Arm指令,32位的指令集,一共有16条的基本指令,每条指令都可以按条件执行, 指令都是32bit的,高四位是条件码[31:28], Thumb指令,16位的指令集,执行效率比arm指令集要低,但是节 ...

  4. [zhuan]arm中的汇编指令

    http://blog.csdn.net/qqliyunpeng/article/details/45116615 一. 带点的(一般都是ARM GNU伪汇编指令)   1. ".text& ...

  5. ARM中的---汇编指令

    一. 带点的(一般都是ARM GNU伪汇编指令) 1. ".text".".data".".bss" 依次表示的是"以下是代码段& ...

  6. Uboot中汇编指令

    LDR(load register)指令将内存内容加载入通用寄存器 ARM是RISC结构,数据从内存到CPU之间的移动只能通过L/S指令来完成,也就是ldr/str指令.比如想把数据从内存中某处读取到 ...

  7. 计算机系统6-> 计组与体系结构3 | MIPS指令集(中)| MIPS汇编指令与机器表示

    上一篇计算机系统5-> 计组与体系结构2 | MIPS指令集(上)| 指令系统从顶层讲解了一个指令集 / 指令系统应当具备哪些特征和工作原理.这一篇就聚焦MIPS指令集(MIPS32),看看其汇 ...

  8. C语言中插入汇编nop指令

    工作过程中,有的时候需要打桩cycle,想在C语言中插入nop指令,可以采取的方法是 头文件中加入#inlude <stdio.h> 定义一个内联函数,然后调用这个函数,不过得测一下平台调 ...

  9. 1.汇编指令介绍(arm)

    本文作为本人学习过程中的记录及时不时的突发奇想偶记.鄙人菜鸟一只,文中如有错误或疏漏,若读者肯不吝赐教,在下感激零涕.文章一直不断更新中 一.汇编语言 汇编语言是一种应用计算机.微处理器.微控制器或其 ...

随机推荐

  1. excel中使用统计列中的值在其他列出现的次数

    excel中使用统计一列的中值在其他列出现的次数 =COUNTIFS($J$:$J$,K2) 解释下 $J$2 J列中的第二行到 $J$373 J列的373行  范围内 查找 k列的第二行的值 出现的 ...

  2. ScheduledThreadPoolExecutor使用指南

    ScheduledThreadPoolExecutor是Timer的多线程实现版本,JDK官方推荐使用.ScheduledThreadPoolExecutor用于替代Timer.是接口Schedule ...

  3. 我是如何一步步编码完成万仓网ERP系统的(九)产品库设计 5.产品属性项

    https://www.cnblogs.com/smh188/p/11533668.html(我是如何一步步编码完成万仓网ERP系统的(一)系统架构) https://www.cnblogs.com/ ...

  4. linux 忘记mysql用户root密码 解决方案

    1.vim /etc/my.cnf[mysqld]skip-grant-tables ##追加此行,跳过权限表, 2.重启mysqlsystemctl restart mysqld 3.mysql 登 ...

  5. 了解MySQL

    目前流行的数据库 MySQL Oracle Microsoft SQLServer Microsoft Access PostgreSQL DB2/UDB InfoMax MySQL介绍 世界上最流行 ...

  6. Vue定义组件和生命周期函数及实例演示!

    定义全局组件 Vue.component("name",{...}) 定义局部组件 let Com = {....} new Vue({ data : ..., ..., comp ...

  7. Object::connect: No such slot QWidget::

    出现如下错误 Object::connect: No such slot QWidget::readMyCom() in ../untitled/ConversionScreen.cpp:49 解决办 ...

  8. Github标星过万,Python新手100天学习计划。

    大数据文摘编辑部出品 作为目前最火也是最实用的编程语言,Python不仅是新手入门程序界的首选,也逐渐成为了从大厂到小厂,招牌需求list的必要一条. 当然,学Python这件事情,你可能也和文摘菌一 ...

  9. 03篇ELK日志系统——升级版集群之ELK日志系统整合springboot项目

    [ 前言:整个ELK日志系统已经搭建好了,接下来的流程就是: springboot项目中的logback日志配置通过tcp传输,把springboot项目中所有日志数据传到————>logsta ...

  10. pip requirements.txt

    生成文件 pip freeze > requirements.txt 依赖库会导到于requirements.txt 比如:   image.png 从requirements.txt安装依赖库 ...