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

如何在Ubuntu环境的x64 Intel汇编中实现字符判断的if-else语句

问题分析与修正方案

核心错误点

  • 你当前的比较逻辑是在对比内存地址而非字符的实际值:cmp rsp, r9是把存储输入字符的栈地址,和.catletter的内存地址做对比,这两个地址不可能相等,自然不会触发跳转。
  • 尝试cmp rsp, "c"或cmp rsp, 67时,错误地把栈指针(地址)当成了存储的字符值;且67是大写字母C的ASCII码,你需要的小写c对应ASCII码是99。

正确实现方式

要对比的是输入的字符值,而非它的存储地址。可以直接读取栈中存储的字节,和目标字符常量做对比,以下是修正后的完整代码:

.global _start
.intel_syntax noprefix

_start:
        // Print Question
        mov rax, 1
        mov rdi, 1
        lea rsi, [.the_ask]
        mov rdx, 28
        syscall
        // Load Input into memory
        mov rax, 0
        sub rsp, 8          // 分配8字节栈空间存输入
        mov rdi, 0
        lea rsi, [rsp]
        mov rdx, 1
        syscall
        // Print Newline
        mov rax, 1
        mov rdi, 1
        lea rsi, [.newline]
        mov rdx, 2
        syscall
        // 正确的字符比较逻辑
        cmp byte [rsp], 'c' // 直接对比栈中存储的字节与字符'c'
        je _docatstuff
        cmp byte [rsp], 'd' // 对比栈中字节与字符'd'
        je _dodogstuff

        // Exit (输入不匹配时执行)
        mov rax, 60
        mov rdi, 1
        syscall

_docatstuff:
        // meow at user
        mov rax, 1
        mov rdi, 1
        lea rsi, [.catstuff]
        mov rdx, 4
        syscall
        // newline
        mov rax, 1          // 显式设置syscall编号,避免依赖之前的寄存器值
        mov rdi, 1
        lea rsi, [.newline]
        mov rdx, 2
        syscall
        // exit
        mov rax, 60
        mov rdi, 0
        syscall

_dodogstuff:
        // bark at user
        mov rax, 1
        mov rdi, 1
        lea rsi, [.dogstuff]
        mov rdx, 4
        syscall
        // newline
        mov rax, 1
        mov rdi, 1
        lea rsi, [.newline]
        mov rdx, 2
        syscall
        // exit
        mov rax, 60
        mov rdi, 0
        syscall

.the_ask:
        .asciz "Please Enter: (c)at, (d)og: "

.newline:
        .asciz "\n"

.catstuff:
        .asciz "meow"

.dogstuff:
        .asciz "woof"

关键修正说明

  1. 字符对比逻辑:用cmp byte [rsp], 'c'直接读取栈中存储的1字节输入字符,和字符常量'c'(汇编器会自动转换为对应的ASCII码99)做对比,这才是正确的字符值比较。
  2. 冗余代码移除:删掉了.catletter和.dogletter两个不必要的字符常量,直接用字符常量对比更简洁。
  3. syscall寄存器规范:在打印换行时显式重新设置rax和rdi,避免依赖之前的寄存器状态,让代码更健壮。

内容的提问来源于stack exchange,提问作者synnøve

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 14:05:56