IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 工具——C语言内联汇编(Inline Assembly)原来是这样的 -> 正文阅读

[C++知识库]工具——C语言内联汇编(Inline Assembly)原来是这样的

Inline Assembly(C语言内联汇编)

What is C program Inline Assembly(C语言内联汇编)

C语言内联汇编是在高级语言内部嵌入汇编代码的成分,再实现某些功能的时候,C语言是一门高级语言,虽然它与其它语言相比,有着比较高的底层相容性,但是针对某些情形的境况还是不太够,而内联汇编正是解决了这个问题,让C语言可以利用汇编语言的硬件亲和性来亲近底层开发,这也是原来用C语言来开发操作系统的重要原因之一

Inline Assembly‘s General Fomart (内敛汇编的基本格式)

在C语言中,如果要使用内联汇编,他需要以asm或__asm__开头,asm和__asm__的区别为,在GitHub搜到的一个解释为

# The asm keyword used to identify the inline assembly code section 
# may be altered if necessary. The ANSI C specifications use the asm keyword 
# for something else, preventing you from using it for your inline assembly
# statements. If you are writing code using the ANSI C conventions, 
# you must use the __asm__ keyword instead of the normal asm keyword.

意思即为asm关键字被用于定义内联汇编,但是如果必要,可以更改,在ANSI C语法规范下面,他是为了防止你使用内敛汇编定义集,如果你遵循ANSI C规范,那么必须用__asm__来定义内敛汇编

通俗的来说就是用__asm__就是了

其格式为

__asm__ (__volatile__) ("assemble code"
                        :output location
                        :input operands
                        :changed registers);
// 更细致一点就是
__asm__ (__volatile__) ("assemble code"
                        :[name]"modifier+tag"(variable),.....
                        :[name]"tag"(variable),.....
                        :"tag",....);

__volatile__的作用是,如果加了这个声明,说明这个部分在编译的时候不要优化

output location 表明你程序处理完毕之后结果的输出位置

input operands表明你的输入操作数

changed registers定义了可以被内敛汇编语句使用到的寄存器列表

Up Hand Inline Assembly(上手内联汇编)

Example1

有一个栗子,计算两数之和并将它存放到另外一个数中

// mian.c 文件
#include<stdio.h>
int main(){
    int data1 = 10;
	int data2 = 20;
	int result;
	asm ("addl %%edx, %%ecx\n\t"
     	"movl %%ecx, %%eax"
     	: "=a"(result)
     	: "d"(data1), "c"(data2));
	printf("%d\n",result);
    return 0;
}

用gcc命令编译成可执行文件, 并执行,可以看到输出30

$>gcc main.c -o test
$>.\test
30

从上面的例子可以看到,程序将data1的值和data2的值相加并存放到了result中,这其中的过程即为输入操作数data1和data2分别存放到了寄存器edx,ecx中,这个就涉及到数据存放的问题,这个数据具体存放到哪,看的是前边的"a","d","c"这些标号,这些标号对这些输入输出数据进行规定,其分别代表的意思是

标号含义
a使用eax or ax oral寄存器存放数据
b使用ebx or bx orbl寄存器存放数据
c使用ecx or cx orcl寄存器存放数据
d使用edx or dx ordl寄存器存放数据
S使用esi or si 寄存器存放数据,(esi寄存器是栈指针寄存器,也是一个通用寄存器)
D使用edi or di 寄存器存放数据
r使用任何闲暇的通用寄存器存放数据
q使用eax,ebx,ecx,edx其中之一存放数据
A使用eax 和 edx存放64位数据
f使用浮点数指针寄存器存放数据
t使用第一个浮点数指针寄存器存放数据
u使用第二个浮点数指针寄存器存放数据
m使用变量的内存地址
o使用偏移内存位置
V只使用直接内存的位置
i使用一个直接整数值
n使用一个已知的直接整数值
g使用任何空闲的寄存器或内存地址
修饰符描述
+操作数既可读也可写
=操作数只可以写
%如果需要,操作数可以与下一个操作数进行切换
&操作数可以在内联函数之前删除和重用

在这个需要注意的是,如果在内联汇编中需要用到寄存器的话,与AT&T语法中加%不同的是,要用两个%

Example2

int data1 = 10;
int data2 = 20;
int result;
asm ("addl %[i1], %[i2]\n\t"
         "movl %[i2], %[ret]"
    	: [ret]"=a"(result)
  		: [i1]"d"(data1), [i2]"c"(data2));
printf("%d\n",result);
return 0;
$> gcc main.c -o test
$>.\test
30

可以用,可以用一些标号来代替,如上所示

Example3

#include<stdio.h>
int main(){

    int data1 = 10;
    int data2 = 20;
    int result;
    asm ("imull %1, %2\n\t"
         "movl %2, %0"
    : "=r"(result)
    : "r"(data1), "r"(data2));
    printf("%d\n",result);
    return 0;
}

在这里0代表result1代表data12代表data2

Example4(定义宏函数)

比如将上面的加法封装成宏函数,也可以直接调用的

#include<stdio.h>

#define SUM(a, b, res){ \
__asm__("addl %%ebx, %%ecx\n\t"\
"movl %%ecx, %%eax"\
:"=a"(res):"b"(a),"c"(b));                 \
}

int main(){

    int data1 = 10;
    int data2 = 20;
    int result;
    SUM(data1, data2, result);
    printf("%d\n",result);
    return 0;
}
  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-11-30 15:24:34  更:2021-11-30 15:24:38 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 9:23:42-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码