汇编实战!手把手教你从“计算器”入门汇编语言
<ul><li><span style="font-size: 18pt"><strong>基于汇编语言的简单整数计算器设计与实现</strong></span></li>
</ul>
<p> </p>
<p><span style="font-size: 18pt"><strong>(此代码仅供学习使用,请勿用作其他用途)</strong></span></p>
<h2>摘要</h2>
<p>本论文介绍了一款使用汇编语言编写的简单整数计算器程序,该程序支持基本的四则运算操作,并能处理包含括号的数学表达式。本文通过分析程序的代码结构,宏定义、数据段、子程序以及关键功能的实现,详细介绍了其设计与实现。同时,还讨论了程序的输入输出流程、符号优先级处理、运算逻辑、错误处理机制等方面的内容,以及代码中所使用的宏定义的功能。通过本文的阐述,读者将能够了解汇编语言中如何实现一个简单但完整的计算器程序。</p>
<h2>引言</h2>
<p>计算器是现代计算机科学中的一个重要应用,能够进行数学运算,解决各种实际问题。虽然现代计算器通常是软件应用程序,但在本文中,我们将介绍如何使用汇编语言设计和实现一个简单的整数计算器。该计算器能够执行加法、减法、乘法、除法等基本运算,同时支持使用括号改变运算的优先级。</p>
<p> </p>
<h2>数据段(Datas Segment)</h2>
<p>程序的数据段包括字符串、标志、数值和运算符缓冲区。其中,字符串用于用户界面和错误信息的显示,标志用于跟踪输入状态,数值缓冲区用于存储数字,运算符缓冲区用于存储运算符和其优先级。这些数据段在程序运行时将用于输入、输出和计算。</p>
<h2>宏定义</h2>
<p>程序中使用了三个宏定义,分别是<code>show</code>、<code>fq</code>和<code>hchh</code>。这些宏用于实现代码的复用和简化,使代码更加易读。<code>show</code>宏用于显示字符串,<code>fq</code>宏用于为运算符赋权值,<code>hchh</code>宏用于在控制台输出时添加回车换行。</p>
<h2>主程序(Main Procedure)</h2>
<p>主程序是程序的入口点,它包括初始化数据段、显示用户界面、处理用户输入、进行运算和输出结果。主程序使用循环来不断接收用户输入,并根据用户的操作执行相应的计算和输出。如果用户输入的表达式不合法,程序会进行错误处理并提供相应的错误提示。</p>
<h2>子程序(Procedures)</h2>
<p>程序中包含了多个子程序,用于实现不同的功能。其中,<code>dyfq</code>子程序用于为运算符赋予优先级,<code>output</code>子程序用于输出计算结果,<code>ys</code>子程序用于执行实际的运算操作。这些子程序提高了代码的可维护性和模块化程度。</p>
<h2>运算逻辑</h2>
<p>程序使用栈来处理运算符的优先级。栈中存储了运算符和它们的优先级,通过比较运算符的优先级来决定执行哪个运算。程序会根据用户输入的数学表达式,依次处理数字和运算符,同时根据运算符的优先级进行相应的计算。</p>
<h2>错误处理</h2>
<p>程序实现了错误处理机制,当用户输入的表达式存在括号不匹配、运算符不合法或其他错误情况时,程序会输出错误提示信息,并允许用户重新输入。这增加了程序的健壮性和用户友好性。</p>
<p> </p>
<div>
<div>datas segment</div>
<div> str1 db 0ah,0dh,'*******************************************$'</div>
<div> str2 db 0ah,0dh,'* 1 2 3 4 5 *$'</div>
<div> str3 db 0ah,0dh,'* 6 7 8 9 0 *$'</div>
<div> str4 db 0ah,0dh,'* + - * / = *$'</div>
<div> str5 db 0ah,0dh,'*******************************************$'</div>
<div> str6 db 0ah,0dh, 'please input a formula: $'</div>
<div> str7 db 'continue(y/n)$'</div>
<div> sign1 dw 0 ;值为0代表输入的不是数字,为1代表输入的是数字</div>
<div> sign2 dw 0,0 ;值为0代表输入的符号是匹配的,为1输入的符号不匹配</div>
<div> number dw 20 dup(0) ;保存输入的数值</div>
<div> operator db '$' ;判断输入的运算符是否为空</div>
<div> db 10 dup(0) ;保存该运算符对应的权值</div>
<div> error db 'wrong!$'</div>
<div>datas ends</div>
<br>
<div>STACKS SEGMENT</div>
<div> </div>
<div>STACKS ENDS</div>
<br>
<div>show macro str ;宏定义,显示字符串</div>
<div> lea dx,str</div>
<div> mov ah,9</div>
<div> int 21h</div>
<div>endm</div>
<div>fq macro ascii,a,b ;宏定义,给运算符赋权值</div>
<div> cmp al,ascii</div>
<div> jne s&a</div>
<div> mov ch,b</div>
<div> jmp s7</div>
<div>endm</div>
<div>hchh macro ;宏定义,回车换行</div>
<div> mov ah,2</div>
<div> mov dl,0dh</div>
<div> int 21h</div>
<div> mov ah,2</div>
<div> mov dl,0ah</div>
<div> int 21h</div>
<div>endm</div>
<br>
<div>codes segment</div>
<div>main proc far</div>
<div> assume cs:codes,ds:datas</div>
<div> start: </div>
<div> mov ax,datas</div>
<div> mov ds,ax</div>
<div> lea di,number</div>
<div> lea si,operator</div>
<div> show str1</div>
<div> show str2</div>
<div> show str3</div>
<div> show str4</div>
<div> show str5</div>
<div> show str6</div>
<div> mov ax,0</div>
<div> mov bx,0</div>
<div> mov cx,0</div>
<div> mov dx,0</div>
<div> start1:</div>
<div> hchh</div>
<div> input: mov ah,1</div>
<div> int 21h</div>
<div> cmp al,'='</div>
<div> je let0</div>
<div> cmp al,1bh</div>
<div> je exit</div>
<div> cmp al,28h ;第二种情况,第一次输入的与28h也就是‘(’比较</div>
<div> jb input ;小于28h=(则重新输入 因为不管数字还是符号都比(大</div>
<div> cmp al,39h</div>
<div> ja input ;大于39h=9则重新输入 再大也用不着</div>
<div> cmp al,2fh ;判断是数字还是符号</div>
<div> jbe let1 ;是符号转入响应操作</div>
<div> inc word ptr sign1 ;是数字的话将数字标志位加1</div>
<div> sub al,30h ;ASCII码与数字差</div>
<div> mov ah,0</div>
<div> xchg ax, ;mul用ax中数乘源操作数</div>
<div> mul bx</div>
<div> mov bx,10</div>
<div> xchg ax,</div>
<div> add ,ax</div>
<div> jmp input</div>
<div> call fun</div>
<div> ret</div>
<div>main endp</div>
<div>fun proc near ;***********************************************************</div>
<br>
<div> let0: </div>
<div> cmp word ptr sign2,0 ;判断配对标志位</div>
<div> je let1 ;经过左括号和右括号抵消为0则跳转</div>
<div> jmp let8 ;否则跳转到bc显示输入错误</div>
<div> let1: </div>
<div> cmp word ptr sign1,0</div>
<div> je let2</div>
<div> add di,2 ;</div>
<div> mov word ptr sign1,0 ;将数字标志位sign1复0</div>
<div> let2: </div>
<div> call dyfq ;设定优先级</div>
<div> cmp ch,5 ;判断输入的符号是否是左括号</div>
<div> jne let3 ;不是则判断输入的是否是右括号</div>
<div> inc word ptr sign2 ;是左括号,括号标志位sign2加1</div>
<div> let3: </div>
<div> cmp ch,1 ;判断输入的是否是右括号</div>
<div> jne let4</div>
<div> dec word ptr sign2 ;是右括号,括号标志位减1</div>
<div> let4: </div>
<div> cmp byte ptr,'$' ;判断运算符存储区是否为空</div>
<div> je let6</div>
<div> cmp ch, ;的内容为前一个符号或其权值</div>
<div> ja let6</div>
<div> cmp byte ptr,'('</div>
<div> jne let5</div>
<div> dec si</div>
<div> jmp input</div>
<div> let5: </div>
<div> dec si</div>
<div> mov cl,</div>
<div> call ys ;判断是什么运算符并进行相应的计算</div>
<div> jmp let4</div>
<div> let6: </div>
<div> cmp ch,0 ;判断是否是等号</div>
<div> je output</div>
<div> cmp ch,1</div>
<div> je input ;“)”不保存,输入下一个数</div>
<div> inc si</div>
<div> mov ,al ;保存符号</div>
<div> inc si</div>
<div> cmp ch,5 ;判断是否是左括号</div>
<div> jne let7</div>
<div> mov ch,2 ;改变(的权值</div>
<div> let7: </div>
<div> mov ,ch ;紧跟着保存符号的权值</div>
<div> jmp input</div>
<div> let8: </div>
<div> lea dx,error</div>
<div> mov ah,9</div>
<div> int 21h</div>
<div> jmp exit</div>
<div> ret</div>
<div>fun endp ;**********************************************************************</div>
<div>dyfq proc ;子程序dyfq调用宏fq,判断优先级</div>
<div> fq 28h,1,5 ;调用宏fq为(赋权值</div>
<div> s1: fq 29h,2,1 ;调用宏fq为)赋权值</div>
<div> s2: fq 2ah,3,4 ;调用宏fq为*赋权值</div>
<div> s3: fq 2fh,4,4 ;调用宏fq为/赋权值</div>
<div> s4: fq 2bh,5,3 ;调用宏fq为+赋权值</div>
<div> s5: fq 2dh,6,3 ;调用宏fq为-赋权值</div>
<div> s6: fq 3dh,7,0 ;调用宏fq为=赋权值</div>
<div> s7: ret</div>
<div>dyfq endp ;*********************************************</div>
<div> output: ;输出运算结果</div>
<div> sub di,2</div>
<div> cmp word ptr,0</div>
<div> jge k1</div>
<div> neg word ptr ;求负数的绝对值</div>
<div> mov dl,'-'</div>
<div> mov ah,2</div>
<div> int 21h</div>
<div> k1: mov bx,10000</div>
<div> mov cx,5</div>
<div> mov si,0</div>
<div> k2: mov ax,</div>
<div> cwd ;字到双字符的扩展</div>
<div> div bx</div>
<div> mov ,dx</div>
<div> cmp al,0</div>
<div> jne k3</div>
<div> cmp si,0</div>
<div> jne k3</div>
<div> cmp cx,1</div>
<div> je k3</div>
<div> jmp k4</div>
<div> k3: mov dl,al</div>
<div> add dl,30h</div>
<div> mov ah,2</div>
<div> int 21h</div>
<div> mov si,1</div>
<div> k4: mov ax,bx ;实现进制转换</div>
<div> mov dx,0</div>
<div> mov bx,10</div>
<div> div bx</div>
<div> mov bx,ax</div>
<div> loop k2</div>
<div> hchh</div>
<div> show str7</div>
<div> mov ah,1</div>
<div> int 21h</div>
<div> cmp al,'n' ;判断是否继续输入,输入n则结束操作</div>
<div> je exit</div>
<div> cmp al,'N'</div>
<div> je exit</div>
<div> mov word ptr,0</div>
<div> lea di,number</div>
<div> lea si,operator</div>
<div> jmp start1</div>
<div> exit: </div>
<div> mov ah,4ch</div>
<div> int 21h</div>
<div>ys proc near ;子程序,进行相应的运算</div>
<div> push ax</div>
<div> mov ax,0</div>
<div> mov bx,0</div>
<div> cmp cl,2ah ;乘法运算</div>
<div> jne chu</div>
<div> sub di,2</div>
<div> xchg bx,</div>
<div> sub di,2</div>
<div> xchg ax,</div>
<div> imul bx</div>
<div> mov ,ax</div>
<div> add di,2</div>
<div> jmp finish</div>
<div> chu: </div>
<div> cmp cl,2fh ;除法运算</div>
<div> jne jia</div>
<div> sub di,2</div>
<div> xchg bx,</div>
<div> sub di,2</div>
<div> xchg ax,</div>
<div> cwd</div>
<div> idiv bx</div>
<div> mov ,ax</div>
<div> add di,2</div>
<div> jmp finish</div>
<div> jia: </div>
<div> cmp cl,2bh ;加法运算</div>
<div> jne jian</div>
<div> sub di,2</div>
<div> xchg bx,</div>
<div> sub di,2</div>
<div> add ,bx</div>
<div> add di,2</div>
<div> jmp finish</div>
<div> jian: </div>
<div> cmp cl,2dh ;减法运算</div>
<div> jne finish</div>
<div> sub di,2</div>
<div> xchg bx,</div>
<div> sub di,2</div>
<div> sub ,bx</div>
<div> add di,2</div>
<div> finish:</div>
<div> pop ax</div>
<div> ret</div>
<div>ys endp ;**************************************************************</div>
<div>codes ends</div>
<div> end start</div>
<div> </div>
<div> </div>
<div>运行截图:</div>
<div> </div>
<div>
<p><img src="https://img2023.cnblogs.com/blog/2968878/202310/2968878-20231012233243532-1011051739.png"></p>
<p> </p>
<p>.</p>
<p> </p>
</div>
</div><br><br>
来源:https://www.cnblogs.com/zzbcoder/p/17760895.html
頁:
[1]