专栏首页乱码三千8086汇编语言之代码分段

8086汇编语言之代码分段

## 场景

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

db-->define byte  定义字节
dw-->define word  定义字

如果按照以下写法:

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默认将数据识别为代码, 将导致数据不可用,那么解决办法为,增加入口标记:

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数据,有一种快捷的语法:
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. 数据段和栈段的定义
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. 分段定义
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当作指令进行执行

看注释说明:

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 ;标记名称可自定义

本文分享自微信公众号 - 乱码三千(infree6),作者:有瓣知识

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2021-08-11

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 8086汇编语言之数据段和代码段以及栈段的理解

    代码从 MOV AX 0220H 开始,那么代码段指向这行代码地址, 如果想要跳过这行代码的执行,那么进行代码段偏移

    乱码三千
  • 8086汇编语言之Loop

    Loop指令和cx寄存器配合使用, 用于循环操作,类似于高级语言中的do while循环

    乱码三千
  • 8086汇编语言——使用数据段和栈段

    zy010101
  • 8086汇编语言之dos打印hello world

    乱码三千
  • x86汇编语言之8086语法和指令集

    上面使用db或者dw定义数据的方式,定义数据的同时就已经定义好了数据所在的物理地址, 如果我们想要从指定的内存地址中写入或者读取数据的话,需要借助段寄存器来实现...

    乱码三千
  • 8086汇编语言之函数的声明和调用

    由于print函数默认执行,为了保证在call时才执行, 咱们将print函数代码移至中断后:

    乱码三千
  • 8086汇编语言之debug模式常用指令介绍

    上面为 (段地址:偏移地址) 查看方式。D命令默认会显示寻址地址开始的后128个内存单元的内容,以16进制的方式显示(每个内存单元8位,一行最多16个内存单元)...

    乱码三千
  • Linux 从头学 01:CPU 是如何执行一条指令的?

    这两年多以来,我的本职工作重心一直是在 x86 Linux 系统这一块,从驱动到中间层,再到应用层的开发。

    IOT物联网小镇
  • 汇编语言之GNU ARM

    GNU最开始其实是一个操作系统,旨为打造一个开源免费自由的操作系统,目前操作系统还在完善中

    乱码三千
  • 16位汇编第第四讲常用的7种寻址方式

    常用的7中寻址方式 昨天稍微讲了一下,立即数寻址,今天继续讲解寻址方式. (注意,这个属于简陋版的,写了4个小时的博客,也就是第一版,保存了一下,但是博客出问题...

    IBinary
  • 8086汇编语言之各个通用寄存器的作用

    1. asm编译器无法识别中括号,mov ax,[0]编译时会默认去除中括号.使用bx替代可以解决这个问题,如果在debug模式下使用-a命令输入中括号则没有问...

    乱码三千
  • 未整理的计组复习笔记?

    计组是我听过的最脑阔疼的课。不过已经考过了orz以及,大家学的计组内容可能不一样,这篇复习包括的内容应该是比较简略的。

    gojam
  • Linux从头学03:如何告诉 CPU,代码段、数据段、栈段在内存中什么位置?

    前两篇文章,我们一起学习了 8086 处理器中关于 CPU、内存的基本使用方式,重点对段寄存器和内存的寻址方式进行了介绍。

    IOT物联网小镇
  • 爱了爱了,这篇寄存器讲的有点意思

    下面我们就来介绍一下关于寄存器的相关内容。我们知道,寄存器是 CPU 内部的构造,它主要用于信息的存储。除此之外,CPU 内部还有运算器,负责处理数据;控制器控...

    C语言与CPP编程
  • go语言调度器源代码情景分析之六:go汇编语言

    go语言runtime(包括调度器)源代码中有部分代码是用汇编语言编写的,不过这些汇编代码并非针对特定体系结构的汇编代码,而是go语言引入的一种伪汇编,它同样也...

    阿波张
  • 吹弹牛皮之C++ 汇编指令

    本节及接下来的研究内容,着重的是x64的汇编。x64汇编根据编译器的不同,又有两种书写格式。

    用户7698595
  • JITWatch查看字节码被JIT编译后的汇编代码

    最近看书看到关于volitale关键字与jmm内存模型的介绍,这个知识点似乎看了好多次,背都能背下来了。但理论性的东西真的很容易忘记,看不到摸不着。于是乎,我上...

    Java艺术
  • 《汇编语言》——笔记(一)

    在讲汇编语言之前,先介绍下机器语言。机器语言是机器指令的集合。电子计算机的机器指令是一列二进制数字,计算机将转变高低电平,来驱动电子器件。

    天钧
  • 汇编语言学习

       7、1Byte = 8bit ;    1KB = 1024B ;  1MB = 1024KB ;   1GB = 1024MB

    tandaxia

扫码关注云+社区

领取腾讯云代金券