x86汇编基础指令
2022-9-17 21:8:51 Author: 轩公子谈技术(查看原文) 阅读量:14 收藏

寄存器

存储cpu中的数据

32位通用寄存器

32位

16位

8位

EAX

AX

AL

ECX

CX

CL

EDX

DX

DL

EBX

BX

BL

ESP

SP

AH

EBP

BP

CH

ESI

SI

DH

EDI

DI

BH

8位寄存器在16位寄存器中,而16位寄存器在32位寄存器中。

简单来说

32位寄存器就是一整个

16位寄存器就是32的一半 15-0这部分

8位寄存器分高位和低位,分别代表15-8 7-0,如下图

做个实验就明白了

将32位寄存器全部写满数据

对16位寄存器调试

可以看到更改的数据是后面四个

对8位高低寄存器调试,可以看到ah是在eax寄存器的后34位改变的,al是后两位改变的

od添加两个指令

f8执行,eax的值变成了1 又把eax的值给了edx

内存

写立即数到内存

mov byte ptr ds:[内存窗口的已申请的16进制],1byte < word < dword 字节大小mov byte ptr ds:[0019FB90],20

写寄存器到内存

mov byte ptr ds:[0019FB90],eax

读内存到寄存器

mov eax,byte ptr ds:[0019FB90]

内存地址的五种表示方式

形式1

立即数 0019FB90

形式2

[reg] 代表任意寄存器

形式3

[reg+立即数]

形式4

[reg+reg*{1,2,4,8}]

形式5

[reg+reg*{1,2,4,8}+立即数]

数据的存储模式

大段模式:数据高位在低位,数据地位在高位小段模式:数据低位在低位,数据高位在高位
db 内存地址   查看一个字节
dw 内存地址 查看两个字节
dd 内存地址 查看四个字节

⼤⼩端的使⽤场景

1、Intel的80×86系列芯⽚使⽤⼩端存储模式

2、ARM芯⽚默认采⽤⼩端,但可以切换为⼤端

3、MIPS芯⽚采⽤⼤端,但可以在⼤⼩端之间切换

4、在⽹络上传输的数据普遍采⽤的都是⼤端

0x11223344 11是高位 44是低位

在内存地址中 90<93内存地址,所以是小段模式

0019FF90 44

0019FF91 33

0019FF92 22

0019FF93 11

mov 移动数据

mov eax,1   将1存储到eax中mov eax,edx 将edx的值存储到eax

add 数据相加

add eax,1 eax加1结果给eax

sub 数据相减

sub eax,1  eax减1结果给eax

and 作用按位与运算

按位与
作用:只将某一位变成0,而其他位保持不变
使用:谁要变0,谁就和0与
and就是与运算,两个数按二进制位相与,全1为1,有0为0,常用于把低位清零

or 按位或运算

or eax,edx

按位或
作用:只将某一位变成1,而其他位保持不变
使用:谁要变1,谁就和1或

xor 异或运算 一样为0 不一样为1

xor eax,ecx

not 异或运算 一样为1 不一样为0

not eax,ecx

movs 移动数据,内存-内存

movs byte ptr es:[EDI],byte ptr ds:[ESI]movs word ptr es:[EDI],word ptr ds:[ESI]movs dword ptr es:[EDI],dword ptr ds:[ESI]简写movsbmovswmovsd

EFL 标志寄存器

DF的值 由第十位决定

为0时,则EDI ESI +1 +2 +4

为1时,则EDI ESI -1 -2 -4

stos指令 将al/ax/eax的值存储到edi指定的内存单元

stos byte prt es:[EDI]stos word prt es:[EDI]stos dword prt es:[EDI]简写stosbstoswstosd

rep指令,按计数寄存器ECX中指定的次数重复执行字符串指令

mov ecx,10rep movsd
rep stosd

堆栈

ESP栈指针寄存器

push指令 向堆栈压入数据,修改斩顶指针ESP寄存器

相当于mov sub -4

push 3push eaxpush dword prt ds:[18FFA4]

pop指令 将斩顶数据存储到寄存器,修改栈顶ESP寄存器

相当于mov add +4

pop ecxpop 3

修改EIP指令 下一次要执行的指令

jmp指令 跳转

jmp 004F11jmp 10jmp eax

call指令

修改EIP的值

call指令结束后,下一行地址存到堆栈中

同时ESP的值 -4

call 004F11call eax

ret指令

把当前栈顶的值放到EIP,ESP +4ret

函数

指令的集合

函数的调用

jmp 或 call

小案例 两数相加

001  mov ecx,1002  mov edx,2003  call 009
008 add ecx,edx009 mov eax,ecx010 ret

堆栈平衡

如果要返回父程序,则当我们在堆栈中进行堆栈的操作的时候,一定要保证在ret指令之前,ESP指向的是我们压入栈中的地址。

如果通过堆栈传递参数 了,那么在函数执行完毕后,要平衡参数导致的堆栈变化。

ESP寻址

001 push 1002 push 2003 call 007004 add esp,8
007 mov eax,dword prt ss:[esp+4]008 mov eax,dword prt ss:[esp+8]009 ret

EBP寻址

开辟新的内存空间 esp ebp整体移动,等函数调用结束在回到原位

001 push 1002 push 2003 call 007004 add esp,8
007 push ebp008 mov ebp,esp009 sub esp,10010 mov eax,dword ptr ss:[ebp+8]011 mov eax,dword ptr ss:[esp+C]012 mov esp,ebp013 pop ebp014 ret

jcc指令

标志寄存器

 CF 第0位,表示无符号数运算的溢出状态,溢出为1,反之为0

溢出了 cf为1

mov al,0xFEadd al,2

PF 如果结果的最低有效字节包含偶数个1位,则为1,反之为0

mov al,0xceadd al,0

AF 如果算数操作在结果的第三位发生进位或借位则将该标志置1,否则清零

ZF 若结果为0,则为1,反之为0

mov eax,100mov ecx,100cmp eax,ecxcmp与sub类似,但想减的结果并不保存到第一个操作数中
test eax,ecx

SF 该标志被设置为有符号整型的最高有效位(0 指示结果为正,反之则为负)

mov al,0x7Fadd al,2
mov al,0xFEadd al,2

OF 反映有符号数加减运算所得结果是否溢出

如果无符号运算,溢出看cf位

如果有符号运算,溢出看of位

mov al,0x7Fadd al,2

JCC指令

中文含义

检查符号位

JZ/JE

若为0则跳转;

ZF=1


若相等则跳转

ZF=1

JNZ/JNE

若不为0则跳转;

ZF=0


若不相等则跳转

ZF=0

JS

若为负则跳转

SF=1

JNS

若为正则跳转

SF=0

JP/JPE

若1出现次数为偶数则跳转

PF=1

JNP/JPO

若1出现次数为奇数则跳转

PF=0

JO

若溢出则跳转

OF=1

JNO

若无溢出则跳转

OF=0

JC/JB/JNAE

若进位则跳转;

CF=1


若低于则跳转;

CF=1


若不高于等于则跳转

CF=1

JNC/JNB/JAE

若无进位则跳转;

CF=0


若不低于则跳转;

CF=0


若高于等于则跳转;

CF=0

JBE/JNA

若低于等于则跳转;

ZF=1或CF=1


若不高于则跳转

ZF=1或CF=1

JNBE/JA

若不低于等于则跳转;

ZF=0而且CF=0


若高于则跳转

ZF=0而且CF=0

JL/JNGE

若小于则跳转;

SF != OF


若不大于等于则跳转

SF != OF

JNL/JGE

若不小于则跳转;

SF = OF


若大于等于则跳转;

SF = OF

JLE/JNG

若小于等于则跳转;

ZF != OF 或 ZF=1


若不大于则跳转

ZF != OF 或 ZF=1

JNLE/JG

若不小于等于则跳转;

SF=0F 且 ZF=0


若大于则跳转

SF=0F 且 ZF=0


文章来源: http://mp.weixin.qq.com/s?__biz=MzU3MDg2NDI4OA==&mid=2247487044&idx=1&sn=2ce4bb2d94050dbe19b5f1f24b3ec823&chksm=fce9a98bcb9e209ddfb65445338613c8c1d934664adab3007a4599aeabd3726f7bcdb8dd4232#rd
如有侵权请联系:admin#unsafe.sh