CPU指令集(CPU微处理器架构)分为x86以及ARM
ASM(assembly language):汇编语言
在运行 Microsoft Windows 的 x86 系统中,其他一些有名的汇编器包括:TASM(Turbo 汇编器),NASM(Netwide 汇编器)和 MASM32(MASM 的一种变体)。GAS(GNU 汇编器)和 NASM 是两种基于 Linux 的汇编器。在这些汇编器中,NASM 的语法与 MASM 的最相似。
32 位保护模式(32-Bit Protected Mode):32 位保护模式程序运行于所有的 32 位和 64 位版本的 Microsoft Windows 系统。它们通常比实模式程序更容易编写和理解。从现在开始,将其简称为 32 位模式。
64 位模式(64-Bit Mode):64 位程序运行于所有的 64 位版本 Microsoft Windows 系统。
16 位实地址模式(16-Bit Real-Address Mode):16 位程序运行于 32 位版本 Windows 和嵌入式系统。 64 位 Windows 不支持这类程序。
汇编语言与机器语言是一对一(one-to-one)的关系:每一条汇编语言指令对应一条机器语言指令。
x86可以再两种操作模式下运行:实模式 和保护模式
x86通过一种环级别(ring level)的抽象来支持特权隔离。处理器支持4种特权级别,编号为0到3(通常不使用ring1和ring2,所以不讨论)
因此现代操作系统通常将用户模式应用程序运行在ring3级别,内核运行在ring0级别,以此实现用户/内核特权隔离,ring级别编码于CS寄存器
x86独有的,支持INC或ADD指令,让内存地址中的某个数递增
Intel
mov ecx , AABBCCDDh mov ecx , [eax] mov ecx , eax
AT&T
movl $0xAABBCCDD , %ecx movl (%eax) , %ecx movl %eax , %ecx
x86使用[]标识内存地址,LEA指令也使用[],但不一定指内存 ,LEA不访问内存 。
转化为C伪码
dword (double word)双字 就是四个字节 ptr pointer缩写 即指针 []里的数据是一个地址值,这个地址指向一个双字型数据 比如mov eax, dword ptr [12345678] 把内存地址12345678中的双字型(32位)数据赋给eax
C语言实现strlen()
通用寄存器名
作用
EAX(双字)
EBX(双字)
ECX(双字)
循环计数
EDX
EDI
字符串/内存操作的目标
ESI
字符串/内存操作的源
EBP
帧基指针
ESP
栈指针
其他寄存器
作用
EIP
存储指令指针,存储CPU当前要运行的内存地址
EFLAGS
用于存储算术运算状态以及其他运行状态(比如陷阱标志位DF)
CR0
控制分页机制的开关
CR2
保存着导致缺页异常发生的线性地址
CR3
分页数据结构的基地址
CR4
控制硬件虚拟化设置
DR0~DR7
用于设置内存断电,其中系统只支持4个内存断电(DR0~DR3),其余寄存器用于保存状态
指令
作用
MOVSB/MOVSW/MOVSD
指令分别以1字节,2字节或4字节为单位,在两个内存地址之间移动数据
SCAS(B/W/D)
SCAS指令隐式地把(当指令为SCASB/SCASW/SCASD时)AL/AX/EAX的数值与地址为EDI的内存数值比较。根据EFLAGS中DF标志位的不同,EDI自动递增或递减。
REP
重复执行目标指令n次,比如:rep movsd ;复制4n字节(重复n次movsd),找ECX,每循环一次,ECX值减一,满足条件ECX>0
LEA
repne(repeat no equal)
不相等时重复(零标志位)ZF=0且ECX>0进行重复
repe(repeat equal)
相等是时候重复(零标志位)ZF=1且ECX>0进行重复
MUL(无符号)
只允许后面有一个操作数,比如:mul ebx ;将ebx的值与eax的值相乘,若结果存不下,则扩展为EDX:EAX。乘法运算,寄存器值与AL、AX或EAX值相乘,结果存储于AX、DX:AX或EDX:EAX 例如:mul ecx ;EDX:EAX=EAX*ECX
DIV(无符号)
只允许后面有一个操作数,比如:div ebx ;将EAX / EBX 的商放入EAX,余数放入EDX。计算得到的商和余数存储在AL/AH、AX/DX或EAX/EDX中。
IMUL(有符号)
可有多个操作数。例如:imul ebx,ecx ;若溢出,结果高位部分存到ECX,低位部分存入EBX。
指令
作用
NOP
垃圾指令,不执行任何操作
PUSHFD
对标志位进行现场保护,对标志位寄存器的压入栈
POPFD
还原标志位寄存器,从栈中弹出标志位寄存器的值到标志位寄存器
MOVSX
有符号扩展( movsx eax,bx)(movsx eax , bh(或者bl))如果bx(对应2个字节),bh/bl(对应一个字节)的值大于它所对应字节的一半+1,则复制到的存储器的高位值要变负。
MOVZX
无符号扩展( movzx eax, bx)(movzx eax, bh(或者bl))如果bx(对应2个字节),bh/bl(对应一个字节)的值大于它所对应字节的一半+1,则复制到的存储器的高位值不用变。
XCHG
值交换,将两个值交换
ADC
比如:adc eax,ebx 相当于 eax=eax+ebx+CF(进位标志位)
SBB
比如:sbb eax,ebx 相当于 eax=eax-ebx-CF
INC
递增,就是寄存器自动加1
指令
作用
DEC
递减,就是寄存器自动减1
IDIV (有符号)
XADD
例如:xadd ebx,eax ; 设ebx为3,eax为2,则执行执行这条指令,交换双方的值,ebx为2,eax为3,然后相加返回给ebx,则ebx为5。
NEG
取反指令,neg ebx ;若ebx为100,则执行此指令,ebx为-100
CMP
比较指令,比较两个寄存器的值是否想等。例如:cmp edx,eax ;其实是两个值相减,sub edx,eax比较两个值是否相等,结果并不会存到edx寄存器,若比较出来结果相等,即相减为0,则运算结果为0,ZF标志位置为1
TEST
比较指令,比较两个寄存器的值是否相等。例如:test eax,ebx;其实是两个值进行与运算,and eax,ebx;运算结果是否为0,若为0,则置ZF为1,否则置0。结果不保存到EAX寄存器上。
JMP
无条件跳转指令,不根据标志位来改变程序运行逻辑
JE/JZ
根据ZF标志位来进行跳转,如果ZF标志位为1时则跳,为0时不跳
指令
作用
JNE/JNZ
根据ZF标志位来进行跳转,ZF标志位为0时则跳,为1时则不跳
JS
如果结果为负,SF为1,根据SF标志位来进行跳转,如果SF标志位为1时则跳,为0时则不跳
JNS
根据SF标志位来进行跳转,如果SF标志位为0时则跳,为1时则不跳
JP/JPE
如果结果的低十六位含1个数为偶数时,PF为1。根据PF标志位来进行跳转,如果PF标志位为1时则跳,为0时则不跳
JNP/JPO
根据PF标志位来进行跳转,如果PF标志位为0时则跳,为1时则不跳
JO
根据OF标志位来进行跳转,如果OF标志位为1时则跳,为0时则不跳
JNO
根据OF标志位来进行跳转,如果OF标志位为0时则跳,为1时则不跳
JB
(判断无符号)根据CF标志位(根据无符号进行运算,只有进位或借位,不存在有无符号)来进行跳转,如果CF标志位为1时则跳,为0时则不跳
JNB
根据CF标志位来进行跳转,如果CF标志位为0时则跳,为1时则不跳
指令
作用
JBE
根据CF或ZF标志位来进行跳转,如果CF或者ZF标志为1时则跳,为0则不跳。例如:cmp eax,ebx;若运算结果为0,ZF为1,运算结果小于0,CF为1。所以就是看eax-ebx的结果是否<=0,就是判断eax<=ebx
JNBE/JA
根据CF和ZF标志位来进行跳转,如果CF和ZF标志都为0时则跳,有一个为1时则不跳。例如:cmp eax,ebx;若运算结果不为0,ZF为0,运算结果大于0,CF为0。所以就是看eax-ebx的结果是否>0,就是判断eax>ebx
JL
(判断有符号)根据SF标志位(根据有符号进行运算)来进行跳转,若SF为1,则跳,为0则不跳
JNL
(判断有符号)根据SF标志位(根据有符号进行运算)来进行跳转,若SF为0,则跳,为1则不跳
CALL
函数调用,例如:call 00007FFB59C4A838 ;跳到子程序的地址执行,主程序的下个地址存入栈中,当子程序执行完后,从栈顶弹出地址赋值给EIP,然后继续执行主程序后的部分。
RET
call和ret配合使用,当运行到ret时,表示子程序返回到主程序。
LOOP
根据寄存器ECX值递减至1时,则不继续循环,且ECX减为0;常见有loopd,loopb和loop是一样的 loopd使用ECX 32位计数器。loopb使用ECX 8位计数器。
mov dword ptr [eax] ,
1
;把
1
放入EAX内存地址
mov ecx, [eax]
;访问EAX寄存器存储的地址值,并把这个地址值当做内存地址值去访问内存,把值提取出来并放入ECX寄存器
mov [eax], ebx
;把EBX寄存器里的值放入EAX内存地址
mov [esi
+
34h
], eax
;把EAX寄存器里的值放入内存地址为(ESI
+
0x34
)的值
mov eax, [esi
+
34h
]
;把内存地址为(ESI
+
0x34
)的值放入EAX寄存器
mov edx, [ecx
+
eax]
;把内存地址为(ECX
+
EAX)的值放入EDX寄存器
mov dword ptr [eax] ,
1
;把
1
放入EAX内存地址
mov ecx, [eax]
;访问EAX寄存器存储的地址值,并把这个地址值当做内存地址值去访问内存,把值提取出来并放入ECX寄存器
mov [eax], ebx
;把EBX寄存器里的值放入EAX内存地址
mov [esi
+
34h
], eax
;把EAX寄存器里的值放入内存地址为(ESI
+
0x34
)的值
mov eax, [esi
+
34h
]
;把内存地址为(ESI
+
0x34
)的值放入EAX寄存器
mov edx, [ecx
+
eax]
;把内存地址为(ECX
+
EAX)的值放入EDX寄存器
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课
上传的附件: