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

目录

        • 汇编语言基础
        • [x86 体系的寄存器说明](#x86 体系的寄存器说明)
        • [Intel 和 AT&T 语法](#Intel 和 AT&T 语法)
        • ["helloworld" 汇编程序分析](#"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 的高字节

同样的,其他的通用寄存器,也会与类似的用法:

描述 64bit 低32bit 0~16 bit 8~16 bit 0~8 bit
累加器 rxa eax ax ah al
基址寄存器 rbx ebx bx bl bh
程序计数器 rcx ecx cx cl ch
数据寄存器 rdx edx dx dl dh
  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 的汇编代码:

c 复制代码
  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
相关推荐
EterNity_TiMe_12 分钟前
【论文复现】(CLIP)文本也能和图像配对
python·学习·算法·性能优化·数据分析·clip
sanguine__16 分钟前
java学习-集合
学习
lxlyhwl16 分钟前
【STK学习】part2-星座-目标可见性与覆盖性分析
学习
nbsaas-boot17 分钟前
如何利用ChatGPT加速开发与学习:以BPMN编辑器为例
学习·chatgpt·编辑器
陌小呆^O^18 分钟前
Cmakelist.txt之win-c-udp-client
c语言·开发语言·udp
CV学术叫叫兽1 小时前
一站式学习:害虫识别与分类图像分割
学习·分类·数据挖掘
我们的五年1 小时前
【Linux课程学习】:进程程序替换,execl,execv,execlp,execvp,execve,execle,execvpe函数
linux·c++·学习
一棵开花的树,枝芽无限靠近你2 小时前
【PPTist】添加PPT模版
前端·学习·编辑器·html
VertexGeek2 小时前
Rust学习(八):异常处理和宏编程:
学习·算法·rust
二进制_博客2 小时前
Flink学习连载文章4-flink中的各种转换操作
大数据·学习·flink