DS寄存器
内存地址由段地址和偏移地址构成,其段地址数据就存储在DS中,
CS:IP是cpu要执行指令的位置,DS是指令要执行哪个内存的段地址,比如
在1000:0指令,mov bx = 1000,mov ds bx,mov al,[0],其中ds=1000H就是要说明
对段地址为1000,偏移地址为0的内存的数据写入alCS,IP,DS都是段寄存器以及后面提及的SS
- 字占两个字节16位,cpu一次能处理16位,即两个字节,因为内部总线为16
- 8086寻址能力2^16 = 64kB
- 结论,访问内存都需要段地址和偏移地址
栈(字为单位)
- 先进后出,入栈指的是从栈的顶部添加一个数据,出栈指的是从栈的顶部去除一个元素
LIFO(last in first out) - 8086cpu能够将一块内存当做栈来使用,并且以字为单位
- PUSH 入栈命令 例如 push ax;把ax的数据压入栈中
- POP 出栈命令 例如 pop ax;把栈顶的数据取出到ax寄存器中
CPU通过SS段寄存器以及SP寄存器(偏移地址)来指向栈顶元素的地址
用指令
mov ax 0123; push ax
之后,在内存SS:SP中就可看到此数据,可以自行修改SS:SP指定栈位置
设置内存ffff为起始存储单元的,就要设置SS为0000,sp为0000,因为push数据会在下一个
注意,0000H栈顶下一个元素地址为FFFE,该栈最底部的存储单元为0000:FFFF,最底部字单元
为0000:FFFE,push数据后,寄存器sp会自动-2,POP命令SP+2
- push是将数据往低位家,sp-2
- pop是将sp+2,部改原来数据
- d命令是列出内存地址从低向高位显示
- 0000的内存地址比1000大
栈的越界问题
- 8086CPU只提供了栈顶在何处,不知哪里是界限
PUSH,POP其他用法
push 寄存器;将寄存器的内容压入栈中,栈的位置为SS:SP,可用R查看 push ax
pop 寄存器;将栈顶的内容写入到寄存器中 pop ax
push 段寄存器; push ds(内存单元的段地址) push cs(指令的段地址) push ip(指令的偏移地址)
pop 段寄存器; 例子如上
push 内存单元; push [0],假设ds=1000H,那么意为:将内存1000:0的数据压栈
pop 内存单元; 例子如上
完整例子:
mov ax,1000;
mov ds,ax; 注意ds无法直接赋值,下面的[偏移地址]ds(段地址)
push [0]; 将1000:0处的字(1000:0~1000:1)压栈
pop [2]; 将栈顶的字出栈到1000:2