C语言内嵌汇编

这篇具有很好参考价值的文章主要介绍了C语言内嵌汇编。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

反编译(二进制文件或者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文章来源地址https://www.toymoban.com/news/detail-636462.html

两家汇编主要区别

Intel Code AT&T Code
mov eax,1 movl $1,%eax
mov ebx,0ffh movl $0xff,%ebx
int 80h int $0x80
mov ebx, eax movl %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寄存器

到了这里,关于C语言内嵌汇编的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 汇编语言笔记(一)——汇编语言基础

    一、开发环境 我使用visual studio 2022 preview,其他版本的设置大同小异。 第一步: 打开visual studio,点击“创建新项目”: 第二步: visual studio并没有专门的汇编项目,所以需要挂羊头卖狗肉,选择C++空项目 第三步: 输入项目名称,点击创建 第四步: 鼠标右键单击项目名称—

    2024年02月05日
    浏览(30)
  • 汇编语言—常见汇编指令汇总

    mov    寄存器 ,数据                如:mov ax ,8 mov   寄存器,寄存器              如:mov ax,bx mov   寄存器,内存单元          如:mov ax,[0] mov   内存单元,寄存器          如:mov [0],ax mov   段寄存器,寄存器          如:mov ds,ax add   寄存器,数据

    2024年02月10日
    浏览(28)
  • Alpaca-cpp(羊驼-cpp): 可以本地运行的 Alpaca 大语言模型

    Stanford Alpaca (羊驼):ChatGPT 学术版开源实现 Alpaca-Lora (羊驼-Lora): 轻量级 ChatGPT 的开源实现(对标 Standford Alpaca) I know。这几天介绍了很多 Alpaca,各种羊驼,似乎有些随心所欲、杂乱无章。但实际上,正如《寒战》中梁家辉饰演的李文斌被廉政公署问话时所说:“要在(每一个

    2023年04月24日
    浏览(46)
  • 低级语言汇编真的各个面不如汇编吗?

    今日话题,低级语言汇编真的各个面不如C语言吗?C语言因其可移植性、开发效率和可读性而在各领域广泛使用,市场占有率极高。然而,汇编语言在特定场景下仍然具有独特优势,稳固地占据一席之地。如果你对这方面感兴趣,我可以分享一套包含各类语言和嵌入式行业教

    2024年02月06日
    浏览(31)
  • 5.8 汇编语言:汇编高效除法运算

    通常情况下计算除法会使用 div/idiv 这两条指令,该指令分别用于计算无符号和有符号除法运算,但除法运算所需要耗费的时间非常多,大概需要比乘法运算多消耗10倍的CPU时钟,在Debug模式下,除法运算不会被优化,但Release模式下,除法运算指令会被特定的算法经过优化后转

    2024年02月11日
    浏览(32)
  • 5.7 汇编语言:汇编高效乘法运算

    乘法指令是一种在CPU中实现的基本算术操作,用于计算两个数的乘积。在汇编语言中,乘法指令通常是通过 mul(无符号乘法) 和 imul(有符号乘法) 这两个指令实现的。由于乘法指令在执行时所消耗的时钟周期较多,所以编译器在优化代码时通常会尝试将乘法操作转换为更

    2024年02月11日
    浏览(21)
  • 5.6 汇编语言:汇编高效数组寻址

    数组和指针都是用来处理内存地址的操作,二者在C语言中可以互换使用。数组是相同数据类型的一组集合,这些数据在内存中是连续存储的,在C语言中可以定义一维、二维、甚至多维数组。多维数组在内存中也是连续存储的,只是数据的组织方式不同。在汇编语言中,实现

    2024年02月11日
    浏览(31)
  • 5.10 汇编语言:汇编过程与结构

    过程的实现离不开堆栈的应用,堆栈是一种后进先出 (LIFO) 的数据结构,最后压入栈的值总是最先被弹出,而新数值在执行压栈时总是被压入到栈的最顶端,栈主要功能是暂时存放数据和地址,通常用来保护断点和现场。 栈是由 CPU 管理的线性内存数组,它使用两个寄存器 (S

    2024年02月11日
    浏览(28)
  • 汇编语言第一讲:计算机的组织架构和汇编语言介绍

    第一讲:计算机的组织架构和汇编语言介绍 汇编语言 计算机组织架构 数字电路 术语回顾 数制 数字电路 硬件电路 数字电路的问题 汇编语言的开始 程序的节(sections) 调用操作系统的系统调用 列出文件(Listing files) 汇编和链接 调试汇编程序 反汇编现有的程序 附录 课程资源

    2024年04月09日
    浏览(37)
  • 南京邮电大学汇编语言程序设计实验一(汇编语言语法练习与代码转换)

    排除语法错误:给出的是一个通过比较法完成8位二进制数转换成十进制数送屏幕显示功能的汇编语言源程序,但有很多语法错误。要求实验者按照原样对源程序进行编辑,汇编后,根据TASM给出的信息对源程序进行修改,知道没有语法错误为止。然后进行链接,并执行相应可

    2024年02月08日
    浏览(45)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包