汇编语言学习的一些小总结

来源:互联网 发布:淘宝权重低怎么办 编辑:程序博客网 时间:2024/04/30 03:48

8086汇编学习笔记(一)

8086汇编常用的十六位寄存器:AX,BX,CX,DX,CS,DS,ES,SS,BP,IP,SP,DI,SI

其中AX,BX,CX,DX,BP,IP,SP,DI,SI为通用寄存器

CS,DS,ES,SS称作段寄存器

 

注:通用寄存器可以装入立即数,但段寄存器不能直接装入立即数。

如果想要向段寄存器中装入数字,需要先将立即数装入通用寄存器,然后再将寄存器中的数字转到目标段寄存器中。

 

注意:对于8086汇编指令此处使用Intel的描述规则,实际上AT&T还有另一套规则,不过二者无太大差别,若无特别说明,本文中使用Intel的规则。

 

首先先确定,在Intel体系的指令中,一般采用: 指令 目的寄存器 源寄存器/立即数 的形式

采用这种操作的指令有:mov ,add ,div 等

如:mov  ax , 2 或者 add  ax , bx 的形式

此处 mov 为移位指令表示把一个数字从源寄存器移动到目标寄存器,add 为算数加法指令,表示将源寄存器中的数据与目标及村中的数据加和,并放入目标寄存器中。

 

还有一些指令比如 jmp 跳转指令,这个指令可以使程序跳转

这个指令的形式为 jmp  data ,其本质是修改IP寄存器中的数值以实现程序的跳转

还有 inc 指令,用法为 inc  ax(目的寄存器)

 

有了以上对指令的一些基本认识,接下来就上面所说的一些寄存器进行更加详细的介绍

首先介绍段寄存器:段寄存器比较重要,希望大家将功能记清楚,以避免出错

在介绍这些寄存器之前,还要介绍一下8086的内存寻址方式,由于汇编是对内存中的数据进行直接的读写操作,所以明白其内存如何寻址很重要。

8086 的内存读取采用 段地址偏移地址的表现形式。

具体为地址 = 段地址X 16 + 偏移地址

比如:一内存地址表述为1000:ffe0  /*十六进制*/  则其在内存中的地址为1000x10 +ffe0=1ffe0 。注:16D的十六进制表示为10H

附:一些debug 的参数说明。

         -r 用来查看当前寄存器的状态。

也可以来修改寄存器中的内容(如下图)

要修改的内容

         -a 用来输入一段汇编代码

       -t 同来执行cs:ip指向的汇编代码

-u 会列出从当前cs:ip开始向后的十六条汇编指令以及相应的地址和二进制码

 

段寄存器

 

8086的段寄存器有CS  ,DS ,ES  ,SS。

段寄存器中一般装的是内存寻址时的段地址,此寄存器只能从通用寄存器中移入数据

而不能直接装入立即数。

如图示: (错误)

 

上图为正确的运行过程及输出结果。

1.      DS寄存器

DS寄存器一般用来存放要访问内存的段地址,用法如:

mov ax , 1000

mov ds ,ax

mov ax ,[ds:ffff]

分析:这段代码执行时,先将立即数1000H装入通用寄存器AX中,让后将AX中的数据移入ds段寄存器中,然后利用将内存地址为1000 : ffff 的数据装入寄存器AX中

2.      CS寄存器

CS寄存器用来存放汇编代码指令存放执行时的地址,指令执行时,会先从CS:IP指向的内存中取出指令,交给cpu此时IP 会根据指令而变化,从而指向下一条指令所在区域,然后循环以上过程即可。具体如上图所示。

3.      SS寄存器

SS寄存器又叫栈寄存器,用来定义一段栈,通常与SP配合使用,寻址时常用SS:SP的形式。SP为栈指针,通常进行压栈,出栈操作时sp指针会进行一些变化。

4.      ES寄存器

ES寄存器

通用寄存器

通用寄存器除了常见的AX,BX,CX,DX外还有BP,SP,DI,SI。

其中AX通常存储回调函数的返回值

而DX则在进行除法运算时有特别用处,8086进行16位的除法时,在AX中装入被除数,而除数作为DIV 后面的指令给出,例如:DIV  DX。当除法运算进行完以后寄存器AX中会装入运算的商,DX中会装入运算后的余数。

寄存器SP通常作为栈指针来使用。

转移指令

凡是对寄存器CS 和寄存器IP 进行修改的指令都称为转移指令。

常见如:JMP,CALL,RET等

JMP 多用于直接修改 例如:JMP word ptrDS:XXXX

而CALL与RET相较之JMP略有不同,JMP不用操作栈,而CALL与RET指令均需要对栈进行操作,不同之处在于,前者需要压栈,而后者需要出栈,且操作对象正是程序的执行顺序指令CS:IP 。

CALL指令在执行时可以按照汇编语言拆解为两步动作。

第一,  先将CS,IP分别入栈(注意:此处实际应考虑转移的远近,如果是近转移则只需将IP压栈,而无需将CS压栈。如果此处是远转移则按照如上所述将二者顺序压栈)。

此处相当于: PUSH CS

                       PUSH IP

第二,  需要将程序指令转移至变化后的CS:IP所指向的指令。

此处相当于JMP word ptr 内存单元。

与此类似RET指令在执行时可将其看做拆解后的CALL指令执行时第一步的反过程

即:POP IP

POP CS

其实RET指令类似于POP IP,RETF指令类似于POP IP  , POP CS两步。

而CALL与RET指令一起使用时能起到调用子函数的功能,过程大致可以描述为:由CALL开始将CS:IP压栈保存程序转移至子函数处执行,执行完毕后利用RET指令,再将CS:IP出栈恢复到原函数。(此处应当注意,在CALL执行时,会先有指令计数器IP的变化,之后才会进行跳转)。