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

x86汇编中len1 equ $-msg1为何包含msg2?单次系统调用打印两条消息原因

问题原因

核心问题出在对汇编位置计数器$和equ伪指令的理解有误,另外代码的段声明也存在语法错误。

  • 先明确两个基础汇编规则:
    • $代表汇编过程中当前位置计数器的值,对应正在汇编内容的内存偏移,每分配1字节的指令或数据,位置计数器就加1。
    • equ是纯汇编期的常量定义,本身不会生成任何指令或数据,也不会推动位置计数器移动,它的值完全由书写这行代码时的位置计数器即时计算得到。
  • 你的代码把len1: equ $-msg1写在了msg2的定义之后:
    数据段内的分配顺序是先为msg1分配12字节("Hello world"加换行符共12个字符),再为msg2分配13字节("Hello world!"加换行符共13个字符),等汇编到len1的equ定义时,位置计数器已经走到了msg2的末尾,此时$-msg1的计算结果是msg1长度 + msg2长度 = 25,根本不是msg1单独的长度。
  • 调用write系统调用时传入的输出长度是25,系统会从msg1起始地址开始连续读取25个字节输出,自然把紧随其后的msg2内容也一起打印了。

额外提一下代码里的段声明语法错误:section.text:和section.data:的写法非法,section伪指令和段名之间必须加空格,段名以.开头,且段声明后不需要加冒号,正确写法是section .text和section .data。这个问题不会直接导致本次输出异常,但会让汇编器无法正确识别段切换,所有代码和数据都会被汇编到默认段中,造成程序段布局不符合预期。

修复方法

把每个字符串对应的长度equ定义,紧跟在对应字符串的定义之后,保证计算长度时位置计数器刚好走到当前字符串的末尾即可,修正后的data段写法如下:

section .data
msg1: db "Hello world", 10
len1: equ $-msg1   ; 此时位置计数器刚好在msg1末尾,计算得到长度12
msg2: db "Hello world!", 10
len2: equ $-msg2   ; 此时位置计数器刚好在msg2末尾,计算得到长度13

修正后len1的值为12,write调用只会输出msg1的内容,不会连带打印msg2。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 13:03:21