汇编语言联合 (union) 的声明和使用

< 上一页结构嵌套简述 宏过程简述下一页 >

结构中的每个字段都有相对于结构第一个字节的偏移量,而联合 (union) 中所有的字段则都起始于同一个偏移量。一个联合的存储大小即为其最大字段的长度。如果不是结构的组成部分,那么需要用 UNION 和 ENDS 伪指令来定义联合:

unionname UNION
    union-fields
unionname ENDS

如果联合嵌套在结构内,其语法会有一点不同:

structname STRUCT
    structure-fields
    UNION unionname
        union-fields
    ENDS
structname ENDS

除了其每个字段都只有一个初始值之外,联合字段声明的规则与结构的规则相同。例如,Integer 联合对同一个数据声明了 3 种不同的大小属性,并将所有的字段都初始化为 0:

Integei; UNION
    D DWORD 0
    W WORD 0
    B BYTE 0
Integer ENDS

一致性

如果使用初始值,那么它们必须为相同的数值。假设 Integer 声明了 3 个不同的初始值:

Integer UNION
    D DWORD 1
    W WORD 5
    B BYTE 8
Integer ENDS

同时还假设声明了一个 Integer 变量 mylnt 使用默认初始值:

.data
mylnt Integer <>

结果发现,myInt.D、myInt.W 和 myInt.B 都等于 1。字段 W 和 B 中声明的初始值会被汇编器忽略。

结构包含联合

在结构声明中使用联合的名称,就可以使联合嵌套在这个结构中。方法如同下面在 Fileinfo 结构中声明 FilelD 字段一样:

Fileinfo STRUCT
    FilelD Integer <>
    FileName BYTE 64 DUP(?)
Fileinfo ENDS

还可以直接在结构中定义联合,方法如同下面定义 FilelD 字段一样:

Fileinfo STRUCT
    UNION FilelD
        D DWORD ?
        W WORD ?
        B BYTE ?
    ENDS
    FileName BYTE 64 DUP(?)
Fileinfo ENDS

声明和使用联合变量

联合变量的声明和初始化方法与结构变量相同,只除了一个重要的差异:不允许初始值多于一个。下面是 Integer 类型变量的例子:

val1 Integer <12345678h>
val2 Integer <100h>
val3 Integer <>

在可执行指令中使用联合变量时,必须给出字段的一个名称。下面的例子把寄存器的值赋给了 Integer 联合字段。注意其可以使用不同操作数大小的灵活性:

mov val3.B, al
mov val3.W, ax
mov val3.D, eax

联合还可以包含结构。有些 MS-Windows 控制台输入函数会使用如下 INPUT_RECORD 结构,它包含了一个名为 Event 的联合,这个联合对几个预定义的结构类型进行选择。EventType 字段表示联合中出现的是哪种 record。每一种结构都有不同的布局和大小,但是一次只能使用一种:

INPUT_RECORD STRUCT
    EventType WORD ?
    ALIGN DWORD
    UNION Event
        KEY_EVENT_RECORD <>
        MOUSE_EVENT_RECORD <>
        WINDOW_BUFFER_SIZE_RECORD <>
        MENU_EVENT_RECORD <>
        FOCUS_EVENT_RECORD <>
    ENDS
INPUT_RECORD ENDS

Win32 API

在命名结构时,常常使用单词 RECORD。KEY_EVENT_RECORD 结构的定义如下所示:

KEY_EVENT_RECORD STRUCT
    bKeyDown DWORD ?
    wRepeatCount WORD ?
    wVirtualKeyCode WORD ? wVirtualScanCode WORD ?
    UNION uChar
        UnicodeChar WORD ?
        AsciiChar BYTE ?
    ENDS
    dwControlKeyState DWORD ?
KEY_EVENT_RECORD ENDS

< 上一页结构嵌套简述 宏过程简述下一页 >

编程帮,一个分享编程知识的公众号。跟着站长一起学习,每天都有进步。

通俗易懂,深入浅出,一篇文章只讲一个知识点。

文章不深奥,不需要钻研,在公交、在地铁、在厕所都可以阅读,随时随地涨姿势。

文章不涉及代码,不烧脑细胞,人人都可以学习。

当你决定关注「编程帮」,你已然超越了90%的程序员!

编程帮二维码
微信扫描二维码关注