学习笔记分享之汇编---2. 汇编指令&语法
前言:
此文章收录在本人的《学习笔记分享》分类中,此分类记录本人的学习心得体会,现全部分享出来希望和大家共同交流学习成长。附上分类链接:
https://www.cnblogs.com/tibbors/category/1729804.html
学习内容:汇编指令&语法:
-
拷贝源操作数到目标操作数:
mov 目标操作数,源操作数
-
源操作数可以是任意单元(r/m/sr/imm) (sr:Segment Register)
-
目标操作数可以是除了立即数之外的任意单元(r/m/sr)
-
操作数的宽度必须前后一致
-
源操作数和目标操作数不能同时为内存单元
-
-
加/减/与/或/异或:
🞕 add/sub/and/or/xor 目标操作数,源操作数
-
源操作数可以是r/m/imm
-
目标操作数可以是r/m
-
操作数的宽度除了源操作数是立即数的情况之外(即:立即数可以是任意位)必须前后一致
🞕 非:
- not r/m8 not r/m16 not r/m32
-
-
从指定内存中写入/读取数据:
mov dword ptr ds:[m],imm //写
mov r,dword ptr ds:[r] //读
ptr: Point 代表后面是一个指针 (指针即里面存的不是普通的值,而是个地址) 在8086中设置4个16位的段寄存器,用于管理4种段: ①数据段---ds(Data Segment):数据段寄存器 ②代码段---cs(Code Segment):代码段寄存器 ③堆栈段---ss(Stack Segment):堆栈段寄存器 ④附加段---es(Extra Segment):附加段寄存器 BYTE 字节 = 8(BIT) WORD 字 = 16(BIT) DWORD 双字 = 32(BIT) 1KB = 1024 BYTE
-
寻址公式
(LEA与MOV的区别在于MOV是取地址中的值,而LEA是取地址)
①[imm]形式
读取内存的值 向内存中写数据 读取内存编号 mov r,dword ptr ds:[m] mov dword ptr ds:[m],r/imm lea r,dword ptr ds:[m] ②[r]形式
读取内存的值 向内存中写数据 读取内存编号 mov r',imm
mov r'',dword ptr ds:[r']mov r,imm
mov dword ptr ds:[r],immlea r',dword ptr ds:[r'']
mov r',dword ptr ds:[r'']③[r+imm]形式
读取内存的值 向内存中写数据 读取内存编号 mov r',imm
mov r'',dword ptr ds:[r'+imm]mov r,imm
mov dword ptr ds:[r+imm],immlea r,dword ptr ds:[r+imm]
mov r,dword ptr ds:[r+imm]④[r+r*(1/2/4/8)]形式
读取内存的值 向内存中写数据 读取内存编号 mov r',imm
mov r'',imm
mov r''',dword ptr ds:[r'+r''*4]mov r',imm
mov r'',imm
mov dword ptr ds:[r'+r''*4],immlea r',dword ptr ds:[r'+r''*4] ⑤[r+r*(1/2/4/8)+imm]
读取内存的值 向内存中写数据 读取内存编号 mov r',imm
mov r'',imm
mov r''',dword ptr ds:[r'+r''*4+8]mov r',imm
mov r'',imm
mov dword ptr ds:[r'+r''*4+8],immlea r',dword ptr ds:[r'+r''*4+8] -
压栈与出栈
PUSH与POP的语法:PUSH:
- PUSH r16/32
- PUSH m16/32
- PUSH imm8/16/32
POP:
- POP r16/32
- POP m16/32
🞕 注意:
PUSH/POP加减2/4是看它PUSH/POP的是16/32位的单元🞕 附:
PUSHAD可将八个通用寄存器中的数据写入内存中,然后即可对八个通用寄存器中的数据进行随意更改
而更改完之后需要恢复现场,就可以用POPAD再将刚刚PUSHAD出去的八个通用寄存器中的值原封不动的还原回去 -
带进/借位加/减法
ADC/SBB:带 进位/借位 加/减法格式:
ADC/SBB r/m , r/m/imm 两边不能同时为内存,宽度要一样
计算过程:
当使用ADC/SBB指令后,在执行加/减法时会先看C位寄存器的值:
①C位寄存器值为1----执行加/减法时自动多加/减1
②C位寄存器值位0----正常执行加/减法e.g.
①C位寄存器值为1MOV EAX,3
MOV ECX,1将C位寄存器值置为1
ADC EAX,ECX
将C位寄存器值置为1
SBB EAX,ECX
②C位寄存器值为0
MOV EAX,3
MOV ECX,1将C位寄存器值置为0
ADC EAX,ECX
将C位寄存器值置为0
SBB EAX,ECX
-
交换数据:
XCHG:
格式:
XCHG r/m , r/m 两边都必须为容器且不能同时为内存,宽度要一样e.g.
XCHG AL,CL
XCHG DWORD PTR DS:[12FFC4],EAX
XCHG BYTE PTR DS:[12FFC4],AL -
移动数据:
MOVS:
即:把一块内存中的数据移动到另一块内存中
内存--内存(注意宽度) (唯一可以两边同时为内存单元的指令)
此指令默认操作[EDI]和[ESI]寄存器
格式:
MOVSB == MOVS BYTE PTR ES:[EDI],BYTE PTR DS:[ESI]
MOVSW == MOVS WORD PTR ES:[EDI],WORD PTR DS:[ESI]
MOVSD == MOVS DWORD PTR ES:[EDI],DWORD PTR DS:[ESI]
// 注意:[EDI]搭配的是PTR ES,而不是PTR DS
计算过程:
①将[ESI]中存储的地址 对应的 内存中的值 赋给[EDI] 指定的内存
②[ESI]和[EDI]中存储的地址同时 加/减 1/2/4
注意:
[ESI]和[EDI]中存储地址 加/减 取决于D位寄存器的值为 0/1 -
串存储指令
STOS(Store inTO String):
功能:
将[EAX/AX/AL]中的值存入[EDI]指定的内存单元(注意:不是存入[EDI]) 中 (存入的值的位数由BYTE/WORD/DWORD决定,存入后[EDI]的值加/减 由 D位寄存器的值是0/1 决定)
格式:
STOSB == STOS BYTE PTR ES:[EDI]
STOSW == STOS WORD PTR ES:[EDI]
STOSD == STOS DWORD PTR ES:[EDI] -
重复指令
REP:
功能:
按计数寄存器(ECX)中指定的次数重复执行字符串指令
每执行一次,就根据D位寄存器中的值(0/1)把内存地址加/减1/2/4MOV ECX,10 //注意,ECX,10 中的10为十六进制,即十进制的16 REP MOVSD REP STOSD
-
修改[EIP]寄存器
补充[关于[EIP]]:
[EIP]中存储的是一个地址,这个地址就是CPU下一步要去的地方,即决定了CPU即将要执行的代码是什么
想要修改CPU的行为就要修改[EIP]的值
🞕 JMP:
功能:
只修改[EIP]的值,相当于专用于[EIP]的MOV指令
格式:
JMP r/imm
注: JMP只影响[EIP]。
完整操作简述为:
MOV EIP,r/imm
🞕 CALL:
功能:
修改[EIP]的值,和JMP一样,但是CALL会修改[ESP]的值,会把下一行指令的地址压栈,而下一行指令的地址的计算是根据CALL这一行存储的字节数相加得到的,然后[ESP]中的值移动到[ESP-4]的内存地址中,相当于把CALL的下一个地址进行一个PUSH。
格式:
CALL r/addr
注:函数的返回地址就是此处CALL压入栈中的地址值
完整操作简述为:
PUSH [CALL的地址+CALL行存储的字节数]
MOV EIP,m/addr
🞕 RET:
功能:
回到刚刚CALL的位置,出栈,相当于一个POP,然后把CALL的下一个地址写入[EIP]。
格式:
RET
完整操作简述为:- LEA ESP,[ESP+4]
- MOV EIP,[ESP-4]
(=POP EIP)
-
比较指令:
🞕 CMP:
功能:
该指令是比较两个操作数,实际上,它相当于SUB指令,但是相减的结构并不保存到第一个操作数中。即:在不改变任何数据的情况下,比较两个操作数的大小,比较结果可以通过Z位、S位寄存器得到。- Z = 0 : 操作数1 ≠ 操作数2
- Z = 1 : 操作数1 = 操作数2
- S = 0 : 操作数1 > 操作数2
- S = 1 : 操作数1 < 操作数2
0001 0000 0010 0000 -0010 0000 -0001 0000 =1111 0000 =0001 0000 S=1 S=0
格式:
CMP r/m,r/m/imm
🞕 TEST:
功能:
两个数值进行与操作,该指令在一定程序上和CMP指令类似,结果不保存,但是会改变相应标志位。
格式:
TEST r/m,r/m/imm
常见用法:
用TEST指令判断某个单元是否为0,通过Z位寄存器即可得到结果。
TEST EAX,EAX- Z = 1 : 空
- Z = 0 :非空
e.g.
标准用法MOV EAX,3
TEST EAX,3
常见用法
MOV EAX,3
TEST EAX,EAX
MOV EAX,0
TEST EAX,EAX