引言
看资料的第六章内容,都是一些汇编代码案例,本章内容较少,简单记录一些,方便日后随时随地都可以查看。学到这里,能够勉强看懂汇编代码,一些实例了,但是还是不太熟练。
第6章
包含多个段的程序
程序取得所需空间的方法有两种,
- 在加载程序的时候为程序分配,
- 程序在执行的过程中向系统申请。
主要学习的是加载程序的时候为程序分配。
下面借用书中本章较为复杂的一个例子学习。
assume cs:code,ds:data,ss:stack ;定义了三个段,分别是code、date、stack
data segment ;date段
dw 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h ;0-15单元
data ends
stack segment
dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ;0-31单元
stack ends
code segment
start: mov ax, stack;将名称为“stack”的段的段地址送入ax
mov ss, ax
mov sp, 20h ;设置栈顶ss:sp指向stack:20。 20h = 32d
mov ax, data ;将名称为“data”的段的段地址送入ax
mov 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, 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
关键点说明:
- 使用不同段的原因
1、把它们放到一个段中使程序显得混乱;
2、前面程序中处理的数据很少,用到的栈空间也小,加上没有多长的代码,放到一个段里面没有问题。但如果数据、栈和代码需要的空间超过64KB,就不能放在一个段中(一个段的容量不能大于64KB,是我们在学习中所用的8086模式的限制,并不是所有的处理器都这样)。 - 在程序中,段名就相当于一个标号,它代表了段地址。所以指令“mov ax,data”的含义就是将名称为“data”的段的段地址送入ax。一个段中的数据的段地址可由段名代表。
- 指令
mov ds,data
是错误的,因为8086CPU 不允许将一个数值直接送入段寄存器中。编译时,date被处理成了一个表示段地址的数值,而不是一个地址寄存器了。 - 代码中的
code、date、stack、s、so
这些都只是一个标号而已,都只存在源程序中,CPU并不会因为这种写就去把它们区分成不同的段,这样命名,仅仅是为了使程序便于阅读。 - assume是伪指令,是由编译器执行的,也是仅在源程序中存在的信息,CPU并不知道它们。
assume cs:code
并不是说cs就指向了code的段地址。 -
end start
说明了程序的入口,这个入口将被写入可执行文件的描述信息,可执行文件中的程序被加载入内存后,CPU的CS:IP被设置指向这个入口,从而开始执行程序中的第一条指令。 - CPU到底是如何把写的段当做指令、数据或者栈来处理的,是通过汇编指令来设定的,与其他无关,如CS:IP(指令),SS:IP(设置栈空间),DS(设置数据段)等来设置的。
- 程序中的
dw
的含义是定义字型数据。dw
即“define word”
在这里,使用dw定义了8个字型数据(数据之间以逗号分隔),它们所占的内存空间的大小为16个字节。
(一个字大小等于2字节)
参考资料 王爽《汇编语言第三版》
欢迎关注本人微信公众号:那个混子
记录自己学习的过程,分享乐趣、技术、想法、感悟、情感!
单片机类嵌入式交流学习可加企鹅群:120653336
网友评论