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

如何修复汇编计算器代码中的IMUL和DIV指令错误?

汇编计算器程序的编译错误修复

错误信息

main.asm:60: error: invalid combination of opcode and operands
main.asm:71: error: operation size not specified

原代码

section .bss
    num1 resb 8         ; Buffer to store the first number (max 8 bytes)
    num2 resb 8         ; Buffer to store the second number (max 8 bytes)
    operator resb 1     ; Buffer to store the operator (1 byte)
    result resb 16      ; Buffer to store the result (max 16 bytes)

section .text
    global _start

_start:
    ; Read the first number
    mov rax, 0          ; syscall number (sys_read)
    mov rdi, 0          ; file descriptor (stdin)
    mov rsi, num1       ; buffer to store input
    mov rdx, 8          ; number of bytes to read (max 8 bytes)
    syscall             ; call kernel

    ; Read the operator
    mov rax, 0          ; syscall number (sys_read)
    mov rdi, 0          ; file descriptor (stdin)
    mov rsi, operator   ; buffer to store input
    mov rdx, 1          ; number of bytes to read (1 byte)
    syscall             ; call kernel

    ; Read the second number
    mov rax, 0          ; syscall number (sys_read)
    mov rdi, 0          ; file descriptor (stdin)
    mov rsi, num2       ; buffer to store input
    mov rdx, 8          ; number of bytes to read (max 8 bytes)
    syscall             ; call kernel

    ; Convert first number from ASCII to integer
    movzx eax, byte [num1]
    sub eax, '0'

    ; Convert second number from ASCII to integer
    movzx ebx, byte [num2]
    sub ebx, '0'

    ; Perform the specified operation
    mov cl, byte [operator]
    cmp cl, '+'
    je add_operation
    cmp cl, '-'
    je sub_operation
    cmp cl, '*'
    je mul_operation
    cmp cl, '/'
    je div_operation

add_operation:
    add eax, ebx
    jmp output

sub_operation:
    sub eax, ebx
    jmp output

mul_operation:
    imul eax, ebx
    jmp output

div_operation:
    xor edx, edx
    div ebx
    jmp output

output:
    add eax, '0'
    mov [result], al
    mov [result+1], 0 ; null terminator for safety
    mov rax, 1          ; syscall number (sys_write)
    mov rdi, 1          ; file descriptor (stdout)
    mov rsi, result     ; buffer to store output
    mov rdx, 2          ; number of bytes to write (result + null terminator)
    syscall             ; call kernel

    ; Exit
    mov rax, 60         ; syscall number (sys_exit)
    xor rdi, rdi        ; exit code 0
    syscall             ; call kernel

错误分析与修复

1. 操作数大小未指定错误(第71行)

mov [result+1], 0 未明确指定写入的字节宽度,汇编器无法判断要写入1字节、2字节还是4字节的0,需显式指定为字节操作:

mov byte [result+1], 0 ; 明确写入1字节的空终止符

2. IMUL指令操作数无效错误(第60行)

部分NASM版本对32位寄存器的双操作数imul组合有严格要求,可通过两种方式修复:

  • 方式一:显式指定32位操作数宽度
imul dword eax, dword ebx
  • 方式二:改用无符号乘法指令mul(输入为0-9的无符号数字,结果与IMUL一致)
mul ebx

修复后的完整代码

section .bss
    num1 resb 8         ; Buffer to store the first number (max 8 bytes)
    num2 resb 8         ; Buffer to store the second number (max 8 bytes)
    operator resb 1     ; Buffer to store the operator (1 byte)
    result resb 16      ; Buffer to store the result (max 16 bytes)

section .text
    global _start

_start:
    ; Read the first number
    mov rax, 0          ; syscall number (sys_read)
    mov rdi, 0          ; file descriptor (stdin)
    mov rsi, num1       ; buffer to store input
    mov rdx, 8          ; number of bytes to read (max 8 bytes)
    syscall             ; call kernel

    ; Read the operator
    mov rax, 0          ; syscall number (sys_read)
    mov rdi, 0          ; file descriptor (stdin)
    mov rsi, operator   ; buffer to store input
    mov rdx, 1          ; number of bytes to read (1 byte)
    syscall             ; call kernel

    ; Read the second number
    mov rax, 0          ; syscall number (sys_read)
    mov rdi, 0          ; file descriptor (stdin)
    mov rsi, num2       ; buffer to store input
    mov rdx, 8          ; number of bytes to read (max 8 bytes)
    syscall             ; call kernel

    ; Convert first number from ASCII to integer
    movzx eax, byte [num1]
    sub eax, '0'

    ; Convert second number from ASCII to integer
    movzx ebx, byte [num2]
    sub ebx, '0'

    ; Perform the specified operation
    mov cl, byte [operator]
    cmp cl, '+'
    je add_operation
    cmp cl, '-'
    je sub_operation
    cmp cl, '*'
    je mul_operation
    cmp cl, '/'
    je div_operation

add_operation:
    add eax, ebx
    jmp output

sub_operation:
    sub eax, ebx
    jmp output

mul_operation:
    imul dword eax, dword ebx ; 显式指定32位操作数宽度
    jmp output

div_operation:
    xor edx, edx
    div ebx
    jmp output

output:
    add eax, '0'
    mov [result], al
    mov byte [result+1], 0 ; 明确指定字节操作
    mov rax, 1          ; syscall number (sys_write)
    mov rdi, 1          ; file descriptor (stdout)
    mov rsi, result     ; buffer to store output
    mov rdx, 2          ; number of bytes to write (result + null terminator)
    syscall             ; call kernel

    ; Exit
    mov rax, 60         ; syscall number (sys_exit)
    xor rdi, rdi        ; exit code 0
    syscall             ; call kernel

额外提示

当前代码仅支持0-9的单个数字运算,若结果超过9(如5*3=15),add eax, '0'会将其转换为非数字的ASCII字符,输出结果错误。后续可扩展代码实现多位数输入和多位数结果的ASCII转换逻辑。

内容的提问来源于stack exchange,提问作者권민서

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 10:34:59