汇编语言程序知识点整理

1.debug的六种指令

Debug是DOS、Windows都提供的实模式(8086)程序的调试工具。使用它可以查看CPU各种寄存器中的内容、内存情况和在机器码级跟踪程序的运行。

  • 用Debug的R命令查看、改变CPU寄存器的内容
  • 用Debug的D命令查看内存中的内容
  • 用Debug的E命令改写内存中的内容
  • 用Debug的U命令将内存中的机器指令翻译成汇编指令
  • 用Debug的T命令执行一条机器指令
  • 用Debug的A命令以汇编指令的格式在内存中写入一条机器指令

实操:

  • 用Debug的R命令查看、改变CPU寄存器的内容
    1. 首先输入debug进入Debug模式
    2. 然后输入r查看寄存器内容
    3. 输入r ax可以改变ax中的内容
    4. 输入5678回车,即可看见AX=5678

  • 用Debug的D命令查看内存中的内容

    如果想要知道内存10000H处的内容,可以用“d 段地址:偏移地址”的格式进行查看

    1. 输入d 1000:0

    2. 输入d 0000:9可见它从第九位开始输出内容
      在这里插入图片描述

  • 用Debug的E命令改写内存中的内容

    1. 如果我们想改写0000:0000地址以后的数据

    2. 我们输入e 0000:0000 12 23 34 45 56 67 78代表从0000:0000这个地址往后7个地址进行改写

    3. 我们输入d 0000:0000进行查看可见0000:0000往后7个地址内容已经被改变
      在这里插入图片描述

    4. 我们可以输入e 0000:0000回车 然后会出现逐个改变

    5. 我们将12->AB 23->CD回车

    6. 输入d 0000:0000可以查看内容已经被更改
      在这里插入图片描述

  • 用Debug的A命令以汇编指令的格式在内存中写入一条机器指令

    1. 我们输入a 073F:0100回车
    2. 输入add bx,ax回车,再输入mov cx,ax指令,回车
  • 用Debug的T命令执行一条机器指令

    1. 我们连续t即可执行上面写入的机器指令

    2. 可见BX:0000->5678 CX:0000->5678

在这里插入图片描述

  • 用Debug的U命令将内存中的机器指令翻译成汇编指令

    1. 我们输入d 073F:0100可见内存中有01 C3 89 C1

    2. 然后输入u 073F:0100可见将指令翻译成汇编指令

在这里插入图片描述

2.mov、add、sub指令

1.mov指令

  • mov 寄存器,数据
    • mov ax,8
  • mov 寄存器,寄存器
    • mov ax,bx
  • mov 寄存器,内存单元
    • mov ax,[0]
  • mov 内存单元,寄存器
    • mov [0],ax
  • mov 段寄存器,寄存器
    • mov ds,ax
  1. 我们输入a 073F:0100输入指令
  2. 然后输入三次t执行指令
  3. 可见AX:0000->0008 BX:0000->0008 CX:0000->1000
    在这里插入图片描述

在这里插入图片描述

  1. mov ah,13意思就是将13赋给ax的高八位AX:0008->1308
  2. mov bl,22意思就是将22赋给bx的低八位BX:0008->0022
  3. mov ch,ah意思就是将ah的高八位给cx的高八位CX:1000->1300

2.add指令

  • add 寄存器,数据
    • add ax,8
  • add 寄存器,寄存器
    • add ax,bx
  • add 寄存器,内存单元
    • add ax,[0]
  • add 内存单元,寄存器
    • add [0],ax
  1. 我们输入a将指令存进去
  2. add ax,3意思就是将ax+3,因为十六进制08+03=B,所以1308->130B
  3. add bx,4意思就是将bx+4,因为十六进制22+04=26,所以0022->0026
  4. add cx,bx意思就是将bx加到cx身上,因为十六进制0026+1300=1326

在这里插入图片描述

3.sub指令

  • sub 寄存器,数据
    • sub ax,9
  • sub 寄存器,寄存器
    • sub ax,bx
  • sub 寄存器,内存单元
    • sub ax,[0]
  • sub 内存单元,寄存器
    • sub [0],ax
  1. 我们输入a将指令存进去
  2. sub ax,8意思就是ax-8,所以130B-8=1303
  3. sub bx,F意思就是bx-F,所以0026-F=0017
  4. sub ax,bx意思就是ax-bx,所以1303-0017=12EC
    在这里插入图片描述

3.其它指令

1.mul指令

mul指令是乘法指令

注意点:

  1. 两个相乘的数:两个相乘的数,要么都是8位,要么都是16位。如果8位,一个默认放在AL中,另一个放在8位reg或内存字节单元中;如果是16位,一个默认放在AX中,另一个放在16位reg或内存字单元中。
  2. 结果:如果是8位乘法,结果默认是放在AX中;如果是16位乘法,结果高位默认放在DX中,低位在AX中放。

实操:

  1. mov ax,64
  2. mov bx,A
  3. 使用t指令操作指令存放数据
  4. mul bl
  5. 0064*000A=03E8

在这里插入图片描述

  1. mov ax,64
  2. mov bx,2710
  3. mul bx
  4. 因为是十六进制,所以64*2710=F4240高位在DX中存放,低位在AX中存放

在这里插入图片描述

2.div指令

div是除法指令,使用div做除法的时候应该注意以下问题:

  1. 除数:有8位和16位两种,在一个reg或内存单元中。
  2. 被除数:默认放在AX或DX和AX中,如果除数为2位,被除数则为16位,默认在AX中存放;如果除数为16位,被除数则为32位,在DX和AX中存放,DX存放高16位,AX存放低16位
  3. 结果:如果除数为8位,则AL存储除法操作的商,AH存储除数操作的余数;如果除数为16位,则AX存储除数操作的商,DX存储除数操作的余数。

实操:

  1. mov ax 2711
  2. mov bl,64
  3. div b1
  4. 2711的十进制10001,64十进制100,10001/100余数为1,存放在AH

在这里插入图片描述

3.and指令

逻辑与指令,按位进行与运算

例如指令:

mov al,01100011B

and al,00111011B

执行结果:al = 00100011B两位都为1才为1

通过该指令可将操作对象的相应为设为0,其他位不变

4.or指令

逻辑或指令,按位进行或运算

例如指令:

mov al,01100011B

or al,00111011B

执行结果:al = 01111011B只要一位为1就为1

通过该指令可将操作对象的相应位设位1,其他位不变

5.shl指令

shl是逻辑左移指令,它的功能为:

  1. 将一个寄存器或内存单元中的数据向左移位
  2. 将最后移出的一位写入CF中
  3. 最低位用0补充

指令:mov al 01001000B

shl al,1

执行结果:al = 10010000b CF=0

6.shr指令

shr是逻辑右移指令,它的功能:

  1. 将一个寄存器或内存单元中的数据向右移位
  2. 将最后移出的一位写入CF中
  3. 最低位用0补充

如果移动位数大于1,必须将移动位数放在cl中

mov al,01010001b

mov cl,3

shl al,cl

执行结果:al = 10001000b CF = 0

在这里插入图片描述

上述操作:左移一位变成90,右移一位回到48

7.inc指令

类似于i++操作

8.dec指令

类似于i–操作

在这里插入图片描述

9.xchg指令

  1. 作用:用于交换两个数据的内容的一个指令

在这里插入图片描述

10.neg指令

  1. 即用0减操作数,并将求得的结果存入指定的寄存器或内存单元(把操作数按位取反,末位加1

4.寄存器

1.通用寄存器

8086CPU的所有寄存器都是16位,可以存放两个字节。AX、BX、CX、DX这四个寄存器通常用来存放一般性数据,被称为通用寄存器。
在这里插入图片描述

8086CPU的AX、BX、CX、DX这四个寄存器都可分为两个可独立使用的8位寄存器来使用:

  • AX可分为AH和AL
  • BX可分为BH和BL
  • CX可分为CH和CL
  • DX可分为DH和DL
    在这里插入图片描述

2.字在寄存器中的存储

8086CPU可以一次性处理以下两种尺寸的数据:

  1. 字节:记为byte,一个字节由8个bit组成,可以存在8位寄存器中
  2. 字:记为word,一个字由两个字节组成,这两个字节分别称为这个字的高位字节和低位字节

在这里插入图片描述

3.物理地址

CPU访问内存单元时,要给出内存单元的地址。所有内存单元构成的存储空间是一个一维的线性空间,每一个内存单元在这个空间中都有唯一的地址,我们称为物理地址。

CPU通过地址总线送入存储器的,必须是一个内存单元的物理地址。在CPU向地址总线上发出物理地址之前,必须要在内部先形成这个物理地址。不同的CPU可以有不同的形成物理地址的方式。

8086CPU有20位地址总线,可以传送20位地址,达到1MB的寻址能力。8086CPU又是16位结构,在内部一次性处理、传输、暂时存储的地址为16位。从8086CPU的内部结构来看,如果将地址简单的发出去,那么它只能送出16位地址,表现出的寻址能力只有64KB。

在这里插入图片描述

4.段地址x16+偏移地址=物理地址

  1. 本质含义:CPU在访问内存时,用一个基=基础地质(段地址X16)和一个相对于基础地址的偏移地址相加,给出内存单元的物理地址。

5.CS和IP

CS和IP是8086CPU中两个最关键的寄存器,他们指示了CPU当前要读取指令的地址。CS为代码寄存器,IP为指令指针寄存器。

在8086CPU中,任意时刻,设CS中的内容为M,IP中的内容为N,8086CPU将从内存MX16+N单元开始,读取一条指令并执行。

在这里插入图片描述

  1. 我们存放几条指令,发现t指令没有执行
  2. 然后我们将cs和ip指向2000:0000然后执行t指令,发现指令执行
    在这里插入图片描述

6.jmp指令

  1. 作用:同时修改CS、IP的内容,可用形如jmp 段地址:偏移地址的指令完成

  2. 例如:

    1. jmp 2AE3:3执行后:CS = 2AE3H IP = 0003HCPU将从2AE33H开始读取指令

    2. jmp 3:0B16执行后:CS = 0003H IP = 0B16HCPU将从30B16开始读取指令

    3. jmp ax 指令执行前:AX = 1000H CS = 2000H IP = 0003H

      执行指令后:AX = 1000H CS = 2000H IP = 1000H

  3. jmp 某一合法寄存器 之类的功能:用寄存器中的值修改为IP

  4. jmp ax 在含义上好似: mov IP,ax

实操:

在这里插入图片描述

  1. 输入以上指令
  2. 我们首先执行t指令执行,发现AX:0006->6622
  3. 再次执行t指令,可见CS和IP的地址变成了1000:0003
  4. 执行t指令,发现AX:6622->0000

在这里插入图片描述

7.push、pop指令

在这里插入图片描述

8086CPU中,有两个寄存器,段寄存器SS和寄存器SP,栈顶的段地址存放在SS中,偏移地址存放在SP中。任意时刻,SS:SP指向栈顶元素。push和pop指令执行时,CPU从SS和SP中得到栈顶的地址。

实操:

  1. 将10000H-1000FH这段空间当作栈,初始状态栈是空的
  2. 设置AX=001AH,BX=001BH
  3. 将AX和BX中的数据入栈
  4. 然后将AX、BX清零
  5. 从栈中恢复AX、BX原来的内容

代码如下:

mov ax,1000H
mov ss,ax		;不能直接向段寄存器中送入数据,所以用ax中转
mov sp,0010H

mov ax,001AH
mov bx,001BH

push ax
push bx

sub ax,ax	;将ax清零
sub bx,bx

pop bx	;恢复AX,BX中原来内容,所以需要先pop bx,再
pop ax
pop ax

5.寻址方式

1.[bx+idata]

我们用[bx]来指明一个内存单元,还可以用一种更为灵活的方式来指明内存单元。[bx+idata]表示一个内存单元,它的偏移地址为(bx)+idata(bx中的数值加上idata)

mov ax,[bx+200]

将一个内存单元的内容送入ax,这个内存单元的长度为2个字节,存放一个字,偏移地址为bx中的数值加上200,段地址在ds中

实操:

  1. 首先我们在内存2000:1000写入数据BE 00 06
  2. 然后使用a指令存入指令
  3. 使用t指令操作指令
  4. 发现mov ax,2000H执行后AX: 0000->2000
  5. 发现mov ds,ax执行后DS:073F->2000
  6. 发现mov bx,1000H执行后BX:0000->1000
  7. 发现mov ax,[bx]执行后AX:2000->00BE
  8. 发现mov cx,[bx+1]执行后CX:0000->0006

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

2.[bx+si]、[bx+di]

[bx+si]表示一个内存单元,它代表的偏移地址为(bx)+(si)

mov ax,[bx+si]

将一个内存单元的内容送入ax,这个内存单元的长度为2字节,存放一个字,偏移地址为bx中的数值加上si中的数值,段地址在ds中

实操:

  1. 首先我们使用a指令存入数据
  2. 我们使用t指令执行指令
  3. 发现mov ax,[bx+si]执行后AX:2000->00BE
  4. 发现mov cx,[bx+si]执行后CX:0000->0600
  5. 发现add cx,[bx+di]执行后CX:0600->0606
    在这里插入图片描述

在这里插入图片描述

6.标志寄存器

1.ZF

零标志位,它记录相关的指令执行后,其结果是否为0,如果结果为0,那么ZF=1;如果结果不为0,那么ZF=0

实操:

mov ax,1

sub ax,1

结果为0,ZF=1

mov ax,2

sub ax,1

结果为1,ZF=0

2.PF

奇偶标志位,它记录相关的指令执行后,其结果的所有bit位中1的个数是否为偶数。如果1的个数为偶数,PF=1,如果为奇数,PF=0。

实操:

mov al,1

add al,10

结果为:00001011B,3(奇数)个1,则PF=0

3.SF

符号标志位,它记录相关的指令执行后,其结果是否为负。如果为负数,SF=1,如果非负,SF=0。
在这里插入图片描述

实操:

mov al,10000001B

add al,1

结果为:10000010B SF=1

mov al,10000001B

add al,0111111B

结果:0 SF=0

4.CF

进位标志位,一般情况下,在进行无符号数运算的时候,它记录了运算结果的最高有效位向更高位的进位值,或从更高位的借位值。

5.OF

在进行有符号数运算的时候,结果如果超过了机器所能表示的范围,称为溢出。
溢出标志位,发生溢出,OF=1,没有溢出,OF=0。
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值