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

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

3.1 内存中的字存储

CPU 中用16位寄存器存储一个字,高8位存放高位字节,低8位存放低位字节。内存单元是字节单元,一个单元存放一个字节,一个字需要使用两个连续的内存单元进行存放,这个字的低位字节存放在低地址单元,高位字节存放在高地址单元

image

问题:

  1. 0地址单元存放的字节型数据是多少?20
  2. 0地址单元存放的字型数据是多少?4E20
  3. 2地址单元存放的字节型数据是多少?12
  4. 2地址单元存放的字型数是多少?0012
  5. 1地址单元存放的字型数据是多少?124E

3.2 DS 和 [address]

CPU 要读写一个内存单元的时候,必须给出这个内存单元的地址。内存单元的地址由段地址和偏移地址组成。DS 寄存器通常需要存放访问数据的段地址

mov bx,1000H
mov ds,bx
mov al,[0]

[0]:表示内存单元的偏移地址
指令执行的时候,CPU 自动取 ds 中的数据作为内存单元的段地址
mov al,[0]:表示数据从1000:0 单元到 al 的传送

mov ds,1000H 是非法的。

只能通过一个寄存器来进行中转,如 bx。

  • mov bx,1000H
  • mov ds,bx

3.3 字的传送

CPU 是16位结构,有16根数据线,可以一次性传送16位数据,就是一个字

image

3.4 mov、add、sub 指令

mov 指令可以有以下几种形式:

  • mov 寄存器,数据 比如:mov ax,8
  • mov 寄存器,寄存器 比如:mov ax,bx
  • mov 寄存器,内存单元 比如:mov ax,[0]
  • mov 内存单元,寄存器 比如:mov [0],ax
  • mov 段寄存器,寄存器 比如:mov ds,ax

add 和 sub 指令有以下几种形式:

  • add 寄存器,数据 比如: add ax,8
  • add 寄存器,寄存器 比如:add ax,bx
  • add 寄存器,内存单元 比如:add ax,[0]
  • add 内存单元,寄存器 比如:add [0],ax
  • sub 寄存器,数据 比如:sub ax,9
  • sub 寄存器,寄存器 比如:sub ax,bx
  • sub 寄存器,内存单元 比如:sub ax,[0]
  • sub 内存单元,寄存器 比如:sub [0],ax

3.5 数据段

image

总结

  1. 字在内存中存储,使用两个地址连续的内存单元存放,低位字节存放在低地址单元,高位字节存放在高地址单元
  2. 使用 mov 指令访问内存单元,可以在 mov 指令中只给出单元的偏移地址,此时段地址默认在DS寄存器中
  3. [address]表示一个偏移地址位 address 的内存单元
  4. 在内存和寄存器之间传动数据的时候,高地址单元和高8位寄存器,低地址单元和低8位寄存器相对应
  5. mov、add、sub 是具有两个操作对象的指令。jmp 是具有一个操纵对象的指令

3.6 栈

  1. 入栈:就是将一个新的元素放到栈顶
  2. 出栈:就是从栈顶取出一个新的元素
  3. 栈顶的元素总是最后入栈。
  4. 栈的这种操作规则被称为:LIFO(Last In First Out)后进先出

3.7 CPU 提供栈机制

基本命令就是 PUSH 和 POP,push ax 表示将寄存器 ax 中的数据送入栈中,pop ax 表示从栈顶中取出数据送入到 ax,CPU 入栈和出栈操作都是已字为单位进行的

段寄存器 SS 和 SP,栈顶的段地址存放在 SS 中,偏移地址存放在 SP 中,任意时刻 SS : SP 指向栈顶元素

下图描述了 8086CPU 对 push 指令的执行过程:

image

将 10000H ~ 1000FH 如果初始状态栈是空的,SS = 10000H,SP = ?

image

将 10000H~1000FH 这段空间当作栈段,SS = 1000H,空间大小为16节,最底部的字单元地址为 1000 : 000E。任意时刻,SS : SP指向顶,当栈中只有一个元素的时候,SS = 1000H,SP = 000EH。

栈为空,就相当于栈中唯一的元素出栈,出栈后,SP = SP + 2,SP原来为 000EH,加2后 SP = 10H,所以栈为空的时候,SS = 1000H,SP = 10H。

图3.12描述了 8086CPU 对 pop 指令的执行过程:

image

pop ax 的执行过程和 push ax 刚好相反,由下面两步完成:

  • 将 SS : SP 执行的内存单元处的数据送入 ax 中;
  • SP = SP + 2, SS :SP 指向当前栈顶下面的单元,以当前栈顶下面的单元为新的栈顶。

注意:出栈后,SS : SP 指向新的栈顶 1000EH,pop 操作钱的栈顶元素,1000CH 处的2266H 依然存在,但是它已不在栈中。当再次执行 push 等入栈指令后,SS : SP 移至 1000CH,新数据将覆盖旧数据。

3.8 栈顶超界问题

CPU 不会保证我们对栈的操作不会超界。CPU 只知道栈顶 (SS : SP) 在何处,不知道安排的栈的空间由多大。所以编程的时候操心栈顶超界的问题。

3.9 栈的总结

初始化栈的代码

mov ax,1000H
mov ss,ax
mov sp,0010H	;
  1. 在 ss,sp 中存放栈顶的段地址和偏移地址:提供入栈和出栈的指令,他们根据 SS : SP 指示的地址,按照栈的方式访问内存单元
  2. push 指令的执行步骤:①sp = sp-2 ②向 ss : sp 指向的字单元中送入数据
  3. pop 指令的执行步骤:①从 ss :sp 指向的字单元中读取数据 ②sp = sp+2
  4. 任意时刻,ss : sp 指向栈顶元素
  5. CPU 只记录栈顶,栈空间的大小由我们自己管理
  6. 用栈来暂存以后需要恢复的寄存器的内容时,寄存器出栈的顺序要和入栈的相反
  7. push,pop 实质是一种内存传送指令,注意他们灵活使用

总结:栈是一种非常重要的机制,一定要深入理解,灵活掌握

image

3.10 段的综述

我们可以将一段内存定义为一个段,用一个段地址指示段,用偏移地址访问段内的单元

我们用一个段存放数据,可以定义为 数据段

我们用一个段存放代码,可以定义为 代码段

我们用一个段当作栈,可以定义为 栈段

数据段: 将段地址存放在 DS 中

代码段 将它们的段地址存放在 cs 中,将段中的第一条指令的偏移地址存放在 IP 中,这样 CPU 就将执行我们定义的代码段中的指令

栈段 段地址存放在 ss 中,将栈顶单元的偏移地址存放在 sp 中

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

霜晨月c

谢谢老板地打赏~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值