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

x64汇编器内存地址是4字节还是8字节?及列表文件地址解析

x64汇编器的内存地址长度与列表文件偏移解析

1. x64汇编器使用的内存地址长度

x64(AMD64/Intel 64)是64位架构,内存地址为8字节(64比特)。汇编器(比如你用的NASM)在处理x64代码时,会生成适配64位地址空间的目标文件(ELF64格式),但要明确两点:

  • 汇编阶段(生成.o文件),汇编器处理的是段内偏移或符号引用,还不是最终的虚拟内存地址,完整的64位虚拟地址要等到链接阶段(由gcc/ld链接器)确定;
  • 像mov rsi, msg这类指令,汇编器会先把msg标记为.data段的符号,链接时再替换成该符号对应的64位虚拟地址。

2. NASM生成的hello.lst文件第二列地址含义

你通过nasm -f elf64 -g -F dwarf hello.asm -l hello.lst生成的列表文件,第二列的8位十六进制数是当前内容在所属段(section)内的偏移地址:

  • 对于.data段的msg,它的偏移是00000000,因为是.data段的第一个数据项;
  • 对于.text段的代码,main标签的偏移是00000000,之后每条指令的偏移是累加指令字节长度得到的:比如mov rax, 1是5字节指令,下一条mov rdi,1的偏移就是00000005,以此类推;
  • 用8位十六进制显示是因为x64的段偏移最大可到64位(范围0x0000000000000000到0xFFFFFFFFFFFFFFFF),NASM统一用8位十六进制格式输出,即使当前段内容偏移远小于这个范围,也会补零对齐,保持列表格式整齐。

对应你的代码,hello.lst的核心部分大概是这样:

1                                  ; hello.asm
     2 00000000                          section .data                                   
     3 00000000 68656C6C6F2C20776F726C64 msg db      "hello, world",0                       
     4 0000000D 00
     5                                  section .bss                                                   
     6                                  section .text                                                   
     7 00000000                          global main                                 
     8 00000000                          main:
     9                                  
    10 00000000 B801000000                mov     rax, 1          ; 1 = write      
    11 00000005 BF01000000                mov     rdi, 1              ; 1 = to stdout          
    12 0000000A 48BE[0000000000000000]    mov     rsi, msg    ; string to display in rsi
    13 00000014 BA0C000000                mov     rdx, 12             ; length of the string, without 0
    14 00000019 0F05                      syscall                             ; display the string
    15 0000001B B83C000000                mov     rax, 60             ; 60 = exit      
    16 00000020 BF00000000                mov     rdi, 0              ; 0 = success exit code
    17 00000025 0F05                      syscall                             ; quit

这里第二列的数值逻辑很清晰:

  • 第3行的00000000是msg在.data段的起始偏移;
  • 第10行的00000000是main在.text段的起始偏移;
  • 第11行的00000005是上一条5字节指令累加后的偏移结果。

当你用gcc链接生成可执行文件时,链接器会给每个段分配虚拟基址,比如.text段可能被加载到0x401000,那么main的实际虚拟地址就是0x401000 + 0x00000000 = 0x401000,mov rax,1这条指令的地址就是0x401000,以此类推。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 20:15:11