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