汇编 第三章 寄存器(内存访问)

第三章 寄存器(内存访问)

3.1 内存中字的存储

在这里插入图片描述

1.任何两个地址连续的内存单元,N号单元和N+1号单元,可以将他们看成两个存储单元
    也可以看成一个地址为N的字单元中的高位字节单元和低位字节单元
2.注意:在内存的表示中,从高到低,是从0号单元开始,然后逐渐变大,
    即在书写时,低位写在高的地方,高位写在低的地方,
    如上图所示:4E20H即是0号字节存储20,1号字节存储4E,如果是0号字则存的是4E20H(字=2字节)
3.2 DS和[address]
1.8086中有一个DS寄存器,通常用来存放要访问的数据的段地址
2.例如:我们要读取10000H单元的内容可以用如下程序段进行:
    mov bx,1000H
    mov ds,bx
    mov al,[0]
  上面的三条指令将10000H(1000:0)中的数据读到al(8bit)中
    1.复习:已知mov指令可以完成的两种传送功能
        1.将数据直接送入寄存器
        2.将一个寄存器中的内容送入另一个寄存器中
    2.除此之外,mov指令还可以将一个内存单元中的内容送入一个寄存器
        mov指令格式:mov 寄存器名,内存单元地址
        [...]表示一个内存单元,“[...]”中的...表示内存单元的【偏移地址】
        执行指令时,8086CPU自动取DS中的数据为内存单元的【段地址】
    3.如何把1000H放入DS中?
        要通过通用寄存器把段地址传入到DS中
        8086CPU不支持将数据直接送入段寄存器的操作,DS是一个段寄存器
        即:mov ds,1000H  是非法的(硬件设计的问题)
        数据->通用寄存器->段寄存器
3.写几条指令,将AL中的数据送入内存单元10000H?
    mov bx,1000H
    mov ds,bx
    mov [0],al      ;al中的字节型数据送入到1000H:0中
3.3 字的传送
1.8086CPU是16位结构,有16根数据线,所以可以一次性传送16位的数据
    即:一次可以传送一个字
2.比如
    mov bx,1000H
    mov ds,bx
    mov ax,[0]      ;1000H:0处的字型数据送入ax中
    mov [0],cx      ;cx中的16位数据送入到1000H:0中
3.4 mov、add、sub指令
1.复习:已学mov指令的几个形式
    1.mov 寄存器,数据         ;立即寻址
    2.mov 寄存器,寄存器        ;寄存器寻址
    3.mov 寄存器,内存单元      ;直接寻址
    4.mov 内存单元,寄存器      ;寄存器寻址?
    5.mov 段寄存器,寄存器      ;寄存器寻址
    6.mov 寄存器,段寄存器      ;寄存器寻址
2.add、sub同mov一样,都有两个操作对象
    1.add的用法
        1.add 寄存器,数据      ;立即寻址
        2.add 寄存器,寄存器    ;寄存器寻址
        3.add 寄存器,内存单元  ;直接寻址
        4.add 内存单元,寄存器  ;
    2.sub的用法
        【不带借位的减法】
        指令格式 sub op1,op2    ;意为:op1=op1-op2
        1.sub 寄存器,数据      ;立即寻址
        2.sub 寄存器,寄存器    ;寄存器寻址
        3.sub 寄存器,内存单元  ;直接寻址
        4.sub 内存单元,寄存器  ;
3.5 数据段
如何访问数据段中的数据?
    将一段内存当作数据段,是我们在编程时的一种安排
    具体操作:用DS存放数据段的段地址,再根据需要,用相关指令访问数据段中的具体单元
3.6 栈和cpu提供的栈机制
1.8086CPU提供相关的指令来以栈的方式访问内存空间
    这意味着,我们在基于8086CPU编程的时候,可以将一段内存当作栈来使用
2.8086CPU提供入栈和出栈指令:(最基本的)
    push(入栈)
    pop(出栈)
    1.push ax:将寄存器ax中的数据送入栈中
    2.pop ax:从栈顶取出数据送入ax
    3.8086CPU的入栈和出栈操作都是以【字(16位)】为单位进行的
    4.pop和push可以在寄存器和内存之间传送数据
3.CPU如何知道一段内存空间被当做栈使用?
    1.8086CPU中,有两个寄存器
        1.段寄存器SS:存放栈顶的段地址
        2.寄存器SP:存放栈顶的偏移地址【专用寄存器】
    2.任意时刻SS:SP指向栈顶元素,当栈为空的时候,也就不存在栈顶元素
        ss:sp也就指向栈最高地址单元的下一个单元
4.执行push和pop的时候,如何知道哪个单元是栈顶单元?
    1.执行push ax时
        1.sp=sp-2
        2.将ax中的内容送入到ss:sp指向的内存单元
            ss:sp此时指向新栈顶
    2.执行pop ax时
        1.将ss:sp指向的内存单元的内容送入到ax中
            注意:这里取出的内容在内存中还是存在的,并没有被重置
                下一轮push会覆盖
        2.sp=sp+2
5.如果栈是空的,sp指向哪里?
    sp指向最高地址单元的下一个单元

在这里插入图片描述

3.7 栈顶超界的问题 push/pop指令
ss、sp只记录了栈顶的地址,依靠ss、sp可以保证在入栈和出栈时找到栈顶
可以,如何能够保证在入栈、出栈时,栈顶不会超出栈空间?
1.8086CPU不保证栈的操作不会越界
2.当栈空的时候,再执行pop出栈 或者 当栈满的时候再使用push入栈
    都会发生栈顶超界问题,会操作到栈以外的数据,
    这些数据可能是其他用途的数据或者代码
    栈顶超界是危险的!!!
3.8086CPU没有记录栈顶上下限的寄存器
push ds:将段寄存器ds中的数据送入栈中
pop es:从栈顶取出数据送入段寄存器es
push[0]:将内存单元 ds:0中的数据送入栈中
pop [2]:从栈顶取出数据送入ds:[2]内存单元
3.8 栈段
1.将一段内存当做栈段,仅仅是我们在编程时的一种安排,
2.ss:sp指向我们定义的栈段的栈顶;
3.当栈空时,sp指向最高地址的下一个单元
4.思考:一个栈段最大可以设为多少?
    64KB
5.设栈顶的变化范围是0-FFFFH,从栈空时sp=0(最高地址单元FFFFH的下一个单元0000H)
    一直压栈,直到栈满,sp=0;
    如果再次压栈,栈顶将环绕,覆盖原来栈中的内容
6.一段内存,既可以是代码的存储空间,又可以是数据的存储空间,还可以是栈空间
    也可以是什么都属实。
    关键在于CPU中寄存器的设置,即:cs、ip、ss、sp、ds的设置
    **可以通过mov直接给sp赋值【立即数寻址】,但是不能通过mov给cs、ip、ss、ds赋值
        给cs和ip赋值需要使用jum指令
        给ss和ds赋值需要使用mov ss或ds,寄存器   ;【寄存器寻址】

【实验二】
在这里插入图片描述

执行过程中发现mov sp,10 不见了,跟随mov ss,ax一起执行了。为什么会这样呢?要想彻底说清楚这里面的来龙去脉,在这里还为时过早,因为这涉及我们在以后的课程中要深入研究的内容:中断机制,它是我们后半部分课程中的一个主题。现在我们只要知道这一点就可以了:Debug 的T命令在执行修改寄存器SS 的指令时,下一条指令也紧接着被执行。

继续执行可以看到栈中数据放入了 3123,3366
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值