MOV 指令为双 *** 作数指令,两个 *** 作数中必须有一个是寄存器
MOV DST , SRC // Byte / Word
执行 *** 作: dst = src
1目的数可以是通用寄存器, 存储单元和段寄存器(但不允许用CS段寄存器)
2立即数不能直接送段寄存器
3不允许在两个存储单元直接传送数据
4不允许在两个段寄存器间直接传送信息
PUSH 入栈指令及POP出栈指令: 堆栈 *** 作是以“后进先出”的方式进行数据 *** 作
PUSH SRC //Word
入栈的 *** 作数除不允许用立即数外,可以为通用寄存器,段寄存器(全部)和存储器
入栈时高位字节先入栈,低位字节后入栈
POP DST //Word
出栈 *** 作数除不允许用立即数和CS段寄存器外, 可以为通用寄存器,段寄存器和存储器
执行POP SS指令后,堆栈区在存储区的位置要改变
执行POP SP 指令后,栈顶的位置要改变
XCHG(eXCHanG)交换指令: 将两 *** 作数值交换
XCHG OPR1, OPR2 //Byte/Word
执行 *** 作: Tmp=OPR1 OPR1=OPR2 OPR2=Tmp
1必须有一个 *** 作数是在寄存器中
2不能与段寄存器交换数据
3存储器与存储器之间不能交换数据
XLAT(TRANSLATE)换码指令: 把一种代码转换为另一种代码
XLAT (OPR 可选) //Byte
执行 *** 作: AL=(BX+AL)
指令执行时只使用预先已存入BX中的表格首地址,执行后,AL中内容则是所要转换的代码
LEA(Load Effective Address) 有效地址传送寄存器指令
LEA REG , SRC //指令把源 *** 作数SRC的有效地址送到指定的寄存器中
执行 *** 作: REG = EAsrc
注: SRC只能是各种寻址方式的存储器 *** 作数,REG只能是16位寄存器
MOV BX , OFFSET OPER_ONE 等价于 LEA BX , OPER_ONE
MOV SP , [BX] //将BX间接寻址的相继的二个存储单元的内容送入SP中
LEA SP , [BX] //将BX的内容作为存储器有效地址送入SP中
LDS(Load DS with pointer)指针送寄存器和DS指令
LDS REG , SRC //常指定SI寄存器。
执行 *** 作: REG=(SRC), DS=(SRC+2) //将SRC指出的前二个存储单元的内容送入指令中指定的寄存器中,后二个存储单元送入DS段寄存器中。
LES (Load ES with pointer) 指针送寄存器和ES指令
LES REG , SRC //常指定DI寄存器
执行 *** 作: REG=(SRC) , ES=(SRC+2) //与LDS大致相同,不同之处是将ES代替DS而已
LAHF ( Load AH with Flags ) 标志位送AH指令
LAHF //将PSW寄存器中的低8位的状态标志(条件码)送入AH的相应位, SF送D7位, ZF送D6位
执行 *** 作: AH=PSW的低位字节。
SAHF ( Store AH into Flags ) AH送标志寄存器指令
SAHF //将AH寄存器的相应位送到PSW寄存器的低8位的相应位, AH的D7位送SF, D6位送ZF
执行 *** 作: PSW的低位字节=AH。
PUSHF ( PUSH the Flags) 标志进栈指令
PUSHF //将标志寄存器的值压入堆栈顶部, 同时栈指针SP值减2
执行 *** 作: SP=SP-1,(SP)=PSW的高8位, SP=SP-1, (SP)=PSW的低8位
POPF ( POP the Flags ) 标志出栈指令
POPF //与PUSHF相反, 从堆栈的顶部d出两个字节送到PSW寄存器中, 同时堆栈指针值加2
执行 *** 作: PSW低8位=(SP), SP=SP+1, PSW高8位=(SP) , SP=SP+1
输入输出指令(IN,OUT):只限于使用累加器AX或AL与外部设备的端口传送信息
IN (INput)输入指令:信息从I/O通过累加器传送到CPU
IN AL , PORT //直接的字节输入,PORT是外设端口编号(即端口地址),只能取 00H ~ 0FFH共256个端口地址
IN AX , PORT //直接的字输入,AX存储连续两个端口地址PORT+1,PORT
IN AL , DX //间接的字节输入,端口地址范围可通过DX设置为0000H ~ 0FFFFH共65536个端口地址
IN AX , DX //间接的字输入
OUT( OUTput)输出指令 :信息从CPU通过累加器传送到I/O
OUT PORT , AL //直接的字节输出,PORT规定与IN指令相同
OUT PORT , AX
OUT DX , AL //间接的字节输出
OUT DX , AX
MOV AL,05H OUT 27H, AL //将字节05H传送到地址27H的端口
ADD(ADD)加法指令
ADD DST , SRC //Byte/Word
执行 *** 作: dst=dst+src
1两个存储器 *** 作数不能通过ADD指令直接相加, 即DST 和SRC必须有一个是通用寄存器 *** 作数
2段寄存器不能作为SRC 和DST
3影响标志位Auxiliary Crray Flag ,Carry Flag, Overflow Flag, Parity Flag, Sign Flag 和Zero Flag ,如下所示:
CF 根据最高有效位是否有进(借)位设置的:有进(借)位时CF=1, 无进(借)位时CF=0
OF 根据 *** 作数的符号及其变化来设置的:若两个 *** 作数的符号相同,而结果的符号与之相反时OF=1, 否则为0
ZF 根据结果来设置:不等于0时ZF=0, 等于0时ZF=1
SF 根据结果的最高位来设置:最高位为0, 则SF=0
AF 根据相加时D3是否向D4进(借)位来设置:有进(借)位时AF=1, 无进(借)位时AF=0
PF 根据结果的1的个数时否为奇数来设置:1的个数为奇数时PF=0, 为偶数时PF=1
ADC( ADd with Carry)带进位加法指令
ADC DST , SRC //Byte/Word
执行 *** 作: dst=dst+src+CF //与ADD不同之处是还要加上进位标志位的值
INC ( INCrement) 加1指令
INC OPR //Byte/Word
执行 *** 作: OPR=OPR+1
1OPR可以是寄存器和存储器 *** 作数, 但不能是立即数和段寄存器
2影响标志位OF,SF,ZF,PF 和AF,不影响CF
SUB ( SUBtract ) 不带借位的减法指令
SUB DST , SRC //Byte/Word
执行 *** 作:dst=dst - src
1DST和SRC寻址方式及规定与ADD相同
2影响全部标志位(判断标志位参见ADD)
SBB ( SuBtract with Borrow) 带借位减法指令
SBB DST , SRC //Byte/Word
执行 *** 作:dst= dst - src - CF
DEC ( DECrement ) 减1指令
DEC OPR //Byte/Word
执行 *** 作:OPR = OPR - 1 //除CF标志位, 其余标志位都受影响
NEG ( NEGate ) 求补指令
NEG OPR
执行 *** 作:opr = 0- opr //将 *** 作数按位求反后末位加1
CMP ( CoMPare ) 比较指令
CMP OPR1 , OPR2
执行 *** 作:OPR1 - OPR2 //与SUB指令一样执行运算, 但不保存结果
比较情况 无符号数 有符号数
A=B ZF=1 ZF=1
A>B CF=0 && ZF=0 SF^OF=0 && ZF=0
A<B CF=1 && ZF=0 SF^OF=1 && ZF=0
A>=B CF=0 || ZF=1 SF^OF=0 || ZF=1
A<=B CF=1 || ZF=1 SF^OF=1 || ZF=1
MUL ( unsigned MULtiple ) 无符号数乘法指令
MUL SRC //Byte/Word
执行 *** 作:Byte => AX= AL src //字节运算时目的 *** 作数用AL, 乘积放在AX中
Word => DX=AX src //字运算时目的 *** 作数用AX, DX存放乘积的高位字, AX放乘积的低位字
1目的数必须是累加器 AX 或AL,指令中不需写出
2 源 *** 作数SRC可以是通用寄存器和各种寻址方式的存储器 *** 作数, 而绝对不允许是立即数或段寄存器
IMUL (sIgned MULtiple) 有符号数乘法指令
IMUL SRC //与MUL指令相同,但必须是带符号数
DIV ( unsigned DIVide) 无符号数除法指令
DIV SRC //Byte/Word 其中: SRC的规定同乘法指令MUL
执行 *** 作:Byte => AX / src //字节运算时目的 *** 作数在AX中,结果的商在AL中 ,余数在AH中
Word=> DX,AX /src //字运算时目的 *** 作数在DX高位字和AX低位字中,结果的商在AX中 ,余数在DX中
存储器 *** 作数必须指明数据类型:BYTE PTR src 或 WORD PTR src
IDIV (sIgned DIVied) 有符号数除法指令
IDIV SRC //Byte/Word 与DIV指令相同,但必须是带符号数
CBW (Convert Byte to Word) 字节转换为字指令
CBW
执行 *** 作: AL中的符号位(D7)扩展到8位AH中,若AL中的D7=0,则AH=00H,若AL中的D7=1,则AH=FFH
CWD (Convert Word to Double word) 字转换为双字指令
CWD
执行 *** 作: AX中的符号位(D15)扩展到16位DX中,若AX中的D15=0,则DX=0000H,若AX中的D15=1,则DX=FFFFH
十进制调整指令
当计算机进行计算时,必须先把十进制数转换为二进制数,再进行二进制数运算,最后将结果又转换为十进制数输出
在计算机中,可用4位二进制数表示一位十进制数,这种代码称为BCD ( Binary Coded Decimal )
BCD码又称8421码,在PC机中,BCD码可用压缩的BCD码和非压缩的BCD码两种格式表示
压缩的BCD码用4位二进制数表示一个十制数,整个十进数形式为一个顺序的以4位为一组的数串
非压缩的BCD码以8位为一组表示一个十进制数,8位中的低4位表示8421的BCD码,而高4位则没有意义
压缩的BCD码调整指令
DAA (Decimal Adjust for Addition) 加法的十进制调整指令
DAA
执行 *** 作:执行之前必须先执行ADD或ADC指令,加法指令必须把两个压缩的BCD码相加,并把结果存话在AL寄存器中
DAS (Decimal Adjust for Subtraction) 减法的十进制调整指令
DAS
执行 *** 作:执行之前必须先执行SUB或SBB指令,减法指令必须把两个压缩的BCD码相减,并氢结果存放在AL寄存器中
非压缩的BCD码调整指令
AAA (ASCII Adjust for Addition) 加法的ASCII调整指令
AAA
执行 *** 作:执行之前必须先执行ADD或ADC指令,加法指令必须把两个非压缩的BCD码相加,并把结果存话在AL寄存器中
AAS (ASCII Adjust for Subtraction) 减法的ASCII调整指令
AAS
执行 *** 作:执行之前必须先执行SUB或SBB指令,减法指令必须把两个非压缩的BCD码相减,并氢结果存放在AL寄存器中
MOVS ( MOVe String) 串传送指令
MOVB //字节串传送 DF=0, SI = SI + 1 , DI = DI + 1 ;DF = 1 , SI = SI - 1 , DI = DI - 1
MOVW //字串传送 DF=0, SI = SI + 2 , DI = DI + 2 ;DF = 1 , SI = SI - 2 , DI = DI - 2
执行 *** 作:[DI] = [SI] ,将位于DS段的由SI所指出的存储单元的字节或字传送到位于ES段的由DI 所指出的存储单元,再修改SI和DI, 从而指向下一个元素
在执行该指令之前,必须预置SI和DI的初值,用STD或CLD设置DF值
MOVS DST , SRC //同上,不常用,DST和SRC只是用来用类型检查,并不允许使用其它寻址方式来确定 *** 作数
1目的串必须在附加段中,即必须是ES:[DI]
2源串允许使用段跨越前缀来修饰,但偏移地址必须是[SI]
STOS (STOre into String) 存入串指令
STOS DST
STOSB //存放字节串 ( DI ) = AL
STOSW //存放字串 ( DI ) = AX
执行品作:把AL或AX中的内容存放由DI指定的附加段的字节或字单元中,并根据DF值修改及数据类型修改DI的内容
1在执行该指令之前,必须把要存入的数据预先存入AX或AL中,必须预置DI的初值
2DI所指向的存储单元只能在附加段中,即必须是ES:[DI]
LODS ( LOaD from String ) 从串取指令
LODS SRC
LODSB //从字节串取 AL=(SI)
LODSW //从字串取 AX= (SI±1) (SI)
执行 *** 作:把由SI指定的数据段中字节或字单元的内容送入AL或AX中,并根据DF值及数据类型修改SI的内容
1在执行该指令之前,要取的数据必须在存储器中预先定义(用DB或DW),必须预置SI的初值
2源串允许使用段超越前缀来改变数据存储的段区
REP (REPeat)重复 *** 作前缀
REP String Primitive //其中:String Primitive可为MOVS,STOS或LODS指令
执行 *** 作:使REP前缀后的串指令重复执行,每执行一次CX=CX-1,直至CX=0时退出REP
方向标志设置
CLD (CLear Direction flag) 清除方向标志指令
CLD
执行 *** 作:令DF=0, 其后[SI],[DI]执行增量 *** 作
STD (SeT Direction flag) 设置方向标志指令
STD
执行 *** 作:令DF=1, 其后[SI],[DI]执行减量 *** 作
CMPS (CoMPare String) 串比较指令
CMPS SRC , DST
CMPSB //字节串比较 (SI)-(DI)
CMPSW //字串比较 (SI+1)(SI) - (DI+1)(DI)
执行 *** 作:把由SI指向的数据段中的一个字节或字与由DI指向的附加段中的一个字节或字相减,不保留结果,只根据结果置标志位
SCAS (SCAn String ) 串扫描指令
SCAS DST
SCASB
SCASW
执行 *** 作:把AX或AL的内容与由DI指向的在附加段中的一个字节或字相减,不保留结果,根据结果置标志位
AND, OR , XOR 和 TEST都是双字节 *** 作指令, *** 作数的寻址方式的规定与算术运算指令相同
NOT是单字节 *** 作指令,不允许使用立即数
逻辑运算均是按位进行 *** 作,真值表如下:
AND (位与&) OR ( 位或| ) XOR ( 位异或^ )
1 & 1 = 1 1 | 1 = 1 1 ^ 1 = 0
1 & 0 = 0 1 | 0 = 1 1 ^ 0 = 1
0 & 1 = 0 0 | 1 = 1 0 ^ 1 = 1
0 & 0 = 0 0 | 0 = 0 0 ^ 0 = 0
A:逻辑运算指令
AND (and) 逻辑与指令
AND DST , SRC //Byte/Word
执行 *** 作:dst = dst & src
1AND指令执行后,将使CF=0,OF=0,AF位无定义,指令执行结果影响SF,ZF和PF标志位
2AND指令典型用法A:用于屏蔽某些位,即使某些位为0
屏蔽AL的高4位:即将高4位和0000B相与,低4位和1111B相与
MOV AL , 39H //AL= 0011 1001B[39H]
ADD AL , 0FH // AL= 0000 1001B[09H] 即0011 1001B[39H] & 0000 1111B[0FH] = 0000 1001B[09H]
3AND指令典型用法B:取出某一位的值(见TEST)
OR (or) 逻辑或指令
OR DST , SRC //Byte/Word
执行 *** 作:dst = dst | src
1OR指令执行后,将使CF=0, OF=0, AF位无定义,指令执行结果影响SF, ZF和PF标志位
2常用于将某些位置1
将AL的第5位置1:
MOV AL , 4AH // AL=0100 1010B[4AH]
OR AL , 10H // AL=0101 1010B[5AH] 即0100 1010B[4AH] | 0001 0000B[10H] =0101 1010B [5AH]
XOR (eXclusive OR) 逻辑异或指令
XOR DST , SRC //Byte/Word
执行 *** 作:dst = dst ^ src
1XOR指令常用于使某个 *** 作数清零,同时使CF=0,清除进位标志
2XOR指令使某些位维持不变则与 '0' 相异或,若要使某些位取反则与 '1'相异或
将AL的高4位维持不变,低4位取反:
MOV AL, B8H //AL=1011 1000B[B8H]
XOR AL, 0FH //AL=1011 0111B[B7H] 即1011 1000B[B8H] ^ 0000 1111[0FH]=1011 0111B[B7H]
测试某一个 *** 作数是否与另一确定 *** 作数相等:
XOR AX , 042EH
JZ //如果AX==042EH, 则ZF=TRUE(1), 执行JZ
NOT (not) 逻辑非指令
NOT OPR //Byte/Word
执行 *** 作:opr = ~opr // ~ 01100101 [65H] =10011010 [9AH]
1 *** 作数不能使用立即数或段寄存器 *** 作数,可使用通用寄存器和各种方式寻址的存储器 *** 作数
2NOT指令不影响任何标志位。
将AL各位取反:
MOV AL,65H //AL=0110 0101B[65H]
NOT AL //AL=1001 1010B[9AH] 即 ~ 0110 0101B[65H]=1001 1010B[9AH]
TEST (test) 指令
TEST OPR1 , OPR2 //Byte/Word
执行 *** 作:opr1 & opr2
1两个 *** 作数相与的结果不保存,结果影响标志位PF,SF和ZF,使CF=0, OF=0,而AF位无定义
2TEST指令常用于在不改变原有的 *** 作数的情况下,检测某一位或某几位的条件是否满足只要令用来测试的 *** 作数对应检测位为1,其余位为0,相与后判断零标志ZF值的真假
检测某位是否为1:
令用来测试的 *** 作数对应检测位为1,其余位为0,TEST指令后,若该位为1则 JNZ
TEST AL , 0000 00001B //测试AL最低位是否为1:: 令用来测试的 *** 作数对应检测位为1,其余位为0,执行TEST指令
JNZ THER //最低位若为1, 则ZF=FALSE(0), 执行JNZ THER, 否则执行下一条指令
或者:先对 *** 作数求反,令用来测试的 *** 作数对应检测位为1,其余位为0,TEST指令后,若该位为1则JZ
MOV DL , AL //将AL 传送到DL,主要是不要影响AL的值 以下测试AL的b2位是否为1
NOT DL //先对 *** 作数求反
TEST 0000 0100B //令用来测试的 *** 作数对应检测位为1,其余位为0,执行TEST指令
JZ THER //若AL的b2位为1,则ZF=TRUE(1), 执行JZ THER
B:移位指令[所有的移位指令都影响标志位CF、OF、PF、SF和ZF、AF无定义]
非循环逻辑移位:把 *** 作数看成无符数来进行移位
SHL ( SHift logical Left )逻辑左移指令
SHL OPR , CNT //Byte/Word
执行 *** 作:使OPR左移CNT位,并使最低CNT位为全0
1OPR *** 作数不能使用立即数或段寄存器 *** 作数,可使用通用寄存器和各种方式寻址的存储器 *** 作数
2移位次数由CNT决定每次将OPR的最高位移出并移到CF,最低位补0
MOV CL , 7 //若移位多次, 先预置移位次数CL
SHL DX , CL //CNT可取1或CL寄存器 *** 作数
SHR (SHift logical Right) 逻辑右移指令
SHR OPR , CNT //Byte/Word
同SHL,每次将OPR的最低位D0移出并移到CF最高位补0
非循环算术移位:将 *** 作数看成有符号数来进行移位
SAL (Shift Arithmetic Left) 算术左移指令
SAL OPR , CNT //Byte/Word
SAL指令与SHL指令完全相同
SAR(Shift Arithmetic Right) 算术右移指令
SAR OPR , CNT //Byte/Word
SAR指令每次移位时,将最高位移入次高位的同时最高位值不变,最低位D0移出并移到CF
循环移位指令
ROL ( ROtate Left) 循环左移指令
ROL OPR , CNT //Byte/Word
每次移位时,最高位移出并同时移到CF和最低位D0
ROR (ROtate Right)循环右移指令
ROR OPR,CNT //Byte/Word
每次移位时,最低位D0移出并同时移到CF和最高位
带进位循环移位指令
RCL (Rotate Left through Carry)带进位循环左移指令
RCL OPR,CNT //Byte/Word
RCR (Rotate Right through Carry)带进位循环右移指令
RCR OPR ,CNT //Byte/Word
处理器控制指令
CLC (CLear Carry) 进位位置0指令
CLC //执行 *** 作后,CF=0
CMC (CoMplement Carry) 进位位求反指令
CMC //执行 *** 作后,CF=!CF
STC (SeT Carry) 进位位置1指令
STC //执行 *** 作后,CF=1
NOP (No Operetion) 无 *** 作指令
NOP //此指令不执行任何 *** 作,其机器码占一个字节单元
HLT (HaLT) 停机指令
HLT
执行 *** 作后,使机器暂停工作,使处理器CPU处于停机状态,以等待一次外部中断到来,中断结束后,程序继续执行,CPU继续工作
JMP ( JuMP ) 无条件转移指令
名称 格式 执行 *** 作
段内直接短跳转 JMP SHORT OPR IP=IP+8 位偏移量
段内直接近转移 JMP NEAR PTR OPR IP=IP+16位偏移量
段内间接转移 JMP WORD PTR OPR IP=(EA)
段间直接转移 JMP FAR PTR OPR IP=OPR 偏移地址, CS=OPR 段地址
段间间接转移 JMP DWORD PTR OPR IP=(EA),CS=(EA+2)
1无条件转移到指定的地址去执行从该地址开始的指令
2段内转移是指在同一代码段的范围内进行转移,只需改变IP寄存器内容
3段间转移则要转移到另一个代码段执行程序,此时要改变IP寄存器和CS段寄存器的内容
条件转移指令:根据上一条指令所设置的条件码(标志位)来判断测试条件
根据五个标志位:ZF、SF、OF、 PF、 CF的两种状态(0 FALSE或1 TRUE)产生10种测试条件
Name Flag Flag == TRUE [1] Flag ==FALSE [ 0]
Zero Falg ZF JE/JZ OPR //结果为零转移JNE/JNZ OPR //结果不为零转移
Sign Falg SF JS OPR //结果为负转移JNS OPR //结果为正转移
Overflow Flag OF JO OPR //溢出转移JNO OPR //不溢出转移
Parity Flag PF JP/JPE OPR //结果为偶转移 JNP/JPO OPR //结果为奇转移
Carry Flag CF JC OPR //有进位转移 JNC OPR //无进位转移
两个数比较:
情况 指令 满足条件 指令 满足条件
A < B JC CF==1 JL SF^OF==1 && ZF==0
A ≥ B JNC CF==0 JNL SF^OF==0 || ZF==1
A ≤ B JNA CF==1 || ZF==1 JLG SF^OF==1 || ZF==1
A > B JA CF==0 && ZF==0 JG SF^OF==0 && ZF==0
测试CX转移指令
JCXZ OPR //CX==0时转移
LOOP(LOOP)循环指令
LOOP OPR 测试条件:CX ≠ 0 //OPR在程序中实际是个标号
LOOPZ OPR 测试条件:ZF == 1 && CX ≠ 0
LOOPNZ OPR 测试条件:ZF == 0 && CX ≠ 0
执行 *** 作: 先执行CX=CX-1,再检测上面的测试条件,如满足则IP=IP+符号扩展的D8,不满足则退出循环
过程调用及返回指令
CALL (CALL) 过程调用指令
CALL DST //DST在程序中实际是子程序标号
执行 *** 作:先将过程的返回地址(即CALL的下一条指令的首地址)存入堆栈,然后转移到过程入口地址执行子程序
调用方式 格式 断点保护入栈情况 过程入口地址
段内直接 CALL NEAR PTR PR1 (SP-1)(SP-2)←IP , CS不进栈 CS值保持不变,IP←DST
段内间接 CALL WORD PTR (EA) (SP-1)(SP-2)←IP , CS不进栈 CS值保持不变,IP←(EA)
段间直接 CALL FAR PTR PR1 (SP-1)(SP-2)←CS , (SP-3)(SP-4)←IP IP←DST偏移地址,CS←DST段地址
段间间接 CALL DWORD PTR (EA) (SP-1)(SP-2)←CS , (SP-3)(SP-4)←IP IP←(EA),CS←(EA+2)
注:为了表明是段内调用,可使用NEAR PTR属性 *** 作符作说明
RET(RETurn)子程序返回指令
RET
RET EXP //带立即数返回
子程序返回指令RET放在子程序末尾,它使子程序在执行完全部任务后返回主程序继续执行被打断后的程序返回地址在子程序调用时入栈保存的断点地址-IP或IP和CS
把压缩BCD码转换成二进制数再进行乘除运算,把结果转换回压缩BCD码就是了
不进行数制转换,就用压缩BCD硬算,多字节无符号的
你是要进行大数运算吧,先设计一个BCD格式,比如最多十位,二十位什么的,这样才能通用于所有的BCD运算,不然你BCD长度不一样程序就不通用了。
设计好BCD长度后,就模拟人工手算方式进行运算,你有一个1#数据定义和一个2#数据定义,以及一个3#数据定义存放结果。每个数据都是压缩BCD方式定义的多字节
乘:
取2#数最末位,与1#数最末位相乘,这得用MUL指令(完全杜绝二进制指令那你就累加),转换成BCD格式,结果放在3#数据里,然后与1#倒数第二位进行乘法运算,转换成BCD格式,结果与3#数据移位累加(你得设计出BCD格式的加法),一直到1#数据的所有位完成为止(也可以以1#数据位出现0为终止条件)
2#数最末位完成后,进行2#数的其它位乘法,具体与最末位过程是一样的。当所有位运算完后,3#结果存放的就是符合你要求的BCD格式的数据了。
除:
你得设计出BCD相减算法,用1#数据减2#数据,直到不够减为止,那时的减的次数是商,余下的就是余数了。
综上所述,要完成大数BCD码的乘除运算,没有相应的加减算法支持是不行的,因为按你的意思大数可能超出了32位(8086汇编还只是16位),也就是说,大于65535的BCD码相加你不能依靠机器自有加法指令,只好自己设计相关算法了。
具体加减方式也差不多,和手工相似:
加:
从最末位到第一位,提取各自的BCD码值进行数据相加,加的过程中你要处理进位情况
减:
从最末位到第一位,提取各自的BCD码值进行数据相减,减的过程中你要处理借位情况
当然,具体到编程中去可能没有说的这么简单,这只是个过程描述而已。
以前有本书好像是叫《80386协处理器数值编程》,时间太长了,除当时外也没再关注此书,所以不敢肯定,那上面就有BCD码+-/的算法,好像也就十来位。你能找到最好,找不到我也没办法,那书早搞丢了。
还有个完成此类问题的思路,当然它也有局限性,那就是用浮点指令来进行运算,它的表示范围是计算机当前所能表示的最大范围,你设计一个浮点数与BCD码也好,二进制也好它们之间的双向转换算法,然后借用浮点指令进行运算,结果再转换回来,那本书也有此代码,不过很可惜,这点我帮不上你,而且可以告诉你,无论那种方法,汇编代码都不短
以上就是关于汇编语言y=sin(x)怎么写详细见图片全部的内容,包括:汇编语言y=sin(x)怎么写详细见图片、[汇编]压缩BCD码的乘除法算法、等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)