NASM x86-64 Linux ARM下字符串输入的if/else实现求助
Linux x86-64 NASM 字符串判断的if/else实现方案
字符串比较和整数判断逻辑完全不同,不能直接套用整数的cmp指令逻辑——整数是单值直接比对,字符串需要逐字节校验直到遇到空字符或不相等字节。下面是符合你需求的完整实现,附带详细解释:
完整代码
section .data prompt db "Enter your name: ", 0x0 prompt_len equ $ - prompt access_denied db "Access denied!", 0xA, 0x0 denied_len equ $ - access_denied access_granted db "Access granted!", 0xA, 0x0 granted_len equ $ - access_granted target_name db "max", 0x0 ; 目标字符串,必须以空字符结尾 section .bss input_buf resb 64 ; 预留64字节存储用户输入 section .text global _start _start: ; 1. 打印输入提示 mov rax, 1 ; sys_write系统调用号 mov rdi, 1 ; 文件描述符:stdout mov rsi, prompt ; 提示字符串地址 mov rdx, prompt_len ; 字符串长度 syscall ; 2. 读取用户输入 mov rax, 0 ; sys_read系统调用号 mov rdi, 0 ; 文件描述符:stdin mov rsi, input_buf ; 输入缓冲区地址 mov rdx, 63 ; 最多读取63字节(留1字节存空字符) syscall ; 3. 替换输入末尾的换行符为空白字符(sys_read会读取回车换行) mov rbx, input_buf mov rcx, rax ; rax存储实际读取的字节数 dec rcx ; 指向最后一个读取的字符(换行符) mov byte [rbx + rcx], 0x0 ; 4. 调用自定义strcmp比较输入与目标字符串 mov rdi, input_buf ; 第一个参数:输入字符串 mov rsi, target_name; 第二个参数:目标字符串 call strcmp ; 5. 根据strcmp返回值分支判断 cmp rax, 0 ; 返回0表示字符串相等 je .denied ; 相等则跳转到拒绝分支 jmp .granted ; 否则跳转到允许分支 .denied: ; 输出拒绝信息 mov rax, 1 mov rdi, 1 mov rsi, access_denied mov rdx, denied_len syscall jmp .exit .granted: ; 输出允许信息 mov rax, 1 mov rdi, 1 mov rsi, access_granted mov rdx, granted_len syscall jmp .exit .exit: ; 退出程序 mov rax, 60 ; sys_exit系统调用号 mov rdi, 0 ; 退出码0 syscall ; 自定义strcmp函数:比对两个以空字符结尾的字符串 ; 参数:rdi = 字符串1地址,rsi = 字符串2地址 ; 返回值:rax = 0(相等)/ <0(字符串1更小)/ >0(字符串1更大) strcmp: push rbx push rcx xor rbx, rbx ; rbx作为索引,初始化为0 .loop: mov cl, byte [rdi + rbx] ; 取字符串1当前字节 mov dl, byte [rsi + rbx] ; 取字符串2当前字节 cmp cl, dl ; 比对两个字节 jne .done ; 不相等则退出循环 cmp cl, 0x0 ; 判断是否到字符串结尾 je .done ; 到结尾则退出循环 inc rbx ; 索引+1,继续下一字节 jmp .loop .done: mov al, cl sub al, dl ; 计算字节差值作为返回基础 movsx rax, al ; 扩展为64位返回值 pop rcx pop rbx ret
代码模块解释
数据段(.data)
- 所有固定字符串都存在这里,用
equ $ - 标签自动计算长度,避免手动数字节出错。 target_name必须以0x0(空字符)结尾,这是C风格字符串的标准格式,也是字符串比较函数判断结束的标志。
未初始化数据段(.bss)
input_buf预留64字节缓冲区,用来存储用户输入,足够容纳绝大多数短字符串输入。
代码核心逻辑
- 输入输出:使用Linux x86-64原生系统调用
sys_write和sys_read完成IO操作,无需依赖C标准库。 - 输入处理:必须把用户输入末尾的换行符替换为空字符——否则字符串比较会因为多了一个
0xA字节而判定不相等。 - 字符串比较:自定义
strcmp函数逐字节比对两个字符串,直到遇到不相等字节或空字符,返回值符合C标准库strcmp的规则(0表示相等)。 - 分支判断:用
cmp rax, 0检查strcmp的返回值,je(相等则跳转)指令实现if逻辑,jmp实现else分支。
编译与运行
用NASM编译、ld链接:
nasm -f elf64 your_program.asm -o your_program.o ld your_program.o -o your_program ./your_program
你之前方案无效的原因
整数判断直接用cmp比对寄存器或内存中的数值即可,但字符串是多字节序列,必须逐字节校验。你套用整数判断的逻辑,相当于只比对了字符串的地址或者第一个字节,自然无法正确判断整个字符串是否相等。
内容的提问来源于stack exchange,提问作者Troyer05
相关产品推荐
相关产品推荐

