X86汇编语言总结

时间:2022-10-28 19:27:25

下载地址:点击打开下载链接

  • AX、BXCXDX一般用来存放数据

  • [BX][BP][SI][DI]中一般存放着某个段寄存器的偏移地址,默认情况下,[BX]中存放着数据段(DS)的偏移地址,[BP]中存放着栈段(SS)的偏移地址(功能和SP类似),其中BX只能和SI、DI组合,BP只能和SI、DI组合,SI、DI间是不能组合的

  • Loop指令一般搭配着CX寄存器使用,每循环一次,CX寄存器中的值减少1

  • 执行PUSH指令时,SP-2,执行POP时,SP+2
  • 个人的一点总结:压栈时,先减后压;出栈时,先出后加

  • dw表示define word,即定义字,有16位
  • db表示define byte,即定义字节,有8位
  • dd表示double world,即定义双字,有32位

  • ptr来指定程序操作的内存的具体的大小
  • 例如:

mov wordptr ds:[0],1                   表示将1存放到大小为一个字(两个字节)的内存单元中

mov byte ptrds:[0], 1                           表示将1存放到大小为一个字节的内存单元中

  • div除法指令;inc:++指令;

  • dup是一个操作符,在汇编语言中同db、dw、dd等一样,也是由编译器识别处理的符号(伪指令)。Dup通常和db、dw、dd配合起来使用。dup示例如下:

db 3 dup(0) ------à定义了3个字节,它们的值都是0,相当于db 0,0,0

db 3 dup(0, 1, 2)-----à定义了9个字节,它们是:0、1、2、0、1、2、0、1、2

  • offset在汇编语言中是由编译器处理的符号,它的功能是取得标号的偏移地址。

  • NOP空操作指令,功能: 本指令不产生任何结果,仅消耗几个时钟周期的时间,接着执行后续指令,常用于程序的延时等。

  • Jmp short ptr 标号

Ø  8位位移=“标号”处的地址-jmp指令后的第一个字节的地址;

Ø  Short ptr指明此处的位移为8位位移,进行的是段内短转移

Ø  8位位移的范围是:-127 ~ 12,用补码表示

Ø  8位位移由编译器在编译时算出。

  • Jmp near ptr 标号

Ø  16位位移=“标号”处的地址-jmp指令后的第一个字节的地址

Ø  Near ptr指明此处的位移为16位位移,进行的是段内近转移

Ø  16位位移的范围是:-32769 ~ 32767,用补码表示

Ø  16位位移由编译器在编译时算出。

  • Jmp far ptr 标号

Ø  实现的是段间转移,又称为远转移。

Ø  Far ptr指明了指令用标号的段地址和偏移地址修改CS和IP。

  • Jmp word ptr 内存单元地址(段内转移)

Ø  内存单元地址开始处存放着一个字,是转移的目的地址。

Ø  内存单元地址可用寻址方式的任一格式给出。

  • Jmp dword ptr 内存单元地址(段间转移)

Ø  从内存单元地址处开始存放着两个字(四字节),高地址处的字是转移的目的段地址,低地址处是转移的母的偏移地址。

(CS) =  (内存单元地址+2)

(IP) =  (内存单元地址)

Ø  内存单元地址可用寻址方式的任一格式给出。

  • Jcxz指令为有条件转移指令,所有的有条件转移指令都是短转移,在对应的机器码中包含转移的位移,而不是目的地址。对IP的修改范围都为-128 ~ 127。

Ø  指令格式:jcxz 标号如果(CX) = 0,则转移到标号处执行

Ø  当(cx)= 0时,(IP)=(IP)+ 8位位移

  • Ret指令用栈中的数据,修改IP的内容,从而实现近转移!

Ø  CPU执行ret指令时,进行下面两步操作:

(1)(IP) = ((SS) * 16 + (SP))

(2)(SP) = (SP) +2

  • Retf指令用栈中的数据,修改CS和IP的内容,从而实现远转移

Ø  CPU执行retf指令时,进行下面两步操作:

(1)     (IP) = ((SS) * 16 + (SP))

  (SP) = (SP) + 2

(2)    (CS) = ((SS) * 16 + (SP))

  (SP) = (SP) + 2

  • Call指令经常跟ret指令配合使用。

Ø  一次CPU执行call指令,进行如下两步操作:

(1)将当前的IP或CS和IP压入栈中;

(2)转移(jmp)

Ø  Call指令不能实现短转移,除此之外,call指令实现转移的方法和jmp指令的原理相同。

Ø  Call 标号(将当前的IP压栈后,转移到标号处执行指令.)。

Ø  CPU执行此种格式的call指令时,进行如下的操作:

(1)(SP) = (SP) – 2

           ((SS) * 16 + (SP)) = (IP)

(2)(IP) = (IP) + 16位位移

²  16位位移 = “标号”处地址 – call指令后的第一个字节的地址;

²  16位位移的范围为-32768 ~ 32767,用补码表示;

²  16位位移由编译器在编译时算出。

  • Call far ptr 标号指令的操作:

Ø  (1) (SP) = (SP) – 2

  ((SS) * 16 + (SP)) = (CS)

  (SP) = (SP) – 2

  ((SS) * 16 + (SP)) = (IP)

                   (2)(CS) = 标号所在的段地址

                (IP) = 标号所在的偏移地址

  • Call 16位寄存器

Ø  操作过程:

(SP) = (SP) – 2

((SS) * 16 + (SP)) = (IP)

(IP) = (16位寄存器)

  • 转移地址在内存中的call指令格式:

Ø  (1)call word ptr内存单元地址

  call dword ptr内存单元地址

  • Mul乘法指令,若乘数位8位则乘积默认保存在AX中,若乘数位16位在乘积保存在DX和AX中。

  • Int()描述性运算符,取商,例如:int(38/10) = 3

  • Rem()描述性运算符,取余数,例如:rem(38/10) = 8

  • 标志寄存器:

Ø  ZF零标志位(第6位)-à运算结果为零,则此位为1

Ø  PF奇偶标志位(第2位)---à运算结果中含1的个数是偶数,则此位为1

Ø  SF符号标志位(第7位)---à运算结果为负,则此位为1

Ø  CF进位标志位(第0位)--à无符号数运算若产生进位或借位,则此位为1

Ø  OF溢出标志位(第1位)--à有符号数运算若产生溢出,则此位为1

Ø  DF方向标志位(第10位)àDF = 0每次操作后si,di递增;DF = 1每次操作后si,di递减

  • Adc 操作对象1,操作对象2    是带进位加法指令

Ø  功能:操作对象1 = 操作对象1 + 操作对象2 +CF

  • Sbb 操作对象1,操作对象2     是带借位的减法指令

Ø  功能:操作对象1 = 操作对象1 – 操作对象2 – CF

  • Cmp指令

Ø  格式:cmp操作对象1,操作对象2

Ø  功能:计算操作对象1 – 操作对象2但并不保存结果,仅仅根据计算结果对标志寄存器进行设置。

  • 检测比较结果的条件转移指令

Ø  条件转移指令小结

指令

含义

检测的相关标志位

Je

等于则转移

ZF = 1

Jue

不等于则转移

ZF = 0

Jb

低于则转移

CF = 1

Jnb

不低于则转移

CF = 0

Ja

高于则转移

CF = 0, ZF = 0

Jna

不高于则转移

CF = 1或ZF = 1

  • Movsb指令

Ø  功能:(以字节为单位传送)

(1)((ES) * 16 + (DI)) = ((DS) *16 +(SI))

(2)如果DF = 0,则:(si) = (si) + 1

                             (di) = (di) + 1

如果DF = 1,则:(si) = (si) – 1

                                (di) = (di) – 1

  • Movsw指令

Ø  功能:(以字为单位传送)

(1)((ES) * 16 + (DI)) = ((DS) * 16 + (SI))

(2)如果DF = 0,则:(si) = (si) + 2

                             (di) = (di) + 2

          如果DF = 1,则:(si) = (si) – 2

                             (di) = (di) – 2

Ø  Movsbmovsw一般都是和rep指令配合使用的。

²  格式:rep movsb或 repmovsw

²  Rep的作用是根据cx的值,重复执行后面的串传送指令

  • cld指令:将标志寄存器的DF位设置为0

  • std指令:将标志寄存器的DF位设置为1

  • pushf指令:将标志寄存器的值压栈

  • popf指令:从栈中弹出数据送入标志寄存器中

  • 8086CPU中断过程:

Ø  (1)取得中断类型码N

     (2)pushf  ==========è 将标志寄存器的值压入栈中,保护标志寄存器中的数据

     (3)TF = 0,IF = 0  ===è 设置标志寄存器的第8位TF和第9位IF设置为0

     (4)push CS  ========è 将此处的代码段的段地址压入栈中

     (5)push IP  ========è 将此处的代码段的偏移地址压入栈中

     (6)(IP)= (N * 4) , (CS) = (N * 4 + 2)  è根据中断类型码计算中断处理程序的入口地址

  • Iret指令:通常和硬件自动完成的中断过程配合使用

Ø  Iret功能描述(汇编语言描述):    pop IP

pop CS

popf

Ø  Iret的出栈顺序:IPCS、标志寄存器

  • 汇编编译器是识别“+”、“-”、“*”、“/”的。

Ø  Mov ax, (5 + 3) * 5 / 10就等效于mov ax, 4

  • 中断向量表:

Ø  中断向量表存储在内存中的0 ~3FFh(即0 ~ 1023,这1024个字节空间中)的内存中

Ø  在中断向量表中,每4个字节确定一个中断类型

Ø  每个中断类型都有一个中断类型码,用来唯一标示该中断类型

Ø  每个中断类型的4个字节指向中断处理程序的入口地址,其中前2个字节用来存储中断处理程序的偏移地址(即IP),后2个字节用来存储中断处理程序的段地址(即CS)

Ø  每个中断类型的4个字节的存储工作都是程序员通过代码来实现

  • 单步中断(中断类型码为1

Ø  CPU在执行完一条指令之后,如果检测到标志寄存器的TF位为1,则产生单步中断,引发中断过程。

Ø  单步中断的中断类型码为1,他所引发的中断过程如下:

²  (1)取得中断类型码1

   (2)标志寄存器入栈,TF、IF设置为0

   (3)CS、IP入栈

   (4)(IP) = (1 * 4), (CS) = (1 * 4 + 2)   

  • Int指令

Ø  格式:int n     ====èn为中断类型码。它的功能是引发中断过程

Ø  CPU执行int n指令,相当于引发一个n号中断的中断过程,执行如下:

²  (1)取中断类型码n ;

   (2)标志寄存器入栈,IF = 0,TF = 0 ;

   (3)CS、IP入栈;

   (4)(IP) = (n * 4), (CS) = (n * 4 + 2)