• Win32汇编--数据结构


    数据结构
    据结构实际上是由多个字段组成的数据样板,相当于一种自定义的数据类型,数据结构中间的每一个字段可以是字节、字、双字、字符串或所有可能的数据类型。(据说人是由泥巴捏成的)

    比如在API函数RegisterClass 中要使用到一个叫做WNDCLASS的数据结构,Microsoft的手册上是如下定义的: struct _WNDCLASS

    typeof struct _WNDCLASS {
                  UINT             style;
                  WNDPROC           lpfnWndProc;
                  Int             cbClsExtra;
                  Int             cbWndExtra;
                  HINSTANCE         hInstance;
                  HICON            hIcon;
                  HCURSOR           hCursor;
                  HBRUSH         hbrBackground;
                  LPCTSTR           lpszMenuName;
                  LPCTSTR           lpszClassName;
           }WNDCLASS, *PWNDCLASS;

    注意,这是C语言格式的,这个数据结构包含了10个字段,字段的名称是style,lpfnWndProc和cbClsExtra等,前面的UINT和WNDPROC等是这些字段的类型,在汇编中,数据结构的写法如下:
    结构名    struct
           字段1     类型              ?
           字段2     类型              ?
           ……
    结构名    ends
    WNDCLASS         struct
           Style      DWORD        ?
           LpfnWndProc   DWORD        ?
           cbClsExtra    DWORD        ?
           cbWndExtra    DWORD        ?
           hInstance    DWORD        ?
           hIcon      DWORD        ?
           hCursor     DWORD        ?
           hbrBackground  DWORD        ?
           lpszMenuName   DWORD        ?
           lpszClassName  DWORD        ?
           WNDCLASS    ends
    和大部分的常量一样,几乎所有API所涉及的数据结构在Windows.inc文件中都已经有定义了。
    要注意的是,定义了数据结构实际上只是定义了一个样板,上面的定义语句并不会在哪个段中产生数据。(只是以一个模板的形式存在,今后通过这个样板声明定义结构变量才占用空间)
    和Word中使用各种信纸与文书等模板类似,定义了数据结构以后就可以多次在源程序中用这个样板当做数据类型来定义数据,使用数据结构在数据段中定义数据的方法如下:

    .data?
           stWndClass    WNDCLASS         <>
                 ……

    .data
           stWndClass    WNDCLASS         <1,1,1,1,1,1,1,1,1,1,>
                 ……

    这个例子定义了一个以WNDCLASS为结构的变量 stWndClass。

    第一段的定义方法是未初始化的定义方法;

    第二段是在定义的同时指定结构中各字段的初始化值,各字段的初始值用逗号隔开,在这个例子中10个字段的初始值都指定为1。


    数据结构的引用
    在汇编中,数据结构的引用方法有好几种,以上面的定义为例,如果要使用stWndClass中的lpfnWndProc字段,最直接的办法是:
           mov  eax, stWndClass.lpfnWndProc

    它表示把lpfnWndProc字段的值放入eax中去,假设stWndClass在内存中的地址是403000h,这句指令会被编译成mov eax, [403004h],因为lpfnWndProc 是 stWndClass 中的第二个字段,第一个字段是dword,已经占用了4字节的空间。

    在实际使用中,常常有使用指令存取数据结构的情况,如果使用 esi 寄存器做指针寻址,可以使用下列语句完成同样的功能:
      mov esi, offset stWndClass
      move ax, [esi + WNDCLASS.lpfnWndProc]

    注意:第二句是[esi + WNDCLASS.lpfnWndProc] 而不是[esi + stWndClass.lpfnWndProc],因为前者被编译成mov eax, [esi + 4],而后者被编译成mov eax, [esi + 403004h],后者的结果显然是错误的!

    MASM还有一个用法,可以用assume伪指令把寄存器预先定义为结构指针,再进行操作:
           mov esi, offset stWndClass
           assume esi: ptr WNDCLASS
           move ax, [esi].lpfnWndProc
           ……
           assume esi:nothing

    注意:在不再使用esi寄存器做指针的时候要用assume esi:nothing取消定义。


    结构定义的嵌套
    结构的定义也可以嵌套,如果要定义一个新的NEW_WNDCLASS结构,里面包含一个老的WNDCLASS结构和一个新的dwOption字段,那么可以如下定义:

    NEW_WNDCLASS       struct
     
         DwOption           dword                 ?
         OldWndClass     WNDCLASS       <>
     
    NEW_WNDCLASS       ends

    假设现在esi是指向一个NEW_WNDCLASS的指针,那么引用里面嵌套的oldWndClass中的lpfnWndProc字段时,就可以用下面的语句:
      mov eax, [esi].oldWndClass.lpfnWndProc

    结构的嵌套在Windows的数据定义中也常有,熟练掌握数据结构的使用对Win32汇编编程是很重要的!

  • 相关阅读:
    C#读取资源文件的两种方法及保存资源文件到本地
    T4模板编辑器
    VS (Visual Studio) 快捷键
    以太网帧类型速查
    线程间操作无效: 从不是创建控件“XXX”的线程访问它
    C# 集合
    C#控件之ListView
    C# Color颜色对照表
    Java的内存需要划分成为5个部分:
    Java学习:数组的使用和注意事项
  • 原文地址:https://www.cnblogs.com/poli/p/4742599.html
Copyright © 2020-2023  润新知