怎么样?这次的专栏够不够硬核?这次我打算由浅入深的带大家学习汇编,这个令人恐惧不想接触,一看就晕的语言(我承认有点夸张了)
我会尽量用简单易懂有趣的语言带大家学习。
希望我能坚持下去💪
(⊙﹏⊙)
Ⅰ.一些你可能感到疑惑的问题
0x00 什么是汇编
汇编是什么玩意?
简单来说汇编就是二进制的助记符。
在上古时代,苦逼的程序员只能使用一天天二进制文件来编程。
但是二进制文件根本就不是给人看的
不信
(以上是一个打印helloworld的二进制程序)
二进制根本就不是给人看的,程序做了啥根本看不出来。
聪明的程序员就发明了汇编语言(虽然难度几乎没变,但总比一堆看不懂的0101要好)
汇编的指令和二进制是一一对应的。
编译器的工作也十分简单,只需要将文字的代码翻译成二进制指令就行了。
不同cpu的指令集是不同的,对应的汇编语言也不一样。
目前来说汇编格式主要分两种Intel和AT&T,我们将要学习的则是比较常见的Intel格式,也就是Intel公司使用的。
0x01 汇编难吗?
汇编语言的语法可能是你学过所有语言中最简单的。
但是汇编相较于高级语言来说更偏底层,其很多地方也是不一样的。
像是有c语言基础的入门汇编可能会简单一些。
这里先给大家打个预防针,提前展示一下下一节可能会接触到的汇编程序。
mov ax, 0x06
mov bx, ax
add ax, bx
sub ax, bx
jmp $
语法很简单吧,代码我就不多说了。
不理解也没事,到时候也会说。
毕竟代码也不知道会不会该。
0x02 汇编一定要学吗?
汇编实际上并不是必须的。
只要你主要是应用层的开发,不接触底层就没必要使用汇编。
但是如果是学习c/c++之类的,或者想要接触内核级的开发,最好还是学一下汇编。
汇编对于编程还是有一定帮助的(比如说在朋友面前写个汇编装B)
0x03 怎么运行汇编代码
汇编向上面说的,编译器会把代码编译成二进制文件。
但是这个二进制文件不可以直接运行。
因为这些命令是给cpu执行的,程序系统无法直接食用。
所以我们需要用电脑直接运行二进制文件,越过操作系统。
方法也比较简单,把二进制文件写入u盘,将u盘作为启动盘,再用电脑使用u盘启动。
这也太难了,为了避免大家在这里就被劝退,我还带来了另一种方法。
那就是虚拟机!!!
虚拟机真的是一个伟大的发明,在减少学习成本的同时又可以保护爱机不受伤害。
0x04 。。。应该没了
什么?你还有!
我劝你别多问
Ⅱ.环境配置
0x00 用什么工具
首先是编译器,编译器没有任何犹豫选择nasm。
有些人可能会说其他的,比如masm。
但是nasm是开源的,而且更现代化。
是未来的趋势。
虚拟机方面的选择就多了。
大概可以分为两类:
1.通过软件模拟cpu的,如bochs,qemu
2.通过硬件虚拟化来实现的,如VMware,VirtualBox
在速度上第二类几乎可以完善,原因也不用过多解释。
第一类的优势则是可以模拟多种cpu,第二类就不用说了...
在准确性方面也是第一类更好。
大家可以根据自己的喜好选择,我比较建议的是bochs,调试什么也比较轻松。
这个只能说萝卜青菜各有所爱
0x01 NASM安装
nasm官网地址:https://nasm.us/
我们首先先进入官网,点击download按钮
进入列表选择第一个最新版本
选择自己的系统进入,我这里是win11 64位,所以是win64文件夹
点击下载第一个安装程序
下载完成后打开
点击确定就行了
选择要按照的组件,全选即可
选择安装目录,最好不要在D盘
然后是设置名称,默认就行了
然后点击install就可以了
这里可以把安装路径添加到环境变量,以后使用会方便一些。
0x02 Bochs安装
这里只介绍bochs的安装,其他的自行搜索。
bochs下载地址:Bochs x86 PC emulator download | SourceForge.net
还是先进入下载地址,点击安装download
下载后打开,一直next到这
这里设置安装的组件
然后就是设置安装目录
点击install等待安装完成即可。
Ⅲ.纵览寄存器
这节课我就不讲汇编代码了,提前了解一下寄存器吧。
为后面打基础,别到时候看到寄存器一脸懵逼。
0x00 为什么用寄存器而不是直接使用内存
首先cpu只负责计算,数据都是存储在外部的。
而内存的速度比cpu慢了几百倍,cpu根本等不及呀。
没办法,这样实在太浪费资源了。
人们就发明了寄存器作为一个更快的临时存储单元。
嗯,有理有据,多的我也不说了。
0x01 有什么寄存器
8086CPU一个有14个16位寄存器,这几个寄存器的名称也一直留到现在。
其中有8个通用寄存器,分别是AX,BX,CX,DX,DI,SI,BP,SP。
还有两个控制寄存器IP和FI,
四个段寄存器CS、DS、SS、ES。
0x02 通用寄存器
8个通用寄存器都可以用来暂存参加运算的数据或中间结果,但又有各自的专门用途。
我们先来讲讲前四个寄存器AX,BX,CX,DX。
以AX为例,寄存器的逻辑结构如下:
其中AX寄存器的高八位是AH,低八位是AL。
其他三个通用寄存器也是类似:
BX:BH,BL;
CX:CH,CL;
DX:DH,DL。
其余四个就没有那么多分类了。
在讲讲这八个寄存器的用途:
- AX,BX,CX,DX称作为数据寄存器:
AX (Accumulator):累加寄存器,也称之为累加器;
BX (Base):基地址寄存器;
CX (Count):计数器寄存器;
DX (Data):数据寄存器;
- SP和BP又称作为指针寄存器:
SP (Stack Pointer):堆栈指针寄存器;
BP (Base Pointer):基指针寄存器;
- SI和DI又称作为变址寄存器:
SI (Source Index):源变址寄存器;
DI (Destination Index):目的变址寄存器;
这些全部都要记住哈!😎
哈哈,开个玩笑,这些记不住也没事。
0x03 其他寄存器
其他几个寄存器不常用,大家只需要了解一下就行了。
控制寄存器:
IP (Instruction Pointer):指令指针寄存器;
FLAG:标志寄存器;
段寄存器:
CS (Code Segment):代码段寄存器;
DS (Data Segment):数据段寄存器;
SS (Stack Segment):堆栈段寄存器;
ES (Extra Segment):附加段寄存器;
0x04 拓展寄存器
8086cpu十分老,那时候的cpu只是16位的。
现在16位的寄存器已经不能满足需求了,32位的寄存器也就出现。
为保持向后兼容性,32位一样可以访问16的寄存器,在实模式(也就是16位模式下)也可以访问拓展后的寄存器。
拓展的如下,例如AX。
AX属于EAX(也就是拓展的32位)的低十六位。
其余七个寄存器的名称也一次类推:
EAX,EBX,ECX,EDX,ESP,ESI,EDI,EBP。
聪明的同学可能想到了,64位的cpu是不是也有拓展寄存器?
64位的拓展寄存器则是由R开头。