汇编语言入门:寄存器和内存访问

有了前面基础知识的铺垫,我们对于汇编语言已经有了一个宏观的认识。现在让我们由浅入深,逐渐深入……

补充说明:本系列汇编教程均采用Intel语法


内存中字的存储

高位高地址,低位对应低地址……
下图,在0地址处开始存放20000(4E20H)
汇编语言入门:寄存器和内存访问_第1张图片
看图,“0地址单元中存放的字节型数据是20H”,“0地址字单元中存放的字型数据是4E20H”,“2地址单元中存放的字节型数据是1200H”,“2地址单元中存放的字型数据是0012H”,“1地址单元中存放的字型数据是124EH”

结论(规定):任何两个地址连续的内存单元,N号单元和N+1号单元,可以将它们看成两个内存单元,也可以看成一个地址为N的字单元中高位字节和低位字节单元


DS和[address]

CPU要读取一个内存单元,必须要先给出该单元的地址

在8086CPU中,内存单元由段地址和偏移地址组成

8086CPU中有一个DS寄存器,通常用来存放要访问的数据的段地址

例如:要读取10000H单元的内容

mov BX, 1000H
mov DS, BX
mov al[0]
; 上面三条指令将1000H(1000:0的简写)中的数据读到al中

小结:mov指令的三种用法
1. 将立即数送入寄存器
2. 将寄存器的值送入另一个寄存器
3. 将一个内存单元的值送入一个寄存器(如上面的第三行汇编)

关于mov指令的第三点用法:
1. 格式:mov 寄存器名 内存单元的地址
2. [...]表示一个内存单元,方括号内的值表示偏移地址(如上面的0)

执行指令时,8086CPU自动获取DS中的数据(段地址)

再看一个详细的讲解:

; 使用mov指令从10000H中读取数据
; 10000H表示为1000:0(段地址:偏移地址)
; 将段地址1000H送入DS寄存器
; 用mov al[0]完成传送(mov指令中的[]说明操作数是一个内存单元,‘0’说明偏移地址为0,它的段地址默认存放在DS中)

再次强调,不能直接把立即数送入DS寄存器(必须通过通用寄存器!!8086CPU的硬件设计不支持将数据直接送入段寄存器而DS是一个段寄存器)

mov DS, 1000H   ; 这是一个非法的指令!!!

栗子:将数据从寄存器al送入内存单元10000H(一种合理的回答)

; 分析:将数据送入指定地址的内存单元(使用DS保存段地址,而这个段地址的值必须先用通用寄存器传送给DS)
mov BX, 1000H
mov DS, BX
mov [0], al

还是挺简单的……


字的传送

因为8086CPU是16位结构,由16根数据线,所以可以一次性传送16位的数据,也就是说可以一次性传送一个字

mov BX, 1000H
mov DS, BX
mov AX, [0] ;将1000:0内存中的数据送入寄存器AX
mov [0], CX ;将CX中的16位数据送到1000:0处(8086CPU,16位结构16位数据)

所谓的“单步调试”,可以使用windows下的“的 debug”命令分析
汇编语言入门:寄存器和内存访问_第2张图片

-c 1000:0 23 11 22 66
-a 1386:100
mov AX, 1000
mov DS, AX
mov AX, [0]
mov BX, [2]
mov CX, [1]
add BX, [1]
add CX, [2]
; 现在可以使用-t来单步调试
; 可以看到现在AX=1123,因为AX是16位存储结构(从低位开始到16位包括高位字节,[0]实际上表示的是字节单元或字单元的首地址或者说低地址,至于是字节单元还是字单元要根据送入的寄存器的存储结构大小,如16位AX就是字位单位存储)
; BX=6622
; CX=2211
; BX=6622+2211=8833
; CX=2211+6622=8833

上面,如果把”ax”改为”al”,结果不同:第一次调试后,把23送入寄存器ax中(而不是1123)
上面解释下,当写成”AL”, “AH”的形式,就要把它们两个当成两个完全独立的寄存器看待,而且它们的存储能力为原来寄存器AX的一半

你可能感兴趣的:(汇编语言)