我们知道,人和人之间交流,需要语言、文字等来交流,那么人和计算机交流是怎么交流呢?人和计算机交流也需要语言,不过这种语言是需要计算机这个机器能够识别,那就是二进制,即0和1。
但是0和1这种语言对于我们来说不易理解,所以就在这个基础上诞生了汇编语言。汇编语言对于我们来说较为容易理解。学习汇编语言主要是为了让我们了解计算机在底层的操作。接下来就让我们从计算机结构开始我们的学习之旅。
一、计算机结构
现在计算机体系结构基本上用的都是冯诺依曼的机构
1.中央处理器cpu:运行代码
2.内存(RAM):存储数据和代码
3.输入输出系统
如上图所示,CPU中包含了其他的组件:寄存器、控制单元、ALU等。
控制单元中有一个叫指令指针的寄存器,用来获取内存中要执行的指令,这个寄存器储存的是指令地址。
算数逻辑单元(ALU)是执行从内存中获取的指令,并将结构保存在寄存器或者内存中。
寄存器:寄存器的类型有很多,主要功能是CPU暂时储存数据的一个结构。
二、内存
数据:数据是指在内存中的数据节,数据节是程序初始化时储存程序中不变的数据,是储存全局变量的。
代码:代码块是程序运行时储存指令的,而指令就是程序告诉CPU需要做什么,该怎么完成任务。
堆:堆称为动态数据,就是存储程序运行过程中生成的数据以及消除的数据。
栈:栈用于程序的局部变量和参数。
这只是展示了内存的四个主要节,并不是说一定是按照这个存储数据,他们可以存储在内存中的任何位置。
三、指令
指令由助记符和零个或者多个操作数组成。汇编语言就是由指令组成的。
1.操作码和字节序
操作码:操作码是机器能够读懂的语言
指令:指令是将操作码经过反汇编得到的语言
字节序:字节序是指在大数据项中,大端位还是小端位哪个排在前面,在X86中是小端字节序。不过网络是大段字节序。
2.操作数
操作数只是说明指令要使用的数据,操作数有三类。
(1)立即数:操作数是一个固定的值
(2)寄存器:操作数指向一个寄存器
(3)内存地址:操作数指向感兴趣数值的内存地址,一般是由放括弧内包含值或者寄存器或者方程式
3.寄存器
寄存器是位于CPU中,用于储存数据的一个容器
寄存器的分类如下图所示
(1)通用寄存器,CPU执行期间使用,存储数据和内存地址。通用寄存器的位数时32位的,具体看下图。
(2)段寄存器:用于指向内存中的节
(3)状态标志:用于做出决定。它是32位的,每一位是一个标志。在执行期间,每一位要么置位为1,要么为0。由这些数值来控制CPU的运算,主要的位请看下图。
(4)指令指针寄存器:用于定位下一条要执行的指令。储存的是CPU下一步要执行的指令的内存地址。
4.简单指令
(1)mov:将一个位置的数据移动到另一个位置处,它可以将数据移动到内存或者寄存器
(2)lea(意思是load effective address,加载有效地址):这个指令就是将内存地址赋给目的操作数。具体介绍如下图。
(3)算数运算
加法:add
减法:sub
减法指令会修改两个重要的标志,ZF和CF,如果结果为0,则ZF被置位,如果目标操作数比减去的值小,则CF值置位。
Inc和dec指令会将一个寄存器加一和减一
乘法:mul
除法:div
乘法和除法是已经将寄存器规定好了,寄存器中的值已经被赋值好了,故而乘法的形式是mul value ,除法的格式是div value,如果乘法的得出的值分存在EDX和EAX中。而乘法恰好相反,他是将EDX和EAX中的值合在一起后,再除去VALUE。EDX中储存的时余数,而EAX中储存的是余数。
(4)逻辑运算
AND(与操作)/OR(或操作)/XOR(异或操作)/NOT(非)等。这些指令跟算数运算符差不多,就是将源操作数和目的操作数做相应的操作,然后结构保留在目的操作数中。
(5)移位操作数
Shr:向右移。格式是shr 目的操作数,count
Shl:向左移。
移出的位数放在了CF位中,被溢出的位用0来填充
(6)循环移位
左循环移位:rol
右循环移位:xor
循环移位跟移位操作其实差不了太多,只不过循环移位是将移出来的位数放在了移动后空置的位数上。右循环就是将最低位放在最高位上。具体如下:
(7)栈中指令操作
栈是一种用压和弹来刻画的数据结构,用来存储局部变量、流控制结构。跟栈有关系的是寄存器是ESP和EBP。EBP是栈的基地址,它是不变的,函数用它来定位局部变量和参数的位置。ESP是栈指针,包含了指向栈顶的内存地址,它的数值是会随着压和弹的动作而改变的。
与栈有关的指令是pop,push,call,leave,enter和ret
这些指令具体如下:
(8)条件指令
条件指令是用于做比较的指令
常见的比较指令是cmp和test
Test指令跟and指令差不多,只不过test指令不改变目的操作数,test指令指设置标志位,我们感兴趣的是ZF位。
cmp指令跟sub指令差不多,但是不改变目的操作数。它也是只改变操作位,操作结果看ZF和CF位。
(9)分支指令
最常见的分支指令是跳转指令,最常见是jmp指令,这个指令被成为无条件跳转,有条件的跳转使用标志位来决定是否跳转还是继续执行下一个指令。有条件的跳转指令具体如下: