ARM汇编:如何声明文件内全局及程序全局可见变量
汇编中全局变量的可见性对应写法
嘿,这个问题刚好戳中了C和汇编在全局变量可见性上的对应点,我来给你掰扯清楚——不管是用GNU汇编(GAS,gcc默认那套)还是NASM,核心都是区分局部符号(仅当前文件可见,对应C的static全局)和全局符号(整个程序可见,对应C的非static全局),下面逐个对应你的四个变量:
一、GNU汇编(GAS)写法
GAS用.local标记局部符号(文件内可见),用.global标记全局符号(全程序可见);初始化变量放.data段,未初始化的高效写法是放.bss段(系统自动清0,不占可执行文件空间)。
- 对应
static int foo[3];(文件内可见)
# 初始化版本 .data .local foo # 标记为局部符号,仅当前文件可访问 foo: .long 0, 0, 0 # int是4字节,3个元素初始化为0 # 未初始化版本(更高效) .bss .local foo foo: .space 12 # 3*4=12字节空间
- 对应
static char bar[4];(文件内可见)
# 初始化版本 .data .local bar bar: .byte 0, 0, 0, 0 # char是1字节,4个元素 # 未初始化版本 .bss .local bar bar: .space 4
- 对应
char barfoo;(全程序可见)
# 初始化版本 .data .global barfoo # 标记为全局符号,全程序可访问 barfoo: .byte 0 # 未初始化版本 .bss .global barfoo barfoo: .space 1
- 对应
int foobar;(全程序可见)
# 初始化版本 .data .global foobar foobar: .long 0 # 未初始化版本 .bss .global foobar foobar: .space 4
二、NASM写法
NASM的规则更简单:默认所有未用global声明的符号都是局部的(对应C的static),用global声明的符号是全局的(全程序可见);同样用section .data放初始化变量,section .bss放未初始化变量。
- 对应
static int foo[3];(文件内可见)
; 初始化版本 section .data foo: dd 0, 0, 0 ; dd = 双字(4字节),对应C的int,3个元素 ; 未初始化版本 section .bss foo: resd 3 ; resd 3 = 保留3个双字的空间(12字节)
- 对应
static char bar[4];(文件内可见)
; 初始化版本 section .data bar: db 0, 0, 0, 0 ; db = 字节,对应C的char ; 未初始化版本 section .bss bar: resb 4 ; resb 4 = 保留4字节空间
- 对应
char barfoo;(全程序可见)
; 初始化版本 section .data global barfoo barfoo: db 0 ; 未初始化版本 section .bss global barfoo barfoo: resb 1
- 对应
int foobar;(全程序可见)
; 初始化版本 section .data global foobar foobar: dd 0 ; 未初始化版本 section .bss global foobar foobar: resd 1
核心规则总结
- 文件内可见(C static全局):让符号成为局部符号,禁止其他目标文件访问。GAS用
.local标记,NASM默认不声明global的符号就是局部的。 - 全程序可见(C非static全局):必须用全局声明指令把符号暴露给链接器,GAS和NASM都用
global(GAS是.global)。
内容的提问来源于stack exchange,提问作者scugn1zz0
相关产品推荐
相关产品推荐

