《汇编语言》- 读书笔记 - 第6章- 包含多个段的程序
- 6.1 在代码段中使用数据
- 程序 6.1
- 程序 6.2
- 6.2 在代码段中使用栈
- 6.3 将数据、代码、栈放入不同的段
- 程序 6.4
- 实验 5 编写、调试具有多个段的程序
应该将数据、代码、栈放进不同的段中。
程序在加载和运行时都可以向系统申请内存空间来用。
从系统申请内存来用才是安全的,不应该自己直接写内存,那样可能会破坏重要数据。
6.1 在代码段中使用数据
考虑这样一个问题,编程计算以下 8 个数据的和,结果存在 ax 寄存器中:
0123h, 0456h, 0789h, 0abch, 0defh, 0fedh, 0cbah, 0987h
在代码中声明数据段
,这样程序加载到内容中,这些数据也就合法的从系统获得了内存空间。
程序 6.1
没有 start 用于引出 6.2,程序没法正常执行。
程序 6.2
assume cs:code
code segment
dw 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h
start: mov bx, 0
mov ax, 0
mov cx, 8
s: add ax, cs:[bx]
add bx, 2
loop s
mov ax, 4c00h
int 21h
code ends
end start
dw
表示define word
。定义字型数据。代码中共定义了8个,占16字节。add ax, cs:[bx]
:因为数据放在代码段,所以可以从CS
获取段地址。- 数据在代码段开头,所以偏移从 0 开始。
- 因为是
字类型
,所以每次偏移量+2
。8个数据的偏移分别对应:0、2、4、6、8、A、C、E
- 标号 start 用于指定程序入口。也就是
CS:IP
指向的位置。因为代码段的开头我们放的是一堆数据,它们是没法正常执行的。
可执行文件由描述信息
和程序
组成,CS:IP
的指向就在描述信息
中。
描述信息
由编译连接程序对源程序中的伪指令处理得来。
6.2 在代码段中使用栈
assume cs:code
code segment
dw 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h ; cs:00~0F
dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ; cs:10~2F
start: mov ax, cs
mov ss, ax
mov sp, 30h ; 栈顶指向CS:30,cs:2E + 2
mov bx, 0
mov cx, 8
s: push cs:[bx]
add bx, 2
loop s ; 以上将代码段 0~15 单元中的 8 个字型数据依次入栈
mov bx, 0
mov cx, 8
s0: pop cs:[bx]
add bx, 2
loop s0 ; 以上依次出栈 8 个字型数据到代码段 0~15 单元中
mov ax, 4c00h
int 21h
code ends
end start
可以说 dw 定义了 xx 个字的数据,也可以说它开辟了 xx 个字的内存空间。效果一样。
6.3 将数据、代码、栈放入不同的段
- 把
数据
、代码
、栈
放到一个段中使程序显得混乱; - 如果
数据
、栈
和代码
需要的空间超过 64KB,就不能放在一个段中。(一个段的容量不能大于 64KB,是我们在学习中所用的 8086 模式的限制,并不是所有的处理器都这样)。
程序 6.4
6.4 实现 6.3 一样的功能,不同之处在于将数据、栈和代码放到了不同的段中。
assume cs:code, ds:data, ss:stack
data segment
dw 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h
data ends
stack segment
dw 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16
stack ends
code segment
start: mov ax, stack ; 获取栈段
mov ss, ax ; 设置栈段
mov sp, 20h ; 设置栈顶 ss:sp 指向 stack:20h
mov ax, data
mov ds, ax ; ds 指向 data 段
mov bx, 0
mov cx, 8
s: push [bx]
add bx, 2
loop s ; 以上将 data 段中的 0~15 单元中的 8 个字型数据依次入栈
mov bx, 0
mov cx, 8
s0: pop [bx]
add bx, 2
loop s0 ; 以上依次出栈 8 个字型数据到 data 段的 0~15 单元中
mov ax, 4c00h
int 21h
code ends
end start
- 定义多个段的方法:定义一个段的方法和前面所讲的定义代码段的方法没有区别,只是对于不同的段,要有不同的段名。
- 对段地址的引用:在程序中
段名
就代表段地址
。如:mov ax,data
将名称为data
的段的段地址送入ax
。 代码段
,数据段
,栈段
完全是我们的安排。当作什么来用完全是我们对CS:IP
、SS:SP
、DS
等寄存器的设置来决定的。
实验 5 编写、调试具有多个段的程序
《汇编语言》- 读书笔记 - 实验5 编写、调试具有多个段的程序