程序中新出现了一条指令--ADC,这条指令以ADD一样用于完成加法,不过它在把两个操作数相加之后还要多加一些东西:
助记符:ADC(Add with Carry)
用 途:完成带进位的加法运算
格 式:ADC 寄存器,立即数
ADC 寄存器,寄存器
ADC 寄存器,存储单元
ADC 存储单元,寄存器
执 行:两个操作数相加,再加上标志寄存器的CF位,所得结果保存在左边
的寄存器或存储单元中。
所谓多加的东西,就是标志寄存器中的CF位。举个例子,如果AX=0003H,BX=0005H,CF=1,那么执行指令"ADD AX,BX"之后将得结果AX=0008H,若执行的指令是"ADC AX,BX",那么结果就是AX=0009H,CF标志被加入结果中。
与这个指令相对的就是带借位的减法指令--SBB:
助记符:SBB(Subtract with Borrow)
用 途:完成带借位的减法运算
格 式:SBB 寄存器,立即数
SBB 寄存器,寄存器
SBB 寄存器,存储器
SBB 存储器,寄存器
执 行:两个操作数相减,同时减去CF标志,结果保存在左边的寄存器或存
储单元中。
ESC_KEY equ 1bh ;ESC键的ASCII码 code segment assume cs:code,ds:code org 100h main proc far jmp start ;跳过数据区 msg db 0dh,0ah,'Press any key...',0dh,0ah,24h start: mov ah,9 ;显示字符串MSG mov dx,offset msg int 21h mov ah,0 ;等待键盘输入 int 16h cmp al,ESC_KEY ;输入的是ESC键吗? jz exit ;是ESC键,转EXIT结束进程 call hex16o ;调用HEX16O输出所按键的ASCII码 jmp start ;转START继续 exit: mov ah,4ch ;结束程序 int 21h main endp hex16o proc near ;输出ASCII码的程序 push bx ;保存寄存器 push cx mov ch,4 ;输出4个字符 loop1: mov cl,4 ;将AX寄存器的高4位移至低4位 rol ax,cl mov bx,ax ;暂存移位后的结果 and ax,0fh ;保存AX寄存器的低4位 add al,90h ;AL寄存器加上90H daa ;对计算结果进行调整 adc al,40h ;AL寄存器再上40H及CF标志 daa ;再次对计算结果进行调整 mov ah,0eh ;调用10H中断的0EH功能输出AL中的字符 int 10h mov ax,bx ;取回移位后的结果 dec ch ;处理完AX寄存器中的数据了吗? jnz loop1 ;未处理完数据,转LOOP1继续 pop cx ;恢复寄存器 pop bx ret ;返回主过程 hex16o endp code ends end main
压缩的BCD码不能进行乘、除运算,因为没有相应的调整指令处理运算结果。而采用非压缩BCD码不仅可以进行加、减运算,而且可以作乘、除运算,计算结果都有相应指令进行调整。其调整指令共有4条:
·AAA(ASCII Adjust for Addition)加法的ASCII调整指令
·AAS(ASCII Adjust for Subtraction)减法的ASCII调整指令
·AAM(ASCII Adjust for Multiplication)乘法的ASCII调整指令
·AAD(ASCII Adjust for Division)除法的ASCII调整指令
这四条指令之所以被称为 "ASCII调整指令",可能是由于字符0-9的ASCII码与非压缩BCD码之间的密切关系而来的。指令记忆起来也比较容易,前两个字母都是AA,第三个字母表示了这条指令对何种运算结果进行调整。
有些朋友总觉得汇编指令繁杂难记,其实并非如此,关键在于掌握合理的记忆方法。按字母死背是最笨的。实际上指令的助记符都来源于一些实际的英文单词,就连标志寄存器中各个位的符号其实也是英文缩写。如果能确实搞懂这些单词的含义自然就能把这些指令、符号之类的东西记住,所以说死记指令不如活学英语。这样学习就可以做到一举多得,至少可以两得,既学了编程又学了英语。