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

x86_64 NASM汇编求三个数最大值:输出异常问题求助

问题排查与解决:x86_64 NASM汇编求三数最大值输出异常

问题根源

你遇到的输出异常核心原因是字符定义的误解:在NASM中,用单引号包裹多字符(如'22')时,汇编器只会保留第一个字符的ASCII值。也就是说:

  • num1='22'实际存储的是字符'2'(ASCII码50)
  • num2='33'实际存储的是字符'3'(ASCII码51)
  • num3='44'实际存储的是字符'4'(ASCII码52)

你的代码本质上是在比较单个字符的ASCII值,最终输出单个字符'4',而非你期望的双字符字符串'44'。

解决方案

要处理两位数字的字符串并正确输出,需要完成以下几点:

  1. 将数字定义为以0结尾的字符串(而非单个字符)
  2. 先把字符串转换为整数进行数值比较(避免直接比较字符ASCII的偏差)
  3. 输出时完整打印整个字符串

修正后的代码示例

section .data
    num1 db '22', 0   ; 定义为以0结尾的字符串
    num2 db '33', 0
    num3 db '44', 0
    newline db 0xa     ; 换行符

section .text
    global _start

_start:
    ; 字符串转整数:num1 -> eax
    mov esi, num1
    call str_to_int
    mov ebx, eax       ; ebx暂存当前最大值

    ; 处理num2
    mov esi, num2
    call str_to_int
    cmp eax, ebx
    jg update_max1     ; num2更大则更新最大值
    jmp check_num3

update_max1:
    mov ebx, eax

check_num3:
    ; 处理num3
    mov esi, num3
    call str_to_int
    cmp eax, ebx
    jg update_max2     ; num3更大则更新最大值
    jmp print_max

update_max2:
    mov ebx, eax

print_max:
    ; 整数转字符串并输出
    mov eax, ebx
    call int_to_str
    mov esi, eax
    call print_str

    ; 打印换行
    mov eax, 4
    mov ebx, 1
    mov ecx, newline
    mov edx, 1
    int 0x80

    ; 退出程序
    mov eax, 1
    xor ebx, ebx
    int 0x80

; 字符串转整数:esi指向输入字符串,返回eax为转换后的整数
str_to_int:
    xor eax, eax
    xor ecx, ecx
.next_char:
    mov cl, [esi]
    test cl, cl
    jz .done
    sub cl, '0'
    imul eax, 10
    add eax, ecx
    inc esi
    jmp .next_char
.done:
    ret

; 整数转字符串:eax为输入整数,返回esi指向转换后的字符串(栈上存储)
int_to_str:
    mov esi, esp
    sub esp, 10        ; 预留字符串存储空间
    mov ebx, 10
    xor ecx, ecx
.next_digit:
    xor edx, edx
    div ebx
    add dl, '0'
    mov [esi + ecx], dl
    inc ecx
    test eax, eax
    jnz .next_digit
    ; 反转字符串(因为除法得到的是逆序数字)
    mov edi, esi
    add edi, ecx
    dec edi
.reverse_loop:
    cmp esi, edi
    jge .reverse_done
    mov al, [esi]
    mov bl, [edi]
    mov [esi], bl
    mov [edi], al
    inc esi
    dec edi
    jmp .reverse_loop
.reverse_done:
    mov byte [esi + ecx], 0  ; 添加字符串结束符
    mov esi, esp             ; 返回字符串指针
    ret

; 打印字符串:esi指向目标字符串
print_str:
    xor ecx, ecx
.count_len:
    mov al, [esi + ecx]
    test al, al
    jz .print
    inc ecx
    jmp .count_len
.print:
    mov eax, 4
    mov ebx, 1
    mov edx, ecx
    int 0x80
    ret

编译运行

仍使用你原来的编译步骤:

$ nasm -f elf64 hello.asm -o hello.o
$ ld -o hello hello.o
$ ./hello

运行后会输出44,符合预期。

内容的提问来源于stack exchange,提问作者imindMan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 16:51:15