;运行效果
;win32汇编环境,结构体的使用示例二
;举例说明结构体的定义,如何访问其中的成员,使用assume指令指向某个结构体,计算结构数组所需的偏移量得到某个成员值等
;直接抄进RadAsm可编译运行。重要部分加备注。
;下面为asm文件
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.386
.model flat,stdcall
option casemap:none
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Include 文件定义
include windows.inc
include user32.inc
include kernel32.inc
includelib user32.lib
includelib kernel32.lib
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 自定义函数声明
DlgProc proto :DWORD,:DWORD,:DWORD,:DWORD ;对话框窗口函数
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 数据段
.data
DlgName db "MyDialog",0
szCaption db "提示",0
szFormat db "%d",0
szYES db "Yes",0
;比如,以下定义3个不同的结构,第2个结构里面嵌套的1个成员是第1个结构体,第3个结构为没有初始化的结构
Aligned_student struct
m_A DWORD ? ;不初始化,DWORD是4字节
m_B BYTE 20 DUP(?) ;大小为20字节的字符串数组,即将BYTE重复30次的意思,初始化为0
m_C DWORD 12
Aligned_student ends
Bligned_student struct
m_Age DWORD ? ;不初始化,DWORD是4字节
m_Name BYTE 30 DUP(?) ;大小为30字节的字符串数组,即将BYTE重复30次的意思,初始化为0
m_Score DWORD 0 ;整型变量,初始化为0,因为是DWORD型,即4个字节
m_Interests BYTE "No",0 ;初始化为 "No\0",N是1个字节,o是1个字节,0是1个字节,共3个字节。如果后面改变它的值,又不止3个字节,则为溢出。一样可以读取,但却成了bug
m_Add Aligned_student <> ;这个成员是个上面的结构体
Bligned_student ends
Cligned_student struct
m_A DWORD ?
m_B BYTE 20 DUP(?)
Cligned_student ends
hData01 Bligned_student <> ;定义1个Bligned_student结构,按其默认值初始化
hData02 Bligned_student 2 dup(<>) ;定义2个Bligned_student结构,按其默认值初始化
hData03 Bligned_student <20,"你好"> ;定义1个自已初始化的Bligned_student结构,第3、4个成员已经初始化,不可再初始化。第5个成员是结构体,也保持默认设置,可以在后面改变它。
hData04 equ this byte ;定义名为hData04的Cligned_student结构数组,并进行初始化。它总共有3个数组成员,每个数组成员都是Cligned_student结构。这种情况与要使用许多头文件里面的结构的操作方法很类似,比如图像列表结构,工具栏中按钮列表结构
Cligned_student <0,"123">
Cligned_student <1,"456">
Cligned_student <2,"789">
.data?
hInstance HINSTANCE ?
.const
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;Equ 等值定义
ICO_MAIN equ 1000 ;图标标识符
IDB equ 10 ;按钮控件标识符
IDB01 equ 11
IDB02 equ 12
IDB03 equ 13
IDB04 equ 14
; 代码段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.code
start:
invoke GetModuleHandle, NULL
mov hInstance,eax
invoke DialogBoxParam, hInstance, ADDR DlgName,NULL, addr DlgProc, NULL
invoke ExitProcess,eax
DlgProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
LOCAL @szBuffer[256]:byte
.if uMsg == WM_INITDIALOG
invoke LoadIcon,hInstance,ICO_MAIN
invoke SendMessage,hWnd,WM_SETICON,ICON_BIG,eax
.elseif uMsg == WM_COMMAND
mov eax,wParam
.if eax == IDB01
invoke wsprintf,addr @szBuffer,addr szFormat,sizeof Bligned_student ;Bligned_student结构,里面4个成员,分别是4字节、30字节、4字节、3字节,加起来就是41字节,里面还包含Aligned_student结构,而Aligned_student有28字节,则总共69字节
invoke MessageBox,NULL,addr @szBuffer,addr szCaption,MB_OK
.elseif ax == IDB02 ;读取hData02结构变量中嵌入结构内的第3个值,即默认的12。这里定义的是2个重复的Bligned_student结构,现在读取的是第1个Bligned_student结构的第3个值。
mov ebx,offset hData02
assume ebx:ptr Bligned_student
mov eax,[ebx].m_Add.m_C
invoke wsprintf,addr @szBuffer,addr szFormat,eax
invoke MessageBox,NULL,addr @szBuffer,addr szCaption,MB_OK
assume ebx:nothing
.elseif ax == IDB03 ;显示hData02结构变量的第2个成员
invoke MessageBox,NULL,addr hData03.m_Name,addr szCaption,MB_OK
.elseif ax == IDB04 ;开始读取hData04结构变量的第3个数组内的第2个值,即读取到“789”.这里要计算“789”所在的偏移量
mov ecx,sizeof Cligned_student ;得到Cligned_student结构的字节数
mov eax,2 ;乘以2,因为要读取的值在第3个数组内,所以要把指针向后推2个Cligned_student结构字节量
mul ecx
add eax,offset hData04 ;加上hData04的地址值,就是第3个数组的地址值。结果地址值在eax里面
assume eax:ptr Cligned_student ;用assume把eax绑定到Cligned_student结构定义。
invoke MessageBox,NULL,addr [eax].m_B,addr szCaption,MB_OK ;这里就可以引用到第3个数组的第2个成员的值了
assume eax:nothing ;走时用assume把eax解绑
.endif
.elseif uMsg == WM_CLOSE
invoke EndDialog, hWnd,NULL
.else
mov eax,FALSE
ret
.endif
mov eax,TRUE
ret
DlgProc endp
end start
;下面为rc文件内容
#include "resource.h" //提示缺少该文件,可以在资源里下载
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
#define ICO_MAIN 1000 //图标
#define IDB01 11
#define IDB02 12
#define IDB03 13
#define IDB04 14
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
ICO_MAIN ICON "Main.ico"
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
//定义对话框
MyDialog DIALOG 10, 10, 140, 100
STYLE DS_CENTER | WS_CAPTION | WS_MINIMIZEBOX | WS_SYSMENU | WS_VISIBLE | WS_OVERLAPPED | DS_MODALFRAME | DS_3DLOOK
CAPTION "对话框程序模版"
FONT 11, "宋体"
BEGIN
PUSHBUTTON "查看结构有多少字节", IDB01, 10,10,120,14
PUSHBUTTON "显示嵌套结构中的成员值", IDB02, 10,30,120,14
PUSHBUTTON "显示结构的第2个成员", IDB03, 10,50,120,14
PUSHBUTTON "显示结构数组成员内的值", IDB04, 10,70,120,14
END
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>