对比NASM x86写法,如何用ARM+as汇编器定义结构体?
ARM汇编(GNU as)中结构体的定义与使用
在x86平台搭配NASM编译器时,你可以这样定义和使用结构体:
结构体定义(.bss段)
section .bss STRUCT my_structure elem_1: RESW 1 elem_2: RESW 1 elem_3: RESD 1 ENDSTRUC
结构体实例化(.data段)
section .data s: ISTRUC my_structure AT elem_1, DW 0x01 AT elem_2, DW 0x02 AT elem_3, DD 0x0 IEND
在ARM平台搭配GNU as汇编器时,由于没有NASM那样原生的STRUCT/ENDSTRUC指令,我们可以通过常量偏移定义或宏封装来实现相同的结构体功能,具体如下:
1. 结构体定义
方式一:手动定义成员偏移(简单直接)
直接用.equ定义结构体的总大小和每个成员的偏移量,适合简单结构体:
@ 定义my_structure的成员偏移与总大小 .equ my_structure_size, 8 @ 2字节(elem_1) + 2字节(elem_2) + 4字节(elem_3) = 8字节 .equ elem_1_offset, 0 @ 第一个成员,偏移0 .equ elem_2_offset, 2 @ 跳过elem_1的2字节,偏移为2 .equ elem_3_offset, 4 @ 跳过elem_1+elem_2的4字节,偏移为4(自动对齐到4字节边界)
方式二:用宏自动计算偏移(灵活不易错)
通过自定义宏来模拟NASM的STRUCT/ENDSTRUC逻辑,自动计算成员偏移,避免手动计算出错:
@ 自定义结构体相关宏 .macro STRUCT_START name \name\_current_size = 0 .endm .macro STRUCT_MEMBER name, size \name\_offset = \struct\_current_size \struct\_current_size = \struct\_current_size + \size @ 可选:添加ARM常用的4字节对齐处理 .if (\struct\_current_size % 4) != 0 \struct\_current_size = \struct\_current_size + (4 - (\struct\_current_size % 4)) .endif .endm .macro STRUCT_END name \name\_size = \struct\_current_size .endm @ 使用宏定义my_structure STRUCT_START my_structure STRUCT_MEMBER elem_1, 2 @ 对应NASM的RESW 1(2字节) STRUCT_MEMBER elem_2, 2 @ 对应NASM的RESW 1(2字节) STRUCT_MEMBER elem_3, 4 @ 对应NASM的RESD 1(4字节) STRUCT_END my_structure
2. 结构体的使用
在.data段初始化结构体实例
和NASM的ISTRUC/IEND对应,我们可以直接按成员顺序初始化,或者用偏移定位明确指定成员:
方式一:按顺序直接初始化
.data s: .word 0x01 @ elem_1,对应偏移0 .word 0x02 @ elem_2,对应偏移2 .long 0x00000000 @ elem_3,对应偏移4
方式二:通过偏移定位初始化(类似NASM的AT指令)
如果需要跳过某些成员或明确指定初始化的成员,可以用.org指令定位到对应偏移:
.data s: .word 0x01 @ 初始化elem_1 .org s + elem_2_offset @ 定位到elem_2的偏移位置 .word 0x02 @ 初始化elem_2 .org s + elem_3_offset @ 定位到elem_3的偏移位置 .long 0x00000000 @ 初始化elem_3
在.bss段预留结构体空间
对应NASM中用RESW/RESD预留空间的操作,GNU as用.skip或.space指令预留整个结构体的大小:
.bss my_struct_instance: .skip my_structure_size @ 预留my_structure大小的未初始化空间
内容的提问来源于stack exchange,提问作者ginko
相关产品推荐
相关产品推荐

