VB.net 2010 视频教程 VB.net 2010 视频教程 python基础视频教程
SQL Server 2008 视频教程 c#入门经典教程 Visual Basic从门到精通视频教程
当前位置:
首页 > 编程开发 > 汇编语言 >
  • 汇编语言1:基础知识

 
这个假期开始系统学习汇编语言,采用跟随视频教程的方式,所用教程是网易云课堂中的《汇编语言从0开始》,讲者是workWork。该课程一共有167个课时,每个课时从几分钟到十几分钟不等,时间不长,短小精悍,反馈及时,让人有动力一直看下去。这门课程很适合零基础的同学,因为在正式编程前,讲者用了大量时间讲述基础性的知识,包括二进制十进制十六进制、CPU执行指令的过程、寄存器的讲解、栈的使用等等。我个人认为,即使你已经不算零基础了,认真地看完这些课程,巩固一下基础知识也是必要的。我之前看过一本基于Linux的教材,因为Linux采用的是AT&T风格,与DOS/Windows的Intel风格有很大差异,所以即使也写过几个汇编小程序,但始终觉得对于寄存器、指令/数据长度以及栈的概念懵懵懂懂,基础并没有打好。我建议大家如果是初学者,还是先从DOS/Windows平台的汇编开始学习比较好,尤其是要使用Windows XP中的debug程序反复练习,这样可以在编程之前打好坚实的基础。
  下面对编程之前的基础知识做一个小小的总结。

一、十进制、二进制和十六进制

       二进制之所以重要,是因为整个计算机体系就是建立在二进制的基础上的,实际上所有的指令和数据在计算机中存储和运算的形式就是二进制。十六进制之所以重要,是因为查看内存中的指令和数据时,是以十六进制显示的。一个十六进制数字,实际上相当于四个二进制数字的表示。这方面需要掌握以下几个知识点:
  • 十进制与二进制的相互转换/快速转换
  • 十进制与十六进制的的相互转换/快速转换
  • 十六进制与二进制的相互转换/快速转换

  基础的相互转换就不说了,即使对于初学者也应该是容易掌握的。说一下快速转换的方法。

  1. 十进制快速转换成二进制

  首先对于二进制来说,位于最末一位的1表示加1,右数第二位表示加2,依次类推为4、8、16、32、64。对于100以内的十进制数,只能是由以上几个数字相加得成。那么我们就可以开始凑了。比如98,可以写成64+32+2,再把对应位置为1,即1100010。
  1. 十进制快速转换成十六进制

  这个方法只能用在小于256的数。很简单,先用该数除以16,得到一个结果和一个余数。比如81=5*16+1,则十六进制表示为51H。
  1. 十六进制和二进制的快速转换

  上文说过一个十六进制数字可以由四个二进制数来表示,比如7EH,就是把7用二进制表示,E用二进制表示,即0111 1110。反之亦然,二进制转换成十六进制时,每四个数字划分即可。
  最后,记住一个式子:
  字节byte = 2个十六进制数字 = 8个二进制数字 = 8比特bit

二、CPU、寄存器和指令执行

  1. 地址信息、数据信息和控制信息

  6个小题,掌握了就可以了。
          (1)1个CPU的寻址能力为8KB,那么它的地址总线宽度为  13
          8KB = 8*1024字节,总共是2的13次方
          (2)1KB的存储器有 1024 个存储单元,存储单元的编号从 0 到 1023
          (3)1KB的存储单元可以存储 1024*8 bit,1024  Byte 
          (4)1GB, 1MB, 1KB 分别是        2^30    2^20   2^10    Byte
          (5)地址线有16根,寻址能力为64KB,20根,1MB,24根,16MB,32根,4GB
          (6)数据线有8根,一次可以传送数据为1Byte,16根,2Byte,32根,4Byte
  1. 寄存器

          (1)通用寄存器

  ax = ah + al
  bx = bh + bl
  cx = ch + cl
  dx = dh + dl
  一般用来存放数据,对于ax来说,能表示最大值为FFFFH,即0-66535。ax是16位,AH是8位,ah最大可表示FFH,即0-255。对于ax存放的数据是一个字,即两个字节。而一个地址当中只能存放一个字节,即1个字需要2个地址连续的内存单元存放,高位地址存放高位字节,低位地址存放低位字节

          (2)用于表示地址的寄存器

  段地址:偏移地址
  ds            si
  es            di
  ss            bp
  cs            ip
      sp
      bx
  物理地址 = 基础地址 + 偏移地址
  基础地址 = 段地址 * 16(10H)
  其中cs:ip表示读取指令的地址,ds 是段寄存器,一般以ds:[0]的形式表示要使用的数据所在的地址。
  1. 指令执行

  读取指令的地址为cs:ip。

          (1)指令执行的过程:

  ①CPU从cs:ip所组成的地址中读取指令,将这个指令存放在指令缓存器中;
  ②ip = ip + 所读指令的字节数;
  ③执行指令缓存器中的内容,回到步骤1,重复这个过程。

          (2)指令执行要完成的任务:

  ①数据在什么位置?
  ②处理数据;
  ③把处理过后的结果储存起来。

三、debug指令

          r 显示寄存器内容
          d 显示内存中的内容
               段地址:偏移地址 - 偏移地址
          u 将内存中内容翻译成汇编指令
          a 向当前内存中写指令(汇编指令)
          e 加上段地址:偏移地址,即向当前内存中写入内容(16进制)

四、栈

  栈就是一段连续的内存空间,遵循后进先出的准则。栈的操作有两个,分别是入栈和出栈。栈的地址由ss:sp表示。入栈指令是push加地址,出栈指令是pop加地址。注意push和pop指令后加的地址是待入栈数据的地址/出栈后数据存放的地址。ss:sp永远指向栈顶数据,可以由程序员修改决定。注意使用栈时一定要防止越界。
  push -> SP - 2 -> SS:SP 字型数据存入
  pop   ->  SS:SP字型数据取出 ->  SP - 2

五、基本的汇编指令

  1. 移动指令

          mov 寄存器,数据
          mov 寄存器,寄存器
          mov 寄存器,内存单元
          mov 内存单元,寄存器
          mov 段寄存器,寄存器
          mov 寄存器,段寄存器
  1. 运算指令

          add 寄存器,数据
          add 寄存器,寄存器
          add 寄存器,内存单元
          add 内存单元,寄存器
          sub
  1. 转移指令

          转移指令能够修改ip或cs,例如jump 2000:0,实际上就是把cs改成2000,ip改成0,那么下一条指令就是从2000:0开始执行。

六、编程前的总结

  1. 关于寄存器与地址表示

          CS:IP   和指令有关
          DS:[0] [1] …  和数据有关
          SS:SP  临时性数据(栈)
  1. 关于指令执行的过程

          通过汇编指令修改CPU中寄存器中的内容。需要考虑的问题有:
          (1)数据在哪里?
          (2)数据的长度:字节型数据 字型数据    AX BX CX DX   AH AL BH BL
          (3)数据的处理    ADD    SUB
          (4)数据存放到哪里?
  1. 关于程序员的工作

          数据是我们程序自己安排,存放在哪里也要自己安排,指令在哪里也要自己安排——相比高级语言,汇编语言给程序员绝对的自由,然而自由的代价是谨慎,汇编语言比高级语言更容易出现种种问题。
相关教程