王爽 《汇编语言》 读书笔记 六 包含多个段的程序

第六章  包含多个段段程序


程序所需要空间有两种方法,一是加载程序时为程序分配,二是在运行时向系统申请(暂不讨论)

1)在一个段中存放数据,代码,栈,段情况

2)将数据,代码,栈放入不同段段中。


6.1 在代码段中使用数据

累加一下8个数据  存入ax中

0123h, 0456h, 0789h, 0abch, 0defh, 0fedh, 0cbah, 0987h


assume cs:code
code 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
code ends
end

dw表示 define word  定义字型数据


由于前16个字节是自定义数据被debug翻译成汇编指令就会看不懂。

从cs:10h开始就是程序的内容


修改IP值为10h  用g t  p之类的可以正常执行程序

但是直接中系统中执行会出问题。需要指明程序的入口

在入口处加入标号start  

在end 后加上start 表面程序入口地址是start

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

修改后重新编译用debug查看入口的IP被设置为10h


这样代码可以正常运行。

可执行文件中有描述信息记录第一条指令的地址。程序被加载后加载器读取其描述信息获取入口地址,然后设置CS:IP 

也就是用end 后加标号指明入口地址

一个基本的代码框架

assume cs:code
code segment
	;data definition

start: ; code definition

	mov ax, 4c00h
	int 21h
code ends
end start


6.2 在代码段中使用栈

完成以下代码,利用栈,将程序中定义的数据逆序排放

assume cs:code
code segment
		dw 0123h, 0456h, 0789h, 0abch, 0defh, 0fedh, 0cbah, 0987h ;data definition

start: 	 ;code definition

		mov ax, 4c00h
		int 21h
code ends
end start

可以用默认系统分配的栈(但是地址随机性加上系统不管理栈溢出问题)

编译后代码如下

assume cs:code
code segment
		dw 0123h, 0456h, 0789h, 0abch, 0defh, 0fedh, 0cbah, 0987h ;data definition
		dw 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0	;  16 x dword space for stack
start: 	mov ax, cs ;code definition
		mov ss, ax
		mov sp, 30h
		
		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
code ends
end start

运行结果如下

dw 可用于定义数据 或者 定义存储空间(静态区)


监测点

6.1 代码

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
		add bx, 2
		loop s
		
		mov ax, 4c00h
		int 21h
codesg ends
end start


运行结果


2)用内存0:0~0:15单元中的内容修改程序中的数据,数据传送用栈来进行。

运行时0:0 ~f的数据会被修改运行之后重新check 0:0~f 与CS:0~f的数据

代码

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 dword space
		
start:	mov ax, cs
		mov ss, ax
		mov sp, 24h
		
		mov ax, 0
		mov ds, ax
		mov bx, 0
		mov cx, 8
	s:	push [bx]
		pop cs:[bx]
		add bx, 2
		loop s
		
		mov ax, 4c00h
		int 21h
codesg ends
end start

运行结果



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

将数据,空间,栈放一起有弊端

1)程序显得混乱

2)前面处理的数据少,如果超过64KB就不能放在一个段中(8086的限制 段容量不能大于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  ; 16 dword space of stacks
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

mov ds, data 是错误的。

因为8086不允许直接将数据送入段寄存器

mov ax, data会被编译器处理成一个表示段段段地址

1)cpu并不区分段,只是程序设计的安排

2)伪指令 assume cs:code, ds:data, ss:stack cpu并不会立拿cs 指向code ds指向data ss指向stack

3)需要用机器指令控制cpu


实验5 编写调试多个段的程序

5) 编写代码 将a段和b段段数据一次相加结果存入c段

assume cs:code
a segment
	db 1, 2, 3, 4, 5, 6, 7, 8
a ends

b segment
	db 1, 2, 3, 4, 5, 6, 7, 8
b ends

c segment
	db 0, 0, 0, 0, 0, 0, 0, 0
c ends

code segment
start:	mov ax, c
		mov ds, ax ; set data segment to c
		
		mov bx, 0
		mov cx, 8
	s:	mov ax, a
		mov es, ax	; set es to a
		mov dl, es:[bx]
		
		mov ax, b
		mov es, ax	; set es to b
		add dl, es:[bx]
		
		mov [bx], dl ; save the result to ds:[bx]
		inc bx
		loop s
		
		mov ax, 4c00h
		int 21h

code ends
end start
运行结果

6) 将a段中段前8个字数据逆序存储到b段段8个字单元中

assume cs:code
a segment
	dw 1, 2, 3, 4, 5, 6, 7, 8, 9, 0ah, 0bh, 0ch, 0dh, 0eh, 0fh, 0ffh
a ends

b segment
	dw 0, 0, 0, 0, 0, 0, 0, 0
b ends

code segment
start:	mov ax, b
		mov ss, ax	; set ss to b
		mov sp, 10h
		
		mov ax, a
		mov ds, ax	; set ds to a
				
		mov bx, 0
		mov cx, 8
		
	s:	mov ax, [bx] ; get data from (ds:bx)
		push ax
		add bx, 2
		loop s
		
		mov ax, 4c00h
		int 21h

code ends
end start

运行结果如下




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值