什么是汇编语言
为了克服机器指令难以书写和理解的缺点,人们想到可以用一些容易理解和记忆的符号,也就是助记符,来描述指令的功能和操作数的类型,这就产生了汇编语言 --x86汇编语言
通俗一点来说,汇编语言和C语言、java它们一样,都是计算机编程语言,只不过汇编语言更贴底层。最终也是需要通过编译器编译成为计算机所能够理解的机器语言。
初识处理器、内存、寄存器、指令
处理器
处理器是整个计算机最核心的部分,计算机上的一些任务能够正确有序的进行,都是处理器的功劳。
处理器内部构造也是很复杂的,包括寄存器、算术逻辑部件、控制器等等
比如计算A+B的时候
寄存器RA和RB会锁住A和B,然后经过算术逻辑部件算出来结果之后,会用RC锁存。
寄存器根据存储二进制位的大小可以分为64位寄存器,32位寄存器,16位寄存器,8位寄存器等
寄存器是暂时存储数据,16位寄存器可以存储两个字节,也称为一个字。4个字节称为双字
寄存器
暂时存储数据
8086内部有8个16位的通用寄存器
分别是AX BX CX DX SI DI BP SP
其中AX还可以分为两个8位寄存器使用 分为 AH AL
其中BX还可以分为两个8位寄存器使用 分为 BH BL
其中CX还可以分为两个8位寄存器使用 分为 BH BL
其中DX还可以分为两个8位寄存器使用 分为 BH BL
4个段寄存器
CS (代码段寄存器)DS(数据段寄存器) ES(附加段寄存器) SS (栈段寄存器)
一个指令指针寄存器
IP (只和CS一起使用)
处理器 通过CS和IP来取指令和执行指令,当需要访问内存的时候,就会需要用到DS段寄存器(提供数据段的基地址)加上偏移地址。
内存
内存也称为内存储器,主存,它通常只和处理器相连,处理器执行的一些指令,都是通过访问内存得到的。在C语言指针中,我们也接触到一点内存。
指令和指令集
处理器是依靠指令来执行一些功能的,程序也是指令的集合。
指令一般有操作码和操作数组成,操作数分为立即数和非立即数,这个在大学计算机基础上曾经学过一点,当时其实还不是很清晰,现在清晰一点了。
立即数就是操作码后面直接跟着一个数(16进制表示的),非立即数就是操作码后面跟着的是一个内存地址,你通过这个地址来取操作数。
指令在内存中的布局
因为操作数和操作码都是二进制数,有时候容易混淆,所以一般会采用分段,内存里面,代码段和数据段是分开的。
因为指令在内存中的地址往往不是连续的,也不是我们能够控制的,所以采用绝对地址是行不通的,可能在你的电脑上面能跑,在其他人电脑上就跑不了了,所以要采用相对地址或者说是逻辑地址。
所以采用“逻辑地址:偏移地址”的模式。
因此引入了DS段(数据段)寄存器和CS段(代码段)寄存器,还有ES段寄存器。
举个例子:
代码段中0002代表的是偏移地址,实际物理地址是DS寄存器中的段地址+这个偏移地址
所以最后访问的是地址为1002的内容。
PS 为了提高访问内存的大小,增大地址范围。段寄存器的内容会左移4位(相当于乘以16进制的10和十进制的16),形成20位的段地址,在同16位的偏移地址相加
举个例子:
对于逻辑地址为 F000H:052DH,处理器在形成物理地址的时候,段地址会变为F0000H,然后加上偏移地址,最后得到的是F052DH
最后简单感受一下汇编程序
使用的编译器是NASM
用记事本写一个汇编语言源程序,使用的是汇编语言的语法(后面会学习到)保存格式为.asm
用16进制编辑器打开看一下
然后拿到nasm-shell里面编译一下
用16进制编辑器打开这个编译后的.bin文件
直观感受一下编译前和编译后的区别。