汇编指令与C语言对比

汇编指令与C语言对比

这两天在巩固基础,重拾汇编语言,对于汇编语言的思考,记录在此,仅仅是自己的思考笔记,可能有错误的地方,欢迎提意见。

计算机两个最主要的组成部分,就是CPU和内存了。我们编写的程序要运行,是需要先加载到内存中,然后由CPU控制执行的。

简而言之,我们写的程序,其实就是使用CPU对内存进行操作,即CPU和内存的交互,CPU是通过内部的寄存器和内存交互的,所以程序就是寄存器和内存的交互。

重要的事情说三次,寄存器和内存的交互,寄存器和内存的交互,寄存器和内存的交互。 请牢记这句话,我们通篇文章都会贯穿这种思想。

一般c语言的教程,都包含这几个部分:

  • 变量和数组(内存)
  • 控制(if, for)
  • 函数(栈)

我们就来看看,以上这些知识,是怎么跟汇编语言联系起来的(这里讲的是8086汇编)。

寻址

8086 CPU是16位处理器,即其内部的寄存器是16位的,但是呢8086的地址总线却是20位的。那这么说,寄存器是否只能访问到2的16次方个内存地址,其他的内存无法访问了吗?

为了解决这个问题,聪明的硬件设计师们将寄存器分为两类,段寄存器和通用寄存器。寻址时,通过段寄存器左移4位+通用寄存器来确定一个内存地址,这样就能访问到所有的内存单元了。

8086 CPU中的寄存器个数很少,每个都有名字(代号)。8086 CPU总共有14个寄存器。

  • 段寄存器:CS(Code Segment),DS(Data Segment),SS(Stack Segment),ES(Extend Segment)
  • 通用寄存器:AX,BX(Base),CX(Count),DX

这里需要注意的是,所有的内存包括显存和ROM是统一编址的。

指令和数据的区分

计算机的世界里只有0101,那么CPU是怎么区分这个0101代表的是指令还是数据呢?通过寄存器,如上。
CS左移4位+IP寄存器所得的地址,其指向的地址存储的0101,就是下一条即将指向的指令。 DS就是代表的数据,SS代表栈。

寄存器的常用组合

寄存器一般的搭配为:

  • CS+IP:指定指令地址
  • DS+([0], [BX], [BX+0], [SI], [DI]) :指定数据地址,BX寄存器存放偏移地址,SI和DI可以用于复制
  • SS+SP:指定栈内存
  • loop+CX:CX寄存器放置循环次数
  • DS+[BX+SI+0]:可以用于数组,该命令格式也可以写为,200[SI]或[BX][SI]或[BX][SI]这种更像数组的写法

内存

在C语言中,我们不需要直接指定内存的地址来获取数据,但在汇编中,是需要我们指定地址的。每一个内存单元代表一个字节(8位),所以一个寄存器为16位则需要两个字节存放。高地址存放在高位,低地址存放低位。如下图,

20191208215732.png

## 汇编指令和C语言对比

### 变量和数组(内存)

  • 变量和数组:变量和数组的分配都是在内存中。如int i = 0;或者int[] array = {1, 2},在汇编中则是mov [0], 0或者mov [BX],1; add BX,2; mov[BX],2;

    控制(if, for)

  • go跳转语句:在汇编中则是jmp short, jmp far ptr,该命令操作了CS和IP寄存器。jmp far ptr段间跳转,不止修改了IP的值还修改了CS的值,而jmp short只修改IP的值
  • if判断:在汇编中是JE指令,相等则跳转。
  • for, while循环:for在汇编中是loop+CX,其中CX设置循环次数,while则可以使用JE跳转

    函数(栈)

  • 函数的调用和返回指令:call, call far ptr, ret, retf,该指令会把IP或CS和IP入栈,

中断

中段可以认为就是不断检测系统发生的事件,然后系统先停下手头的工作响应中断,根据中断类型找到中断程序的入口,执行该中断处理程序,完成后返回。

打赏一个呗

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦