3.1内存中字的存储
CPU中寄存器是16位的,可以用高低字节存储一个字,但是每个内存单元是8位的,只能存储一个字节,
所以内存中用相邻2个内存单元存储一个字的高低字节
如:20000数值(4E20H)在地址0的内存单元数值为20H,在地址1的内存单元数值为4EH
两个内存单元存储一个字型数据叫做一个字单元,
字单元的起始地址为N就叫N地址字单元,表示一个字的低字节在地址N的内存单元,高字节在地址N+1的内存单元
任意连续的2个内存单元都可以组成一个字单元
3.2 DS和 【address】
CS寄存器用于存放下个指令所在内存单元的段地址。用jmp 1000:0 赋值 CS
DS寄存器一般用于存放要访问的内存单元的段地址:
如我们想把内存单元10000H(1000:0)的内容放到AL中:
mov bx,1000H 将要访问的内存单元段地址放到bx中
mov ds,bx 将bx放入ds段寄存器中
mov al,[0] 将[0]代表的内存单元内容放到al中
[0]: 表示一个内存单元,段地址是DS中的值,偏移地址是0,所以此时【0】表示1000:0内存单元的内容
注意: mov ds,1000H是不行的,段寄存器是不可以直接赋值的,只能从其他寄存器转义到段寄存器
相反:将AL写入10000H
mov bx,1000H
mov ds,bx
mov [0],al
3.3字的传送
mov指令两个参数的位数相同,
当mov在寄存器与内存进行数据交互时,寄存器的字节数决定了传送单个内存单元还是字单元。
mov ax,[0] 会将该地址的字单元数据组合成16位传入ax寄存器,即传送了一个字
问题 :
mov ax,1000H ax=1000H
mov ds,ax ds=1000H
mov ax,[0] ax=1123H
mov bx,[2] bx=6622H
mov cx,[1] cx=2211H
add bx,[1] bx=8833H
add cx,[2] cx=8833H
3.4 mov,add,suv指令
mov 寄存器,数据 数据只能转移到寄存器,不能转移到段寄存器
寄存器,段寄存器,内存单元在mov指令中的位置都是可以随意换的
mov 寄存器,数据
mov 寄存器,寄存器
mov 寄存器,内存单元
mov 内存单元,寄存器
mov 内存单元,段寄存器
mov 段寄存器,内存单元
mov 段寄存器,寄存器
mov 寄存器,段寄存器
add,sub只能对数据,寄存器,内存单元操作,不能用于段寄存器
3.5数据段:存放数据的连续内存单元形成一个数据段
根据需要可以随意操作数据段中的数据
如123B0H-123B9H是一个长度为10的数据段.
1.累加前3个内存单元
mov bx,123BH
mov ds,bx
add al,[0]
add al,[1]
add al,[2]
2.累加前3个字型数据
add ax,[0]
add ax,[2]
add ax,[4]
检测点3.1
1)在Debug中用 \'d 0:0 1f\' 查看内存,结果如下
0000:0000 70 80 F0 30 EF 60 30 E2-00 80 80 12 66 20 22 60
0000:0010 62 26 E6 D6 CC 2E 3C 3B-AB BA 00 00 26 06 66 88
下面程序执行前AX=0,BX=0 写出下列命令执行后相关寄存器中的值
mox ax,1 AX=1
mov ds,ax DS=1
mov ax,[0000] AX=(16+0=10H)= 2662H
mov bx,[0001] BX=(16+1=11H)=E626H
mov ax,bx AX=E626H
mov ax,[0000] AX=2662H
mov bx,[0002] BX=(16+2=12H)=D6E6H
add ax,bx AX=FD48H
add ax,[0004] AX=2C14H 12C14
mov ax,0 AX=0
mov al,[0002] AX=00E6H
mov bx,0 BX=0
mov bl,[000C] BX=0026H
add al,bl AX=000CH
2)内存情况如图所示:
寄存器初始值: CS=2000H,IP=0,DS=1000H,AX=0,BX=0
a.写出CPU执行顺序,及执行后相关寄存器值
mov ax,6622H ax=6622H
jmp 0ff0:0100
mov ax,2000H ax=2000H
mov ds,ax ds=2000H
mov ax,[0008] ax=C389
mov ax,[0002] ax=EA66
3.6栈
后进先出LIFO,栈就是一个有特殊访问方式的存储空间
只有2种操作,入栈和出栈,并且有个指针总是指向栈顶元素
3.7CPU提供的栈机制
8086CPU提供PUSH和POP指令用于操作栈内存,PUSH和POP操作单位是字单元
利用SS存储栈顶内存单元的段地址,SP存储栈顶内存单元的偏移地址.
栈顶内存单元地址小,栈底内存单元地址大
PUSH分两步: a.SP-2 b.写入/覆盖
POP分两步 : a.读取 b.SP+2 内存单元的值依然存在,但是指针已经移到别处,再PUSH的时候就会覆盖原来值
3.8栈顶越界问题
CPU不会指针是否指向栈顶或者栈低,只会根据SS:SP进行PUSH或者POP,需要程序员自己控制
栈为空时SS:SP指向栈底内存单元的下一个内存单元
3.9 PUSH和POP指令
PUSH和POP可以对寄存器、段寄存器、内存单元操作
3.10栈段
把一段起始地址是16整数倍的连续的内存单元看做一个栈,就是一个栈段
栈段根据SS:SP的指向利用PUSH、POP操作
段的综述数据段,段地址存放在DS中,add,sub,mov访问内存单元时候,CPU就把我们定义的数据段中的内容当做数据来操作
代码段,段地址存放在CS中,段中第一条指令的偏移地址存放在IP中,这样CPU就能执行我们的代码段
栈段 ,段地址存放在SS中,栈指针的偏移地址存放在SP中,CPU根据SS:SP进行PUSH,POP操作
检测点3.2
mov ax,1000H
mov ds,ax
mov bx,2000H
mov ss,bx
mov sp,10H
push [0]
push [2]
push [4]
push [6]
push [8]
push [A]
push [C]
push [E]
2)补全下面的程序,使得10000H-1000FH逆向复制到20000H-2000FH中
mov ax,2000H
mov ds,ax
mov ax,1000H
mov ss,ax
mov sp,0H
pop [E]
pop [C]
pop [A]
pop [8]
pop [6]
pop [4]
pop [2]
pop [0]