汇编语言第六章总结
-
在代码段中使用数据
assume cs:code code segment dw 0123h,0456h,0789h,0abch,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
1.dw——定义字型数据,即define word(类似,db即为定义字节数据)。
(这些数据的偏移地址分别为0、2、4、6、8、A、C、E,没有标号start时,它们的段地址在CS中,因为这是一段代码段)
2.标号start与end start——end除了通知编译器程序结束外,还可以通知编译器程序的入口在什么地方,此处用end指令表明了程序的入口在标号start处,被转化为一个入口地址。
3.当程序被加载入内存之后,通过读到程序的入口地址,设置CS:IP。
-
在代码段中使用栈
assume cs:codesg codesg segment dw 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h ;用dw定义16个字型数据,在程序加载后,将取得16个字的内存空间,0~f,存放这16个数据 dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ;在此处预留了32个字节作为栈,10~2f,在后面的程序将这段空间当作栈来使用 start: mov ax,cs mov ss,ax mov sp,30h ;将栈顶ss:sp指向cs:30h 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单元中 codesg ends end start
1.注意:我们将cs:10~cs:2F的内存空间当作栈来用,初始状态下为空,所以ss:sp要指向栈底,即cs:30h
-
将数据、代码、栈放入不同的栈
1.放在一个段的缺点:
(1)把它们放到一个栈中使程序显得混乱
(2)若数据、栈和代码需要的空间超过64KB,就不能放在一个段中(一个段的容量不能大于64KB)
assume cs:code, ds:data, ss:stack data segment dw 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h data ends stack segment dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 stack ends code segment start: mov ax,stack ;注意 mov ss,ax mov sp,20h ;设置栈顶ss:sp指向stack:20 mov ax,data ;注意 mov ds,ax ;ds指向data段 mov bx,0 ;ds:bx指向data段中的第一个单元 : :(与上面代码相同,部分省略)
2.一个段中的数据的段地址可由段名代表,在上例中data和stack这两个段名就存入了相应的段寄存器中
3.注意:
(1)mov ds,data 是错误的,8086不允许将一个数值直接送入段寄存器中,在编译器中将段名表示为一个段地址的数值
(2)用伪指令assume将cs、ds、ss分别和code、data、stack段相连之后,CPU也没并没有将对应的段和段寄存器相连接,因为assume只是伪指令
(3)在源程序的最后用end start说明了程序的入口,CPU将会设置CS:IP,再执行里面的指令mov ax,stack等和mov ax,data等时,才真正地实现了SS:SP、DS等的设置