MASM中Group的作用
Masm5以后推出的simplified segment模式及.model标准模型中,都将段组合成一个group,group的作用及优点是什么呢?
一、Group的作用
将组(group)后的所有段加入一个组,位于这些段内的的label(标号)或variables(变量)的偏移地址都参照Group的起始地址进行计算,而不是所在段的起始地址进行计算:
1、多数据段代码举例如下
assume cs:codesg,ss:stacksg,ds:datasg1,es:datasg2 ;------------------------------------------- stacksg segment stack db 100 dup (0) stacksg ends ;------------------------------------------- datasg1 segment var1 db 6 datasg1 ends ;------------------------------------------- datasg2 segment var2 db 9 datasg2 ends ;------------------------------------------- codesg segment start: ;------------------------------------------- mov al,var1 mov al,var2 ;------------------------------------------- mov ax,4c00h int 21h codesg ends end start
如果不定义组,则var1和var2的偏移地址都是0000,编译后代码如下:
如将datasg1和datasg2编入组:
mygroup group datasg1,datasg2 assume cs:codesg,ss:stacksg,ds:mygroup
则编译后代码如下:
可见,编入组后var1和var2都参照mygroup的起始地址计算偏移地址。
2、多代码段代码举例如下
assume cs:codesg,ss:stacksg,ds:datasg ;------------------------------------------- stacksg segment stack db 100 dup (0) stacksg ends ;------------------------------------------- datasg segment var1 db 6 datasg ends ;------------------------------------------- codesg segment start: ;------------------------------------------- mov al,var1 jmp far ptr funone ;------------------------------------------- mov ax,4c00h int 21h codesg ends ;------------------------------------------- assume cs:excode excode segment funone: mov ax,2222h excode ends ;------------------------------------------- end start
其中jmp funone由于已经跨段,所以应该是jmp far ptr funone,如果改成jmp funone,编译就会出现错误
将2个代码段加到一个组中,则可以直接jmp funone,代码如下:
cgroup group codesg,excode assume cs:cgroup,ss:stacksg,ds:datasg ;------------------------------------------- stacksg segment stack db 100 dup (0) stacksg ends ;------------------------------------------- datasg segment var1 db 6 datasg ends ;------------------------------------------- codesg segment start: ;------------------------------------------- mov al,var1 jmp funone ;------------------------------------------- mov ax,4c00h int 21h codesg ends ;------------------------------------------- excode segment funone: mov ax,2222h excode ends end start
逻辑上codesg和excode组合成一个段,段地址是cgroup的首地址(也就是组中第一个代码段的地址)。
注意:
1、assume ds:mygroup、assume cs:cgroup语句不能少(即将段地址和组地址进行关联),否则组定义无意义。
2、加入组的第一个段和最后一个段之间的距离不能超过65535Byte(想想为什么)。
3、Group并不改变段在内存的位置,只是改变组内代码和数据的访问方式:因为定义在不同段的代码需要通过far ptr来跨段访问 ,数据则需要改变段寄存器来访问,即使根据实际位置并不需要这么做。group将所有属于组内的代码和数据在逻辑上按属于同一段的方式来访问,这个段的段地址就是group的首地址。
二、Group的优点
这样做的好处是cpu在代码跳转或数据访问时,段寄存器不用变更(都参照group的起始地址),减少跨段访问操作,加快程序的执行速度。
三、Group知识扩展
Mams5后对段的定义即划分进行了简化,并给出了标准化建议。如按照标准化定义段,还可以与c、basic、pascal等高级语言进行相互调用。
.model tiny/small/medium/compat/large/huge(6种内存模型)
tiny,代码和数据在一个段中,整个程序只有一个段。
small,代码只有一个段,数据只有一个段。
medium,数据只有一个段,代码可存在多个段。
compat,代码只有一个段,数据可存在多个段。
large,代码和数据都可以有多个段。
huge,代码和数据都可以有多个段,且data array可以超过64K。
.model指令还自动定义group和assume指令,将相应的段加入group,并将段寄存器与group关联,如.model small,就会自动生成
dgroup group _data,const,_bss,stack assume ds:dgroup。
但注意,这里需要手动为ds赋值:
mov ax,dgroup mov ds,ax
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· .NET10 - 预览版1新功能体验(一)