汇编语言(王爽版)学习笔记 第六章 包含多个段的程序

6.1 在代码段中使用数据

考虑这样一个问题,编程计算以下8个数据的和,结果存在ax寄存器中:
0123H,0456H,0789H,0abcH,0defH,0fedH,0cbaH,0987H。
(前面的章节是累加某些内存单元中的数据,并不关心数据本身。这个问题是要累加已经给定了数值的数据。)
assume cs:codesg
codesg segment
	dw 0123H,0456H,0789H,0abcH,0defH,0fedH,0cbaH,0987H
	mov bx,0
	mov ax,0
	mov cx,8
s: add ax,cs:[bx]
	add bx,2
	loop s
	mov ax,4c00h
	int 21h
codesg ends
end
"dw"含义是定义字型数据,即define word
在这里,我们使用dw定义了8个字型数据(数据之间以逗号分隔),它们所占的内存空间的大小为16个字节。
用dw定义的数据处于代码段的最开始,所以偏移地址为0,2,4,6,8,A,C,E处。

在这里插入图片描述

assume cs:codesg
codesg 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
codesg ends
end start
end作用:
end除了通知编译器程序结束外,还可以通知编译器程序的入口在什么地方。

6.2 在代码段中使用栈

完成下面的程序,利用栈,将程序中定义的数据逆序存放。
assume cs:codesg
codesg segment
	dw 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h ;定义字型数据
	?
code ends
end
程序思路:
程序运行时,定义的数据存放在cs:0~cs:15单元中,共8个字单元。
依次将这8个字单元中的数据入栈,然后再依次出栈到这8个字单元中,从而实现数据的逆序存放。
assume cs:codesg
codesg segment
	dw 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h
	dw 0,0,0,0,0,0,0,0
	
	
 start:mov ax,cs
	mov ss,ax
	mov sp,32
	mov bx,0
	mov cx,8
	s:push cs:[bx]
	add bx,2
	loop s
	
	mov bx,0
	mov cx,8
 s0:pop cs:[bx]
	add bx,2
	loop s0
	mov ax,4c00h
	int 21h
	
codesg ends
end start

检测点6.1

(1)下面的程序依次实现用0:0~0:15内存单元的内容改写程序中的数据

assume cs:codesg
codesg segment
        dw 0123H,0456H,0789H,0abcH,0defH,0fedH,0cbaH,0987H
start:
        mov ax,0
        mov ds,ax
        mov bx,0
        mov cx,8
s:        mov ax,[bx]
        mov cs:[bx],ax;填空地址,dw对应地址为cs:从0到定义数量*2,将ds:[bx]的数覆盖dw
        add bx,2
        loop s
        
        
        mov ax,4c00H
        int 21h
codesg ends
end start

(2)下面的程序依次实现用0:0~0:15内存单元的内容改写程序中的数据,数据的传送用栈来进行,栈空间设置在程序内。

assume cs:codesg
codesg segment

    dw 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h  # 定义数据
    dw 0,0,0,0,0,0,0,0,0,0   # 10个字单元用作栈空间
start: mov ax,cs         # 定义代码段
       mov ss,ax         # 定义栈段
       mov sp,24h        # 定义栈底为24h (hex(8*2 + 10*2))
       
       mov ax,0
       mov ds,ax         # 定义内存起始段
       mov bx,0          # 定义内存偏移
       mov cx,8         
       
    s: push [bx]         # 将ds:[bx]内存单元中的数据写入栈单元ss:sp(sp=24h) -> sp=24h - 2h = 22h
       pop cs:[bx]       # 将ss:sp(sp=22h)为栈顶的字单元中的数据写入cs:[bx]中 -> sp=22h + 2h = 24h
       add bx,2          
       loop s

       mov ax,4c00h
       int 21h

codesg ends
end start    

6.3 将数据、代码、栈放入不同的段

  • 将数据和代码放到同一个段中,使得程序看上去混乱
  • 如果数据、栈和代码需要的空间超过64KB,就不能放在一个段中(一个段的容量不能大于64KB,是我们在学习所用的8086模式的限制,并不是所有的处理器都这样)

如何解决?

  • 我们用和定义代码段一样的方法来定义多个段,然后在这些段里面定义需要的数据,或通过定义数据来取得栈空间。
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
			mov ax,data
			mov ds,ax
			mov bx,0
			mov cx,8
		s:push [bx]
			add bx,2
			loop s
			mov bx,0
			mov cx,8
		s0:pop [bx]
			add bx,2
			loop s0
			mov ax,4c00h
			int 21h
code ends
end start
说明:
1.我们在源程序中为这三个段起了具有含义的名称。
用来存放数据的段我们将其命名为"data",用来存放代码的段我们将其命名为"code",用来作栈空间的命名为"stack"
 2.assume是伪指令,是由编译器执行的。

CPU如何执行程序?

我们在源程序的最后用"end start"说明了程序的入口。
这个入口将被写入可执行文件的描述信息,可执行文件中的程序被加载如内存后,
CPU的CS:IP被设置指向这个入口,从而开始执行程序中的第一条指令。
标号"start"在"code"段中,这样CPU就将code段中的内容当作指令来执行了。
我们在code段中,使用指令:
mov ax,stack
mov ss,ax
mov sp,16

设置ss指向stack,设置ss:sp指向stack:16,CPU执行这些指令后,将把stack段当作栈空间来用。
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值