如何在 MASM 程序集中初始化本地结构
How to initialize a local struct in MASM assembly
我想在堆栈上初始化一个本地结构。
Records STRUCT
data1 DWORD ?
data2 DWORD ?
data3 DWORD ?
data4 DWORD ?
Records ENDS
.CODE
main:
mov ebp, esp
sub esp, SIZEOF Records
如何创建 struct Records
的命名实例,然后我可以使用它来初始化数据成员?我想将 struct
指令与点运算符一起使用,而不是指针添加。
我开始为结构体分配space,那我该怎么办?
我会使用 PROC
指令的强大功能来定义函数 1 和 LOCAL
指令在函数中分配变量。汇编程序将处理序言和结尾代码,您可以将类型与本地相关联。
您可以编写如下所示的函数:
main PROC
LOCAL rec1: Records
mov rec1.data1, 1
mov rec1.data2, 2
mov rec1.data3, 3
mov rec1.data4, 4
ret
main ENDP
代码将在堆栈上为名为 rec1
的变量分配 space,其余行使用值 1、2、3、4 初始化结构字段。生成的汇编代码类似于:
Segment: _TEXT DWORD USE32 00000033 bytes
0000 _main:
0000 55 push ebp
0001 8B EC mov ebp,esp
0003 83 EC 10 sub esp,0x00000010
0006 C7 45 F0 01 00 00 00 mov dword ptr -0x10[ebp],0x00000001
000D C7 45 F4 02 00 00 00 mov dword ptr -0xc[ebp],0x00000002
0014 C7 45 F8 03 00 00 00 mov dword ptr -0x8[ebp],0x00000003
001B C7 45 FC 04 00 00 00 mov dword ptr -0x4[ebp],0x00000004
0022 C9 leave
0023 C3 ret
汇编程序创建了一个堆栈帧并为您计算了堆栈上相对于 EBP 的所有偏移量。如果您想将 rec1
的地址放入寄存器并将其作为结构使用,您可以使用 LEA
获取堆栈上变量的有效地址并使用 ASSUME
对其应用指针类型:
main PROC
LOCAL rec1: Records
lea eax, [rec1]
ASSUME eax: ptr Records
mov [eax].data1, 1
mov [eax].data2, 2
mov [eax].data3, 3
mov [eax].data4, 4
ret
main ENDP
生成的汇编代码为:
Segment: _TEXT DWORD USE32 00000035 bytes
0000 _main:
0000 55 push ebp
0001 8B EC mov ebp,esp
0003 83 EC 10 sub esp,0x00000010
0006 8D 45 F0 lea eax,-0x10[ebp]
0009 C7 00 01 00 00 00 mov dword ptr [eax],0x00000001
000F C7 40 04 02 00 00 00 mov dword ptr 0x4[eax],0x00000002
0016 C7 40 08 03 00 00 00 mov dword ptr 0x8[eax],0x00000003
001D C7 40 0C 04 00 00 00 mov dword ptr 0xc[eax],0x00000004
0024 C9 leave
0025 C3 ret
您也可以使用 LOCAL
指令来创建类型数组。然后您可以初始化数组中各个记录的元素。此示例在堆栈上为一个名为 rec1
的 4 Records
数组分配 space 并初始化第三个元素(数组索引 2,因为数组元素编号是从零开始的):
main PROC
LOCAL rec1[4]: Records
; Compute address of third Record structure in array
lea eax, [rec1]
ASSUME eax: ptr Records
add eax, 2*(SIZEOF Records)
; Initialize the the third Record structure
mov [eax].data1, 1
mov [eax].data2, 2
mov [eax].data3, 3
mov [eax].data4, 4
ret
main ENDP
生成的汇编代码为:
Segment: _TEXT DWORD USE32 00000038 bytes
0000 _main:
0000 55 push ebp
0001 8B EC mov ebp,esp
0003 83 EC 40 sub esp,0x00000040
0006 8D 45 C0 lea eax,-0x40[ebp]
0009 83 C0 20 add eax,0x00000020
000C C7 00 01 00 00 00 mov dword ptr [eax],0x00000001
0012 C7 40 04 02 00 00 00 mov dword ptr 0x4[eax],0x00000002
0019 C7 40 08 03 00 00 00 mov dword ptr 0x8[eax],0x00000003
0020 C7 40 0C 04 00 00 00 mov dword ptr 0xc[eax],0x00000004
0027 C9 leave
0028 C3 ret
我将 LEA
和 ADD
分成单独的指令,以更好地说明发生了什么。可以通过删除 ADD
并使用 LEA
将偏移量直接添加到 rec1
数组的基指针来简化。最好写成:
lea eax, [rec1 + 2*(SIZEOF Records)]
ASSUME eax: ptr Records
全局范围内的结构
如果您在全局范围内创建结构(而不是堆栈上的本地),您可以这样声明和初始化它们:
.DATA
rec2 Records <1,2,3,4>
结构中的每个字段都用逗号分隔。该结构将出现在 _DATA
段中,如下所示:
Segment: _DATA DWORD USE32 00000010 bytes
0000 01 00 00 00 02 00 00 00 03 00 00 00 04 00 00 00 ................
数据以字节为单位打印。每个单独的 DWORD 以 LSB(最低有效字节)到 MSB(最高有效字节)出现。如果显示为 DWORD,它们将显示为
0000 00000001 00000002 00000003 00000004
脚注
1我在汇编文件的顶部使用了一个 .MODEL
指令来假定 C默认样式调用约定:
.386
.model flat, C
我想在堆栈上初始化一个本地结构。
Records STRUCT
data1 DWORD ?
data2 DWORD ?
data3 DWORD ?
data4 DWORD ?
Records ENDS
.CODE
main:
mov ebp, esp
sub esp, SIZEOF Records
如何创建 struct Records
的命名实例,然后我可以使用它来初始化数据成员?我想将 struct
指令与点运算符一起使用,而不是指针添加。
我开始为结构体分配space,那我该怎么办?
我会使用 PROC
指令的强大功能来定义函数 1 和 LOCAL
指令在函数中分配变量。汇编程序将处理序言和结尾代码,您可以将类型与本地相关联。
您可以编写如下所示的函数:
main PROC
LOCAL rec1: Records
mov rec1.data1, 1
mov rec1.data2, 2
mov rec1.data3, 3
mov rec1.data4, 4
ret
main ENDP
代码将在堆栈上为名为 rec1
的变量分配 space,其余行使用值 1、2、3、4 初始化结构字段。生成的汇编代码类似于:
Segment: _TEXT DWORD USE32 00000033 bytes 0000 _main: 0000 55 push ebp 0001 8B EC mov ebp,esp 0003 83 EC 10 sub esp,0x00000010 0006 C7 45 F0 01 00 00 00 mov dword ptr -0x10[ebp],0x00000001 000D C7 45 F4 02 00 00 00 mov dword ptr -0xc[ebp],0x00000002 0014 C7 45 F8 03 00 00 00 mov dword ptr -0x8[ebp],0x00000003 001B C7 45 FC 04 00 00 00 mov dword ptr -0x4[ebp],0x00000004 0022 C9 leave 0023 C3 ret
汇编程序创建了一个堆栈帧并为您计算了堆栈上相对于 EBP 的所有偏移量。如果您想将 rec1
的地址放入寄存器并将其作为结构使用,您可以使用 LEA
获取堆栈上变量的有效地址并使用 ASSUME
对其应用指针类型:
main PROC
LOCAL rec1: Records
lea eax, [rec1]
ASSUME eax: ptr Records
mov [eax].data1, 1
mov [eax].data2, 2
mov [eax].data3, 3
mov [eax].data4, 4
ret
main ENDP
生成的汇编代码为:
Segment: _TEXT DWORD USE32 00000035 bytes 0000 _main: 0000 55 push ebp 0001 8B EC mov ebp,esp 0003 83 EC 10 sub esp,0x00000010 0006 8D 45 F0 lea eax,-0x10[ebp] 0009 C7 00 01 00 00 00 mov dword ptr [eax],0x00000001 000F C7 40 04 02 00 00 00 mov dword ptr 0x4[eax],0x00000002 0016 C7 40 08 03 00 00 00 mov dword ptr 0x8[eax],0x00000003 001D C7 40 0C 04 00 00 00 mov dword ptr 0xc[eax],0x00000004 0024 C9 leave 0025 C3 ret
您也可以使用 LOCAL
指令来创建类型数组。然后您可以初始化数组中各个记录的元素。此示例在堆栈上为一个名为 rec1
的 4 Records
数组分配 space 并初始化第三个元素(数组索引 2,因为数组元素编号是从零开始的):
main PROC
LOCAL rec1[4]: Records
; Compute address of third Record structure in array
lea eax, [rec1]
ASSUME eax: ptr Records
add eax, 2*(SIZEOF Records)
; Initialize the the third Record structure
mov [eax].data1, 1
mov [eax].data2, 2
mov [eax].data3, 3
mov [eax].data4, 4
ret
main ENDP
生成的汇编代码为:
Segment: _TEXT DWORD USE32 00000038 bytes 0000 _main: 0000 55 push ebp 0001 8B EC mov ebp,esp 0003 83 EC 40 sub esp,0x00000040 0006 8D 45 C0 lea eax,-0x40[ebp] 0009 83 C0 20 add eax,0x00000020 000C C7 00 01 00 00 00 mov dword ptr [eax],0x00000001 0012 C7 40 04 02 00 00 00 mov dword ptr 0x4[eax],0x00000002 0019 C7 40 08 03 00 00 00 mov dword ptr 0x8[eax],0x00000003 0020 C7 40 0C 04 00 00 00 mov dword ptr 0xc[eax],0x00000004 0027 C9 leave 0028 C3 ret
我将 LEA
和 ADD
分成单独的指令,以更好地说明发生了什么。可以通过删除 ADD
并使用 LEA
将偏移量直接添加到 rec1
数组的基指针来简化。最好写成:
lea eax, [rec1 + 2*(SIZEOF Records)]
ASSUME eax: ptr Records
全局范围内的结构
如果您在全局范围内创建结构(而不是堆栈上的本地),您可以这样声明和初始化它们:
.DATA
rec2 Records <1,2,3,4>
结构中的每个字段都用逗号分隔。该结构将出现在 _DATA
段中,如下所示:
Segment: _DATA DWORD USE32 00000010 bytes 0000 01 00 00 00 02 00 00 00 03 00 00 00 04 00 00 00 ................
数据以字节为单位打印。每个单独的 DWORD 以 LSB(最低有效字节)到 MSB(最高有效字节)出现。如果显示为 DWORD,它们将显示为
0000 00000001 00000002 00000003 00000004
脚注
1我在汇编文件的顶部使用了一个
.MODEL
指令来假定 C默认样式调用约定:.386 .model flat, C