汇编语言学习4

DS和[address]

Posted by BINBIN Blog on August 9, 2019

##DS和[address]

DS寄存器:通常用来存放要访问数据的段地址

[address]表示一个偏移地址为address的内存单元,段地址默认放在ds中

通过数据段段地址和偏移地址即可定位内存单元

mov bx, 1000H ;8086CPU不支持将数据直接送入段寄存器的操作

mov ds, bx ;ds存放数据段地址

mov al, [0];

这个要解释一下 mov 指令,完成两种传送, 1.数据直接送入寄存器,2 讲一个寄存器的内容送入另外一个寄存器。

所以也可以将一个内存单元的内容送入一个寄存器中,指令需要指名。寄存器用寄存器指名,内存单元则需要内存单元指名。

显然格式就是 mov 寄存器名, 内存单元

“[…]”表示一个内存单元,”[…]”中的0 表示内存单元的偏移地址。 自然这个也需要段地址,CPU 会自动取ds中的数据作为内存单元的段地址。 所以此时ds寄存器里面的内容已经是1000H。

注意: 不能使用mov ds,1000H的,因为ds是段寄存器,只能通过寄存器中转,这个属于硬件设计问题,跟软件无关

字的传送

因为8086是16位CPU ,可以一次性传送16位数据,书中是把16位数据当做一个字节

mov bx,1000H
mov ds,bx
mov ax,[0] ; 1000:0处的字型数据送入ax
mov [0],bx ; cx中的16位数据送到1000:0处

mov、 add 、 sub指令 格式一样

SS和SP 栈

在基于8086CPU编程的时候,可以将一段内存当作栈来使用。 如图指令执行的过程

mov ax,0123H
push ax
mov bx,2266H
push bx
mov cx,1122H
push cx
pop ax
pop bx
pop cx

注意,字型数据用两个单元存放

CPU 也有两个寄存器,段寄存器SS 和寄存器SP 栈顶的段地址存放在SS ,偏移地址存放在SP中,任意时刻,SS:SP 指向栈顶元素,所以push 和pop指令执行,cpu 会从ss和sp 得到栈顶地址。

栈段寄存器SS,存放段地址,SP寄存器存放偏移地址,任意时刻,SS:SP指向栈顶元素

8086CPU中,入栈时,栈顶从高地址向低地址方向增长。

push ax表示将寄存器ax中的数据送入栈中,由两步完成。

SP=SP-2,SS:SP指向当前栈顶前面的单元,以当前栈顶前面的单元为新的栈顶; 将ax中的内容送入SS:SP指向的内存单元处,SS:SP此时指向新栈顶。

pop ax表示从栈顶取出数据送入ax,由以下两步完成。

将SS:SP指向的内存单元处的数据送入ax中; SP=SP+2,SS:SP指向当前栈顶下面的单元,以当前栈顶下面的单元为新的栈顶。

栈顶超界问题

执行push导致超出栈顶空间

执行pop导致超出栈空间

该例子提醒我们编程的时候一定要注意避免超出栈空间错误,CPU 并没有这样的寄存器检查栈顶地址是否超出空间。

实验

1.将10000H~1000FH这段空间当作栈,初始状态栈是空的; 2.设置AX=001AH,BX=001BH; 3.将AX、BX中的数据入栈; 4.然后将AX、BX清零; 5.从栈中恢复AX、BX原来的内容。 代码如下:

mov ax, 1000H 
mov ss, ax 
mov sp, 0010H    ;初始化栈顶
mov ax, 001AH
mov bx, 001BH 

push ax 
push bx    ;ax、bx入栈

sub ax, ax   ;将ax清零,也可以用mov ax,0,
             ;sub ax,ax的机器码为2个字节,
             ;mov ax,0的机器码为3个字节。
        
sub bx, bx 

pop bx  ;从栈中恢复ax、bx原来的数据
pop ax  ;