[汇编]包含多个段的程序,定位内存地址

刚刚学markdown,为适应语法,下面的格式包含 炫技 成分,看着难受也不关我事

包含多个段的程序

dw:数据存放在哪里

程序需要其他空间来存放数据,这个内存空间一定要是安全的。而在操作系统允许的情况下,程序可以取得任意容量的空间。
程序取得所需空间的方法有两种:

  1. 加载程序时系统自动分配内存空间
  2. 执行过程中向系统申请内存空间

申请方法不讨论,我们下面讨论能让系统心甘情愿为我们分配空间的方法。
这种方法的关键是定义段

assume cs:code
code segment
dw  0123h,0456h,0789h

==dw(define word)==是定义字型数据[^1]的关键字
注意:dw定义的数据内存空间处于代码段的最开始,
所以它的偏移地址 CS:0,CS:2 …

由于dw在代码指令之前,所以要借助start关键字来指定程序入口所在。

dw 0123h ...
start: mov bx,0  
       mov ax,0
          ...
code ends //结束代码段
end start

程序之所以知道哪一条是第一个要执行的指令,是因为 可执行文件中的描述信息 的指明。而一个可执行文件由描述信息程序本身 组成,

  • 程序来自于源程序中的汇编指令和定义数据;
  • 描述信息主要是编译和连接过程中,对源程序的伪指令进行处理得到的信息。

实际上,伪指令end 和 紧随其后的标号 就会被转化为地址存放在描述信息中。

如果你的指令操作有内存空间的需求(像需要一些memory space来作为栈),
可以用数据0 提前占位。

dw 0123h,0456h,0789h    #该数据段在最开始 CS:0处,即CS :00~CS:06
dw 0 0 0 0 0 0 0 0       #预先占位的内存,地址为CS:07~CS:26

由上,dw的作用可以说有两个方面

  • 定义数据
  • 开辟内存空间

定义多个段

场景
值得注意的是,代码段和数据段、栈等在源程序中要分段处理。定义多个段,不仅能让代码更简洁,还因为一个段本身的容量限制。应考虑定义多个段来存放不同内容。
格式

assume cs:code,ds:data,ss:stack
data segment
dw 0123h,0456h
data ends

stack segment
dw 0,0,0,0,0
stack ends
code segment
start: mov ax,stack
mov sp,2h
mov ax,data
code ends
end start

规律:

  • 定义不同的段时,要有不同的段名
  • 段名相当于一个标号,它代表了段地址。

该段中数据的段地址由段名代表,偏移地址看他在段中的位置
(这里强调一下,不允许将数值直接送入段寄存器)

当我们谈到多个段时,我们谈些什么

①segment 与 ends 是配套使用的,而段名则是随意命名。编译器不管你是stack,stock乃至st0ck,在它眼里只是一个段。我们定义段为code,stack,data等仅仅为了方便用户阅读。
②assume cs:code 等伪指令是由编译器执行,跟CPU没什么关系,也不会将CS真的指向code。具体的意义这里不深究。

[^1]:这些定义的数据内存大小当然是16字节喽


灵活定位内存地址

何谈灵活

先明确一下,所谓的灵活定位,只是因为加了一个变量:idata和两个类bx寄存器 si和di。

  • idata是任意常量
  • 同bx一样,bp是另一个基址寄存器
  • si和di是类似bx功能的变址寄存器(只是这俩不能分成两个8位寄存器使用)

所以指定内存地址,现在的方法有:
[bx(+idata)] [si(+idata)] [di(+idata)]
[bx+si(+idata)] [bx+di+idata]
注意点:

  1. [bx+si]可以表示为[bx][si]
  2. si和bi两个变址寄存器不能同时使用。
    bx和bp两个基址寄存器不能同时使用

AND OR的介绍

AND

格式:AND 数据寄存器 对应进制数据
效果:逻辑意义上的按位与
应用:可通过特定数据将对象数据的相应位设为0,其他位不变
例子:mov al,00111011B

OR

相应AND,不解释。
应用:将对象数据的相应位设为1,其他位不变。

字符形式的数据

格式:
db

data segment
db 'unIX'
db ‘LeBron’
data ends

存储方式为ASCII码
地址偏移同dw
一个规律:ASCII码中字母的二进制形式,第五位为0即大写,1即小写。

ASCII码

文本编辑过程中,:
1.(键盘等)文本信息输入
2.信息转为ASCII码存在指定内存
3.文本编辑器将内存中的ASCII码信息送到显卡 显存中
4.显卡用ASCII码规则解释传入信息
5.数据信息转为字符,并由显卡驱动显示器,显示在屏幕上
[id]: https://baike.baidu.com/item/ASCII/309296?fromtitle=ascii%E7%A0%81&fromid=99077&fr=aladdin


关于数据处理的两点

数据处理有两个核心问题:

  • 处理数据在什么地方
  • 处理数据有多长
    (这里给出描述性符号:reg指代其他寄存器,sreg指代段寄存器)

机器指令处理数据,不关心数据的值,只关心指令执行前,将要处理数据的位置。

数据位置

汇编指令指令执行前的数据位置
mov bx,[0]内存,ds:0 单元
mov bx,axCPU内部,ax寄存器
mov bx,1CPU内部,指令缓冲器

由表可知有三种位置表达:立即数,寄存器,EA+SA(段/偏移地址)

寻址方式

直接寻址 - 立即数

立即数
上面的1称为立即数(idata)
直接包含在机器指令中,在汇编指令中直接给出。

间接寻址 - 数据寄存器

[ax] , [bx]

相对寻址 - 基址寄存器 + 立即数

  • 用于结构体:[bx].idata
  • 用于数组:idata[si],idata[di]
  • 用于二维数组:[bxi][data]

基址变址寻址 - 基址寄存器 + 变址寄存器

二维数组 :[bx][si]

相对基址变址寻址 - 基 + 变 + idata

二维数组:idata[bx][si]
结构中的数组 [bx].idata[si]

数据长度

我们学习的8086cpu只有两种尺寸数据处理:byte和word。
通过以下方式处理数据长度
1.寄存器名
2.没有寄存器名,利用操作符 X ptr 指明长度

mov word ptr ds:[0],1
mov byte ptr ds:[0],1

3.指令默认
push[1000h]:push指令只进行字操作。


END

last but not least:
当我们谈论自由,我们谈论什么
当我们谈论爱情,我们谈论什么
[当我们谈论跑步,我们谈论什么](###直接寻址 - 立即数)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值