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

Linux下x86_64汇编声明时字符串长度的参数传递异常问题

搞定这个x86_64汇编的奇怪数值问题

嘿,这个坑我踩过好多次了!你遇到的无意义大数值问题,根源是x86_64架构下64位寄存器和32位数据定义的不匹配,具体拆解给你看:

  • Linux x86_64的sys_write系统调用要求第三个参数(存在%rdx寄存器里)是64位的长度值,但你定义的len1用的是.long——这是32位整数类型,只占4字节内存。
  • 当你直接把len1加载到64位的%rdx时,汇编器会执行64位的内存读取操作,相当于把len1的4字节有效数据,加上它后面内存里随机的4字节垃圾数据,拼成了一个8字节的超大数,也就是你看到的那个无意义长串。
  • 至于sys_exit的%rdi寄存器看起来正常?那多半是巧合——要么len1后面的内存恰好是0,要么你用了32位加载(比如mov edi, len1),这种情况下x86_64会自动把32位值零扩展到64位,所以结果正常,但这不是靠谱的写法。

两种靠谱的修复方法

方法1:把长度变量改成64位类型

直接把.long换成.quad(x86_64下的64位整数类型),这样内存里存的就是完整的64位长度值,加载到%rdx时自然不会读入垃圾数据:

.section .data
string1: .string "test\n"
len1:    .quad .-string1  # 用.quad替代.long,定义64位长度
string2: .string "another string\n"
len2:    .quad .-string2

方法2:加载时做零扩展(保留32位定义的话)

如果非要保留.long的定义,那加载的时候要明确用32位寄存器做中转,x86_64会自动把32位值零扩展到64位寄存器的高位,避免读取多余的内存垃圾:

# 错误写法:直接读64位,带垃圾数据
# mov rdx, len1

# 正确写法:先加载到32位edx,自动零扩展到rdx
mov edx, len1

验证小技巧

你可以用objdump -d foo.o反汇编你的目标文件,看看加载len1的指令:

  • 如果是mov rdx,0xXXXXXX这种,就是64位读取,肯定会带垃圾数据;
  • 如果是mov edx,0xXXXXXX,就是32位读取,自动零扩展,结果就对了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 10:28:56