C语言内嵌汇编

news2024/10/7 12:23:40

反编译(二进制文件或者so库)

objdump --help
objdump -M intel -j .text -ld -C -S  out > out.txt #显示源代码同时显示行号, 代码段反汇编
		-M intel 英特尔语法
		-M x86-64
		-C:将C++符号名逆向解析
		-S 反汇编的同时,将反汇编代码和源代码交替显示
		-l 插入源文件名和行号
		-d 将代码段反汇编
		-j section:仅反汇编指定的section


一、基础内联汇编:

单个%前缀修饰寄存器
立即数都有 ‘$’ 前缀。如 “movl $78, %1 \n”
以 ‘b’、‘w’ 和 ‘l’ 为后缀指明内存访问长度是:movb movl
基址寄存器是放在小括号 () 内的。例:section: disp(base, index, scale)

二、扩展内联汇编:

两个%前缀修饰寄存器, 单个 % 前缀修饰操作数

 语法:
	`asm` [`volatile`] ( 
	汇编程序
	: 输出
	: 输入
	: 寄存器列表
	);

__asm__ 等同于  asm 
__volatile__ 等同于 volatile

示例 参考:https://blog.csdn.net/lwx62/article/details/82796364

#include <iostream>
using namespace std;

int main11(int argc, char*argv[])
{
    int a=10, b;
    asm ("movl %1, %%eax;"
         "movl %%eax, %0;"
        :"=b"(b)        /* output */
        :"c"(a)         /* input */
        :"%eax"         /* clobbered register */
        );

    int count = 1;
    char *str = "hello world!\n";
    asm("int $0x80"
        : "=a"(count)
        : "a"(5), "b"(1), "c"(str), "d"(13));

    int var = 100;
    asm ("incl %0" :"=a"(var):"0"(var)); //+1
    asm ("decl %0" :"=a"(var):"0"(var)); //-1
    //asm ("sidt %0\n" : :"m"(var));

    cout << var << endl;
    return 0;
}

int main22()
{
    int foo = 10, bar = 15;
    __asm__ __volatile__("addl  %%ebx,%%eax"
                         :"=a"(foo)
                         :"a"(foo), "b"(bar)
                         );
    printf("foo+bar=%d\n", foo);
    return 0;
}


int main33()
{
    int my_var = 10;
    int my_int = 20;
    int foo = 10, bar = 15;
    __asm__ __volatile__(
        "   lock       ;\n"
        "   subl %1,%0 ;\n"
        : "=m"  (my_var)
        : "ir"  (my_int), "m" (my_var)
        :
        );
    cout << "my_var-my_int=:" << my_var << endl;
    cout << "my_int:" << my_int << endl;
    return 0;
}

static inline char * _strcpy(char * dest,const char *src)
{
	int d0, d1, d2;
	__asm__ __volatile__(  "1:\tlodsb\n\t"
		                   "stosb\n\t"
		                   "testb %%al,%%al\n\t"
		                   "jne 1b"
		                 : "=&S"(d0), "=&D"(d1), "=&a"(d2)
		                 : "0" (src), "1" (dest) 
		                 : "memory");
	//lodsb:load string; 
	//stosb:store string;
	//testb:就是test测试检查src/dst是否一致
	//约束“&S”,“&D”,“&a”表示寄存器esi,edi和eax, 
	//是early clobber寄存器,即它们的内容将在函数完成之前改变
	//jne:判断上一步结果是否等于0,如果不等于0,则ZF=0,则进行跳转
	//1b: 表示 backward 向前跳转,1表示局部标签1
	//1f: 表示 forward 向后跳转

	return dest;
}

int main()
{
    int a = 1;
    int b = 2;
    asm("movl %%eax,%1" ::"a"(a), "m"(b));
    cout << b << endl;
    
    int var = 100;
    asm ("incl %0" :"=a"(var):"0"(var));  //自+1
    asm ("decl %0" :"=a"(var):"0"(var));  //自-1
    
    //
    const char* s1="hello ASM";

    char buf[1024]={0};
    _strcpy(buf,s1);
    cout << " s1:" << s1 << endl;
    cout << "buf:" << buf << endl;
}

/*
%0、%1 ... %9 它们依次代表 10 个操作数
a:表示寄存器eax
b:表示寄存器ebx
c:表示寄存器ecx
d:表示寄存器edx
D:表示寄存器edi
S:表示寄存器esi
q:表示以下任意四个寄存器之一:eax/ebx/ecx/edx
r:表示任意六个通用寄存器之一:eax/ebx/ecx/edx/edi/esi
g:表示可以存放到任意地点
A:把eax和edx组合成64位数
f:表示浮点寄存器
t:表示第一个浮点寄存器
u:表示第二个浮点寄存器

m:操作数内存
o:偏移量访问

*/

32位前缀 E
64位前缀 R
在这里插入图片描述

两家汇编主要区别

Intel CodeAT&T Code
mov eax,1movl $1,%eax
mov ebx,0ffhmovl $0xff,%ebx
int 80hint $0x80
mov ebx, eaxmovl %eax, %ebx
mov eax,[ecx]movl (%ecx),%eax
mov eax,[ebx+3]movl 3(%ebx),%eax
mov eax,[ebx+20h]movl 0x20(%ebx),%eax
add eax,[ebx+ecx*2h]addl (%ebx,%ecx,0x2),%eax
lea eax,[ebx+ecx]leal (%ebx,%ecx),%eax
sub eax,[ebx+ecx*4h-20h]subl -0x20(%ebx,%ecx,0x4),%eax

CPU 一般规则:

eax: 执行加法,函数返回值
ebx: 数据存取
ecx: 计数器
edx: 读写I/O端口时,edx用来存放端口号
esp: 栈顶指针
ebp: 栈底指针,ebp+偏移量 来定位 栈中变量
esi: 字符串操作时,用于存放数据源的地址
edi: 字符串操作时,用于存放目的地址的

寄存器常识

通用寄存器:r8-r15

标志寄存器
	CF 进位标志
	PF 奇偶标志
	ZF 零标志
	SF 符号标志
	OF 补码溢出标志
	TF 跟踪标志
	IF 中断标志
	...
指令寄存器
段寄存器

控制寄存器
	int3软中断指令,向量号为3
	32位:cr0-cr4
	    cr0: CPU控制标记和工作状态
	    cr1: 保留未使用
	    cr2: 页错误出现时保存导致出错的地址
	    cr3: 当前进程的虚拟地址空间的重要信息:页目录地址
	    cr4: 也存储了CPU工作相关以及当前人任务的一些信息
	64位:cr8

调试寄存器
	8个:DR0~DR7

描述符寄存器
	全局描述符表GDT(Global Descriptor Table):
		一级描述符表,一个处理器对应一个GDT,GDT可以被放在内存的任何位置,但CPU必须知道GDT的入口
		LGDT和SGDT分别用于加载和保存GDTR寄存器的内容
	
	局部描述符表LDT(Local Descriptor Table):
		二级描述符表,有若干张,每个任务一张;LDTR可以在程序中随时改变,通过使用lldt指令
		由于每个进程都有自己的一套程序段、数据段、堆栈段,有了局部描述符表,
		则可以将每个进程的程序段、数据段、堆栈段封装在一起,只要改变LDTR就可以实现对不同进程的段进行访问
	
	中断描述符表寄存器IDTR:LIDT和SIDT分别用于加载和保存IDTR寄存器的内容

任务寄存器TR:
	用于寻址一个特殊的任务状态段(Task State Segment,TSS)指令LTR和STR分别用于加载和保存TR寄存器的段选择符部分

MSR寄存器

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

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

相关文章

C++利用mutex和thread实现一个死锁

程序 #include<iostream> #include<mutex> #include<thread> using namespace std; mutex mtx1; mutex mtx2; void A(){mtx1.lock();cout<<"a:mtx1"<<endl;this_thread::sleep_for(chrono::milliseconds(1000));mtx2.lock();cout<…

《Java-SE-第三十一章》之网络编程

前言 在你立足处深挖下去,就会有泉水涌出!别管蒙昧者们叫嚷:“下边永远是地狱!” 博客主页&#xff1a;KC老衲爱尼姑的博客主页 博主的github&#xff0c;平常所写代码皆在于此 共勉&#xff1a;talk is cheap, show me the code 作者是爪哇岛的新手&#xff0c;水平很有限&…

右值引用与移动语义与完美转发

右值引用 右值 什么是右值&#xff0c;没有地址临时数据的我们称之为右值 我们无法对10、aa、字符串取地址的值我们称之为右值。因为他们是临时数据&#xff0c;并不保存再内存中&#xff0c;所以我们右值没有地址&#xff0c;也无法被赋值&#xff08;除const外&#xff0c;左…

【Elasticsearch】学好Elasticsearch系列-分词器

本文已收录至Github&#xff0c;推荐阅读 &#x1f449; Java随想录 先看后赞&#xff0c;养成习惯。 点赞收藏&#xff0c;人生辉煌。 文章目录 规范化&#xff1a;normalization字符过滤器&#xff1a;character filterHTML Strip Character FilterMapping Character FilterP…

IMV6.0

一、背景 经历了多个版本&#xff0c;基础内容在前面&#xff0c;可以使用之前的基础环境&#xff1a; v1&#xff1a; https://blog.csdn.net/wtt234/article/details/132139454 v2&#xff1a; https://blog.csdn.net/wtt234/article/details/132144907 v3&#xff1a; https…

vue实现pdf预览功能

背景&#xff1a;材料上传之后点击预览实现在浏览器上预览的效果 效果如下&#xff1a; 实现代码如下&#xff1a; //预览和下载操作 <el-table-column fixed"right" label"操作" width"210"><template #default"scope">…

JAVA Android 正则表达式

正则表达式 正则表达式是对字符串执行模式匹配的技术。 正则表达式匹配流程 private void RegTheory() {// 正则表达式String content "1998年12月8日&#xff0c;第二代Java平台的企业版J2EE发布。1999年6月&#xff0c;Sun公司发布了第二代Java平台(简称为Java2) &qu…

每次执行@Test方法前都执行一次DB初始化(SpringBoot Test + JUnit5环境)

引言 在执行单元测试时&#xff0c;可以使用诸如H2内存数据库替代线上的Mysql数据库等&#xff0c;如此在执行单元测试时就能尽可能模拟真实环境的SQL执行&#xff0c;同时也无需依赖线上数据库&#xff0c;增加了测试用例执行环境的可移植性。而使用H2数据库时&#xff0c;通…

Node.js |(二)Node.js API:fs模块 | 尚硅谷2023版Node.js零基础视频教程

学习视频&#xff1a;尚硅谷2023版Node.js零基础视频教程&#xff0c;nodejs新手到高手 文章目录 &#x1f4da;文件写入&#x1f407;writeFile 异步写入&#x1f407;writeFileSync 同步写入&#x1f407;appendFile / appendFileSync 追加写入&#x1f407;createWriteStrea…

点成分享丨qPCR仪的原理与使用——以Novacyt产品为例

近年来&#xff0c;PCR检测在多种领域发挥着巨大的作用。短时高效和即时监测都成为了PCR仪发展的方向。作为世界领先的制造商之一&#xff0c;Novacyt公司为来自全球多个国家和行业的用户提供了优质的qPCR仪。 MyGo Mini S qPCR仪是一种紧凑型的实时qPCR仪&#xff0c;非常适合…

【算法|双指针系列No.1】leetcode283. 移动零

个人主页&#xff1a;平行线也会相交 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 平行线也会相交 原创 收录于专栏【手撕算法系列专栏】【LeetCode】 &#x1f354;本专栏旨在提高自己算法能力的同时&#xff0c;记录一下自己的学习过程&#xff0c;希望…

c++进阶--二叉搜索树

目录 前言 一、二叉搜索树 1.二叉搜索树概念 2.二叉搜索树操作 二、二叉搜索树实现 0.定义一个节点 1.定义一棵树 2.增删改查 2.1.查找 2.2.插入 2.3.删除 2.3.1非递归删除法 a.只有左孩子 -- 删除14 b.只有右孩子-- 删除10 c.有左右孩子--删除8 2.3.2递归删除…

【论文总结】Chatting with GPT-3 for Zero-Shot Human-Like Mobile Automated GUI Testing

与GPT-3对话进行零尝试人类化移动自动化GUI测试 摘要&#xff1a; 移动应用在人们的日常生活中变得不可或缺&#xff0c;而自动化图形用户界面&#xff08;Graphical User Interface&#xff0c;GUI&#xff09;测试广泛用于应用程序质量保证。对于自动化GUI测试&#xff0c;越…

rv1126更新rknpu驱动教学

测试平台&#xff1a;易佰纳rv1126 38板 查看板端版本-------------------------------------------------- 1&#xff1a;查看npu驱动版本 dmesg | grep -i galcore&#xff0c;可以看到版本为6.4.3.5 2&#xff1a;查看rknn-server版本 strings /usr/bin/rknn_server | g…

新能源电动车充电桩控制主板的材料选择

新能源电动车充电桩控制主板的材料选择 你是否想过&#xff0c;汽车充电桩控制主板的材料选择竟然还有这么多讲究?不再只是简单的充电问题&#xff0c;而是涉及到耐高温、耐高压、耐腐蚀、耐潮湿、耐油污、低热耗等方方面面。 首先&#xff0c;安全性是材料选择的首要考虑因素…

mysql自增主键不连续情况分析

1.唯一键冲突 比如increnment_test中已经存在了co1为3的记录,当再插入col1为3的记录时,就会出现主键不唯一错误,但此时自增主键已经1,所以会发生主键不连续情况 DROP TABLE IF EXISTS increnment_test; CREATE TABLE increnment_test (id int(0) NOT NULL AUTO_INCREMENT,col…

svg使用技巧

什么是svg SVG 是一种基于 XML 语法的图像格式&#xff0c;全称是可缩放矢量图&#xff08;Scalable Vector Graphics&#xff09;。其他图像格式都是基于像素处理的&#xff0c;SVG 则是属于对图像的形状描述&#xff0c;所以它本质上是文本文件&#xff0c;体积较小&#xf…

Python-OpenCV中的图像处理

Python-OpenCV中的图像处理 颜色空间转换物体跟踪获取HSV的值几何变换图像缩放图像平移图像旋转仿射变换透视变换 图像阈值单阈值自适应阈值Otsus二值化 颜色空间转换 在 OpenCV 中有超过 150 中进行颜色空间转换的方法。但是你以后就会 发现我们经常用到的也就两种&#xff1…

ZMQ发布订阅模式二次封装

ZeroMQ 参考ZMQ从入门到掌握一 ZeroMQ是一种基于消息队列的多线程网络库&#xff0c;其对套接字类型、连接处理、帧、甚至路由的底层细节进行抽象&#xff0c;提供跨越多种传输协议的套接字。ZeroMQ 并不是一个对 socket 的封装&#xff0c;不能用它去实现已有的网络协议。它有…

加密、解密、编码

urlencode urlencode_百度百科 Base64是一种二进制到文本的编码方式&#xff0c;而且编码出的字符串只包含ASCII基础字符 下图是Base64码表&#xff0c;可以看到从0到63的每个数字都对应一个上面的一个字符。 文件-base64字符串互转 sun.misc包中的类 try (FileOutputStre…