内容概述
通过学习完栈的简单原理,以及相应的ss,sp寄存器的使用。现在已经学习了三种“段”,分别是数据段,代码段,栈段。对于我这种小白极其容易混淆,于是打算进行区分比较。(手把手投喂)
1.数据段
①对应需要的寄存器:DS
②作用:通过将段地址存放到DS,输入访问内存单元的指令,CPU就将我们定义的数据段中的内容当做数据来访问。
③注意事项:1.由于8086CPU不支持将数据直接送入到寄存器的操作,于是需要进行中转。比如我想将段地址设为1000H(由于段地址*16,实际对应的地址为10000H),那么我就要进行中转操作:MOV AX,1000H MOV DS,AX 2.对下列指令的分析(右侧是10000H:0 3地址对应的原始数据)
10000H 23 10001H 11 10002H 22 10003H 66 MOV AX,1000H
MOV DS,AX
MOV AX,[0]
MOV [2],AX
首先1,2步就是将段地址设为1000H,第3步是将1000H*16+0出的数据送入到AX,10001H存储在高八位,10000H放在低八位,此时AX中的内容为1123H,第4步就是将此时AX中的内容放在10002H处,同样有高八位和低八位的区别,此时10002H的内容就为23H,10003H的内容为11H。
2.代码段
①对应需要的寄存器:CS(不能直接赋值),IP
②作用:根据需要将某个段地址当作代码段,利用CS,IP指向让CPU知道从哪开始执行,进而执行代码。
③注意事项:这里的CS,IP可以直接被赋值,没有DS那么麻烦。由于底层机器并不能解析我们输入的汇编语言,便会将汇编语言转换成机器码。为了更好的理解分析下列代码
-R //查看寄存器中的内容,主要看CS,IP(CS:1000H,IP:0000H)
内存中的机器码 10000H B8 10001H 23 10002H 01 10003H B8 10004H 00 10005H 00 10006H 8B 10007H DB 10008H FF 10009H E3 -T //执行CS,IP对应的物理地址的代码
10000H--10002H对应的汇编语言为 MOV AX,0123H
10003H--10005H对应的汇编语言为 MOV AX,0000
当输入-T后便会执行第一步代码,此时AX中的内容变为0123H,当然对应的CS,IP中的内容也会变化,段地址CS不变,而IP会+3(由于这个汇编指令需要三个内存单元存储,执行完后,会变成0003,以便执行下一行代码)前面所学的U命令就可以将机器码转化为汇编语言。
3.栈段
①对应需要的寄存器:SS,SP(栈空时,SS,SP指向栈空间最高地址单元的下一个单元),比如:栈空间在10000H--1000FH,1那么SS,SP就指向1000F+1=10010H的地址
②作用:8086CPU提供入栈(PUSH)和出栈(POP),入栈和出栈都是以字为单位(1个字=两个字节)
后续将起始地址为N的字单元简称为N地址单元。比如一个字由2,3两个内存单元组成,可以说是2地址字单元
③注意事项:由于CPU提供入栈和出栈的操作机制,那么就分别对这两种操作进行解释
- PUSH
1000BH 1000CH 1000DH 23 1000EH 01 MOV AX,0123H
PUSH AX
默认未执行前栈段为空,此时SS,SP指向10010H,CPU执行时,首先SP先减2(因为一个字为一个单位),然后再将AX中的内容放到栈中,依据高八位和低八位,那么执行后的栈中内容就如上图所示。
- POP
1000BH 1000CH 1000DH 23 1000FH 01 POP BX
延续上个内容,将输入栈中的内容释放出来(如果有多个数据要遵循LAST IN FIRST OUT后进先出)CPU执行这段内容时与PUSH完全相反,先是执行POP BX,然后SP+2,就又回到栈顶了。
4.总结
当然上述不同的段并非一定独立存在,有时一段地址中既是代码段,数据段又是栈段
比如:
MOV AX,1000H
MOV SS,AX
MOV SP,0020H //初始化栈顶
MOV AX,CS
MOV DS,AX //将CS地址给DS数据段地址
MOV AX,[0]
PUSH AX
POP BX
在上述内容中CS,IP指向10000H,这段代码得以执行。可以看出,这段地址中既是代码段,数据段又是栈段。
标签:汇编语言,IP,SP,MOV,第三天,学习,地址,CS,AX From: https://blog.csdn.net/whitehat_/article/details/144644810