文章目录
- 包含多个段的程序
- 在代码段中使用数据
- 在代码段中使用栈
- 将数据、代码、栈放入不同的段
包含多个段的程序
在代码段中使用数据
考虑这样一个问题,编程计算以下8个数据的和,结果存在ax 寄存器中:0123H,0456H,0789H,0abcH,0defH,0fedH,0cbaH,0987H。
代码:
assume cs:codesg
codesg segmentdw 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987hmov bx,0mov ax,0mov cx,8s: add ax,cs:[bx]add bx,2loop smov ax,4c00hint 21h
codesg ends
end
“dw”的含义是定义字型数据。dw即define word。在这里,我们使用dw定义了8个字型数据(数据之间以逗号分隔),它们所占的内存空间的大小为16个字节。
这8 个数据在代码段的偏移地址为0、2、4、6、8、A、C、E处。
程序中,我们用bx存放加2递增的偏移地址,用循环来进行累加。
在循环开始前,设置(bx)=0,cs:bx指向第一个数据所在的字单元。
每次循环中(bx)=(bx)+2,cs:bx指向下一个数据所在的字单元。
查看内存单元地址可得cs:ip指向第一个字单元,此字单元被我们用来存储数据,计算机却误认为这是代码并从此处开始执行。
再次查询偏移地址为16的内存空间,这次得到的才是我们真正要执行的代码。
为了解决上述问题,我们可以给代码段添加一个开始标识符
assume cs:codesg
codesg segmentdw 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987hstart: mov bx,0mov ax,0mov cx,8s: add ax,cs:[bx]add bx,2loop smov ax,4c00hint 21h
codesg ends
end start
再次调式可得程序会从偏移地址为16的位置开始执行代码。
在代码段中使用栈
我们可以在程序中通过定义数据来取得一段空间,然后将这段空间当作栈空间来用。
代码示例:利用栈,将程序中定义的数据逆序存放
assume cs: codesg
codesg segmentdw 0123h,0456h,0789h,0abch,0defh, 0fedh,0cbah,0987hdw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0;用dw定义16个字型数据,在程序加载后,将取得16 个字的;内存空间,存放这16个数据。在后面的程序中将这段;空间当作栈来使用
start: mov ax,cs mov ss,ax mov sp,30h ;将设置栈顶ss:sp指向cs:30mov bx,0mov cx,8s: push cs:[bx]add bx,2loop s ;以上将代码段0~15单元中的8个字型数据依次入栈mov bx,0mov cx,8
s0: pop cs:[bx]add bx,21oop s0 ;以上依次出栈8个字型数据到代码段0~15单元中mov ax, 4c00hint 21h
codesg ends
end start
将数据、代码、栈放入不同的段
我们在程序中用到了数据和栈,我们将数据、栈和代码都放到了一个段里面。我们在编程的时候要注意何处是数据,何处是栈,何处是代码。
这样做显然有两个问题:
- 把它们放到一个段中使程序显得混乱。
- 前面程序中处理的数据很少,用到的栈空间也小,加上没有多长的代码,放到一个段里面没有问题。但如果数据、栈和代码需要的空间超过64KB,就不能放在一个段中(一个段的容量不能大于64 KB,是我们在学习中所用的8086模式的限制,并不是所有的处理器都这样)。
所以,我们应该考虑用多个段来存放数据、代码和栈。
我们用和定义代码段一样的方法来定义多个段,然后在这些段里面定义需要的数据,或通过定义数据来取得栈空间。
代码示例
assume cs:code, ds:data,ss:stackdata segmentdw 0123h, 0456h, 0789h, 0abch,0defh,0fedh,0cbah,0987h
data endsstack segmentdw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
stack endscode segmentstart: mov ax,stackmov ss,axmov sp,20h ;设置栈顶ss:sp指向 stack:20mov ax,datamov ds,ax ;ds指向data段mov bx,0 ;ds:bx指向data段中的第一个单元mov cx,8 s: push [bx]add bx, 2 loop s ;以上将data段中的0~15单元中的8个字型数据依次入栈mov bx,0mov cx,8 s0: pop [bx]add bx,2loop s0 ;以上依次出栈8个字型数据到data段的0~15单元中mov ax,4c00hint 21h
code ends
end start