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
posted @ 2024-05-15 00:42  美洲象  阅读(12)  评论(0编辑  收藏  举报