You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在NASM的text段初始化结构体值并解决对应编译报错

问题解决说明

报错原因及修复方案

1. symbol 'test_struc.value' undefined报错

NASM的struc语法中,结构体成员本质是相对于结构体首地址的偏移常量,不属于实例的附属符号,不支持实例名.成员名的寻址格式。正确写法是用结构体实例地址+成员偏移名的组合,将原代码里的mov rax, [test_struc.value]修改为mov rax, [test_struc + value]即可解决。

注意:加中括号是取成员对应内存的内容,不加中括号是取成员的地址,请根据你的实际需求选择。

2. label '_exit' changed during code generation报错

这是NASM的前向引用导致的问题:你在_start里引用_exit标签时,标签还未被定义,NASM默认会将其识别为32位近地址,后续定义标签时判定地址长度不匹配就会抛出错误。两种修复方式选其一即可:

  • 把_exit标签的定义移到_start之前
  • 引用时明确指定跳转类型,写成jmp near _exit

原需求适配说明

你最初需要不在rodata段初始化结构体、可直接写入结构体值的要求,现在把结构体实例放在.data段已经完全满足:.data是可读写数据段,不属于只读的rodata段,运行时可以直接修改test_struc内的数值。
如果你非要把结构体定义在代码段(.text),需要注意默认.text是只读段,直接写入会触发段错误,链接时给ld加上--omagic参数即可将.text段改为可写权限,正常写入数据。


修复后的完整代码

BITS 64
global _start

; 结构体定义统一放在段声明前,仅定义结构布局不占实际存储空间
struc test
        value: resb 256
endstruc

segment .bss
segment .data
        name db "Bryton", 0
        test_struc:
                istruc test
                        at value, db "Hello world"
                iend

segment .text
; 提前定义_exit标签解决前向引用问题
_exit:
        mov rax, 0x3c
        mov rdi, 0
        syscall
_start:
        mov rax, [test_struc + value]
        mov rax, name
        jmp _exit

编译链接命令参考:
nasm -f elf64 struct.s -o struct.o
ld struct.o -o struct


内容的提问来源于stack exchange,提问作者Bryton

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 02:06:11