汇编语言程序设计简明教程——第3章数据运算与输入输出.ppt_第1页
汇编语言程序设计简明教程——第3章数据运算与输入输出.ppt_第2页
汇编语言程序设计简明教程——第3章数据运算与输入输出.ppt_第3页
汇编语言程序设计简明教程——第3章数据运算与输入输出.ppt_第4页
汇编语言程序设计简明教程——第3章数据运算与输入输出.ppt_第5页
免费预览已结束,剩余130页可下载查看

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1,汇编语言程序设计简明教程,2,第三章数据运算与输入输出,3.1算术运算3.2循环3.3十进制数运算3.4逻辑运算3.5控制台输入和输出3.6移位和处理器控制习题三,3,本章的学习重点:数值计算与标志位;指针的使用;循环程序基本结构;输入输出与数制转换。,4,3.1算术运算,3.1.1加法指令3.1.2减法指令3.1.3乘法和除法指令3.1.4表达式计算,5,(1)ADD(Addition):加法指令格式:ADD目的操作数,源操作数功能:目的操作数目的操作数+源操作数目的操作数:8/16/32位的寄存器/存储器源操作数:与目的操作数同类型的寄存器/存储器/立即数例:ADDAX,SI;AX(AX)+(SI),16位运算ADDX,3;X(X)+3,运算位数由X的类型确定ADDEBX,EDX;DS:EBXDS:EBX+EDX,32位运算,3.1.1加法指令,6,下面的指令无法确定操作数的类型,汇编时将报告错误:ADDSI,5;两个操作数都没有明确类型如果目的操作数是DS:SI指向的字节存储单元,可以修改如下:ADDBYTEPTRSI,5说明:加法指令执行后,状态标志CF,OF,ZF,SF,PF,AF按照运算结果被刷新;操作数可以是8位/16位/32位,源操作数与目的操作数应该有相同的类型,不能同时为内存操作数。,7,(2)ADC(AdditionwithCarry):带进位的加法指令格式:ADC目的操作数,源操作数功能:目的操作数目的操作数+源操作数+CF目的操作数:8/16/32位的寄存器/存储器源操作数:与目的操作数同类型的寄存器/存储器/立即数说明:该指令对标志位的影响、对操作数的要求与ADD指令相同;主要用于对数据分段相加时高位的加法运算。,8,例3-1X=33445566778899AAH,Y=123456789ABCDEF0H,计算Z=X+Y(对应的数据段已经定义,变量X,Y,Z用DQ定义)MOVEAX,DWORDPTRX;取X的低32位,送入EAXADDEAX,DWORDPTRY;X,Y的低32位相加;(EAX)=778899AAH+9ABCDEF0H=1245789AH,CF=1MOVDWORDPTRZ,EAX;低32位的和送Z的低32位MOVEAX,DWORDPTRX+4;取X的高32位,送入EAXADCEAX,DWORDPTRY+4;X,Y的高32位及低位进位相加;(EAX)=33445566H+12345678H+CF=4578ABDFH,CF=0MOVDWORDPTRZ+4,EAX;高32位的和送Z的高32位,9,例3-2A,B,C均为8位无符号数,求它们的和,送入SUM三个8b无符号数的和可能超过255,将它们的和保留为16b。MOVAL,A;取第一个数MOVAH,0;高8位清零,第一个数“零扩展”为16位MOVDL,B;取第二个数MOVDH,0;把第二个数“零扩展”为16位ADDAX,DX;加第二个数MOVDL,C;取第三个数,高8位已经为0ADDAX,DX;加第三个数MOVSUM,AX;保存三个数的和,10,这个问题的另一种方法:MOVAL,A;取第一个数MOVAH,0;高8位清零,准备存放和的高8位ADDAL,B;加第二个数ADCAH,0;如果有进位,存入AHADDAL,C;加第三个数ADCAH,0;如果有进位,加入AHMOVSUM,AX;保存三个数的和,11,这个问题的第三种方法:.386MOVZXAX,A;取第一个数MOVZXBX,B;取第二个数ADDAX,BX;加第二个数MOVZXBX,C;取第三个数ADDAX,BX;加第三个数MOVSUM,AX;保存三个数的和,12,例3-3P,Q,R均为8位有符号数,求它们的和,送入TOTAL将三个8b有符号数的和保留为16b。MOVAL,P;取第一个数CBW;扩展为16位MOVDX,AX;第一个数转存入DXMOVAL,Q;取第二个数CBW;扩展为16位ADDDX,AX;加第二个数MOVAL,R;取第三个数CBW;扩展为16位ADDDX,AX;加第三个数MOVTOTAL,DX;保存三个数的和,13,本题另一种方法.386MOVSXAX,P;取第一个数MOVSXBX,Q;取第二个数ADDAX,BX;P,Q相加MOVSXBX,R;取第三个数ADDAX,BX;与第三个数相加MOVTOTAL,AX;保存三个数的和,14,(3)INC(Increment):增量指令格式:INC目的操作数功能:目的操作数目的操作数+1目的操作数:8/16/32位的寄存器/存储器例:INCEBX;EBX(EBX)+1,32位运算INCX;X(X)+1,运算位数由X的类型确定INCWORDPTRBX;DS:BXDS:BX+1,16位运算说明:增量指令执行后,CPU的状态标志OF,ZF,SF,PF,AF按照运算结果被刷新,但是CF标志不受影响;增量指令常常用来修改计数器和存储器指针的值。,15,(1)SUB(Subtract):减法指令格式:SUB目的操作数,源操作数功能:目的操作数目的操作数源操作数目的操作数:8/16/32位的寄存器/存储器源操作数:与目的操作数同类型的寄存器/存储器/立即数例:SUBEAX,ESI;EAX(EAX)(ESI),32位运算SUBY,20H;Y(Y)20H,运算位数由Y的类型确定SUBWORDPTRBP,5;SS:BPSS:BP5,16位运算说明:该指令对标志位的影响、对操作数的要求与ADD指令相同。,3.1.2减法指令,16,(2)SBB(SubtractwithBorrow):带借位的减法指令格式:SBB目的操作数,源操作数功能:目的操作数目的操作数源操作数CF目的操作数:8/16/32位的寄存器/存储器源操作数:与目的操作数同类型的寄存器/存储器/立即数说明:该指令对标志位的影响、对操作数的要求与ADD指令相同;主要用于对一个数据分段相减时高位的减法运算,17,(3)DEC(Decrement):减量指令格式:DEC目的操作数功能:目的操作数目的操作数1目的操作数:8/16/32位的寄存器/存储器例:DECCX;CX(CX)1,16位运算DECX;X(X)1,运算位数由X的类型确定DECDWORDPTRDI;DS:DIDS:DI1,32位运算说明:减量指令执行后,CPU的状态标志OF,ZF,SF,PF,AF按照运算结果被刷新,但是CF标志不受影响;减量指令常常用来修改计数器和存储器指针的值;,18,(4)NEG(Negate):求补指令格式:NEG目的操作数功能:目的操作数0目的操作数目的操作数:8/16/32位的寄存器/存储器例:NEGZ;ZZ,运算位数由Z的类型确定由于有符号数均使用补码表示,所以该指令的操作等效于:目的操作数目的操作数求补,19,(1)MUL(UnsignedMultiplication):无符号数乘法格式:MUL源操作数源操作数:8位/16位/32位的寄存器/存储器功能:8位源操作数时:AX(AL)源操作数16位源操作数时:DX,AX(AX)源操作数32位源操作数时:EDX,EAX(EAX)源操作数说明:两个N位操作数相乘,得到2N位的乘积;如果乘积的高N位为0,则CF=OF=0,否则CF=OF=1。其余标志位无意义。,3.1.3乘法和除法指令,20,(2)IMUL(SignedIntegerMultiplication):有符号数乘法格式1:IMUL源操作数源操作数:8位/16位/32位的寄存器/存储器功能:8位源操作数时:AX(AL)源操作数16位源操作数时:DX,AX(AX)源操作数32位源操作数时:EDX,EAX(EAX)源操作数,21,说明:两个N位操作数相乘,得到2N位的乘积;源操作数不能为立即数;如果乘积高N位为低N位的符号扩展,则CF=OF=0,否则CF=OF=1,其余标志位无意义。相同的两组二进制代码分别用MUL和IMUL运算,可能得到不同的结果:例如:(AL)=0FFH,(X)=2MULX;(AX)=01FEH,(2552=510)IMULX;(AX)=0FFFEH,(12=2),22,格式2:IMUL目的操作数,源操作数目的操作数:16位/32位的寄存器源操作数:与目的操作数相同类型的寄存器/存储器/立即数功能:目的操作数目的操作数源操作数说明:两个N位操作数相乘,得到N位的乘积;本指令的操作数不能为8位。例:IMULAX,3;AX(AX)3IMULEDX,VERB;EDX(EDX)(VERB),变量VERB用DD定义,23,格式3:IMUL目的操作数,源操作数1,源操作数2目的操作数:16位/32位的寄存器源操作数1:与目的操作数相同类型的寄存器/存储器源操作数2:与目的操作数相同类型的立即数功能:目的操作数源操作数1源操作数2说明:两个N位操作数相乘,得到N位的乘积;本指令的操作数不能为8位。对于IMUL指令,除8/16位的单操作数指令外,其余均为286/386新增的,需要在程序的首部用“.386”加以申明。,24,(3)DIV(UnsignedDivision):无符号除法格式:DIV源操作数源操作数:8位/16位/32位的寄存器/存储器功能:8位源操作数时:(AX)源操作数,AL商,AH余数16位源操作数时:(DX,AX)源操作数,AX商,DX余数32位源操作数时:(EDX,EAX)源操作数,EAX商,EDX余数说明:两个N位操作数相除,应首先把被除数零扩展为2N位;例如,要进行除法(AX)(BX),假设AX、BX内均为无符号数:MOVDX,0;32位被除数高16位清零DIVBX;(DX,AX)BX,AX商,DX余数如果(2N位)(N位)的商大于2N-1,会产生“除法溢出”错误。源操作数不能为立即数,25,例如,要进行除法(AX)5,首先应确定是16位8位还是32位16位:如果能确定(AX)5的商小于255,可以执行16位8位除法:MOVBL,5;除数存入BL寄存器DIVBL;16位8位,AL商,AH余数如果不能确定(AX)5的商小于255,可以执行32位16位除法:MOVBX,5;除数存入BX寄存器MOVDX,0;32位被除数高16位清零DIVBX;(DX,AX)BX,AX商,DX余数,26,(4)IDIV(SignedIntegerDivision):有符号数除法格式:IDIV源操作数源操作数:8位/16位/32位的寄存器/存储器功能:8位源操作数时:(AX)源操作数,AL商,AH余数16位源操作数时:(DX,AX)源操作数,AX商,DX余数32位源操作数时:(EDX,EAX)源操作数,EAX商,EDX余数,27,说明:两个N位操作数相除,应首先把被除数符号扩展为2N位;例如,要进行除法(AX)(BX),AX、BX内均为有符号数CWD;被除数AX符号扩展到DX,AXIDIVBX;(DX,AX)(BX),AX商,DX余数两个有符号数相除,余数与被除数同号:10IDIV3;商=3,余数=110IDIV3;商=3,余数=1如果(2N位)(N位)的商大于2N-1-1或者小于-2N-1,会产生“除法溢出”错误。源操作数不能为立即数;相同的两组二进制代码分别用DIV和IDIV运算,可能得到不同的结果:例如:(AX)=0FFFFH,(CL)=1DIVCL;0FFFFH1=0FFFFH,产生除法溢出IDIVCL;(AL)=0FFH,(AH)=0(11=10),28,例3-4A、B、C、D均为有符号字变量,计算:Z=确定计算顺序如下:A+B(A+B)/2暂存中间结果;AC暂存中间结果;B+C(B+C)*3(B+C)*3/(AC)(B+C)*3/(AC)+(A+B)/2保存最终结果。确定各次运算的数据类型:A+B扩展为32b,(A+B)/2结果为16b;(B+C)*3结果为32b,AC结果为16b,(B+C)*3/(AC)结果为16b,最终结果为16b。,3.1.4表达式计算,29,MOVAX,A;取操作数AADDAX,B;进行运算“A+B”CWD;把被除数扩展为32bMOVBX,2;除数转入寄存器IDIVBX;进行运算(A+B)/2MOVBX,AX;把商转存到BXMOVCX,A;取分母第一个操作数SUBCX,C;进行运算“AC”MOVAX,B;取分子第一个操作数ADDAX,C;进行运算“B+C”MOVDX,3;乘数转入寄存器IMULDX;进行运算(B+C)*3IDIVCX;进行运算(B+C)*3/(AC)ADDAX,BX;运算(B+C)*3/(AC)+(A+B)/2MOVZ,AX;保存最终结果,30,上面的程序不包含输出部分,因此直接运行无法观察到运行结果,需要通过TD来运行该程序:用TD命令调出可执行程序;对照源程序,找出变量Z的存储地址;单步或连续运行程序,直到指令“MOVZ,AX”被执行;在数据窗口中观察运行结果。,31,3.2循环,3.2.1基本循环指令3.2.2程序的循环3.2.3数据的累加3.2.4多项式计算,32,格式:LOOP标号功能:CX(CX)1如果(CX)0,转向“标号”处执行,否则执行下一条指令。说明:LOOP可以改变指令的执行次序,称为“控制指令”;LOOP指令使一段程序重复地执行,称为“循环”。重复执行的次数由CX寄存器中的值决定。CX寄存器因此称为“计数器”。,3.2.1基本循环指令,33,如果将上面的程序写成如下的情形:L1:MOVCX,10.;重复执行的若干条指令LOOPL1这个程序将无限制地运行下去,称为“死循环”。,MOVCX,10L1:.;需要重复执行的若干条指令LOOPL1上面的程序将L1到LOOP指令之间的一段程序重复执行10次。指令“MOVCX,10”称为“装载循环计数器”,在循环之前完成。,34,例3-5用循环的方法,将字节数组ARRAY的20个元素清零。DATASEGMENTARRAYDB20DUP(?);定义数组ARRAYDATAENDSCODESEGMENTASSUMEDS:DATA,CS:CODESTART:MOVAX,DATAMOVDS,AXLEABX,ARRAY;把数组ARRAY首地址装入BXMOVCX,20;装载循环计数器的初始值,3.2.2程序的循环,35,ONE:MOVBYTEPTRBX,0;数组ARRAY的一个元素清零INCBX;修改BX的值,为下一次操作做准备LOOPONE;计数循环MOVAX,4C00HINT21HCODEENDSENDSTART上面程序里,BX存放数组元素的地址,称为“指针”,每次使用后,要及时修改它的值(地址),以便下一次使用。同样原因,装载BX初值(ARRAY数组首地址)的指令也要安放在循环开始之前。,36,MOVCX,10;装载循环计数器的初始值ONE:MOVWORDPTRBX,0;把两个元素清零INCBX;修改BX的值,为下一次操作做准备INCBXLOOPONE;计数循环,经过这样修改,程序变长了,但是重复执行的次数减少了,总的执行时间缩短了。,MOVCX,10;装载循环计数器的初始值MOVAX,0;累加器AX清零ONE:MOVBX,AX;把数组ARRAY的两个元素清零INCBX;修改BX的值,为下一次操作做准备INCBXLOOPONE;计数循环,程序又一次变长了,但使用8086CPU时执行时间会进一步缩短。,37,把数据不断加入同一个容器的过程称为“累加”,这个容器称为“累加器(Accumulator)”。,3.2.3数据的累加,编制程序时,经常会遇到“求若干个数据的和”的问题:,安排一个容器(例如:寄存器),将它清零;把需要求和的数据逐个加入这个容器;加法结束时,容器中的数据就是这些数据的和。,38,DATASEGMENTLISTDW20,25,70,15,200,30,75,108,90,36SUMDW?;SUM存放累加和DATAENDSCODESEGMENTASSUMEDS:DATA,CS:CODESTART:MOVAX,DATAMOVDS,AX,例3-6求LIST字数组所有元素的和。,39,MOVBX,0;BX是数组元素在数组内的位移,初值0MOVCX,10;装载循环计数器的初始值MOVAX,0;累加器AX清零ONE:ADDAX,LISTBX;把数组的一个元素加入AX中INCBX;修改BX的值,为下一次操作做准备INCBXLOOPONE;计数循环MOVSUM,AX;保存结果(累加和)MOVAX,4C00HINT21HCODEENDSENDSTART,40,(1)循环准备阶段:包括向累加器、计数器、指针赋初值,它们出现在循环开始之前,每条指令只执行一次;(2)循环阶段:包括数据累加、修改指针、循环计数和控制三项操作。每条指令重复执行10次。这部分的程序称为“循环体”。(3)循环结束处理阶段:保存数据的累加和。这条指令在循环结束后执行,只执行一次。,程序的主体部分分为三段:,大多数的循环程序都具有上面叙述的三个阶段。,41,SUMDD?MOVAX,0;累加器低位AX清零MOVDX,0;累加器高位DX清零ONE:ADDAX,LISTBX;把数组LIST的一个元素加入AX中ADCDX,0;把可能的进位收集到DX中INCBX;修改BX的值,为下一次操作做准备INCBXLOOPONE;计数循环MOVWORDPTRSUM,AX;保存和的低位MOVWORDPTRSUM+2,DX;保存和的高位,10个16b的无符号数的和可能会超过16b的表示范围。,42,MOVSUM,0;累加器清零ONE:MOVAX,LISTBX;取出数组的一个元素CWD;扩展成32b,置于DX、AX中ADDWORDPTRSUM,AX;低16b累加ADCWORDPTRSUM+2,DX;高16b累加INCBX;修改BX的值,为下一次操作做准备INCBXLOOPONE;计数循环,如果LIST数组的元素是有符号数,处理的方法要随之变化:,43,例3-7已知X=3,计算多项式Y=4X6+7X45X3+2X26X+21的值。上面的多项式可以改写为:(0X+4)X+0)X+7)X5)X+2)X6)X+21上面的计算等同于:P=0;P=PX+4;P=PX+0;除了给P赋初值的“P=0”之外,其余的计算具有相同的公式:P=PX+Ai;Ai是多项式的一个系数用循环的方法计算上面的多项式,多项式的值用16b有符号数存储。,3.2.4多项式计算,44,DATASEGMENTPARMDW4,0,7,-5,2,-6,21;多项式的系数XDW3YDW?DATAENDSCODESEGMENTASSUMEDS:DATA,CS:CODESTART:MOVAX,DATAMOVDS,AX,45,LEASI,PARM;系数数组指针初值MOVCX,7;循环次数MOVAX,0;累加器初值(P=0)NEXT:IMULX;P=PXADDAX,SI;P=PX+AiADDSI,2;修改指针LOOPNEXT;计数和循环控制MOVY,AX;保存结果MOVAX,4C00HINT21HCODEENDSENDSTART,46,DATASEGMENTPARMDW2,8,7,9,3;多项式的系数C10DW10;常数10BINARYDW?DATAENDSCODESEGMENTASSUMEDS:DATA,CS:CODESTART:MOVAX,DATAMOVDS,AX,例3-8编制程序,把十进制数28793转换成二进制数28793=2104+8103+7102+9101+3,47,LEASI,PARM;系数数组指针初值MOVCX,5;循环次数MOVAX,0;累加器初值NEXT:IMULC10;P=P10ADDAX,SI;P=P10+AiADDSI,2;修改指针LOOPNEXT;计数和循环控制MOVBINARY,AX;保存结果MOVAX,4C00HINT21HCODEENDSENDSTART,48,3.3十进制数运算,3.3.1压缩BCD数运算3.3.2非压缩BCD数运算,49,每一个4位组中,如果本组数字相加的和不超过9,结果正确。如果本组的和有进位(超过15),或者虽然没有进位,但是出现了非法的组合(本组和小于16,大于9),得到的结果是错误的。,用二进制加法指令将两个压缩BCD数相加:,3.3.1压缩BCD数运算,50,对相加后的结果作调整:,在80X86微处理器上,上述调整由“十进制调整指令”实现。,如果4位组的和有进位,或者出现了非法组合,将本组数字加6调整,51,格式:DAA功能:对AL中的加法结果进行BCD运算调整例:89+57MOVAL,89H;BCD数89装入AL,使用16进制数格式ADDAL,57H;按照二进制格式相加,(AL)=0E0H,AF=1DAA;进行BCD加法调整,(AL)=46H,CF=1说明:调整之前先进行二进制加法,和必须在AL中。,(1)DAA(DecimalAdjustafterAddition)十进制加法调整,52,if(AL低4位9或AF=1)thenAL=AL+06H;AF=1;endifif(AL高4位9或CF=1)thenAL=AL+60H;CF=1;endif,DAA调整算法:,53,格式:DAS功能:对AL中的减法结果进行BCD运算调整例:8357MOVAL,83H;BCD数83装入AL,使用16进制数格式SUBAL,57H;按照二进制格式相减,(AL)=2CH,AF=1DAS;进行BCD减法调整,(AL)=26H,CF=0说明:调整之前先进行二进制减法,差在AL中。,(2)DAS(DecimalAdjustafterSubtraction)十进制减法调整,54,if(AL低4位9或AF=1)thenAL=AL06H;AF=1;endifif(AL高4位9或CF=1)thenAL=AL60H;CF=1;endif,DAS调整算法:,55,两个数的加法要分4次进行。最低2位数的加法(78+66)用ADD指令相加,DAA指令调整。其余三次加法用ADC指令相加,DAA指令调整。上面的4次运算可以用循环实现。运算前通过指令“ADDAL,0”把CF清零,4次加法统一使用ADC指令实现。,DATASEGMENTADD12345678HBDD33445566HXDD?DATAENDS,例3-9用BCD数进行运算:12345678+33445566,56,CODESEGMENTASSUMEDS:DATA,CS:CODESTART:MOVAX,DATAMOVDS,AXMOVDI,0;设置指针初值MOVCX,4;循环次数ADDAL,0;CF清零NEXT:MOVAL,BYTEPTRADI;取出A的两位BCD数ADCAL,BYTEPTRBDI;与B的对应两位进行加法DAA;BCD数加法调整MOVBYTEPTRXDI,AL;保存结果INCDI;修改指针LOOPNEXT;计数和循环控制MOVAX,4C00HINT21HCODEENDSENDSTART,57,程序运行后,(X)=45791244H,结果正确。如果把“INCDI”指令改为“ADDDI,1”,运行后(X)=45781144H,结果错误。用TD单步执行程序,发现78H+66H和56H+55H均产生了进位(CF=1),执行“ADDDI,1”指令后,CF均被清零,低位的进位没有传递到高位,导致了错误的发生。“INCDI”指令不影响CF,程序能够正常运行,这一点在设计指令系统时已经作了充分的考虑。从本例可以看到,使用CF传递进位时,要细心地选择所使用的指令。汇编语言程序员,应该十分注意标志位的状态。,58,(1)AAA(ASCIIAdjustafterAddition)非压缩十进制加法调整格式:AAA功能:对AL中的加法结果进行非压缩BCD数运算调整例:9+8MOVAL,9;非压缩BCD数9装入AL,使用ASCII格式ADDAL,8;按照二进制格式相加,(AL)=71H,AF=1AAA;非压缩BCD加法调整,(AL)=07H,CF=1说明:调整之前先进行二进制加法,和必须在AL中;低4位的进位用两种方式同时表达:CF=1,AH=AH+1。,3.3.2非压缩BCD数运算,59,if(AL低4位9或AF=1)thenAL=AL+06H;AH=AH+1;AF=1;CF=1;elseAF=0;CF=0;endifAL=ALAND0FH;AL高4位清零,AAA调整算法:,60,格式:AAS功能:对AL中的减法结果进行非压缩BCD数运算调整例:68MOVAL,6;非压缩BCD数6装入AL,使用ASCII格式SUBAL,8;按照二进制格式相减,(AL)=0FEH,AF=1AAS;进行非压缩BCD加法调整,(AL)=08H,CF=1说明:调整之前先进行二进制减法,差在AL中。低4位的借位用两种方式同时表达:CF=1,AH=AH1。,(2)AAS(ASCIIAdjustafterSubtraction)非压缩十进制减法调整,61,if(AL低4位9或AF=1)thenAL=AL06H;AH=AH1;AF=1;CF=1;elseAF=0;CF=0;endifAL=ALAND0FH;AL高4位清零,AAS调整算法:,62,格式:AAM功能:对AX中的乘法结果进行非压缩BCD数运算调整调整算法:AH=AX/10,AL=AXmod10例:67MOVAL,6;非压缩BCD数6装入AL,高4位必须为0MOVBL,7;非压缩BCD数7装入BL,高4位必须为0MULBL;按照二进制格式相乘,(AX)=002AHAAM;非压缩BCD乘法调整,(AH)=04H,(AL)=02H说明:先进行二进制无符号乘法,积在AX中(积81,因此AH=0)然后用AAM指令调整。,(3)AAM(ASCIIAdjustafterMultiplication)非压缩十进制乘法调整,63,格式:AAD功能:将AH和AL中的两位BCD数调整为等值的16位二进制数调整算法:AX=AH10+AL例:587MOVAX,0508H;非压缩BCD数58装入AX,高4位必须为0AAD;把非压缩BCD数58调整为二进制数,(AX)=003AHMOVBL,7DIVBL;按照二进制格式相除;(AL)=08H(商),(AH)=02H(余数)说明:先进行非压缩BCD数调整,然后用二进制无符号数除法指令相除,商在AL中,余数在AH中。,(4)AAD(ASCIIAdjustbeforeDivision)非压缩十进制除法调整,64,3.4逻辑运算,逻辑运算指令将每一位二进制数单独进行运算,各位之间没有相互进位的关系。逻辑运算指令执行之后,CF、OF标志位固定为0。SF,PF,ZF按照运算结果的特征设置。,65,格式:AND目的操作数,源操作数功能:目的操作数和源操作数进行逻辑乘,送目的操作数。逻辑乘规则:00=0,01=0,10=0,11=1也可以归纳为:0X=0,1X=X,XX=X,X=0说明:使用AND指令可以对操作数有选择地部分清零;对操作数类型的要求与ADD指令相同。例:MOVAL,7;(AL)=37HANDAL,0FH;(AL)=07H,字符7转换成二进制数例:ANDCX,0;(CX)=0,同时CF=OF=0,ZF=1例:ANDAX,AX;AX的值不变,CF=OF=0,(1)AND逻辑乘(逻辑与)指令,66,格式:OR目的操作数,源操作数功能:将目的操作数和源操作数进行逻辑加,送目的操作数。逻辑加规则:00=0,01=1,10=1,11=1也可以归纳为:0X=X,1X=1,XX=X,X=1说明:使用OR指令可以有选择地将操作数的某些位置1;OR指令对操作数类型的要求与ADD指令相同。例:MOVAL,7;(AL)=07HORAL,30H;(AL)=37H,二进制数7转换成字符7例:ORAX,AX;AX的值不变,CF=OF=0,(2)OR逻辑加(逻辑或)指令,67,格式:XOR目的操作数,源操作数功能:将目的操作数和源操作数进行逻辑异或运算。逻辑异或规则:00=0,01=1,10=1,11=0也可以归纳为:0X=X,1X=,XX=0,X=1说明:使用XOR指令可以有选择地将操作数的某些位取反;对操作数类型的要求与ADD指令相同。例:MOVAL,35H;(AL)=35HXORAL,0FH;(AL)=3AH,高4位不变,低4位取反例:XORAX,AX;将AX清零,同时CF=OF=0,(3)XOR逻辑异或(半加)指令,68,格式:NOT目的操作数功能:将目的操作数各位取反。取反规则为:NOT0=1,NOT1=0说明:目的操作数可以是8/16/32位寄存器/存储器操作数。例:MOVAL,35H;(AL)=35H=00110101BNOTAL;(AL)=0CAH=11001010B,各位取反,(4)NOT逻辑非(取反)指令,69,3.5控制台输入和输出,3.5.1字符的输出3.5.2字符的输入3.5.3输入、输出库子程序,70,大多数的程序,都有一个“人机”交互的过程,也就是说,从键盘上输入程序所需要的控制信息和数据,把程序的运行结果和运行状态向显示器输出。,交互使用的键盘称为“标准输入设备”,显示器称为“标准输出设备”,合称为“控制台(Console)”。,71,3.5.1字符的输出,通过操作系统的服务程序(INT21H)输出;通过“基本输入输出系统(BIOS)”输出;把显示内容(ASCII代码)直接写入“显示存储器(VideoRAM,VRAM)”,由显示器接口电路转换输出。,向显示器输出信息有三种方法:,本章首先介绍使用操作系统服务程序进行输出的方法。,72,例:下面的程序在显示器上输出数字字符“9”:MOVAH,2;功能号02HMOVDL,39H;字符“9”的ASCII代码INT21H;调用21H号系统服务程序字符“9”显示在光标(Cursor)位置,光标向右移动一个字符位置。,(1)输出单个字符,DL待输出字符的ASCII代码AH02HINT21H,X为DB定义的一个变量,下面的程序能够输出X的值吗?,MOVAH,2;功能号02H装入AH寄存器MOVDL,X;变量X的值装入DL寄存器INT21H;调用21H号系统服务程序,73,CODESEGMENTASSUMECS:CODESTART:LEABX,STRINGMOVCX,7ONE:MOVDL,CS:BX;取出一个字符的ASCII代码MOVAH,2;单个字符输出的功能号INT21H;调用系统服务,输出一个字符INCBX;修改指针LOOPONE;计数与循环控制MOVAX,4C00HINT21HSTRINGDB“Hello!”CODEENDSENDSTART,例3-10在显示器上输出文字“Hello!”,74,STRING在代码段里定义,取字符需要增加段跨越前缀“CS:BX”,否则会到“DS:BX”处取字符,输出不确定的内容。代码为0DH的字符称为“回车(CarriageReturn,CR)”,把光标移动到本行的第一个字符位置,代码为0AH的字符称为“换行(LineFeed,LF)”,把光标移动到下一行的相同位置上。,MOVCX,11STRINGDB0DH,0AH,“Hello!”,0DH,0AH,75,(2)输出一个字符串DS:DX待输出字符串的首地址AH09HINT21H字符串以字符“$”为结束标志,该字符本身不输出。,CODESEGMENTASSUMECS:CODE,DS:CODESTART:MOVAX,CODEMOVDS,AXLEADX,STRINGMOVAH,9INT21HMOVAX,4C00HINT21HSTRINGDB0AH,0DH,“Hello!”,0AH,0DH,$CODEENDSENDSTART,76,DATASEGMENTXDB10110111BC10DB10DATAENDSCODESEGMENTASSUMEDS:DATA,CS:CODESTART:MOVAX,DATAMOVDS,AXMOVCX,3;循环次数MOVAL,X,例3-11在显示器上用十进制格式输出单字节无符号数的值,77,ONE:MOVAH,0;高8位清零DIVC10;执行16b8b除法PUSHAX;把余数(在AH中)压入堆栈LOOPONEMOVCX,3;重新装载CXTWO:POPDX;从堆栈中弹出余数(在DH中)XCHGDH,DL;把余数交换到DLORDL,30H;转换成数字的ASCII代码MOVAH,2INT21H;向显示器输出一个字符LOOPTWOMOVAX,4C00HINT21HCODEENDSENDSTART,78,DATASEGMENTYDW0100101010110111BC16DW16HEXDB“0123456789ABCDEF”DATAENDSCODESEGMENTASSUMEDS:DATA,CS:CODESTART:MOVAX,DATAMOVDS,AXMOVCX,4;循环次数MOVAX,Y,例3-12在显示器上用十六进制格式输出无符号字变量Y的值。,79,ONE:MOVDX,0;高16位清零DIVC16;执行32b16b除法PUSHDX;把余数压入堆栈LOOPONE;第一个循环计数控制MOVCX,4;重新装载CXLEABX,HEX;表的首地址装入BXTWO:POPAX;从堆栈中弹出余数XLAT;转换成数字的ASCII代码MOVDL,AL;转移到DL中MOVAH,2INT21H;向显示器输出一个字符LOOPTWO;第二个循环计数控制MOVAX,4C00HINT21HCODEENDSENDSTART,80,(1)AH01INT21H键盘输入字符后返回,ASCII码在AL中,同时显示(“回显”,Echo)。(2)AH07INT21H键盘输入字符后返回,ASCII码在AL中,无回显。(3)AH08INT21H键盘输入字符后返回,ASCII码在AL中,无回显。同时检测Ctrl+Break和Ctrl+C键的组合。,3.5.2字符的输入,81,DATASEGMENTSUMDB?DATAENDS;-CODESEGMENTASSUMEDS:DATA,CS:CODESTART:MOVAX,DATAMOVDS,AX,例3-13从键盘输入5个数字,求它们的和,存入SUM。,82,MOVCX,5;循环次数MOVSUM,0;累加器清零ONE:MOVAH,1;输入单个字符的功能号INT21H;输入一个字符,ASCII码在AL中ANDAL,0FH;ASCII码转换成二进制数ADDSUM,AL;累加LOOPONE;计数与循环MOVAX,4C00HINT21HCODEENDSENDSTART,83,第一字节:输入字符存放区的大小。第二字节:由服务程序填入实际输入的字符个数,不包括回车。第三字节之后:输入字符存放区,存放输入的字符和回车。,操作系统提供的从键盘输入一行字符的服务程序如下。,DS:DX输入缓冲区首地址AH0AHINT21H,输入缓冲区格式:,BUFFERDB81,?,81DUP(?),如果从键盘上输入“ABCDE”,返回后,缓冲区各字节依次为:81,5,41H,42H,43H,44H,45H,0DH,。,84,DATASEGMENTSUMDB?BUFFERDB6,?,6DUP(?)DATAENDSCODESEGMENTASSUMEDS:DATA,CS:CODESTART:MOVAX,DATAMOVDS,AXLEADX,BUFFER;装载输入缓冲区首地址MOVAH,0AH;行输入功能代号INT21H;调用系统服务,例3-14从键盘输入最多5个数字,求它们的和,存入SUM。,85,MOVSUM,0;累加器清零MOVCL,BUFFER+1;循环次数MOVCH,0LEABX,BUFFER+2;装载字符存放区首地址ONE:MOVAL,BX;取出一个字符ANDAL,0FH;ASCII码转换成二进制数ADDSUM,AL;累加INCBX;修改指针LOOPONE;计数与循环MOVAX,4C00HINT21HCODEENDSENDSTART,86,DATASEGMENTBUFFERDB6,?,6DUP(?)C10DW10XDW?DATAENDSCODESEGMENTASSUMEDS:DATA,CS:CODESTART:MOVAX,DATAMOVDS,AXLEADX,BUFFER;装载输入缓冲区首地址MOVAH,0AH;行输入功能代号INT21H;从键盘输入一个数,以回车键结束,例3-15从键盘上输入不大于65535的十进制数,转换成二进制数,87,MOVAX,0;累加器清零MOVCL,BUFFER+1;循环次数MOVCH,0LEABX,BUFFER+2;装载字符存放区首地址ONE:MULC10;P=P10MOVDL,BX;取出一个字符ANDDL,0FH;转换成二进制数ADDAL,DL;累加ADCAH,0INCBX;修改指针LOOPONE;计数与循环MOVX,AX;保存结果MOVAX,4C00HINT21HCODEENDSENDSTART,88,3.5.3输入、输出库子程序,(1)从键盘输入一个十进制无符号整数入口:程序首部增加:EXTRNREADDEC:FARDS:DX=提示信息字符串首地址,没有提示信息,置DX=0FFFFH。调用:CALLREADDEC出口:AX=16b二进制无符号整数输入数据范围:065535,89,(2)从键盘输入一个十进制有符号整数入口:程序首部增加:EXTRNREADINT:FARDS:DX=提示信息字符串首地址,没有提示信息,置DX=0FFFFH。调用:CALLREADINT出口:AX=16b二进制有符号整数(补码)输入数据范围:-32768+32767,90,(3)十进制格式输出无符号整数入口:程序首部增加:EXTRNWRITEDEC:FARAX=16b二进制无符号整数DS:DX=提示信息字符串首地址,没有提示信息,置DX=0FFFFH。调用:CALLWRITEDEC出口:数据在光标位置输出,前后各空一格,91,(4)十进制格式输出有符号整数入口:程序首部增加:EXTRNWRITEINT:FARAX=16b二进制有符号整数(补码)DS:DX=提示信息字符串首地址,没有提示信息,置DX=0FFFFH。调用:CALLWRITEINT出口:数据在光标位置输出,前后各空一格,92,(5)十六进制格式输出无符号整数入口:程序首部增加:EXTRNWRITEHEX:FARAX=16b二进制无符号整数DS:DX=提示信息字符串首地址,没有提示信息,置DX=0FFFFH。调用:CALLWRITEHEX出口:数据在光标位置输出,前后各空一格,93,(6)输出回车换行入口:程序首部增加:EXTRNCRLF:FAR调用:CALLCRLF出口:无,94,(7)“头文件”YLIB.H包含:EXTRNREADINT:FAR,READDEC:FAR,EXTRNWRITEINT:FAR,WRITEDEC:FAREXTRNWRITEHEX:FAR,CRLF:FAR使用:程序首部增加:INCLUDEYLIB.H此后,可以直接用CALL指令调用所需子程序。,95,INCLUDEYLIB.HDATASEGMENTMESS1DB0AH,0DH,“Inputanumberplease:$”MESS2DB0AH,0DH,“Thesumoftwonumberis:$”NUMDW?,?SUMDW?DATAENDSCODESEGMENTASSUMEDS:DATA,CS:CODESTART:MOVAX,DATAMOVDS,AX,例3-16从键盘上输入两个有符号十进制数,求它们的和,在显示器上输出结果。,96,LEABX,NUM;输入缓冲区首地址MOVCX,2;输入数据个数INPUT:LEADX,MESS1;提示信息首地址CALLREADINT;输入一个有符号数MOVBX,AX;保存这个数据INCBX;修改指针INCBXLOOPINPUT;计数与循环MOVAX,NUM;取出第一个数ADDAX,NUM+2;与第二个数相加MOVSUM,AX;保存两个数的和,97,LEADX,MESS2;输出结果的前导文字MOVAX,SUMCALLWRITEINT;输出两个数的和CALLCRLF;输出回车、换行MOVAX,4C00HINT21HCODEENDSENDSTART,98,TASMMYPRG16;产生名为MYPRG16.OBJ的目标文件TLINKMYPRG16,YLIB16.LIB;与库文件YLIB16.LIB连接,得到可执行文件MYPRG16;执行程序,进行相关的输入输出Inputanumberplease:3048Inputanumberplease:4000Thesumoftwonumberis:952,程序“MYPRG16.ASM”的上机过程:,99,库程序名:“YLIB32.LIB”区别:输入/输出的数据存放在32位寄存器EAX中,对应的数据范围扩大为:无符号整数:04294967295有符号整数:21474836482147483647。程序“MYPRG32.ASM”的上机过程:TASMMYPRG32;产生名为MYPRG32.OBJ的目标文件TLINKMYPRG32,YLIB32.LIB;与库文件YLIB32.LIB连接,得到可执行文件MYPRG32;执行程序,进行相关的输入输出,32位子程序库,100,3.6移位和处理器控制,3.6.1移位指令3.6.2循环移位指令3.6.3标志处理指令3.6.4处理器控制指令,101,逻辑移位指令把操作数看作是各位相互独立的二进制串,最后移出的位进入CF,空出的位用0填充。(1)SHL(ShiftLeft)逻辑左移格式:SHL目的操作数,移位次数目的操作数:8/16/32位寄存器/存储器;移位次数:常数1或寄存器CL,286以上指令集可以使用不大于255的立即数。功能:将目的操作数向左移动指定的位数,目的操作数的高位移入CF,低位用0填充,3.6.1移位指令,1逻辑移位指令,102,逻辑、算术移位指令,103,PUSHBX;保护BX寄存器的原来的值SHLAX,1;左移一位,AX(原AX)2MOVBX,AX;BX2(原AX)SHLAX,1;左移一位,AX4(原AX)SHLAX,1;左移一位,AX8(原AX)ADDAX,BX;AX原(8AX)+原(2AX)POPBX;恢复BX寄存器的原来的值,例3-17用移位指令实现AX(AX)10,104,MOVCL,4;移位次数置入CLSHLAH,CL;AH低4位移到高4位,低4位清零ANDAL,0FH;AL高4位清零ORAL,AH;组合成压缩BCD码,例3-18AX的值为一个2

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论