汇编语⾔———数据段、程序段、栈段
1. 段的概念
我们注意到,“段地址”这个名称中包含着“段”的概念。这种说法可能对⼀些学习者产⽣了误导,使⼈误以为内存被划分成⼀个⼀个的段,每⼀个段都有⼀个地址。如果我们在⼀开始形成了这种认知,将影响以后对汇编语⾔的深⼊理解和灵活应⽤。
其实,内存并没有分段,段的划分来⾃于CPU。由于8086CPU⽤“基础地址(段地址×16)+偏移地址=物理地址”的⽅式给出内存单元的物理地址,使得我们可以⽤分段的⽅式来管理内存。
如下图所⽰,我们可以认为:地址10000H~100FFH的内存单元组成⼀个段,该段的起始地址(基础地址)为10000H,段地址为
1000H,⼤⼩为100H;我们也可以认为地址10000H~1007F、10080H~100FHH的内存单元组成两个段,它们的起始地址(基础地址)为:10000H和10080H,段地址为:1000H和1008H,⼤⼩都为80H。
分段
以后,在编程时可以根据需要,将若⼲个地址连续的内存单元看做⼀个段,⽤段地址×16定位段的起始地址(基础地址),⽤偏移地址定位段中的内存单元。
有两点需要注意:段地址×16必然是16的倍数,所以⼀个段的起始地址也⼀定是16的倍数;偏移地址为16位,16位的寻址能⼒为
64KB,所以⼀个段的长度最⼤为64KB。
内存单元地址⼩结
CPU访问内存单元时,必须向内存提供内存单元的物理地址。8086CPU在内部⽤段地址和偏移地址移位相加的⽅法形成最终的物理地址。
思考下⾯的两个问题。
(1)观察下⾯的地址,你有什么发现?
物理地址段地址偏移地址
21F60H2000H1F60
2100H0F60
21F0H0060H
21F6H0000H
1F00H2F60H
结论:CPU可以⽤不同的段地址和偏移地址形成同⼀个物理地址。
⽐如CPU要访问21F60H单元,则它给出的段地址SA和偏移地址EA满⾜SA×16+EA=21F60H即可。
(2)如果给定⼀个段地址,仅通过变化偏移地址来进⾏寻址,最多可以定位多少个内存单元?
结论:偏移地址16位,变化范围为0~FFFFH,仅⽤偏移地址来寻址最多可以寻64KB个内存单元。
⽐如给定段地址1000H,⽤偏移地址寻址,CPU的寻址范围为:10000H~1FFFFH。
在8086PC机中,存储单元的地址⽤两个元素来描述,即段地址和偏移地址。
“数据在21F60H内存单元中。”这句话对于8086PC机⼀般不这样讲,取⽽代之的是两种类似的说法:①数据存在内存2000:1F60单元中;②数据存在内存的20000H段中的1F60H单元中。这两种描述都表⽰“数据在内存21F60H单元中”。
可以根据需要,将地址连续、起始地址为16的倍数的⼀组内存单元定义为⼀个段。
问:什么是段地址?
答:段地址是针对内存的分段⽽⾔的,将每⼀段的段⾸地址定义为段地址。段地址的存在是由系统的分段存储决定的,通过段地址和偏移地址就能对数据进⾏寻访。
问:什么是偏移地址?
答:偏移地址也称为偏移量,由于8086/8088CPU内部的ALU只能进⾏16位的运算,⽽8086/8088有20条地址线,直接寻址能⼒
1MB。因此,8086/8088所使⽤的20位物理地址,是由相应的段地址加上偏移地址组成的。
问:为什么给定段地址1000H,⽤偏移地址寻址,CPU的寻址范围为:10000H~1FFFFH?
答:把段地址1000H,乘以16,就是在1000H后⾯加上个0,可得到10000H。
把10000H,加上偏移量的范围0000H~FFFFH,
即有CPU的寻址范围:10000H~1FFFFH。
----------
偏移量的范围0000H~FFFFH,就是16位⼆进制数的变化范围。
2. 段寄存器
1. CS和IP。
CS为代码段存器,IP为指令指针寄存器。CPU将CS:IP指向的内容当作当前的指令。
2. DS
存放要访问的数据的段地址。8086CPU⾃动取ds中的数据为内存单元的段地址。同时8086CPU不⽀持将数据直接送⼊段寄存器操作。eg:将10000H的内容,送⼊al。
汇编语言要什么基础mov ax,1000
mov ds,ax
mov al,[0]
3. SS和SP
3.数据段、程序段、栈段
数据段:存放数据的段。使⽤时候,⽤DS寄存器。
程序段:⽤来存放程序的段。使⽤的时候,⽤CS和IP寄存器。
栈段:是⼀个栈。使⽤时,初始设置SS和SP寄存器。
实战操作⼀波:把10000H~1000FH的空间当作栈;把20000H和20002H中的数据通过栈进⾏对换。程序的位置在30000H ~。
debug -a 3000:0
/*⾸先是在程序段中写程序*/
//建⽴栈
mov ax,1000
mov ss,ax
mov sp 0010//注意
//到数据段的位置
mov ax,2000
mov ds,ax
//兑换内存中的数据
push [0]
push [2]
pop [0]
pop [2]
//执⾏程序段
-r cs
3000
-r ip
-t//多次执⾏
注意:实验的时候,要注意各个寄存器的变化。Debug的T命令在执⾏修改寄存器SS的指令的时候,下⼀条指令也会紧接着执⾏。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论