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

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字节缓冲区,用来存储用户输入,足够容纳绝大多数短字符串输入。

代码核心逻辑

  1. 输入输出:使用Linux x86-64原生系统调用sys_write和sys_read完成IO操作,无需依赖C标准库。
  2. 输入处理:必须把用户输入末尾的换行符替换为空字符——否则字符串比较会因为多了一个0xA字节而判定不相等。
  3. 字符串比较:自定义strcmp函数逐字节比对两个字符串,直到遇到不相等字节或空字符,返回值符合C标准库strcmp的规则(0表示相等)。
  4. 分支判断:用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 17:30:46