如何在NASM x86汇编中实现逐字符遍历拆分字符串功能
NASM x86 实现字符串逐字符遍历拆分
你贴的参考JS代码存在两处笔误,会导致逻辑失效:text.lenght拼写错误(正确为length),for循环括号后多余的分号会让循环体空跑,最终仅执行一次块内代码。以下实现对应你需要的逐字符遍历、逐个输出字符的正确逻辑,基于32位Linux平台NASM语法,可直接编译运行。
核心逻辑对应关系
汇编实现和JS逻辑的映射如下:
let text = "abcde":数据段定义字符串,汇编中常用末尾加0(null字符)的方式标记字符串结尾,无需提前硬编码长度let i = 0:用跨系统调用保留的通用寄存器esi存储遍历索引,初始值设为0text.charAt(i):通过「字符串基址+索引偏移」的寻址方式,直接读取对应内存位置的1字节数据,即为当前位置的字符console.log():通过Linux软中断int 0x80调用sys_write系统调用实现字符输出,额外输出换行符匹配JS中console.log逐行打印的效果- 循环终止判断:读取到null结束符时跳出循环,和JS中
i < text.length的终止判断效果一致
完整实现代码
section .data ; 待遍历字符串,末尾0为结束标记 text db "abcde", 0 newline db 0xA ; 换行符ASCII码 section .text global _start _start: ; 初始化遍历索引i = 0 mov esi, 0 traverse_loop: ; 读取当前索引位置的字符 text[i] mov al, [text + esi] ; 判断是否到达字符串结尾(读到null字符),满足则退出循环 test al, al jz exit_prog ; 调用sys_write输出当前单个字符 mov eax, 4 ; 系统调用号:sys_write mov ebx, 1 ; 输出目标:标准输出(文件描述符1) lea ecx, [text + esi] ; 输出内容内存地址 mov edx, 1 ; 输出长度:1字节 int 0x80 ; 输出换行符,实现逐行打印效果 mov eax, 4 mov ebx, 1 mov ecx, newline mov edx, 1 int 0x80 ; 索引自增 i++ inc esi ; 回到循环起始位置 jmp traverse_loop exit_prog: ; 调用sys_exit正常退出程序 mov eax, 1 mov ebx, 0 int 0x80
编译运行方法
依次执行以下命令即可生成可执行文件:
- 汇编生成目标文件:
nasm -f elf32 char_traverse.asm -o char_traverse.o - 链接生成可执行文件:
ld -m elf_i386 char_traverse.o -o char_traverse - 运行程序:
./char_traverse
运行后预期输出:
a b c d e
可选调整说明
- 如果不需要逐行输出、要连续打印所有字符,直接删除代码中输出
newline的那段系统调用逻辑即可,运行后会直接输出abcde - 如果要完全对齐JS中提前取字符串长度的写法,可以在数据段定义字符串时直接计算长度:
循环判断逻辑改成text db "abcde" text_len equ $ - text ; 编译期自动计算字符串字节数cmp esi, text_len、je exit_prog即可,不需要依赖null结束符判断终止。
内容的提问来源于stack exchange,提问作者Сашенька Глинин
相关产品推荐
相关产品推荐

