汇编笔记

基本概念

机器语言(machinelanguage)是一种数字语言,专门设计成能被计算机处理器(CPU)理解。所有x86处理器都理解共同的机器语言。

汇编语言(assemblylanguage)包含用短助记符如ADD、MOV、SUB和CALL书写的语句。汇编语言与机器语言是一对一(one-to-one)的关系:每一条汇编语言指令对应一条机器语言指令。

汇编器(assembler)是一种工具程序,用于将汇编语言源程序转换为机器语言。

**常用的汇编编译器 **有MASM( Microsoft 宏汇编器)、TASM(Turbc汇编器),NASM(NetWide汇编器)和MASM32(MASM的一种变体)。GAS(GNU汇编器)和NASM是两种基于Linux的汇编器。在这些汇编器中,NASM的语法与MASM的最相似。

链接器(linker)是一种工具程序,它把汇编器生成的单个文件组合为一个可执行程序。

高级语言如Python、C++和Java与汇编语言和机器语言的关系是一对多(one-to-many)。比如,C++的一条语句就会扩展为多条汇编指
令或机器指令。

X86处理器

中央处理单元(CPU)处理算术和逻辑运算。它包含了有限数量的存储位置,即寄存器;一个高频时钟用于同步其操作;一个控制单元和一个算术逻辑单元。内存存储单元在计算机程序运行时,保存指令和数据。总线是一组并行线路,在计算机不同部件之间传输数据。

image-20230207141550992

32位x86处理器

基本程序运行寄存器由4类寄存器组成。具体包括8个通用寄存器,6个段寄存器,1个EFLAGS寄存器(标志寄存器)以及1个指令指针寄存器。

  • 通用寄存器主要用于算术运算、数据传输和逻辑操作。
  • 段寄存器存放预先分配的内存区域的基址,这些内存区域就是段。
  • 标志寄存器包含的独立二进制位用于控制CPU的操作,并反映ALU操作的结果。
  • 指令指针寄存器存放的是下一条要执行指令的地址。

其他寄存器还包括控制寄存器(CR0、CR1、CR2、CR3)、调试寄存器(DR0-DR7)、系统地址寄存器浮点寄存器等。

通用寄存器是一种通用型的寄存器,用于传送和暂存数据,也可参与算数逻辑运算,并保存计算结果。

寄存器 名称 32位 16位 高8位 低8位 主要用途
EAX 累加器 EAX AX AH AL 针对操作数和结果数据
EBX 基址寄存器 EBX BX BH BL DS段中的数据指针
ECX 计数器 ECX CX CH CL 字符串和循环操作
EDX 数据寄存器 EDX DX DH DL I/O指针
ESI 源变址寄存器 ESI SI - - 字符串操作源指针
EDI 字符串操作目标指针 EDI DI - - 字符串操作目标寄存器
EBP 扩展基址指针寄存器 EBP BP - - SS段中栈内数据指针
ESP 栈指针寄存器 ESP SP - - 栈指针寄存器

段寄存器 IA-32 的保护模式中,段是一种内存保护技术,它把内存划分为多个区段,并为每个区段赋予起始地址、范围、访问权限等,以保护内存。此外同分页技术一起用于将虚拟内存变更为实际物理内存。段内存记录在 SDT(Segment Descriptor Table,段描述符表)中,而段寄存器就持有这些 SDT 的索引。

寄存器 名称 用途
CS Code Segment 代码段寄存器
SS Stack Segment 栈段寄存器
DS Data Segment 数据段寄存器
ES Extra ( Data ) Segment 附加(数据)段寄存器
FS Data Segment 数据段寄存器
GS Data Segment 数据段寄存器

EFLAGS寄存器 包含了独立的二进制位,主要用于反映处理器的状态和ALU运算结果的某些特征及控制指令的执行。

标志位(外语缩写) 标志位名称 1 0
CF 进位标志 进位 无进位
PF 奇偶标志
AF 辅助进位标志 进位 无进位
ZF 零标志 等于零 不等于零
SF 符号标志 非负
TF 跟踪标志 单步工作方式 连续工作方式
IF 中断标志 允许 禁止
DF 方向标志 减少 增加
OF 溢出标志 溢出 未溢出

指令指针寄存器 EIP(Instruction Pointer),用于指向下一条要执行的指令。

64位x86-64处理器

x86-64处理器向下兼容x86指令集,且比x86处理器多了8个通用寄存器(R8到R15)。

x86-64通用寄存器RAX、RBX、RCX、RDX、RDI、RSI、RBP、RSP、R8、R9、R10、R11、R12、R13、R14、R15。

处理器架构

IA32和x86

IA-32为Intel Architecture 32bit简称,即英特尔32位体系架构,在英特尔公司1985年推出的80386微处理器中首先采用。通常也被称为i386、x86-32、x86等。

x86-64、x64、AMD64、Intel64

后来AMD推出了兼容32位的64位集关于IA-32的扩展,之后改名为AMD64,Intel后来也采用该架构,在其文档中称为Intel64。同时,该架构又被称为x86-64或者x64。

以上都属于x86架构,使用CISC(Complex Instruction Set Computer,复杂指令集计算机)。

其他主流cpu架构还包括ARMRISC-VMIPS

IA64是后来intel和惠普联合推出的64位体系架构,但是不兼容原有的32位体系结构的应用程序,导致市场惨淡。不属于x86架构。

汇编语言基础

1
2
3
4
5
6
7
8
9
10
11
12
13
14
;32位程序模板(Template.asm)
.386
.model flat, stdcall
.stack 4096
ExitProcess PROTO, dwExitCode:DWORD

.data
;在这里声明变量
.code
main PROC
;在这里编写自己的代码
INVOKE ExitProcess,0
main ENDP
END main

用汇编语言编写的源程序不能直接在其目标计算机上执行,必须通过汇编将其转换为可执行代码。汇编器生成包含机器语言的文件,称为目标文件(object file)。这个文件还没有准备好执行,它还需传递给一个被称为链接器(linker)的程序,从而生成可执行文件(executable file)。编辑、汇编、链接和执行汇编语言程序的过程,如下:、

  • 步骤1:编程者用编辑器创建一个ASCIl文本文件,称之为源文件。
  • 步骤2:汇编器读取源文件,并生成目标文件,即对程序的机器语言翻译。或者,它也会生成列表文件。只要出现任何错误,编程者就必须返回步骤1,修改程序。
  • 步骤3:链接器读取并检查目标文件,以便发现该程序是否包含了任何对链接库中过程的调用。链接器从链接库中复制任何被请求的过程,将它们与目标文件组合,以生成可执行文件。
  • 步骤4:操作系统加载程序将可执行文件读入内存,并使CPU分支到该程序起始地址,然后程序开始执行。

image-20230207160612066

列表文件(listingfile)包括了程序源文件的副本,再加上行号、每条指令的数字地址、每条指令的机器代码字节(十六进制)以及符号表。符号表中包含了程序中所有标识符的名称、段和相关信息。

传递参数

x86-32时,使用栈传递参数。程序中的参数会以从右往左的方向依次压入栈中。这也是方便出栈时,左边第一个参数最先出来。

x86-64时,前6个基础类型参数通过寄存器传递,第7个参数开始用栈传递。通过寄存器传递可减少压栈和弹栈开销,提升性能。具体来说,前6个参数分别通过寄存器rdi,rsi,rdx,rcx,r8和r9寄存器传递,剩下的参数,依次通过调用者的rsp+0,rsp+8,rsp+16,……,rsp+8^N 这些地址空间传递。

rdi rsi rdx rcx r8 r9 栈传递

在Windows 64位系统中,函数参数传递的顺序通常是按照以下规则:

  1. 整数和指针参数: 从左到右依次压入64位寄存器 RCX, RDX, R8, R9。如果参数超过4个或者是浮点数,则额外的参数通过栈传递。
  2. 浮点数参数: 浮点数参数通过 XMM0, XMM1, XMM2, XMM3 寄存器传递,超过4个或者是整数参数则通过栈传递。

这种参数传递顺序适用于大多数的函数调用约定(calling convention)在Windows x64系统上。

https://learn.microsoft.com/zh-cn/cpp/build/x64-calling-convention?view=msvc-170#parameter-passing

栈和栈桢

汇编中一般堆栈(stack)指的就是栈(stack),**区分堆(heap)、栈(stack)、堆栈(stack)**。

堆栈帧(stack frame)(或活动记录(activation record))是一块堆栈保留区域,用于保存被传递的实际参数、子程序的返回值、局部变量以及被保存的寄存器。

寄存器EBP指向当前的栈帧的底部,寄存器ESP指向当前的栈帧的顶部。

注意:EBP指向当前位于系统栈最上边一个栈帧的底部,而不是系统栈的底部。严格说来,“栈帧底部”和“栈底”是不同的概念;ESP所指的栈帧顶部和系统栈的顶部是同一个位置。

https://blog.csdn.net/melonyzzZ/article/details/127754271


汇编笔记
http://wangchenchina.github.io/2023/02/13/汇编笔记/
作者
Demo
发布于
2023年2月13日
许可协议