寄存器(内存访问)
3.1 内存中字的存储
- 把0地址开始存放 4e20
- 0号单元是低地址单元,1号单元是高地址单元
0 | 20 |
---|---|
1 | 4e |
2 | 12h |
-
任何两个地址连续的内存单元,n号单元和n+1号单元,可以将他们看成两个内存单元,也可以看成一个地址为n的字单元中的高位字节单元和低位字节单元
- 高位单元:n+ 低位单元:n
3.2 DS和[Address]
- CPU要赌气一个内存单元的时候,必须先给出这个内存单元的地址
- 内存地址是由:段地址和偏移地址组成的
- CPU中有一个DS寄存器,通常用来存放要访问的数据的段地址
mov bx, 1000
mov ds, bx
mov al, [0]
- 上面三条指令将10000(1000:0)中的数据读到al中
mov al, [0]
- 已知的mov指令可以用完成两种传送功能
- 将数据直接送入寄存器
- 将寄存器中的内容送入另一个寄存器中
- 除此之外,mov指令还可以将一个内存单元中的内容送入一个寄存器
*上面就是 将内存偏移地址为0的内容送入ax低八位(al)寄存器
-
mov指令格式:
- mov 寄存器,内存单元地址
- […]表示一个内存单元,”[…]“中的0表示内存单元的偏移地址
- 执行指令时 CPU会自动取DS中的数据为内存单元的段地址
- 将1000放入ds ,但是不会能直接放入到ds,ds是一个段寄存器 不是通用寄存器,不支持将数据直接送入 需要借助通用寄存器
- 用mov al, [0] 完成传送 (mov指令中的【】说明操作对象是一个内存单元的偏移地址,是0 它的段地址默认放在ds中
- 数据 -> 通用寄存器 -> 段寄存器
- Mov bx, 1000 为将数据送入寄存器
- mov bx, 1000; mov ds, bx; mov [0], al; 将数据从寄存器送入内存单元 最终的结果:就是把al寄存器中的内容送入[0](1000:0)内存单元中
- mov bx, 1000; mov ds, bx; mov al, [0]; 将内存单元送入寄存器 最终结果:就是把[0](1000:0)内存单元送入al寄存器
3.3 字的传送
- 16结构的从CPU 有16根数据线,所以一次性传送16位的数据,也就是一次性传送一个字
-
mov bx, 1000 mov ds, bx # 上面为:将1000送入到ds中 设置默认段地址为:1000 mov ax, [0] # 将1000:0处的字型数据送入 ax, 因为是ax 16位寄存器 所以是字数据,al为8位寄存器就是直接数据 也可以称为16个字节数据或一个字数据 mov [0], cx # 将cx中的16位数据送到1000:0处
-
答案:执行步骤详解
mov ax, 1000 # 将1000赋值给ax ax=1000 mov ds, ax # 将ax赋值给ds为默认段地址 ds=1000 mov ax, [0] # 将 ds:0(23) 赋值给ax 因为ds:0是字节单元 而ax是字单元 所以自动会把高八位ds:1(11)拉出来 所以ax=1123 mov bx, [2] # 将 ds:2(22) 赋值给bx 拖一个高地址 bx=6622 mov cx, [1] # 将 ds:1(11) 赋值给cx 拖一个告地状 cx=2211 add bx, [1] # 将 ds:1(11) 拖一个高地址 2211加上bx(6622) bx=8833 add cx, [2] # 将 ds:2(22) 6622+2211 cx=8833 mov al, [1] # 如果是赋值给字节寄存器 那么 al的值为 ds:1(11) ax 8811
第二题答案:
-
mov ax, 1000 # 将ax设置为 1000 mov ds, ax # 将段地址设置为 ax=1000 mov ax, 2c34 # 将ax 设置为2c34 十进制:11316 mov [0], ax # 将1000:0 设置为ax mov 10000:0, ax mov bx, [0] # 将bx 设置为 1000:0 = ds:0 = 2c34 sub bx, [2] # bx = bx-ds:2 拖一位高地址 ds:2 = 1122 bx = 2c34 - 1122 = 1b12 mov [2], bx # 将ds:2的值设置为 bx 1b12
3.4 mov、add、sub指令
mov指令的几种形式
- mov 寄存器, 数据 # 这里的寄存器为通用寄存器
- mov 寄存器,寄存器
- mov 寄存器,内存单元
- mov 内存单元,寄存器
- mov 段寄存器,寄存器
- mov 寄存器,段寄存器
add sub 是一样的
-
3.5 数据段
- 我们可以根据需要将一组内存单元定义为一个段(可以是代码段、数据段等)
- 我么可以将一组数据长度为n(n<=64)、地址连续、起始地址为16的倍数的内存单元当做专门存数据的内存空间,从而定义了一个数据段。
-
比如123B0~123B9这个空间来存放数据:
- 段地址:123B
- 长度:10字节 (0~9 十个字节)
-
如何访问数据段中的数据?
- 将一段内存当做数段,是我们在编程的时候的一种安排,我们可以在具体操作的时候,用ds存放数据段的段地址,在根据需要,用相关指令访问数据段中的具体单元
- 要累加这个数据段中的前3个单元中的数据,代码如下:
mov ax, 123b mov ds, ax mov al, [0] # 只有用8位字节寄存器(al)才可以,不然会拖一个高地址内存单元过来 add al, [1] add al, [2]
-
要累加这个数据段中前3个字型数据,代码如下:
mov ax, 123b mov ds, ax mov ax, [0] # 一个字型数据 占两个内存单元,所以便宜地址是0,2,4 add ax, [2] add ax, [4]
小结:
- 字在内存中存储时,要用两个连续的内存单元来存放,字的地位字节存放在低地址单元中。高位字节存放在高地址单元中
- 用mov 指令要访问内存单元,可以在mov指令中给出单元的偏移地址,此时段地址默认在ds寄存器中
- [address] 表示一个 段地址为ds 偏移地址为address的内存单元
- 在内存和寄存器之间传送字型数据时。高地址单元和高8位寄存器、低地址单元和低8位寄存器相对应。
- mov、add、sub 是具有两个操作队形的指令 、jmp(无条件跳转)是具有一个操作对象的指令
- 可以根据自己的推测在 debug中实验指令的格式是否正确 以及结果