上一篇文章我们主要学习了段寄存器:CS和IP
顺便通过实验的形式将debug中常用的指令熟悉过了.
来回顾下
指令 | 作用 |
---|---|
R | 查看修改对应寄存器的内容 |
D | 查看对应内存中的内容 |
E | 修改对应内存中的内容 包括写入字符 数字 字符串 |
U | 将内存中的内容解释为对应的汇编指令 |
T | 执行对应内容中的指令(CS:IP) |
A | 以汇编的形式写入内存 |
本篇文章将讲解剩余的部分
1.1 内存中的字存储
我们知道在8086CPU中,用16位寄存器来存放一个字,高8位(H)存放高字节,低8位(:L)存放低字节,在内存中存储时,由于内存单元是字节单元(一个单元存放一个字节),因此一个字要用两个连续的内存空间来存储(每个一个字节,共两个字节,16位,每个空间内存8位,1字节),字的低位字节存放在低地址,高位字节存放在高地址.
如图所示,不难看出 0,1 两个内存空间所组成的为 20000(4E20H) 其高位字节为4E 存放到1处,低位字节为20H存放到低处0
再来举个例子:18(0012H) 其高位为00 所以存放到3 处 低位为12 存放到2处
一个字单元就是存放一个完整的字所占的内存单元 ,这里的 01 23 都可以算作字单元
将起始地址为N的字单元简称为N地址字单元,如 一个字所占的内存空间为2,3 那么这个字单元就是2地址字单元,像图中的0012
为2地址字单元,4e20为0地址字单元
1.2 思考:
对于图中的表示,思考以下几个问题:
- 0地址单元中存放的字节数据是? 答:20H
- 0地址字单元中存放的字型数据是? 答:4E20H
- 2地址单元中存放的字节数据是? 答: 12H
- 2 地址字单元中存放的字型数据是? 答:0012H
- 1 地址单元中存放的字节数据是? 答:4EH
- 1 地址字单元中存放的字型数据是? 答:124EH(4686)
所以这里的问题6就表明了 不一定是固定的两个 如 01 23 可以组成地址字单元 12 也可以
1.3 DS和[address]
我们知道 当cpu想要访问一个内存的单元时,必须要知道其物理地址,我们还知道,在8086CPU中的物理地址由段地址和偏移地址组成.DS寄存器就是存放要访问的段地址.
假设我们要读取10000H处的内容,我们可以用汇编语言来这样实现:
mov bx,10000H
mov ds,bx
mov al,[0]
这段指令的意思时将10000H中的第0块数据读入到AL中
mov指令的功能有:将数据送入寄存器,将一个寄存器的内容送入另一个寄存器.
这里还有一个功能:将内存中的数据送入一个寄存器,
这里的
mov al,[0]
就是用到了这一点
其中[xxx]表示一个内存单元,[0]表示一个内存单元的偏移地址,这个偏移是基于ds寄存器中的内容进行的,cpu在访问时,先去读取ds中的内容,后根据给定的偏移地址进行读取,因此在执行mov 指令将内存中的内容送入寄存器时,要先给出对应内存的地址,并将其送入ds寄存器中.
有人可能就想:为什么不能直接使用
mov ds,10000H
来将内存地址送入ds寄存器中呢?
很抱歉,并不可以,因为这是8086CPU的硬件设计问题,所以在送入ds寄存器中时,要从其他寄存器中传入值,再利用mov指令传送到ds寄存器中
1.3.1 思考
写出指令,将al中的数据送入到内存单元10000H处
答:
mov bx,10000H
mov ds.bx
mov [0],al
总结:mov指令的用法有:
继续来做问题:
问题1
给定内存空间如图所示,现执行以下指令,思考对应的寄存器变化:
mov ax,1000H
mov ds,ax
mov ax,[0]
mov bx,[2]
mov cx,[1]
add bx,[1]
add cx,[2]
首先毫无疑问的是 前两条指令是把ds的值变为10000H
随后开始mov ax 注意
mov ax,[0]
所处理的是将低位的值送入al中,高位的值送入ah中,从[0]开始计数,两个内存空间,一个内存空间占一个字节,一个字空间共占两个字节,因此[0]代表着1123
因此在这条指令执行后,ax变为:1123H
mov bx.[2]
执行后bx为6622
mov cx,[1]
执行后cx变为2211
add bx,[1]
bx现在的值为:6622
加上[1]处的2211 变为 8833
具体分析如王爽老师的表格所示
问题2
内存单元如图所示:
现有指令:
mov ax,1000H
mov ds,ax
mov ax,11316
mov [0].ax
mov bx,[0]
sub bx,[2]
mov [2],bx
这里的sub
指令为相减的作用
具体来说:
sub a,b
将a与b相减,结果存在a中.
前两条指令的作用是将10000H存入到ds寄存器中,很常规了
接下来看第三条指令,将11316送入ax中,但是很明显,11316并不是一个16进制数字,而是一个10进制数,这里需要将其转化为16进制数字;2C34H
因此这里的ax为2C34H
随后,将ax中的值送入到[0]处
因此10000H处变为34 10001处变为2C
然后继续:执行
mov bx,[0]
将2C34送入bx,bx变为2C34H
随后执行:
sub bx,[2]
也就是bx需要与1122做差 变为 1B12H
随后执行
mov [2],bx
将bx中的内容存入内存[2]处,因此10003H变为1B 10002H变为12
下半部分将带来更加精彩的栈问题.以及pop push指令.