前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >8086汇编语言之代码分段

8086汇编语言之代码分段

作者头像
乱码三千
发布2021-08-24 15:13:04
9740
发布2021-08-24 15:13:04
举报
文章被收录于专栏:乱码三千乱码三千

## 场景

当我们需要在内存中申请一块空间,可以使用伪指令dbdw

代码语言:javascript
复制
db-->define byte  定义字节
dw-->define word  定义字

如果按照以下写法:

代码语言:javascript
复制
assume cs:code
code segment
	db 1,2,3,4,5
	db 'hello'
	db "pangshu"
	
	mov al ,cs:[0] ;取出预先定义好的数据 ip默认从0开始
	;退出程序
	mov ah 4ch
	int 21h
code ends
end

以上代码存在一个问题, 由于数据是在代码段中定义, cpu默认将数据识别为代码, 将导致数据不可用,那么解决办法为,增加入口标记:

代码语言:javascript
复制
assume cs:code
code segment
	db 1,2,3,4,5
	db 'hello'
	db "pangshu"
	
start:	mov al ,cs:[0] ;取出预先定义好的数据 ip默认从0开始
		;退出程序
		mov ah 4ch
		int 21h
code ends
end start ;标记名称可自定义

标记是为了告诉编译器代码段入口位置, 这样就能保证db数据不被识别为指令

知识点

  1. 如果我想定义20个0数据,有一种快捷的语法:
代码语言:javascript
复制
assume cs:code
code segment	
	db 20 dup(0) ;申请20个字节的空间 然后存放0
	
start:	mov al ,cs:[0] ;取出预先定义好的数据 ip默认从0开始
		;退出程序
		mov ah 4ch
		int 21h
code ends
end start ;标记名称可自定义
  1. 数据段和栈段的定义
代码语言:javascript
复制
assume cs:code
code segment	
	db 20 dup(0) ;可存数据也可当作栈
	db 20 dup(0) ;可存数据也可当作栈
start:	;将数据所在的物理基地址交由ds段寄存器进行存放管理
		mov dx,cs
		mov ds,dx
		mov ax,1122h
		mov [0],ax
		
		;定义栈段 将栈空间所在的物理基地址交由ss栈段进行保存管理
		mov ss,ds
		mov sp,40 ;从高字节往低字节存放
		push ax
		
		;退出程序
		mov ah 4ch
		int 21h
code ends
end start ;标记名称可自定义
  1. 分段定义
代码语言:javascript
复制
assume cs:code,ds:data,ss:stack

;数据段 代码段可直接获取数据段中数据, 相当于高级语言中的局部变量
stack segment
	db 20 dup(0) ;定义数据相当于是定义了段地址
stack ends

;数据段 代码段可直接获取数据段中数据, 相当于高级语言中的全局变量
data segment
	db 20 dup(0) ;定义数据相当于是定义了段地址
	age dw 20h ;给数据取个别名为age
	
data ends

code segment	
	
	
start:	
		mov ax,1122h
		mov age,ax ; 相当于[14h],ax
		
		;退出程序
		mov ah 4ch
		int 21h
code ends
end start ;标记名称可自定义

额外思考

事实上我们使用的段其实是一个逻辑概念,即是我们自己定义的,

再说白了,我定义一个段,我说它是数据段那它就是数据段,我说它是代码段那么它就是代码段,

它们其实都是一块连续的内存而已,至于为什么要区分为数据段和代码段,

很明显,是用来给我们编程提供方便的,即我们在自己的思想上或者说是编码习惯上规定,

数据放数据段中,代码放代码段中 。而我们在使用数据段的时候,为了方便或者说是代码的编写方便起见,

我们一般把数据段的段地址放在 DS 寄存器中,当然,如果你硬要觉得 DS 不顺眼,那你可以换个 ES 也是一样的,但是换成CS则不行,因为CS指向的数据都被当成指令进行处理,如果换成SS呢,可行,但是读取数据需要使用pop,修改数据需要使用push,如果是用DS或者ES ,可以直接使用DS:[0]这种形式进行内存数据的读写

被DS和ES指向的内存空间的数据被cpu当作数据处理,被SS指向的内存空间的数据被cpu当作是栈空间,被CS指向的内存空间的数据被cpu当作指令进行执行

看注释说明:

代码语言:javascript
复制
assume cs:code,ds:data,ss:stack

;开辟了一块栈空间 同时生成了与之对应的物理地址
stack segment
	db 20 dup(0) ;定义数据相当于是定义了段地址
stack ends

;开辟了一块数据空间 同时生成了与之对应的物理地址
data segment
	db 20 dup(0) ;定义数据相当于是定义了段地址
	age dw 20h ;给数据取个别名为age
	
data ends

;开辟了一块代码空间 如果没有入口标记 那么里面无论存放什么, cpu都把它当成指令
code segment	
start:	
		;程序开始
		
		;获取栈空间基地址 存放在ss寄存器中
		mov ax ,stack
		mov ss ,ax
		;获取数据空间基地址 存放在ds寄存器中
		mov ax,data
		mov ds ,ax
		
		;如果有别名 可以直接使用别名访问数据,而不需要另外借助段地址
		mov age,ax ; 相当于[14h],ax
		
		;退出程序
		mov ah 4ch
		int 21h
code ends
end start ;标记名称可自定义
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-08-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 乱码三千 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 知识点
  • 额外思考
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档