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

x86-64汇编多条件跳转处理及计算器运算优先级实现问题

处理x86-64汇编计算器的运算优先级问题

当前你的计算器代码仅按输入顺序从左到右执行运算,未遵循乘除优先级高于加减的规则。要解决这个问题,最经典的方案是双栈法——维护数字栈和运算符栈,通过优先级判断决定何时执行运算。

核心规则

  • 数字栈:存储解析后的十进制数字
  • 运算符栈:存储运算符,并按优先级管理栈内元素
  • 优先级定义:*、/优先级为2,+、-优先级为1
  • 处理逻辑:
    • 遇到数字:直接压入数字栈
    • 遇到运算符:
      1. 若运算符栈为空,直接压入
      2. 若当前运算符优先级高于栈顶运算符,压入栈
      3. 若当前运算符优先级≤栈顶运算符,弹出栈顶运算符和数字栈的两个数字(注意顺序:后弹出的是左操作数),计算结果后压回数字栈,重复此步骤直到栈顶运算符优先级低于当前运算符,再压入当前运算符
    • 遍历完输入后,依次弹出栈内运算符和对应数字计算,直到运算符栈为空,数字栈剩余的唯一值就是结果

修改后的汇编代码示例

;calculator.asm

%macro  convert 2
    mov al, dl
    mov dl, 0
    mov bl, %1
    div bl
    add byte[result+%2], al
%endmacro

; 栈操作宏:压入字节到栈,栈顶指针递减(x86栈向低地址增长)
%macro push_byte 2
    mov byte[%1 + %2 - 1], dl  ; %1是栈基址,%2是栈顶指针当前值
    dec %2                     ; 更新栈顶指针
%endmacro

; 弹出字节从栈,栈顶指针递增
%macro pop_byte 2
    inc %2
    mov dl, byte[%1 + %2 - 1]
%endmacro

section .data
    msg db  "Enter an equation: "
    input   db  "000000000", 10
    ; 数字栈和运算符栈,初始栈顶指向栈底+1(空栈状态)
    num_stack db 0,0,0,0,0,0,0,0
    num_top dq 8
    op_stack db 0,0,0,0,0,0,0,0
    op_top dq 8
    result  db 0,0,0
    endLoop dq 9

; 获取运算符优先级:dl=运算符,返回al=优先级
get_priority:
    cmp dl, '+'
    je prio1
    cmp dl, '-'
    je prio1
    cmp dl, '*'
    je prio2
    cmp dl, '/'
    je prio2
prio1:
    mov al, 1
    ret
prio2:
    mov al, 2
    ret

; 执行运算:弹出num栈两个数,op栈一个运算符,计算后压回num栈
execute_op:
    ; 弹出右操作数
    pop_byte num_stack, qword[num_top]
    mov bl, dl
    ; 弹出左操作数
    pop_byte num_stack, qword[num_top]
    mov al, dl
    ; 弹出运算符
    pop_byte op_stack, qword[op_top]
    cmp dl, '+'
    je do_add
    cmp dl, '-'
    je do_sub
    cmp dl, '*'
    je do_mul
    cmp dl, '/'
    je do_div
do_add:
    add al, bl
    jmp push_result
do_sub:
    sub al, bl
    jmp push_result
do_mul:
    mul bl
    jmp push_result
do_div:
    div bl
push_result:
    mov dl, al
    push_byte num_stack, qword[num_top]
    ret

section .text
    global _start

_start:
    ; 输出提示信息
    mov     rax, 1
    mov     rdi, 1
    mov     rsi, msg
    mov     rdx, 19
    syscall
    
    ; 读取输入
    mov     rax, 0
    mov     rdi, 0
    mov     rsi, input
    mov     rdx, 10
    syscall

    xor r10d, r10d
parse_loop:
    ; 解析数字:连续数字合并(比如"123"转为123)
    xor eax, eax
parse_digit:
    mov dl, byte[input+r10]
    cmp dl, '0'
    jb end_digit
    cmp dl, '9'
    ja end_digit
    ; 数字合并:当前值*10 + 新数字
    imul eax, 10
    sub dl, '0'
    add al, dl
    inc r10
    jmp parse_digit
end_digit:
    ; 将解析后的数字压入数字栈
    mov dl, al
    push_byte num_stack, qword[num_top]
    
    ; 检查是否到输入末尾
    cmp r10, qword[endLoop]
    je process_remaining_ops
    
    ; 读取运算符
    mov dl, byte[input+r10]
    inc r10
    
operator_process:
    ; 如果运算符栈为空,直接压入
    cmp qword[op_top], 8
    je push_op
    ; 获取当前运算符优先级
    call get_priority
    mov cl, al
    ; 获取栈顶运算符优先级
    mov dl, byte[op_stack + qword[op_top]]
    call get_priority
    ; 比较优先级:当前优先级>栈顶则压入,否则先执行运算
    cmp cl, al
    jg push_op
    call execute_op
    jmp operator_process
push_op:
    mov dl, byte[input+r10-1]  ; 刚才读取的运算符
    push_byte op_stack, qword[op_top]
    jmp parse_loop

; 处理剩余的运算符
process_remaining_ops:
    cmp qword[op_top], 8
    je done
    call execute_op
    jmp process_remaining_ops

done:
    ; 弹出最终结果
    pop_byte num_stack, qword[num_top]
    mov dl, al
    
    ; 转换为ASCII
    convert 100, 0
    convert 10, 1
    convert 1, 2
    add byte[result+2], dl
    ; 补ASCII偏移
    add byte[result], '0'
    add byte[result+1], '0'
    add byte[result+2], '0'

    ; 输出结果
    mov     rax, 1
    mov     rdi, 1
    mov     rsi, result
    mov     rdx, 3
    syscall
    
    ; 退出程序
    mov     rax, 60
    mov     rdi, 0
    syscall

关键修改说明

  1. 新增数字栈和运算符栈,用宏实现栈的压入/弹出操作(用静态数组模拟栈,符合x86栈向低地址增长的特性)
  2. 实现多位数合并逻辑,支持多位数输入(原代码仅支持单数字)
  3. 新增get_priority函数判断运算符优先级,execute_op函数统一处理运算逻辑,避免重复代码
  4. 按双栈规则处理运算符,确保乘除先于加减执行
  5. 遍历完输入后处理栈内剩余运算符,完成所有计算

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 03:31:05