查漏
- 2^n-1
- word=2B=16bit
8086CPU在内部用两个16位地址合成的方法形成一个20位的物理地址
- 物理地址=段地址x16(16进制的情况下左移一位,2进制左移四位)+偏移地址
- 一个段的最大长度为64KB。2^16
- 段地址:偏移地址
-
段寄存器(提供段地址)
8086CPU:CS(指令) DS SS ES
- CS:代码段寄存器 IP:指令指针寄存器
- CPU刚开始工作: CS=FFFFH IP=0000H
- CS:IP -> 读取指令
- IP=IP+读取指令的长度
- 修改CS、IP的内容(不能用mov)
- jmp CS’:IP’
- jmp ax (用ax里的值修改IP)
DS:数据段寄存器 [address]:数据段偏移地址
- 例子:读取1000:0中的数据(一个内存单元8bit,如果只传递一个字节用al存就够了)
- mov bx,1000H
- mov ds,bx ;一定要通过通用寄存器把值赋给段寄存器
- mov al,[0] ;al8位
- mov [0],al;寄存器->内存单元
- mov ax,[0];将字型数据送入ax
- mov [0],ax
- 例子:读取1000:0中的数据(一个内存单元8bit,如果只传递一个字节用al存就够了)
SS:存放栈顶的段地址 SP:存放栈顶的偏移地址
- 任何时刻SS:SP执行栈顶元素
- push ax;SP=SP-2,ax->新SS:SP
- 栈:从高地址->低地址
- 栈空时,SP指向栈的最高地址的下一个单元(SP-2)
- mov ax,1000H
- mov ss,ax
- mov sp,0010H ;初始指向最高地址的下一个单元
- 任何时刻SS:SP执行栈顶元素
- 栈顶越界危险
- push和pop只对SP操作
- push:SP-2
- pop:SP+2
- push和pop可以对段寄存器进行操作
- push [0] (ds:0)
- pop es
代码段(数据段、代码段、栈段)
- 16位系统:起始地址为16的倍数,大小<=64KB
- CPU只认CS:IP指向的内存单元
实验
- R:查看寄存器内容
- 查看:-r
- 修改:-r ax
- D:查看内存
- -d fff0:0 ff(查看fff00000开始的ff个内存单元的内容)
- E:改写内存(用机器指令)
- -e b810:0 01 01 02 02..
- U:机器指令->汇编指令
- T:执行机器指令
- A:以汇编指令的格式在内存写入一条机器指令(常用)
- -a CS:IP(输入的起始地址)
- P:
- 执行中断:int xx
- 跳过循环
G
- g 指令地址:直接跳到指定的指令地址继续执行
清零:xor ax,ax
内存中字的存储
- 一个内存单元存储一个字节
- 1个内存单元的长度是8bits,占一个字节。
- 32位是指地址长度,四个字节。
- 内存地址指向内存单元(可能1个或更多),32位系统每次读取的内存单元都是4个字节的偶数倍,可能会根据需要忽略多余的字节。
- 寻址地址是根据你的CPU的地址总线来确定的,跟内存没多大关系。
- 至于8字节的内存单元是认为定义,是为了兼容性和编程实现考虑的