关于寄存器和内存单元之间数据的传送方式
这一小节提到的一个新知识是mov 寄存器名,内存单元地址
这个地址是偏移地址,直接用方括号包起来比如mov al, [0]
既然是偏移地址,那么我们在执行的时候就需要转化成物理地址,这里就涉及到了一个段地址的寄存器DS
DS中存着当前的段地址,对其进行写入操作时必须从另外一个寄存器中传进去,因为8086CPU不支持将数据直接送入段寄存器,必须通过一个寄存器进行中转
例如
1 | mov bx,1000H |
add和sub不能对段寄存器进行操作,可以对内存单元操作
错误的:add ds,ax
栈
对于栈的描述有一句话写的很好:最后进入这个空间的数据,最先出去。这个规则被称作LIFO(Last In First Out)
push/pop
push指令的作用是入栈,pop指令的作用是出栈。例如:push ax; pop ax
,8086cpu的入栈出栈操作都是以字为单位进行的。
push后面跟着的寄存器是原本就有数据的,整条指令的作用就是将该寄存器的内容压入栈
pop后面跟着的寄存器是用来接收数据的,整条指令执行后该寄存器内容变成栈顶的一个字长度的内容
既然这些操作都和栈顶息息相关,那么cpu一定也要随时知道栈顶的地址,就像当初的CS:IP
这里是SS:SP,SS表示栈顶的段寄存器,SP表示栈顶的偏移地址,任意时刻,SS:SP指向栈顶元素
无论是push还是pop都存在溢出问题(pwn手狂喜),如果一段栈空间满了,再执行push就会覆盖外部低地址栈内容,如果一段栈空间空了,再执行pop就会pop出外部高地址栈内容
栈段
没什么特殊的就是定义一个段当成栈空间来使用