C 语言学习(5) ---- 汇编语法基础

news2025/1/21 12:04:11

目录

        • 汇编语言基础
        • x86 体系的寄存器说明
        • Intel 和 AT&T 语法
        • "helloworld" 汇编程序分析
        • 指令和伪指令
        • TBD

汇编语言基础

汇编程序基本由 4 种类型的组件组成:指令(instruction)伪指令(directive)、标号(label)以及注释(comment)

类型示例含义
指令mov eax 0给 EAX 赋值为0
伪指令.section.text以下代码放入 text 节
伪指令.string "foobar"定义一个 ASCII 字符串 foobar
伪指令.long 0x12345678定义一个双字 0x12345678
标号foo:.string "foobar"使用符号定义的 foobar 字符串
注释#注释表示注释信息
x86 体系的寄存器说明

在 x86 架构的 CPU 中,存在多种可编程的寄存器,它们用于不同的目的,以下是一些主要的可编程寄存器类型:

  1. 通用寄存器
    • AX (累加器寄存器):用于算术运算和 I/O 指令。
    • BX (基址寄存器):用于存储数据指针。
    • CX (计数寄存器):通常用于循环计数。
    • DX (数据寄存器):用于 I/O 操作和其他数据传输。
    • SI (源索引寄存器)、DI (目的索引寄存器):用于字符串操作。
    • BP (基址指针寄存器):用于访问栈中的参数和局部变量。
    • SP (堆栈指针寄存器):用于管理堆栈。
    • AXBXCXDX 寄存器还可以分为高字节和低字节寄存器,例如 AHAL 分别是 AX 的高字节和低字节。

EAX 是一个32位的寄存器,用于处理 32 位的数据,而 AX 是一个 16 位的寄存器,用于处理 16 位的数据。
在32位模式下,AXEAX 的一个低位部分,可以直接用于 16 位数据的操作。

x86 基于原始的 8086 指令集,寄存器是16位宽,而32bit 的 x86 ISA 将这些寄存区扩展为32位,然后 x86-64 将它们进一步扩展为64位。
为了保证向后兼容性,新指令集中使用的寄存器是旧的寄存器的超集。

在汇编中指定寄存器的操作数,需要是以寄存器的名称,比如 mov rax,64 就是将 64 赋值给 rax 寄存器,
下图显示了如何将 x86-64 rax 寄存器分为传统的 32 位和 64 位寄存器,rax 的低32位形成了一个名位 eax 的寄存器,
其低16位形成了一个原始的 8086 寄存器 AX,读者可以通过寄存器名称 AL 访问 AX 的低字节,通过 AH 访问 AX 的高字节
AX寄存器分析
同样的,其他的通用寄存器,也会与类似的用法:

描述64bit低32bit0~16 bit8~16 bit0~8 bit
累加器rxaeaxaxahal
基址寄存器rbxebxbxblbh
程序计数器rcxecxcxclch
数据寄存器rdxedxdxdldh
  1. 段寄存器

    • CS (代码段寄存器):包含当前执行指令的段地址。
    • DS (数据段寄存器):包含数据段的段地址。
    • ES (附加段寄存器):用于额外的数据段。
    • FSGS:提供额外的段寄存器,由操作系统或应用程序定义。
    • SS (堆栈段寄存器):包含堆栈段的段地址。
  2. 指令指针寄存器

    • IP (指令指针寄存器):也称为 EIP(在 32 位模式下)或 RIP(在 64 位模式下),它指向下一条要执行的指令。
      本质上就是指针指针寄存器
  3. 标志寄存器

    • FLAGS (标志寄存器):包含各种状态标志,如进位、零、符号、溢出等。
  4. 控制寄存器

    • CR0 - CR4:用于控制处理器的操作模式和特性,如分页、保护模式等。
  5. 系统寄存器

    • MSR (模型特定寄存器):提供对处理器特定功能的访问,如性能监控计数器。
  6. 浮点寄存器

    • ST0 - ST7 (浮点堆栈寄存器):用于浮点运算。
    • Control WordStatus WordTag WordInstruction PointerLast Instruction Opcode:用于控制浮点单元的操作和报告状态。
  7. SIMD 寄存器

    • MMX 寄存器:用于多媒体扩展运算。
    • XMM0 - XMM15 (SSE 寄存器):用于 SIMD 扩展运算。
    • YMM0 - YMM15 (AVX 寄存器):在 AVX 指令集中使用,提供更大的 SIMD 数据宽度。
      这些寄存器在不同的 x86 处理器模式下(实模式、保护模式、长模式等)可能会有不同的名称和大小。
      例如,在 32 位模式下,通用寄存器通常有 32 位宽,而在 64 位模式下,它们会扩展到 64 位宽。
Intel 和 AT&T 语法

正如前面所提到的,不同的汇编器对汇编程序有不同的语法,表示 x86 机器指令的语法格式主要有两种:Intel 语法 和 AT&T 语法,
AT&T 语法显式的再每个寄存器名称前面加上 % 符号,每个常量前面加上$ 符号, Intel 语法没有这种格式:

AT&TIntel之间最重要的区别是使用完全相反的指令操作数顺序:
AT&T语法中源操作数在目的操作数前面,所以是从左向右读
Intel语法中目的操作数位于源操作数前面,所以是从右向左读
如果汇编语言中出现 % 和 $ 前缀,就是使用AT&T语法,应该从左向右读

“helloworld” 汇编程序分析

helloworld 的汇编代码:

  1         .file   "main.c"
  2         .text
  3         .section        .rodata
  4 .LC0:
  5         .string "hello world"
  6         .text
  7         .globl  main
  8         .type   main, @function
  9 main:
 10 .LFB0:
 11         .cfi_startproc
 12         endbr64
 13         pushq   %rbp
 14         .cfi_def_cfa_offset 16
 15         .cfi_offset 6, -16
 16         movq    %rsp, %rbp
 17         .cfi_def_cfa_register 6
 18         leaq    .LC0(%rip), %rdi
 19         call    puts@PLT
 20         movl    $0, %eax
 21         popq    %rbp
 22         .cfi_def_cfa 7, 8
 23         ret
 24         .cfi_endproc
 25 .LFE0:
 26         .size   main, .-main
 27         .ident  "GCC: (Ubuntu 9.5.0-1ubuntu1~22.04) 9.5.0"
 28         .section        .note.GNU-stack,"",@progbits
 29         .section        .note.gnu.property,"a"
 30         .align 8
 31         .long    1f - 0f
 32         .long    4f - 1f
 33         .long    5
 34 0:
 35         .string  "GNU"
 36 1:
 37         .align 8
 38         .long    0xc0000002
 39         .long    3f - 2f
 40 2:
 41         .long    0x3
 42 3:
 43         .align 8
 44 4:

从中可以看出:

  • printf 函数最终是调用到 puts 执行打印 helloworld 的操作
  • main 函数的返回值是通过 EAX 传递的
  • 函数执行时会将当前 rbp 寄存器的值压入到堆栈中,然后将当前开辟的 rsp的值赋给它
  • 函数执行结束会弹出 rbp 寄存器的值
指令和伪指令

指令是 CPU 执行的实际操作,伪指令意在告诉汇编工具生成特定的数据,并将指令和数据放在指定的节,
标号是汇编工具中引用指令或数据的符号名称,注释是可读注释。在程序被汇编链接成二进制程序后,所有的符号名称都被地址所取代

伪指令:
.section 告诉汇编工具将在那个节放置后面的内容,
.ascii 表示定义 ascii 字符串的伪指令,当前还有一些伪指令用于定义其他数据类型:
.byte 一个字节
.word 两个字节
.long 四个字节
.quad 八个字节

TBD

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

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

相关文章

Python在指定文件夹下创建虚拟环境

基于不同python版本和第三方包版本开发的项目,为了方便学习和管理python环境,可以在指定的文件夹里创建项目所需的虚拟环境。具体流程如下: (1) 以管理员身份打开Ananconda Prompt,查看当前虚拟环境,输入命令如下&…

C#中的Modbus协议

协议介绍 关于Modbus协议: Modbus协议是MODICON(莫迪康)(现施耐德品牌)在1979年开发的,是全球第一个真正用于现场的总线协议;Modbus协议是应用于电子控制器上的一种通用语言。通过此协议&…

一、报名与安装软件

声明 首先声明这个考试是需要费用的,目前我缴纳的费用是980元 官网 报名与学习官网为:https://cloud.aigccert.com/web/index 选择此处,点击报名后按要求完善个人信息。 完善个人信息后可以开始学习视频,视频内容看起来多其实…

Servlet开发流程 (里面有Idea项目添加Tomcat依赖详细教程)

目标: 校验注册时,用户名是否被占用。通过客户端向一个Servlet发送请求,携带username,如果用户 名是zhangsan,则向客户端响应 NO,如果是其他,响应YES。 1.在idea中创建web工程 1右键点击父工程-New-Module …

【MySQL 01】在 Ubuntu 22.04 环境下安装 MySQL

文章目录 🌈 1. 说明🌈 2. 卸载不必要的环境🌈 3. 安装 MySQL🌈 4. 启动和关闭 MySQL 服务🌈 5. 临时登录 MySQL🌈 6. 设置 MySQL 密码🌈 7. 配置 MySQL 🌈 1. 说明 在安装与卸载中…

此卷不包含可识别的文件系统‘及高效数据恢复策略

在数字信息的海洋中遨游时,我们偶尔会遭遇“此卷不包含可识别的文件系统”这一突如其来的警示,它像是一道无形的屏障,阻挡了我们与宝贵数据之间的直接联系。这一错误提示,往往意味着存储设备的文件系统结构出现了异常,…

嵌入式全栈开发学习笔记---数据结构概述

目录 入门级概念 什么是数据结构? 什么是算法?算法和数据结构有什么联系? 为什么要学习数据结构? 逻辑结构 线性结构(嵌入式领域的重点) 树形结构 图形结构 线性结构(嵌入式领域的重点…

【书生大模型实战营(暑假场)】入门任务二 Git 关卡

入门任务二 Git 关卡 参考: 教程任务 1 闯关任务 1.1 使用 Git 完成破冰介绍 本任务将基于开发机实现,重点在于熟悉Git操作。首先要了解 Git操作的常见四部曲,即:舔 Add,提 Commit,拉 Pull&#xff0c…

架构师知识梳理(一):计算机硬件

目录 计算机硬件组成 CPU CPU的组成 CPU的功能 校验码 奇偶校验 CRC CRC计算案例 指令 指令指行过程 指令系统 指令系统分类 指令流水线技术 流水线技术相关计算公式 存储 计算机存储系统设计 高速缓存Cache 缓存的局部性原理 地址映射 替换算法 关于命中…

2024华数杯数学建模竞赛选题建议+初步分析

提示&#xff1a;DS C君认为的难度&#xff1a;C<A<B&#xff0c;开放度&#xff1a;A<B<C。 综合评价来看 A题适合对机械臂和机器人运动学感兴趣的同学&#xff0c;尤其是有一定编程和优化算法基础的同学。不建议非相关专业同学选择。 B题挑战较大&#xff0…

红黑树的概念及应用

参考文章&#xff1a;红黑树c实现 一.红黑树是什么 红黑树是一种自平衡二叉查找树&#xff0c;是计算机科学领域中的一种数据结构&#xff0c;典型的用途是实现关联数组&#xff0c;存储有序的数据。它可以在O(logn)时间内做查找&#xff0c;插入和删除&#xff0c;这里的n是树…

Docker Remote API 未授权访问漏洞

Docker Remote API 未授权访问漏洞 Docker是一个开源的应用容器引擎&#xff0c;让开发者可以打包他们的应用以及依赖包到一个可移植的容器中&#xff0c;然后发布到任何流行的LINUX机器上&#xff0c;也可以实现虚拟化。 Docker swarm 是一个将docker集群变成单一虚拟的docker…

LeetCode刷题笔记 | 643 | 子数组最大平均数 | 双指针 | 滑动窗口 | 数组 | Java | 详细注释 | 三种解法

&#x1f64b;大家好&#xff01;我是毛毛张! &#x1f308;个人首页&#xff1a; 神马都会亿点点的毛毛张 双指针在一定条件下可以转化成滑动窗口&#xff0c;这道题就是个很好的例子 LeetCode链接&#xff1a;643. 子数组最大平均数 I 1.题目描述 给你一个由 n 个元素组成…

SpringMVC 工作流程简述

SpringMVC 工作流程简述 1. 请求接收2. 请求解析3. 查找处理器4. 处理器适配5. 调用处理器6. 处理结果7. 结果传递8. 视图解析9. 视图渲染10. 响应用户 &#x1f496;The Begin&#x1f496;点点关注&#xff0c;收藏不迷路&#x1f496; #mermaid-svg-xZqkXNPjG0SH5tMA {font-…

经典算法KMP讲解,包含C++解法ACM模式

写在前面&#xff1a;一个人能走的多远不在于他在顺境时能走的多快&#xff0c;而在于他在逆境时多久能找到曾经的自己。——KMP 讲解前置知识模拟next的构建匹配思路匹配字符串构建next数组 模板代码 题目一&#xff1a;KMP字符串题目二&#xff1a;找出字符串中第一个匹配项的…

电脑开机启动项管理小工具,绿色免安装

HiBit Startup Manager 是一款功能强大的启动项管理工具&#xff0c;旨在帮助用户管理和优化计算机的自动启动程序。该软件通过添加或删除应用程序、编辑它们的属性以及管理流程、服务、任务调度程序和上下文菜单来实现这一目标。 HiBit Startup Manager 提供了以下主要功能&a…

Day82 代码随想录打卡|贪心算法篇---K次取反后最大化的数组和

题目&#xff08;leecode T1005&#xff09;&#xff1a; 给你一个整数数组 nums 和一个整数 k &#xff0c;按以下方法修改该数组&#xff1a; 选择某个下标 i 并将 nums[i] 替换为 -nums[i] 。 重复这个过程恰好 k 次。可以多次选择同一个下标 i 。 以这种方式修改数组后…

【C++】第一讲:入门概论

个人主页&#xff1a; 深情秋刀鱼-CSDN博客 C专栏&#xff1a;C程序设计 一、C发展历史 C的起源可以追溯到1979年&#xff0c;当时Bjarne Stroustrup(本贾尼斯特劳斯特卢普&#xff0c;这个翻译的名字不 同的地⽅可能有差异)在⻉尔实验室从事计算机科学和软件⼯程的研究⼯作。…

Linux中NFS配置

文章目录 一、NFS介绍1.1、NFS的工作流程1.2、NFS主要涉及的软件包1.3、NFS的主要配置文件 二、安装NFS2.1、更新yum2.2、安装NFS服务2.3、配置NFS服务器2.4、启动NFS服务2.5、配置防火墙&#xff08;如果启用了防火墙&#xff0c;需要允许NFS相关的端口通过&#xff09;2.6、生…

最新版Sonible Plugins Bundle v2024 winmac,简单智能,持续更新长期有效

一。Sonible Plugins Bundle v2024 win&mac Sonible Plugins Bundle是一款以创作者为中心的智能音频插件系列。这些工具的特点是易于使用&#xff0c;搭配高级处理和优质音质。pure:bundle的所有插件都由sonible的智能插件系列中使用的技术驱动&#xff0c;但在设计时考虑到…