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

汇编中NULL字符未终止字符串:是否混淆C与汇编逻辑?

问题:汇编代码输出不符合预期的原因分析

你正在学习汇编语言并编写了一段测试代码:

1 global _start
  2 
  3 section .data
  4     msg db "HelloWo",0,10,117
  5     lenmsg equ $-msg
  6 
  7 section .text
  8 _start:
  9     mov eax , 4
 10     mov ebx , 1
 11     mov ecx , msg
 12     mov edx , lenmsg
 13     int 0x80
 14     mov eax ,1
 15     mov ebx ,0
 16     int 0x80 

原本预期输出为HelloWo,因为在"o"后有一个NULL(\0)字符,但实际所有字符都被输出到控制台,结果为:

HelloWo
u

编译运行命令:

nasm -f elf32 tes.asm -o tes.o
[[ -f tes.o ]] && ld -m elf_i386 tes.o -o tes
[[ -f tes ]] && ./tes

提问:我的理解误区在哪里?是否混淆了C语言与汇编语言的逻辑?


解答

你的核心误区就是混淆了C语言字符串的规则和Linux系统调用的底层逻辑:

  • C语言里的字符串依赖\0作为终止符,printf、puts这类库函数会自动识别\0并停止输出;但你用的是Linux的int 0x80系统调用(eax=4对应write系统调用),它完全不关心\0——它只会严格按照你在edx里指定的长度(也就是lenmsg,这里等于整个msg的字节数:"HelloWo"7个字符+0+换行符(10)+字符'u'(117),共10字节),从ecx指向的内存地址开始,输出对应长度的所有字节。
  • 你定义的lenmsg equ $-msg计算的是从msg标签到当前位置的字节差,也就是整个msg数据段的总长度,所以write会把这些字节全部输出到控制台。

如果要实现只输出HelloWo,有两种简单方式:

  • 方式一:调整msg的定义,只保留"HelloWo",让lenmsg自动计算为7字节;
  • 方式二:手动将edx的值设为7,替代lenmsg,强制write只输出前7个字符。

内容的提问来源于stack exchange,提问作者mНBr

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 11:27:34