GCC嵌入汇编特性

news2024/9/25 13:26:14

前言

在C语言编程中,使用汇编指令有两种方式,一种是使用单独的汇编源文件,在最后编译的时候和其它C工程文件编译到一起,这种方式能够做到汇编函数和C函数的互相调用,但是如果希望在C语言中直接调用汇编表达式就不是那么方便了,为此我们需要使用另一种方式,即内嵌汇编。

GCC嵌入汇编语法

内嵌汇编使用一种约束好的格式来实现C调用汇编指令,GCC使用的嵌入汇编语法的基本格式如下所示

__asm__ (汇编指令模板
    :输出部分
    :输入部分
    :破坏描述部分);

上述格式给出了嵌入汇编时可能需要使用到的基本元素,依次为汇编指令模板、输出部分、输入部分和破坏描述部分,各部分使用”:”格开,其中汇编语句模板必不可少,其他三部分可选。如果使用了后面的部分,而前面部分为空,也需要用”:”格开,相应部分内容为空。示例如下:

__asm__ __volatile__("cli": : :"memory")

在GNU C嵌入汇编中,我们常看到__asm__后都会带上__volatile____volatile__表示编译器不要优化代码,后面的指令保留原样,volatile是它的别名。一个更加完整的嵌入汇编使用如下所示:

__asm__ __violate__ ("addl %1, %%eax;"
    "movl %%eax,%0;" 
    : "=r" (result) 
    : "r" (input));

汇编指令模板

汇编语句模板由汇编语句序列组成,语句之间使用”;”、”\n”或”\n\t”分开。指令中的操作数可以使用占位符引用C语言变量,操作数占位符最多10个,名称如下:%0,%1,…,%9,其中%0表示第一个参数,%1表示第二个参数。另外,为了增强代码可读性,可以使用汇编符号名字来替代以%表示的操作数。

__asm__ __violate__ ("addl %[in], %%eax;"
    "movl %%eax, %0;" 
    : [res] "=r" (result) 
    : [in]"r" (input));

其中,[res]表示定义了一个汇编符号操作数,符号名为res,对应于输出参数"=r" (result);同理,[in]对应于输入参数"r" (input)

转义字符

汇编指令模板规定了一些特殊字符的含义:

  • %%: 在输出的汇编代码中表示一个’%'字符,如上面的嵌入汇编示例中,%%eax等价于%eax,在AT&T的汇编语法中,引用寄存器需要加上%前缀;
  • %= 在输出的汇编代码中生成一个唯一的数字,该数字可以代表编写的内嵌汇编程序,这相当于生成了一个本地标号;

输出部分

输出部分描述输出操作数,不同的输出操作数之间用逗号格开,每个操作数由限制字符串和C语言变量组成。每个输出操作数的限制字符串通常以”=”或者“+”开头,然后是一个字母表示对操作数类型的说明,接着是关于变量结合的约束。“=”表示被修饰的操作只具有可写属性,“+”号表示被修饰的操作数具有可读可写属性。

__asm__ __volatile__("pushfl ; popl %0 ; cli":"=a" (x) )

上面的示例会使用eax寄存器存放pop出的值,然后存储到变量x中

输入部分

输入部分描述输入操作数,不同的操作数之间使用逗号格开,每个操作数描述符由限制字符串和C语言变量组成。输入部分描述的操作数只有只读属性,不允许修改,因此,在输入部分中,不能使用“=”或者“+”约束条件,否则编译器会报错。

__asm__ __volatile__ ("lidt %0" : : "m" (real_mode_idt));

破坏描述部分

破坏描述符用于通知编译器我们使用了哪些寄存器或内存,由逗号格开的字符串组成,每个字符串描述一种情况,一般是寄存器名;除寄存器外比较常用的还有“memory”和“cc”:

  • memory:告知GCC编译器,嵌入汇编代码修改了内存中的值,强迫编译器在执行该汇编代码前存储所有缓存的值,在执行完汇编代码之后重新加载该值,目的是防止编译乱序;
  • cc:表示嵌入汇编代码修改了状态寄存器的相关标志位。

限制字符串

限制字符的作用是指示编译器如何处理其后的C语言变量与指令操作数之间的关系。限制字符有很多种。有些是与特定体系结构相关,此处列出常用的限定字符和x86中可能用到的一些常用的限定符。

限定符类型含义
“r”寄存器将变量放入通用寄存器中
“a”寄存器将变量放入eax寄存器中
“b”寄存器将变量放入ebx寄存器中
“c”寄存器将变量放入ecx寄存器中
“d”寄存器将变量放入edx寄存器中
“m”内存内存变量
“0-9”匹配逐一匹配操作数表达式,注意与%1-%9区分

示例分析

在这里插入图片描述

相关参考

  • 《奔跑吧,Linux内核》
  • 《GCC工具手册》

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/127504.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

kibana在linux环境安装实战遇到的问题汇总

kibana在linux环境安装实战遇到的问题汇总: 1、找不到主节点的错误: savedobjects-service] Unable to connect to Elasticsearch. Error: [master_not_discovered_exception] null 原因是找不到es的主节点,意思是es没有配置主节点。 解决…

【Spring】Spring @Cacheable 官方学习及demo

文章目录前言Cacheable 的来源应用场景集成Redis的思路代码及验证后记前言 Spring 有很多声明式的编程风格,Transactional 是,Cacheable 也是。说起 Transactional,复杂的事务情况下,这个注解也有局限,需要用到编程式…

奇安信病毒检测中心 2022年第二季度App收集个人信息检测报告 学习笔记 附下载地址

奇安信 2022年第二季度App收集个人信息检测报告 下载地址 2022年第二季度 APP收集个人信息 检测报告 奇安信 病毒响应中心 研究背景 随着互联网和移动设备的发展,手机已成为人人都拥有的设备,其中各式各样的APP更是丰富了人们的生活,从社交…

现在考系统集成项目管理工程师有用吗?

有用! 现在考系统集成项目管理工程师还是挺有用的哈,虽然它资质评定国务院取消了,但它是由国家人力资源和社会保障部、工业和信息化部领导下的国家级考试,并且是职业资格考试、职称资格考试和水平考试。 系统集成项目管理工程师…

sql-labs靶场环境搭建及搭建过程遇到的问题

sql-labs是github上的一个开源项目,通过闯关的方式训练自己的SQL注入。 下载php-study 进入官网 php-study 下载sql-labs 进入github sql-labs 将sql-labs下载到php-study的WWW\目录下,解压。 配置sql-llibs 记事本打开sqli-labs-master\sql-conn…

用python采集四大电商平台商品数据进行对比

前言 大家早好、午好、晚好吖 ❤ ~ 环境介绍: python 3.8 越稳定越好 pycharm 2021专业版 一、考拉 模块使用: requests >>> pip install requests parsel >>> pip install parsel 代码展示 导入模块 # import 导入模块 import requests # 第三方…

这届黑客不讲武德

编者按 腾讯安全2022年典型攻击事件复盘第七期,希望帮助企业深入了解攻击手法和应对措施,完善自身安全防御体系。 本篇讲述了某物流公司遭遇不明黑客攻击,腾讯安全服务团队和客户通力合作,排查溯源,最后揪出黑客的尾…

十、HashMap详解

文章目录小结底层源码框架特点源码详解小结 Map接口的常用实现类:HashMap、Hashtable和Properties.HashMap是Map接口使用频率最高的实现类。HashMap是以 key-val对的方式来存储数据(HashMap$Node类型)key不能重复,但是值可以重复,允许使用null键和null值。如果添加…

Android设计模式详解之组合模式

前言 组合模式也称为部分整体模式,结构型设计模式之一; 定义:将对象组合成树形结构以表示“部分-整体”的层次结构,使得用户对单个对象和组合对象的使用具有一致性; 使用场景: 表示对象的部分-整体的层…

屏幕录制为什么没声音?检查这2项,轻松解决

相信很多人在录制视频的时候都会遇到各种各样的问题,比如录制的视频没有声音。屏幕录制为什么没声音?今天小编就和大家分享一下如何录制音画同步视频的具体操作方法。如果你有录制的视频没有声音,你可以试试这个方法。 一、检查是否打开电脑系…

amCharts 5: Maps 附加组件

amCharts 5: Maps 附加组件 将reverseGeodata设置添加到MapPolygonSeries。如果设置为true,将反转GeoJSON数据中多边形角的方向。 向MapLine添加了新的linechanged事件。 amCharts 5:地图 amCharts:Maps是amCharts:Charts的附加组件。使用它可以将完整的…

Java学习笔记【7】面向对象

⭐ ⭐ ⭐ ⭐ ⭐ ⭐ ⭐ ⭐ ⭐ ⭐ ⭐ 🌀 个人首页:🏠 星空之路Star 🏠 🌀 所属专栏:📖 Java知识点总结 📖 🌀 大家好🤝 我是 👉老孙👈 &…

操作系统期末考试必会题库5——文件管理

1、画出文件系统的层次模型,并描述各层的功能。 2、某文件系统为一级目录,文件的数据一次性写入磁盘,已经写入的文件不可修改,但可以多次创建新文件,请回答: (1) 采用哪种文件物理结构形式更适合&#xff…

hnu计网实验二-网络基础编程实验(JAVA\Python3)

前言:这次实验用的是python语言,但是本人的python也不是很强,所以代码大部分也是借鉴别人的。实验本身还是很有趣的 一、实验目的 通过本实验,学习采用Socket(套接字)设计简单的网络数据收发程序&#xf…

Qt编写雷达模拟仿真工具

一、前言 雷达模拟仿真工具,已发布很长一段时间,一直以来没有好好整理该系列文章,在刘哥6.5的极力推荐下,整理出该系列的更加详细细节的文章出来。懒散了很久,也颓废了不少,人啊,感觉不能颓废下…

Python入门小案例: 采集全网表情包图片

前言 嗨喽,大家好呀~这里是爱看美女的茜茜呐 又到了学Python时刻~ 环境使用: Python 3.8 Pycharm 2021.2版本 模块使用: import requests >>> pip install requests -pip install -i https://pypi.doubanio.com/simple/ requests import re 安装pyt…

Revit中:该扶手的坡度可能与梯段及平台楼梯不平行问题

一、Revit中单独绘制楼梯扶手问题 单独绘制扶手的时候总是会出现梯段及平台上的楼梯不平行,这种情况怎么办? 在正常操作下楼梯会制动生成扶手,但有时候还是回碰到单独绘制扶手的时候然后就会出现这样的些问题,如图1、图2所示。 解决方法&…

(Research)深度迁移学习使循环肿瘤细胞的病变追踪成为可能

Tips: 深度迁移学习使循环肿瘤细胞的病变追踪成为可能 (Nat Commun),原文链接: https://pubmed.ncbi.nlm.nih.gov/36509761/ 摘要: CTC做为液体活检中最重要的一个目标,如果能够对 CTC 进行溯源那么就能够实现肿瘤的早…

mediasoup create/connect WebRtcTransport 流程分析

一. 前言 在这篇博客中我们介绍了 mediasoup-demo 启动流程与信令交互,关键信令包括 getRouterRtpCapabilites,join, createWebRtcTransport, connectWebRtcTransport, produce,本文将介绍 createWebRtcTransport 和 connectRtcTransport 的流…

为远程MySQL数据库配置固定的公网TCP地址【内网穿透】

在上篇文章中, 我们成功实现了在公网环境下远程连接内网MySQL数据库。但由于使用的免费的cpolar内网穿透,其所生成的公网地址为随机临时地址,24小时内会发生变化,对于需要长期远程访问的用户来讲非常不方便。因此,本篇…