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

汇编语言算术运算指南:加减乘除示例及int 21h指令解析

汇编语言算术运算实现与int 21h指令说明

一、四种算术运算的示例代码(Linux NASM 32位环境)

以下示例基于Linux 32位系统,使用int 0x80完成系统调用,包含输入、运算、输出完整流程。注意:输入的字符需先转为数值,运算后再转回ASCII格式输出。

1. 加法运算

section .data
    prompt1 db '输入第一个数字: ', 0xA, 0xD
    len1 equ $ - prompt1
    prompt2 db '输入第二个数字: ', 0xA, 0xD
    len2 equ $ - prompt2
    result_msg db '结果: ', 0xA, 0xD
    len_result equ $ - result_msg

section .bss
    num1 resb 2
    num2 resb 2
    sum resb 1

section .text
    global _start

_start:
    ; 输出第一个输入提示
    mov eax, 4
    mov ebx, 1
    mov ecx, prompt1
    mov edx, len1
    int 0x80

    ; 读取第一个数字
    mov eax, 3
    mov ebx, 0
    mov ecx, num1
    mov edx, 2
    int 0x80

    ; 输出第二个输入提示
    mov eax, 4
    mov ebx, 1
    mov ecx, prompt2
    mov edx, len2
    int 0x80

    ; 读取第二个数字
    mov eax, 3
    mov ebx, 0
    mov ecx, num2
    mov edx, 2
    int 0x80

    ; ASCII转十进制数值:减去字符'0'的ASCII值
    mov al, [num1]
    sub al, '0'
    mov bl, [num2]
    sub bl, '0'

    ; 执行加法操作
    add al, bl

    ; 数值转ASCII:加上字符'0'的ASCII值
    add al, '0'
    mov [sum], al

    ; 输出结果提示
    mov eax, 4
    mov ebx, 1
    mov ecx, result_msg
    mov edx, len_result
    int 0x80

    ; 输出计算结果
    mov eax, 4
    mov ebx, 1
    mov ecx, sum
    mov edx, 1
    int 0x80

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

2. 减法运算

section .data
    prompt1 db '输入被减数: ', 0xA, 0xD
    len1 equ $ - prompt1
    prompt2 db '输入减数: ', 0xA, 0xD
    len2 equ $ - prompt2
    result_msg db '结果: ', 0xA, 0xD
    len_result equ $ - result_msg

section .bss
    num1 resb 2
    num2 resb 2
    diff resb 1

section .text
    global _start

_start:
    ; 输出提示并读取两个数字
    mov eax, 4
    mov ebx, 1
    mov ecx, prompt1
    mov edx, len1
    int 0x80

    mov eax, 3
    mov ebx, 0
    mov ecx, num1
    mov edx, 2
    int 0x80

    mov eax, 4
    mov ebx, 1
    mov ecx, prompt2
    mov edx, len2
    int 0x80

    mov eax, 3
    mov ebx, 0
    mov ecx, num2
    mov edx, 2
    int 0x80

    ; ASCII转数值
    mov al, [num1]
    sub al, '0'
    mov bl, [num2]
    sub bl, '0'

    ; 执行减法操作
    sub al, bl

    ; 数值转ASCII
    add al, '0'
    mov [diff], al

    ; 输出结果
    mov eax, 4
    mov ebx, 1
    mov ecx, result_msg
    mov edx, len_result
    int 0x80

    mov eax, 4
    mov ebx, 1
    mov ecx, diff
    mov edx, 1
    int 0x80

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

3. 乘法运算(修正ASCII转换问题)

section .data
    prompt1 db '输入第一个数字: ', 0xA, 0xD
    len1 equ $ - prompt1
    prompt2 db '输入第二个数字: ', 0xA, 0xD
    len2 equ $ - prompt2
    result_msg db '结果: ', 0xA, 0xD
    len_result equ $ - result_msg

section .bss
    num1 resb 2
    num2 resb 2
    product resb 2  ; 预留两位存储结果

section .text
    global _start

_start:
    ; 输入第一个数字
    mov eax, 4
    mov ebx, 1
    mov ecx, prompt1
    mov edx, len1
    int 0x80

    mov eax, 3
    mov ebx, 0
    mov ecx, num1
    mov edx, 2
    int 0x80

    ; 输入第二个数字
    mov eax, 4
    mov ebx, 1
    mov ecx, prompt2
    mov edx, len2
    int 0x80

    mov eax, 3
    mov ebx, 0
    mov ecx, num2
    mov edx, 2
    int 0x80

    ; ASCII转数值
    mov al, [num1]
    sub al, '0'
    mov bl, [num2]
    sub bl, '0'

    ; 执行乘法:mul bl 结果存于AX寄存器(AH=高位,AL=低位)
    mul bl

    ; 数值转ASCII:拆分十位和个位
    mov ah, 0
    mov bl, 10
    div bl          ; AL=十位,AH=个位
    add al, '0'
    mov [product], al
    add ah, '0'
    mov [product+1], ah

    ; 输出结果提示
    mov eax, 4
    mov ebx, 1
    mov ecx, result_msg
    mov edx, len_result
    int 0x80

    ; 输出计算结果
    mov eax, 4
    mov ebx, 1
    mov ecx, product
    mov edx, 2
    int 0x80

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

4. 除法运算

section .data
    prompt1 db '输入被除数: ', 0xA, 0xD
    len1 equ $ - prompt1
    prompt2 db '输入除数: ', 0xA, 0xD
    len2 equ $ - prompt2
    result_msg db '商: ', 0xA, 0xD
    len_result equ $ - result_msg
    rem_msg db '余数: ', 0xA, 0xD
    len_rem equ $ - rem_msg

section .bss
    num1 resb 2
    num2 resb 2
    quotient resb 1
    remainder resb 1

section .text
    global _start

_start:
    ; 输入被除数和除数
    mov eax, 4
    mov ebx, 1
    mov ecx, prompt1
    mov edx, len1
    int 0x80

    mov eax, 3
    mov ebx, 0
    mov ecx, num1
    mov edx, 2
    int 0x80

    mov eax, 4
    mov ebx, 1
    mov ecx, prompt2
    mov edx, len2
    int 0x80

    mov eax, 3
    mov ebx, 0
    mov ecx, num2
    mov edx, 2
    int 0x80

    ; ASCII转数值
    mov al, [num1]
    sub al, '0'
    mov bl, [num2]
    sub bl, '0'

    ; 执行除法:AX为被除数,BL为除数,结果AL=商,AH=余数
    mov ah, 0
    div bl

    ; 数值转ASCII
    add al, '0'
    mov [quotient], al
    add ah, '0'
    mov [remainder], ah

    ; 输出商
    mov eax, 4
    mov ebx, 1
    mov ecx, result_msg
    mov edx, len_result
    int 0x80

    mov eax, 4
    mov ebx, 1
    mov ecx, quotient
    mov edx, 1
    int 0x80

    ; 输出余数
    mov eax, 4
    mov ebx, 1
    mov ecx, rem_msg
    mov edx, len_rem
    int 0x80

    mov eax, 4
    mov ebx, 1
    mov ecx, remainder
    mov edx, 1
    int 0x80

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

二、int 21h指令的含义

int 21h是DOS操作系统下的软中断指令,用于触发系统调用,实现输入输出、文件操作、程序退出等系统级功能。

使用规则:

  1. 先将功能号存入AH寄存器;
  2. 根据功能要求设置其他寄存器的参数;
  3. 执行int 21h触发调用。

常见功能号示例:

  • AH=01h:从键盘读取一个字符并回显,结果存入AL;
  • AH=02h:输出DL寄存器中存储的ASCII字符;
  • AH=4Ch:终止当前程序,返回DOS系统。

注意:int 21h仅适用于DOS或兼容DOS的环境(如早期Windows的DOS窗口),现代Linux系统使用int 0x80或syscall指令完成系统调用。

三、你提供的乘法代码分析

你给出的代码是Linux 32位NASM汇编,核心逻辑是读取输入、执行乘法、输出结果,但存在一个关键问题:

代码直接对输入的ASCII字符执行乘法,而非先转为十进制数值。例如输入'2'(ASCII值0x32)和'3'(0x33),实际计算的是0x32 * 0x33 = 0xA2C,存入product后输出的是对应ASCII字符(非数字),导致显示乱码。

修正方案参考上面的乘法运算示例,先将输入的ASCII字符减去'0'转为数值,运算后再将结果转为ASCII字符输出。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 20:05:33