美文网首页
寄存器及数据存储

寄存器及数据存储

作者: freemanIT | 来源:发表于2024-01-31 13:32 被阅读0次

CPU 的组成

  • 运算器进行信息处理
  • 寄存器进行信息存储
  • 控制器协调各种器件进行工作
  • 内部总线实现CPU 内各个器件之间的联系
CPU的组成

寄存器是CPU 内部的信息存储单元

8086 有14 个寄存器

  • 通用寄存器: AX, BX, CX, DX
  • 变址寄存器: SI, DI
  • 指针寄存器: SP, BP
  • 指令指针寄存器: IP
  • 段寄存器: CS, SS, DS, ES
  • 标志寄存器: PSW

它们的共性为都是16 位的, 可以存放两个字节

例如通用寄存器AX, 能存储一个16 位的数据, 最大值为2^{16} -1

如何保证对上一代的兼容? 将通用寄存器分为2 个独立的8 位寄存器使用, 例如将AX 分为AH, AL 高位和低位. 相应的8086 的字长为16bit, 高位存在高8 位寄存器, 低位存在低8 位寄存器

寄存器 寄存器中的数据 表示的值
AX 0100111000100000 20000(4E20H)
AH 01001110 78(4EH)
AL 00100000 32(20H)

mov 和add 指令

举例, AX 和BX 值默认是0000H

指令 执行后AX 中的数据 执行后BX 中的数据
mov ax, 4E20H 4E20H 0000H
add ax, 1406H 6226H 0000H
mov bx, 2000H 6226H 2000H
add ax, bx 8226H 2000H
mov bx, ax 8226H 8226H
add ax, bx 044CH 8226H
指令 执行后AX 中的数据 执行后BX 中的数据
mov ax, 001AH 001AH 0000H
mov bx, 0026H 001AH 0026H
add al, bl 0040H 0026H
add ah, bl 2640H 0026H
add bh, al 2640H 4026H
mov ah, 0 0040H 4026H
add al, 85H 00C5H 4026H
add al, 93H 0058H 4026H

物理地址确定的方法

物理地址

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

物理地址

但是8086 有20 位地址总线, 寻址能力为1M. 而8086 是16 位结构的CPU, 运算器以此最多可以处理16 位的数据, 寄存器的最大宽度为16 位, 在8086 内部处理的, 传输, 咱村的地址也是16 位, 寻址能力也只有64KB, 如何解决呢?

物理地址确定方法

用2 个16 位地址(段地址, 便宜地址) 合成一个20 位物理地址

物理地址 = 段地址 * 16 偏移地址

物理地址确定方法 通过加法器计算

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

分段方式管理内存

实际中是没有分段, 段的划分来自于CPU

同一段内存, 可以有多中分段方案

但是, 1. 段地址 * 16 必然是16 的倍数, 所以一个段的起始地址也一定是16 的倍数. 2. 偏移地址为16 位, 16 位地址的寻址能力为64k, 所以一个段的长度最大为64k

例如

物理地址 段地址 偏移地址
21F60H 2000H 1F60H
2100H 0F60H
21F0H 0060H
21F60H 0000H
1F00H 2F60H

表示方法为2000:1F60H

专门的寄存器存放地址

  • CS 代码段寄存器
  • DS 数据段寄存器
  • SS 栈段寄存器
  • ES 附加段寄存器

debug 的使用

常见命令

用R命令查看、改变CPU寄存器的内容

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

用E命令改变内存中的内容

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

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

用T命令执行机器指令

用Q 命令退出debug

R 命令的使用

R命令查看和修改寄存器

D 命令查看内存内容

d命令查看内容
  • 默认128 个字节内容
  • 段地址:偏移地址, 列出内存中指定地址处的内容
  • 段地址:偏移地址 结尾偏移地址, 列出内存中指定地址范围内的内容

E 命令改变内存中的内容

E命令修改寄存器内容
  • 段地址:偏移地址 数据1 数据2 ...
  • 段地址: 偏移地址
    • 逐个询问修改
    • 空格, 接受 继续
    • 回车, 结束

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

  • 汇编指令为

    mov ax, 0123H

    mov bx, 0003H

    mov ax, bx

    add ax, bx

  • 对应的汇编为

    B8 23 01

    BB 03 00

    89 D8

    01 D8

  • e 地址 数据, 写入

  • d 地址, 查看

  • u 地址, 查看代码

u命令查看代码

A 命令以汇编指令的格式在内存中写入机器指令

  • 汇编指令为

    mov ax, 0123H

    mov bx, 0003H

    mov ax, bx

    add ax, bx

  • 对应的汇编为

    B8 23 01

    BB 03 00

    89 D8

    01 D8

  • a 地址, 写入汇编指令

  • d 地址, 查看数据

  • u 地址, 查看代码

a命令修改内容 u命令查看代码

T 命令执行机器指令

mov ax, 0123H

mov bx, 0003H

mov ax, bx

add ax, bx

t命令逐步执行命令

CS 和IP 寄存器

CS: 代码段寄存器

IP: 指令指针寄存器

CS:IP, CPU 将内存中的CS:IP 指向的内容当做指令执行

以上代码的执行过程为

  • 从CS:IP 执行内存单元读取指令, 读取的指令进入指令缓冲器
  • IP = IP + 所读取指令的长度, 从而指向下一条指令
  • 指向指令, 重复第一步
cs:ip执行过程

而内存中有数据B8 23 01 BB 03 00 89 D8 01 D8 是一段数据还是指令呢?

CPU 将CS:IP 指向的内存单元中的内容看做指令

jmp 指令

使用jmp 来修改cs 和ip 指令

例如

jmp 段地址:偏移地址

jmp 2AE3:3

jmp 3:0B16

用指令中给出的段地址修改cs, 偏移地址修改ip

尽修改ip 内容

jmp 某一合法寄存器

jmp ax, 类似于mov IP,ax

jmp bx

用寄存器中的值修改IP

jmp指令应用

从20000H 开始, 执行序列:

  1. mov ax,6622
  2. jmp 1000:3
  3. mov ax,0000
  4. mov bx,ax
  5. jmp bx
  6. mov ax,0123H
  7. 转到第3 步继续执行

用DS 和[address] 实现字的传送

问题 CPU 从内存单元中要读取数据

要求: CPU 要读取一个内存单元的时候, 必须先给出这个内存单元的地址

原理: 在8086 中, 内存地址由段地址和偏移地址组成

解决: DS 和[address] 配合

  • 用ds 寄存器存放要访问的数据的段地址
  • 偏移地址用[...] 形式给出

mov bx,1000H

mov ds,bx

mov al,[0]

将10000H(1000:0) 中的数据读到al 中

mov bx,1000H

mov ds,bx

mov [0],al

将al 中的数据写到10000H(1000:0) 中

注意不可以使用mov ds,1000H, 8086 不支持将数据直接写入段寄存器

方法应为: 数据 -> 一般寄存器 -> 段寄存器

对内存单元中的数据访问

可以根据需要将一组内存单元定义为一个段

  • 物理地址 = 段地址 * 16 + 偏移地址
  • 将一组长度为N(N<= 64k) 地址连续, 起始地址为16 的倍数的内存单元当做专门存储数据的内存空间, 定义一个数据段

处理方式(DS):([address])

  • 用DS 存放数据段的段地址
  • 用相关指令访问数据段中的具体单元, 单元地址由[address] 指出

例如1: 累加数据段中的前3 个单元中的数据

mov ax,123BH
mov ds,ax
mov al,0
add al,[0]
add al,[1]
add al,[2]
累加前3个单元

例2: 累加数据段中的前3 个字型数据

mov ax, 123BH
mov ds,ax
mov ax,0
add ax,[0]
add ax,[2]
add ax,[4]

总结

用mov 指令操作数据

指令形式 示例
mov 寄存器,数据 mov ax,8
mov 寄存器,寄存器 mov ax,bx
mov 寄存器, 内存单元 mov ax,[0]
mov 内存单元, 寄存器 mov, [0],ax
段寄存器, 寄存器 mov ds,ax

加法add 和减法sub 指令

add 指令 示例
add 寄存器,数据 add ax,8
add 寄存器,寄存器 add ax,bx
add 寄存器,内存单元 add ax,[0]
add 内存单元,寄存器 add [0],ax
sub 指令 示例
sub 寄存器,数据 sub ax,8
sub 寄存器,寄存器 sub ax,bx
sub 寄存器,内存单元 sub ax,[0]
sub 内存单元,寄存器 sub [0],ax

DS 和[address] 访问内存中数据段方法总结

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

栈及其操作

栈是一种只能在一端进行插入或删除操作的数据结构

  • 入栈, 将一个新的元素放到栈顶
  • 从栈顶取出一个元素
push ax; 将ax 中的数据送入栈中
pop ax; 从栈中取出数据送入ax 中
都是以字为单位对栈操作

规则: LIFO 后进先出

在8086 中可以将一段内存当做栈来使用

问题一, CPU 如何直到一段内存空间当做栈使用?

问题二, 执行push 和pop, 如何直到哪个单元是栈顶单元

8086 中, 有两个与栈相关的寄存器

  • 栈段寄存器SS, 存放栈顶的段地址
  • 栈顶制作寄存器SP, 存放栈顶偏移地址

任意时刻, SS:SP 指向栈顶元素

mov ax,1000H
mov ss,ax
mov sp,0010H
AX BX SS SP
1000H 1000H 0010
mov ax,001AH
mov bx,001BH
AX BX SS SP
001AH 001BH 1000H 0010
push ax
push bx
AX BX SS SP
001AH 001BH 1000H 000C
pop ax
pop bx
AX BX SS SP
001BH 001AH 1000H 0010
执行过程

push ax

  1. SP = SP - 2
  2. 将ax 中的内容送入SS:SP 指向的内存单元, SS:SP 此时指向新的栈顶

pop ax

  1. 将SS:SP 指向的内存单元的数据送入ax
  2. SP = SP + 2, SS:SP 指向当前栈顶下面的单元, 以当前栈顶下面的单元为新的栈顶

注意栈顶超界的问题

栈小结

  • push pop 实质上就是一种内存传送指令, 可以在寄存器和内存之间传送数据, 与mov 不同, push 和pop 指令访问的内存单元地址不是指令中给出的, 而是SS:SP 指出的
  • 执行push 和pop 时, SP 中的内容会自动改变
  • 8086 提供栈操作机制
    • 在SS, SP 中存放栈顶段地址和偏移地址, 入栈出栈指令根据SS:SP 指示的地址, 按照栈的方式访问内存单元
    • push 执行步骤
      • SP = SP - 2
      • 向SS:SP 指向的字单元中送入数据
    • pop 步骤
      • 从SS:SP 指向的字单元中读取数据
      • SP = SP - 2

相关文章

  • Java的存储

    程序运行时,有6个地方可以保存数据: 寄存器 堆栈 堆 静态存储 常数存储 非RAM存储 寄存器 寄存器位于处理器...

  • 函数的本质

    寄存器的补充 数据地址寄存器 数据地址寄存器通常用来做数据计算的临时存储、做累加、计数、地址保存等功能。定义这些寄...

  • 对象,一切皆是对象

    1.六个数据保存的地方:寄存器、堆栈、堆、静态存储、常数存储、非RAM存储。 (1)寄存器,位于处理器内部,这是最...

  • 寄存器

    累加寄存器(accumulator register):存储执行运算的数据和运算后的数据 标志寄存器(flag r...

  • iOS逆向(二)函数本质

    概念 一、寄存器 1.数据地址寄存器 通常用来做数据计算的临时存储、累加、计数、地址保存等功能。定义这些寄存器的作...

  • STM32学习:存储器与寄存器

    一、寄存器及寄存器映射 存储器本身不具有地址信息,它的地址是由芯片厂商或用户分配,给存储器分配地址的过程称为存储器...

  • 汇编语言

    程序的本质 寄存器与内存 通常,CPU会先将内存中的数据存储到寄存器中,然后再对寄存器中的数据进行运算 假设内存中...

  • JAVA——用引用操纵对象2

    JAVA中的数据存储 1、寄存器 这是最快的存储区域,因为它位于处理器内部。但是寄存器的数目很有限,会根据需求分配...

  • 计算机常见基本概念

    寄存器 RAX ios目前寄存器最大为8个字节(寄存器有n个)寄存器是CPU中的数据临时存储单元CPU执行的每条指...

  • 汇编基础(通用寄存器)

    寄存器 所谓寄存器(register),它是CPU内部用来存放数据的一些小型存储区域,用来暂时存放参与运算...

网友评论

      本文标题:寄存器及数据存储

      本文链接:https://www.haomeiwen.com/subject/kitaodtx.html