;ex8.asm(e:\masm\base) 結構體應用示例。
.386
.model flat, stdcall
option casemap :none
include windows.inc
include kernel32.inc
includelib kernel32.lib
include user32.inc
includelib user32.lib
.data
;COORD STRUCT ;windows.inc 文件中有定義
; x WORD ?
; y WORD ?
;COORD ENDS
buffer db 80 dup(0)
CapMsg db '輸出',0
szFmt db 'stPos.x 的和 = %d, stPos.y 的和 = %d',0
stPos1 COORD <4,8> ;定義結構體變量並初始化
stPos2 COORD <> ;定義結構體變量(取結構體原初始值)
stPos3 COORD {2,4} ;定義結構體變量並初始化
stPos4 COORD {,40} ;定義結構體變量並初始化
stPos COORD 10 dup(<0,0>) ;定義結構體數組
.code
start:
mov stPos2.x, 10 ;域的使用
mov stPos2.y, 20
mov ecx,10
mov edi,offset stPos ;edi指向結構體變量
mov eax,1
mov ebx,11
@@:
mov (COORD ptr[edi]).x, ax
mov (COORD ptr[edi]).y, bx
add edi,type COORD ;結構體的大小
inc ax
inc bx
loop short @B
xor eax,eax
xor ebx,ebx
mov ecx,10
mov edi,offset stPos ;edi指向結構體變量
@@:
add ax,(COORD ptr[edi]).x
add bx,(COORD ptr[edi]).y
add edi,type COORD ;結構體的大小
loop short @B
invoke wsprintf, ;格式化信息串
addr buffer, ;信息串格式化後的存放地
addr szFmt, ;信息串的格式
eax,
ebx
invoke MessageBox, ;顯示信息框
NULL, ;父窗口句柄
offset buffer, ;正文串
offset CapMsg, ;擡頭串
MB_OK ;按鈕"確定"
INVOKE ExitProcess,0 ;結束進程
end start
參考資料:
1、結構類型的定義
用STRUC和ENDS可以把壹系列數據定義語句括起來作為壹種新的、用戶定義的結構類型。其壹般說明格式如下:
結構名 STRUC [Alignment][, NONUNIQUE]
數據定義語句序列
結構名 ENDS
解釋:結構名是壹個合法的標識符,且具有唯壹性。結構名代表整個結構類型,前後兩個結構名必須壹致。結構內被定義的變量為結構字段,變量名即為字段名。
壹個結構中允許含有任意多個字段,各字段的類型和所占字節數也都可任意。如果字段有字段名,則字段名必須唯壹。每個字段可獨立存取。
對齊方式(Alignment):可用1、2或4來指定結構中字段的字節邊界(Byte boundary),其缺省值為1。見4.3.2節中的有關敘述;
NONUNIQUE:要求結構中的字段必須用全名才能訪問,見本小節中的“結構類型字段的引用”。
例如:
COURSE
STRUC 在左上例中,COURSE是結構名,它含有三個字段:NO、CNAME和SCORE,它們的類型分別是DD、DB和DW。
NO DD ?
CNAME DB 'Assember'
SCORE DW 0
COURSE
ENDS
上例中,COURSE是結構名,它含有三個字段:NO、CNAME和SCORE,這些字段的類型分別是DD、DB和DW。
結構類型COURSE***占14個字節,其字段NO、CNAME和SCORE的偏移量分別為:0、4和12。
結構中的字段可以有字段名,也可以沒有字段名。有字段名的字段可直接用該字段名來訪問它,沒有字段名的字段可以用該字段在結構中的偏移量來訪問。
例如:
PEASON
STRUC
NO DD ? ;偏移量為0
NAME DB 10 dup (?) ;偏移量為4
DB 1 ;偏移量為14
PEASOM
ENDS
在結構PEASON中,有二個字段有字段名,壹個字段沒有字段名,但不管有無字段名,我們都可用其偏移量來訪問它。
2、結構類型變量的定義
在定義某個結構類型後,程序員就可以說明該結構類型的內存變量。它的說明形式與前面介紹的簡單數據類型的變量說明基本上壹致。其定義格式如下:
[變量名] 結構名 <[字段值表]>
解釋:1)、
變量名即為該結構類型的變量名,它可省缺。如果省缺,則不能用符號名來訪問該內存單元;
2)、 字段值表是給字段賦初值,中間用逗號','分開,其字段值的排列順序及類型應與該結構說明時各字段相壹致;
3)、 如果結構變量中某字段用其說明時的缺省值,那麽,可用逗號來表示;如果所有字段都如此,則可省去字段值表,但必須保留壹對尖括號"<"、">"。
例如:
COURSE1
COURSE <> ;使用缺省的初值
COURSE2 COURSE <1, 'Pascal', 60>
COURSE3 COURSE <2, , 84> ;使用缺省的課程名
PEASON1 PEASON <1000, '張 三', 34>
3、結構類型字段的引用
定義了結構類型的變量後,若要訪問其結構中的某個字段,則可采用如下形式:
結構變量名.字段名
該引用方式與高級語言的字段引用方式完全壹致,我們還可用偏移量來訪問其中的某個字段,但此方法不直觀,變動性大,所以,壹般情況下,不提倡使用此方法。
例如:
EXAM1 STRUC
F1 DW ?
F2 DB ?
EVEN ;偶對齊
F3 DW ?
EXAM1 ENDS
E1 EXAM1 <1234H,'A',8765H> ;定義結構EXAM1的壹個變量E1
下面二種方法都可以把結構變量E1中字段的內容賦給寄存器AX,但如果在字段F3之前增加或減少了字段,那麽,這些引用需要改變嗎?
(1)、用字段名直接引用
MOV AX, E1.F3
(2)、用字段的偏移量間接引用
LEA SI, E1
MOV AX, [SI+4] ;其中4是字段F3的偏移量