汇编语言算术运算指南:加减乘除示例及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操作系统下的软中断指令,用于触发系统调用,实现输入输出、文件操作、程序退出等系统级功能。
使用规则:
- 先将功能号存入
AH寄存器; - 根据功能要求设置其他寄存器的参数;
- 执行
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
相关产品推荐
相关产品推荐

