一 二进制数转换为 ASCⅡ 码 将一个字节的二进制数转换为两位 16 进制数的 ASCⅡ 码 main: mov a,@0x9f ; 二进制数为 0x9f mov 0x30,a ; 二进制数存入 0x30 mov a,@0x02 mov 0x10,a ;0x10 中存放转换次数 mov a,@0x31 mov 0x04,a ;0x04 中为转换后数据存放地址 mov a,0x30 B1: ; 取 a 低 4 位 mov 0x00,a sub a,@0x09 ; 低 4 位大于 9 跳往 B2 jbs 0x03,0 jmp B2 mov a,0x00 ; 低 4 位不大于 9 则加 0x30 add a,@0x30 mov 0x00,a ; 将 ASCⅡ 码存入 0X04 所指单元 jmp B3 B2: mov a,0x00 ; 大于 9 则加 0X37 add a,@0x37 mov 0x00,a B3: swapa 0x30 ; 将 0X30 高 4 位换入 A 低 4 位 inc 0x04 ; 存储地址加 1 djz 0x10 ; 循环次数减 1, 为 0 则返回 jmp B1 ; 不为 0 继续转换 二 多字节二进制加法 0X20,0X21 中的二进制无符号数与 0X22,0X23 中的二进制无符号数相加, 结果放在 0X24,0X25,0X26 中, 低地址中放低字节数据 Main: mov a,@0x78 ; 赋值 mov a,@0xc6 mov a,@0x86 mov a,@0x9e mov a,@0x0 ;0x26 单元清 0 mov 0x26,a mov a,0x21 add a,0x23 mov 0x25,a ; 高字节相加, 结果送 0x25 inc 0x26 ; 有进位则 0x26 加 1 mov a,0x20 add a,0x22 ; 低字节相加, 结果送 0x24 1
jbs 0x03,0 jmp self ; 无进位跳 self inc 0x25 ; 有进位 0x25 加 1 inc 0x26 ; 有进位 0x26 加 1 三 多字节二进制减法 0x20,0x21 中的二进制无符号数减 0x22,0x23 中的二进制无符号数, 低地址中放低字节 数据 假设被减数大于减数 注意 :( 1 ) sub 指令减出结果为正时,c 标志置 1 (2)sub 指令减出结果为 0 时,c 标志也置 1 即,sub 指令执行后,c 标志清 0 表示结果为负 main: mov a,@0x67 ; 赋值 mov a,@0xff mov a,@0xe8 mov a,@0x44 ; 高字节相减 sub a,0x21 mov 0x25,a ; 结果存 0x25 mov a,0x22 ; 低字节相减 sub a,0x20 jbs 0x03,0 dec 0x25 ; 有借位则 0x25 减 1 四 二进制乘法运算 EM78 单片机没有乘法指令, 所以乘法运算需要转化为加法运算 0X20 单元数据乘以 0X21 单元数据, 结果放在 0X22,0X23 中 main: mov a,@0x0 ;0x22,0x23 单元清 0 mov a,@0x3f ; 赋值 mov a,@0x22 mul1: mov a,0x20 ;0x20 与 0x22 内容相加 add 0x22,a inc 0x23 ; 有进位 0x23 加 1 djz 0x21 ;0x21 中次数减到 0 则结束 jmp mul1 ; 没减到 0 则继续 2
五 二进制除法运算 多字节二进制除法 被除数为 3 个字节, 在 0x20 0x21 0x22 单元中,0x22.7 为最高位,0x20.0 为最低位 除数为 2 个字节, 在 0x30 0x31 中 算法 :EM78 单片机没有除法指令, 而且本例中除法为多字节除法, 可采用如下算法 将被除数扩充一个字节 0X23,0X23 清 0 被除数左移 1 位,0X23 0X22 中数据减去 0X31 0X30 中数据, 够减则减且 0X20.0 置 1, 减出结果存入 0X23 0X22; 不够减则 0X23 0X22 保持不变,0X20.0 清 0 然后被除数再左移 1 位, 重复上述过程 共循环 16 次, 最后 0X23 0X22 中得相减余数,0X21 0X20 中得商 注意, 若被除数左移后 C 标志为 1, 则不比较 0X23 0X22 与 0X31 0X30 数据大小关系而直接相减 main: mov a,@0x55 ; 被除数赋值 mov a,@0x0 ; 被除数扩充 1 字节并清 0 mov a,@0x12 ; 除数赋值 mov 0x30,a mov 0x31,a mov a,@0x10 ; 循环次数为 16 again: call rt_sub ; 调移位除法子程 djz 0x32 ;16 次循环完成则结束 jmp again ; 未完成则继续 rt_sub: bc 0x03,0 ;c 标志清 0 rlc 0x20 ; 被除数左移 1 位 rlc 0x21 rlc 0x22 rlc 0x23 jmp rt3 ;c 标志为 1 则直接相减 mov a,0x23 ;c 标志为 0 则先比较大小 mov 0x25,a mov a,0x22 mov a,0x31 ; 先比较高位 sub 0x25,a jbc 0x03,2 jmp rt1 ; 高位相等跳 rt1 比较低位 jmp rt2 ; 高位不等跳 rt2 rt1: mov a,0x30 ; 比较低位 sub 0x24,a jbc 0x03,2 jmp rt3 ; 低位也相等则跳 rt3, 相减, 上 1 rt2: jbs 0x03,0 ; 减数大则返回, 减数小则相减, 上 1 3
rt3: bs 0x20,0 ; 上 1 call sub_2b ; 调 2 字节减法子程 sub_2b: mov a,0x31 ; 高字节相减 sub 0x23,a mov a,0x30 ; 低字节相减 sub 0x22,a jbc 0x03,2 ; 低字节相等, 无借位, 返回 ; 无借位, 返回 dec 0x23 ; 低字节相减有借位, 高字节结果减 1 六 BCD 数转换为二进制数 两字节压缩 BCD 码转换为两字节二进制数 算法如下 : BCD 码 abcd=1000a+100b+10c+d=10{10[10a+b]+c}+d, 将各位 BCD 码分离出之后, 即可根 据此式转换为二进制数 涉及到乘法运算和多字节加法运算 0X20,0X21 中为 BCD 码,0X21 高 4 位为最高位 转换结果放在 0X30,0X31 中 main: mov a,@0x79 mov a,@0x54 ; 赋值 mov a,0x20 swapa 0x20 mov a,0x21 swapa 0x21 mov 0x25,a ;BCD 码展开后存于 0X22,0X23,0X24,0X25 mov a,0x25, ;0X25 为最高位 mov 0x30,a mov a,@0x0 ; 多字节加法高位为 0 mov 0x31,a mov a,0x24 call a_b ; 调子程 mov a,0x23 call a_b mov a,0x22 call a_b 4
a_b: mov a,@0x0 ;0X34,0X35 存储中间结果 mov 0x34,a mov 0x35,a mov a,@0x0a ; 实现乘 10 mov 0x33,a a1: mov a,0x35 ; 两字节二进制加法, 在本例中高字节肯定无进位 add a,0x31 mov 0x35,a mov a,0x34 add a,0x30 mov 0x34,a inc 0x35 djz 0x33 jmp a1 mov a,0x32 add 0x34,a inc 0x35 mov a,0x34 mov 0x30,a mov a,0x35 mov 0x31,a 七 二进制数转换为 BCD 码 本例为单字节二进制数 (0X20) 转换为非压缩 BCD 码, 存在 0X25,0X24,0X23 中,0X25 为 百位,0X23 为个位 main: mov a,@0xa4 ; 赋值 mov a,@0x0 ;0x23,0x24,0x25 单元清 0 mov 0x25,a mov a,@0x64 ; 对 100 的个数计数 mov 0x26,a mov a,@0x25 ; 百位存在 0x25 中 mov 0x04,a call a0 ; 调计数子程 mov a,@0x0a ; 对 10 的个数计数 mov 0x26,a dec 0x04 ; 个位存在 0x24 中 call a0 mov a,0x22 ; 除去百位, 十位, 余下的即个位, 存入 0x23 5
a0: ; 计数子程 mov a,0x26 sub 0x22,a jbs 0x03,2 jmp a1 inc 0x00 ; 无余数则对应位加 1 mov a,@0x0 ;0x21 与 0x22 在返回时应保持相同 a1: jbs 0x03,0 ; 小于则跳 a2 jmp a2 inc 0x00 ; 大于则计数值加 1 mov a,0x22 ; 将 0x22 保存到 0x21 中 jmp a0 ; 跳回 a0 继续计数 a2: mov a,0x21 ;0x21 中保存的减之前的数据, 此时恢复到 0x22 6