一、x86汇编语言指令基础:
1、指令的作用与格式:
2、八个寄存器(32bit 且e开头):
eax ebx ecx edx 通用寄存器(存放内容未知)
可只使用后两位如ax,代表使用该寄存器的低16位
或者ah,al,代表低16位的高八位与低八位
esi edi 变址寄存器(通常用于线性表与字符串的的处理)
ebp esp 指针寄存器(堆栈基指针 堆栈顶指针用于实现函数调用)
3、一些常用的x86汇编指令
dword ptr[地址]32bit
word ptr[地址]16bit
byte ptr[地址]8bit
register:寄存器 memory:内存 constant:常数
mov: mov 目标操作数d,源操作数s
mov eax,ebx(将ebx寄存器的值复制到eax寄存器中)
mov eax,dword ptr[ebx] (将ebx所指主存地址的32bit复制到eax寄存器中)
add: (+) add d,s(d+s存入d)
sub: (-) sub d,s(d-s存入d)
mul / imul: (x) mul / imul d,s(d*s存入d)(mul无符号数 imhl有符号数)
div / idiv: (/) div / idiv s(edx:eax/s,商存入eax,余数存入edx)(div无符号除法 idiv有符号除法
negative:(取负数)neg d(将-d存入d)
inc:(自增)inc d
dec:(自减)dec d
and:(与)and d,s(将d、s逐位相与并将结果放回d所指位置)
or:(或)or d,s
not:(非)not d
xor:(异或)xor d,s
shl:(左移)shl d,s
shr:(右移)shr d,s
cmp test jmp jxxx push pop call ret 等
(后面有部分指令解释)
二、AT&T格式与v.s.Intel格式
AT&T格式一般为Unix、Linux的常用格式
v.s.Intel格式一般为Windows的常用格式
下表为两者区别:
这里可以注意一下贮存地址偏移量的表示第二个,我们用v.s.Intel格式中的mov eax,[ebx+ecx*32+4]为例:
我们可以创建一个学生数组
将基址存入ebx,再将变址(0到n)存入ecx,此时存入3,比例因子字节为32bit,偏移量为4,该语句的意思便为:将数据元素3中的变量1存入eax存储器中。
三、选择语句的机器级表示:
这里用到jmp指令(无条件跳转指令)
jmp <地址> #PC(ip寄存器)无条件转移至<地址>
jmp 128 #<地址>可用常数给出
jmp eax #<地址>可来自于寄存器
jmp指令的拓展jxxx指令:
接下来看简单的选择语句如何用汇编语言表示:
注意这里满足条件所执行的语句NEXT在后面,这里与C语言是不同的
也可写成:
mov eax,7
mov ebx,6
cmp eax ebx
jle NEXT
mov ecx,eax
jmp END
NEXT :
mov ecx,ebx
END :
可用“标号”锚定位置(特征:有冒号且名字可以自己取)eg:NEXT
四、循环语句的机器级表示
1、用条件转移指令实现循环:
4个部分都需要考虑一下
2、用loop指令实现循环
loopnz中ZF==0意为最后一次运行结果不为0
注意使用loop指令时ecx(此时的循环寄存器)只能自减且比较的一定是ecx与0
五、栈相关(函数调用的机器级表示)
x86系统中,默认以4字节为栈的操作单位
1、Call与ret指令
<1>函数调用栈
上一篇中已经说明,这里不再详细讲了
<2>call指令
call:函数调用指令
call <函数名>
可看为:push eip jmp callee
作用:1、将ip旧值压入栈内 2、设置ip新值并无条件转移至callee(被调用函数)的第一条指令
<3>ret指令
ret:函数返回指令
ret
可看为:pop eip
作用:从函数栈帧中找到ip旧值,将其出栈并恢复ip寄存器
2、如何访问栈帧
<1>标记栈帧范围
esp:指向当前栈帧栈顶
ebp:指向当前栈帧栈底
<2>mov指令结合esp与ebp指针访问栈帧数据
可用add/sub修改esp值
两种方法:
3、如何切换栈帧
可以直接通过改变ebp与esp的值来切换栈帧
<1>enter指令
enter:进入指令
等价为:push ebp mov ebp,esp
作用:保存ebp旧值并将此时esp值赋给ebp
每个函数开头的例行处理
<2>leave指令
leave:离开指令
等价为:mov esp,ebp pop ebp
作用:让esp指向当前栈帧底部并将esp所指元素出栈并保存到edp寄存器中
为每个函数ret前的例行处理
六、CISC与RISC
两种设计方向
1、 CISC:
一条指令完成一个复杂的基本功能
思路:除了提供整数的加减乘指令除之外,还提供矩阵的加法指令、矩阵的减法指令、矩阵的乘法指令;一条指令可以由一个专门的电路完成;有的复杂指令用纯硬件实现很困难,采用“存储程序”的设计思想,由一个比较通用的电路配合存储部件完成一条指令
2、RISC:
一条指令完成一个基本“动作”;多条指令组合完成一个复杂的基本功能
思路:只提供整数的加减乘指令;一条指令一个电路,电路设计相对简单,功耗更低;“并行”、“流水线”